More Tutorials

3DS supported Adyen.js Integration with Chargebee APIs

Adyen
3D Secure
Product Catalog 1.0

Tutorial Scope

This tutorial will address the specifics of implementing card payments with 3D Secure flow and creating a subscription in Chargebee, using Adyen's Web Components, integrated through Chargebee.js and Chargebee APIs.

Adyen.js: Overview

Adyen is a payment solution that processes payments from all over the world. The card details are captured and tokenized on your side by Adyen's javascript library, and the token is sent to Chargebee. Learn more about Adyen documentation.

Adyen does not provide an option to retrieve the details of an object, which makes the integration process difficult. Also, Adyen requires you to set identifiers like unique transaction reference (Transaction ID) during the initial payment processing step, increasing complexity. Therefore, we have mandated the use of Chargebee.js helper function even if you want to use Adyen.js with Adyen Web Components to make the integration process more manageable and smoother. Without Chargebee.js, the integration will not work correctly.

We have implemented 3DS support for the latest version of Adyen.js using Chargebee.js 3DS helper module. If you are using Adyen's CSE (Client-Side Encryption), you need to adopt the latest version of Adyen.js to avail Chargebee's 3DS helper JS. To know more about versions in Adyen, see Adyen Release Notes filtered by version.

Alternatively, you can also integrate with Adyen using Chargebee’s Components and Hosted Fields. For more details, see Chargebee documentation. Refer to our 3DS helper JS implementation guide to rewire your Adyen.js integration and accommodate 3DS.

Overview

Here's a detailed overview of how the Adyen.js and Chargebee 3DS checkout flow works:

  • After the customer is led to the checkout page, Adyen web components are used to collect the card details of the customer.
  • When the customer submits the payment form, Adyen passes this information to Chargebee.js to perform the 3DS flow.
  • Chargebee uses the 3DS-verified token to create a payment intent.
  • When the payment intent is authorized, it is used to create a subscription in Chargebee using the create subscription API.

Prerequisites

Before trying out this tutorial, you need to setup the following:

  • A Chargebee account. Signup for a free trial if you don't have one.
  • Plans configured in Chargebee.
  • Adyen sandbox account integrated with your Chargebee user interface.
  • Adyen’s client key and API key
  • Your Chargebee test site's API key.

Client-Side Implementation

Step 1: Get available payment methods

Start by getting a list of the available payment methods of the customers based on their country, device, and payment amount. From your server, make a POST / paymentMethods request to Adyen to get a list of payment methods available, specifying:

  • Merchant Account - The merchant account name

  • Amount - The currency and value of the payment

  • Country Code - Customers country code. This is used to filter the list of available payment methods.

Request: Here is a sample request to get the available payment methods:

curl https://checkout-test.adyen.com/v67/paymentMethods \
-H "x-API-key: YOUR_X-API-KEY" \
-H "content-type: application/json" \
-d '{
  "merchantAccount": "YOUR_MERCHANT_ACCOUNT",
  "countryCode": "NL",
  "amount": {
    "currency": "EUR",
    "value": 1000
  },
  "channel": "Web",
  "shopperLocale": "nl-NL"
}'

Response

{
 "paymentMethods":[
  {
    "details":[...],
    "name":"Credit Card",
    "type":"scheme"
    ...
  },
  {
    "details":[...],
    "name":"SEPA Direct Debit",
    "type":"sepadirectdebit"
  },
  ...
  ]
}

Pass the response to your front end to show a list of available payment methods.

Step 2: Build the checkout form

Next, use the Adyen web components to render the payment method and collect the payment details of the customer. Install the Adyen Web Component's node package or use a <script> tag. Click Adyen's documentation to know more about the web components.

  • Include the script in the <body> above any other JavaScript in your checkout page. Use the script from Adyen documentation.

Sample Script

adyen_wc_3ds/index.htmlView full code
<script
  src="https://checkoutshopper-test.adyen.com/checkoutshopper/sdk/4.7.3/adyen.js"
  integrity="sha384-YiT4BfPwbplFwUnpDjm2rmWCvpzdi6+l+1E+J9JKTB3CYyKbbwJ8ghkUheQf79X9"
  crossorigin="anonymous"
></script>
<link
  rel="stylesheet"
  href="https://checkoutshopper-test.adyen.com/checkoutshopper/sdk/4.7.3/adyen.css"
  integrity="sha384-X1zQUhO5NGWdMQmDcuv2kyQK65QR7/VJtNthEImZm7jOvOEicQrnVijI0n9DcHkF"
  crossorigin="anonymous"
/>
<!-- Adyen provides the SRI hash that you can include as the integrity attribute.-->
<!-- Refer to their release notes to get the SRI hash for the specific version: https://docs.adyen.com/online-payments/release-notes -->
  • Create a DOM element on your checkout page, placing it where you want the payment method form to be rendered.
