Это видео недоступно.
Сожалеем об этом.

Designing Idempotent API Endpoints for Payments at Stripe

Поделиться
HTML-код
  • Опубликовано: 16 авг 2024
  • System Design for SDE-2 and above: arpitbhayani.m...
    System Design for Beginners: arpitbhayani.m...
    Redis Internals: arpitbhayani.m...
    Build Your Own Redis / DNS / BitTorrent / SQLite - with CodeCrafters.
    Sign up and get 40% off - app.codecrafte...
    In the video, I explained the importance of idempotent APIs in handling network glitches in payment services. By ensuring APIs are idempotent, servers process requests exactly once, avoiding unintended behaviors like duplicate transactions. I discussed the challenges of automatic retries and the solution of using item potency keys to track requests. This simple approach helps maintain exactly-once semantics, crucial for critical APIs like payment services. I highlighted how payment services like Stripe implement idempotency and recommended checking their API documentation for further understanding.
    Recommended videos and playlists
    If you liked this video, you will find the following videos and playlists helpful
    System Design: • PostgreSQL connection ...
    Designing Microservices: • Advantages of adopting...
    Database Engineering: • How nested loop, hash,...
    Concurrency In-depth: • How to write efficient...
    Research paper dissections: • The Google File System...
    Outage Dissections: • Dissecting GitHub Outa...
    Hash Table Internals: • Internal Structure of ...
    Bittorrent Internals: • Introduction to BitTor...
    Things you will find amusing
    Knowledge Base: arpitbhayani.m...
    Bookshelf: arpitbhayani.m...
    Papershelf: arpitbhayani.m...
    Other socials
    I keep writing and sharing my practical experience and learnings every day, so if you resonate then follow along. I keep it no fluff.
    LinkedIn: / arpitbhayani
    Twitter: / arpit_bhayani
    Weekly Newsletter: arpit.substack...
    Thank you for watching and supporting! it means a ton.
    I am on a mission to bring out the best engineering stories from around the world and make you all fall in
    love with engineering. If you resonate with this then follow along, I always keep it no-fluff.

