Stripe SCA

When using Stripe, Payment Intents give you the ability to handle Strong Customer Authentication

Integrating Stripe's 3-DS goes a little bit further than just using billforward-js for capturing cards.

Do I need to worry about Strong Customer Authentication?

If you're doing business in the EU or have any customers with credit cards issued by EU-based banks then you might not be able to collect payments from those customers if SCA requirements are not met from your side. Meeting those requirements from your side is essentially supporting 2-FA for credit cards during card capture process.

 

Refer to Stripe's documentation about Setup Intents or their API docs for the SetupIntent object for more insight on how this works on the Stripe's end.

How to implement it if I'm currently using BillForward-js?

  • Upgrade to the latest version (v6+)
  • Add Stripe.js V3 to your page e.g. <script src="https://js.stripe.com/v3/"></script>
  • If you're using BillForward.captureCard() method then add "requires-setup-intent": true to the object that you're passing to that method, e.g.: BillForward.captureCard({..., "requires-setup-intent": true})
  • If you're using BillForward.captureCardOnSubmit() then you need to add a hidden input tag: <input type="hidden" bf-data="requires-setup-intent" value="true" />
  • Add a callback (4th parameter for both of those methods mentioned above) that will be called once the initial card setup is done, we will need to do the 3-DS confirmation after that.
  • In your callback you'll get the resulting data that contains the captured card, as the first parameter (let's call it data). You should be able to access a string value at data.additionalData.setupIntentStatus which will be either requires_confirmation, requires_action, or succeeded . We're only interested in the first two - if we get any of those this means that we need to invoke the confirmation procedure.
  • Next we can confirm the SetupIntent by calling Stripe's handleCardSetup(data.additionalData.setupIntentClientSecret) method. Doing this will open a new popover (modal) window inside your page where the customer will be able to go through their bank's 3-DS flow.
  • Once the SetupIntent is confirmed the only thing left is to let BillForward know that the card in question has its setup intent confirmed, which can be done by calling BillForward.stripeVerifySetupIntent(data.id, [(data, error) => console.log(data, error)])

How to implement this if I'm not using BillForward-js?

  • Make sure that you're using Stripe.js V3 (<script src="https://js.stripe.com/v3/"></script>)
  • When you make the /v1/tokenization/auth-capture API call to BillForward to save the card, add requiresSetupIntent: true to the request.
  • In the response you'll get SetupIntent's client secret which you'll need to use in order to confirm the SetupIntent: var intentSecret = captureResult.results[0].additionalData.setupIntentClientSecret;
  • You only have to confirm the SetupIntent if its status is requires_confirmation or requires_action :
if (captureResult.results[0].additionalData.setupIntentStatus === "requires_action" ||
captureResult.results[0].additionalData.setupIntentStatus === "requires_confirmation") { ... }
  • Call Stripe's confirmCardSetup(intentSecret)
  • And let BillForward know once the SetupIntent is confirmed:
var paymentMethodId = captureResult.results[0].id;
confirmCardSetup(...).then(intentResult => {
$.ajax({
type: "POST",
url: "https://app-sandbox.billforward.net/v1/payment-methods/"
+ paymentMethodId + "/verify/stripe-setup-intent" + "?"
+ $.param({ access_token: bfAPIKey }),
data: JSON.stringify({}),
contentType: 'application/json',
crossDomain: true,
async: true
})
});