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
andvalue
of the paymentCountry 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
<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.
<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.
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
.
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.
<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.
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.
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.
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
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.
Reference Links
We're always happy to help you with any questions you might have!
support@chargebee.com