- Issue created by @Nicolas Bouteille
- 🇫🇷France Nicolas Bouteille
After digging a little bit more into that topic, this is what I think I understand:
Stripe.php (ie Card Element) executes the payment in ajax in commerce_stripe.review.js using stripe.handleCardPayment(). Only when this ajax call is over, form.submit() is called which I assume goes to the next checkout step PaymentProcess which calls $this->createPayment in order to create the Commerce Payment inside the database. A few lines below, $payment_gateway_plugin->createPayment($payment, $this->configuration['capture']) calls Stripe.php->createPayment() and eventually the order will be placed / completed.
StripePaymentElement.php (Payment Element) executes the payment in ajax as well in commerce_stripe.payment_element.js using stripe.confirmPayment({}) when choosing a new payment method. stripe.confirmPayment uses a return_url parameter that will redirect to PaymentCheckoutController->returnPage() which will call StripePaymentElement->onReturn() to create the payment method in our database and then call $checkout_flow_plugin->redirectToStep($redirect_step_id); to make us reach the PaymentProcess step, etc.
Back to commerce_stripe.payment_element.js, in case we've selected a stored credit card, we fire stripe.confirmCardPayment() that does not need a return_url since we don't need to create the payment method afterwards because it already exists. Instead $form.submit(); makes us go to the Payment Process step.
Conclusion: in all these situations, if the customer's session gets killed after the ajax call of stripe.handleCardPayment(), stripe.confirmPayment({}) or stripe.confirmCardPayment(), and we never reach the PaymentProcess step, no information about the successful payment is stored inside the database, and the order never gets completed either.
To prevent this type of scenario from happening, we can / should plug Stripe's events to custom webhooks / api endpoints / urls instead.
https://stripe.com/docs/payments/accept-a-payment-deferred?platform=web&...
https://stripe.com/docs/webhooks
With this solution, even if the user session gets closed right after the ajax payment, Stripe would still communicate with our website and we would still be able to finalize the order no matter what.
Disavantage: for local testing, I guess this requires to have a local url accessible from the outside using something like ngrok.What do you guys think?
- 🇫🇷France Nicolas Bouteille
Because this is issue is too long, I'll just keep it a support request and we could create a cleaner, shorter, separate feature request...