0
votes

I am building an app to sell single item product (i.e, each kind of products listed on my platform only has a single item).

  1. (this part has been done, and won't change) I built an in-house backend having the Rest API POST -D {"buyer_email": "[email protected]"} url/items/{itemID}, let's call it transaction_call, which will make sure once a customer succeed the POST operation, his contact info is recorded into my backend as the successful buyer; and all other customers will fail to buy that item (at API level, transaction_call return 4xx error) because my platform can only sell one item for that product;
  2. (this is the step that my current question is about) I am trying to use Stripe as my payment system on this platform.

I really want to integrate with Stripe as simple as possible (as I understand Stripe Checkout is the most simple / out-of-box way to implement payment). However, I am not sure if Stripe Checkout can achieve the above functionality correctly. Since the problem is a two-step problem, here is the potential issue I may run into:

  • Let's say, two customers A, B, get to my platform at 10:00am, both of them start purchasing process for a product, Item_a

  • If my system interact / call the Stripe Checkout first as the first step then call the transaction_call, here could be the problem:

    • A's Stripe call hits the Stripe server at 10:00:01am, and A's buying call hits my backend at 10:00:02am;
    • B's Stripe call hits the Stripe server at 10:00:01am, and A's buying call hits my backend at 10:00:03am;
    • in this way, we have already charged B but he really did not get the item
  • If my system calls the transaction_call first, and only if transaction call succeeds then it interacts / calls the Stripe Checkout, then

    • A's transaction_call succeed at 10:00:01am, but he for some reason decided not to pay (not click confirm button on the Stripe Checkout UI)
    • In this way, my system fails to sell the item to other buyers.

My question is whether the above reasoning process is correct, and whether I could somehow use Stripe Checkout to achieve what I am doing.

Maybe I have implement the payment functionality using Stripe Intent API to build a workflow-based payment, which I assume will be much more complex, if the Stripe Checkout way (simple wayO is really not possible.

1

1 Answers

0
votes

From what I understand you have a potential race problem, where the item you're selling is very limited in quantity and you want to make sure that you can correctly notify users if it's out of stock or already spoken for.

For your first scenario, the simple solution is only invoke Stripe's API on your backend when you've received the transaction_call. For instance, you'd only create the Checkout Session once your system has identified that the item is still available. You'd then "lock" the item so that when B attempts to purchase you can immediately return an error instead of creating a payment via Stripe's API. The logic on who to charge (basically who initiated the checkout process first) in the case of a tie would then be for you to implement in your transaction_call rather than on Stripe's side.

The second scenario is a little tricker, as Checkout Sessions can't be cancelled once you create them. They automatically cancel themselves after 24 hours if no payment is made, but I doubt that you'd want B to have to wait that long if A abandons the payment flow.

Instead I think you should look at implementing a PaymentIntents integration, where you can more finely control the flow.

Your flow for scenario 2 could be:

  1. A begins the checkout process, create a PaymentIntent on the backend, "lock" the item and start a timer
  2. The timer (which you'd ideally show to your user) times out after N minutes if A doesn't pay
  3. Cancel the PaymentIntent on your backend and remove the lock
  4. B can now attempt to pay for the item, upon where you restart the process