Proper way to handle customer delays in stripe payment gateway - stripe-payments

I have a question to ask about payment strategy with Stripe Checkout API. consider following scenario
A vendor published 10 products(apples) for 5$ each in a marketplace
A customer wants to buy 8 of them, and he fill the details and click checkout button
( stripe checkout page comes)
But customer waits idle for 1 hr without completing the payment ( just looking at the UI)
Mean while someone else buy all 10 apples
first customer doesn't know about that because he is already in final payment page.
And he pays 40 $ for 8 apples
Transaction is fault because no apples left to deliver.
I am trying to integrate Stripe payment gateway to my marketplace platform and I could not find a solution for this kind of scenario.
Is there any feature in Stripe to handle this ? Like session timeout period ?
Or What is the standard way to handle this ?
Appreciate your help.

I don't know if this is still relevant!
But I had the same problem before. What I did is I start managing the sessions from the application side. So I have a stripe sessions table and I have a timeout, and status of the session. Also, I have a purchase table with a status that could be pending if the user didn't pay yet. So I can update the items counts in the real store.
This is the scenario I have implemented. It might help you or anyone who is thinking of this problem. Maybe there is a more perfect scenario but this works for me :v:
User presses on pay
The application makes a POST request to your application create session endpoint, with all needed information
In the backend, check if this user has an active session with the same information, if yes just redirect him to that active session id. If no just create another stripe session, record its info in your database and redirect the user to the new session id
Then add a purchase record with the amount/quantity the user is attempting to get (with status = pending) and the session id you have. Then update the items page and subtract this quantity...
Create a webhook with that session id. So you can know if it is done or not (you have to have an endpoint that accepts session ids)
You check your active sessions periodically (cronjob) if a session is too old (like one hour) you just delete it and delete the pending purchase then update the items count in your store back to the actual count.
And when stripe calls your webhook with the required events, you can now set the session status and purchase status to done (Don't forget to check the call signature for more security)
I hope this will help you.

Related

Stripe create Subscription with payment method in one go instead of two

for my subscription based product I want to have a possibility to subscribe and enter payment details at once with stripe and struggle with that with the api.
In https://stripe.com/docs/billing/subscriptions/build-subscriptions?ui=elements I see an option to create a subscription with payment_behavior='default incomplete' and then enter the details to confirm the payment intent. So far so good. However if I create the subscription like that even before the customer confirms payment details stripe already generates an invoice which is not really what I want before final confirmation by customer.
Options I see:
create setupintent, have this filled by customer via elements and then have the customer subscribe. Technically works nicely but for a sales and customer perspective is not good as it has two steps thus probably reduces conversion.
create the subscription in the background before final subscription confirmation by customer and use the clientsecret of it to pass back to browser and then have customer enter his payment data and submit that and finish the setup of subscription and payment info. Technically works - however I realize that when I create the subscription to get the clientsecret to pass to elements before the customer enters his payment data and confirms the subscription the subscription is not only created but an invoice too - which would be really, i.e. an invoice created before customers really confirms the contract
create setupintent and submit it via elements and in metadata of it add the info of product that customers wants so that when the paymentmethod gets created and I get webhook event I do the booking of the product given in metainfo. May however mean the customer gets to success page but the webhook has not notified yet and thus the customer is not really subscrubed at the point in time but gets a success message he is
same as 3 except do not pass info via metadata but via successUrl parameters which refers to and endpoint at my backend which upon being called after setupintent was setup will do the subscription and then redirect to my frontend which shows success page. That seems like a error prone workaround however.
Create a workflow which is a 2 step sign up and asks for paymentinfo, sets that up and then brings customer to a final confirmation page where the submit triggers subscription creation. Seems a bit complicated from a user flow, but so far probably the best option?
Any better options?
Cheers
Tom
ps: Interestingly enough on discord stripe support told me #2 is the way to go - find it hard to believe ...
As far as I know, there isn't a workaround for this unfortunately. It is just how Subscriptions API is designed by Stripe. You can learn more about that here where they talk about "how subscriptions work".

Stripe Elements - Payment Updates Database

I am currently integrating Stripe Elements into my ReactJS app. What I am developing is a system in which my users can upload an image to display as an advertisement on my web app for 30 days. This means that a payment needs to update a row in my database with a new expiration date. We are also having the users manually renew each expiration period so we are not using subscriptions.
From what I understand, the flow is as follows for a first time customer:
User goes to the advertisement upload page
The user submits the advertisement form. Client sends POST request to my API server and creates payment intent with NodeJS Stripe SDK
Advertisement is saved into DB with an expiration date of null.
Payment Intent ID is saved to relationship table associating it with the banner
advertisement
Payment Intent secret is sent to client with status OK
Client Secret is given to Elements to show and handle the payment form
Stripe sends the event to my webhook endpoint with Payment Intent ID.
Use Payment Intent ID to find which banner advertisement should be updated with new expiration date
From what I've read on the docs, this flow should work. If anyone notices issues, please let me know!
My question is: can I show the user their next advertisement expiration date right after their purchase? Or do I need to show them "Pending" until my webhook receives the event?
Thanks in advance for any answers or advice!
You can, but whether or not you should is primarily a business decision for you to make based on the customer experience you're hoping to achieve.
It will likely be influence by the exact integration path and payment method options that you're offering. If you're going to use the Payment Element with delayed notification payment methods, then you may want to wait for confirmation that the payment was successful.
https://stripe.com/docs/payments/payment-methods#payment-notification
But if you're using the Card Element(s) and only accepting cards, then part of the response from confirmCardPayment is the Payment Intent if the payment was successful so you have a more immediate indicator of success.
https://stripe.com/docs/js/payment_intents/confirm_card_payment

With paypal REST API V2 if payer does not complete the payment, what is the best way to implement retry payment feature?

I am quite new to PayPal rest API and wanted to provide user with a way to retry payment option in case user does not continue or cancel from the PayPal approve URL. Should I create a new order altogether and get a new approve URL or is there a way to retry payment for an old order in 'CREATED' OR 'APPROVED' state?
An order is valid for 72 hours from the moment it is created, and for 3 hours once loaded in a PayPal checkout for approval.
If a user abandons it and is going to restart their checkout on your site, it's generally best to forget about the old order and generate a new one. You can specify a unique invoice_id for orders to prevent any accidental duplicate payments (by default the PayPal account will only allow one completed payment per invoice ID)
Rather than redirecting away from your website to PayPal for approval, for modern websites it's best to keep the user on your site, and have them approve the payment in an in-context experience/lightbox, which also has the option of expanding a credit card form right within your website. See the demo at https://developer.paypal.com/demo/checkout/#/pattern/server

With stripe Checkout, how do I keep track of the payment status

In the stripe documentation, it says:
So in this case, the checkout page goes to the success or failed page on my frontend.
I use the backend to track the payment status so that we can monitor the transactions in the admin portal, and the above approach seems dangerous to me.
When checkout is successful, it redirects the window to the success url. This means I have to call the backend API in the success page to update the payment status. However, the stripe is the source of truth about the payment status, and the status update on DB should come from Stripe, not come from a frontend page. At the very minimum, if a user refreshes the success page, it would have called the API again and again which is bad. Also, it is about "a user says I paid successfully" v.s. "Stripe says they paid successfully".
I tried the Stripe webhooks, but in the webhook data object, there is no information that I can use to link it to the sessionId that is generated from creating the checkout session, but the session id is the only tracking id I can get from Stripe about a payment.
What's the best practice, if Checkout is the only solution, to securely update my database?
You have 2 options:
Rely on webhooks. The checkout.session.completed event will describe a Checkout Session which contains its ID, which you hopefully saved when you created the Session earlier so you can link the two together.
Retrieve the session ID from the success URL once the payment is complete and retrieve the Session on your server, then check the Session's payment_status. This way your server can verify if the payment was actually completed or if someone just managed to guess the URL of your success page.
Stripe doesn't recommend only doing option 2, as it's very possible that users close the browser tab or window before the redirect to your success page can happen, resulting in a possible loss of payment confirmation. You should always use webhooks instead to guarantee your purchase fulfillment logic correctly fires.
You can get Stripe Payment status or session Details by session_id on asp.net core || .Net 5
var service = new SessionService();
Session session = service.Get(yourSessionId);
// You can track :-
session.Id;
session.PaymentStatus; // Paid or Unpaid
session.Status;
session.Mode;
//And more

Booking Engine Payment Gateway Logic

I am developing a booking engine in node js & Parse for a hotel website. In this I am checking for availability twice. Once when user fills all booking details and other before going to payment gateway. The payment gateway (CCAvenue) has success and cancel URL where they post data as per users behaviour. But the problem here is that if the tab is closed by the user there is no event called by the payment gateway. I can open this payment gateway page in new tab. But still I want the booking id of the booking cancelled due to tab close.
NOTE: I am creating booking with PENDING status and updating the status to ACTIVE when payment is successful.
The simpler answer is to update to PENDING status and also a "Pending Expire DateTime". Make this whatever works for your business. Maybe 1 Hour.
Then if they have NOT posted a payment successfully within one hour then you change the PENDING to "FailedDeposit" and allow the room to be booked again.
Make sure your user is aware of that they have to pay deposit and do NOT give them a confirmation until after the payment is received. The user doesn't need to know that you are holding the room for them. They should believe that they are not confirmed until they pay.

Resources