Комментарии • 88

  • @kumarutsav5161
    @kumarutsav5161 Год назад +26

    The idea of Idempotentency for APIs means that clients can retry the request without changing the state of the system. Whether the server processes the request multiple times or once(as in this case) is an internal detail. Informative video nonetheless!

  • @ankk98
    @ankk98 6 месяцев назад +2

    Idempotency is a very important concept in software development.
    We have developed our apis in such a way that the values are always overwritten instead of some other operation like increment operation. We can do this as we are sure that there will always be a singular api call.

  • @saikatmukherjee8683
    @saikatmukherjee8683 Год назад +4

    You said when the operation is successful, the server will delete the key from Redis. Wondering how would the server know that operation was successful if a retry comes in with same key? Server should not delete the key but rather should keep it in the key-store till the time the payment url is valid and then delete it based on ttl

  • @sahilguleria5505
    @sahilguleria5505 Год назад +7

    Great video, had some queries
    1. Is the idempotence key unique to each transaction?
    2. What if the client crashes looses the idempotency key and when it resumes it retries with different idempotency key. That will be treated as a new transaction and same operation is done twice?

    • @harendraprasad6209
      @harendraprasad6209 Год назад +1

      I had the same concern, and addition to that if on one failure cant it request a new key and then tries with it again ?

    • @lbirkert
      @lbirkert Год назад

      @@harendraprasad6209 what you could try is to just put the key somewhere where it is stored even after a page refreshes like as an URL parameter or in the localStorage. There will still be a chance that the client looses its key. If this happens you could implement a protection, which diffs the transaction (amount, user that the payment is directed to) and then notify the user that a similar transaction has already been made and ask for his approval to send this money twice.

  • @lknockoutl
    @lknockoutl Год назад +6

    If the server crashes right after hitting the Payments DB you will not have updated the Redis. The client will call the API again and hit the Payments DB once again.
    How do you handle that scenario?

    • @cowabunga2597
      @cowabunga2597 8 месяцев назад +1

      I wont

    • @anuragdas1978
      @anuragdas1978 2 месяца назад

      make it atomic, so it can rollback

    • @InvincibleMan99
      @InvincibleMan99 Месяц назад

      As far as i understand, it should be in some transaction, so it will rollback

  • @gauravraj2604
    @gauravraj2604 Год назад +3

    Hi Arpit,
    Thank you for such informative video. I really admire you putting your continuous efforts towards "Real Engineering".
    Can you please tell me if my approach is correct or not:
    1. Client requests idempotency-key from server. Server generates one, save it in a key-value store and return it.
    2. Client sends idempotency-key as header along with other parameters in its request.
    3. Case a: If due to network failure request did not reach the server, then client retries along with same idempotency-key.
    4. Server processes the request, deletes the idempotency-key from the store and return response to client.
    5. Case b: If request reaches the server and the server starts processing but in between it got failed, in this case as well idempotency-key remains intact, and client can send retry request.
    6. Case c: On retry request, say it got successful and idempotency-key got deleted but client did not receive the response.
    7. Client will retry with same idempotency-key. Since server could not find idempotency-key, there can be two possibilities which are either this request was already processed, or idempotency-key is invalid.

  • @SentryProductions1
    @SentryProductions1 4 месяца назад

    Nice video - we use this in open-banking for retrieving a request/consentToken prior to making a payment (we can build on top of OIDC and OAuth)

  • @sachinjindal4921
    @sachinjindal4921 Год назад +1

    I really like your way of explaining. The way you put a blog into simple understandable language.
    Thanks Arpit for bringing such kind of content.
    Keep inspiring us 🙂

  • @abhikumar310
    @abhikumar310 Год назад +2

    Thanks for the helpful video.
    One thing, this will have possibility of race-around condition if one request with idempotent key is under-process and the other request could come-up.
    How to handle these situations?

  • @kapilchoudhary2922
    @kapilchoudhary2922 Год назад

    Simply amazing, nothing else!! Thank you so much for making these kind of educational videos which help the dev community.

  • @rajatiitr
    @rajatiitr Год назад +2

    Hi Arpit,
    Hope you're doing well.
    I joined Adobe last month. I would like to thank you for providing the best quality content on design [not just for interviews but beyond that] on your channel. It helped me a lot
    Thanks!!

    • @AsliEngineering
      @AsliEngineering  Год назад

      Congratulations 🎉🎉 keep soaring 🚀

    • @gmmkeshav
      @gmmkeshav Год назад

      writting bhi bahut payari hai sir ki may be a font I guess

    • @AsliEngineering
      @AsliEngineering  Год назад +1

      @@gmmkeshav not a font. That's my handwriting.

    • @gmmkeshav
      @gmmkeshav Год назад

      @@AsliEngineering 🙏🙏🙏

    • @rajeshgopidi7842
      @rajeshgopidi7842 Год назад

      @@AsliEngineering can you please share name of the app that you are using for white boarding?

  • @johnrush607
    @johnrush607 6 месяцев назад +2

    Does the idempotency key have to be generated on the server side? Seems like the client could generate the unique identity instead, collisions should be minimal?

    • @AsliEngineering
      @AsliEngineering  6 месяцев назад +1

      Server should generate it. If done on client side then people can spoof the flow.

  • @ajaysaini6934
    @ajaysaini6934 Год назад +1

    I was wondering about it's optimisation further. Will it makes sense to batch GET the keys, in order to avoid two trips to downstream service for every request.
    Absolutely incredible technique. Thanks for bringing up such informative content consistently.

  • @shishirchaurasiya7374
    @shishirchaurasiya7374 Год назад

    When you say na at the end Hope you found it interesting there at that point I just wanna shout and say its very very very interesting

  • @tarunkishore9508
    @tarunkishore9508 5 месяцев назад +1

    Thanks for the video, my question is why should'd we store that idmpotent key on the primary db itself this will help us take leverage of db transactions, because there could be a case where the payment transacition is successful but while deleting the idempotent key from redis an error occurred and key didn't gets deleted.

    • @InvincibleMan99
      @InvincibleMan99 Месяц назад

      +1, Agree with you. Also we will have the history of api's (transactions)

  • @sheikhsaifuddinahmed7375
    @sheikhsaifuddinahmed7375 Год назад +2

    At 12:35 if the server is deleting the key after the request is handled, that means after the response is send, now let's say the response could not reach the client because of network issue, the client will retry, but the server has already delete the key, so it would consider the retry request as a new request so how to handle that

    • @koteshwarraomaripudi1080
      @koteshwarraomaripudi1080 Год назад +2

      If we don't have the idempotent key in the DB that means, it is processed. If its a new request it should have obtained the key from the key generator and it will be present in the DB

    • @shashankagrawal1902
      @shashankagrawal1902 Год назад +1

      "Keys are eligible to be removed from the system automatically after they're at least 24 hours old": stripe doc. They don't immediate delete it, to handle cases mentioned by you.

  • @koteshwarraomaripudi1080
    @koteshwarraomaripudi1080 Год назад +3

    How do we handle the following scenario,
    money is successfully transferred from A to B but we have failed to delete the idempotent key from DB (maybe because of a DB issue). Now if the client retries we will process it again right. How do we handle this kind of scenario?

    • @akashshirale1927
      @akashshirale1927 Год назад

      Good question...Ans: Store the idempotent key with TTL of milliseconds in Redis, that will solve this issue.

    • @koteshwarraomaripudi1080
      @koteshwarraomaripudi1080 Год назад

      @@akashshirale1927 Thanks. let's say we failed to process the request because of any xyz reason in that case key should not be deleted that means we have to increase ttl of that key. Now what if we failed to increase the ttl? Then the key would be deleted and we would consider request as processed even though it is not processed

    • @akashshirale1927
      @akashshirale1927 Год назад +2

      @@koteshwarraomaripudi1080 You might hear arpit saying a lot of this...Simple systems scale...complicated systems don't scale. So here we would just fail the request if the key is not present And just tell the user to retry his operation and give him a new idempotent key.

    • @koteshwarraomaripudi1080
      @koteshwarraomaripudi1080 Год назад +1

      @@akashshirale1927 Thats true. I guess it's better off to fail off the request by guaranteeing idempotent. Thanks a lot Akash

  • @nasirmushtaq6056
    @nasirmushtaq6056 Год назад

    Thanks for making videos public

  • @abhishekvishwakarma9045
    @abhishekvishwakarma9045 Год назад

    Thanks arpit sir, great explanation🔥 easy to understand 😎

  • @cooldudecs
    @cooldudecs Год назад

    I call the random key architecture a newbie architecture. State change only occurs on when key doesn't exist

  • @karanyadav5549
    @karanyadav5549 5 дней назад

    where can i get your notes?

  • @ashwanidu-mca5935
    @ashwanidu-mca5935 11 месяцев назад

    Hi Arpit, I want to task 1 thing. Which all tools do you use to create the content, how your video is coming along with notes being shared ?

  • @adityasoni1207
    @adityasoni1207 Год назад

    Thanks for an amazing video! Have we discussed about fencing tokens? Thanks

  • @gsenthilkumar8139
    @gsenthilkumar8139 4 месяца назад

    Idempotent key is generated by client it self using UUID lib not by calling the server

    • @AsliEngineering
      @AsliEngineering  4 месяца назад

      Both approaches are possible, I prefer doing it at server side to have greater control.

  • @nabhavlogs371
    @nabhavlogs371 Год назад

    How to handle cases when the request is partially processed? In this case, neither i can save the idempotent response, nor I want my system to reprocess the work that has already been done.

    • @AsliEngineering
      @AsliEngineering  Год назад

      Depends on the usecase. Not everything is resumable.

  • @Proman.Offbeat.Traveller
    @Proman.Offbeat.Traveller Год назад

    Nyc information bhai ❤️

  • @arpanghoshal2579
    @arpanghoshal2579 Год назад

    Consider this scenario
    Server gets a payment request with a idempotency key and beings processing the request, mean while due to some network error the client reties the same request with the same idempotency key. At this point the server is still processing the initial request so the idempotency key is still marked as unused. What happens here?
    Even if the server marks the idempotency key as "used" immediately when it starts processing the request still we might end up with this problem in some rare scenarios due to race conditions. The only way to the solve this that I can think of is some kind of locking or transactions on the DB layer.

  • @arhamcodes
    @arhamcodes Год назад +2

    Great tutorial!! Have some doubts:
    What if you have a microservice architecture and you have multiple APIs in the backend?
    Each of those APIs would be storing the idempotent key? and what if request is failed somewhere between whole APIs?

    • @rajeshdansena
      @rajeshdansena Год назад +1

      I think in this case, you must need a distributed system which should maintain the idempotent keys and status of it. If there are many APIs which needs this key and need to update the status then you may consider any data structure/a way to store multiple status and have a final status.

    • @akashshirale1927
      @akashshirale1927 Год назад

      True…you can store keys in redis cache and each api will request a key from a redis key pool

  • @user-wj9dk9yl2t
    @user-wj9dk9yl2t Год назад

    Why can't the client generate the idempotency key on its own? Why does it need to ask server to generate it?

  • @shashankagrawal1902
    @shashankagrawal1902 Год назад +1

    Hey Arpit, great stuff.
    Quick question: 8:25 you mentioned client talking to server to generate a random id,
    but instead of talking twice to the server, it can generate an idempotence key and share it along the payload with the server in a single step.
    And if server is seeing it for the first time it can store it, right?

    • @AsliEngineering
      @AsliEngineering  Год назад

      It defeats the purpose. You cannot guarantee idempotency through this. Easily hackable

    • @adityasheth
      @adityasheth Год назад

      @@AsliEngineering Hi Arpit, I had the same question. Can you please explain how it's easily hackable?
      I read the blog of stripe and they are generating random idempotence key at client-end itself.

    • @AsliEngineering
      @AsliEngineering  Год назад +1

      @@adityasheth if end user/ frontend is responsible for generating idempotent keys and sending it to backend. What stops then to generate a new key every time and not adhere to the protocol of reusing.

    • @adityasheth
      @adityasheth Год назад +1

      @@AsliEngineering That makes sense.
      In that case, even a mistake of API call with a new idempotent key from the end-user can make double transactions that way.

    • @JohnMcclaned
      @JohnMcclaned 9 месяцев назад +1

      @@AsliEngineering You are conflating security with Idempotency. Idempotency covers the case when a client request is left in a situation where it doesn't know if the request was executed or not. The client needs a reliable way to send the SAME request to the server and have it be recognised as a duplicate send. It can generate a uuid. The server can make the decision to ignore or execute.
      If a "hacker" maliciously double executes requests, it doesn't matter (they transfer money twice), it doesn't hurt anything. Your goal is trying to prevent normal users accidentally double submitting, not malicious users poking around and losing their money twice.

  • @gmmkeshav
    @gmmkeshav Год назад

    maja agaya sir

  • @barebears289
    @barebears289 Год назад

    I want to buy your pre recorded cohort videos, but why are they from your June cohort not the latest one?

    • @AsliEngineering
      @AsliEngineering  Год назад +1

      Because June 2022 is the best till date, also after June only 2 more have happened. I give the best till date in recordings.

    • @barebears289
      @barebears289 Год назад

      @@AsliEngineering 🙏

  • @ankitkalavagunta8951
    @ankitkalavagunta8951 11 месяцев назад

    If redis goes down you've lost state. You need a persistent DB.

  • @rahulpanjwani1887
    @rahulpanjwani1887 Год назад

    Any idea on how to make api calls idempotent in case a new request is submitted within a matter of milliseconds by a user by mistake? Here in this case the new request will have a new idempotent key and hence it will be treated seperately by the server, right?

    • @AsliEngineering
      @AsliEngineering  Год назад

      Transactions solve this.

    • @gauravraj2604
      @gauravraj2604 Год назад

      @@AsliEngineering I did not get it Arpit. Can you please explain a bit more?

  • @rohitsrivastava3768
    @rohitsrivastava3768 Год назад

    Sorry if I missed out but curious to know what will happen to case 3 with Idempotency key where the server has completed the execution but somehow there was network issue while sending the response back to the client.

    • @ayush_walia
      @ayush_walia Год назад

      Well server knows it has processed the transaction with that idompotent key. client doesn't get the response so it retries with same idompotent key. This time hopefully response doesn't fail again so client gets the success response.

    • @rohitsrivastava3768
      @rohitsrivastava3768 Год назад

      So question still stays the same, if the client does a retry, server will know it has marked that request with the same Idempotency key as completed, so won't it throw error or ignore the request?

    • @ayush_walia
      @ayush_walia Год назад

      @@rohitsrivastava3768 why ignore? Just respond as ALREADY_PROCCESSED or something

    • @barebears289
      @barebears289 Год назад

      @@rohitsrivastava3768 next time the client will know with server responds with already done.

    • @hemanthaugust7217
      @hemanthaugust7217 Год назад

      @@ayush_walia How long can we keep the key in server? I think we can delete these keys older than a few minutes, right? As old keys anyway don't make sense.

  • @waleedahmad2012
    @waleedahmad2012 Год назад

    So a single network request would be converted to two requests for one operation😵

  • @abcd-sf5ur
    @abcd-sf5ur Год назад

    I am having 4 months experience as SDE-1. Can I join your course? is it beginner friendly?

    • @AsliEngineering
      @AsliEngineering  Год назад +1

      My course is not beginner friendly. It is meant for 2+ years of work ex. The detailed curriculum is listed on my website.

  • @soodankit1993
    @soodankit1993 Год назад

    Hi Arpit,
    I think there is an edge case here but I might be mistaken. Consider a scenario where the idempotence key was sent and application tried to do the operation. Once operation is successful, we will commit the same to our key value store. But there is a possibility that our key value store is down or application went down before making that call.
    In this case, consumer will send the request again and application will still do the reprocessing. Is there a way to handle this gracefully.

    • @sagarkhasnis5991
      @sagarkhasnis5991 Год назад

      You'd typically store this information in your backend as well, and could check for the same transaction there. (If it exists, ignore/return success or error)

    • @AsliEngineering
      @AsliEngineering  Год назад +2

      Why commit to KV store. Should be modelled as a transaction.

    • @gauravraj2604
      @gauravraj2604 Год назад +1

      @@AsliEngineering If I am correct, you are saying that doing the operation and storing the idempotency key into key-value store should be under single transaction boundary. That means in case, storing fails all changes done till now will rollback.

    • @charan775
      @charan775 Год назад

      ​@@gauravraj2604 not possible in case of money transfer APIs though. you have to create refund.

    • @charan775
      @charan775 Год назад

      but I would generally if the operation is creating some entry in DB, better to store reference key there.

  • @gomchik
    @gomchik Год назад

    Please allow me to join Feb cohort

    • @AsliEngineering
      @AsliEngineering  Год назад

      Feb cohort is full and really sorry I cannot accommodate more. I am just trying to maximize learning outcomes. I hope you understand.
      Looking forward to seeing you in the April cohort. The admission will open in March first week. Please join the waitlist to get notified.

    • @rohitsrivastava3768
      @rohitsrivastava3768 Год назад

      Video Published: 2 hrs back today
      This comment: 1d ago
      How is this even possible 🥺

    • @AsliEngineering
      @AsliEngineering  Год назад +1

      @@rohitsrivastava3768 it was a premiere. The video was listed but was not playable until today 10 am.

    • @gomchik
      @gomchik Год назад

      @@rohitsrivastava3768 The Video publisher can schedule a stream in advance on RUclips.