adyen_wc_3ds/index.htmlView full code
<div id="component-container"></div>
  • Create a configuration object with the below parameters and use that configuration object to create an instance of Adyen checkout. Then use the checkout.create to create and mount an instance of the payment method component. Check out configuration objects in Adyen.

OnSubmit, create a function handleChargebeeFlow(), use this function to pass in the tokenized card information to Chargebee.

adyen_wc_3ds/index.htmlView full code
function handleOnChange(state, component) {
  state.isValid; // True or false. Specifies if all the information that the shopper provided is valid.
  state.data; // Provides the data that you need to pass in the `/payments` call.
  component; // Provides the active component instance that called this event.
}

function handleOnAdditionalDetails(state, component) {
  state.data; // Provides the data that you need to pass in the `/payments/details` call.
  component; // Provides the active component instance that called this event.
}

const configuration = {
  locale: "en_US", // The shopper's locale. For a list of supported locales, see https://docs.adyen.com/online-payments/components-web/localization-components.
  environment: "test", // When you're ready to accept live payments, change the value to one of our live environments https://docs.adyen.com/online-payments/components-web#testing-your-integration.
  clientKey: "<ADYEN_CLIENT_KEY>", // Your client key. To find out how to generate one, see https://docs.adyen.com/development-resources/client-side-authentication. Web Components versions before 3.10.1 use originKey instead of clientKey.
  paymentMethodsResponse: paymentMethodsResponse, // The payment methods response returned in step 1.
  onChange: handleOnChange, // Your function for handling onChange event
  showPayButton: true,
  onSubmit: handleChargebeeFlow,
  amount: {
      // Optional. Used to display the amount in the Pay Button.
      value: 900,
      currency: "USD",
  },
  onAdditionalDetails: handleOnAdditionalDetails, // Your function for handling onAdditionalDetails event
};

For example, here is how you would mount the Card Component using any CSS Selector, card.

adyen_wc_3ds/index.htmlView full code
const checkout = new AdyenCheckout(configuration);
const card = checkout.create("card");
card.mount("#component-container");

Step 3: Set Up Chargebee Js

Follow these steps to pass the card component to Chargebee.js to complete the 3DS.

  • Insert the Chargebee.js into your application.

Include the following script into your HTML page.

adyen_wc_3ds/index.htmlView full code
<script src="https://js.chargebee.com/v2/chargebee.js"></script>
  • Initialize the Chargebee Instance

Inside your JavaScript code, initialise Chargebee once the page is loaded and store the Chargebee instance in a variable. Further you can use this to create a 3DS handler.

adyen_wc_3ds/index.htmlView full code
let chargebeeInstance = Chargebee.init({
  site: "acme-test",
  publishableKey: "test__"
});
// You can access the above created instance anywhere using the following code
let chargebeeInstance = Chargebee.getInstance();

Step 4: 3D Secure Check

Load 3DS handler

This function will load the 3DS-helper module and initializes the 3DS handle object. You can use this approach to load the 3DS-helper module.

adyen_wc_3ds/index.htmlView full code
chargebeeInstance.load3DSHandler()

Set Payment Intent

Use this function to set paymentIntent that was created on your server-side. The paymentIntent will contain information about the payment gateway and the amount that needs to be charged.

  • Pass Adyen checkout instance while setting up payment intent on the 3DS Handler. Learn more about 3DS handler instance.
  • If the amount/currency gets changed during the checkout process, use the Update a payment intent API to update properties on a PaymentIntent object. Learn more about updating payment intent.
adyen_wc_3ds/index.htmlView full code
threeDSHandler.setPaymentIntent(response, {
  adyen: checkout
});

Handle Payment Intent

Call this function to initiate 3DS flow for the entered card details. Based on the Issuing Bank and gateway settings, the 3DS flow or challenge flow may be initiated or skipped. After a successful 3DS authorization, paymentIntent will be marked as authorized. This paymentIntent ID can then be used to create subscriptions or create payment methods. Learn more about the parameters used in handleCardPayment.

Adyen card component needs to pass as payment info.

Return value: Authorized paymentIntent object

adyen_wc_3ds/index.htmlView full code
let payment_info = {};
payment_info.element = card;
let additionalData = {};
additionalData.billingAddress =
  firstName: "John",
  lastName: "Doe",
  phone: "+234567890",
  addressLine1: "PO Box 9999",
  addressLine2: "",
  addressLine3: "",
  city: "Walnut",
  state: "California",
  stateCode: "CA",
  countryCode: "US",
  zip: "91789",
};
payment_info.additionalData = additionalData;
let callbacks = {
  change: function(intent) {
    // Triggers on each step transition
    console.log("Data Changed");
  },
  success: function(intent) {
    // Triggers when card is 3DS authorized
    create_subscription(intent);
  },
  error: function(intent, error) {
    // Triggers when 3DS authorization fails
    console.log("3DS Authorization failed");
    console.log(error);
  },
};
threeDSHandler.handleCardPayment(payment_info, callbacks);

