Strong Customer Authentication

What is SCA?

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.

How to use our Payment Methods API and Stripe with SCA

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:

1. Setup Stripe.js and Elements

<!-- 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');

2. Create and save a payment method

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
});

3. Use the setup intent secret with your Stripe card setup

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
    });
});

3. Update payment method

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.

In-session order payment requires re-authentication

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 SDK

stripe.handleCardAction(payment.metadata.intent_client_secret, cardElement)
  .then(function(stripeResponse) {
    // Handle stripeResponse.error or stripeResponse.paymentIntent
  });

Off-session subscription payment requires re-authentication

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.

Confirm Payment after successful re-authentication

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_idand the payment_client_secretproperties 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 updated