Tokenization with Payments API
Collecting Card Details Using Xendit.js
This tutorial explains how to use HTML and Xendit.js v3, our foundational JavaScript library, to collect card details and perform tokenization. Your token can then be used to create a Payment Request to complete a card payment. There are three(3) steps to collecting card details:
- Collecting card information with Xendit.js
- Converting those card details to a single-use token
- Submitting that token, with the rest of your form, to your server
The above steps assume you have a typical HTML payment form, with a span for displaying error messages returned by Xendit.js.
For an example, here is a sample form that includes basic error checking to ensure valid responses from the user, and a span to display any errors back to the user for them to take action.
INFO
Our Payments API requires you to use Xendit.js v3. You may read more about the APIs available through this library on our GitHub repository.
Step 1: Load the XenditJS Library
To securely collect card information, include Xendit.js in your page by putting this code into the <head>
section of your website. Note that Xendit.js should be loaded from the CDN and not locally:
<script type="text/javascript" src="https://js.xendit.co/v3/xendit.min.js"></script>
<script type="text/javascript">
Xendit.setPublishableKey('YOUR_PUBLISHABLE_API_KEY');
</script>
Your publishable API key identifies your website to Xendit during communications. Replace it with your actual Public API key to test this code through your Xendit account.
When you're ready for production, be sure to change from your Test Public API Key to your Live Public API Key.
Step 2: Create a Payment Method
For security, the user’s card information never passes through your servers. Instead, the card information is ‘tokenized’ in the browser during the Payment Method creation process. You may create and tokenize card information by calling the `createPaymentMethod` function, part of our Payments API.
Xendit.payment.createPaymentMethod(
{
type: 'CARD',
card: {
currency: 'PHP',
channel_properties: {
success_return_url: 'https://redirect.me/goodstuff',
failure_return_url: 'https://redirect.me/badstuff',
},
card_information: {
card_number: cardNumber, // '4000000000001091'
expiry_month: expiryMonth, // 03
expiry_year: expiryYear, // 2030
cvv: cvvNumber, // 111
cardholder_name: "John Doe",
cardholder_email: "johndoe@gmail.com",
cardholder_phone_number: "+628212223242526"
},
reusability: 'MULTIPLE_USE',
}, (err, resp) => console.log(resp, "Here is the response sent by the server")
)
The cardNumber
, expiryMonth
, expiryYear
and cvvNumber
should be variables that captures the user's card details upon entry in your checkout page. For security and PCI DSS compliance, make sure to never log or store these fields on your server.
A full list of accepted properties is available here:
Parameter Name | Mandatory | Type | Description |
---|---|---|---|
type | Yes | string | The type of Payment Method creation. Should always be "CARD" |
reusability | Yes | string | Specifies how many times you'd like to reuse the returned Card token. Accepts "MULTIPLE_USE" or "ONE_TIME_USE" |
card.channel_properties.skip_three_d_secure | No | boolean | Indicates whether to enable 3DS validation for this card transaction. |
card.channel_properties.success_return_url | Yes | string | The URL of your website that Xendit should redirect your customer to after a successful card tokenization |
card.channel_properties.failure_return_url | Yes | string | The URL of your website that Xendit should redirect your customer to after a failed card tokenization |
card.channel_properties.cardonfile_type | No | string | Type of “credential-on-file” / “card-on-file” / COF payment for subsequent usage. Default: 'CUSTOMER_UNSCHEDULED' Possible values: *CUSTOMER_UNSCHEDULED - If you intend to use this Payment Method to perform future COF payments that do not follow a schedule. Example: simple “save card for future checkout” eCommerce flow, the future payments would always be CUSTOMER_UNSCHEDULED *MERCHANT_UNSCHEDULED - If you intend to use this Payment Method to perform future COF payments initiated without customer interaction and do not follow a schedule. Example: auto top-up payment flow *RECURRING - If you intend to use this Payment Method to process a series of transactions at fixed, regular intervals. Example: Subscriptions |
card.card_information.card_number | Yes | string | The full card number you have accepted from the customer |
card.card_information.expiry_month | Yes | string | The expiry month of the card you have accepted from the customer. Eg: "07" |
card.card_information.expiry_year | Yes | string | The expiry year of the card you have accepted from the customer. Eg: "2030" |
card.card_information.cvv | Yes | string | The CVV of the card you have accepted from the customer. Eg: "546" |
card.card_information.cardholder_name | Yes | string | The name of the cardholder |
card.currency | Yes | string | The currency to charge the transaction for. Eg: "IDR" |
customer_id | No | string | A Xendit Customer ID to link a Customer Object to a Card |
country | Yes | string | Two letter identifier of the country of transaction. Eg: "PH" for Phillipines |
description | No | string | Free text field for specifying a description a |
metadata | No | object | Merchant specified object to store any additional info |
for_user_id | No | string | Business ID of a sub-account for XenPlatform merchants |
idempotency_key | No | string | Idempotency key to enable idempotent transactions |
card.card_information.cardholder_email | Yes | string | The registered email of the cardholder |
card.card_information.cardholder_phone_number | Yes | string | The registered phone number of the cardholder |
You may use the second argument in this function to define a function to handle the response from the server. This function is important to store the Payment Method ID returned by Xendit to you for actual card payment.
You should also define a success_return_url
and a failure_return_url
to redirect your customer to after successful (or failed) 3DS verification. Xendit will redirect your customer to this page after they complete verification.
Step 3: Handle 3DS or OTP flows
If you select MULTIPLE_USE
as the Payment Method reusability, some cards may require an additional level of authentication known as 3D Secure (3DS) or OTP (one-time password).
If the payment method requires 3DS, the response status will be REQUIRES_ACTION
and the actions array will have an AUTH
object, you will need to send your customer to the URL so they can enter the OTP. When 3DS is completed either successful or fail, merchants would receive callback for the Payment Method creation result. The customer is then redirected to the success_redirect_url
you defined in the previous step
An example of this is given below. The other fields in the Payment Method response from Xendit have been abstracted away for convenience.
...
"status": "REQUIRES_ACTION",
"actions": [
{
"action": "AUTH",
"url": "https://redirect.xendit.co/callbacks/v2/authentications/63201d86ea3d99001aad0724/authentication_redirect?api_key=xnd_public_development_k3WxkSkv0DXkb1WqWKIJ3ZpMCZZC6hNtQFL7lrRdpvICxdFecoTyZAycTed572mU",
"url_type": "WEB",
"method": "GET"
}
],
...
Here, the URL https://redirect.xendit.co/callbacks/v2/authentications/63201d86ea3d99001aad0724/authentication_redirect?api_key=xnd_public_development_k3WxkSkv0DXkb1WqWKIJ3ZpMCZZC6hNtQFL7lrRdpvICxdFecoTyZAycTed572mU
is the one you are required to redirect the customer to.
Step 4: Store the Payment Method for future payment
After successfully creating and authenticating your Payment Method, you are free to save the entire object for payment. All fields returned in the Payment Method response are safe for storage on your server.
For completing a card payment, you are required to pass in the Payment Method id in a Payment Request subsequently created on the server.
Next Steps
You've successfully created a Payment Method on your frontend application. You may now:
- Create a Payment Request with the created Payment Method. Read more about this on our API Reference
Last Updated on 2024-10-30