I'm testing a payment link application with the CLI. When I trigger a sandbox payment with:
$ stripe trigger checkout.session.completed
then my webhook code sees, in order:
1. payment_intent.created
2. charge_updated
3. product_created
4. price_created
5. charge.succeeded
6. checkout.session.completed
7. payment_intent.succeeded
8. payment_intent.created
9. charge_updated
charge.succeeded
and payment_intent.succeeded
both have a status of succeeded
. checkout.session.completed
has a payment_status
of paid
.
This is too much information: is there a single definitive statement that the money has been paid, and isn't in some state where it might not eventually be paid? Is it sufficient that charge.succeeded
arrived? The simplest test is that checkout.session.completed
has a status of paid
, but is this sufficient?
If you are using checkout session in payment
mode, you want to listen for checkout.session.completed
and checkout.session.async_payment_succeeded'
. The latter is relevant if you are using delayed payment method like ACH Direct Debit, which takes awhile to know whether the payment is truly successful. You might find this section in Stripe Doc helpful: https://docs.stripe.com/checkout/fulfillment?payment-ui=stripe-hosted#immediate-versus-delayed-payment-methods
Upon receiving the two events above, you'd want to check the payment status of the checkout session again to ensure it's paid: https://docs.stripe.com/api/checkout/sessions/object#checkout_session_object-payment_status
If you are creating subscriptions through Stripe Checkout, you can refer to the answer in this thread instead: Stripe Checkout webhook - which event to listen for