Example

{
  "amount": 9999999,
  "created_at": 1630489992,
  "currency_code": "USD",
  "expires_at": 1630491792,
  "gateway": "adyen",
  "gateway_account_id": "gw_16BjrWSedpvrr2KJh",
  "id": "AzZlysShkfqRT2KiaW5mUzjwmOU02t1FUlVB6Hcd9bZKjeOBV3",
  "modified_at": 1630489992,
  "object": "payment_intent",
  "payment_method_type": "card",
  "status": "authorized"
}

To create a subscription in Chargebee, the Payment Intent has to be in an Authorized state. On receiving a successful response, the 3DS is authorized and you can move on to create a subscription in Chargebee.

Server-Side Implementation

Step 1: Set up Chargebee’s Client Library

Download and import the client library of your choice. Configure the client library with the Chargebee Test site and its full-access API Key.

Step 2: Create a Chargebee Payment Intent

A paymentIntent must be created at your server using create paymentIntent API and returned to the client-side. 3DS handler uses the created paymentIntent internally to perform 3DS authorization.

While creating the paymentIntent, you need to specify the amount that needs to be charged from the customer. You can also choose to specify which gateway needs to be used for this charge.

Before you create the paymentIntent, you need to configure Adyen in Chargebee. Make sure you have 3DS enabled in your Chargebee Test Site.

Here's the sample code to create a payment_intent

curl  https://{site-name}.chargebee.com/api/v2/payment_intents \
     -u {fullaccess_api_key}:\
     -d amount=500 \
     -d currency_code="EUR"
     -d gateway_account_id=""
     -d payment_method_type=""

Response

{
  "payment_intent": {
    "amount": 5000,
    "created_at": 1517501515,
    "currency_code": "USD",
    "expires_at": 1517503315,
    "gateway": "chargebee",
    "gateway_account_id": "gw___test__KyVnGlSBWTQeudG",
    "id": "__test__KyVnHhSBWTQz2Cu__test__0DZayCQMcAwDkEIPpUrGwkiyL25s7W1X",
    "modified_at": 1517501515,
    "object": "payment_intent",
    "payment_method_type": "card",
    "status": "inited"
  }
}

Step 3: Creating a Subscription

To create a subscription in Chargebee, the[Chargebee Payment Intent]fetched earlier has to be passed along with other POST parameters (from the checkout page's form submit an event), using the create subscription API.

Sample request to create a subscription in Chargebee


curl  https://<site-name>.chargebee.com/api/v2/subscriptions \
     -u {full_access_api_key}:\
     -d payment_intent[id]="<Id of authorized payment_intent recieved in last step.>"
     -d plan_id="pro_plan"\
     -d plan_quantity: 1\
     -d customer[first_name]="John" \
     -d customer[last_name]="Doe" \
     -d customer[email]="john@acme.com" \
     -d customer[allow_direct_debit]=true \
     -d billing_address[first_name]="John" \
     -d billing_address[last_name]="Doe" \
     -d billing_address[line1]="PO Box 9999" \
     -d billing_address[city]="Walnut" \
     -d billing_address[state]="California" \
     -d billing_address[zip]="91789" \
     -d billing_address[country]="US"

Though the parameters have been validated at the client-side, for additional security, we strongly recommend that you perform these validations on the server-side as well.

Chargebee Response

  • Chargebee returns a successful response in the JSON format that is wrapped in the form of a 'result' class by the client library.

  • In case of an error, Chargebee returns an error response, which is an exception thrown by the client library.

In case of successful checkout, you can redirect the user to a simple Thank You page.

Validation and Error-Handling

Here's how we validate user inputs and handle API call errors in this demo:

  • Client-Side Validation: Chargebee uses the jQuery form validation plugin to verify whether the user's field inputs(email, zip code, and phone number) are valid or not.
  • Server-Side Validation: As this is a demo application we have skipped the server-side validation for all input parameters. However, we recommend you perform the validation at your end.

  • Payment Errors: If a payment fails due to card verification or processing errors, Chargebee returns an error response which is returned as a payment exception by the client library. Exceptions are handled in the demo application with appropriate error messages.

  • General API Errors: Chargebee might return error responses due to various reasons such as invalid configuration, bad requests, etc. To identify specific reasons for all error responses you can check the API documentation. Also, take a look at the error handler file to check how these errors can be handled.

Test Cards

When you're all set, test your integration with some test transactions. Here are some credit card numbers that you can use to test the application:

 Card Type

  Card Number

 Expiry Date 

  Security Code  

 American Express

  3714 4963 5398 431

   03/2030

         7373

 Visa

  4917 6100 0000 0000

   03/2030

          737

Check out about test cards.

Was this tutorial helpful ?
Need more help?

We're always happy to help you with any questions you might have!

support@chargebee.com