3DS Helper
Overview
The 3DS Helper is the module in Chargebee.js that runs 3-D Secure authentication flows for you. Pass it any of the following and it takes the payment from there:
- A Chargebee temporary token, obtained through Card Components
- Tokenized card details
- A permanent token (reference ID)
- Raw card details
Any of these can go to the handleCardPayment function.
Why 3DS matters
Under the revised Payment Services Directive (PSD2), Strong Customer Authentication (SCA) requires customers in Europe to perform additional authentication when they submit their card details.
3-D Secure (3DS) authentication is one reliable way to verify a customer's authenticity. 3DS 2.0 sends the customer's device ID to the issuing bank, which verifies authenticity and gives a frictionless checkout experience. In some scenarios the issuing bank asks for more proof before it validates the transaction, and the customer goes through a 3DS verification flow.
If the issuing bank doesn't support 3DS 2.0, the customer authenticates through 3DS 1.0 instead — a redirection flow that opens a new authentication window and asks for a password.
How to be SCA-ready
- If you collect card details through Chargebee's Checkout and Self-Serve Portal, implementing 3DS at the gateway level is enough.
- If you collect card details through Card Components, follow one of the recipes on this page to support 3DS in your checkout flow.
- If you collect raw card details yourself and create subscriptions or payment sources directly through the APIs, the 3DS Helper takes care of the 3DS flows for you.
Advantages
- Every gateway ships its own JS for 3DS, but Chargebee.js is tailor-made for subscription businesses.
- If you already collect card details with a gateway's JS, Chargebee.js coexists with it and handles only the 3DS authentication.
- Chargebee.js supports every 3DS-capable gateway in Chargebee, so you can route a payment through your preferred gateway for each currency and still run the 3DS flow.
Recipes for using 3DS
Which recipe you use depends on how you collect card details, and each one carries a different PCI compliance effort.
Using Card Components
Note
PCI compliance effort: low. You are eligible for SAQ-A with this approach.
Either of the two recipes below works when you collect card details through Card Components.
Frontend only
This recipe completes the entire 3DS flow on the frontend.
- Capture card details with Card Components.
- Request a Chargebee temporary token.
- Set up the 3DS Helper.
- Call
handleCardPaymentto start the 3DS flow.
Supported gateways: Bluesnap, Braintree, Cybersource, Ingenico Direct, Mollie, Razorpay, Stripe, and Worldpay.
Support for the Adyen gateway
To run 3DS through Adyen while using Card Components, use the authorizeWith3ds method.
If the 3DS overlay appears on frictionless flows after you call authorizeWith3ds, see Why does the 3DS popup appear on every payment when using Adyen? for the fix.
Warning
Chargebee.js does not support payments through the in-app browsers of Instagram, Facebook, and Snapchat for Mollie and Razorpay.
Everything on the frontend except payment intent creation
- On the frontend, capture card details with Card Components.
- On your server, create a payment intent for the customer and pass it to the frontend.
- On the frontend, begin the 3DS flow with that payment intent.
Supported gateways: Adyen, Bluesnap, Braintree, Checkout.com, Cybersource, Ingenico Direct, Mollie, Razorpay, Stripe, Worldpay, and Bank of America.
Using the gateway's hosted fields
Either of the two options below works when you collect card details through the gateway's hosted fields.
Tokenize using Chargebee.js
Note
PCI compliance effort: low. You are eligible for SAQ-A with this approach.
On the frontend:
- Collect card details with gateway hosted fields such as Stripe Elements or Braintree Hosted Fields.
- Set up the 3DS Helper.
- Call
handleCardPaymentto start the 3DS flow, passing the gateway hosted field object aspaymentInfo.elements.
Supported gateways: Stripe (Stripe Elements), Braintree (Braintree Hosted Fields), and Adyen (Adyen Hosted Fields).
Tokenize using the gateway's JS
Warning
PCI compliance effort: medium. Check with your payment gateway to evaluate the compliance effort this approach needs.
On the frontend:
- Collect card details on your frontend.
- Set up the 3DS Helper.
- Call
handleCardPaymentto start the 3DS flow, passing the gateway's tokenizer function aspaymentInfo.tokenizer.
Supported gateways: Stripe and Braintree.
Using a permanent token
Warning
PCI compliance effort: medium. The effort is low while you use permanent tokens. However, if you handle card data yourself when generating a permanent token for the first time, the compliance requirements are high.
Use a permanent token already in your system for card information stored earlier.
- On your server, create a payment intent with the reference ID as input, and send the payment intent to the frontend.
- On the frontend, set up the 3DS Helper, set the payment intent, and call
handleCardPaymentwithout thepaymentInfoparameter.
Supported gateways: Adyen, Bluesnap, Braintree, Cybersource, Ingenico Direct, Mollie, Razorpay, Stripe, and Bank of America.
Collecting raw card details
Warning
PCI compliance effort: high. This option needs the highest compliance effort. Check with your payment gateway for details.
Collect raw card details in your checkout and pass them to the 3DS Helper to run the 3DS flow. On the frontend:
- Collect raw card details in your checkout.
- Set up the 3DS Helper.
- Pass the card details to
handleCardPaymentaspaymentInfo.card.
Supported gateways: Adyen, Bluesnap, Braintree, Checkout.com, Cybersource, Ingenico Direct, Mollie, Razorpay, Stripe, Worldpay, and Bank of America.
Integrate 3D Secure
Set up Chargebee.js first, then follow the steps below.
Load the 3DS Helper module
Use load3DSHandler to load and initialize the module, then use the returned threeDSHandler to start the 3DS flow.
let cbInstance = Chargebee.getInstance();
cbInstance.load3DSHandler().then((threeDSHandler) => {
// your code here
});Create the payment intent
Create a paymentIntent on your server with the create a payment intent API and return it to the client. The 3DS handler uses it internally to perform the authorization.
When you create the payment intent, specify the amount to charge the customer. You can also choose the gateway to use for the charge; if you don't, smart routing rules apply.
Use the update a payment intent API to change the amount before the intent is consumed, which happens when tax is applied or the customer enters a discount coupon.
To authorize a stored payment method, pass the amount and the payment method's reference ID when you create the payment intent.
Note
If there is no immediate charge, specify a default amount, which is gateway-specific. This amount is returned to the customer after verification.
Set the payment intent on the handler
On the client, set the payment intent on the 3DS handler with setPaymentIntent.
function createPaymentIntent() {
return fetch("/payment-intents", {
method: "POST",
})
.then((response) => response.json())
.then((response) => response.payment_intent);
}
createPaymentIntent().then((paymentIntent) => {
cbInstance.load3DSHandler().then((threeDSHandler) => {
threeDSHandler.setPaymentIntent(paymentIntent);
// Update the paymentIntent whenever the amount changes.
threeDSHandler.updatePaymentIntent(paymentIntent);
});
});See the setPaymentIntent reference for the supported parameters.
Handle card payments with 3DS
3DS for a new card
When the customer checks out after entering their card details, call handleCardPayment to start the 3DS flow. See the handleCardPayment reference for the full list of parameters.
threeDSHandler.handleCardPayment(
{
card: {
firstName: "First Name",
lastName: "Last Name",
number: "xxxx xxxx xxxx xxxx",
cvv: "",
expiryMonth: "10",
expiryYear: "2030",
},
additionalData: {
// Pass additional information to improve the chances of a frictionless transaction.
},
},
{
change: function (intent) {
// Triggers on each step transition.
},
success: function (intent) {
// Triggers when the card is 3DS authorized.
},
error: function (intent, error) {
// Triggers when 3DS authorization fails.
},
}
);3DS for an existing card
Specify the payment method's referenceId when you create the payment intent, then call handleCardPayment without any additional parameters.
threeDSHandler
.handleCardPayment()
.then((intent) => {
// Call the update subscription API or the collect now API.
})
.catch((error) => {
// Handle the error.
});Use the authorized payment intent
Once the 3DS flow completes, the returned paymentIntent is in the authorized state. Use its ID to create a subscription, add a payment source, or collect payment for an unpaid invoice that failed because of 3DS.
To implement the RBI mandate with an authorized payment intent:
- Create a payment intent for the actual subscription amount, which you can get from the Estimate API.
- Set the
mandateobject if the mandate needs to be created. - Use the authorized payment intent to create the subscription, so that the mandate is associated with it.
Note
If you use payment_intent to add a payment_method at the customer level separately, and then create a subscription with the existing payment_method outside the payment intent flow, the mandate is not associated with the subscription.
3DS with challenge URL redirection
handleCardPayment can also give you the challenge URL without presenting the challenge window to the customer automatically. In this workflow, you present the challenge URL yourself in an iframe or a popup window.
Access the URL by implementing the challenge callback in handleCardPayment. The transaction only proceeds in this workflow if the callback is implemented.
When the customer closes the challenge window, call the cancel method to cancel the ongoing transaction. This refuses the payment attempt, and the handleCardPayment call is rejected with an authentication-failed status.
Adyen, Braintree, and Stripe support this workflow.
Examples
Was this article helpful?