Hmmm ... imagine that a client pays for a subscription, the payment is successful on Stripe (via Cashier), it returns a success response to the application, but for some problem the webhook isn't processed correctly by the application and the subscription isn't stored in the database.
In this case, I have checked in Stripe, the webhook is considered having been processed correctly by Stripe, I don't find anywhere in Stripe that Stripe will retry to send trigger the webhook.
for some problem the webhook isn't processed correctly by the application and the subscription isn't stored in the database
There is no reason for Stripe to resend the webhook if it received a successful response; you will need to work out why the webhook was not processed correctly in your application! In the meantime, consider storing (in your apllication) the full webhook payload for such important webhooks as payment_success, so that you can replay the event listener logic if needed.
it returns a success response to the application, but for some problem the webhook isn't processed correctly by the application and the subscription isn't stored in the database.
In this case, I have checked in Stripe, the webhook is considered having been processed correctly by Stripe, I don't find anywhere in Stripe that Stripe will retry to send trigger the webhook.
@vincent15000 Stripe’s not going to retry sending the webhook if your application has told Stripe everything was fine. You either need to:
Store the webhook message on a queue so that you get visibility if processing it fails, and you can retry it.
Not tell Stripe everything was OK if everything wasn’t OK and there was in fact an error or a problem.
@martinbean@tykus Thank you both ... hmmm ok I didn't thought about storing the webhook message in the database. I will try this to check if I can do something with it.
@martinbean Hmmm ... In the different documentations about Laravel Cashier and Stripe, I don't have seen anything about Stripe waiting for a response after having sent a webhook.
@vincent15000 They will retry, which is also a condition you need to handle. For example, they dont get your 200 although you processed the transaction ok. You need to handle them sending a duplicate transaction.
To be honest, I thought Cashier took care of this?
@Snapey Yes Cashier does this automatically, I don't need to send a response manually. I just want to imagine all possible scenarii in the case where some problem happens.
Hmmm ... In the different documentations about Laravel Cashier and Stripe, I don't have seen anything about Stripe waiting for a response after having sent a webhook.
@vincent15000 I don’t really understand what you mean?
The way webhooks work is:
Something happens in Stripe.
Stripe sends a POST request to your configured webhook endpoint(s) with an event describing the change.
If your server responds with a 2xx status, Stripe assumes the webhook was delivered (and processed) correctly and won’t retry.
If your server responds with a 4xx or 5xx error status, Stripe will keep re-trying to send the message until it gets a 2xx response.
So if your application is responding with a 2xx status (even though there’s an error), Stripe’s basically going to go, “A 200? All good. We’re done” and not re-send the message again.
So again, you need to detect and handle errors better. You can either just marshal the webhook event into a queue that your application can then attempt to process (and notify you of any errors). Or, you need to ensure exceptions are bubbling up and making your application return a 4xx or 5xx response, so that Stripe goes, “Oh? There was a problem? No worries, we’ll try re-sending the message again in a few minutes.”
@martinbean Sorry, yes the webhook works so. I'm using Cashier and I think that Cashier does all this for me under the hood.
But for some reason, perhaps a webhook won't be processed by the application.
I explain : last week I wanted to test something with Cashier and Stripe on the application, but I forgot to execute the listener locally and the webhook wasn't processed locally, Cashier sent back 200, but the subscription wasn't stored in the database.
I don't want to have this situation in production. So I just want to prevent from such a situation.