- Issue created by @nicolas bouteille
So far, we are displaying the message of any kind of error returned by Stripe to our clients.
I think we should not.
We should differentiate expected errors from unexpected ones.
An error such as a declined credit card is an expected error. We can handle it, display a comprehensive error message to the user (the default one provided by Stripe), and let them retry. All fine. We don't even need to log this as an error in our logs, maybe a warning for traceability... ?
But there are other kind of errors that can happen. The ones that are not supposed to happen but we did not think about. Unexpected ones.
Those errors are not the client's responsibility. We should not display such error message to the client:
The client_secret provided does not match the client_secret associated with the PaymentIntent.
If such an error occurs, I actually believe we should log the error (we did so with a custom ajax callback that logs messages), display a generic error message letting the client know something went wrong on our side and they should not try again right away. We should not even display the submit button again.
Fortunately, Stripe provides an error.type and explains that errors of type 'card_error' and 'validation_error' can be displayed to the customer as is. They are our expected errors...
https://stripe.com/docs/js/payment_intents/confirm_payment (see the Return section)
All other errors can be considered as unexpected errors. We should not display their message as is, but a generic error message instead, log them to the system, and the client should not be encouraged to try again.
Actually there is one exception though for the 3DS authentication failure that is unfortunately an error of type invalid_request_error (I don't know why...) and that is an expected error that we should display as is to the client and let them try again.
Last but not least, there can be even bigger errors that make the Promise to never even resolve. Try for example to forget the 'elements' or 'clientSecret' parameter and this will result in this error:
IntegrationError: stripe.confirmPayment(): expected either `elements` or `clientSecret`, but got neither.
But since the Promise does not resolve, here is how we can handle this kind of error:
stripe.confirmPayment({
clientSecret: settings.clientSecret,
confirmParams: {
return_url: settings.returnUrl,
}
}).then(function (result) {
if (result.error) {
// handle error sent by Stripe
if (error.type === 'card_error' || error.type === 'validation_error') { // expected errors
}
else {
if (error.code === "payment_intent_authentication_failure") { // expected error even though of type invalid_request_error
}
else {
// unexpected errors
}
}
}
}, (error) => {
// handle bigger error
});
what do you think?
Active
1.1
Payment Element