Is it possible to receive a Stripe Webhook for a payment event before I can hit my servers controller to finish processing? - stripe-payments

In my app, on the client side, I'm calling Stripe's "confirmCardPayment()" to finish the purchase. When the result comes back I take the result, if successful, and then call my server controller to finish the processing (DB entry).
QUESTION - Would it be possible to confirm the payment on the client side with Stripe and then receive the Stripe Webhook on the server side before I have time to post back to the controller to finish the payment processing? Or put another way, is the Webhook sent immediately or does it wait for some time before it's sent to the endpoint?

Stripe does not guarantee delivery of events in the order in which they are generated. You can read about it in more detail here : https://stripe.com/docs/webhooks/best-practices#event-ordering
You would want to always rely on the webhook to update your database or execute business logic as relying on requests triggered from the browser isn't reliable. E.g. Your customer could close the browser after the payment is authorised but before you are able to post to your server to update your database.

Related

How to process payment on the backend side using Stripe?

I am new to Stripe and payments in general. I've found few articles on the internet with the examples and guidelines eg. this one. As i noticed the algorithm for creating the payment looks like this:
Client app fetches the publishable Stripe key from the server
Server application creates the checkout session, client app fetches the checkout session id using retrieved publishable key
Client app redirects to checkout
User finishes the payment and being redirect back to client app
Please correct me if i'm wrong. In general i don't understand one thing - how the server application knows that the payment is completed successfully or not? Should i redirect the flow from stripe checkout to backend first, process the result and the from the backend call the frontend again? Or should i somehow use the checkout session to check has it been completed? Shall i use some kind of cron then to process pending checkout sessions? Thanks in advance for any help. Regards
Basically, what you lay out is viable. You can check the Session status when the client is directed back to your server, but you will want to check this status at least one other way, either via a webhook or the cron job you mention.
Should i redirect the flow from stripe checkout to backend first, process the result and the from the backend call the frontend again?
This is possible. Stripe allows you to add the {CHECKOUT_SESSION_ID} template parameter to your Checkout's success URL, when the user is redirected after their checkout, that template will be replaced with the actual Checkout Session ID which you can use to retrieve the Session and its status.
That being said, it is possible for a Customer to make a payment but have their connection cut out before navigating back to your page. So, if you rely on that redirect the customer will be charged but you will never know to fulfill their order. That leads to unhappy customers so Stripe typically recommends setting up a webhook endpoint on your server[2] so that they can send you a checkout.session.completed event to notify you that the customer has finished their Checkout Session. That way, even if a customer never gets to your success page, you will know to fulfill their order.
[1] https://stripe.com/docs/payments/checkout/custom-success-page#modify-success-url
[2] https://stripe.com/docs/payments/checkout/fulfill-orders

Is there a way to get a response back from Stripe API webhooks?

I am currently working on a React website and NodeJS API that implements the Stripe API to allow payments. The user can subscribe to 3 different plans and get different access depending on the chosen plan.
I have already set up the webhook endpoint URL in my stripe account and there is no problem about that. I am getting webhooks and I manage my database depending on the event type.
My problem is that I want to update my frontend as soon as a payment succeeded for example when the invoice.payment_succeeded is triggered. But the fact that this is a webhook to a POST route, I can not send back a responses to my client. I was wondering if there is actually a way to send back data after a webhook.
Thanks to anyone who can help me.
Implement a web socket connection.
send data to the web socket as soon as you receive invoice.payment_succeeded from the webhook.
implement socket client in the react app to listen to the data send from the 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

How do I Notify the Client when a Payment Systems sends a Request to my API callback URL?

I'm currently building a website with Vue.JS as my static frontend and writing a separate backend API hosted in the cloud using Node and Express.
Currently, I want to integrate payments with a payment provider called Swish. The way this API works is that a payment request is issued from the client with a Callback URL that Swish calls when the payment Errors or is Paid. This URL will be a post request to my API. I want to know how the "Create Payment Request" can asynchronously wait for the post request to be issued by my payment provider so that it returns when Swish (payment provider) is done processing the payment and I can then update the status of the payment in Vue to the user.
I haven't managed to solve this without polling yet. A simple solution would be to have the Post request that Swish visits update some state in my SQL database and have the "Create Payment Request" wake up every 10 seconds or so to check if the database has been changed. Is there a way to do this without polling? Could I somehow emit some event to wake up a sleeping Express endpoint from another Express endpoint? Or could I pass to the callback URL some webhook or something so that the Swish callback can directly notify my Vue frontend when it's called?
For timescales, it takes a maximum of 3 minutes for Swish to call the callback URL.
I think Websockets should work for your problem. As you already said you should persist the state of the payment in your database. When the Swish app calls your callback url you send an websocket request with the new state and needed information. The state is needed when the websocket connection is recreated due errors in the communication.
Some links which may be usefull:
websockets/ws
nathantsoi/vue-native-websocket
sockjs/sockjs-client
stomp-js/stompjs

Stripe and validate payments synchronously

I am integrating Stripe in my site and I have the following question. I have read in the official documentation that is needed to use Payment Intents / Checkout to accomplish with 3d secure payments but my doubt is: How can I validate a payment made through this methods in a synchronous way to allow customers to instant download a product without waiting to the webhook call?
I am using Symfony to build the front and the back of the system.
thanks
You don't need to wait for a webhook to get confirmation that a payment was successful. stripe.handleCardPayment will immediately tell you if the payment was successful or not. See the then promise fulfillment here.
If you're using new Checkouts, users will be directed to your payment success page on completion of payment. A webhook is sent to inform you of the payment completion in case the user closes the browser or tab before the redirect can happen.

Resources