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:

  1. Collecting card information with Xendit.js
  2. Converting those card details to a single-use token
  3. 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.


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=""></script>
<script type="text/javascript">

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.

   type: 'CARD',
   card: {
     currency: 'PHP',
     channel_properties: {
       success_return_url: '',
       failure_return_url: '',
     card_information: {
       card_number: cardNumber, // '4000000000001091'
       expiry_month: expiryMonth, // 03
       expiry_year: expiryYear, // 2030
       cvv: cvvNumber, // 111
   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 NameMandatoryTypeDescription
typeYesstringThe type of Payment Method creation. Should always be "CARD"
reusabilityYesstringSpecifies 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_secureNobooleanIndicates whether to enable 3DS validation for this card transaction.
card.channel_properties.success_return_urlYesstringThe URL of your website that Xendit should redirect your customer to after a successful card tokenization
card.channel_properties.failure_return_urlYesstringThe URL of your website that Xendit should redirect your customer to after a failed card tokenization
card.card_information.card_numberYesstringThe full card number you have accepted from the customer
card.card_information.expiry_monthYesstringThe expiry month of the card you have accepted from the customer. Eg: "07"
card.card_information.expiry_yearYesstringThe expiry year of the card you have accepted from the customer. Eg: "2030"
card.card_information.cvvYesstringThe CVV of the card you have accepted from the customer. Eg: "546"
card.card_information.cardholder_nameYesstringThe name of the cardholder
card.currencyYesstringThe currency to charge the transaction for. Eg: "IDR"
customer_idNostringA Xendit Customer ID to link a Customer Object to a Card
countryYesstringTwo letter identifier of the country of transaction. Eg: "PH" for Phillipines
descriptionNostringFree text field for specifying a description a
metadataNoobjectMerchant specified object to store any additional info
for_user_idNostringBusiness ID of a sub-account for XenPlatform merchants
idempotency_keyNostringIdempotency key to enable idempotent transactions

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": "",
     "url_type": "WEB",
     "method": "GET"

Here, the URL 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 2023-12-19