Strong Customer Authentication
Strong Customer Authentication, or SCA, is part of the the Revised Payment Services Directive (PSD2). The SCA is a new requirement for authenticating online payments and will be mandatory in Europe from the 14 September 2019. The goal is to reduce the risk of fraud and make transactions more secure.
If you want to learn more about SCA, please read this excellent article from Stripe: Strong Customer Authentication
SCA will ONLY apply to transactions where both the business and the cardholder’s bank are located in the European Economic Area.
Let's look at how to save a payment method before an order is complete. The benefit with this approach is that SCA re-authentication is triggered on card save while the user is in-session, and is completely handled by Stripe.
For example purposes we are showing the code snippets in javascript. Your setup of Stripe.js and Elements should look something like this:
<!-- Card element which will show the prebuilt Stripe elements UI component-->
<div id="card-element"></div>
/* You will find the YOUR_STRIPE_PUBLISHABLE_KEY key on our dashboard,
on the settings view, in the Stripe payment provider block.
*/
const stripe = Stripe(YOUR_STRIPE_PUBLISHABLE_KEY);
let elements = stripe.elements();
let cardElement = elements.create('card');
// Mounting the component above
cardElement.mount('#card-element');
let cardholderName = document.getElementById('cardholder-name');
let cardButton = document.getElementById('card-button');
Create a Payment Method, sending just the
payment_method
attribute to stripe
. This will return an empty payment method with a generated Stripe setup intent secret.fetch('/payment_methods', {
method: 'POST',
body: {
payment_method: 'stripe'
}
}).then(function(emptyPaymentMethod) {
// response contains the setup intent secret needed to handle card setup with Stripe
});
Send the setup intent secret to Stripe on card setup. If the users bank requires re-authentication, it will be handled in this step by Stripe.
// Triggers when the user has finished typing their card details
cardButton.addEventListener('click', (ev) => {
// https://stripe.com/docs/stripe-js/referece#stripe-handle-card-action
stripe.handleCardSetup(emptyPaymentMethod.setup_intent.client_secret, cardElement)
.then(function(stripeResponse) {
// Handle stripeResponse.error or stripeResponse.setupIntent
});
});
Update the empty payment method in our API with the returned Stripe payment method id.
fetch(`/payment_methods/${paymentIntent._id.$oid}`, {
method: 'PUT',
body: {
payment_method_id: stripeResponse.setupIntent.payment_method
}
}).then(function(fullPaymentMethod) {
// Contains the fully populated payment method (retrieved from Stripe on the backend)
});
To ensure that your solution is SCA ready, remember to test it out using the Stripe regulatory test cards and look at the chapter below to implement the error handling you need for your use case.
Implementing proper flows to handle SCA related errors is crucial! The bank might require re-authentication of a payment method at any time, so these errors should always be handled. We explain the two possible SCA related errors below.
Case: While trying to pay for an order on a client, we get an error notifying us that re-authentication is required
Solution: We will return an error with the status code 422 if a payment requires further authentication from the bank. The API response will contain the payment with these three properties in the metadata:
Using the
payment_intent_id
and intent_client_secret
, you need to confirm the payment using the Stripe SDKstripe.handleCardAction(payment.metadata.intent_client_secret, cardElement)
.then(function(stripeResponse) {
// Handle stripeResponse.error or stripeResponse.paymentIntent
});
Case: While trying to charge a customer for a recurring subscription, the bank notifies us that the payment needs to be re-authenticated.
Solution: BuiltOn API will trigger a specific Webhook,
payment.requires_auth
, every time the subscription charge needs to be re-authenticated. You will need to handle the flow to ensure that your customer's card is re-authenticated. This could be handled by sending an email or a push notification to your customer notifying them on that a payment needs to be re-authenticated. Have a look at our SCA confirm payment page example to get a better understanding of the flow required to re-authenticate a payment (or just clone and copy our example!).Make sure you created a Webhook listening to the event:
payment.requires_auth.
The event will contain all the parameters you need to re-authenticate an off-session payment.Once the customer has re-authenticated the payment, you will be able to effectively charge them by calling our API route:
POST /payments/<payment_id>/confirm
with thepayment_intent_id
and the payment_client_secret
properties in the body.POST /payments/<payment_id>/confirm HTTP/1.1
Content-Type: application/json
X-Builton-Api-Key: <builton-api-key>
Host: api.builton.dev
{
"payment_intent_id": "set_payment_intent_id",
"payment_client_secret": "set_payment_client_secret"
}
Last modified 2yr ago