NAV undefined
bash php javascript java go python

Introduction

Welcome! Here at Xendit, our mission is to provide payments infrastructure that helps you succeed. We help with both the money in (accepting payments) and money out (disbursing payments). Use cases range from platform business to eCommerce, SaaS, and everything else in between.

The Xendit API is organized around REST. Our API has predictable, resource-oriented URLs, and uses HTTP response codes to indicate API errors. We use built-in HTTP features and HTTP verbs, which are understood by off-the-shelf HTTP clients. JSON is returned by all API responses, including errors.

To make it easier to get familiar with our APIs, we've published a Postman Collection so that you can see examples of all of Xendit APIs in one place.

Run in Postman

See our Postman Guide to get started!

Authentication

To successfully authenticate with Xendit's APIs, you must authenticate your secret API key using Basic Auth. You can obtain your API keys in Dashboard. For example if your API key is

xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==

Select Basic Auth authentication. Input secret API key in username and leave the password empty

Basic Auth format
{{username}}:{{password}}

Following the format (with colon)
xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==:

Encode Basic Auth format above into Base64 format

eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==

Include Base64 encoded value in HTTP(s) header

Authorization: Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==

Xendit API is organized around REST to make it cleaner and easier to understand. All our API responses return JSON. To let you explore our APIs, make sure that you have registered an account. You can obtain and manage your API keys in API Keys Settings. We provide you API keys for both the test and live environments.

To authenticate your account, you have to include your secret API key in the request which can be accessed in Xendit Dashboard. Here are the steps to authenticate your account:

  1. Generate secret API key
  2. Obtain your secret API key from Dashboard
  3. Select Basic Access Authentication or BASIC AUTH authentication
  4. BASIC AUTH format will be {{username}}:{{password}}
  5. Input Secret API key as username and leave the password empty. Make sure to include : at the end
  6. Encode the value above into Base64 format
  7. Include the base64 encoded into Authorization header

All the API requests should be made over HTTPS instead of HTTP (all calls made over plain HTTP will fail). All requests made in the test environment will never hit the banking networks and will not cost you anything. Your API keys should be kept private so do not share your secret API keys. Learn more about API key here

Libraries / SDKs

Xendit has official libraries for different programming languages and mobile platforms. We are continuously developing more libraries and plugins. If you have implemented your own library or an example that you would like to share, send us a link to your code and we'll be happy to add it to the list!

Node.js

Install via npm

npm install xendit-node

See the source on Github

Node.js library is a server-side library that helps you to integrate Xendit easily using Node.js.

List of Supported Products

  1. Credit/debit cards
  2. eWallets
  3. Cardless Credit
  4. QR Codes
  5. Customers
  6. Direct Debit
  7. Bank Transfer via Virtual Accounts
  8. Retail Outlets
  9. Invoices
  10. Recurring Payments
  11. Payouts
  12. Disbursements
  13. Batch Disbursements

Installation

You can install our Node.js library using npm npm install xendit-node or check out the source on Github

PHP

Download PHP package here

https://packagist.org/packages/xendit/xendit-php

PHP library is a client that is created on top of PHP so it is easier for you to integrate with us to accept payments via our supported payment channels.

You can visit our PHP library in Packagist

There are two versions of Xendit PHP libraries that we support:

List of Supported Products - Xendit PHP v2

  1. Credit/debit cards
  2. eWallets
  3. Cardless Credit
  4. Bank Transfer via Virtual Accounts
  5. Retail Outlets
  6. Invoices
  7. Recurring Payments
  8. Payouts
  9. Disbursements
  10. Batch Disbursements
  11. Customers
  12. Direct Debit

List of Supported Products - Xendit PHP v1

  1. Credit/debit cards
  2. Bank Transfer via Virtual Accounts
  3. Invoices
  4. Disbursements

Installation and Upgrade Guide

Check out our Github source to learn on how to install or upgrade Xendit PHP library

Java

Install Xendit in your Java code

Maven

<dependency>
    <groupId>com.xendit</groupId>
    <artifactId>xendit-java-lib</artifactId>
    <version>SELECTED_VERSION</version>
</dependency>

Gradle

compile 'com.xendit:xendit-java-lib:{SELECTED_VERSION}'

Import Xendit Library

import com.xendit.Xendit; 
import com.xendit.exception.XenditException; 
import com.xendit.model.AvailableBank; 
import com.xendit.model.VirtualAccount;

Java library is a server-side library that helps you to integrate Xendit easily using Java.

List of Supported Products

  1. Credit/debit cards
  2. eWallets
  3. Cardless Credit
  4. Bank Transfer via Virtual Accounts
  5. Retail Outlets
  6. Invoices
  7. Recurring Payments
  8. Payouts
  9. Disbursements
  10. Batch Disbursements
  11. Customers
  12. Direct Debit

Installation

Xendit Java library (Gradle and Maven) installation is easy and simple. For more detail about the steps, refer to the right section

  1. Add Xendit dependency in your Java code
  2. Import Xendit library
  3. Obtain your API keys in Dashboard to start using Xendit Java library APIs.

You can also learn more on our Github source for complete installation guide

Go

See the source on Github

Go library is a server-side library that helps you to integrate Xendit easily using Go programming language.

List of Supported Products

  1. Credit/debit cards
  2. eWallets
  3. Cardless Credit
  4. Bank Transfer via Virtual Accounts
  5. Retail Outlets
  6. Invoices
  7. Recurring Payments
  8. Payouts
  9. Disbursements
  10. Batch Disbursements
  11. Customers
  12. Direct Debit

Installation

You can install our Go library by checking out our source on Github for complete installation guide

Python

Install via pip

pip install xendit-python

See the source on Github

Python library is a server-side library that helps you to integrate Xendit easily using Python.

List of Supported Products

  1. Credit/debit cards
  2. eWallets
  3. Cardless Credit
  4. QR Codes
  5. Direct Debit
  6. Bank Transfer via Virtual Accounts
  7. Retail Outlets
  8. Invoices
  9. Recurring Payments
  10. Payouts
  11. Disbursements
  12. Batch Disbursements

Installation

You can install our Python library using pip pip install xendit-python or check out the source on Github

Android

Download Xendit Android SDK

https://github.com/xendit/xendit-sdk-android

Android SDK helps you to process digital payments using Xendit with features as follow:

  1. Tokenize credit/debit cards with single-use token
  2. Tokenize credit/debit cards with multiple-use token
  3. Authenticate credit/debit card transactions

iOS

Download Xendit iOS SDK

https://github.com/xendit/xendit-sdk-ios

iOS SDK helps you to process digital payments using Xendit with features as follow:

  1. Tokenize credit/debit cards with single-use token
  2. Tokenize credit/debit cards with multiple-use token
  3. Authenticate credit/debit card transactions

Versioning

Versioning Example

curl https://api.xendit.co/ewallets -X POST \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
   -H X-API-VERSION='2020-02-01' \
   -d external_id='ovo-ewallet' \
   -d amount=1000 \
   -d phone='08123123123'\
   -d ewallet_type='OVO'

Xendit evolves APIs continuously to grow together with you. We always strive to make backward-compatible changes. When we introduce backward-incompatible changes, we release a new dated version to avoid breaking your code and you can upgrade to newer versions whenever you are ready.

To see what version you're running and upgrade to the latest one, visit your Dashboard. To test a specific API version, you can override your API version by attaching API-Version header in API requests

Header Description
API-Version
optional
string Attach this parameter in the request to specify which API version you are going to request

Format: YYYY-MM-DD. Example: 2020-02-01

Default value will follow your account API version settings

Backward Compatibility

We consider the following changes to be backward compatible:

Migration Guide

The following guide will help you to migrate from your current version to latest version safely

  1. Test new APis using explicit API-Version header in Test mode. Make sure you have handled new request,response, errors, and callback data correctly. Test scenarios can be found in Test Scenarios section
  2. When everything is working as expected in Test mode, you can switch your Test mode API version in Dashboard. This switches the version used by API calls that don't have the API-Version header and also switches the version to render objects sent to your callback URLs
  3. Repeat #1 and #2 respectively in Live mode
  4. When faced with any disruption during migration process, you can always switch back to previous versions

Changelog

Version Date API Resources Path Changelog
2020-02-21 eWallets /ewallets Create OVO Payment will be processed asynchronously and callback will be sent after process has been completed
2019-05-01 Credit Cards /credit_card_charges/refunds Create Refund will be processed synchronously

Errors

Your Xendit integration might have to deal with errors at some point when making API requests to Xendit. These errors fall into a few major categories:

The right approach and idempotency semantics to use for handling errors depend on the type of error being handled.

HTTP Status Code

Xendit uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, a charge failed, etc). Codes in the 5xx range indicate an error with Xendit's servers (these are rare).

Status Code Description
200 - OK Everything worked as expected
400 - Bad Request The request was unacceptable, often due to missing a required parameter
401 - Unauthorized No valid API key provided
403 - Forbidden The API key doesn't have permissions to perform the request
404 - Not Found The requested resources doesn't exist
500 - Server Errors Something went wrong on Xendit's end (These are rare)

Error Code

Below are some of most common errors across all our endpoints. Specific errors are located under each endpoint.

Error Code Description
API_VALIDATION_ERROR Invalid request errors arise when your request has invalid parameters
INVALID_API_KEY No valid API key provided
REQUEST_FORBIDDEN_ERROR
The API key doesn't have permissions to perform the request
SERVER_ERROR API errors cover any other type of problem (e.g. a temporary problem with Xendit's servers), and are extremely uncommon

Error Handling

Safely retry requests with idempotency

A key part of web API design is the idea of idempotency, defined as being able to apply the same operation multiple times without changing the result beyond the first try. Because a certain amount of intermittent failure is to be expected, clients need a way of reconciling failed requests with a server, and idempotency provides a mechanism for that.

The Xendit API guarantees the idempotency of GET requests, so it's always safe to retry them. Including an idempotency key makes POST and PATCH request idempotent, which prompts the API to do the bookkeeping required to prevent duplicate operations. For example, if a request to create disbursements does not respond due to network connection error, you can retry the request with the same idempotency key to guarantee that no more than one disbursement is created.

Idempotency keys are sent in the x-idempotency-key header, and you should use them for all POST requests to Xendit's API whenever supported. A few common strategies for generating idempotency keys are:

A response that's being replayed from the server because it had already executed previously can be identified by the error code DUPLICATE_TRANSACTION_ERROR

Content errors

Content errros are the result of the contents of an API request being invalid and return a 4xx error code. Integrations should correct the original request and try again. Depending of the type of user error, it may be possible to handle the problem programmatically.

For a POST operation using an idempotency key, as long as an API method began execution, Xendit's API servers will cache the results of the request regardless of what they were. A request that returns a 400 will send back the same 400 if followed by a new request with the same idempotency key. A fresh idempotency key should be generated when modifying the original request to get a successful result. The safest strategy where 4xx errors are concerned is to always generate a new idempotency key.

Network errors

Network errors are the result of connectivity problems between client and server and tend to manifest as low-level errors like socket or timeout exceptions.

This class of errors is where the value of idempotency keys and request retries is most obvious. When intermittent problems occur, clients are usually left in a state where they don't know whether or not the server received the request. To get a definitive answer, they should retry such requests with the same idempotency keys and the same parameters until they're able to receive a result from the server. Sending the same idempotency with different parameters will produce an error indicating that the new request didn't match the original.

Server errors

Server errors are the result of a server-side problem and return a 5xx error code. These errors are the most difficult to handle, so we try to ensure that they happen as infrequently as possible.

As with the errors, retrying them with the same idempotency key will usually produce the same result. The request can be retried with a new idempotency key, but we'd advice against it because it's possible for the original one to have produced side effects.

The result of a 500 request should be treated as indeterminate. The exact nature of any retroactive changes in the system depend heavily on the type of request. For example, if creating a disbursement returns a 500 error but we detect that the information has gone out to a payment network, we'll try to roll it forward and send callback after it has been completed. If not, we'll try to roll it back. However, ideal results under these circumstances are not guaranteed, and requests resulting in a 500 error may proeduce user-visible side effects.

Integration that want to maximize robustness must configure callback handlers that are capable of receiving events that have never been seen in an API response.

Callback

Xendit uses callback to notify your application any time an event happens on your account. Set up callback for events that Xendit doesn't already notify you of, like when a disbursement has been completed, a Virtual Account has been created and paid, or your invoice has expired.

Setup

You need to provide an endpoint in your system to receive callback from us. The callback notification will be sent over POST request to your callback URL that you have set. Setup your callback URL in Callback settings. You can use a tool like ngrok to make your endpoint available for receiving callback during testing.

Delivery Attempts and Retries

Understand how to view delivery attempts and retry logic when callback events aren't acknowledged

View events

When viewing information about a specific event through the Dashboard's Callback tab, you can check how many times Xendit attempted to send an event to the endpoint. This shows the latest response from your endpoint, a list of all attempted callback, and the respective HTTP status codes Xendit received.

Retry logic

Xendit attempts to deliver your callback six times with exponential backoff between each interval and will stop retrying until we have received response from your server or there is still no response yet

Retry Number Interval (relative to last retry) Interval (relative to original attempt)
1 15m 15m
2 45m 1h
3 2h 3h
4 3h 6h
5 6h 12h
6 12h 24h

Receive callback statistics via email

You can also receive summary of your callback statistics (number of success and failed callback) via email every 6 hours. You can enable this feature in Email Recipient settings

Event Handling

Handling callback events correctly is crucial to making sure your integration's business logic works as expected

Acknowledge events immediately

If your callback script performs complex logic, or makes network calls, it's possible that the script would time out before Xendit sees its complete execution. Ideally, your callback handler code (acknowledging receipt of an event by returning a 2xx status code) is separate of any other logic you do for that event.

Handle duplicate events

Callback endpoints might occasionally receive the same event more than once. We advise you to guard against duplicated event receipts by making your event processing idempotent. One way of doing this is logging the events you've processed, and then not processing already-logged events.

Order of events

Xendit does not guarantee delivery of events in the order in which they are generated. Your endpoint should not expect delivery of these events in this order and should handle this accordingly. You can also use the API to fetch any missing objects.

Security

Keeping your endpoints secure is critical to protecting your customers' information. Xendit provides several ways for you to verify events are coming from Xendit in a secure manner.

Receive events with an HTTPS server

If you use an HTTPS URL for your callback endpoint, Xendit will validate that the connection to your server is secure before sending your callback data. For this to work, your server must be correctly configured to support HTTPS with a valid server certificate.

Verify events are sent from Xendit

Xendit can optionally sign the callback events it sends to your endpoints. We do so by including a token in each event's x-callback-token header. This allows you to verify that the events were sent by Xendit, not by a third party.

Header Parameter Description
x-callback-token
string Your Xendit unique callback token to verify the origin of the callback

Before you can verify tokens, you need to retrieve your callback token from Dashboard's Callback settings. Each secret is unique to each environments.

Balances

Get Balance

Endpoint: Get Balance

GET https://api.xendit.co/balance?account_type={account_type}

Balance is like your wallet since it will tell you how much money is available to you on Xendit. You can retrieve it to see the current balance on your Xendit cash account. Your balance is debited on any money out transaction, e.g. when performing disbursements or Xendit fees are charged. Your balance is credited when money comes into your account, e.g. invoices are paid or you deposit funds.

Request Parameters

Example Get Balance Request

curl https://api.xendit.co/balance -X GET \
-u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
<?php

  use Xendit\Xendit;
  require 'vendor/autoload.php';

  Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=='); // this is Xendit API key example, you can go to Setting > API Key to get your API Key

  $getBalance = \Xendit\Balance::getBalance('CASH');
  var_dump($getBalance);

?>
const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });

const { Balance } = x;
const balanceSpecificOptions = {};
const b = new Balance(balanceSpecificOptions);

const resp = await b.getBalance()
console.log(resp);
Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
try {
  Balance balance = Balance.get();
} catch (XenditException e) {
  e.printStackTrace();
}
xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="

data := balance.GetParams{
  AccountType: "CASH",
}

resp, err := balance.Get(&data)
if err != nil {
  log.Fatal(err)
}

fmt.Printf("balance: %+v\n", resp)
from xendit import Xendit, BalanceAccountType

api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
xendit_instance = Xendit(api_key=api_key)
Balance = xendit_instance.Balance

balance = Balance.get(
    account_type=BalanceAccountType.CASH,
)

print(balance)

Get Balance allows you to retrieve the balance of your cash and pending balance. Some use cases include: deciding when you may need to withdraw funds, and determining if you have funds to disburse

Header Parameter Type Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information

Query Parameter Type Description
account_type
optional
default: CASH
string The selected balance type

available values: CASH, HOLDING, TAX

Response Parameters

Example Get Balance Response

{
  "balance": 1241231
}
Parameter Description
balance The balance remaining in your cash account

Payment Channels

Get Payment Channels

Endpoint: Get Payment Channels API

GET https://api.xendit.co/payment_channels

Example Get Payment Channels

curl https://api.xendit.co/payment_channels -X GET \
-u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:

Request Parameters

Returns an array of payment channel objects. Use this to identify which payment channels have been enabled for your business.

Header Parameter Type Description
for-user-id
optional
string The Sub-account user-id that you want to make this transaction for

This header is only used if you have access to xenPlatform. See xenPlatform for more information.

Response Parameters

Example Get Payment Channels Response

[
  {
    "business_id": "xxxxxxxx",
    "is_livemode": true, 
    "channel_code": "BRI",
    "name": "BRI Virtual account",
    "currency": "IDR",
    "channel_category": "VIRTUAL_ACCOUNT",
    "is_enabled": false
  },
  {
    "business_id": "xxxxxxxx",
    "is_livemode": true, 
    "channel_code": "MASTERCARD",    
    "name": "Mastercard credit and debit cards",
    "currency": "IDR",
    "channel_category": "CREDIT_CARD",
    "is_enabled": true     
  },
  {
    "business_id": "xxxxxxxx",
    "is_livemode": true, 
    "channel_code": "MASTERCARD",    
    "name": "Mastercard credit and debit cards",
    "currency": "USD",
    "channel_category": "CREDIT_CARD",
    "is_enabled": true     
  }
  ...
]
Parameter Type Description
business_id
required
string Your business ID
is_livemode
required
boolean true When making the request with your live API key. false when making the request with your test API key
channel_code
required
string Payment channel code.
name
required
string Payment channel name
currency
required
string Processing currency of the payment channel. Based on ISO 4217 currency code.
channel_category
required
string Payment channel category.
Available values: VIRTUAL_ACCOUNT, RETAIL_OUTLET, EWALLET,CREDIT_CARD, QRIS
is_enabled
required
boolean When true, an API request can be successfully made for the business with the payment channel. When false, the API request will fail. You should activate the payment channel in the dashboard settings to make it successfully

Customers

An API to manage end customer information. Supports storage of customer profiles for businesses and individuals, along with their KYC documentation and other account information. For use in support of various payment use-cases throughout the Xendit Payment APIs, including utilising the Direct Debit channel, to fulfil KYC requirements for remittance payments, or for enhanced payments reporting.

Customer Object

Example Customer Object

{
    "id": "239c16f4-866d-43e8-9341-7badafbc019f",
    "reference_id": "demo_1475801962607",
    "email": "customer@website.com",
    "mobile_number": null,
    "given_names": "John",
    "description": null,
    "middle_name": null,
    "surname": "Doe",
    "phone_number": "+6285300000000",
    "nationality": "ID",
    "addresses": [{
        "country": "ID",
        "street_line1": "Jalan Makan",
        "street_line2": "Kecematan Kebayoran Baru",
        "city": "Jakarta Selatan",
        "province": "Daerah Khusus Ibukota Jakarta",
        "state": null,
        "postal_code": "12160"
    }],
    "date_of_birth": "2000-01-01",
    "metadata": null
}

Version

You are currently viewing API version 2020-05-19. New version is available! Click here to view newer versions.

Parameter Description
id string Unique ID generated by Xendit for the particular customer
reference_id string Identifer you provided during request
mobile_number string Mobile number of the customer
email string Email address of the customer
given_names string Primary of first name/s of the customer
middle_name string Middle name of the customer
surname string Surname of the customer
description string Description you provided for the customer object
phone_number string Alternate or landline phone number
nationality string Country code for the customer's nationality
addresses object array Array of objects containing the specific customer's address information
Key Value
country
required
2-letter ISO 3166-2 country code for the customer's country of residence
street_line1
optional
Building name and apartment unit number
street_line2
optional
Building street address
city
optional
City, village or town as appropriate
province
optional
Geographic area, province, or region, if applicable
state
optional
Formal state designation within country, if applicable
postal_code
optional
Postal, zip or rural delivery code, if applicable
date_of_birth string Date of birth of the customer in YYYY-MM-DD format
metadata object A free-format JSON for additional information that you provded during request.

Create Customer

A customer object is required in order to link a payment method for direct debit. This allows you to easily link and track payment methods and transactions.

Endpoint: Create Customer

POST https://api.xendit.co/customers

Version

You are currently viewing API version 2020-05-19. New version is available! Click here to view newer versions.

Create Customer - Request

Example Create Customer Request

curl https://api.xendit.co/customers -X POST \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
   -H 'Content-Type: application/json' \
   -d reference_id=demo_1475801962607 \
   -d given_names="John" \
   -d mobile_number="+6287774441111" \
   -d email="customer@website.com" \
<?php

  use Xendit\Xendit;
  require 'vendor/autoload.php';

  Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');

  $customerParams = [
    'reference_id' => '' . time(),
    'given_names' => 'customer 1',
    'email' => 'customer@website.com',
    'mobile_number' => '+6281212345678',
    'description' => 'dummy customer',
    'middle_name' => 'middle',
    'surname' => 'surname',
    'addresses' => [
      [
        'country' => 'ID',
        'street_line1' => 'Jl. 123',
        'street_line2' => 'Jl. 456',
        'city' => 'Jakarta Selatan',
        'province' => 'DKI Jakarta',
        'state' => '-',
        'postal_code' => '12345'
      ]
    ],
    'metadata' => [
      'meta' => 'data'
    ]
  ];

  $createCustomer = \Xendit\Customers::createCustomer($customerParams);
  var_dump($createCustomer);

?>
const x = new require("xendit-node")({
  secretKey:
    "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
});

const { Customer } = x;
const customerSpecificOptions = {};
const c = new Customer(customerSpecificOptions);

const resp = await c.createCustomer({
  referenceID:'demo_1475801962607',
  givenNames: 'John',
  mobileNumber: '+6287774441111',
  email: 'customer@website.com',
});
console.log(resp);
xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="

customerAddress := xendit.CustomerAddress{
  Country:      "ID",
  StreetLine1:  "Jl. 123",
  StreetLine2:  "Jl. 456",
  City:         "Jakarta Selatan",
  Province:     "DKI Jakarta",
  State:        "-",
  PostalCode:   "12345",
}

data := customer.CreateCustomerParams{
  ReferenceID:  "test-reference-id-003",
  Email:        "tes@tes.com",
  GivenNames:   "Given Names",
  Nationality:  "ID",
  DateOfBirth:  "1995-12-30",
  Addresses:    []xendit.CustomerAddress{customerAddress},
  Metadata:     map[string]interface{}{
    "meta": "data",
  },
}

resp, err := customer.CreateCustomer(&data)
if err != nil {
  log.Fatal(err)
}

fmt.Printf("created payment: %+v\n", resp)
try {
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";

    CustomerAddress customerAddress =  CustomerAddress.builder()
        .country("ID")
        .streetLine1("Jl. 123")
        .streetLine2("Jl. 456")
        .city("Jakarta Selatan")
        .province("DKI Jakarta")
        .state("-")
        .postalCode("12345")
        .category("None")
        .isPreferred(true)
        .build();
    CustomerAddress[] customerAddressArray = new CustomerAddress[]{customerAddress};

    Map<String, Object> metadata = new HashMap<>();
    metadata.put("halo", "hello");
    metadata.put("tes", "123");

    Map<String, Object> params = new HashMap<>();
    params.put("reference_id", "test-reference-id");
    params.put("email", "tes@tes.com");
    params.put("given_names", "Given Names");
    params.put("nationality", "ID");
    params.put("date_of_birth", "1995-12-30");
    params.put("addresses", customerAddressArray);
    params.put("metadata", metadata);

    Customer customer = Customer.createCustomer(params);
} catch (XenditException e) {
    e.printStackTrace();
}
from xendit import Xendit

api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
xendit_instance = Xendit(api_key=api_key)
DirectDebit = xendit_instance.DirectDebit

customer = DirectDebit.create_customer(
    reference_id="merc-1594279037",
    email="t@x.co",
    given_names="Adyaksa",
)
print(customer)
Header Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Request Body Parameter Description
reference_id
required
string Merchant-provided identifier for the customer
mobile_number
either mobile_number or email is required
string Mobile number of the customer in E.164 international standard.
Format: +(country code)(subscriber number)
email
either mobile_number or email is required
string Email address of the customer
given_names
required
string Primary of first name/s of the customer
middle_name
optional
string Middle name of the customer
surname
optional
string Surname of the customer
description
optional
string Merchant-provided description for the customer object
phone_number
optional
string Alternate or landline phone number in E.164 international standard.
Format: +(country code)(subscriber number)
nationality
optional
string 2-letter ISO 3166-2 country code for the customer's nationality
addresses
optional
array of object Array of objects containing the specific customer's address information

Each object may have the following properties:
Key Value
country
required
2-letter ISO 3166-2 country code for the customer's country of residence
street_line1
optional
Building name and apartment unit number
street_line2
optional
Building street address
city
optional
City, village or town as appropriate
province
optional
Geographic area, province, or region, if applicable
state
optional
Formal state designation within country, if applicable
postal_code
optional
Postal, zip or rural delivery code, if applicable
date_of_birth
optional
string Date of birth of the customer in YYYY-MM-DD format
metadata
optional
object A free-format JSON for additional information that you may use.

Create Customer - Response

Example Create Customer Success Response

{
    "id": "239c16f4-866d-43e8-9341-7badafbc019f",
    "reference_id": "demo_1475801962607",
    "email": "customer@website.com",
    "mobile_number": null,
    "given_names": "John",
    "description": null,
    "middle_name": null,
    "surname": null,
    "phone_number": null,
    "nationality": null,
    "addresses": null,
    "date_of_birth": null,
    "metadata": null
}
Parameter Description
id string Unique ID generated by Xendit for the particular customer
reference_id string Identifer you provided during request
mobile_number string Mobile number of the customer
email string Email address of the customer
given_names string Primary of first name/s of the customer
middle_name string Middle name of the customer
surname string Surname of the customer
description string Description you provided for the customer object
phone_number string Alternate or landline phone number
nationality string Country code for the customer's nationality
addresses object array Array of objects containing the specific customer's address information
Key Value
country
required
2-letter ISO 3166-2 country code for the customer's country of residence
street_line1
optional
Building name and apartment unit number
street_line2
optional
Building street address
city
optional
City, village or town as appropriate
province
optional
Geographic area, province, or region, if applicable
state
optional
Formal state designation within country, if applicable
postal_code
optional
Postal, zip or rural delivery code, if applicable
date_of_birth string Date of birth of the customer in YYYY-MM-DD format
metadata object A free-format JSON for additional information that you provded during request.

Create Customer - Errors

See other common errors here.

Error Code Description
DUPLICATE_ERROR
409
The provided reference_id has been used before. Please enter a unique reference_id and try again.

Get Customer by Reference ID

Retrieves an array with a customer object that matches the provided reference_id - the identifier provided by you

Endpoint: Get Customer by Reference ID

GET https://api.xendit.co/customers?reference_id={reference_id}

Version

You are currently viewing API version 2020-05-19. New version is available!

Get Customer by Reference ID - Request

Example Get Customer by Reference ID Request

curl https://api.xendit.co/customers?reference_id=demo_1475801962607 -X GET \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: 
<?php

  use Xendit\Xendit;
  require 'vendor/autoload.php';

  Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');

  $getCustomer = \Xendit\Customers::getCustomerByReferenceID(
    'cust-ref-id'
  );
  var_dump($getCustomer);

?>
const x = new require("xendit-node")({
  secretKey:
    "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
});

const { Customer } = x;
const customerSpecificOptions = {};
const c = new Customer(customerSpecificOptions);

const resp = await c.getCustomerByReferenceID({
  referenceID: 'demo_1475801962607',
});
console.log(resp);
xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="

data := customer.GetCustomerByReferenceIDParams{
  ReferenceID:  "test-reference-id-003",
}

resp, err := customer.GetCustomerByReferenceID(&getCustomerByReferenceIDData)
if err != nil {
  log.Fatal(err)
}

fmt.Printf("retrieved customer: %+v\n", resp)
try {
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";

    Customer[] customers = Customer.getCustomerByReferenceId("test-reference-id");
} catch (XenditException e) {
    e.printStackTrace();
}
from xendit import Xendit

api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
xendit_instance = Xendit(api_key=api_key)
DirectDebit = xendit_instance.DirectDebit

customer = DirectDebit.get_customer_by_ref_id(
    reference_id="merc-1594279037",
)
print(customer)
Query String Parameter Description
reference_id
required
string Merchant-provided identifier for the customer

Get Customer by Reference ID - Response

Example Get Customer by Reference ID Success Response

[{
    "id": "239c16f4-866d-43e8-9341-7badafbc019f",
    "reference_id": "demo_1475801962607",
    "email": "customer@website.com",
    "mobile_number": null,
    "given_names": "John",
    "description": null,
    "middle_name": null,
    "surname": null,
    "phone_number": null,
    "nationality": null,
    "addresses": null,
    "date_of_birth": null,
    "metadata": null
}]
Header Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Parameter Description
id string Unique ID generated by Xendit for the particular customer
reference_id string Identifer you provided during request
mobile_number string Mobile number of the customer
email string Email address of the customer
given_names string Primary of first name/s of the customer
middle_name string Middle name of the customer
surname string Surname of the customer
description string Description you provided for the customer object
phone_number string Alternate or landline phone number
nationality string Country code for the customer's nationality
addresses object array Array of objects containing the specific customer's address information
date_of_birth string Date of birth of the customer in YYYY-MM-DD format
metadata object A free-format JSON for additional information that you provded during request.

Get Customer by Reference ID - Errors

See other common errors here.

Files

An API to store and manage files for any purpose. Files may be used in any payments endpoint, including for example, KYC documentation for customers and remittance payments, or providing evidence to help support chargeback investigations.

Upload File

Make a POST request to this endpoint to upload a file. We currently support uploading PNG, JPG/JPEG, PDF files of less than 10 MB.

Endpoint: Upload File

POST https://api.xendit.co/files

Request parameters

Example Upload File Request

curl https://api.xendit.co/files -X POST \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
   --form 'file=@/Users/utkarshagarwal/Desktop/Screenshot 2020-10-13 at 5.28.45 PM.png' \
   --form 'purpose=CHARGEBACK_EVIDENCE'
<?php
  $url = "https://api.xendit.co/files";
  $apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==";
  $headers = [];
  $headers[] = "Content-Type: application/json";
  $payload = array('file'=> new CURLFILE('~/yourpath/file.png'),'purpose' => 'CHARGEBACK_EVIDENCE');

  $curl = curl_init();

  $payload = json_encode($data);
  curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($curl, CURLOPT_USERPWD, $apiKey.":");
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_POST, true);
  curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

  $result = curl_exec($curl);
  echo $result;
let apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==";
let url = "https://api.xendit.co/files";

var headers = new Headers();
headers.append("Authorization", "Basic " + btoa(apiKey + ":"));
var formdata = new FormData();
formdata.append("file", fileInput.files[0], "file.png");
formdata.append("purpose", "CHARGEBACK_EVIDENCE");

var requestOptions = {
  method: 'POST',
  headers: headers,
  body: formdata,
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
import requests
import base64

api_key = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:"
url = "https://api.xendit.co/files"

api_key_bytes = api_key.encode('ascii')
base64_bytes = base64.b64encode(api_key_bytes)
base64_token = base64_bytes.decode('ascii')

payload={'purpose': 'CHARGEBACK_EVIDENCE'}
files=[
  ('file', open('/yourpath/file.png','rb'))
]
auth_token = 'Basic ' + base64_token
headers = {
  'Authorization': auth_token
}

response = requests.request("POST", url, headers=headers, data=payload, files=files)

print(response.text)
Body Parameter Type Description
purpose
required
string Purpose of the file being uploaded
Supported values: KYC_DOCUMENT, CHARGEBACK_EVIDENCE
file
required
file The file. Supported types: application/pdf, image/png, image/jpg, image/jpeg

Response parameters

Example Upload File Success Response

{
  "id": "file-ec700c1c-db17-4496-b1fb-04ebe551b412",
  "business_id": "ec700c1c-db17-4496-b1fb-04ebe551b412",
  "purpose": "CHARGEBACK_EVIDENCE",
  "created": "2020-10-08T06:38:33.479Z",
  "updated": "2020-10-08T06:38:33.479Z",
  "type": "image/png",
  "size": 10000,
  "url": "https://files.xendit.co/file-ec700c1c-db17-4496-b1fb-04ebe551b412"
}
Body Parameter Type Description
id
required
string Unique ID generated by Xendit for the particular file
business_id
required
string Your Xendit business id
purpose
required
string Purpose of the file
created
required
string UTC Timestamp of file upload in ISO format
updated
required
string UTC Timestamp of last file update in ISO format
type
required
string Type of the file
size
required
integer Size of the file in bytes
url
required
string URL to download the file

Error Codes

See other common errors here.

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
FILE_TOO_LARGE_EXCEEDED_ERROR
413
The file size is greater than 2000000 bytes and exceeded size limits. Please compress the payload before retrying
UNSUPPORTED_CONTENT_TYPE_ERROR
415
The file format is not supported. Please review the file type before retrying
REQUEST_FORBIDDEN_ERROR
403
API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here
RATE_LIMIT_EXCEEDED
429
You have reached the rate limit for file transfer. Please exponentially back off requests until you no longer receive this error

Get File by Id

Make a GET request to this endpoint to get file details

Endpoint: Get File

GET https://api.xendit.co/files/{file-id}

Example Get File Request

curl https://api.xendit.co/files/file-ec700c1c-db17-4496-b1fb-04ebe551b412 --request GET \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
<?php

  $fileId = "file-ec700c1c-db17-4496-b1fb-04ebe551b412";
  $url = "https://api.xendit.co/files/" . $fileId;
  $apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
  $headers = [];

  $curl = curl_init();

  $payload = json_encode($data);
  curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($curl, CURLOPT_USERPWD, $apiKey.":");
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

  $result = curl_exec($curl);
  echo $result;
let apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==";
let fileId= "file-ec700c1c-db17-4496-b1fb-04ebe551b412";
let url = "https://api.xendit.co/files/"+fileId;

var headers = new Headers();
headers.append("Authorization", "Basic " + btoa(apiKey + ":"));


var requestOptions = {
  method: 'GET',
  headers: headers,
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
import requests
import base64

api_key = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:"
url = "https://api.xendit.co/files/file-ec700c1c-db17-4496-b1fb-04ebe551b412"

api_key_bytes = api_key.encode('ascii')
base64_bytes = base64.b64encode(api_key_bytes)
base64_token = base64_bytes.decode('ascii')
payload={}

auth_token = 'Basic ' + base64_token
headers = {
  'Authorization': auth_token
}

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)

Response parameters

Example Get File Success Response

{
  "id": "file-ec700c1c-db17-4496-b1fb-04ebe551b412",
  "business_id": "ec700c1c-db17-4496-b1fb-04ebe551b412",
  "purpose": "CHARGEBACK_EVIDENCE",
  "created": "2020-10-08T06:38:33.479Z",
  "updated": "2020-10-08T06:38:33.479Z",
  "type": "image/png",
  "size": 10000,
  "url": "https://files.xendit.co/file-ec700c1c-db17-4496-b1fb-04ebe551b412"
}
Body Parameter Type Description
id
required
string Unique ID generated by Xendit for the particular file
business_id
required
string Your Xendit business id
purpose
required
string Purpose of the file
created
required
string UTC Timestamp of file upload in ISO format
updated
required
string UTC Timestamp of last file update in ISO format
type
required
string Type of the file
size
required
integer Size of the file in bytes
url
required
string URL to download the file

Error Codes

See other common errors here.

Error Code Description
DATA_NOT_FOUND
404
File not found for the given id

Download File by Id

Make a GET request to this endpoint to download a file

Endpoint: Download File

GET https://api.xendit.co/files/{file-id}/download

Example Download File Request

curl https://api.xendit.co/files/file-ec700c1c-db17-4496-b1fb-04ebe551b412/download --request GET \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
<?php

  $fileId = "file-ec700c1c-db17-4496-b1fb-04ebe551b412";
  $url = "https://api.xendit.co/files/" . $fileId . "/download";
  $apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
  $headers = [];

  $curl = curl_init();

  $payload = json_encode($data);
  curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($curl, CURLOPT_USERPWD, $apiKey.":");
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

  $result = curl_exec($curl);
  echo $result;
let apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==";
let fileId= "file-ec700c1c-db17-4496-b1fb-04ebe551b412";
let url = "https://api.xendit.co/files/"+fileId+"/download";

var headers = new Headers();
headers.append("Authorization", "Basic " + btoa(apiKey + ":"));


var requestOptions = {
  method: 'GET',
  headers: headers,
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
import requests
import base64

api_key = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:"
url = "https://api.xendit.co/files/file-ec700c1c-db17-4496-b1fb-04ebe551b412/download"

api_key_bytes = api_key.encode('ascii')
base64_bytes = base64.b64encode(api_key_bytes)
base64_token = base64_bytes.decode('ascii')
payload={}

auth_token = 'Basic ' + base64_token
headers = {
  'Authorization': auth_token
}

response = requests.request("GET", url, headers=headers, data=payload)

print(response)

Error Codes

See other common errors here.

Error Code Description
DATA_NOT_FOUND
404
File not found for the given id
RATE_LIMIT_EXCEEDED
429
You have reached the rate limit for file transfer. Please exponentially back off requests until you no longer receive this error

Delete File by Id

Make a Delete request to this endpoint to delete the file

Endpoint: Delete File

DELETE https://api.xendit.co/files/{file-id}

Example Delete File Request

curl https://api.xendit.co/files/file-ec700c1c-db17-4496-b1fb-04ebe551b412 --request DELETE \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
<?php

  $fileId = "file-ec700c1c-db17-4496-b1fb-04ebe551b412";
  $url = "https://api.xendit.co/files/" . $fileId;
  $apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
  $headers = [];

  $curl = curl_init();

  $payload = json_encode($data);
  curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($curl, CURLOPT_USERPWD, $apiKey.":");
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

  $result = curl_exec($curl);
  echo $result;
let apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==";
let fileId= "file-ec700c1c-db17-4496-b1fb-04ebe551b412";
let url = "https://api.xendit.co/files/"+fileId;

var headers = new Headers();
headers.append("Authorization", "Basic " + btoa(apiKey + ":"));


var requestOptions = {
  method: 'DELETE',
  headers: headers,
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
import requests
import base64

api_key = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:"
url = "https://api.xendit.co/files/file-ec700c1c-db17-4496-b1fb-04ebe551b412"

api_key_bytes = api_key.encode('ascii')
base64_bytes = base64.b64encode(api_key_bytes)
base64_token = base64_bytes.decode('ascii')
payload={}

auth_token = 'Basic ' + base64_token
headers = {
  'Authorization': auth_token
}

response = requests.request("DELETE", url, headers=headers, data=payload)

print(response.text)

Response parameters

Example Delete File Success Response

{
  "is_deleted": true,
  "id": "file-ec700c1c-db17-4496-b1fb-04ebe551b412",
  "business_id": "b647524d-9c5d-414c-843a-3c819853d6b0"
}
Body Parameter Type Description
id
required
string Unique ID generated by Xendit for the particular file
business_id
required
string Your Xendit business id
is_deleted
required
boolean Deletion status. True if file was successfully deleted

Error Codes

See other common errors here.

Error Code Description
DATA_NOT_FOUND
404
File not found for the given id

Reports

An API to generate and get report. The available report are Balance and Transaction Report. You can use this endpoint to automate the report generation process. You can use the content of the report to get the detail of transactions and do reconciliation. The report on this API is equivalent to the report that you can download from dashboard.

Report Object

Report Object Example

{
    "id": "report_5c1b34a2-6ceb-4c24-aba9-c836bac82b28",
    "type": "BALANCE_HISTORY",
    "status": "COMPLETED",
    "filter": {
        "from": "2021-06-23T04:01:55.574Z",
        "to": "2021-06-24T04:01:55.574Z"
    },
    "format": "CSV",
    "url": "https://transaction-report-files.s3-us-west-2.amazonaws.com/{report_name}",
    "currency": "IDR",
    "business_id": "5f34f60535ba7c1c0eed846a",
    "created": "2021-06-24T04:01:55.570Z",
    "updated": "2021-06-24T04:01:55.570Z"
}
Body Parameter Type Description
id
required
string The unique id of report. It will have report_ as prefix.
type
required
string The type of report.

Available types:
Type Description
BALANCE_HISTORY Report that shows the historical line per line of your balance. This report is equivalent to Balance History tab in Dashboard. See Balance History Report for more information.
TRANSACTIONS Report that shows history of transaction. This report is equivalent to Transactions tab in Dashboard. See Transactions Report for more information.
UPCOMING_TRANSACTIONS Report that shows the list of upcoming (incoming & outgoing) transactions. This report is equivalent to Upcoming Transaction tab in Dashboard.
filter
required
object Filtering that are applied to report.
Filter Parameter
Key Value
from
required
string (ISO 8601) The start time of the transaction on the report at UTC+0.
to
required
string (ISO 8601) The end time of the transaction on the report at UTC+0.
format
required
string The format of the report.
Available format is CSV.
status
required
string The status of the report. The status will be PENDING when you hit generate the report and will change after that.
Type Description
PENDING The report is acknowledged and being processed.
COMPLETED The report is done and the file can be downloaded.
FAILED The report is failed to be generated. Failed report is safe to retry.
url
optional
string URL to download after report is completed.

The file to download will only be accessible for 24 hours. When the url is expired, you will need to send a new request to generate the report.
currency
required
string The currency inside the report.
See our supported currencies.
business_id
required
string The id of business where this transaction belong to.
created
required
string (ISO 8601 The time when the report request is created at UTC+0.
updated
required
string (ISO 8601 The time when the report is updated at UTC+0.

Generate Report

Endpoint: Generate Report

POST https://api.xendit.co/reports

Request this endpoint to generate the report. You can specify the type and filter the content of the report. The flow of this endpoint is asynchronous. It means Xendit will send callbacks to you after the report is done. See report callback for more information. Alternatively, you can use the get report endpoint to get the report status and its detail.

Request Parameters

Header Parameter Type Description
for-user-id
optional
string The sub-account user-id that you want to get this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information

Example Generate Report Request

curl https://api.xendit.co/reports -X POST \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
   -d type=BALANCE_HISTORY \
   -d currency=IDR

Example Generate Report Response

{
    "id": "report_5c1b34a2-6ceb-4c24-aba9-c836bac82b28",
    "type": "BALANCE_HISTORY",
    "status": "PENDING",
    "filter": {
        "from": "2021-06-23T04:01:55.574Z",
        "to": "2021-06-24T04:01:55.574Z"
    },
    "format": "CSV",
    "currency": "IDR",
    "business_id": "5f34f60535ba7c1c0eed846a",
    "created": "2021-06-24T04:01:55.570Z",
    "updated": "2021-06-24T04:01:55.570Z"
}
Body Parameter Type Description
type
required
string The type of report that will be generated.

Available types:
Type Description
BALANCE_HISTORY Report that shows the historical line per line of your balance. This report is equivalent to Balance History tab in Dashboard. See Balance History Report for more information.
TRANSACTIONS Report that shows history of transaction. This report is equivalent to Transactions tab in Dashboard. See Transactions Report for more information.
UPCOMING_TRANSACTIONS Report that shows the list of upcoming (incoming & outgoing) transactions. This report is equivalent to Upcoming Transaction tab in Dashboard.
filter
required
object Filtering that are applied to report.
Filter Parameter
Key Value
from
string (ISO 8601)
required
The start time of the transaction to be filtered.

If not specified, from is 24 hours before current time
to
string (ISO 8601)
required
The end time of the transaction to be filtered.

If not specified, to is current time. This means if both from and to is not specified, the report will generate the last 24 hours of data.

The combination of from and to must be less than 31 days.
format
optional

default: CSV
string The format of the report.
Available format is CSV.
currency
optional

default: IDR
string The currency to filter.
See our supported currencies.

Response Parameters

Return Report Object with status code 201

Error Codes

See other common errors here.

Error Code Description
FEATURE_NOT_AVAILABLE
400
During this beta, some of customer may encounter this error. Please contact our customer support to enable this feature.
INVALID_DATE_RANGE
400
The from and to filter range is too huge. Please reduce the range according to limit on the request parameter.

Get Report

Endpoint: Get Report

GET https://api.xendit.co/reprots/{report_id}

Request this endpoint to get single specific report details by report id. You can use this endpoint as alternative compared to using the report callback.

Request Parameters

Header Parameter Type Description
for-user-id
optional
string The sub-account user-id that you want to get this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information

Example Get Report

curl https://api.xendit.co/transactions/report_5c1b34a2-6ceb-4c24-aba9-c836bac82b28 -X GET \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:

Example Get Report Response

{
    "id": "report_5c1b34a2-6ceb-4c24-aba9-c836bac82b28",
    "type": "BALANCE_HISTORY",
    "status": "COMPLETED",
    "filter": {
        "from": "2021-06-23T04:01:55.574Z",
        "to": "2021-06-24T04:01:55.574Z"
    },
    "format": "CSV",
    "url": "https://transaction-report-files.s3-us-west-2.amazonaws.com/{report_name}",
    "currency": "IDR",
    "business_id": "5f34f60535ba7c1c0eed846a",
    "created": "2021-06-24T04:01:55.570Z",
    "updated": "2021-06-24T04:01:55.570Z"
}
Path Parameter Type Description
report_id
required
string The id of report.

Response Parameters

Return Report Object with status code 200

Error Codes

See other common errors here.

Error Code Description
TRANSACTION_NOT_FOUND
404
Report the id is not found.
FEATURE_NOT_AVAILABLE
400
During this beta, some of customer may encounter this error. Please contact our customer support to enable this feature.

Report Callback

Endpoint: Report Callback

POST https://yourcompany.com/report_callback_url

Xendit notifies your system upon the completed or failed report via callback. You need to provide an URL to receive callback. Please specify your URL in Callback Settings in Xendit Dashboard.

The payment notification will be sent as POST request to the URL you set. Xendit attach x-callback-token header that you can validate against Verification Token in Callback Settings to verify message authenticity.

Please response back with status 200 immediately. Xendit marks callback event as failed if there is no response within 30s. When events failed, automatic retry will kick-off for the next 24h. Alternatively, you can resend any event in Callback tab at anytime. You can also receive notification via email every 6h to check your callback health.

Learn more about Callback

Callback Payload

Example Report Callback Request for Successful Report

curl --include \
     --request POST \
     --header "X-CALLBACK-TOKEN: MuaJALKJSDK12LASHD123kSAKSDHzjahwUWjkasJSDSA12KSNAK21n==" \
     --header "Content-Type: application/json" \
     --data-binary "{
    \"id\": \"report_5c1b34a2-6ceb-4c24-aba9-c836bac82b28\",
    \"type\": \"BALANCE_HISTORY\",
    \"status\": \"PENDING\",
    \"filter\": {
        \"from\": \"2021-06-23T04:01:55.574Z\",
        \"to\": \"2021-06-24T04:01:55.574Z\"
    },
    \"format\": \"CSV\",
    \"currency\": \"IDR\",
    \"business_id\": \"5f34f60535ba7c1c0eed846a\",
    \"created\": \"2021-06-24T04:01:55.570Z\",
    \"updated\": \"2021-06-24T04:01:55.570Z\"
}}" \
'{{your_company_domain}}/{{callback_url}}'
Body Parameter Type Description
event
required
string The type of the event. The available types are:
Type Description
reports.completed Report is completed. You can download the report from the url parameter.
reports.failed Report is failed to generate. You are safe tor retry the report request.
Report Object The rest of parameter is the same as report object.

Balance History Report

Balance history report is report that show the historical list of balance movements from your accounts. This report is equivalent to Balance Tab on dashboard. You can use this report for checking the daily balance or do reconciliation between your transaction data with the balance that are deducted or added into your account. On the report API you can generate this report by using BALANCE_HISTORY as a type.

Report Columns

Column Description
Product Id Xendit generated ID which will be sent to you via API callback as ‘id’
Transaction Id Xendit uniquely generated ID for each transactions and this ID help you identify Fee or Reversal for specific transactions. This ID can be used to reconcile between Balance History Report and Transaction Report.
Transaction Type List of available transaction type
VA_PAYMENT Payment using Virtual Account
RO_PAYMENT Payment using Retail Outlet
EWALLET_PAYMENT Payment using Ewallet
CARDLESS_CREDIT_PAYMENT Payment using Cardless Credit
DIRECT_DEBIT_PAYMENT Payment using Direct Debit
CREDIT_CARD_PAYMENT Payment using Credit Card
QR_CODE_PAYMENT Payment using QR Code
DISBURSEMENT Disbursement
BATCH_DISBURSEMENT Batch Disbursement
REMITTANCE_PAYOUT Remittance Payout
DEPOSIT Topup to your account
WITHDRAWAL Withdrawal from your account
Line Type List of available line type
TRANSACTION The transaction row, the deduction/addition of balance because of transaction
FEE The fee row, the deduction of balance because of fee
VAT The VAT row, the deduction of balance because of VAT
TRANSACTION_REVERSAL, FEE_REVERSAL, VAT_REVERSAL The reversal of TRANSACTION, FEE, or VAT
Payment Channel The channel to identify the source of the transaction.
See channel codes for more information.
Reference Your generated ID which will be sent to Xendit’s system and will also be available on some product callback as ‘external_id’
Currency Transaction currency.
See our supported currencies.
Amount Nominal amount for the transaction.
The number of decimal place will be different for each currency according to ISO 4217.
Balance Your account balance on this transaction.
Debit or Credit
DEBIT Balance is deducted
CREDIT Balance is added
Created Date ISO Date on when the transaction is created using ISO 8601 format.
Timezone Timezone information formatted as “+XXXX UTC”.
The timezone will always be +0000 UTC when report is generated via this API. This is different from Dashboart which will use the user timezone.
Created Date Date on when the transaction is created.
Payment Date Date on when payment is received but not yet settled. This is only available for payment transaction.
Settlement Date Date on when payment is settled. This means the fund is already received and added to your balance. This is only available for payment transaction.
Completed Date Date on when fund has been disbursed to the destination bank account. This is only available for disbursement transaction.
Bank Code The bank channel that are used as source or destination of transaction. This is only available for VA_PAYMENT and DISBURSEMENT.
Name The name of the VA or receiver. This is only available for VA_PAYMENT and DISBURSEMENT.
Account Number The account number of VA or receiver. This is only available for VA_PAYMENT and DISBURSEMENT.
Description The description of transaction
Invoice ID The ID of invoice. This is only available for payment that are paid via invoice.
Bank Reference The bank reference that is used only for DISBUSEMENT transaction

Transactions Report

Transaction reports are the report that shows all transactions that exist whether it is already deduct the balance or not. This report will not show the non-transaction like topup and withdrawal. This report is equivalent to the Transaction Tab on the dashboard. On the report API you can generate this report by using TRANSACTIONS as a type.

Report Columns

Column Description
Status The corresponding transaction status
PENDING The transaction is still in processing. This refers to money out-transaction when the amount is still on hold
SUCCESS The transaction is successfully sent for money-out or already arrives on money-in
FAILED The transaction failed to send/receive
VOIDED The money-in transaction is voided by you
REFUNDED The money-in transaction is refunded by you
REVERSED The transaction is reversed by Xendit
Type The corresponding transaction type
DISBURSEMENT The disbursement transaction
PAYMENT The payment transaction. All kind of money-in
REMITTANCE_PAYOUT The remittance pay-out transaction
TRANSFER The transfer transaction between Xendit account. This can be transfer in or out
Channel The channel to identify the source of the transaction.
The available channel for each type are:
Type Channels
DISBURSEMENT and REMITTANCE_PAYOUT BANK and CASH
PAYMENT CARDS, CARDLESS_CREDIT, DIRECT_DEBIT, EWALLET, PAYLATER, QR_CODE, RETAIL_OUTLET, VIRTUAL_ACCOUNT
TRANSFER XENPLATFORM
Channel Name Channel name will be different for each channel.
See channel codes for more information
Account Number The account number used for the transaction. The definition of this will be different for each channel. For example, on CARD channel this will be masked card number and on BANK channel it will be account number.
Currency Transaction currency.
See our supported currencies.
Amount Amount of the transaction.
The number of decimal place will be different for each currency according to ISO 4217.
Fee Amount Amount of the fee for this transaction.
VAT Amount Amount of the VAT for this transaction.
3rd Party WHT Amount of the 3rd Party Withholding Tax for this transaction if applicable.
Xendit WHT Amount of the Xendit Withholding Tax for this transaction if applicable.
Net Amount Net Amount of transaction after fee/VAT/WHT is included.
Reference The reference of transaction. This is generated from your side and on some product is known as External Id
Transaction Id The id of the transaction
Invoice Id The id of the invoice, if this transaction is payment using invoice
Batch Id Batch settlement id for credit card transaction
Payment Id Xendit generated payment id which are equivalent to product Id
Payment Date The date when the payment is received to Xendit
Timestamp - Created The timestamp when the transaction is recorded
Timestamp - Updated The timestamp of the latest update occurring for the transaction
Timestamp - Settled The timestamp when the transaction is settled to the merchant
Timezone Timezone information formatted as “+XXXX UTC”.
The timezone will always be +0000 UTC when report is generated via this API. This is different from Dashboart which will use the user timezone.
Description The description of transaction
Channel Reference The reference that is generated by our channel partner. This can be used to reconcile between the data from your side, Xendit, and our partner.

Transactions

An API to search and view transactions. The transactions include money in, money out, and transfer that happens within your account. You can use this single endpoint to get the status of a transaction and do reconciliation. This API is equivalent to the transactions tab from dashboard. See our docs of how to use transaction tab for reconciliation.

Transaction Object

Transaction Object Example

{
    "id": "txn_13dd178d-41fa-40b7-8fd3-f83675d6f413",
    "product_id": "d290f1ee-6c54-4b01-90e6-d701748f0701",
    "type": "PAYMENT",
    "channel_category": "RETAIL_OUTLET",
    "channel_code": "ALFAMART",
    "reference_id": "ref23232",
    "account_identifier": null,
    "currency": "IDR",
    "amount": 1,
    "cashflow": "MONEY_IN",
    "status": "SUCCESS",
    "business_id": "5fc9f5b246f820517e38c84d",
    "created": "2021-06-23T02:42:15.601Z",
    "updated": "2021-06-23T02:42:15.601Z"
}
Body Parameter Type Description
id
required
string The unique id of transaction. It will have txn_ as prefix
product_id
required
string The product_id of transaction. Product id will have different prefix for each different product. You can use this id to match the transaction from this API to each product API.
type
required
string The type of the transactions.

Available types:
Type Description
DISBURSEMENT The disbursement of money-out transaction.
PAYMENT The payment that includes all variation of money-in transaction.
REMITTANCE_PAYOUT The remittance pay-out transaction.
TRANSFER The transfer transaction between xendit account. This can be transfer in or out.
channel
optional
string The channel of the transaction that is used.
See channel codes for the list of available per channel categories.
reference_id
required
string The reference of transaction.
On some product, the term reference is the same as external_id. This is the id that you generate that can be used for reconciliation.
account_identifier
optional
string Account identifier of transaction. The format will be different from each channel. For example, on BANK channel it will be account number and on CARD it will be masked card number.
currency
optional
string (ISO 4217) Currency of transaction.
See our supported currencies.
amount
required
number The amount of transaction.
The number of decimal place will be different for each currency according to ISO 4217.
net_amount
required
number The net amount of transaction after it deducted with fee/vat.
cashflow
required
string Representing whether the transaction is money in or money out For transfer, the transfer out side it will shows up as money out and on transfer in side in will shows up as money-in.
Available values are MONEY_IN for money in and MONEY_OUT for money out.
status
required
string The status of the transaction.

Available status:
Status Description
PENDING The transaction is still pending to be processed. This refers to money out-transaction when the amount is still on hold.
SUCCESS The transaction is successfully sent for money-out or already arrives on money-in.
FAILED The transaction failed to send/receive.
VOIDED The money-in transaction is voided by customer.
REFUNDED The money-in transaction is refunded by the customer.
REVERSED The transaction is reversed by Xendit.
channel_category
required
string The channel category of the transaction to identify the source of the transaction.
The available channel for each type are:
Type Channels
DISBURSEMENT and REMITTANCE_PAYOUT BANK and CASH
PAYMENT CARDS, CARDLESS_CREDIT, DIRECT_DEBIT, EWALLET, PAYLATER, QR_CODE, RETAIL_OUTLET, VIRTUAL_ACCOUNT
TRANSFER XENPLATFORM
business_id
required
string The id of business where this transaction belong to
created
required
string (ISO 8601) Transaction created timestamp on UTC+0
updated
required
string (ISO 8601) Transaction updated timestamp on UTC+0

Get Transaction

Endpoint: Get Transaction

GET https://api.xendit.co/transactions/{transaction_id}

Request this endpoint to get single specific transaction details by transaction id. If you need to search by other parameters or to get multiple result, see list transactions.

Request Parameters

Header Parameter Type Description
for-user-id
optional
string The sub-account user-id that you want to get this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information

Example Get Transaction Request

curl https://api.xendit.co/transactions/txn_13dd178d-41fa-40b7-8fd3-f83675d6f413 -X GET \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:

Example Get Transaction Response

{
    "id": "txn_13dd178d-41fa-40b7-8fd3-f83675d6f413",
    "product_id": "d290f1ee-6c54-4b01-90e6-d701748f0701",
    "type": "PAYMENT",
    "status": "SUCCESS",
    "channel_category": "RETAIL_OUTLET",
    "channel_code": "ALFAMART",
    "reference_id": "ref23232",
    "account_identifier": null,
    "currency": "IDR",
    "amount": 1,
    "cashflow": "MONEY_IN",
    "business_id": "5fc9f5b246f820517e38c84d",
    "created": "2021-06-23T02:42:15.601Z",
    "updated": "2021-06-23T02:42:15.601Z"
}
Path Parameter Type Description
transaction_id
required
string The id of transaction.

Response Parameters

Returns Transaction Object with status code 200

Error Codes

See other common errors here.

Error Code Description
TRANSACTION_NOT_FOUND
404
Transaction with the id is not found.
FEATURE_NOT_AVAILABLE
400
During this beta, some of customer may encounter this error. Please contact our customer support to enable this feature.

List Transactions

Endpoint: List Transactions

GET https://api.xendit.co/transactions

Request this endpoint to get all transactions or select specific filter and search parameters. You can filter by date, type, or status. And you can search by reference, product id, or account identifier. The returned result will be paginated and ordered by the created date.

Request Parameters

Header Parameter Type Description
for-user-id
optional
string The sub-account user-id that you want to get this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information

Example List Transactions Request

curl https://api.xendit.co/transactions?types=PAYMENT&statuses=SUCCESS&channel_categories=EWALLET&channel_categories=RETAIL_OUTLET&limit=2 -X GET \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
Query Parameter Type Description
types
optional
array of strings The type of the transactions that will be filtered. If not specified, all transaction type will be returned.

Available types:
DISBURSEMENT: The disbursement of money-out transaction.
PAYMENT: The payment that includes all variation of money-in transaction.
REMITTANCE_PAYOUT: The remittance pay-out transaction.
TRANSFER: The transfer transaction between xendit account. This can be transfer in or out.
statuses
optional
array of strings The status of the transactions that will be filtered. If not specified, all transaction status will be returned.

Available status:
PENDING: The transaction is still pending to be processed. This refers to money out-transaction when the amount is still on hold.
SUCCESS: The transaction is successfully sent for money-out or already arrives on money-in.
FAILED: The transaction failed to send/receive.
VOIDED: The money-in transaction is voided by customer.
REFUNDED: The money-in transaction is refunded by the customer.
REVERSED: The transaction is reversed by Xendit.
channel_categories
optional
array of strings The channel of the transactions that will be filtered. If not specified, all transaction channel will be returned.

For DISBURSEMENT and REMITTANCE_PAYOUT type, the available channel categories are BANK and CASH.
For PAYMENT type, the available channel categories are CARDS, CARDLESS_CREDIT, DIRECT_DEBIT, EWALLET, PAYLATER, QR_CODE, RETAIL_OUTLET, VIRTUAL_ACCOUNT.
For TRANSFER type, the available channel category is XENPLATFORM.
reference_id
optional
string Reference that will be searched. Search by reference is case sensitive and can be partial match.
product_id
optional
string Product_id that will be searched. Product_id search is an exact match and case sensitive.
account_identifier
optional
string Account identifier that will be searched. Account identifier search is exact match case sensitive.
currency
optional

default: IDR
string (ISO 4217) Currency to filter. See our supported currencies.
amount
optional
number Transaction amount to search. This will be exact match.
created[gte]
optional
string (ISO 8601) Start time of transaction by created date. If not specified will list all dates.
created[lte]
optional
string (ISO 8601) End time of transaction by created date. If not specified will list all dates.
updated[lte]
optional
string (ISO 8601) End time of transaction by updated date. If not specified will list all dates.
updated[gte]
optional
string (ISO 8601) Start time of transaction by updated date. If not specified will list all dates.
limit
optional

default: 10
number A limit on the number of transactions to be returned for each request.
Limit can range between 1 and 50.
after_id
optional
string Id of the immediately previous item. Use this with links on the response for pagination.
before_id
optional
string Id of the immediately following item.

Response Parameters

Example List Transactions Response

{
    "has_more": true,
    "data": [
        {
            "id": "txn_13dd178d-41fa-40b7-8fd3-f83675d6f413",
            "product_id": "d290f1ee-6c54-4b01-90e6-d701748f0701",
            "type": "PAYMENT",
            "status": "SUCCESS",
            "channel_category": "RETAIL_OUTLET",
            "channel_code": "ALFAMART",
            "reference_id": "ref23244",
            "account_identifier": null,
            "currency": "IDR",
            "amount": 1,
            "cashflow": "MONEY_IN",
            "business_id": "5fc9f5b246f820517e38c84d",
            "created": "2021-06-23T02:42:15.601Z",
            "updated": "2021-06-23T02:42:15.601Z"
        },
        {
            "id": "txn_a765a3f0-34c0-41ee-8686-bca11835ebdc",
            "product_id": "d290f1ee-6c54-4b01-90e6-d701748f0700",
            "type": "PAYMENT",
            "status": "SUCCESS",
            "channel_category": "RETAIL_OUTLET",
            "channel_code": "ALFAMART",
            "reference_id": "ref242424",
            "account_identifier": null,
            "currency": "IDR",
            "amount": 1,
            "cashflow": "MONEY_IN",
            "business_id": "5fc9f5b246f820517e38c84d",
            "created": "2021-06-23T02:39:23.176Z",
            "updated": "2021-06-23T02:39:23.176Z"
        }
    ],
    "links": [
        {
            "href": "/transactions?types=PAYMENT&statuses=SUCCESS&channel_categories=EWALLET&channel_categories=RETAIL_OUTLET&limit=2&after_id=txn_a765a3f0-34c0-41ee-8686-bca11835ebdc",
            "method": "GET",
            "rel": "next"
        }
    ]
}
Body Parameter Type Description
data
required
array of objects Returns an array of Transaction Object. Returns empty array when there is no result.
has_more
required
bolean Indicates whether there are more items to be queried with after_id of the last item from the current result.
Use the links to follow to the next result.
links
optional
object The links to the next page based on HATEOAS if there is next result.
The HATEOAS format are:
href: URI of target, this will be to the next link.
rel: The relationship between source and target. The value will be next.
method: The HTTP method, the alue will be GET.

Error Codes

See other common errors here.

Error Code Description
FEATURE_NOT_AVAILABLE
400
During this beta, some of customer may encounter this error. Please contact our customer support to enable this feature.

Credit Cards

Our Credit Cards API enables you to seamlessly charge Indonesian and international credit / debit cards from major schemes: Visa, MasterCard and JCB. To accept AMEX payments, you'll need your own merchant account with Bank Central Asia in Indonesia.

Our APIs are designed to be modular so you can have full control over each step of the card payment process. No sensitive card data will reach your servers when using Xendit - we take care of that for you. We build our integrations to optimize card acceptance rates for all the cards that we help you accept. To date, we've charged cards from over 100 countries.

For full details on each API as well as help on integration, please refer to our documentation.

Using a plugin like Shopify or WooCommerce (Wordpress)? Xendit supports card payments on these as well, see here.

Create Token

Javascript Function: createToken

Xendit.card.createToken(tokenData, function (err, data) {
    if (err) {
        //Define error handling
    }

    if (data.status === 'VERIFIED') {
        // Handle success
    } else if (data.status === 'IN_REVIEW') {
        // Handle authentication (3DS)
    } else if (data.status === 'FAILED') {
        // Handle failure
    }
});

Tokenization is the process where card details (account number and expiration date) are securely collected on the client-side, so that sensitive card data is never passed through your systems. Tokens are then used to Charge Cards. It is important to pass us the details of the cardholder such as their contact details and billing/shipping details, as these will be used for 3DS authentication later on.

Example tokenData object with billing details

{        
    "amount": "10000",        
    "card_data": {
        "account_number": "4456530000001096",        
        "exp_month": "12",        
        "exp_year": "2020"
    },
    "card_cvn": "123",
    "is_multiple_use": false,
    "should_authenticate": true,
    "billing_details": {
        "given_names": "John",
        "surname": "Hudson",
        "email": "john@xendit.co",
        "mobile_number": "+6208123123123",
        "phone_number": "+6208123123123",
        "address": {
            "country": "ID",
            "street_line1": "Panglima Polim IV",
            "street_line2": "Ruko Grand Panglima Polim, Blok E",
            "city": "Jakarta Selatan",
            "province_state": "DKI Jakarta",
            "postal_code": "12345"
        }
    }
}

Example tokenData object with customer object

{        
    "amount": "10000",        
    "card_data": {
        "account_number": "4456530000001096",        
        "exp_month": "12",        
        "exp_year": "2020"
    },
    "card_cvn": "123",
    "is_multiple_use": false,
    "should_authenticate": true,
    "customer": {
        "reference_id": "123e4567-e89b-12d3-a456-426614174000",
        "mobile_number": "+6208123123123",
        "email": "john@xendit.co",
        "given_names": "John",
        "surname": "Hudson",
        "phone_number": "+6208123123123",
        "nationality": "ID",
        "addresses": [{
            "country": "ID",
            "street_line1": "Panglima Polim IV",
            "street_line2": "Ruko Grand Panglima Polim, Blok E",
            "city": "Jakarta Selatan",
            "province_state": "DKI Jakarta",
            "postal_code": "12345",
            "category": "WORK"
        }],
        "date_of_birth": "1990-04-13",
        "description": "customer using promo",
        "metadata": {}
    }
}

Tokens can be created for single or multiple use. If you plan to save a card for future use, set is_multiple_use to true.

See our Tokenization Sample for an example implementation for web application. For SDK implementation, please refer to Xendit Documentation for Android SDK and IOS SDK.

Single Use Tokens

For single-use tokens, authentication is performed by default, and so the amount field is also required. If optional authentication is enabled on your account, it can be bypassed by setting should_authenticate to false.

Multiple Use Tokens

When tokenizing a card for multi-use, the amount field is optional. If you want to use Authentication for a multi-use token, the amount field must be specified during Authentication. See Create Authentication for more details.

Request Parameters (Money-in write permission)

Header Parameter Type Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.
This header is only used if you have access to xenPlatform. See xenPlatform for more information

Body Parameter Type Description
amount
optional
string The charge amount. Only required for single use tokens with bundled authentication.
card_number
required
string Card number which will be converted into a secured token
card_exp_month
required
string Card expiration month
card_exp_year
required
string Card expiration year
card_cvn
optional
string Three digit code written on the back of the card (usually called CVV/CVN). Optional but highly recommended. Required for cards issued in Europe.
is_multiple_use
optional default: false
boolean Whether or not to save token for multiple use
currency
optional default: IDR
string Currency which you want to process the transaction in. Use a three-letter ISO currency code. Xendit supports IDR and PHP by default. Other currencies are supported only if you are using your own MIDs. If left blank, defaults to IDR
should_authenticate
default: true
boolean Whether or not to bundle authentication with tokenization.
By default, authentication is required for all transactions. You can request to enable optional authentication via your Xendit Dashboard.
billing_details
optional
object Billing details of the cardholder. If entered, should correspond with billing details registered by the cardholder with their issuer. These are required for US / CA / UK cards to be verified by the Address Verification System (AVS), and are also required for 3DS 2.0 authentication.
billing details child parameters
Key Value
given_names
optional
string Primary or first name/s of the customer
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
surname
optional
string Surname or last name of the customer
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
email
optional
string Enduser's email address which associated with the card
mobile_number
optional
string Enduser's mobile phone number which associated with the card
phone_number
optional
string Enduser's other phone number which associated with the card (e.g. landline)
address
optional
object Billing Address of the cardholder
Note: Required for AVS and 3DS 2.0
address details child parameters
Key Value
country
required
string 2-letter ISO 3166-2 country code for the customer's country of residence
street_line1
optional
string Building name and apartment unit number
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
street_line2
optional
string Building street address
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
city
optional
string City, village or town as appropriate
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
province_state
optional
string Use this to enter province, state or region of residence. If the user is USA citizen, make sure to use state code (e.g put CA instead of California)
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
postal_code
optional
string Postal, zip or rural delivery code, if applicable
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
customer
optional
object Information about your customer (the cardholder), e.g. their contact details. Sending these details is recommended as they are needed for the best authentication protocols, improving acceptance rates and fraud prevention. Use this object to pass Xendit the customer’s shipping address if they provide it.
Customer object child parameters
Key Value
reference_id
optional
string This is the customer ID that is referenced in your system, if you have previously created a Customer with our Create Customer API.
minimum length: 1 character
maximum length: 255 characters
mobile_number
optional
string Mobile number of customer in E.164 format
Note: Required for AVS and 3DS 2.0
phone_number
optional
string Additional contact number of the customer. can be landline
Note: Required for AVS and 3DS 2.0
email
optional
string Additional contact number of the customer. can be landline
Note: Required for AVS and 3DS 2.0
given_names
optional
string Primary or first name/s of customer
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
surname
optional
string Surname (or last name) of the customer
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
nationality
optional
string Country code for the customer’s nationality 2-letter ISO 3166-2 country code
date_of_birth
optional
string Date of birth of the customer in YYYY-MM-DD format
description
optional
string Merchant-provided description for the customer object
minimum length: 1 character
maximum length: 500 characters
metadata
optional
object A free-format JSON for additional information that you want to provide in the request.
addresses
optional
Array of JSON Information about the customer’s address. Use this to pass Xendit the customer’s shipping address if they provide it. Billing address should be provided in the billing details object above.
object addresses details child parameters
Key Value
country
required
string 2-letter ISO 3166-2 country code for the customer's country of residence
street_line1
optional
stringLine 1 of Building name and apartment unit number
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
street_line2
optional
stringLine 2 of Building street address
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
city
optional
string City, village or town as appropriate of customer
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
province_state
optional
string Use this to enter province, state or region of residence. If the user is USA citizen, make sure to use state code (e.g put CA instead of California)
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
postal_code
optional
string Postal, zip or rural delivery code, if applicable
minimum length: 1 character
maximum length: 255 characters
Note: Required for AVS and 3DS 2.0
category
optional
string Address type. Supported values: HOME, WORK, PROVINCIAL

Example Tokenization Response

{
    "id": "5fcd8deb93e9a90020d8fd2d",
    "masked_card_number": "445653XXXXXX1096",
    "authentication_id": "5fcd8deb93e9a90020d8fd2e",
    "status": "IN_REVIEW",
    "card_info": {
        "bank": "PT. Bank Rakyat Indonesia (Persero)",
        "country": "ID",
        "type": "CREDIT",
        "brand": "VISA"
    },
    "payer_authentication_url": "https://redirect-staging.xendit.co/redirects/authentications/bundled/5fcd8deb93e9a90020d8fd2d?api_key=xnd_public_development_bPgL7lc65YTfywEk10f5qneRuu537yonRbfgQRMBLPUr1mZP4nNVd7iNHU"
}

Response Parameters

Body Parameter Type Description
id
required
string The token ID. This will be used later to Charge the funds from the credit card.
authentication_id
required
string ID for the authentication process. This should be attached during charge in authentication_id field
masked_card_number
required
string The first 6 digits and last 4 digits of the tokenized card.
status
required
string Tokenization status. See Tokenization Statuses
payer_authentication_url
optional
string Returned only if authentication is bundled with tokenization, and the status returned is IN_REVIEW. This field contains the URL to the page for users to authenticate themselves using 3DS. See Tokenization Statuses.
failure_reason
optional
string If the tokenization status is FAILED, this describes the reason for failure. See Tokenization Failure Reasons
card_info
optional
object Information of the card that's already tokenized.
card info child parameters
Key Value
bank
optional
string Bank name which issued the card
country
optional
string 2-letter ISO 3166-2 country code Country code where the card is issued from
type
optional
string Type of card that is being tokenized. Can be CREDIT, DEBIT, PREPAID, and UNKNOWN
brand
optional
string Brand of the card that is being tokenized. Can be VISA, MASTERCARD, JCB, AMEX

Statuses

Status Description
IN_REVIEW Returned only if authentication is bundled with tokenization, and therefore the customer must authenticate their identity. Xendit provides a URL which you should navigate your users to for easily performing 3DS.
VERIFIED This means that a token was successfully created. If authentication was bundled with tokenization, it also means that the user has successfully authenticated their identity via 3DS. It is now safe to send the token to your backend for charging.
FAILED Returned only if authentication is bundled with tokenization, and authentication has failed. Will always return AUTHENTICATION_FAILED as the failure reason.
The token will still be created and authentication can be attempted again using the created token.

Failure Reasons

Failure Reason Description
AUTHENTICATION_FAILED This status means the customer tried to authenticate using 3DS but did not successfully complete the authentication.

Error Codes

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
INVALID_JSON_FORMAT
400
The request body is not valid JSON.
ACCOUNT_NUMBER_INVALID_ERROR
400
Credit card number is invalid.
VALIDATION_ERROR
400
Data was passed in an incorrect format.
BRAND_NOT_SUPPORTED_ERROR
400
Card brand is not supported. Ask user to try a Visa/Mastercard.
AUTHENTICATION_REQUIRED_ERROR
400
A valid authentication_id was not included in the request, and your account is not configured for optional authentication. Include a valid authentication_id or contact us if you would like to enable optional authentication.
REQUEST_FORBIDDEN_ERROR
403
API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here
VERIFICATION_TIMEOUT_ERROR
408
The credit card network timed out when trying to tokenize the card.
TEMPORARY_SERVICE_ERROR
503
There was a problem with the credit card network, which prevents tokenization.
CONNECTION_ERROR
500
Error connecting to our server. Try again and if the error persists, try with another device/network.

Get Token

Definition: Get Token

GET https://api.xendit.co/credit_card_tokens/:credit_card_token_id

Example Get Token Request Using Token ID (Default)

curl https://api.xendit.co/credit_card_tokens/605c05d3f81fa60011b2fa4e \
    -X GET \
    -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==:

Example Get Token Response

{
  "business_id": "602103396f17450020ca2246",
  "created": "2021-03-25T03:38:59.318Z",
  "id": "605c05d3f81fa60011b2fa4e",
  "status": "VALID",
  "card_expiration_month": "12",
  "card_expiration_year": "2025",
  "metadata": {
      "bank": "PT. Bank Rakyat Indonesia (Persero)",
      "country_code": "US",
      "type": "CREDIT",
      "brand": "VISA",
  },
  "card_info": {
      "bank": "PT. Bank Rakyat Indonesia (Persero)",
      "country": "ID",
      "type": "CREDIT",
      "brand": "VISA",
      "card_art_url": "",
      "fingerprint": "6021f7d3717e0500115fbb0d",
  }, 
}

This is endpoint to get a token object. You need to specify the id in the query parameter.

Request Parameters

Header Parameter Type Description
for-user-id
optional
string The sub-account user-id that you want to the token for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information

Query Parameter Type Description
credit_card_token_id
required
string token id of credit card that has been tokenized.

Error Codes

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
CREDIT_CARD_TOKEN_NOT_FOUND_ERROR
404
credit_card_token_id not found

Create Authentication

Javascript Function: createAuthentication

Xendit.card.createAuthentication(authenticationData, function (err, data) {
    if (err) {
        //Define error handling
    }

    if (data.status === 'VERIFIED') {
        // Handle success
    } else if (data.status === 'IN_REVIEW') {
        // Handle authentication (3DS)
    } else if (data.status === 'FAILED') {
        // Handle failure
    }
});

To authenticate a token, use the Xendit.card.createAuthentication function in Xendit.js. This function accepts an authenticationData object and returns an authentication_id which can be used to authenticate a charge. For more details on creating a charge, see Create Charge.

See our Authentication Sample for an example implementation.

Example authenticationData object

{
    "amount": "10000",
    "token_id": "58e2096018b815f555c8a524"
}

Example Authentication Response

{
    "id": "58e2097218b815f555c8a526",
    "status": "VERIFIED"
}

Request Parameters

Header Parameter Type Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information

Body Parameter Type Description
amount
required
string Authentication amount
token_id
required
string Token to authenticate
currency
optional
default: IDR
string Currency which you want to process the transaction in. Use a three-letter ISO currency code Supported currencies include IDR, PHP & USD.
xenditResponseHandler
required
function Response handler, called after authentication attempt to handle errors and response.

Response Parameters

Parameter Type Description
id
required
string Authentication ID returned by Xendit, used when creating a Charge. If authentication status is FAILED, this id will still be returned but authentication will need to be performed again.
status
required
string Authentication status. See Tokenization Statuses
payer_authentication_url
optional
string If status is IN_REVIEW, this contains the URL for authenticating users with 3DS
failure_reason
optional
string If status is FAILED, this describes the failure. See Tokenization Failure Reasons.

Failure Reasons

Failure Reason Description
AUTHENTICATION_FAILED The customer tried to authenticate using 3DS but did not successfully complete the authentication.

Create Authorization

Definition: Create authorization

POST https://api.xendit.co/credit_card_charges

Example Create Authorization Request

curl -X POST \
  https://api.xendit.co/credit_card_charges \
  -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \
  -H 'content-type: application/json' \
  -d '{
      "token_id" : "598d5d0e51e0870d44c61534",
      "external_id": "postman-charge-1502436817",
      "amount": 140000,
      "authentication_id":"598d5d0f51e0870d44c61535",
      "card_cvn":"123",
      "capture":false
    }'
<?php
  require 'vendor/autoload.php';

  $options['secret_api_key'] = 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==';

  $xenditPHPClient = new XenditClient\XenditPHPClient($options);

  $external_id = 'sample-external-id-1475459775872';
  $token_id = 'sample-token-id-1475459775872';
  $amount = 140000;
  $authentication_id = '58e2097218b815f555c8a526';
  $capture = false;

  $response = $xenditPHPClient->captureCreditCardPayment($external_id, $token_id, $amount);
  print_r($response);
?>
const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });

const { Card } = x;
const cardSpecificOptions = {};
const card = new Card(cardSpecificOptions);

const resp = await card.createAuthorization({
  externalID: 'sample-external-id-1475459775872',
  tokenID: 'sample-token-id-1475459775872',
  amount: 140000,
  authID: '58e2097218b815f555c8a526',
})
console.log(resp);
Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
try {
  CreditCardCharge creditCardCharge = CreditCard.createAuthorization(
  "token_id", // tokenId
  "postman-charge-1502436793", // externalId
  140000, // amount
  "auth_id", // authenticationId
  "123", // Card CVN
  false // capture
  );
} catch (XenditException e) {
  e.printStackTrace();
}
from xendit import Xendit

api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
xendit_instance = Xendit(api_key=api_key)
CreditCard = xendit_instance.CreditCard

charge = CreditCard.create_authorization(
    token_id="5f0410898bcf7a001a00879d",
    external_id="card_preAuth-1594106356",
    amount=75000,
    card_cvn="123",
)
print(charge)

Example Create Authorization Response

{
    "created": "2020-01-11T07:33:14.442Z",
    "status": "AUTHORIZED",
    "business_id": "5850e55d8d9791bd40096364",
    "authorized_amount": 140000,
    "external_id": "postman-charge-1502436793",
    "merchant_id": "xendit",
    "merchant_reference_code": "598d5d0d51e0870d44c61533",
    "card_type": "CREDIT",
    "masked_card_number": "400000XXXXXX0002",
    "charge_type": "SINGLE_USE_TOKEN",
    "card_brand": "VISA",
    "bank_reconciliation_id": "5132390610356134503009",
    "eci": "05",
    "id": "598d5dba51e0870d44c61539"
}

You can do authorization using create charge endpoint. Just capture field as false, and you will receive an authorized charge response.

Zero Amount Authorization

You can also do zero amount authorization amount using create charge endpoint. Just put 0 for amount field, and you will receive and authorized charge response.

To be able to do zero amount authorization, your account must have card processor that has zero amount authorization compatibility.
Please contact us to set up zero amount compatible card processor for your account. You can always use development environment to try zero amount authorization feature.

Example Zero Amount Authorization Request

curl -X POST \
  https://api.xendit.co/credit_card_charges \
  -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \
  -H 'content-type: application/json' \
  -d '{
      "token_id" : "598d5d0e51e0870d44c61534",
      "external_id": "postman-charge-1502436817",
      "amount": 0,
      "authentication_id":"598d5d0f51e0870d44c61535",
      "card_cvn":"123"
    }'
<?php
  require 'vendor/autoload.php';

  $options['secret_api_key'] = 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==';

  $xenditPHPClient = new XenditClient\XenditPHPClient($options);

  $external_id = 'sample-external-id-1475459775872';
  $token_id = 'sample-token-id-1475459775872';
  $amount = 0;
  $authentication_id = '58e2097218b815f555c8a526';

  $response = $xenditPHPClient->captureCreditCardPayment($external_id, $token_id, $amount);
  print_r($response);
?>
const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });

const { Card } = x;
const cardSpecificOptions = {};
const card = new Card(cardSpecificOptions);

const resp = await card.createAuthorization({
  externalID: 'sample-external-id-1475459775872',
  tokenID: 'sample-token-id-1475459775872',
  amount: 0,
  authID: '58e2097218b815f555c8a526',
});
console.log(resp);
Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
try {
  CreditCardCharge creditCardCharge = CreditCard.createAuthorization(
  "token_id", // tokenId
  "test_id", // externalId
  0, // amount
  "auth_id", // authenticationId
  "123", // Card CVN
  false // capture
  );
} catch (XenditException e) {
  e.printStackTrace();
}

Example Zero Amount Authorization Response

{
    "created": "2020-01-11T07:33:14.442Z",
    "status": "AUTHORIZED",
    "business_id": "5850e55d8d9791bd40096364",
    "authorized_amount": 0,
    "external_id": "postman-charge-1502436793",
    "merchant_id": "xendit",
    "merchant_reference_code": "598d5d0d51e0870d44c61533",
    "card_type": "CREDIT",
    "masked_card_number": "400000XXXXXX0002",
    "charge_type": "SINGLE_USE_TOKEN",
    "card_brand": "VISA",
    "bank_reconciliation_id": "5132390610356134503009",
    "eci": "05",
    "id": "598d5dba51e0870d44c61539"
}

Reverse Authorization

Definition: Reversing Authorized Charge

POST https://api.xendit.co/credit_card_charges/:charge_id/auth_reversal

Example Reverse Authorization

curl -X POST \
  https://api.xendit.co/credit_card_charges/:charge_id/auth_reversal \
  -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \
  -d '{
    "external_id": "reverse-authorization-1502436817",
    }'
<?php

    use Xendit\Xendit;
    require 'vendor/autoload.php';

    Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');

    $id = '5ecc82736275b80019591c91';
    $params = ['external_id' => 'reverse-authorization-1502436817'];

    $reverseAuth = \Xendit\Cards::reverseAuthorization(
        $id,
        $params
    );
    var_dump($reverseAuth);

?>
const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });

const { Card } = x;
const cardSpecificOptions = {};
const card = new Card(cardSpecificOptions);

const resp = await card.reverseAuthorization({
  externalID: 'reverse-authorization-1502436817',
});
console.log(resp);
Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
try {
  CreditCardReverseAuth creditCardReverseAuth = CreditCard.reverseAuthorization(
    "1234567", //chargeId
    "reverse-authorization-1502436817" //externalId
  );
} catch (XenditException e) {
  e.printStackTrace();
}
xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="

reverseAuthorizationData := card.ReverseAuthorizationParams{
  ChargeID:   "123",
  ExternalID: "reverse-authorization-1502436817",
}

reverseAuthorizationResp, err := card.ReverseAuthorization(&reverseAuthorizationData)
if err != nil {
  log.Fatal(err)
}

fmt.Printf("reversed authorization: %+v\n", reverseAuthorizationResp)
from xendit import Xendit

api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
xendit_instance = Xendit(api_key=api_key)
CreditCard = xendit_instance.CreditCard

reverse_authorization = CreditCard.reverse_authorizatiton(
    credit_card_charge_id="5f0421fa8cc1e8001973a1d6",
    external_id="reverse-authorization-1594106387",
)
print(reverse_authorization)

Example of request body

{        
    "external_id": "reverse-authorization-1502436817",
}

Example of Reverse Authorization Response

{
    "status": "SUCCEEDED",
    "currency": "IDR",
    "credit_card_charge_id": "5ecc82640d679500199621ad",
    "business_id": "5dd7928f4e6d9a2ec299ea43",
    "external_id": "reverse-authorization-1502436817",
    "amount": 5000,
    "created": "2020-05-26T02:44:03.458Z",
    "id": "5ecc82736275b80019591c91"
}

This API provides reversing charge when the charge has AUTHORIZED status and hasn't yet captured.

Request Parameters

Header Parameter Type Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information

Body Parameter Type Description
external_id
required
string Reverse authorization reference to help you track your request

Response Parameters

Parameter Type Description
status
required
string Status of the reverse authorization. See Reverse Authorization Statuses.
currency
required
string Currency of the charge that requested to be reversed.
credit_card_charge_id
required
string The ID of the charge that requested to be reversed.
business_id
required
string The ID of your business in Xendit.
external_id
required
string Unique Identifier for your Reversed Charge reference
amount
required
number The amount that requested to be reversed for this charge.
created
required
string An ISO timestamp that tracks when the reverse authorization was made.
id
required
string ID of the charge transaction in Xendit system that requested to be reversed.
failure_reason
optional
string If status is FAILED, this describes the failure. See Reverse Authorization Failure Reasons.

Statuses

Recommendation Description
SUCCEEDED
Reverse Authorization request is success
FAILED
Reverse Authorization is failed with detailed failure reason

Failure Reasons

Failure Reason Description
REVERSE_AUTHORIZATION_REJECTED_BY_BANK The authorization that you requested to be reversed is rejected by the bank. There's possibility that the authorization is no longer valid and the authorized amount is already reversed back automatically to the card holder's credit balance.
PROCESSOR_ERROR The reverse authorization failed because there's an integration issue between card processor and the bank. Contact us if you encounter this issue.

Error Codes

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
CHARGE_ALREADY_REVERSED_ERROR
400
Charge already reversed, therefore cannot be reversed
CHARGE_ALREADY_CAPTURED_ERROR
400
Charge already captured, therefore cannot be reversed
CHARGE_FAILED_ERROR
400
Charge is failed, therefore cannot be reversed
REQUEST_FORBIDDEN_ERROR
403
API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here
CREDIT_CARD_CHARGE_NOT_FOUND_ERROR
404
credit_card_charge_id not found for this transaction. Please try with another valid charge ID
INVALID_AMOUNT_FOR_REVERSE_AUTHORIZATION_ERROR
400
Invalid charge amount to be reversed. Please make sure that the authorized amount that you requested to be reversed is no 0.

Create Charge

Definition: Create Charge

POST https://api.xendit.co/credit_card_charges

Example Charge Request

curl -X POST \
  https://api.xendit.co/credit_card_charges \
  -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \
  -H 'content-type: application/json' \
  -d '{
      "token_id" : "598d5d0e51e0870d44c61534",
      "external_id": "postman-charge-1502436817",
      "amount": 900000,
      "authentication_id": "598d5d0f51e0870d44c61535",
      "card_cvn": "123",
      "descriptor": "My new store"
      "currency": "IDR",
      "mid_label": "IDR_MID",
      "billing_details": {
        "given_names": "John",
        "surname": "John Doe",
        "email": "johndoe@xendit.co",
        "mobile_number": "+62899336634448",
        "phone_number": "+629934448",
        "address": {
          "street_line1": "Panglima Polim IV",
          "street_line2": "Ruko Grand Panglima Polim, Blok E",
          "city": "Jakarta Selatan",
          "province": "DKI Jakarta",
          "state": "South Jakarta",
          "zip_code": "993448",
          "country": "ID"
        }
      },
      "promotion": {
          "reference_id": "BCA_10",
          "original_amount": 1000000
      },
      "installment": {
          "count": 3,
            "interval": "month"
      }
    }'
<?php

  use Xendit\Xendit;
  require 'vendor/autoload.php';

  Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');

  $params = [
      'token_id' => '5e2e8231d97c174c58bcf644',
      'external_id' => 'card_' . time(),
      'authentication_id' => '5e2e8658bae82e4d54d764c0',
      'amount' => 15000,
      'card_cvn' => '123',
      'capture' => false
  ];

  $createCharge = \Xendit\Cards::create($params);
  var_dump($createCharge);

?>
const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });

const { Card } = x;
const cardSpecificOptions = {};
const card = new Card(cardSpecificOptions);

const resp = await card.createCharge({
  externalID: 'sample-external-id-1475459775872',
  tokenID: 'sample-token-id-1475459775872',
  amount: 900000,
  authID: '58e2097218b815f555c8a526',
  cardCvn: "123",
  descriptor: "My new store",
  currency: "IDR",
  midLabel: "IDR_MID",
  billing_details: {
      given_names: "John",
      surname: "John Doe",
      email: "johndoe@xendit.co",
      mobile_number: "+62899336634448",
      phone_number: "+629934448",
      address: {
          street_line1: "Panglima Polim IV",
          street_line2: "Ruko Grand Panglima Polim, Blok E",
          city: "Jakarta Selatan",
          province: "DKI Jakarta",
          postal_code: "993448",
          country: "ID"
      }
  },
  promotion: {
      referenceId: "BCA_10",
      originalAmount: 1000000
  },
  installment: {
      count: 3,
      interval: "month"
  }
});
console.log(resp);
Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
try {
  CreditCardCharge creditCardCharge = CreditCard.createCharge(
    "token_id", //tokenId
    "postman-authorize-1502437417", //externalId
    90000, //amount
    "auth_id", //authenticationId
    "123", //Card CVN
    "XENDIT*MYBUSINESS-MY NEW STORE" //Descriptor
  );
} catch (XenditException e) {
  e.printStackTrace();
}
xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="

createChargeData := card.CreateChargeParams{
  TokenID:          "example-token-id",
  AuthenticationID: "example-authentication-id",
  ExternalID:       "postman-charge-1502436793",
  Amount:           900000,
  Capture:          new(bool),
}

chargeResp, err := card.CreateCharge(&createChargeData)
if err != nil {
  log.Fatal(err)
}

fmt.Printf("created charge: %+v\n", chargeResp)
from xendit import Xendit

api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
xendit_instance = Xendit(api_key=api_key)
CreditCard = xendit_instance.CreditCard

charge = CreditCard.create_charge(
    token_id="5f0410898bcf7a001a00879d",
    external_id="card_charge-1594106478",
    amount=75000,
    card_cvn="123",
)
print(charge)

Once you have a token, that token can be used to charge a card.

Request Parameters

Header Parameter Type Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information

with-fee-rule
optional
string Fee Rule ID that you would like to apply to this card charge

Please note: If you include this parameter, we will return the fee_rule_id and the fee_id in the header of the API response.

This header is only used if you have access to xenPlatform. See xenPlatform for more information

Body Parameter Type Description
token_id
required
string The token ID used to charge the card.
external_id
required
string A unique identifier of your choice. Max 64 characters.
amount
required
number Amount that expected to be charged.
authentication_id
optional
string Authentication ID for authenticating charge. Optional only if charge was already authenticated with a single-use token, or if optional authentication is enabled for your account.
card_cvn
optional
string 3 or 4 digit CVN (CVC) code. Optional but highly recommended. Required for cards issued in Europe.
capture
optional

default: true
boolean Whether or not to capture immediately. Set to false to issue an authorization (hold funds) only, to be captured later with the capture endpoint.
Note: Authorizations expire in 7 days.
descriptor
optional
string Specific descriptor to define merchant's identity.
Note:
For aggregator merchant, it will always return XENDIT*[MERCHANT_NAME]-DESCRIPTOR
For switcher merchant, it will always return [MERCHANT_NAME]-DESCRIPTOR
currency
optional

default: IDR
string Currency which you want to process the transaction in. Use a three-letter ISO currency code. If left blank, it will default to IDR
mid_label
optional
string Specific string value which labels any of your Merchant IDs (MID) set up with Xendit. This can be configured in the list of MIDs on your Dashboard settings. (If this is not included in a request, and you have more than 1 MID in your list, the transaction will proceed using your prioritized MID (first MID on your list)).
Note:
Only available in the response for switcher merchant
billing_details
optional
object Billing details of the cardholder. If entered, should correspond with billing details registered by cardholder with their issuer. Required for a card to be verified by the Address Verification System (AVS) - only for USA / Canadian / Great Britain cards.
billing details child parameters
Key Value
given_names string Given name (also known as first name)
minimum length: 1 character
maximum length: 255 characters
Note:
Required for AVS and 3DS 2.0
surname
optional
string Surname (also known as last name)
minimum length: 1 character
maximum length: 255 characters
Note:
Required for AVS and 3DS 2.0
email
optional
string Enduser's email address which associated with the card
mobile_number
optional
string Enduser's mobile phone number which associated with the card
phone_number
optional
string Enduser's other phone number which associated with the card (e.g. landline)
address
required
object Address Object
address details child parameters
Key Value
country
required
string 2-letter ISO 3166-2 country code for the customer's country of residence
street_line1
optional
string Building name and apartment unit number
minimum length: 1 character
maximum length: 255 characters
street_line2
optional
string Building street address
minimum length: 1 character
maximum length: 255 characters
city
optional
string City, village or town as appropriate
minimum length: 1 character
maximum length: 255 characters
province
optional
string Geographic area, province, or region, if applicable
minimum length: 1 character
maximum length: 255 characters
state
optional
string Formal state designation within country, if applicable. If the user is USA citizen, make sure to use state code (e.g put CA instead of California)
minimum length: 1 character
maximum length: 255 characters
postal_code
optional
string Postal, zip or rural delivery code, if applicable
minimum length: 1 character
maximum length: 255 characters
promotion
optional
object If you are want to apply a Promotion to a charge, you must input these parameters.
promotion details child parameters
Key Value
reference_id
optional
stringUnique reference, such as an ID or name, you wish to assign to the created Promotion
original_amount
optional
numberThe amount of the original transaction (before the Promotion discount).
installment
optional
object These parameters are required to mark a transaction as an installment.
installment details child parameters
count
optional
numberTogether with the "interval" parameter, this defines your installment tenor. If you want the installment tenor to be 3 months, then the value of "count" should be 3.
interval
optional
string Together with the "count" parameter, this defines your installment tenor. If you want the installment tenor to be 3 months, then the value of "interval" should be "month"

Example Charge Response

{
    "created": "2020-01-11T07:33:14.442Z",
    "status": "CAPTURED",
    "business_id": "5850e55d8d9791bd40096364",
    "authorized_amount": 900000,
    "external_id": "postman-charge-1502436793",
    "merchant_id": "xendit",
    "merchant_reference_code": "598d5d0d51e0870d44c61533",
    "card_type": "CREDIT",
    "masked_card_number": "400000XXXXXX0002",
    "charge_type": "SINGLE_USE_TOKEN",
    "card_brand": "VISA",
    "bank_reconciliation_id": "5132390610356134503009",
    "eci": "05",
    "capture_amount": 900000,
    "descriptor": "XENDIT*MYBUSINESS-MY NEW STORE",
    "id": "598d5dba51e0870d44c61539",
    "mid_label": "IDR_MID",
    "promotion": {
        "reference_id": "BCA_10",
        "original_amount": "1000000"
    },
    "installment": {
        "count": 3,
        "interval": "month"
    }
}

Example Authorization Response

{
    "created": "2020-01-11T07:43:39.563Z",
    "status": "AUTHORIZED",
    "business_id": "5850e55d8d9791bd40096364",
    "authorized_amount": 90000,
    "external_id": "postman-authorize-1502437417",
    "merchant_id": "xendit",
    "merchant_reference_code": "598d5ffb51e0870d44c6153a",
    "card_type": "CREDIT",
    "masked_card_number": "400000XXXXXX0002",
    "charge_type": "SINGLE_USE_TOKEN",
    "card_brand": "VISA",
    "bank_reconciliation_id": "5132390610356134503009",
    "eci": "05",
    "descriptor": "XENDIT*MYBUSINESS-MY NEW STORE",
    "id": "598d602b51e0870d44c6153d",
    "mid_label": "IDR_MID",
    "promotion": {
        "reference_id": "BCA_10",
        "original_amount": "100000"
    },
    "installment": {
        "count": 3,
        "interval": "month"
    }
}

Charge Response



Parameter Type Description
created
required
string An ISO timestamp that tracks when the charge was made.The token ID used to charge the card. The timezone will be default
Timezone: GMT+0
charge_type
required
string Types of charges. See Charge types.
business_id
required
string The ID of your business in Xendit.
authorized_amount
required
number The amount that've been authorized for this charge.
external_id
required
string A unique identifier of your choice.
card_type
required
string Type of card (CREDIT or DEBIT).
merchant_id
required
string Your merchant ID used for processing credit cards with the bank.
masked_card_number
required
string Masked card number. The first 6 digits are the BIN (Bank Identification Number).
charge_type
required
string Types of charges. See Charge types.
card_brand
required
string Card scheme (VISA, MASTERCARD, JCB, ...).
bank_reconciliation_id
required
string ID of the transaction that can be reconciled with the bank.
eci
optional
string Status of 3DS authentication. See ECI codes.
capture_amount
optional
number Amount captured for this charge. Can be up to authorized_amount.
status
required
string Status of the charge transaction in xendit system. See [Charge Statuses] (#statuses).
failure_reason
optional
string If status is FAILED, this describes the failure. See Charge Failure Reasons.
approval_code
optional
string Represents the five or six numbers generated by an issuing bank, or the bank of a buyer using a credit card, for the purpose of validating a credit card whenever it is approved in the transaction.
cvn_code
optional
string Response from validating the CVN (3-digit security code on back of card). See CVN Codes.
merchant_reference_code
required
string An ID used to reconcile transactions with the bank.
descriptor
optional
string Description which already inputted by merchant when creating a charge.
Note:
For aggregator merchant, it will always return XENDIT*[MERCHANT_NAME]-DESCRIPTOR
For switcher merchant, it will always return [MERCHANT_NAME]-DESCRIPTOR
currency
optional

default: IDR
string Currency which you want to process the transaction in. Use a three-letter ISO currency code. If left blank, it will default to IDR
mid_label
optional
string Specific string value which labels any of your Merchant IDs (MID) set up with Xendit. This can be configured in the list of MIDs on your Dashboard settings. (If this is not included in a request, and you have more than 1 MID in your list, the transaction will proceed using your prioritized MID (first MID on your list)).
Note:
Only available in the response for switcher merchant
id
required
string ID of the charge transaction in Xendit system.
promotion
optional
object Detail of promotion that used for this transaction.
promotion details child parameters
Key Value
reference_id
optional
stringUnique reference, such as an ID or name, you wish to assign to the created Promotion
original_amount
optional
numberThe amount of the original transaction (before the Promotion discount).
installment
optional
object These parameters will be returned to mark a transaction as an installment.
installment details child parameters
count
optional
numberTogether with the "interval" parameter, this defines your installment tenor count.
interval
optional
string Together with the "count" parameter, this defines your installment tenor interval."

Statuses

Status Description
CAPTURED Charge is successfully captured and the funds will be settled according to the settlement schedule.
AUTHORIZED Charge is successfully authorized.
REVERSED Charge is successfully reversed.
FAILED Charge failed. See Charge Failure Reasons

CVN Codes

Code Description
M Match - CVN provided matches the CVN on the issuer's record.
N Not match - CVN provided does not match CVN on the issuer's record.
P Not processed - either the card does not have a valid CVN, or the CVN was somehow not accepted by the issuer. Retry again and if the response persists, try a different card.

Failure Reasons

Failure Reason Description
EXPIRED_CARD The card you are trying to capture is expired. Ask your customer for a different card
CARD_DECLINED The card you are trying to capture has been declined by the bank. Ask your customer for a different card
INSUFFICIENT_BALANCE The card you are trying to capture does not have enough balance to complete the capture
STOLEN_CARD The card you are trying to capture has been marked as stolen. Ask your customer for a different card
INACTIVE_CARD The card you are trying to capture is inactive. Ask your customer for a different card
INVALID_CVN The cvn that being submitted is not correct.
PROCESSOR_ERROR The charge failed because there's an integration issue between card processor and the bank. Contact us if you encounter this issue.
BIN_BLOCK The cards' BIN has been blocked by request from the Bank.

Error Codes

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
INVALID_JSON_FORMAT
400
The request body is not valid JSON.
TOKEN_ALREADY_USED_ERROR
400
The single-use token ID has already been used in a charge.
AUTHENTICATION_ALREADY_USED_ERROR
400
The authentication ID has already been used in a charge.
INVALID_TOKEN_ID_ERROR
400
The token ID format is invalid.
INVALID_CVN_LENGTH_ERROR
400
The length of CVN is invalid. For AMEX card, CVN length must be 4 digit and for the others card type it must be 3.
AUTHENTICATION_ID_MISSING_ERROR
400
Authentication ID is required for this charge.
AMOUNT_GREATER_THAN_AUTHENTICATED_ERROR
400
Charge amount was greater than what was authenticated.
INVALID_AUTHENTICATION_ID_ERROR
400
The authentication ID format is invalid.
REQUEST_FORBIDDEN_ERROR
403
API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here
TOKEN_NOT_FOUND_ERROR
404
The token ID was not found in the system.
AUTHENTICATION_NOT_FOUND_ERROR
404
Authenticated token with given authentication ID is not found.
MID_NOT_FOUND_ERROR
404
The MID specified in "mid_label" cannot be found. Check if you have registered this MID, or if you entered the MID label incorrectly
INVALID_PROMOTION_DETAILS
400
The promotion detail which inputted in this request is invalid. Please change the input or check if you have available promotion in your system or not.
CARDHOLDER_NAME_REQUIRED
400
Please send cardholder name fields in the billing_details object in your request body.
INSTALLMENT_BELOW_MINIMUM_AMOUNT
400
Amount is below the minimum allowed for installments.
BRI, BNI: Rp 500.000
INSTALLMENT_UNAVAILABLE
404
Possible error messages:
  • Installments are not available for cards from this bank. Please try with a card from another bank.
  • The requested installment interval is currently not supported. Please try an installment transaction with another interval.

  • AMOUNT_BELOW_MINIMUM_LIMIT
    400
    The amoubnt which inputted in this request is below your minimum limit. Please send another request with amount equal to or greater than the minimum limit. Default minimum limit based on currency:
  • IDR: 5000.
  • PHP: 20.

  • AMOUNT_ABOVE_MAXIMUM_LIMIT
    400
    The amoubnt which inputted in this request is above your maximum limit. Please send another request with amount equal to or lower than the maximum limit. Default maximum limit based on currency:
  • IDR: 200000000.
  • PHP: 700000.

  • Charge Types

    Status Description
    SINGLE_USE_TOKEN Charge created with single-use token
    MULTIPLE_USE_TOKEN Charge created with multiple-use token
    RECURRING Charge a recurring charge in a subscription

    ECI Codes

    ECI Description
    0 Unable to Authenticate (MasterCard)
    1 Authentication attempted (MasterCard)
    2 Successful authentication (MasterCard)
    5 Successful authentication (Visa, AMEX, JCB)
    6 Authentication attempted (Visa, AMEX, JCB)
    7 Unable to Authenticate (Visa, AMEX, JCB)

    Safe Acceptance

    An alternative to the Charge API endpoint, for the following use cases:

    Use this demo page to test scenarios using Safe Acceptance, and to see examples of how Safe Acceptance can be integrated in a web page.

    Payment Processor Integration Methods in Safe Acceptance

    A strength of our Safe Acceptance API is that it is flexible to support card processing using the most common integration methods offered by payment processors. These are generally known as 2.5 or 3-party methods, explained below:

    Note that because the Safe Acceptance API accepts token_id as a valid field, you are still able to use Xendit Tokenization with it if you choose.

    Definition: Create Safe Acceptance

    POST 
    https://api.xendit.co/credit_cards/safe_acceptance

    Example Safe Acceptance Request

    {
        "amount": "1200000",
        "return_url": "https://mybusiness.co",
        "reference_id": "xdt-safe-acceptance-007",
        "transaction_type": "SALES",
        "request_timestamp": "2021-01-10T09:50:40+03:00",
        "descriptor": "INV-SAFE-ACCEPTANCE-007",
        "card_number": "1889800000000171",
        "card_exp_year": "2021",
        "card_exp_month": "03",
        "card_cvn": "101",
        "should_authenticate": true,
        "currency": "IDR",
        "authorization": "Basic eG5kX3B1YmxpY19kZXZlbG9wbWVudF9PNDZBZkw4azFlRGtwSnRmN3RPSERDV01OQ2w4dFI0azNibVJ4bm1EUnIyb0NnZHdnQTo=",
        "signed_field_names": "reference_id,amount,currency,request_timestamp,return_url,authorization,signed_field_names",
        "signature": "37c0323212908b9d4fe607f9d237c95aae2503a799d278afdc663268b5f8906e"
    }

    Example Safe Acceptance Webhook Response (Visa / MasterCard / JCB cards)

    {
            "created": "2021-01-10T09:50:40+03:00",
            "business_id": "5d08a4nfea3b620019cfa213c",
            "authorized_amount": 1200000,
            "reference_id": "ecm-8112",
            "merchant_reference_code": "5d1ec8f4a3bcd10019a7e2de",
            "masked_card_number": "400000XXXXXX0002",
            "charge_type": "SINGLE_USE_TOKEN",
            "card_brand": "VISA",
            "card_type": "CREDIT",
            "status": "CAPTURED",
            "bank_reconciliation_id": "5622988916826241203012",
            "eci": "05",
            "capture_amount": "1200000",
            "currency": "IDR",
            "id": "5d1eca0ca3bcd10019a7e2ee",
            "authorized_amount": "1200000",
            "merchant_id" : "00080091009103589348501",
            "descriptor": "INV-SAFE-ACCEPTANCE-007",
            "signed_field_names": "create,business_id,authorized_amount,reference_id,merchant_reference_code,masked_card_number,charge_type,card_brand,card_type,status,bank_reconciliation_id,eci,capture_amount,currency,id,authorized_amount,merchant_id,mid_label,descriptor",
            "signature": "25798ae4db8361fa4ee423e7321a1558a1b0bf0863e8082e0551e62fd8e7a771"
    }

    Example Safe Acceptance Webhook Response (BCA-branded cards)

    {
            "created": "2021-01-10T09:50:40+03:00",
            "business_id": "5d08a4nfea3b620019cfa213c",
            "authorized_amount": 1200000,
            "reference_id": "ecm-8112",
            "merchant_reference_code": "5d1ec8f4a3bcd10019a7e2de",
            "masked_card_number": "143481XXXXXX0002",
            "charge_type": "SINGLE_USE_TOKEN",
            "card_brand": "BCA",
            "status": "CAPTURED",
            "bank_reconciliation_id": "5622988916826241203012",
            "eci": "05",
            "capture_amount": "1200000",
            "currency": "IDR",
            "id": "5d1eca0ca3bcd10019a7e2ee",
            "authorized_amount": "1200000",
            "merchant_id" : "00080091009103589348501",
            "descriptor": "INV-SAFE-ACCEPTANCE-007",
            "signed_field_names": "create,business_id,authorized_amount,reference_id,merchant_reference_code,masked_card_number,charge_type,card_brand,card_type,status,bank_reconciliation_id,eci,capture_amount,currency,id,authorized_amount,merchant_id,mid_label,descriptor",
            "signature": "25798ae4db8361fa4ee423e7321a1558a1b0bf0863e8082e0551e62fd8e7a771"
    }    

    Example Safe Acceptance Webhook Response (GPN-branded cards)

    {
            "created": "2021-01-10T09:50:40+03:00",
            "business_id": "5d08a4nfea3b620019cfa213c",
            "authorized_amount": 1200000,
            "reference_id": "ecm-8112",
            "merchant_reference_code": "5d1ec8f4a3bcd10019a7e2de",
            "masked_card_number": "143481XXXXXX0002",
            "charge_type": "SINGLE_USE_TOKEN",
            "card_brand": "GPN",
            "status": "CAPTURED",
            "bank_reconciliation_id": "5622988916826241203012",
            "eci": "05",
            "capture_amount": "1200000",
            "currency": "IDR",
            "id": "5d1eca0ca3bcd10019a7e2ee",
            "authorized_amount": "1200000",
            "merchant_id" : "00080091009103589348501",
            "descriptor": "INV-SAFE-ACCEPTANCE-007",
            "signed_field_names": "create,business_id,authorized_amount,reference_id,merchant_reference_code,masked_card_number,charge_type,card_brand,card_type,status,bank_reconciliation_id,eci,capture_amount,currency,id,authorized_amount,merchant_id,mid_label,descriptor",
            "signature": "25798ae4db8361fa4ee423e7321a1558a1b0bf0863e8082e0551e62fd8e7a771"
    }    

    Request Parameters

    Parameter Type Description
    amount
    required
    number Amount of the card payment being processed.
    reference_id
    required
    string A unique identifier of your choice. Max 64 chars.
    request_timestamp
    required
    string Timestamp when you sent the request, in ISO8601 format. Required for creating the signature and subsequent validation by Xendit.
    Example: 2021-01-10T09:50:40+03:00
    currency
    required
    string Currency which you want to process the transaction in. Use a three-letter ISO currency code. Supported currencies:
    • Indonesian businesses: IDR
    • Philippines businesses: PHP, USD
    return_url
    required
    string This is a URL that your customers will be redirected to after the transaction is completed. The URL will be called using a form POST with the results of the transaction. A signature will be sent in the response for the merchant to verify.
    authorization
    required
    string Your Xendit Public API key (must be base-64 encoded).
    signature
    required
    string This value is generated by retrieving your Xendit secret API key from your Xendit Dashboard, then hashing it with SHA256. See our Safe Acceptance Docs for guide.
    signed_field_names
    required
    string The value here should be the names of all the fields you want to use for verification with the created signature, separated with commas.
    Mandatory(if your request contains them):
    amount, currency, authorization, reference_id, request_timestamp,mid_label, channel_code, return_url, should_authenticate
    channel_code
    optional
    string Value used to determine the connector which the Safe Acceptance request runs through. Defaults to Visa/MasterCard/JCB/AMEX connectors if left blank. For other transactions, please see:
    • GPN: (Gerbang Pembayaran Nasional) use this value to charge a GPN card (3 party integration method)
    • BCA: use this value to charge a BCA-branded card on its inhouse connector (2.5 party integration method)
    card_number
    optional
    string Credit / debit card number 16 digits.
    Note: Required when 2 or 2.5 party processors are used
    card_exp_year
    optional
    string Credit / debit card expiration year (4 digit number)
    Note: Required when 2 or 2.5 party processors are used
    card_exp_month
    optional
    string Credit / debit card expiration month (2 digit number)
    Note: Required when 2 or 2.5 party processors are used
    card_cvn
    optional
    string Security code on back of card 3 or 4 digits
    Note: Required when 2 or 2.5 party processors are used
    card_holder_name
    optional
    string Full name of the cardholder
    token_id
    optional
    string ID of the token created during Tokenization.
    Only required if the selected processor requires Tokenization, and you have a Token ID from a Tokenization request previously sent.
    should_authenticate
    optional
    boolean Whether or not to initiate 3D-Secure authentication for this transaction. If not inputted, will follow the merchant's 3DS settings. Accepted values:
    • true: 3DS will be initiated
    • false: 3DS will be skipped
    given_names
    optional
    string Primary or first name/s of the customer
    minimum length: 1 character
    maximum length: 255 characters
    surname
    optional
    string Surname or last name of the customer
    minimum length: 1 character
    maximum length: 255 characters
    email
    optional
    string Enduser's email address which associated with the card
    mobile_number
    optional
    string Enduser's mobile phone number which associated with the card
    phone_number
    optional
    string Enduser's other phone number which associated with the card (e.g. landline)
    country
    required
    string 2-letter ISO 3166-2 country code for the customer's country of residence
    street_line1
    optional
    string Building name and apartment unit number
    minimum length: 1 character
    maximum length: 255 characters
    street_line2
    optional
    string Building street address
    minimum length: 1 character
    maximum length: 255 characters
    city
    optional
    string City, village or town as appropriate
    minimum length: 1 character
    maximum length: 255 characters
    province_state
    optional
    string Use this to enter province, state or region of residence. If the user is USA citizen, make sure to use state code (e.g put CA instead of California)
    minimum length: 1 character
    maximum length: 255 characters
    postal_code
    optional
    string Postal, zip or rural delivery code, if applicable
    minimum length: 1 character
    maximum length: 255 characters
    descriptor
    optional
    string Specific descriptor to define merchant's identity. This is the message that will be printed in the credit card statement.
    minimum length: 1 character
    maximum length: 20 characters
    use_reward
    optional
    boolean Whether to use cardholder’s rewards balance available with their issuing bank for the payment. Should only be sent if merchant has received a Get Charge Option stating that the card is eligible for rewards. Values:
    ‘true’: all available rewards balance on the card will be used
    ‘false’: no rewards balance on the card will be used
    installment_count
    optional
    number Together with the "interval" parameter, this defines your installment tenor. If you want the installment tenor to be 3 months, then the value of "count" should be 3
    installment_interval
    optional
    string Together with the "count" parameter, this defines your installment tenor. If you want the installment tenor to be 3 months, then the value of "interval" should be "month".
    installment_code
    optional
    string Used to identify the installment type and associated features such as interest rates and fees.
    Mandatory if Xendit has returned an installment_code in a Get Charge Option response for this card.
    mid_label
    optional
    string Label assigned to a Merchant ID. Merchant IDs are accounts opened with acquirers to enable Visa/MasterCard (and others) transactions.
    Use only if you have your own MID with an acquirer, and have configured its label in the Xendit Dashboard.

    Response Parameters

    Parameter Type Description
    id
    required
    string Unique ID of the transaction in Xendit’s system.
    created
    required
    string An ISO timestamp that tracks when the charge was made (Timezone: GMT+0).
    reference_id
    required
    string A unique identifier of your choice, included in the request.
    business_id
    required
    string The ID of your business in Xendit.
    card_brand
    required
    string Card scheme (VISA, MASTERCARD, JCB, ...)
    card_type
    required
    string Type of card (CREDIT or DEBIT)
    masked_card_number
    required
    number Masked card number. The first 6 digits are the BIN (Bank Identification Number).
    authorized_amount
    required
    number Amount that was authorized for this charge.
    capture_amount
    required
    number Amount that was captured for this charge. Can be up to the authorized_amount.
    currency
    required
    string Currency in which the payment was made, included in the request.
    status
    required
    string Status of the charge transaction in xendit system. See Charge Statuses.
    eci
    required
    string "Electroni" Commerce Indicator”, which tells you whether 3DS authentication was successful or not. Status of 3DS authentication. See ECI codes.
    cvn_code
    optional
    string Response from validating the CVN (3-digit security code on back of card). See CVN Codes.
    merchant_id
    optional
    string Merchant ID used for processing credit cards. Will return the Merchant ID number provided by the acquirer. Use this to identify the MID used, and reconcile transactions processed with each MID. Only returned if you are using your own MID.
    merchant_reference_code
    required
    string Unique identification code used by the card processor to identify the transaction.Used as another unique identifier for referencing the transaction.
    bank_reconciliation_id
    required
    string Secondary ID used by the processor and bank to reconcile the transaction. Used for reconciling the transaction with acquirers, e.g. when finding out when funds will be settled or if there is an amount discrepancy.
    descriptor
    optional
    string Freetext you can use to describe the transaction. Used to add notes about the transaction e.g. "recurrin" payment for meal plan ABCDE”.
    signed_field_names
    required
    string Names of all the fields used for verification with the created signature, separated with commas.
    signature
    required
    string Signature you provided in the request.
    reward_balance
    required
    string Balance of rewards left in the issuing bank for this card. Only returned if ‘use_reward’ was set to ‘true’ in the Safe Acceptance request.
    installment_count
    required
    string Returned to mark a transaction as an installment. Together with the "interval" parameter, this defines your installment tenor.
    installment_interval
    required
    string Returned to mark a transaction as an installment. Together with the "count" parameter, this defines your installment tenor.
    installment_code
    required
    string Returned to mark a transaction as an installment. Used to identify the installment type and associated features such as interest rates and fees.
    approval_code
    required
    string Represents the five or six numbers generated by an issuing bank, or the bank of a buyer using a credit card, for the purpose of validating a credit card whenever it is approved in the transaction.

    Statuses

    Status Description
    CAPTURED Charge is successfully captured and the funds will be settled according to the settlement schedule.
    AUTHORIZED Charge is successfully authorized.
    REVERSED Charge is successfully reversed.
    FAILED Charge failed. See Charge Failure Reasons

    CVN Codes

    Code Description
    M Match - CVN provided matches the CVN on the issuer's record.
    N Not match - CVN provided does not match CVN on the issuer's record.
    P Not processed - either the card does not have a valid CVN, or the CVN was somehow not accepted by the issuer. Retry again and if the response persists, try a different card.

    Failure Reasons

    Failure Reason Description
    EXPIRED_CARD The card you are trying to capture has expired. Ask your customer for a different card.
    INSUFFICIENT_BALANCE The card you are trying to capture does not have enough balance to complete the capture.
    INVALID_CVN The CVN that is being submitted is not correct.
    CARD_DECLINED The card you are trying to capture has been declined by the issuing bank. Ask your customer for a different card.
    ISSUING_BANK_UNAVAILABLE The card you are trying to use is either a test or invalid card, or the issuing bank is not enrolled in 3DS.

    Error Codes

    Error Code Description
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    INVALID_JSON_FORMAT
    400
    The request body is not a valid JSON.
    INVALID_API_KEY
    400
    Please include your public API key as an authorization.
    SIGNATURE_VALIDATION_ERROR
    400
    The signature created for this transaction is not valid.

    Capture Charge

    Definition: Capture Charge

    POST https://api.xendit.co/credit_card_charges/:credit_card_charge_id/capture

    Example Capture Charge Request

    curl https://api.xendit.co/credit_card_charges/5877255293ff67900c6aa64e/capture \
        -X POST \
        -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \
        -d amount=15000
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $id = '598942c4bb91a4ec309e9a37';
      $params = ['amount' => 10000];
    
      $captureCharge = \Xendit\Cards::capture($id, $params);
      var_dump($captureCharge);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Card } = x;
    const cardSpecificOptions = {};
    const card = new Card(cardSpecificOptions);
    
    const resp = await card.captureCharge({
      chargeID: id,
      amount: 10000,
    });
    console.log(resp)
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      CreditCardCharge creditCardCharge = CreditCard.captureCharge(
        "12345678", //chargeId
        10000 //amount
      );
    } catch (XenditException e) {
      e.printStackTrace();
    }
    captureChargeData := card.CaptureChargeParams{
        ChargeID: "598942c4bb91a4ec309e9a37",
        Amount:   9900,
    }
    
    chargeResp, err := card.CaptureCharge(&captureChargeData)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("captured charge: %+v\n", chargeResp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    CreditCard = xendit_instance.CreditCard
    
    charge = CreditCard.capture_charge(
        credit_card_charge_id="5f0422aa2bbbe50019a368c2",
        amount=75000,
    )
    print(charge)

    Example Capture Charge Response

    {
      "created": "2020-01-08T04:49:08.815Z",
      "status": "CAPTURED",
      "business_id": "5848fdf860053555135587e7",
      "authorized_amount": 10000,
      "external_id": "test-pre-auth",
      "merchant_id": "xendit",
      "merchant_reference_code": "598942aabb91a4ec309e9a35",
      "card_type": "CREDIT",
      "masked_card_number": "400000XXXXXX0002",
      "charge_type": "SINGLE_USE_TOKEN",
      "card_brand": "VISA",
      "bank_reconciliation_id": "5132390610356134503009",
      "capture_amount": 9900,
      "descriptor": "My new store",
      "id": "598942c4bb91a4ec309e9a37"
    }

    Capturing a charge only needed if you do pre-authorization by specifying capture to false in create charge request. You can capture a charge with amount different than authorized amount as long as it's less than authorized amount. Response for this endpoint is the same as create charge response

    Request Parameters

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Query Parameter Type Description
    credit_card_charge_id
    required
    string Charge ID of authorization
    Body Parameter Type Description
    amount
    required
    string Amount to be captured. Can be up to amount of authorization but not more

    Error Codes

    Error Code Description
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    INVALID_JSON_FORMAT
    400
    The request body is not valid JSON.
    AMOUNT_GREATER_THAN_AUTHORIZED_ERROR
    400
    Capture amount is larger than authorized amount
    INVALID_CHARGE_STATUS_ERROR
    400
    Charge status is not AUTHORIZED
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here
    CREDIT_CARD_CHARGE_NOT_FOUND_ERROR
    404
    credit_card_charge_id not found
    AUTHORIZATION_EXPIRED
    400
    It is likely that the authorization has been reversed because it expired. Please create another authorization or charge.

    Create Refund

    Definition: Create Refund

    POST https://api.xendit.co/credit_card_charges/:credit_card_charge_id/refunds

    Example Refund Request

    curl https://api.xendit.co/credit_card_charges/5877255293ff67900c6aa64e/refunds \
        -X POST \
        -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
        -H "X-IDEMPOTENCY-KEY: unique-id-12345" \
        -H "x-api-version: 2019-05-01" \
        -d "amount": 15000
        -d "external_id": unique-external-id
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $params = [
          'external_id' => 'postman-charge-1502436793',
          'amount' => 15000,
          'X-IDEMPOTENCY-KEY' => 'unique-id'
      ];
    
      $refund = \Xendit\Cards::createRefund($id, $params);
      var_dump($refund);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Card } = x;
    const cardSpecificOptions = {};
    const card = new Card(cardSpecificOptions);
    
    const resp = await card.createRefund({
      chargeID: '5877255293ff67900c6aa64e',
      amount: 15000,
      externalID: 'unique-external-id',
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      CreditCardRefund creditCardRefund = CreditCard.createRefund(
        "1234567", //id
        15000, //amount
        "unique-external-id" //externalId
      );
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    createRefundData := card.CreateRefundParams{
      IdempotencyKey: "unique-idempotency-key",
      ChargeID:       "58f984f09d1b74bc08506c34",
      Amount:         15000,
      ExternalID:     "unique-external-id",
    }
    
    refundResp, err := card.CreateRefund(&createRefundData)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("refunded charge: %+v\n", refundResp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    CreditCard = xendit_instance.CreditCard
    
    refund = CreditCard.create_refund(
        credit_card_charge_id="5f0422aa2bbbe50019a368c2",
        amount=10000,
        external_id="card_refund-1594106755",
    )
    print(refund)

    Example Refund Response

    {
      "updated": "2020-01-21T04:05:09.755Z",
      "created": "2020-01-21T04:05:04.936Z",
      "credit_card_charge_id": "58f89041780d51ed097896c5",
      "user_id": "57c5aa7a36e3b6a709b6e148",
      "amount": 15000,
      "external_id": "unique-external-id",
      "status": "REQUESTED",
      "fee_refund_amount": 150,
      "id": "58f984f09d1b74bc08506c34"
    }

    The Refund API accepts two parameters, amount and external_id. The charge ID, which is returned after a successful charge, must be used in request URL per the definition. Several partial refund calls can be made, so long as the total amount refunded is not greater than the total charge amount.

    Note: Idempotency can be achieved by sending a header with the key X-IDEMPOTENCY-KEY.

    Request Parameters

    Header Parameter Type Description
    X-IDEMPOTENCY-KEY
    optional
    string A unique key to prevent processing duplicate requests. Must be unique across test & live mode.
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    x-api-version
    required
    string Value of this must be "2019-05-01".
    Body Parameter Type Description
    amount
    required
    string The amount to be refunded.
    external_id
    required
    string A unique identifier of your choice. Max 64 characters.

    Response Parameters

    Parameter Type Description
    updated
    required
    string ISO timestamp that tracks when the last time refund was updated.
    created
    required
    string ISO timestamp that tracks when the refund was made
    Timezone: GMT+0
    .
    credit_card_charge_id
    required
    string charge ID, a unique identifier for each charge.
    user_id
    required
    string ID of your business in Xendit's system.
    amount
    required
    number Refund amount.
    external_id
    required
    string Unique identifier for refund request, provided by you.
    status
    required
    string Status of the refund. See Refund Statuses
    failure_reason
    optional
    string Reason provided if refund request fails. See Refund Failure Reasons
    fee_refund_amount
    required
    number Amount of Xendit's fee refunded (proportional to the refund amount).
    id
    required
    string Unique ID referencing the refund request.

    Statuses

    Status Description
    REQUESTED Refund request succeeded
    FAILED Refund failed

    Error Codes

    Error Code Description
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    INVALID_JSON_FORMAT
    400
    The request body is not valid JSON.
    REFUND_AMOUNT_EXCEEDED_ERROR
    400
    Refunded amount would exceed total charge
    DUPLICATE_REFUND_ERROR
    400
    external_id has already been used
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here
    CREDIT_CARD_CHARGE_NOT_FOUND_ERROR
    404
    credit_card_charge_id not found

    Failure Reason

    Failure Reason Description
    INSUFFICIENT_BALANCE Your Xendit balance has insufficient funds to create a refund
    REFUND_FAILED The refund request has been rejected by the processor. Please try again or contact us at help@xendit.co
    REFUND_PERIOD_EXPIRED Refund period expired. The period where this charge can be refunded has expired. You can try refunding the charge by making a disbursement

    Get Charge

    Definition: Get Charge

    GET https://api.xendit.co/credit_card_charges/:credit_card_id?id_type=charge

    Example Get Charge Request Using External ID

    curl https://api.xendit.co/credit_card_charges/5877255293ff67900c6aa64e?id_type=external \
        -X GET \
        -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==:

    Example Get Charge Request Using Charge ID (Default)

    curl https://api.xendit.co/credit_card_charges/5877255293ff67900c6aa64e \
        -X GET \
        -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==:
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $id = '598942c4bb91a4ec309e9a37';
      $getCharge = \Xendit\Cards::retrieve($id);
      var_dump($getCharge);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Card } = x;
    const cardSpecificOptions = {};
    const card = new Card(cardSpecificOptions);
    
    const resp = await card.getCharge({ chargeID: '5877255293ff67900c6aa64e' });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      CreditCardCharge creditCardCharge = CreditCard.getCharge("5877255293ff67900c6aa64e");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    getChargeData := card.GetChargeParams{
      ChargeID: "598942c4bb91a4ec309e9a37",
    }
    
    chargeResp, err := card.GetCharge(&getChargeData)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("retrieved charge: %+v\n", chargeResp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    CreditCard = xendit_instance.CreditCard
    
    charge = CreditCard.get_charge(
        credit_card_charge_id="5f0422aa2bbbe50019a368c2",
    )
    print(charge)

    Example Get Charge Response

    {
      "created": "2020-01-08T04:49:08.815Z",
      "status": "CAPTURED",
      "business_id": "5848fdf860053555135587e7",
      "authorized_amount": 10000,
      "external_id": "test-pre-auth",
      "merchant_id": "xendit",
      "merchant_reference_code": "598942aabb91a4ec309e9a35",
      "card_type": "CREDIT",
      "masked_card_number": "400000XXXXXX0002",
      "charge_type": "SINGLE_USE_TOKEN",
      "card_brand": "VISA",
      "bank_reconciliation_id": "5132390610356134503009",
      "capture_amount": 9900,
      "descriptor": "My new store",
      "id": "598942c4bb91a4ec309e9a37"
    }

    This is endpoint to get a charge object. You need to specify the id in the query parameter which you can choose between charge to use charge_id and external to use the external id / reference provided in your create charge request. Response for this endpoint is the same as create charge response

    Request Parameters

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Query Parameter Type Description
    credit_card_id
    required
    string Can be either charge id of the payment that have been authorized / captured OR external_id of the payment that already requested by the user
    id_type
    optional
    string Defined in [ID Types] (#id-types). If not filled, value will use charge by default.

    ID Types

    Type Description
    charge Use charge ID provided by xendit which can be retrieved from the charge response to retrieve the transaction detail (default value)
    external Use external ID submitted by the user during charge / authorization request to retrieve the transaction detail

    Error Codes

    Error Code Description
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here
    CREDIT_CARD_CHARGE_NOT_FOUND_ERROR
    404
    credit_card_charge_id not found

    Get Charge Option

    When accepting credit card payments from your customers, you may wish to give them additional payment options. These can include:

    These options must be selected by a customer before you create a Charge. For example, you would check if a card is eligible for a Promotion, and discount the Charge amount if so, before you initiate payment you would check if a card can be used for installments, and return the option to the customer, to let them choose if they want to do so

    Our GET Charge Option API endpoint helps you with this. Send a request to this endpoint with info entered by your customer (such as card Bank Identification Number (BIN), promo code) and Xendit checks to see what Charge Options are available. The response will contain all options available for that card. You can select an option and create a Charge with the details from that option. This API will only return promotion response with ACIVE status.

    Definition: Get Charge Option

    GET https://api.xendit.co/credit_card_charges/option?amount={amount}&bin={bin}&currency={currency}

    Example Get Charge Option Using First 6 Digits of Card

    curl -X GET \
      https://api.xendit.co/credit_card_charges/option?amount=1000000&bin=552002&currency=IDR
      -u xnd_public_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \
      -H 'content-type: application/json' \

    Example Get Charge Option Using Token ID

    curl -X POST \
      https://api.xendit.co/credit_card_charges/option?amount=1000000&token_id=598d5d0e51e0870d44c61534&currency=IDR
      -u xnd_public_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \
      -H 'content-type: application/json' \

    Get Charge Option Request

    Query Parameter Type Description
    bin
    required but optional if token_id exists
    string The BIN (first 6 digits of a card) entered by the cardholder, which you want to check if it is associated with any Charge Option.
    amount
    required
    number The amount of the original transaction.
    currency
    optional
    string The currency which payment will be made in. For banks with branches in more than one country, a Promotion will only apply to cards based on the currency. e.g. if currency is IDR and channel_code is DBS, then the Promotion will apply only to BINs issued by DBS Indonesia.
    promo_code
    optional
    string Promo code which can be used by an end user to activate the promo. Include this if you want your Promotion be activated by your user entering a promo code is entered.
    Charactersa-z, A-Z, 0-9; accepted symbols - _ \
    token_id
    optional
    string Token ID of a card, obtained during tokenization with Xendit. We will look up the token to associate it with a BIN and get the available options.
    card_cvn
    optional
    number Three digit code written on the back of the card (usually called CVV/CVN). Recommended to include if the token_id you are sending is for a multiple use token.

    Example Get Charge Option Response

    {
        "business_id": "5ea2a0cdb62b6a00108ed248",
        "bin": "552002",
        "promotions":[{
            "reference_id": "some_promo_1",
            "discount_percent": "25",
            "original_amount": 1000000,
            "final_amount": 975000,
            "currency": "IDR",
            "min_original_amount": 500000,
            "max_discount_amount": 25000
        }],
        "installments" : [{
            "count": 3,
            "interval": "month",
            "acquirer": "BRI",
            "currency": "IDR",
            "minimum_amount": 500000
        },{
            "count": 6,
            "interval": "month",
            "acquirer": "BRI",
            "currency": "IDR",
            "minimum_amount": 500000
        },{
            "count": 12,
            "interval": "month",
            "acquirer": "BRI",
            "currency": "IDR",
            "minimum_amount": 500000
        }]
    }

    Get Charge Option Response

    Parameter Type Description
    business_id
    required
    string The ID of your business in Xendit.
    bin
    required
    string The BIN (first 6 digits of a card) entered by the cardholder, which you sent in the Get Charge Option request.
    promotions
    optional
    array Array containing details of all promotions applicable to the card.
    promotion details child parameters
    Key Value
    reference_id
    optional
    string Unique reference, such as an ID or name which you assigned to the promo and you've inputted in the promo creation request.
    Charactersa-z, A-Z, 0-9; accepted symbols - _ \
    original_amount
    required
    number The amount of the original transaction (before the Promotion discount).
    discount_amount
    optional
    number Amount of discount applicable for a specific Promotion (includes decimal).
    MaximumNone
    Minimum0
    discount_percent
    optional
    number Percentage discount applicable for a specific Promotion (includes decimal).
    Maximum100
    Minimum0
    final_amount
    required
    number The final amount, after the Promotion discount has been applied. You should use this sum to charge the card.
    currency
    required
    string The currency which payment will be made in.
    min_original_amount
    optional
    number Minimum of the original amount for a certain promo to be applicable or calculated.
    max_discount_amount
    optional
    number Maximum of the discount amount that will be applied for a certain promo.
    installments
    optional
    array Define the available installment option.
    installments details child parameters
    Key Value
    count
    required
    numberTogether with the "interval" parameter, this defines your installment tenor count.
    interval
    required
    string Together with the "count" parameter, this defines your installment tenor period.
    acquirer
    required
    stringThe bank corresponding to the card BIN, which offers the installments.
    currency
    required
    string The currency which payment will be made in.
    minimum_amount
    required
    numberThe minimum amount necessary for a card Charge to be paid via installments. A Charge with amount below this minimum cannot be paid via installments.

    May differ across banks, and may not always apply.
    maximum_amount
    optional
    numberWill be returned if the Installment plan limits the transaction amount for payments using Installments. If the transaction you have created exceeds this amount, an error may be returned.
    code
    optional
    stringWill be returned if the issuing bank returns an installment code to identify or categorize the available installments.
    description
    optional
    stringWill be returned if the bank returns a description of the Installment plan.
    interest_free_duration
    optional
    numberDescribes the number of months that interest will not be charged for the installments, if available. Should be returned to the customer on the frontend client. Only returned if provided by the bank.
    installment_amount
    optional
    numberThe amount that the cardholder needs to pay for each installment. Takes the total transaction amount and divides it over the installment_count.
    reward
    optional
    object If Rewards are available for the card, this object will be returned.
    reward details child parameters
    Key Value
    balance
    required
    numberThe balance of rewards available to be used for this card.

    Create Promotion

    A great way to attract more customers is to offer discounts based on the type of card that they use. Issuing banks often collaborate with merchants to provide discounts to users if they choose to use their cards. An important feature in the payment flow is the ability to check if the card number entered by a user is issued by a specific bank.

    Xendit's Promotion APIs fully support such promotions. They allow you to create a Promotion and select a range of credit card Bank Identification Numbers (BINs) to whitelist (BINs are the first 6 digits of a card, e.g. 480012). During the card payment process, send us a request to GET a Promotion Calculation. If an applicable Promotion for the type of card exists, Xendit automatically applies the promotion discount rate and returns you the information so you can charge the discounted amount.

    Definition: Create Promotion

    POST https://api.xendit.co/promotions

    Example Create Promotion Request

    curl -X POST \
      https://api.xendit.co/promotions
      -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \
      -H 'content-type: application/json' \
      -d {
          "reference_id": "BRI_20_JAN",
          "description": "20% discount applied for all BRI cards",
          "bin_list": [
              "400000",
              "460000"
          ],
          "discount_percent": 20,
          "channel_code": "BRI",
          "currency": "IDR",
          "min_original_amount": 25000,
          "max_discount_amount": 5000
        }
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    CreditCard = xendit_instance.CreditCard
    
    promotion = CreditCard.create_promotion(
        reference_id="BRI_20_JAN-1594176600",
        description="20% discount applied for all BRI cards",
        discount_amount=10000,
        bin_list=['400000', '460000'],
        start_time="2020-01-01T00:00:00.000Z",
        end_time="2021-01-01T00:00:00.000Z",
        min_original_amount=25000,
        max_discount_amount=5000
    )
    print(promotion)

    Example Create Promotion Response

    {
        "id": "36ab1517-208a-4f22-b155-96fb101cb378",
        "business_id": "5e61664b3dba955c203d232e",
        "reference_id": "BRI_20_JAN",
        "description": "20% discount applied for all BRI cards",
        "start_time": "2020-01-01 00:00:00.000Z",
        "end_time": "2020-01-01 00:00:00.000Z",
        "status": "ACTIVE",
        "bin_list": [
          "400000",
          "460000"
        ],
        "discount_percent": 20,
        "channel_code": "BRI",
        "currency": "IDR",
        "min_original_amount": 25000,
        "max_discount_amount": 5000
    }

    Request Parameters

    Body Parameter Type Description
    reference_id
    required
    string Unique reference, such as an ID or name, you wish to assign to the created Promotion.
    Charactersa-z, A-Z, 0-9; accepted symbols all special characters are allowed
    description
    required
    text The description of the Promotion. This will later be returned in the Get Promotions Calculation response, and you can expose it to the user on your user interface.
    promo_code
    optional
    string Promo code which can be used by an end user to activate the promo.
    Include this if you want your Promotion to be activated by the end user entering a code. A Promotion can be created with both the promo_code and bin_list or channel_code, if you want only certain cards to be able to use the promo code.
    Charactersa-z, A-Z, 0-9; accepted symbols all special characters are allowed
    bin_list
    optional
    array of strings The list of BINs whitelisted for a specific Promotion.
    Example: [ "400000", "460000" ]
    channel_code
    optional
    string The bank whitelisted for a specific Promotion.
    When a specific bank is chosen, any BIN which Xendit associates with that bank will be eligible for the Promotion.
    discount_percent
    optional
    number Percentage discount applicable for a specific Promotion. e.g. you want the Promotion to be a 20% discount.
    Either discount_percent or discount_amount is required.
    CharactersNumbers (includes decimals)
    Maximum 100
    Minimum0
    discount_amount
    optional
    number Amount of discount applicable for a specific Promotion. e.g. you want the Promotion to be a 50000 IDR discount.
    Either discount_percent or discount_amount is required.
    CharactersNumbers (includes decimals)
    Maximum none
    Minimum0
    currency
    required
    default: IDR
    string Currency which you want to process the transaction in. Use a three-letter ISO currency code. For banks with branches in more than one country, a Promotion will only apply to cards based on the currency.
    e.g. if currency is IDR and channel_code is DBS, then the Promotion will apply only to BINs issued by DBS Indonesia.
    start_time
    required
    ISO All created Promotions will start immediately by default.
    If you want a Promotion to start later, use this field to enter the start date of the promotion.
    Promo end date must be a date in the future.
    end_time
    required
    ISO Date which the Promotion will end.
    Promo end date must be a date in the future.
    min_original_amount
    optional
    number Minimum of the original amount for a certain promo to be applicable or calculated.
    max_discount_amount
    optional
    number Maximum of the discount amount that will be applied for a certain promo.

    Response Parameters

    Promotion Object

    Parameter Type Description
    id string Unique ID of the created Promotion (generated by Xendit).
    business_id string ID of your account with Xendit, used to identify you as a unique merchant.
    status string Status of the Promotion. See Promotion Statuses
    reference_id string Unique reference, such as an ID or name, you wish to assign to the created Promotion.
    Charactersa-z, A-Z, 0-9; accepted symbols all special characters are allowed
    description text The description of the Promotion. You can expose this to the user on your user interface to give them details about the Promotion.
    promo_code string Promo code which can be used by an end user to activate the promo. Include this if you want your Promotion to be activated by the end user entering a code. A Promotion can be created with both the promo_code and bin_list or channel_code, if you want only certain cards to be able to use the promo code..
    Charactersa-z, A-Z, 0-9; accepted symbols all special characters are allowed
    bin_list array of strings The list of BINs whitelisted for a specific Promotion.
    channel_code string The bank whitelisted for a specific Promotion. When a specific bank is chosen, any BIN which Xendit associates with that bank will be eligible for the Promotion. The channel code must match the channel codes here precisely.
    discount_percent number Percentage discount applicable for a specific Promotion.
    CharactersNumbers (includes decimals)
    Maximum 100
    Minimum0
    discount_amount number Amount of discount applicable for a specific Promotion.
    CharactersNumbers (includes decimals)
    Maximum none
    Minimum0
    currency
    default: IDR
    string Currency which you want to process the transaction in. Use a three-letter ISO currency code. For banks with branches in more than one country, a Promotion will only apply to cards based on the currency.
    e.g. if currency is IDR and channel_code is DBS, then the Promotion will apply only to BINs issued by DBS Indonesia.
    start_time ISO All created Promotions will start immediately by default.
    If you want a Promotion to start later, use this field to enter the start date of the promotion.
    Promo end date must be a date in the future.
    end_time ISO Date which the Promotion will end.
    Promo end date must be a date in the future.
    min_original_amount number Minimum of the original amount for a certain promo to be applicable or calculated.
    max_discount_amount number Maximum of the discount amount that will be applied for a certain promo.

    Promotion Statuses

    Status Description
    ACTIVE Promotion is active and eligible
    INACTIVE Promotion is still valid but inactive due to not yet started
    EXPIRED Promotion is already passed the end_time
    PAUSED Promotion is paused in the middle of the period based on user's request

    Error Codes

    Error Code Description
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    INVALID_JSON_FORMAT
    400
    The request body is not valid JSON.
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have the necessary permissions to perform the request. Please assign proper permissions for the key, or use a different key.
    REFERENCE_IN_USE
    409
    This Promotion name has been used for a previous or existing Promotion. Please use a different name.
    PROMO_CODE_IN_USE
    409
    This Promotion code has been used for a previous or existing Promotion. Please use a different code

    Get Promotions

    Use this API endpoint to obtain details of a created Promotion. Useful to get a quick snapshot of your available Promotions. If more than one Promotion matches a field you have entered, an array of all the relevant Promotions will be returned.

    Definition: Get Promotions

    GET https://api.xendit.co/promotions?reference_id={reference_id}

    Example Get Promotions Request

    curl -X GET \
      https://api.xendit.co/promotions?reference_id=BRI_20_JAN
      -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \
      -H 'content-type: application/json' \

    Example Get Promotions Response

    {
        "id": "36ab1517-208a-4f22-b155-96fb101cb378",
        "business_id": "5e61664b3dba955c203d232e",
        "reference_id": "BRI_20_JAN",
        "description": "20% discount applied for all BRI cards",
        "start_time": "2020-01-01 00:00:00.000Z",
        "end_time": "2020-01-01 00:00:00.000Z",
        "status": "ACTIVE",
        "bin_list": [
            "400000",
            "460000"
        ],
        "discount_percent": 20,
        "channel_code": "BRI",
        "currency": "IDR",
        "min_original_amount": 25000,
        "max_discount_amount": 5000
    }

    Request Parameters

    Query Parameter Type Description
    reference_id
    optional
    string Enter the specific reference_id of a single Promotion.
    status
    required
    enum Status of the Promotion.
    ACTIVE or INACTIVE.
    bin
    optional
    string A specific BIN.

    Example: 460000
    channel_code
    optional
    string The bank whitelisted for a specific Promotion.
    currency
    optional
    default: IDR
    string Currency which you want to process the transaction in. Use a three-letter ISO currency code.
    currently, only IDR is accepted.

    Response Parameters

    The array returns details of available Promotions depending on what fields you included in your query, in the Promotion Object format. For example, if you entered the bin_list value as [ "400000" ], an array of all available Promotions which include that BIN value will be returned.

    If no promotions match the query, an empty array will be returned.

    Get Promotions Calculation

    This endpoint is used to calculate how much discount should be applied to an amount being charged. It accepts a BIN or a promo_code, as well as the original charge amount. If the BIN or promo_code matches an available Promotion, Xendit will apply the discount to the original amount and return the discounted amount in the response. This API will only perform calculation for promotion with ACIVE status.

    We've built a page for you to test sending Get Promotion Calculations requests before you integrate. Try it out here. You'll need your Public API key, which you can obtain from registering on our Dashboard and heading to the Settings page.

    Definition: Get Promotions Calculation

    GET https://api.xendit.co/promotions/calculate?amount={amount}&bin={bin}

    Example Get Promotions Calculation Request using Bin

    curl -X GET \
      https://api.xendit.co/promotions/calculate?amount=1000000&bin=460000
      -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \
      -H 'content-type: application/json' \

    Example Get Promotions Calculation Request using Token ID

    curl -X GET \
      https://api.xendit.co/promotions/calculate?amount=1000000&token_id=598d5d0e51e0870d44c61534
      -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \
      -H 'content-type: application/json' \

    Get Promotions Calculation Request

    Query Parameter Type Description
    amount
    required
    number The amount of the original transaction (before the Promotion discount).
    bin
    optional
    string The BIN entered by the cardholder, which you want to check if it is associated with any active Promotion.
    promo_code
    optional
    string The promo_code entered by the cardholder, which you want to check if it is associated with any active Promotion.
    currency
    optional
    default: IDR
    string Currency which you want to process the transaction in. Use a three-letter ISO currency code.
    token_id
    optional
    string Token ID of a card, obtained during tokenization with Xendit. We will look up the token to associate it with a BIN and get the available options.

    Example Get Promotions Calculation Response

    {
        "original_amount": 1000000,
        "discount_percent": 20,
        "reference_id": "BRI_20_JAN",
        "final_amount": 900000,
        "currency": "IDR",
        "description": "20% discount applied for all BRI cards with maximum discount amount 100000",
        "min_original_amount": 500000,
        "max_discount_amount": 100000
    }

    Get Promotions Calculation Response

    Parameter Type Description
    reference_id
    required
    string Unique reference which you assigned to the created Promotion.
    original_amount
    required
    number The amount of the original transaction (before the Promotion discount).
    discount_percent
    optional
    number Percentage discount applicable for a specific Promotion.
    Returned if the Promotion was created using discount_percent.
    discount_amount
    optional
    number Amount of discount applicable for a specific Promotion.

    Returned if the Promotion was created using discount_amount.
    final_amount
    required
    number The final amount, after the Promotion discount has been applied. You should use this sum to charge the card.
    description
    required
    text The description of the Promotion. Returned in the Get Promotions Calculation response so you can expose it on your user interface.
    min_original_amount
    optional
    number Minimum of the original amount for a certain promo to be applicable or calculated.
    max_discount_amount
    optional
    number Maximum of the discount amount that will be applied for a certain promo.

    Update Promotion

    Use this endpoint to update the details of an existing Promotion.

    Definition: Update Promotion

    PATCH https://api.xendit.co/promotions/:promotion_id

    Example Update Promotion request

    curl -X PATCH \
      https://api.xendit.co/promotions/36ab1517-208a-4f22-b155-96fb101cb378
      -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \
      -H 'content-type: application/json' \
     -d {
            "description": "20% discount applied for all BCA cards",
            "bin_list": [
              "411455",
              "422566"
            ],
            "discount_percent": 20,
            "channel_code": "BCA",
            "currency": "IDR"
        }

    Example Update Promotion response

    {
        "id": "36ab1517-208a-4f22-b155-96fb101cb378",
        "business_id": "5e61664b3dba955c203d232e",
        "reference_id": "BCA_20",
        "description": "20% discount applied for all BRI cards",
        "start_time": "2020-01-01 00:00:00.000Z",
        "end_time": "2020-01-01 00:00:00.000Z",
        "transaction_limit": 0,
        "is_deleted": false,
        "status": "ACTIVE",
        "bin_list": [
            "411455",
            "422566"
        ],
        "discount_percent": 20,
        "channel_code": "BCA",
        "currency": "IDR",
        "min_original_amount": 25000,
        "max_discount_amount": 5000
    }
    

    Request Parameters

    Path Parameter Type Description
    promotion_id
    required
    string Enter promotion id which provided by Xendit in promotion object

    Not every parameter in the Promotion Object can be updated. Those that can be updated can be found below.

    Body Parameter Type Description
    description
    optional
    text The description of the Promotion. This will later be returned in the Get Promotions Calculation response, and you can expose it to the user on your user interface.
    promo_code
    optional
    string Promo code which can be used by an end user to activate the promo.
    Include this if you want your Promotion to be activated by the end user entering a code. A Promotion can be created with both the promo_code and bin_list or channel_code, if you want only certain cards to be able to use the promo code.
    Charactersa-z, A-Z, 0-9; accepted symbols all special characters are allowed
    bin_list
    optional
    array of strings The list of BINs whitelisted for a specific Promotion.
    channel_code
    optional
    string The bank whitelisted for a specific Promotion. When a specific bank is chosen, any BIN which Xendit associates with that bank will be eligible for the Promotion. The channel code must match the channel codes here precisely.
    discount_percent
    optional
    number Percentage discount applicable for a specific Promotion. e.g. you want the Promotion to be a 20% discount.
    Either discount_percent or discount_amount is required.
    CharactersNumbers (includes decimals)
    Maximum 100
    Minimum0
    discount_amount
    optional
    number Amount of discount applicable for a specific Promotion. e.g. you want the Promotion to be a 50000 IDR discount.
    Either discount_percent or discount_amount is required.
    CharactersNumbers (includes decimals)
    Maximum none
    Minimum0
    currency
    default: IDR
    string The currency which payment will be made in.
    For banks with branches in more than one country, a Promotion will only apply to cards based on the currency. e.g. if currency is IDR and channel_code is DBS, then the Promotion will apply only to BINs issued by DBS Indonesia.
    start_time
    optional
    ISO All created Promotions will start immediately by default.
    If you want a Promotion to start later, use this field to enter the start date of the promotion.
    Promo end date must be a date in the future.
    end_time
    optional
    ISO Date which the Promotion will end.
    Promo end date must be a date in the future.
    min_original_amount
    optional
    number Minimum of the original amount for a certain promo to be applicable or calculated.
    max_discount_amount
    optional
    number Maximum of the discount amount that will be applied for a certain promo.

    Response Parameters

    Returns Promotion Object. The parameters which you updated via the Update Promotion request will be the new parameters.

    Error Codes

    Error Code Description
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    INVALID_JSON_FORMAT
    400
    The request body is not valid JSON.
    PROMOTION_NOT_FOUND_ERROR
    404
    Promotion not found. Please try again with valid promotion id.
    PROMO_CODE_IN_USE
    400
    This Promotion code has been used for a previous or existing Promotion. Please use a different promo_code.
    INVALID_DISCOUNT_TYPE
    400
    Promotion with promotion_id has [discount_amount / discount_percent] type. Please use the correct discount type
    INVALID_START_TIME_UPDATE
    400
    Promotion with promotion_id has end time. Please try again with an updated start time that is before the end time.

    Delete Promotion

    Use this endpoint to delete an existing Promotion from your list of available Promotions.

    Definition: Delete Promotion

    DELETE https://api.xendit.co/promotions/:promotion_id

    Example Delete Promotion request

    curl -X DELETE \
      https://api.xendit.co/promotions/6055a96c-a870-4a2f-b61f-4015af6478cb
      -u xnd_development_OYiAfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/byhDAB+gA==: \

    Example Delete Promotion response

    {
          "id":"6055a96c-a870-4a2f-b61f-4015af6478cb",
          "created":"2020-07-29T10:57:47.426Z",
          "business_id":"5edfb2a5d40e3040347d91fd",
          "reference_id":"Cypress-Test-Promo-Delete-1596020266435",
          "start_time":"2020-07-29T10:57:46.373Z",
          "end_time":"2020-07-30T10:57:46.373Z",
          "status":"DELETED",
          "type":"PROMO_CODE",
          "discount_amount":5000,
          "promo_code":"Cypress-Test-Promo-Delete-1596020266435",
          "currency":"IDR"
       }
    }

    Delete Promotion Request

    Path Parameter Type Description
    promotion_id
    required
    string Enter promotion id which provided by Xendit in promotion object

    Delete Promotion Response

    Parameter Type Description
    id string Unique ID of the deleted Promotion (generated by Xendit).
    is_deleted boolean Status of a promotion to describe that it's already deleted.

    Error Codes

    Error Code Description
    PROMOTION_NOT_FOUND_ERROR
    404
    Promotion with id not found. Please try again with valid id.

    eWallets

    Our eWallet API allows you to seamlessly charge and receive payments directly from top ewallets providers in SEA. With one integration, get access to all our available eWallets and upcoming eWallets integrations as well. To date, we've processed millions of eWallet transactions and support various business use cases

    For full details on each API as well as help on integration, please refer to our documentation

    Version

    You are currently viewing the newest version of our eWallets API. In this API version, integrate once to get access to all available eWallets and future eWallets in Xendit! This API will also be used to support tokenized payment flow and auth/capture payment flow in the near future.

    Version Changelog
    2021-01-25
    Latest
    New simple and consistent eWallets API to support top eWallets providers in Indonesia and Philippines
    No API Versioning is required. You can access the new API easily by calling POST /ewallets/charges
    2020-02-01
    will be deprecated by 31st March 2022
    Implemented the asynchronous flow for OVO payment callbacks.
    2019-02-04
    will be deprecated by 31st March 2022
    Returns a response immediately without any callbacks returned.

    Create eWallet Charge

    Endpoint: Create eWallet Charge Request

    POST https://api.xendit.co/ewallets/charges

    eWallet

    Request Parameters

    Example: Create eWallet Charge Request

    curl https://api.xendit.co/ewallets/charges -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
      --data '{
        "reference_id": "order-id-123",
        "currency": "IDR",
        "amount": 25000,
        "checkout_method": "ONE_TIME_PAYMENT",
        "channel_code": "ID_SHOPEEPAY",
        "channel_properties": {
            "success_redirect_url": "https://redirect.me/payment"
            },
        "metadata": {
            "branch_area": "PLUIT",
            "branch_city": "JAKARTA"
            }
        }' \
    try {
        Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
        Map<String, String> channelProperties = new HashMap<>();
        channelProperties.put("success_redirect_url", "https://dashboard.xendit.co/register/1");
        Map<String, String> metadata = new HashMap<>();
        metadata.put("branch_code", "tree_branch");
    
        Map<String, Object> params = new HashMap<>();
        params.put("reference_id", "test-reference-id");
        params.put("currency", "IDR");
        params.put("amount", 1000);
        params.put("checkout_method", "ONE_TIME_PAYMENT");
        params.put("channel_code", "ID_SHOPEEPAY");
        params.put("channel_properties", channelProperties);
        params.put("metadata", metadata);
    
        EWalletCharge charge = EWalletCharge.createEWalletCharge(params);
    } catch (XenditException e) {
        e.printStackTrace();
    }
    <?php
    
    use Xendit\Xendit;
    require 'vendor/autoload.php';
    
    Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
    $params = [
        'reference_id' => 'test-reference-id',
        'currency' => 'IDR',
        'amount' => 1000,
        'checkout_method' => 'ONE_TIME_PAYMENT',
        'channel_code' => 'ID_SHOPEEPAY',
        'channel_properties' => [
            'success_redirect_url' => 'https://dashboard.xendit.co/register/1',
        ],
        'metadata' => [
            'branch_code' => 'tree_branch'
        ]
    ];
    
    $createEWalletCharge = \Xendit\EWallets::createEWalletCharge($ewalletChargeParams);
    var_dump($createEWalletCharge);
    
    ?>
    from xendit import EWallet
    
    ewallet_charge = EWallet.create_ewallet_charge(
        reference_id="test-reference-id",
        currency="IDR",
        amount=1000,
        checkout_method="ONE_TIME_PAYMENT",
        channel_code="ID_SHOPEEPAY",
        channel_properties={
            "success_redirect_url": "https://dashboard.xendit.co/register/1",
        },
        metadata={
            "branch_code": "tree_branch",
        },
    )
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := ewallet.CreateEWalletChargeParams{
        ReferenceID:    "test-reference-id",
        Currency:       "IDR",
        Amount:         1000,
        CheckoutMethod: "ONE_TIME_PAYMENT",
        ChannelCode:    "ID_SHOPEEPAY",
        ChannelProperties: map[string]string{
            "success_redirect_url": "https://dashboard.xendit.co/register/1",
        },
        Metadata: map[string]interface{}{
            "branch_code": "tree_branch",
        },
    }
    
    charge, chargeErr := ewallet.CreateEWalletCharge(&data)
    if chargeErr != nil {
        log.Fatal(chargeErr)
    }
    
    fmt.Printf("created e-wallet charge: %+v\n", charge)
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { EWallet } = x;
    const ewalletSpecificOptions = {};
    const ew = new EWallet(ewalletSpecificOptions);
    
    const resp = await ew.createEWalletCharge({
      referenceID: 'test-reference-id',
      currency: 'IDR',
      amount: 1000,
      checkoutMethod: 'ONE_TIME_PAYMENT',
      channelCode: 'ID_SHOPEEPAY',
      channelProperties: {
        successRedirectURL: 'https://dashboard.xendit.co/register/1',
      },
      metadata: {
        branch_code: 'tree_branch'
      }
    });
    console.log(resp);
    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Body Parameter Type Description
    reference_id
    required
    string Reference ID provided by merchant (255 characters)
    Note: It has to be unique per charge request
    currency
    required
    string Currency used for the transaction in ISO4217 format - IDR, PHP
    amount
    required
    number Transaction amount to be paid
    Min - 100 IDR or 1 PHP
    Max - based on eWallet holding limit
    checkout_method
    required
    string Checkout method determines the payment flow used to process the transaction
    ONE_TIME_PAYMENT is used for single guest checkouts
    TOKENIZED_PAYMENT can be used for recurring payment
    channel_code
    required if checkout_method = ONE_TIME_PAYMENT, optional if checkout_method = TOKENIZED_PAYMENT
    string Channel Code specifies which eWallet will be used to process the transaction - ID_OVO, ID_DANA, ID_LINKAJA, ID_SHOPEEPAY, ID_SAKUKU, PH_PAYMAYA, PH_GCASH, PH_GRABPAY
    channel_properties
    required based on checkout_method and channel_code pairing
    object Channel specific information required for the transaction to be initiated
    OVO - one time payment required fields
    Key Value
    mobile_number
    required
    string Mobile number of customer in E.164 format (e.g. +628123123123)
    OVO - tokenized payment required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has failed
    redeem_points
    optional
    enum, default = "REDEEM_NONE" "REDEEM_NONE" - no points will be used or "REDEEM_ALL" - points will be used to offset payment amount before cash balance is used. REDEEM_ALL can only be used when approved by OVO for promotions.
    DANA, LINKAJA, SHOPEEPAY, SAKUKU required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    SHOPEEPAY - tokenized payment required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    redeem_points
    optional
    enum, default = "REDEEM_NONE" "REDEEM_NONE" - no points will be used or "REDEEM_ALL" - points will be used to offset payment amount before cash balance is used. Only 50% of transaction amount (rounded down) can paid using SHOPEEPAY coins.
    GCASH, GRABPAY required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has failed
    PAYMAYA required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has failed
    cancel_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes.
    payment_method_id
    required if checkout_method = TOKENIZED_PAYMENT, optional if checkout_method = ONE_TIME_PAYMENT
    string ID of the payment method. Payment method is being used for tokenized payment to abstract your customer's ewallet as payment method
    customer_id
    optional
    string ID of the customer object to which the payment method will be linked to. Use Create Customer API to create your customer
    basket
    optional
    array Array of objects describing the item(s) purchased
    Object parameters details
    Key Value
    reference_id
    required
    string Merchant's identifer for specific product <= 255 characters
    name
    required
    string Name of product
    category
    required
    string Merchant category for item - e.g. Electronics
    currency
    required
    string Currency used for the transaction in ISO4217 format - IDR, PHP
    price
    required
    number Price per unit in basket currency
    quantity
    required
    number Number of units of this item in the basket
    type
    required
    string Type of product - PRODUCT or SERVICE
    url
    optional
    string URL to e-commerce page of the item
    description
    optional
    string Description of product
    sub_category
    optional
    string Merchant sub-category for item - e.g. Mobile Phone
    metadata
    optional
    object Object of additional information the user may use. Users define the JSON properties and values.
    You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
    This will only be used by the user and not Xendit.
    metadata
    optional
    object Object of additional information the user may use. Users define the JSON properties and values.
    You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
    This will only be used by the user and not Xendit.

    Response Parameters

    Example: Create eWallet Charge Request API Success Response

    {
      "id": "ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2",
      "business_id": "5f218745736e619164dc8608",
      "reference_id": "test-reference-id",
      "status": "PENDING",
      "currency": "IDR",
      "charge_amount": 1000,
      "capture_amount": 1000,
      "checkout_method": "ONE_TIME_PAYMENT",
      "channel_code": "ID_SHOPEEPAY",
      "channel_properties": {
        "success_redirect_url": "https://dashboard.xendit.co/register/1"
      },
      "actions": {
        "desktop_web_checkout_url": null,
        "mobile_web_checkout_url": null,
        "mobile_deeplink_checkout_url": "https://deeplinkcheckout.this/",
        "qr_checkout_string": "ID123XenditQRTest321DI"
      },
      "is_redirect_required": true,
      "callback_url": "https://calling-back.com/xendit/shopeepay",
      "created": "2017-07-21T17:32:28Z",
      "updated": "2017-07-21T17:32:28Z",
      "voided_at": null,
      "capture_now": true,
      "customer_id": null,
      "payment_method_id": null,
      "failure_code": null,
      "basket": null,
      "metadata": {
        "branch_code": "tree_branch"
      }
    }
    Body Parameter Type Description
    id
    required
    string Unique identifier for charge request transaction. It will always have the prefix of 'ewc_', followed by a UUIDv4
    business_id
    required
    string Business ID of the merchant
    reference_id
    required
    string Reference ID provided by merchant
    Note: It has to be unique per payment request.
    status
    required
    string Status of charge request
    Key Value
    SUCCEEDED
    Payment transaction for specified charge_id is successfully
    PENDING
    Payment transaction for specified charge_id is awaiting payment attempt by end user
    FAILED
    Payment transaction for specified charge_id has failed, check failure codes for reasons
    VOIDED
    Payment transaction for specified charge_id has been voided
    currency
    required
    string Currency used for the transaction in ISO4217 format - IDR, PHP
    charge_amount
    required
    number Requested charge amount from merchant
    capture_amount
    optional
    number Requested capture amount from merchant. In requests where checkout_method = ONE_TIME_PAYMENT, capture_amount will always be the same as charge_amount
    checkout_method
    required
    string Checkout method determines the payment flow used to process the transaction
    ONE_TIME_PAYMENT is used for single guest checkouts
    channel_code
    required
    string Channel Code specifies which eWallet will be used to process the transaction - ID_OVO, ID_DANA, ID_LINKAJA, ID_SHOPEEPAY, ID_SAKUKU, PH_PAYMAYA, PH_GCASH, PH_GRABPAY
    channel_properties
    optional
    object Channel specific information required for the transaction to be initiated
    OVO required fields
    Key Value
    mobile_number
    required
    string Mobile number of customer in E.164 format (e.g. +628123123123)
    DANA, LINKAJA, SHOPEEPAY, SAKUKU required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    GCASH, GRABPAY required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has failed
    PAYMAYA required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has failed
    cancel_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes.
    actions
    optional
    string Redirection actions to be taken when is_redirect_required returned in response is true. Merchants should choose one of the available options based on the ideal experience for their payment flows
    Key Value
    desktop_web_checkout_url
    eWallet issuer generated URL for web checkout on devices with a stand-alone screen
    mobile_web_checkout_url
    eWallet issuer generated URL for web checkout on mobile devices
    mobile_deeplink_checkout_url
    eWallet issuer generated URL for deeplink checkout on mobile devices (jumps directly into eWallet app for payment confirmation)
    qr_checkout_string
    eWallet issuer generated qr string for checkout usually on devices with a stand-alone screen
    Channels with redirection required more info
    Type DANA LINKAJA PAYMAYA SHOPEEPAY GCASH GRABPAY SAKUKU
    desktop_web_checkout_url
    mobile_web_checkout_url
    mobile_deeplink_checkout_url
    qr_checkout_string
    is_redirect_required
    required
    boolean Flag which indicates whether redirection is required for end user to complete payment
    When True, merchants should redirect the end user to the url given in the “actions” field. When False, there is no need for redirection for payment process to continue
    callback_url
    required
    string Callback URL which payment notifications will be sent
    created
    required
    string ISO 8601 Timestamp for charge object creation. Timezone UTC+0
    updated
    required
    string ISO 8601 Timestamp for latest charge object update. Timezone UTC+0
    voided_at
    optional
    string ISO 8601 Timestamp when transaction was voided. Timezone UTC+0
    capture_now
    required
    string Default: true. Field not in use currently
    customer_id
    optional
    string ID of the customer object created with Xendit. ID to will be linked to the transaction
    payment_method_id
    optional
    string Xendit’s identifier for end user payment tokens binded with merchant. Only used for channels which support tokenized payments
    failure_code
    optional
    string Reason for failure of payment by end user or eWallet issuer. The failure_code is notified to the merchant in the payment callback or GET payment status after transaction is attempted by end user
    basket
    optional
    array Array of objects describing the item(s) purchased
    Object parameters details
    Key Value
    reference_id
    required
    string Merchant's identifer for specific product <= 255 characters
    name
    required
    string Name of product
    category
    required
    string Merchant category for item - e.g. Electronics
    currency
    required
    string Currency used for the transaction in ISO4217 format - IDR, PHP
    price
    required
    number Price per unit in basket currency
    quantity
    required
    number Number of units of this item in the basket
    type
    required
    string Type of product - PRODUCT or SERVICE
    url
    optional
    string URL to e-commerce page of the item
    description
    optional
    string Description of product
    sub_category
    optional
    string Merchant sub-category for item - e.g. Mobile Phone
    metadata
    optional
    object User defined object with JSON properties and values passed in during charge creation.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
    This will only be used by the user and not Xendit.
    metadata
    optional
    object User defined object with JSON properties and values passed in during charge creation.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

    Error Codes

    Example: Create eWallet Charge Request API Error Response

    {
        "error_code": "UNSUPPORTED_CURRENCY",
        "message": "The payment currency request is not supported for this payment channel. Please refer to our API reference or docs to pick available currencies"
    }
    Error Code Description
    DUPLICATE_PAYMENT_REQUEST_ERROR
    400
    The charge with the same reference_id has already been created before
    API_VALIDATION_ERROR
    400
    There is invalid input in one of the required request fields
    UNSUPPORTED_CURRENCY
    400
    The payment currency request is not supported for this payment channel. Please refer to our API reference or docs to pick available currencies
    INVALID_API_KEY
    401
    API key format is invalid
    INVALID_MERCHANT_CREDENTIALS
    401
    Merchant credentials met with an error with the eWallet provider. Please contact Xendit customer support to resolve this issue
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request
    CHANNEL_NOT_ACTIVATED
    403
    Payment request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
    CALLBACK_URL_NOT_FOUND
    404
    Payment request failed because there was no input of callback url in Xendit Dashboard or request headers. Please save your callback url in Xendit Dashboard
    UNSUPPORTED_CONTENT_TYPE
    403
    The content type requested is not supported
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue
    CHANNEL_UNAVAILABLE
    503
    The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue

    Payment Status Callback

    You need to provide an endpoint your system to receive all payment callback notification from our system. You will receive the callback when end-customer attempted payments for available eWallets. Please specify this endpoint in Xendit dashboard callback url page under eWallets paid

    The payment callback notification will be sent as POST request to the URL you have set in the dashboard. Note: Please give this notification a response back with status 200 so we know that our notification is received and will not attempt to retry the notification.

    Callback Payload

    Example: Success Payment Callback Payload

    {
      "event": "ewallet.capture",
      "business_id": "5abe2389ewpejrt238",
      "created": "2020-04-20T16:25:52Z",
      "data": {
        "id": "ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2",
        "business_id": "5f218745736e619164dc8608",
        "reference_id": "test-reference-id",
        "status": "SUCCEEDED",
        "currency": "IDR",
        "charge_amount": 1000,
        "capture_amount": 1000,
        "checkout_method": "ONE_TIME_PAYMENT",
        "channel_code": "ID_SHOPEEPAY",
        "channel_properties": {
          "success_redirect_url": "https://dashboard.xendit.co/register/1"
        },
        "actions": {
          "desktop_web_checkout_url": null,
          "mobile_web_checkout_url": null,
          "mobile_deeplink_checkout_url": "https://deeplinkcheckout.this/",
          "qr_checkout_string": "ID123XenditQRTest321DI"
        },
        "is_redirect_required": true,
        "callback_url": "https://calling-back.com/xendit/shopeepay",
        "created": "2017-07-21T17:32:28Z",
        "updated": "2017-07-21T17:32:28Z",
        "voided_at": null,
        "capture_now": true,
        "customer_id": null,
        "payment_method_id": null,
        "failure_code": null,
        "basket": null,
        "metadata": {
          "branch_code": "tree_branch"
        }
      }
    }
    Header Parameter Type Description
    x-callback-token
    string Your Xendit unique callback token to verify the origin of the callback

    Body Parameter Type Description
    event
    required
    string Identifies the event triggering a notification to merchant. ewallet.capture occurs when eWallet issuer confirms the payment status of a transaction
    business_id
    required
    string Business ID of the merchant
    created
    required
    string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
    data
    optional
    object eWallets charge object will be nested in this parameter. See here for full definitions
    Data fields
    Key Value
    id
    required
    string Unique identifier for charge request transaction. It will always have the prefix of 'ewc_', followed by a UUIDv4
    business_id
    required
    string Business ID of the merchant
    reference_id
    required
    string Reference ID provided by merchant
    Note: It has to be unique per payment request.
    status
    required
    Status of charge request - SUCCEEDED, FAILED, VOIDED
    currency
    required
    string Currency used for the transaction in ISO4217 format - IDR, PHP
    charge_amount
    required
    number Requested charge amount from merchant
    capture_amount
    optional
    number Requested capture amount from merchant. In requests where checkout_method = ONE_TIME_PAYMENT, capture_amount will always be the same as charge_amount
    checkout_method
    required
    string Checkout method determines the payment flow used to process the transaction
    ONE_TIME_PAYMENT is used for single guest checkouts
    channel_code
    required
    string Channel Code specifies which eWallet will be used to process the transaction - ID_OVO, ID_DANA, ID_LINKAJA, ID_SHOPEEPAY, ID_SAKUKU, PH_PAYMAYA, PH_GCASH, PH_GRABPAY
    channel_properties
    optional
    object Channel specific information required for the transaction to be initiated
    OVO required fields
    Key Value
    mobile_number
    required
    string Mobile number of customer in E.164 format (e.g. +628123123123)
    DANA, LINKAJA, SHOPEEPAY required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    GCASH, GRABPAY required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has failed
    PAYMAYA required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has failed
    cancel_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes.
    actions
    optional
    string Redirection actions to be taken when is_redirect_required returned in response is true. Merchants should choose one of the available options based on the ideal experience for their payment flows
    is_redirect_required
    required
    boolean Flag which indicates whether redirection is required for end user to complete payment
    When True, merchants should redirect the end user to the url given in the “actions” field. When False, there is no need for redirection for payment process to continue
    callback_url
    required
    string Callback URL which payment notifications will be sent
    created
    required
    string ISO 8601 Timestamp for charge object creation. Timezone UTC+0
    updated
    required
    string ISO 8601 Timestamp for latest charge object update. Timezone UTC+0
    voided_at
    optional
    string ISO 8601 Timestamp when transaction was voided. Timezone UTC+0
    capture_now
    required
    string Default: true. Field not in use currently
    customer_id
    optional
    string ID of the customer object created with Xendit. ID to will be linked to the transaction
    payment_method_id
    optional
    string Xendit’s identifier for end user payment tokens binded with merchant. Only used for channels which support tokenized payments
    failure_code
    optional
    string Reason for failure of payment by end user or eWallet issuer. The failure_code is notified to the merchant in the payment callback or GET payment status after transaction is attempted by end user
    basket
    optional
    array Array of objects describing the item(s) purchased
    Object parameters details
    Key Value
    reference_id
    required
    string Merchant's identifer for specific product <= 255 characters
    name
    required
    string Name of product
    category
    required
    string Merchant category for item - e.g. Electronics
    currency
    required
    string Currency used for the transaction in ISO4217 format - IDR, PHP
    price
    required
    number Price per unit in basket currency
    quantity
    required
    number Number of units of this item in the basket
    type
    required
    string Type of product - PRODUCT or SERVICE
    url
    optional
    string URL to e-commerce page of the item
    description
    optional
    string Description of product
    sub_category
    optional
    string Merchant sub-category for item - e.g. Mobile Phone
    metadata
    optional
    object User defined object with JSON properties and values passed in during charge creation.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
    metadata
    optional
    object User defined object with JSON properties and values passed in during charge creation.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

    Failure Codes

    Example: Failed Payment Callback Payload

    {
      "event": "ewallet.capture",
      "business_id": "5abe2389ewpejrt238",
      "created": "2020-04-20T16:25:52Z",
      "data": {
        "id": "ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2",
        "business_id": "5f218745736e619164dc8608",
        "reference_id": "test-reference-id",
        "status": "FAILED",
        "currency": "IDR",
        "charge_amount": 1000,
        "capture_amount": 1000,
        "checkout_method": "ONE_TIME_PAYMENT",
        "channel_code": "ID_SHOPEEPAY",
        "channel_properties": {
          "success_redirect_url": "https://dashboard.xendit.co/register/1"
        },
        "actions": {
          "desktop_web_checkout_url": null,
          "mobile_web_checkout_url": null,
          "mobile_deeplink_checkout_url": "https://deeplinkcheckout.this/",
          "qr_checkout_string": "ID123XenditQRTest321DI"
        },
        "is_redirect_required": true,
        "callback_url": "https://calling-back.com/xendit/shopeepay",
        "created": "2017-07-21T17:32:28Z",
        "updated": "2017-07-21T17:32:28Z",
        "voided_at": null,
        "capture_now": true,
        "customer_id": null,
        "payment_method_id": null,
        "failure_code": "USER_DID_NOT_AUTHORIZE_THE_PAYMENT",
        "basket": null,
        "metadata": {
          "branch_code": "tree_branch"
        }
      }
    }
    Failure Code Failure Message
    ACCOUNT_ACCESS_BLOCKED
    End user’s account cannot be accessed as it has been restricted by the eWallet provider. End user should contact the provider for resolution.
    INVALID_MERCHANT_CREDENTIALS
    Merchant credentials met with an error with the eWallet provider. Please contact Xendit customer support to resolve this issue.
    USER_DECLINED_PAYMENT
    End user declined the payment request.
    INVALID_ACCOUNT_DETAILS
    End user provided incorrect information for this transaction.
    MAXIMUM_LIMIT_REACHED
    Accumulated value of payment requested for this end user went above the maximum transaction limit set by end user or eWallets. Payment can be retried when the transaction limit is reset.
    USER_UNREACHABLE
    End user’s device cannot be reached at this moment. Common reasons include unstable network, device error or jailbroken device.
    CHANNEL_UNAVAILABLE
    The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue.
    INSUFFICIENT_BALANCE
    End user has insufficient balance to complete the transaction.
    ACCOUNT_NOT_ACTIVATED
    End user’s account cannot be accessed as it has not been activated. End user should set up their account and ensure there is sufficient balance before retrying.
    INVALID_TOKEN
    Binding for this end user has expired. Please reinitiate binding before retrying.

    Get eWallet Charge Status

    Endpoint: Get eWallet Charge Status

    GET https://api.xendit.co/ewallets/charges/{id}

    This endpoint is used to get payment status of a charge request. You need to specify the id in the response body when hitting create eWallet charge request

    Version

    You are currently viewing the newest version of our eWallets API. Click here to view older versions.

    Request Parameters

    Example: Check eWallet Charge Status Request

    curl 'https://api.xendit.co/ewallets/charges/ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2' \
       -X GET \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
    try {
        Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
        EWalletCharge charge = EWalletCharge.getEWalletChargeStatus("ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2");
    } catch (XenditException e) {
        e.printStackTrace();
    }
    <?php
    
    use Xendit\Xendit;
    require 'vendor/autoload.php';
    
    Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
    $charge_id = 'ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2';
    $getEWalletChargeStatus = \Xendit\EWallets::getEWalletChargeStatus($charge_id);
    var_dump($getEWalletChargeStatus);
    
    ?>
    from xendit import EWallet
    
    ewallet_charge = EWallet.get_ewallet_charge_status(
        charge_id="ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2",
    )
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := ewallet.GetEWalletChargeStatusParams{
        ChargeID: "ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2",
    }
    
    charge, chargeErr := ewallet.GetEWalletChargeStatus(&data)
    if chargeErr != nil {
        log.Fatal(chargeErr)
    }
    
    fmt.Printf("retrieved e-wallet charge: %+v\n", charge)
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { EWallet } = x;
    const ewalletSpecificOptions = {};
    const ew = new EWallet(ewalletSpecificOptions);
    
    const resp = await ew.getEWalletChargeStatus({
      chargeID: 'ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2',
    });
    console.log(resp);
    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Query Parameter Type Description
    charge_id
    required
    string You need to specify the id in the response body when hitting create eWallet charge request

    Example: Check eWallet Charge Status Success Responses

    Check eWallet Charge Status Success Responses

    {
      "id": "ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2",
      "business_id": "5f218745736e619164dc8608",
      "reference_id": "test-reference-id",
      "status": "PENDING",
      "currency": "IDR",
      "charge_amount": 1000,
      "capture_amount": 1000,
      "checkout_method": "ONE_TIME_PAYMENT",
      "channel_code": "ID_SHOPEEPAY",
      "channel_properties": {
        "success_redirect_url": "https://dashboard.xendit.co/register/1"
      },
      "actions": {
        "desktop_web_checkout_url": null,
        "mobile_web_checkout_url": null,
        "mobile_deeplink_checkout_url": "https://deeplinkcheckout.this/",
        "qr_checkout_string": "ID123XenditQRTest321DI"
      },
      "is_redirect_required": true,
      "callback_url": "https://calling-back.com/xendit/shopeepay",
      "created": "2017-07-21T17:32:28Z",
      "updated": "2017-07-21T17:32:28Z",
      "voided_at": null,
      "capture_now": true,
      "customer_id": null,
      "payment_method_id": null,
      "failure_code": null,
      "basket": null,
      "metadata": {
        "branch_code": "tree_branch"
      }
    }
    Body Parameter Type Description
    id
    required
    string Unique identifier for charge request transaction. It will always have the prefix of 'ewc_', followed by a UUIDv4
    business_id
    required
    string Business ID of the merchant
    reference_id
    required
    string Reference ID provided by merchant
    Note: It has to be unique per payment request.
    status
    required
    string Status of charge request
    Key Value
    SUCCEEDED
    Payment transaction for specified charge_id is successfully
    PENDING
    Payment transaction for specified charge_id is awaiting payment attempt by end user
    FAILED
    Payment transaction for specified charge_id has failed, check failure codes for reasons
    VOIDED
    Payment transaction for specified charge_id has been voided
    currency
    required
    string Currency used for the transaction in ISO4217 format - IDR, PHP
    charge_amount
    required
    number Requested charge amount from merchant
    capture_amount
    optional
    number Requested capture amount from merchant. In requests where checkout_method = ONE_TIME_PAYMENT, capture_amount will always be the same as charge_amount
    checkout_method
    required
    string Checkout method determines the payment flow used to process the transaction
    ONE_TIME_PAYMENT is used for single guest checkouts
    TOKENIZED_PAYMENT can be used for recurring payment
    channel_code
    required
    string Channel Code specifies which eWallet will be used to process the transaction - ID_OVO, ID_DANA, ID_LINKAJA, ID_SHOPEEPAY, ID_SAKUKU, PH_PAYMAYA,PH_GCASH, PH_GRABPAY
    channel_properties
    optional
    object Channel specific information required for the transaction to be initiated
    OVO required fields
    Key Value
    mobile_number
    required
    string Mobile number of customer in E.164 format (e.g. +628123123123)
    DANA, LINKAJA, SHOPEEPAY required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    GCASH, GRABPAY required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has failed
    PAYMAYA required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has failed
    cancel_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes.
    actions
    optional
    string Redirection actions to be taken when is_redirect_required returned in response is true. Merchants should choose one of the available options based on the ideal experience for their payment flows
    Key Value
    desktop_web_checkout_url
    eWallet issuer generated URL for web checkout on devices with a stand-alone screen
    mobile_web_checkout_url
    eWallet issuer generated URL for web checkout on mobile devices
    mobile_deeplink_checkout_url
    eWallet issuer generated URL for deeplink checkout on mobile devices (jumps directly into eWallet app for payment confirmation)
    qr_checkout_string
    eWallet issuer generated qr string for checkout usually on devices with a stand-alone screen
    is_redirect_required
    required
    boolean Flag which indicates whether redirection is required for end user to complete payment
    When True, merchants should redirect the end user to the url given in the “actions” field. When False, there is no need for redirection for payment process to continue
    callback_url
    required
    string Callback URL which payment notifications will be sent
    created
    required
    string ISO 8601 Timestamp for charge object creation. Timezone UTC+0
    updated
    required
    string ISO 8601 Timestamp for latest charge object update. Timezone UTC+0
    voided_at
    optional
    string ISO 8601 Timestamp when transaction was voided. Timezone UTC+0
    capture_now
    required
    string Default: true. Field not in use currently
    customer_id
    optional
    string ID of the customer object created with Xendit. ID to will be linked to the transaction
    payment_method_id
    optional
    string ID of the payment method. Only used for channels which support tokenized payments
    failure_code
    optional
    string Reason for failure of payment by end user or eWallet issuer. The failure_code is notified to the merchant in the payment callback or GET payment status after transaction is attempted by end user
    basket
    optional
    array Array of objects describing the item(s) purchased
    Object parameters details
    Key Value
    reference_id
    required
    string Merchant's identifer for specific product <= 255 characters
    name
    required
    string Name of product
    category
    required
    string Merchant category for item - e.g. Electronics
    currency
    required
    string Currency used for the transaction in ISO4217 format - IDR, PHP
    price
    required
    number Price per unit in basket currency
    quantity
    required
    number Number of units of this item in the basket
    type
    required
    string Type of product - PRODUCT or SERVICE
    url
    optional
    string URL to e-commerce page of the item
    description
    optional
    string Description of product
    sub_category
    optional
    string Merchant sub-category for item - e.g. Mobile Phone
    metadata
    optional
    object User defined object with JSON properties and values passed in during charge creation.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
    metadata
    optional
    object User defined object with JSON properties and values passed in during charge creation.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

    Error Codes

    Example: Create eWallet Charge Request API Error Response

    {
        "error_code": "INVALID_API_KEY",
        "message": "API key format is invalid"
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    There is invalid input in one of the required request fields
    INVALID_API_KEY
    401
    API key format is invalid
    INVALID_MERCHANT_CREDENTIALS
    401
    Merchant credentials met with an error with the eWallet provider. Please contact Xendit customer support to resolve this issue
    DATA_NOT_FOUND
    404
    Charge ID specified was not found. Please check your query again.
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Tokenized - Create Customer Object

    There are 3 steps required to perform account linking using our tokenization flow - starting with a customer object creation and ending with a payment method object (to be used during the payment step).

    Step 1 - Creation of customer object via /customers endpoint is the required first step before initiating account linking for tokenized eWallets. The customer_id created will be used in the next API call to identify the end user who is performing account linking. Depending on each payment channel's requirements, there might be required fields for customer objects (e.g. OVO requires name and phone number). In such cases, it is recommended for merchants to build a UI for end users to key in these information themselves. Please refer to the requirements each payment channel below and Customer section to create customer object.

    OVO tokenization - required fields in Customer Object

    Example Customer Object - OVO tokenization

    curl https://api.xendit.co/customers -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
      --data '{
        "reference_id": "demo_1475801962607",
        "given_names": "John",
        "mobile_number": "+6287774441111",
        "email": "customer@website.com"
        }' \
    Request Body Parameter Type Description
    reference_id
    required
    string Merchant-provided identifier for the customer (max 255 characters)
    mobile_number
    required
    string Key identifier used by OVO for account linking. Mobile number of the customer in E.164 international standard must match with OVO's database.
    Format: +(country code)(subscriber number)
    given_names
    required
    string Primary of first name/s of the customer (max 255 characters)

    Tokenized - Account Linking

    Step 2 - Account linking in tokenized eWallet refers to end user authorizing merchants to perform transactions via a token (linking) for the end user's eWallet (account). This endpoint starts the authorization process and a linked account token will be created as a result. End users need to be redirected to the eWallet provider's hosted page to authorize the account linking. Once the account linking is completed by the end user, an account linking notification will be sent to the callback url specified in the request. The linked account id (prefix la-) in the notification should be stored as it will be used to create a payment method object in the next step.

    Endpoint: Initialize Linked Account Tokenization

    POST https://api.xendit.co/linked_account_tokens/auth

    Initialize Linked Account Tokenization - Request

    Example Initialize Linked Account Tokenization Request

    curl https://api.xendit.co/linked_account_tokens/auth -X POST \
       --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
       --header 'Content-Type: application/json' \
       --data-raw '{
        "customer_id": "ba830b92-4177-476e-b097-2ad5ae4d3e55",
        "channel_code": "PH_GRABPAY",
        "properties": {
            "success_redirect_url": "https://www.my-shop.co/auth/success",
            "failure_redirect_url": "https://www.my-shop.co/auth/failed",
            "cancel_redirect_url": "https://www.my-shop.co/auth/cancel"
        }
    }'\
    Request Body Parameter Type Description
    customer_id
    required
    string ID of the customer object to which the account token will be linked to. Call Tokenized - Create Customer to generate Customer ID
    channel_code
    required
    string Identifier for the specific channel of the account to be linked. Code must be in uppercase.

    Supported eWallets and their respective channel codes:
    • OVO (ID) - ID_OVO
    • SHOPEEPAY (ID) - ID_SHOPEEPAY
    • GRABPAY (PH) - PH_GRABPAY
    • PAYMAYA (PH) - PH_PAYMAYA
    properties
    required
    object JSON that contains information needed to proceed with authorization. Values inside properties change based on eWallet provider:

    OVO, SHOPEEPAY, GRABPAY required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_redirect_url
    required
    string URL where the end-customer is redirected if the authorization failed
    callback_url
    required
    string URL where the successful linking webhook will be sent
    PAYMAYA required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_redirect_url
    required
    string URL where the end-customer is redirected if the authorization failed
    cancel_redirect_url
    required
    string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes.
    callback_url
    required
    string URL where the successful linking webhook will be sent
    metadata
    optional
    object Object of additional information the user may use. Users define the JSON properties and values.
    You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

    Initialize Linked Account Tokenization - Response

    Example Initialize Linked Account Tokenization Success Response

    {
        "id": "lat-aa620619-124f-41db-995b-66a52abe036a",
        "customer_id": "ba830b92-4177-476e-b097-2ad5ae4d3e55",
        "channel_code": "PH_GRABPAY",
        "authorizer_url": "https://link-web.xendit.co/oauth/lat-4ec01c8d-0326-4a35-bc11-b64c85f7408e/confirm",
        "status": "PENDING",
        "metadata": null
    }
    Parameter Type Description
    id string Unique ID generated by Xendit for the particular linked account token authorization
    customer_id string Customer object ID
    channel_code string Code identifier for the channel
    authorizer_url string URL generated from eWallet provider for end user to authorize the account linking. End user should be redirected to this URL for tokenization to proceed.
    status string Status of the authorization. A successful API request will respond with a PENDING status. Upon successful account linking, the status will be updated to COMPLETED. If account linking fails, the status will be updated to FAILED.
    metadata object User defined object with JSON properties and values passed in during account linking.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

    Initialize Linked Account Tokenization - Errors

    See other common errors here.

    Error Code Description
    CHANNEL_CODE_NOT_SUPPORTED_ERROR
    400
    Provided channel_code is not supported or has not yet activated for this account.
    CUSTOMER_NOT_FOUND_ERROR
    404
    Provided customer_id in the request does not exist or access is unauthorized
    CHANNEL_UNAVAILABLE
    503
    The target channel is currently unavailable. This is possibly due to partner channel downtime or error.
    INVALID_ACCOUNT_DETAILS
    400
    Provided values in properties in the request does not match any records with the eWallet provider
    ACCOUNT_ACCESS_BLOCKED
    400
    The eWallet provider has rejected the linking. This maybe the eWallet account is inaccessible or not activated for this service.

    Tokenized - Account Linking Status Callback

    The linked account id (prefix la-) in the notification acccounts parameter should be stored as it will be used to create a payment method object in the next step.

    Callback Payload

    Example: Linked Account Tokenization Callback Payload

    {
      "event": "linked_account_token.successful",
      "timestamp": "2021-05-21T12:28:49.019Z",
      "id": "lat-d6876bf1-9722-47e3-8757-f74c7d7772b5",
      "channel_code": "PH_GRABPAY",
      "type": "EWALLET",
      "accounts": [
        {
          "id": "la-eddf88b1-312a-4f78-aca1-96e5ff4161b4",
          "account_details": null,
          "account_type": "EWALLET",
          "balance": 1000000,
          "currency": "PHP",
          "description": null,
          "name": null,
          "point_balance": null
        }
      ]
    }
    Parameter Type Description
    event string Identifier of the event - "linked_account_token.successful"
    timestamp string ISO 8601 timestamp of the event. Timezone is UTC+0
    id string Unique identifier for the Linked Account Tokenization. This has a prefix of lat-.
    channel_code string Code identifier for the channel - ID_OVO, ID_SHOPEEPAY, PH_GRABPAY, PH_PAYMAYA
    type enum EWALLET - type of payment channel
    accounts array
    Key Value
    id string Unique identifier for eWallet account specific to this object. This has a prefix of la-.
    account_details stringIdentifier from eWallet provider e.g. phone number. The value is null if unavailable
    account_type stringType of account. Expected values: EWALLET
    balance numberThe main balance amount on eWallet account provided from eWallet provider. The value is null if unavailable
    currency stringCurrency of the account in ISO 4217 - IDR or PHP
    description stringDescription of the account from eWallet provider. The value is null if unavailable
    name stringName of the eWallet account holder. The value is null if unavailable
    point_balance numberThe point balance amount on eWallet account. Applicable only on some eWallet provider that has point system. The value is null if unavailable

    Tokenized - Create Payment Method

    Step 3 - A payment method object is used to represent the linked account (from the account linking notification - prefix la-) to make payment transactions. To create a payment method object, the customer id and linked account id has to be included in the request to this endpoint.

    With the payment_method_id (prefix pm-) returned in the response of this endpoint, you can specify payment_method_id in the eWallets charge endpoint to initiate a tokenized payment.

    Endpoint: Create Payment Method

    POST https://api.xendit.co/payment_methods

    Create Payment Method - Request

    Example Create Payment Method Request

    curl https://api.xendit.co/payment_methods -X POST \
       --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
       --header 'Content-Type: application/json' \
       --data-raw '{
        "customer_id": "ba830b92-4177-476e-b097-2ad5ae4d3e55",
        "type": "EWALLET",
        "properties": {
            "id": "la-aa620619-124f-41db-995b-66a52abe036a"
        }
    }'\
    Request Body Parameter Type Description
    customer_id
    required
    string ID of the customer object to which the account token will be linked to
    type
    required
    string Type of payment method

    Supported values: EWALLET
    properties
    required
    object JSON that contains information that identifies the payment method:

    Key Value
    id
    required
    ID of Linked Account (prefix la-)
    metadata
    optional
    object Object of additional information the user may use. Users define the JSON properties and values.
    You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

    Create Payment Method - Response

    Example Create Payment Method Success Response

    {
        "id": "pm-fea3b000-f9dc-41c5-9bfc-fd37c2b0d84d",
        "type": "EWALLET",
        "properties": {
            "id": "la-f8b41ad0-180a-44d5-bad5-3291cd7262ac"
        },
        "customer_id": "f0ac5e6f-436b-4228-ac56-7324a2aec6f4",
        "status": "ACTIVE",
        "created": "2021-04-01T10:12:03.564Z",
        "updated": "2021-04-01T10:12:03.564Z",
        "metadata": {},
    }
    
    Parameter Type Description
    id string Unique identifier for the payment method. This has a prefix of pm-.
    type string Type of account that has been linked.
    Expected values: EWALLET
    properties object Object containing information regarding the account.

    Key Value
    id stringID of linked account.
    customer_id string ID of the customer object in which this payment method is linked to
    status string Status of the payment method.
    Will be equal to ACTIVE upon creation.
    created string Timestamp in ISO 8601 when the request was made
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    updated string Timestamp in ISO 8601 when transaction information was updated
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    metadata object User defined object with JSON properties and values passed in during payment method creation.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

    Create Payment Method - Errors

    See other common errors here.

    Error Code Description
    LIINKED_ACCOUNT_NOT_FOUND_ERROR
    400
    Provided properties and type combination in the request does not exist or access is unauthorized
    CUSTOMER_NOT_FOUND_ERROR
    400
    Provided customer_id in the request does not exist or access is unauthorized
    DUPLICATE_ERROR
    409
    There is already an existing ACTIVE payment method that relates to the same account

    Tokenized - Get Account Balance

    This endpoint returns the list of eWallets accounts and corresponding balances accessible by the linked account token (prefix lat-).

    Endpoint: Get Account Balance

    GET https://api.xendit.co/linked_account_tokens/{linked_account_token_id}/accounts

    Get Account Balance - Request

    Example Get Account Balance by Linked Account Token Request

    curl https://api.xendit.co/linked_account_tokens/lat-aa620619-124f-41db-995b-66a52abe036a/accounts -X GET \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
    Path Parameter Type Description
    linked_account_token_id
    required
    string Linked account token id received from Initialize Account Authorization. This has the lat- prefix.

    Get Account Balance - Response

    This endpoint returns an array of objects with the following properties:

    Example Get Account Balance by Linked Account Token Success Response

    [
        {
            "id": "la-f8b41ad0-180a-44d5-bad5-3291cd7262ac",
            "channel_code": "PH_GRABPAY",
            "type": "EWALLET",
            "properties": {
                "account_details": null,
                "account_type": "EWALLET",
                "balance": 1000000,
                "currency": "PHP",
                "description": null,
                "name": null,
                "point_balance": null
            }
        }
    ]
    Parameter Type Description
    id string Unique identifier for the ewallet account. This has a prefix of la-.
    channel_code string Code identifier for the channel - ID_OVO, ID_SHOPEEPAY, PH_GRABPAY, PH_PAYMAYA
    type string Type of account that has been linked.
    Expected values: EWALLET
    properties object Object containing information regarding the account.

    Key Value
    account_details stringIdentifier from eWallet provider e.g. phone number. The value is null if unavailable
    account_type stringType of account. Expected values: EWALLET
    balance numberThe main balance amount on eWallet account provided from eWallet provider. The value is null if unavailable
    currency string Currency of the account in ISO 4217 - IDR or PHP
    description stringDescription of the account from eWallet provider. The value is null if unavailable
    name stringName of the eWallet account holder. The value is null if unavailable
    point_balance numberThe point balance amount on eWallet account. Applicable only on some eWallet provider that has point system. The value is null if unavailable

    Get Account Balance by Linked Account Token - Errors

    See other common errors here.

    Error Code Description
    DATA_NOT_FOUND_ERROR
    404
    Provided linked_account_token_id is not supported or has not yet activated for this account.

    Tokenized - Unlinking

    Unlinks a successful linked account token.

    Endpoint: Unbind a Linked Account Token

    DELETE https://api.xendit.co/linked_account_tokens/{linked_account_token_id}

    Example Unbind a Linked Account Token Request

    curl https://api.xendit.co/linked_account_tokens/lat-aa620619-124f-41db-995b-66a52abe036a/validate_otp -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: 
    <?php
      $linkedAccountTokenId = "lat-aa620619-124f-41db-995b-66a52abe036a";
      $url = "https://api.xendit.co/linked_account_tokens/" . $linkedAccountTokenId;
      $apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
    
      $curl = curl_init();
    
      $payload = json_encode($data);
      curl_setopt($curl, CURLOPT_USERPWD, $apiKey.":");
      curl_setopt($curl, CURLOPT_URL, $url);
      curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    
      $result = curl_exec($curl);
      echo $result;
    let apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
    let linkedAccountTokenId = "lat-aa620619-124f-41db-995b-66a52abe036a";
    let url = "https://api.xendit.co/linked_account_tokens/" + linkedAccountTokenId;
    
    var headers = new Headers();
    headers.append("Authorization", "Basic " + btoa(apiKey + ":"));
    
    var requestOptions = {
      method: 'DELETE',
      headers: headers,
      redirect: 'follow'
    };
    
    fetch(url, requestOptions)
      .then(response => response.text())
      .then(result => console.log(result))
      .catch(error => console.log('error', error));
    try {
      Xendit.apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
    
      UnbindedLinkedAccount linkedAccount = UnbindedLinkedAccount.unbindLinkedAccountToken ("lat-a08fba1b-100c-445b-b788-aaeaf8215e8f");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    Path Parameter Type Description
    linked_account_token_id
    required
    string Linked account token id received from Initialize Account Authorization. This has the lat- prefix.

    Example Unbind a Linked Account Token Success Response

    {
        "id": "lat-aa620619-124f-41db-995b-66a52abe036a",
        "is_deleted": true
    }
    Parameter Type Description
    id string Unique ID generated by Xendit for the particular linked account token authorization
    is_deleted boolean Describes whether or not the linked account token was successfully deleted

    See other common errors here.

    Error Code Description
    DATA_NOT_FOUND_ERROR
    404
    Provided linked_account_token_id is not found or inaccessible for this account.

    PayLater

    With PayLater, you can allow your customers to buy now and pay later in installments. Customers with an active credit line with one of our partner lenders can shop on your store via flexible installment loans.

    With one integration, get access to all our available PayLater channels and upcoming PayLater integrations as well.

    For full details on each API as well as a comprehensive guide on integration, please refer to our documentation.

    Initiate PayLater Plans

    Provide your end-customer information on the available PayLater/installment plans.

    Endpoint: Initiate PayLater Plans

    POST https://api.xendit.co/paylater/plans

    Version

    You are currently viewing the newest version of our PayLater / Cardless Credit API. In this API version, integrate once to get access to all available and future PayLater providers in Xendit!. Click here to view older versions.

    Version Changelog
    2021-06-30
    Latest
    New simple and consistent PayLater API to support top PayLater providers in Indonesia and the Philippines. No API Versioning is required. You can access the new API easily by calling POST /paylater/plans
    2019-02-04 Cardless credit API with support for Kredivo /cardless-credit

    Request Parameters

    Example: Initiate PayLater Plans - Request

    curl https://api.xendit.co/paylater/plans -X POST \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
       -H 'Content-Type: application/json' \
       --data-raw '{
        "customer_id": "49d056bd-21e5-4997-85f2-2127544c2196",
        "channel_code": "PH_BILLEASE",
        "currency": "PHP",
        "amount": 3073.68,
        "order_items": [{
            "type": "PHYSICAL_PRODUCT",
            "reference_id": "SKU_123-456-789",
            "name": "Dyson Vacuum",
            "net_unit_amount": 1234.56,
            "quantity": 3,
            "url": "https://www.zngmyhome.com/dyson_vacuum",
            "category": "Electronics",
            "subcategory": "Appliances"
        }]
    }'
    <?php
      $url = "https://api.xendit.co/paylater/plans";
      $apiKey = "xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:";
      $data = [
        "customer_id" => "49d056bd-21e5-4997-85f2-2127544c2196",
        "channel_code" => "PH_BILLEASE",
        "currency" => "PHP",
        "amount" => 3073.68,
        "order_items" => [
            "type" => "PHYSICAL_PRODUCT",
            "reference_id" => "SKU_123-456-789",
            "name": "Dyson Vacuum",
            "net_unit_amount" => 1234.56,
            "quantity" => 3,
            "url" => "https://www.zngmyhome.com/dyson_vacuum",
            "category" => "Electronics",
            "subcategory" => "Appliances"
        ]
        ];
    
      $curl = curl_init();
    
      $payload = json_encode($data);
      curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
      curl_setopt($curl, CURLOPT_USERPWD, $apiKey.":");
      curl_setopt($curl, CURLOPT_URL, $url);
      curl_setopt($curl, CURLOPT_POST, true);
      curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    
      $result = curl_exec($curl);
      echo $result;
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman",
    });
    
    const { PayLater } = x;
    const payLaterSpecificOptions = {};
    const plp = new PayLater(payLaterSpecificOptions);
    
    const resp = await plp.initiatePayLaterPlans({
      customer_id: '9d056bd-21e5-4997-85f2-2127544c2196',
      channel_code: 'PH_BILLEASE',
      currency: 'PHP',
      amount: 3073.68,
      order_items: {
        type: 'PHYSICAL_PRODUCT',
        reference_id: 'SKU_123-456-789',
        name: 'Dyson Vacuum',
        net_unit_amount: 1234.56,
        quantity: 3,
        url: 'https://www.zngmyhome.com/dyson_vacuum',
        category: 'Electronics',
        subcategory: 'Appliances'
      }
    });
    console.log(resp);
    from xendit import PayLater
    
    paylater_plans = PayLater.initiate_paylater_plans(
        customer_id="9d056bd-21e5-4997-85f2-2127544c2196",
        channel_code="PH_BILLEASE",
        currency="PHP",
        amount=3073.68,
        order_items={
            type="PHYSICAL_PRODUCT",
            reference_id="SKU_123-456-789",
            name="Dyson Vacuum",
            net_unit_amount=1234.56,
            quantity=3,
            url="https://www.zngmyhome.com/dyson_vacuum",
            category="Electronics",
            subcategory="Appliances"
        }
    )
    Header Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Body Parameter Type Description
    customer_id
    required
    string Unique identifier for customer from the Create Customer API POST /customers

    Required parameters to be set for the customer object
    Key Value
    given_names
    required
    string Primary or first name/s of customer
    surname
    required
    string Last or family name of customer
    email
    required
    string E-mail address of customer
    mobile_number
    required
    string Mobile number of customer in E.164 format
    street_line1
    required
    string Customer’s address line
    city
    required
    string Customer’s city
    postal_code
    required
    string ZIP/Postal Code of customer
    country_code
    required
    string Customer’s country code
    channel_code
    required
    string Channel code for PayLater provider

    Supported channels: ID_KREDIVO, ID_AKULAKU, PH_BILLEASE
    currency
    required
    string ISO 4217 currency code of PayLater transaction

    Supported currencies: IDR, PHP
    amount
    required
    number Aggregated transaction amount equivalent to the sum of net_unit_amount multiplied by quantity in the order_items array

    Transaction limits per channel
    Channel Code Min Max
    ID_KREDIVO (IDR) 1,000 30,000,000
    ID_AKULAKU (IDR) 1,000 25,000,000
    PH_BILLEASE (PHP) 50 150,000
    order_items
    required
    array Array of objects describing the item/s purchased using PayLater

    Object parameters
    Key Value
    type
    required
    string Type of item

    DIGITAL_PRODUCT, PHYSICAL_PRODUCT, DIGITAL_SERVICE, PHYSICAL_SERVICE
    reference_id
    required
    string Merchant’s identifier for specific item (ie. SKU, promotion code, etc)

    Format Special and alphanumeric
    Max length 255 characters
    name
    required
    string Item name

    Format Special and alphanumeric
    Max length 255 characters
    net_unit_amount
    required
    number Net amount to be charged per unit
    quantity
    required
    number Number of units of this item in the basket

    Min 1
    url
    required
    string URL of the item

    Must be HTTPS or HTTP
    category
    required
    string Merchant category for item

    Format Special and alphanumeric
    Max length 255 characters
    subcategory
    optional
    string Merchant subcategory for item

    Format Special and alphanumeric
    Max length 255 characters
    description
    optional
    string Item description

    Format Special and alphanumeric
    Max length 255 characters
    metadata
    optional
    object Additional object that may be used for additional item attributes

    Response Parameters

    Example: Initiate PayLater Plans - Success Response

    {
        "id" : "plp_3d88d952-9505-4ed7-84d3-e8639e99e9c4",
        "customer_id" : "49d056bd-21e5-4997-85f2-2127544c2196",
        "channel_code" : "PH_BILLEASE",
        "currency" : "PHP",
        "amount" : 2184.56,
        "order_items": [{
            "type": "PHYSICAL_PRODUCT",
            "reference_id": "SKU_123-456-789",
            "name": "Dyson Vacuum",
            "net_unit_amount": 1234.56,
            "quantity": 1,
            "url": "https://www.zngmyhome.com/dyson_vacuum",
            "category": "Electronics",
            "subcategory": "Appliances",
            "description": "A very powerful vacuum",
            "metadata": null
        },
        {
            "type" : "PHYSICAL_SERVICE",
            "reference_id" : "SKU_123-456-790",
            "name" : "Home Cleaning Service",
            "net_unit_amount" : 1000,
            "quantity" : 1,
            "url" : "https://www.zngmyhome.com/home_cleaning",
            "category" : "Services",
            "subcategory" : null,
            "description" : "1 hour deep cleaning up to 2 rooms",
            "metadata" : null
        }],
        "options": [{
            "downpayment_amount" : 400,
            "installment_amount" : 600,
            "interest_rate" : 0,
            "total_amount" : 1000,
            "interval" : "MONTH",
            "interval_count" : 1,
            "total_recurrence" : 1,
            "description" : "Buy Now, Pay Later"
        },
        {
            "downpayment_amount" : 400,
            "installment_amount" : 100,
            "interest_rate" : 0.025,
            "total_amount" : 1015,
            "interval" : "MONTH",
            "interval_count" : 1,
            "total_recurrence" : 6,
            "description" : "6 month installment plan"
        }],
        "created": "2020-11-11T16:23:52Z"
    }
    Body Parameter Type Description
    id string Unique identifier for PayLater Plan Object

    It will always have the prefix of plp_, followed by a UUIDv4
    customer_id string Unique identifier for customer
    channel_code string Channel code for PayLater provider

    Supported channels: ID_KREDIVO, ID_AKULAKU, PH_BILLEASE
    currency string ISO 4217 currency code of PayLater transaction

    Supported currency: IDR, PHP
    amount number Aggregated transaction amount equivalent to the sum of net_unit_amount multiplied by quantity in the order_items array
    order_items array Array of objects describing the item/s purchased using PayLater
    options array Available payment plans users can view to purchase your goods/services. Provided by PayLater providers directly

    PayLater options details
    Key Value
    downpayment_amount number Amount required to be paid upfront
    installment_amount number Amount to be paid via at every payment interval specified
    interest_rate number Interest rates charged

    Example: 0.2 for twenty percent
    total_amount number Grand total of installment your customers will pay. This is a sum of downpayment amount, installment amount, and other fees by PayLater provider
    interval string The frequency with which a recurring payment invoice should be billed

    DAY, WEEK, MONTH
    interval_count number The number of intervals (specified in the interval property) between installments

    Example: interval=MONTH and interval_count=3 bills every 3 months
    total_recurrence number The number of times installments will be charged to the end user with the specified intervals
    description string Name or descriptor of installment option as given by PayLater provider
    created string Timestamp in ISO 8601 for creation of plan object
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0

    Error Codes

    Example: Initiate PayLater Charge Request API - Error Response

    {
        "error_code": "INVALID_CUSTOMER_ID",
        "message": "Missing or invalid parameter(s) in customer_id: given_names, postcode"
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    There is invalid input in one of the required request fields
    API_VALIDATION_ERROR
    400
    Amount Does Not Tally with Order Items
    request.body.amount must be equal to the sum of net_unit_amount * quantity in request.body.order_items
    API_VALIDATION_ERROR
    400
    Invalid URL
    url must be a valid URL
    INVALID_CUSTOMER_ID
    400
    Missing or invalid parameter(s) in customer_id
    UNSUPPORTED_CURRENCY
    400
    The payment currency request is not supported by PayLater partner. Please refer to our API reference or docs for available currencies
    INVALID_API_KEY
    401
    API key is not authorized for this API service
    INVALID_MERCHANT_CREDENTIALS
    401
    Merchant credentials met with an error with the PayLater partner. Please contact Xendit customer support to resolve this issue.
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request
    CHANNEL_NOT_ACTIVATED
    403
    The API key is forbidden to perform this request
    DATA_NOT_FOUND
    404
    Customer ID is invalid. Please check the ID again or create an ID using Customer API.
    SERVER_ERROR
    500
    An unexpected error occured. Our team has been notified and will troubleshoot the issue
    CHANNEL_UNAVAILABLE
    503
    The payment channel requested is currently experiencing unexpected issues. The PayLater partner will be notified to resolve this issue

    Create PayLater Charges

    Create PayLater transaction / generate checkout URL

    Version

    You are currently viewing the newest version of our PayLater / Cardless Credit API. Click here to view older versions.

    Endpoint: Create PayLater Charges

    POST https://api.xendit.co/paylater/charges

    Request Parameters

    Example: Create Payment Request

    curl https://api.xendit.co/paylater/charges -X POST \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
       -H 'Content-Type: application/json' \
       --data-raw '{
        "plan_id": "plp_3d88d952-9505-4ed7-84d3-e8639e99e9c4",
        "reference_id": "order_id_123",
        "checkout_method": "ONE_TIME_PAYMENT",
        "success_redirect_url": "https://merchant.com/order/confirm",
        "failure_redirect_url": "https://merchant.com/order/fail"
    }'
    <?php
      $url = "https://api.xendit.co/paylater/charges";
      $apiKey = "xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:";
      $data = [
        "plan_id" => "plp_3d88d952-9505-4ed7-84d3-e8639e99e9c4",
        "reference_id" => "order_id_123",
        "checkout_method" => "ONE_TIME_PAYMENT",
        "success_redirect_url" => "https://merchant.com/order/confirm",
        "failure_redirect_url" => "https://merchant.com/order/fail"
        ];
    
      $curl = curl_init();
    
      $payload = json_encode($data);
      curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
      curl_setopt($curl, CURLOPT_USERPWD, $apiKey.":");
      curl_setopt($curl, CURLOPT_URL, $url);
      curl_setopt($curl, CURLOPT_POST, true);
      curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    
      $result = curl_exec($curl);
      echo $result;
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman",
    });
    
    const { PayLater } = x;
    const payLaterSpecificOptions = {};
    const plc = new PayLater(payLaterSpecificOptions);
    
    const resp = await plc.createPayLaterCharge({
      planID: 'plp_3d88d952-9505-4ed7-84d3-e8639e99e9c4',
      referenceID: 'order_id_123',
      checkoutMethod: 'ONE_TIME_PAYMENT',
      successRedirectURL: 'https://merchant.com/order/confirm',
      failureRedirectURL: 'https://merchant.com/order/fail'
    });
    console.log(resp);
    from xendit import PayLater
    
    paylater_charge = PayLater.create_paylater_charge(
        plan_id="plp_3d88d952-9505-4ed7-84d3-e8639e99e9c4",
        reference_id="order_id_123",
        checkout_method="ONE_TIME_PAYMENT",
        success_redirect_url="https://merchant.com/order/confirm",
        failure_redirect_url="https://merchant.com/order/fail"
    )
    Header Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Body Parameter Type Description
    plan_id
    required
    string Installment Plan ID retrieved from Initiate PayLater Plans API
    reference_id
    required
    string Reference ID provided by merchant for the transaction

    Format Special and alphanumeric
    Max length 255 characters
    checkout_method
    required
    string Supported checkout method: ONE_TIME_PAYMENT
    success_redirect_url
    required
    string URL where the customer is redirected after completing transaction

    Must be HTTPS or HTTP
    failure_redirect_url
    optional
    string URL where the end-customer is redirected if the payment has failed

    Must be HTTPS or HTTP
    payment_method_id
    optional
    string Payment method ID of end-customer source of funds

    Required when checkout_method = TOKENIZED_PAYMENT (currently not supported)
    metadata
    optional
    object Object of additional information the user may use. User defines the JSON properties and values.

    You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

    This will only be used by the user and not Xendit.

    Response Parameters

    Example Create PayLater Charge Success Response

    {
        "id": "plc_8cb12305-9bcf-4441-a087-ee0d446e297b",
        "customer_id": "49d056bd-21e5-4997-85f2-2127544c2196",
        "plan_id": "plp_3d88d952-9505-4ed7-84d3-e8639e99e9c4",
        "business_id": "5f27a14a9bf05c73dd040bc8",
        "reference_id": "order_id_123",
        "checkout_method": "ONE_TIME_PAYMENT",
        "channel_code": "PH_BILLEASE",
        "currency": "PHP",
        "amount": 1234.56,
        "refunded_amount": null,
        "order_items": [{
            "type": "PRODUCT",
            "reference_id": "SKU_123-456-789",
            "name": "Dyson Vacuum",
            "net_unit_amount": 1234.56,
            "quantity": 1,
            "url": "https://www.zngmyhome.com/dyson_vacuum",
            "category": "Electronics",
            "subcategory": "Appliances",
            "description": "A very powerful vacuum",
            "metadata": null
        }],
        "success_redirect_url": "https://merchant.com/order/confirm",
        "failure_redirect_url": "https://merchant.com/order/fail",
        "status": "PENDING",
        "created": "2020-11-11T16:23:52Z",
        "updated": "2020-11-11T16:23:52Z",
        "actions": {
            "desktop_web_checkout_url": "https://webcheckout.this/",
            "mobile_web_checkout_url": "https://webcheckout.this/",
            "mobile_deeplink_checkout_url": "app://deeplinkcheckout.this/"
        },
        "callback_url": "https://webhook.me/gethooked",
        "payment_method_id": null,
        "voided_at": null,
        "refunds": null,
        "metadata": null
    }
    Body Parameter Type Description
    id string Unique identifier for the charge request transaction
    It will always have the prefix of plc_, followed by a UUIDv4
    customer_id string Unique identifier for customer
    plan_id string Unique identifier for PayLater plan created
    business_id string Business ID of the merchant
    reference_id string Reference ID provided by merchant for the transaction
    channel_code string Channel code for PayLater provider
    Supported channels: ID_KREDIVO, ID_AKULAKU, PH_BILLEASE
    checkout_method string Supported checkout method: ONE_TIME_PAYMENT
    channel_code string ISO 4217 currency code of PayLater transaction
    Supported currency: IDR, PHP
    amount number Aggregated transaction amount equivalent to the sum of net_unit_amount multiplied by quantity in the order_items array
    refunded_amount number Total amount that has been successfully refunded to end-user
    order_items array Array of objects describing the item/s purchased using PayLater
    status string Charge status
    PENDING, SUCCEEDED, FAILED
    success_redirect_url string URL where the customer is redirected after completing transaction
    Must be HTTPS or HTTP
    failure_redirect_url string URL where the end-customer is redirected if the payment has failed
    Must be HTTPS or HTTP
    created string Timestamp in ISO 8601 for transaction creation
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    updated string Timestamp in ISO 8601 latest object update
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    actions object PayLater Partner’s checkout URL where end-user will be redirected to complete payment

    Types of redirection URLs
    Key Value
    desktop_web_checkout_url string Generated URL for web checkout on devices with a stand-alone screen
    mobile_web_checkout_url string Generated URL for web checkout on mobile devices
    mobile_deeplink_checkout_url string Generated URL for deeplink checkout on mobile devices (jumps directly into PayLater partner's app for payment confirmation)
    callback_url string Default to callback URL in dashboard where the charge status will be notified
    payment_method_id string Payment method ID of end-customer source of funds
    Required when checkout_method = TOKENIZED_PAYMENT (currently not supported)
    voided_at string Timestamp in ISO 8601 for void of transaction
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    metadata object Object of additional information the user may use. Users define the JSON properties and values

    You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long

    This will only be used by the user and not Xendit.
    refunds array Array of refund object IDs (only SUCCEEDED refunds will show)

    Error Codes

    Example: Create PayLater Charge Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "PayLater partner does not support requested checkout_method."
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    There is invalid input in one of the required request fields
    API_VALIDATION_ERROR
    400
    Unsupported Checkout Type
    PayLater partner does not support requested checkout_method
    INVALID_API_KEY
    401
    API key is not authorized for this API service
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request
    PAYLATER_PLAN_DATA_NOT_FOUND
    404
    PayLater Plan ID is invalid. Please check the ID again or create an ID using PayLater Plans API
    SERVER_ERROR
    500
    An unexpected error occured. Our team has been notified and will troubleshoot the issue
    CHANNEL_UNAVAILABLE
    503
    The payment channel requested is currently experiencing unexpected issues. The PayLater partner will be notified to resolve this issue

    Payment Status Callback

    You need to provide an endpoint from your system to receive all payment callback notification from our system. You will receive the callback when end-customer attempted payments for PayLater. Please specify this endpoint in Xendit dashboard callback url page under PayLater paid.

    The payment callback notification will be sent as POST request to the callback_url that you have set in the dashboard. Note: Please give this notification a response back with status 200 so we know that our notification is received and will not attempt to retry the notification.

    POST callback-url

    Version

    You are currently viewing the newest version of our PayLater / Cardless Credit API. Click here to view older versions.

    Callback Payload

    This callback is triggered when a PayLater payment has SUCCEEDED or FAILED.

    Example: PayLater Success Payment Callback Payload

    {
        "event": "paylater.payment",
        "business_id": "5f27a14a9bf05c73dd040bc8",
        "created": "2020-11-11T16:28:52Z",
        "data": {
            "id": "plc_8cb12305-9bcf-4441-a087-ee0d446e297b",
            "customer_id": "49d056bd-21e5-4997-85f2-2127544c2196",
            "plan_id": "plp_3d88d952-9505-4ed7-84d3-e8639e99e9c4",
            "business_id": "5f27a14a9bf05c73dd040bc8",
            "reference_id": "order_id_123",
            "checkout_method": "ONE_TIME_PAYMENT",
            "channel_code": "PH_BILLEASE",
            "currency": "PHP",
            "amount": 1234.56,
            "refunded_amount": null,
            "order_items": [{
                "type": "PRODUCT",
                "reference_id": "SKU_123-456-789",
                "name": "Dyson Vacuum",
                "net_unit_amount": 1234.56,
                "quantity": 1,
                "url": "https://www.zngmyhome.com/dyson_vacuum",
                "category": "Electronics",
                "subcategory": "Appliances",
                "description": "A very powerful vacuum",
                "metadata": null
            }],
            "success_redirect_url": "https://merchant.com/order/confirm",
            "failure_redirect_url": "https://merchant.com/order/fail",
            "status": "SUCCEEDED",
            "created": "2020-11-11T16:23:52Z",
            "updated": "2020-11-11T16:23:52Z",
            "actions": {
                "desktop_web_checkout_url": "https://webcheckout.this/",
                "mobile_web_checkout_url": "https://webcheckout.this/",
                "mobile_deeplink_checkout_url": "app://deeplinkcheckout.this/"
            },
            "callback_url": "https://webhook.me/gethooked",
            "payment_method_id": null,
            "voided_at": null,
            "refunds": null,
            "metadata": null
        }
    }
    Header Parameter Description
    x-callback-token string Your Xendit unique callback token to verify the origin of the callback
    Body Parameter Type Description
    event string Identifies the event triggering a notification to merchant.

    paylater.payment occurs when PayLater partner confirms the payment status of a transaction
    business_id string Business ID of the merchant
    created string ISO 8601 timestamp of the event creation. Timezone is UTC+0
    data object PayLater charge object will be nested in this parameter

    Data fields
    Parameter Description
    id string Unique identifier for the charge request transaction

    It will always have the prefix of plc_, followed by a UUIDv4
    customer_id string Unique identifier for customer
    plan_id string Unique identifier for PayLater plan created
    business_id string Business ID of the merchant
    reference_id string Reference ID provided by merchant for the transaction
    channel_code string Channel code for PayLater provider
    checkout_method string Supported checkout method: ONE_TIME_PAYMENT
    currency string ISO 4217 currency code of PayLater transaction
    amount number Aggregated transaction amount equivalent to the sum of net_unit_amount multiplied by quantity in the order_items array
    refunded_amount number Total amount that has been successfully refunded to end-user
    order_items array Array of objects describing the item/s purchased using PayLater
    success_redirect_url string URL where the customer is redirected after completing transaction
    failure_redirect_url string URL where the end-customer is redirected if the payment has failed
    status string PayLater charge status
    PENDING, SUCCEEDED, FAILED
    created string Timestamp in ISO 8601 for transaction creation
    updated string Timestamp in ISO 8601 latest object update
    actions object PayLater Partner’s checkout URL where end-user will be redirected to complete payment
    callback_url string Default to callback URL in dashboard where the charge status will be notified
    payment_method_id string Payment method ID of end-customer source of funds

    Required when checkout_method = TOKENIZED_PAYMENT (currently not supported)
    voided_at string Timestamp in ISO 8601 for void of transaction
    metadata object object of additional information the user may use.
    refunds array Array of refund objects (only SUCCEEDED status will show).

    Get PayLater Charge by ID

    Retrieve the details of a PayLater payment by Charge ID

    Endpoint: Get PayLater Charge by ID

    GET https://api.xendit.co/paylater/charges/{id}

    Request Parameters

    Example: Check PayLater Charge Status by ID - Request

    curl https://api.xendit.co/paylater/charges/plc_8cb12305-9bcf-4441-a087-ee0d446e297b/ -X GET \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
    <?php
    
    use Xendit\Xendit;
    require 'vendor/autoload.php';
    
    Xendit::setApiKey('xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman');
    
    $charge_id = 'plc_8cb12305-9bcf-4441-a087-ee0d446e297b';
    $getPayLaterChargeStatus = \Xendit\PayLater::getPayLaterChargeStatus($charge_id);
    var_dump($getPayLaterChargeStatus);
    
    ?>
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman",
    });
    
    const { PayLater } = x;
    const paylaterSpecificOptions = {};
    const pl = new PayLater(paylaterSpecificOptions);
    
    const resp = await pl.getPayLaterChargeStatus({
      chargeID: 'plc_8cb12305-9bcf-4441-a087-ee0d446e297b',
    });
    console.log(resp);
    from xendit import PayLater
    
    paylater_charge = PayLater.get_paylater_charge_status(
        charge_id="plc_8cb12305-9bcf-4441-a087-ee0d446e297b",
    )
    Header Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Path Parameter Type Description
    id
    required
    string Unique identifier for charge request transaction (returned as id in the PayLater Charge request)

    Response Parameters

    Example: Check PayLater Charge Status by ID - Response

    {
        "id": "plc_8cb12305-9bcf-4441-a087-ee0d446e297b",
        "customer_id": "49d056bd-21e5-4997-85f2-2127544c2196",
        "plan_id": "plp_3d88d952-9505-4ed7-84d3-e8639e99e9c4",
        "business_id": "5f27a14a9bf05c73dd040bc8",
        "reference_id": "order_id_123",
        "checkout_method": "ONE_TIME_PAYMENT",
        "channel_code": "PH_BILLEASE",
        "currency": "PHP",
        "amount": 1234.56,
        "refunded_amount": null,
        "order_items": [{
            "type": "PRODUCT",
            "reference_id": "SKU_123-456-789",
            "name": "Dyson Vacuum",
            "net_unit_amount": 1234.56,
            "quantity": 1,
            "url": "https://www.zngmyhome.com/dyson_vacuum",
            "category": "Electronics",
            "subcategory": "Appliances",
            "description": "A very powerful vacuum",
            "metadata": null
        }],
        "success_redirect_url": "https://merchant.com/order/confirm",
        "failure_redirect_url": "https://merchant.com/order/fail",
        "status": "SUCCEEDED",
        "created": "2020-11-11T16:23:52Z",
        "updated": "2020-11-11T16:23:52Z",
        "actions": {
            "desktop_web_checkout_url": "https://webcheckout.this/",
            "mobile_web_checkout_url": "https://webcheckout.this/",
            "mobile_deeplink_checkout_url": "app://deeplinkcheckout.this/"
        },
        "callback_url": "https://webhook.me/gethooked",
        "payment_method_id": null,
        "voided_at": null,
        "refunds": null,
        "metadata": null
    }
    Body Parameter Type Description
    id string Unique identifier for the charge request transaction

    It will always have the prefix of plc_, followed by a UUIDv4
    customer_id string Unique identifier for customer
    plan_id string Unique identifier for PayLater plan created
    business_id string Business ID of the merchant
    reference_id string Reference ID provided by merchant for the transaction
    checkout_method string Supported checkout method: ONE_TIME_PAYMENT
    channel_code string Channel code for PayLater provider

    Supported channels: ID_KREDIVO, ID_AKULAKU, PH_BILLEASE
    currency string ISO 4217 currency code of PayLater transaction

    Supported currency: IDR, PHP
    amount number Aggregated transaction amount equivalent to the sum of net_unit_amount multiplied by quantity in the order_items array
    refunded_amount number Total amount that has been successfully refunded to end-user
    order_items array Array of objects describing the item/s purchased using PayLater
    success_redirect_url string URL where the customer is redirected after completing transaction
    failure_redirect_url string URL where the end-customer is redirected if the payment has failed
    status string Charge status
    PENDING, SUCCEEDED, FAILED
    created string Timestamp in ISO 8601 for transaction creation
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    updated string Timestamp in ISO 8601 latest object update
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    actions object PayLater Partner’s checkout URL where end-user will be redirected to complete payment
    callback_url string Default to callback URL in dashboard where the charge status will be notified

    HTTPS is required
    payment_method_id string Payment method ID of end-customer source of funds

    Required when checkout_method = TOKENIZED_PAYMENT (currently not supported)
    voided_at string Timestamp in ISO 8601 for void of transaction
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    metadata object Object of additional information the user may use. Users define the JSON properties and values

    You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long

    This will only be used by the user and not Xendit.| |refunds|array|Array of refund object IDs (only SUCCEEDED refunds will show)|

    Error Codes

    Example: Check PayLater Charge Status by ID - Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "Charge ID does not match plc_UUID format"
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    Charge ID does not match plc_UUID format
    INVALID_API_KEY
    401
    API key is not authorized for this API service
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request
    DATA_NOT_FOUND
    404
    Charge resource was not found. Please check your query again
    SERVER_ERROR
    500
    An unexpected error occured. Our team has been notified and will troubleshoot the issue

    Refund Paylater Charge

    Perform a refund for a PayLater payment by Charge ID. This endpoint will only work for charges created via the /paylater/charges endpoint

    Endpoint: Create Paylater Refund

    POST https://api.xendit.co/paylater/charges/{id}/refunds

    Request Parameters

    Example: Create PayLater Refund - Request

    curl https://api.xendit.co/paylater/charges/plc_8cb12305-9bcf-4441-a087-ee0d446e297b/refunds -X POST \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
       -H 'Content-Type: application/json' \
       --data-raw '{
        "amount": "1000",
        "reason": "DEFECTIVE_ITEM"
    }'

    Example: Sample JSON request

    {
        "amount": 1000,
        "reason": "DEFECTIVE_ITEM"
    }
    Header Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Path Parameter Type Description
    id
    required
    string Unique identifier for charge request transaction (returned as id in the PayLater Charge request)
    Body Parameter Type Description
    amount
    optional
    number Amount to be refunded to the end user. Cumulative amount refunded must not exceed the original transacted amount. Refund will only work for unrefunded amount of the charge.
    If the amount field is not present in the request body, the remaining unrefunded amount of the charge would be processed.
    reason
    optional
    enum Reason for refund, one of the following values can be used. Available values - DUPLICATE, FRAUDULENT, CHANGE_OF_MIND, CHANGE_PAYMENT_METHOD, UNFULFILLED_ITEM, DEFECTIVE_ITEM, OTHERS.

    Response Parameters

    Example: Create PayLater Refund - Response

    {
        "id" : "plr_2f2aa47f-2764-4b42-8712-c3fb1270b09e",
        "charge_id" : "plc_8cb12305-9bcf-4441-a087-ee0d446e297b",
        "channel_code" : "PH_BILLEASE",
        "currency" : "PHP",
        "amount" : 1234.56,
        "reason" : "UNFULFILLED_ITEM",
        "status" : "PENDING",
        "created" : "2021-04-20T16:23:52Z",
        "updated" : null
    }
    Body Parameter Type Description
    id string Unique identifier for the refund transaction
    It will always have the prefix of plr_, followed by a UUIDv4
    charge_id string Unique identifier for the original charge transaction
    It will always have the prefix of plc_, followed by a UUIDv4
    channel_code string Channel code for PayLater provider
    Supported channels: ID_KREDIVO, ID_AKULAKU, PH_BILLEASE
    currency string ISO 4217 currency code of PayLater transaction
    Supported currency: IDR, PHP
    amount number Amount to be refunded
    reason string Reason for refund
    status enum Status of the refund request, available values - SUCCEEDED, FAILED, PENDING
    created string Timestamp in ISO 8601 for refund request
    updated number Timestamp in ISO 8601 for refund object update

    Error Codes

    Example: Create PayLater Refund - Error Response

    {
        "error_code": "DATA_NOT_FOUND",
        "message": "Refund resource was not found. Please check your query again"
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    There is an error with the format submitted to the server.
    REFUND_NOT_SUPPORTED
    400
    Refund request failed because refunds are not supported by the PayLater provider.
    PARTIAL_REFUND_NOT_SUPPORTED
    400
    Refund request failed because partial refunds are not supported by the PayLater provider.
    INSUFFICIENT_BALANCE
    400
    Xendit balance is not enough to perform a refund. Please top up your Xendit balance or wait until other transactions have been settled.
    MAXIMUM_REFUND_AMOUNT_REACHED
    400
    Refund request failed because full amount of the PayLater charge has been refunded to end-user.
    INVALID_API_KEY
    401
    API key format is invalid
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request
    DATA_NOT_FOUND
    404
    Refund resource was not found. Please check your query again
    SERVER_ERROR
    500
    An unexpected error occured. Our team has been notified and will troubleshoot the issue
    CHANNEL_UNAVAILABLE
    503
    The payment channel requested is currently experiencing unexpected issues. The PayLater partner will be notified to resolve this issue.

    Get Refund by Refund ID

    Get refund status for a PayLater refund. This endpoint will only work for charges created via the /paylater/charges endpoint

    Endpoint: Get PayLater Refund by ID

    GET https://api.xendit.co/paylater/charges/{charge_id}/refunds/{refund_id}

    Request Parameters

    Example: GET PayLater Refund by ID - Request

    curl https://api.xendit.co/paylater/charges/plc_8cb12305-9bcf-4441-a087-ee0d446e297b/refunds/plr_2f2aa47f-2764-4b42-8712-c3fb1270b09e -X GET \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
    Header Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Path Parameter Type Description
    charge_id
    required
    string ID of Paylater charge
    refund_id
    required
    string ID of Paylater Refund

    Response Parameters

    Example: GET PayLater Refund by ID - Response

    {
        "id" : "plr_2f2aa47f-2764-4b42-8712-c3fb1270b09e",
        "charge_id" : "plc_8cb12305-9bcf-4441-a087-ee0d446e297b",
        "channel_code" : "PH_BILLEASE",
        "currency" : "PHP",
        "amount" : 1234.56,
        "reason" : "UNFULFILLED_ITEM",
        "status" : "PENDING",
        "created" : "2021-04-20T16:23:52Z",
        "updated" : null
    }
    Body Parameter Type Description
    id string Unique identifier for the refund transaction
    It will always have the prefix of plr_, followed by a UUIDv4
    charge_id string Unique identifier for the original charge transaction
    It will always have the prefix of plc_, followed by a UUIDv4
    channel_code string Channel code for PayLater provider
    Supported channels: ID_KREDIVO, ID_AKULAKU, PH_BILLEASE
    currency string ISO 4217 currency code of PayLater transaction
    Supported currency: IDR, PHP
    amount number Amount to be refunded
    reason string Reason for refund
    status enum Status of the refund request, available values - SUCCEEDED, FAILED, PENDING
    created string Timestamp in ISO 8601 for refund request
    updated number Timestamp in ISO 8601 for refund object update

    Error Codes

    Example: GET PayLater Refund by ID - Error Response

    {
        "error_code": "DATA_NOT_FOUND",
        "message": "Refund resource was not found. Please check your query again"
    }
    Error Code Description
    INVALID_API_KEY
    401
    API key format is invalid
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request
    DATA_NOT_FOUND
    404
    Refund resource was not found. Please check your query again
    SERVER_ERROR
    500
    An unexpected error occured. Our team has been notified and will troubleshoot the issue

    List Paylater Refunds

    Get all refunds status made to a PayLater charge transaction. This endpoint will only work for charges created via the /paylater/charges endpoint

    Endpoint: List Paylater Refunds

    GET https://api.xendit.co/paylater/charges/{id}/refunds/

    Request Parameters

    Example: List Paylater Refunds - Request

    curl https://api.xendit.co/paylater/charges/plc_8cb12305-9bcf-4441-a087-ee0d446e297b/refunds?limit=10&status=SUCCEEDED -X GET \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
    Header Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Path Parameter Type Description
    id
    required
    string Unique identifier for charge request transaction (returned as id in the PayLater Charge request)
    Query Parameter Type Description
    limit
    optional
    number Maximum number of results to return at one time
    Default: 10
    Minimum: 1
    Maximum: 50
    status
    optional
    enum Refund status to be retrieved. Available values - SUCCEEDED, FAILED, PENDING

    Response Parameters

    Example: List Paylater Refunds - Response

    {
      "data": [
        {
          "id": "plr_2f2aa47f-2764-4b42-8712-c3fb1270b09e",
          "charge_id": "plc_8cb12305-9bcf-4441-a087-ee0d446e297b",
          "channel_code": "PH_BILLEASE",
          "currency": "PHP",
          "amount": 1234.56,
          "reason": "UNFULFILLED_ITEM",
          "status": "SUCCEEDED",
          "created": "2021-04-20T16:23:52Z",
          "updated": "2021-04-20T16:23:52Z"
        },
        {
          "id": "plr_a351fd9a-90da-459a-b479-9b34e8be6009",
          "charge_id": "plc_8cb12305-9bcf-4441-a087-ee0d446e297b",
          "channel_code": "PH_BILLEASE",
          "currency": "PHP",
          "amount": 1000,
          "reason": "UNFULFILLED_ITEM",
          "status": "SUCCEEDED",
          "created": "2021-04-20T16:23:52Z",
          "updated": "2021-04-20T16:23:52Z"
        }
      ],
      "has_more": false
    }
    Body Parameter Type Description
    data array Data array of PayLater refund object(s) related to specified charge id
    Refund object parameters
    Key Value
    id string Unique identifier for the refund transaction
    It will always have the prefix of plr_, followed by a UUIDv4
    charge_id string Unique identifier for the original charge transaction
    It will always have the prefix of plc_, followed by a UUIDv4
    channel_code string Channel code for PayLater provider
    Supported channels: ID_KREDIVO, ID_AKULAKU, PH_BILLEASE
    currency string ISO 4217 currency code of PayLater transaction
    Supported currency: IDR, PHP
    amount number Amount to be refunded
    reason string Reason for refund
    status enum Status of the refund request, available values - SUCCEEDED, FAILED, PENDING
    created string UTC+0 Timestamp in ISO 8601 for refund request
    updated string UTC+0 Timestamp in ISO 8601 for refund object update
    has_more boolean Indicates whether there are more items to be queried based on the query filters from the current result. If result is empty, has_more will be false

    Error Codes

    Example: List Paylater Refunds - Error Response

    {
        "error_code": "DATA_NOT_FOUND",
        "message": "Refund resource was not found. Please check your query again"
    }
    Error Code Description
    INVALID_API_KEY
    401
    API key format is invalid
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request
    DATA_NOT_FOUND
    404
    Charge resource was not found. Please check your query again
    SERVER_ERROR
    500
    An unexpected error occured. Our team has been notified and will troubleshoot the issue

    QR Codes

    QR codes payment instrument allows you to receive payments directly from end user's mobile banking app balance or eWallet balance. In Indonesia, our merchants can receive payments from any providers connected on QRIS network. (e.g. OVO, Gopay, DANA, LinkAja, BCA, Shopeepay, full list here )

    Create QR Code

    Endpoint: Create QR Code

    POST https://api.xendit.co/qr_codes

    Request Parameters

    Example: Create QRIS QR Code

    curl https://api.xendit.co/qr_codes -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==: \
       -d external_id='testing_id_123' \
       -d type='DYNAMIC' \
       -d callback_url='https://yourwebsite.com/callback'\
       -d amount=1500
    $ch = curl_init();
    
    curl_setopt($ch, CURLOPT_URL, 'https://api.xendit.co/qr_codes');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, "external_id=testing_id_123&type=DYNAMIC&callback_url=https://yourwebsite.com/callback&amount=1500");
    curl_setopt($ch, CURLOPT_USERPWD, 'xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==' . ':' . '');
    
    $headers = array();
    $headers[] = 'Content-Type: application/x-www-form-urlencoded';
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    
    $result = curl_exec($ch);
    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    }
    curl_close($ch);
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { QrCode } = x;
    const qrcodeSpecificOptions = {};
    const q = new QrCode(qrcodeSpecificOptions);
    
    const resp = await q.createCode({
      externalID: "testing_id_123",
      type: "DYNAMIC",
      callbackURL: "https://yourwebsite.com/callback",
      amount: 1500,
    });
    console.log(resp);
    from xendit import Xendit, QRCodeType
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    QRCode = xendit_instance.QRCode
    
    qrcode = QRCode.create(
        external_id="qrcode-id-1594794038",
        type=QRCodeType.DYNAMIC,
        callback_url="https://webhook.site",
        amount=4000,
    )
    print(qrcode)
    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Body Parameter Type Description
    external_id
    required
    string An ID of your choice. Often it is unique identifier in your system like customer ID or order ID
    Note: It has to be unique per creation request
    type
    required
    string DYNAMIC or STATIC
    Note: DYNAMIC QR code contains the payment value upon scanning and can be paid a single time, subsequent transactions are refunded
    Note: STATIC QR code requires end user to input the payment value and can be paid multiple times
    callback_url
    required
    string The URL to receive payment notification after payment has been made by end user
    amount
    optional
    number The payment value embedded in the QR code, end user can only pay the specified amount after scanning the QR code. For STATIC QR code, amount parameter will be ignored.
    Note: Min amount is 1,500 IDR
    Note: Max amount is 5,000,000 IDR
    metadata
    optional
    object Object of additional information the user may use. Users define the JSON properties and values.
    You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

    Response Parameters

    Example: Create QRIS QR Code API Success Response

    {
        "id": "qr_8182837te-87st-49ing-8696-1239bd4d759c",
        "external_id": "testing_id_123",
        "amount": 1500,
        "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52  045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
        "callback_url": "https://yourwebsite.com/callback",
        "type": "DYNAMIC",
        "status": "ACTIVE",
        "created": "2020-01-08T18:18:18.661Z",
        "updated": "2020-01-08T18:18:18.661Z",
        "metadata": {
            "branch_code": "senayan_372",
        }
    }
    Parameter Type Description
    id
    required
    string Unique identifier for this transaction
    external_id
    required
    string Unique identifier specified by merchant for QR code creation
    amount
    required
    number Amount specified in request
    Note: Value will be NULL if QR type is STATIC
    qr_string
    required
    string QR string to be rendered for display to end users. QR string to image rendering are commonly available in software libraries (e.g Nodejs, PHP, Java)
    callback_url
    required
    string The URL provided by merchant to receive payment notification after payment has been made by end user
    type
    required
    string DYNAMIC or STATIC
    status
    required
    string ACTIVE (QR code can be paid) or INACTIVE (QR code has been paid for DYNAMIC QR)
    created
    required
    string Timestamp ISO 8601 when the QR code was created (in UTC)
    updated
    required
    string Timestamp ISO 8601 when the QR code was patched (in UTC)
    metadata
    optional
    object User defined object with JSON properties and values passed in during charge creation.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

    Error Codes

    Example: Create QRIS QR Code API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "Amount must be within range [1500, 2000000]"
    }
    Error Code Description
    DUPLICATE_ERROR
    409
    The payment with the same external_id has already been made before.
    DATA_NOT_FOUND
    409
    QRIS merchant not found, please contact our customer success team for activation.
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here
    API_VALIDATION_ERROR
    400
    There is invalid input in one of the required request fields.

    Get QR Code by External ID

    GET https://api.xendit.co/qr_codes/:external_id

    Request Parameters

    Example: Get QR Code by external_id

    curl https://api.xendit.co/qr_codes/external_id -X GET \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==: \
    $ch = curl_init();
    
    curl_setopt($ch, CURLOPT_URL, 'https://api.xendit.co/qr_codes/external_id');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    
    curl_setopt($ch, CURLOPT_USERPWD, 'xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==' . ':' . '');
    
    $result = curl_exec($ch);
    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    }
    curl_close($ch);
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { QrCode } = x;
    const qrcodeSpecificOptions = {};
    const q = new QrCode(qrcodeSpecificOptions);
    
    const resp = await q.getCode({
      externalID: "testing_id_123",
    });
    console.log(resp);
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    QRCode = xendit_instance.QRCode
    
    qrcode = QRCode.get_by_ext_id(
        external_id="qrcode-id-1594794038",
    )
    print(qrcode)
    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Path Parameter Type Description
    external_id
    required
    string Merchant provided unique ID used to create QR code

    Response Parameters

    Example: Get QR Code by external_id Success Response

    {
        "id": "qr_8182837te-87st-49ing-8696-1239bd4d759c",
        "external_id": "testing_id_123",
        "amount": 1500,
        "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
        "callback_url": "https://yourwebsite.com/callback",
        "type": "DYNAMIC",
        "status": "ACTIVE",
        "created": "2020-01-08T18:18:18.661Z",
        "updated": "2020-01-08T18:18:18.661Z",
        "metadata": {
            "branch_code": "senayan_372",
          }
        }
    Parameter Type Description
    id
    required
    string Unique identifier for this transaction
    external_id
    required
    string Unique identifier specified by merchant for QR code creation
    amount
    required
    number Amount specified in request
    Note: Value will be NULL if QR type is STATIC
    qr_string
    required
    string QR string to be rendered for display to end users. QR string to image rendering are commonly available in software libraries (e.g Nodejs, PHP, Java)
    callback_url
    required
    string The URL provided by merchant to receive payment notification after payment has been made by end user
    type
    required
    string Type of QR code - DYNAMIC or STATIC
    status
    required
    string ACTIVE (QR code can be paid) or INACTIVE (QR code has been paid for DYNAMIC QR)
    created
    required
    string Timestamp ISO 8601 when the QR code was created (in UTC)
    updated
    required
    string Timestamp ISO 8601 when the QR code was patched (in UTC)
    metadata
    optional
    object User defined object with JSON properties and values passed in during charge creation.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

    Error Codes

    Example: Create QRIS QR Code API Error Response

    {
        "error_code": "DATA_NOT_FOUND",
        "message": "QR code with external_id testing_id_123 not found"
    }
    Error Code Description
    DATA_NOT_FOUND
    404
    The QR code with specified external_id does not exist.
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here

    Get Payments by External ID

    Provides the feature to retrieve all payments that were made into a particular QR code. This endpoint is particularly useful if each QR code is set up to receive multiple payments (e.g. offline static QR codes)

    GET https://api.xendit.co/qr_codes/payments?external_id={external_id}&from={created}&to={created}&limit={number}

    Request Parameters

    Example: Get Array of Payments by external_id

    curl 'https://api.xendit.co/qr_codes/payments?external_id=testing_qr&from=2021-01-04T08:09:30.000Z&to=2021-01-04T08:22:29.000Z&limit=2' -X GET \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==: \
    $ch = curl_init();
    
    curl_setopt($ch, CURLOPT_URL, 'https://api.xendit.co/qr_codes/payments?external_id=testing_qr&from=2021-01-04T08:09:30.000Z&to=2021-01-04T08:22:29.000Z&limit=2');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    
    curl_setopt($ch, CURLOPT_USERPWD, 'xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==' . ':' . '');
    
    $result = curl_exec($ch);
    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    }
    curl_close($ch);
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { QrCode } = x;
    const qrcodeSpecificOptions = {};
    const q = new QrCode(qrcodeSpecificOptions);
    
    const resp = await q.getPayments({
      externalID: "testing_id_123",
      from: "2021-01-04T08:09:30.000Z",
      to: "2021-02-04T07:44:20.332Z",
      limit: 10,
    });
    console.log(resp);
    Path Parameter Type Description
    external_id
    required
    string Merchant provided unique transaction ID used to create QR code
    limit
    optional
    number Default = 10. Number of payment transactions to be returned in response array
    from
    optional
    string Starting timestamp for time based filters using created, timestamp must be earlier than to parameter
    to
    optional
    string Ending timestamp for time based filters using created, timestamp must be later than from parameter

    Response Parameters

    Example: Get Array of Payments by external_id Success Response

    [
          {
      "id": "qrpy_8182837te-87st-49ing-8696-1239bd4d759c",
      "amount": 1500,
      "created": "2020-01-08T18:18:18.857Z",
      "qr_code": {
        "id": "qr_8182837te-87st-49ing-8696-1239bd4d759c",
        "external_id": "testing_id_123",
        "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
        "type": "DYNAMIC",
        "metadata": {
            "branch_code": "senayan_372",
        }
      },
      "status": "COMPLETED"
         },
         {
      "id": "qrpy_8182837te-87st-49ing-8696-1229bd22222",
      "amount": 1500,
      "created": "2020-01-08T18:18:20.857Z",
      "qr_code": {
        "id": "qr_8182837te-87st-49ing-8696-1239bd4d759c",
        "external_id": "testing_id_123",
        "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
        "type": "DYNAMIC",
        "metadata": {
            "branch_code": "senayan_372",
         }
      },
      "status": "COMPLETED"
         }
    ]
    Parameter Type Description
    id
    required
    string Unique identifier for this transaction
    amount
    required
    number Amount paid by end user
    created
    required
    string Timestamp ISO 8601 when the QR code was paid (in UTC)
    qr_code
    required
    object QR code object associated with the QR code payment
    QR code fields
    Key Value
    id
    required
    string Unique identifier for the QR code creation transaction
    external_id
    required
    string Unique identifier for the payment request specified by merchant
    qr_string
    required
    string QR string to be rendered for display to end users
    type
    required
    string Type of QR code - DYNAMIC or STATIC
    metadata
    optional
    object User defined object with JSON properties and values passed in during charge creation.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
    status
    required
    string Status of payment. Possible value(s): COMPLETED

    Error Codes

    Example: Get Array of Payments by external_id

    {
        "error_code": "DATA_NOT_FOUND",
        "message": "QR code with external_id testing_id_123 not found"
    }
    Error Code Description
    DATA_NOT_FOUND
    404
    The QR code with specified external_id does not exist.
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here

    Simulate Payment (for completion of payment in test mode)

    POST https://api.xendit.co/qr_codes/:external_id/payments/simulate

    Request Parameters (test mode)

    Example: Simulate Payment in Test Mode

    curl https://api.xendit.co/qr_codes/:external_id/payments/simulate -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==: \
       -d amount=1500
    $ch = curl_init();
    
    curl_setopt($ch, CURLOPT_URL, 'https://api.xendit.co/qr_codes/:external_id/payments/simulate');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=1500");
    curl_setopt($ch, CURLOPT_USERPWD, 'xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==' . ':' . '');
    
    $headers = array();
    $headers[] = 'Content-Type: application/x-www-form-urlencoded';
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    
    $result = curl_exec($ch);
    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    }
    curl_close($ch);
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { QrCode } = x;
    const qrcodeSpecificOptions = {};
    const q = new QrCode(qrcodeSpecificOptions);
    
    const resp = await q.simulate({
      externalID: "testing_id_123",
    });
    console.log(resp);
    
    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Path Parameter Type Description
    external_id
    required
    string Unique identifier specified by merchant for QR code creation
    Body Parameter Type Description
    amount
    optional
    number The payment value for simulation in callback to test mode endpoint
    Note: Min amount is 1,500 IDR
    Note: Max amount is 5,000,000 IDR

    Response Parameters (test mode)

    Example: Simulate Payment (test mode) Success Response

    {
      "id": "qrpy_8182837te-87st-49ing-8696-1239bd4d759c",
      "amount": 1500,
      "created": "2020-01-08T18:18:18.857Z",
      "qr_code": {
        "id": "qr_8182837te-87st-49ing-8696-1239bd4d759c",
        "external_id": "testing_id_123",
        "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
        "type": "DYNAMIC",
        "metadata": {
            "branch_code": "senayan_372",
        }
      },
      "status": "COMPLETED"
    }
    Parameter Type Description
    id
    required
    string Unique identifier for this transaction
    amount
    required
    number Amount paid by end user
    created
    required
    string Timestamp ISO 8601 when the QR code was paid (in UTC)
    qr_code
    required
    object QR code object associated with the QR code payment
    QR code fields
    Key Value
    id
    required
    string Unique identifier for the QR code creation transaction
    external_id
    required
    string Unique identifier for the payment request specified by merchant
    qr_string
    required
    string QR string to be rendered for display to end users. QR string to image rendering are commonly available in software libraries (e.g Nodejs, PHP, Java)
    type
    required
    string Type of QR code - DYNAMIC or STATIC
    metadata
    optional
    object User defined object with JSON properties and values passed in during charge creation.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
    status
    required
    string Status of payment. Possible value(s): COMPLETED

    Error Codes

    Example: Create QRIS QR Code API Error Response

    {
        "error_code": "DATA_NOT_FOUND",
        "message": "QR code with external_id testing_id_123 not found"
    }
    Error Code Description
    INACTIVE_QR_CODE
    410
    Payment simulation for DYNAMIC QRIS has been completed previously. DYNAMIC QRIS is inactive.
    DATA_NOT_FOUND
    404
    The QR code with specified external_id does not exist.
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here
    API_VALIDATION_ERROR
    400
    There is invalid input in one of the required request fields.

    Payment Status Callback

    Xendit notifies your system upon successful payments via callback. You need to provide an URL to receive callback. Please specify your URL in Callback Settings in Xendit Dashboard.

    The payment notification will be sent as POST request to the URL you set. Xendit attach x-callback-token header that you can validate against Verification Token in Callback Settings to verify message authenticity.

    Please response back with status 200 immediately. Learn more about Callback

    Payment Callback Payload

    Header Parameter Type Description
    x-callback-token
    required
    string Your Xendit unique callback token to verify the origin of the callback

    {
      "event": "qr.payment",
      "id": "qrpy_8182837te-87st-49ing-8696-1239bd4d759c",
      "amount": 1500,
      "created": "2020-01-08T18:18:18.857Z",
      "qr_code": {
        "id": "qr_8182837te-87st-49ing-8696-1239bd4d759c",
        "external_id": "testing_id_123",
        "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
        "type": "DYNAMIC",
        "metadata": {
            "branch_code": "senayan_372",
        }
      },
      "status": "COMPLETED"
    }
    Parameter Type Description
    event
    required
    string Available value: "qr.payment"
    id
    required
    string Unique identifier for this transaction
    amount
    required
    number Amount paid by end user
    created
    required
    string Timestamp ISO 8601 when the QR code was paid (in UTC)
    qr_code
    required
    object QR code object associated with the QR code payment
    QR code fields
    Key Value
    id
    required
    string Unique identifier for the QR code creation transaction
    external_id
    required
    string Unique identifier specified by merchant for QR code creation
    qr_string
    required
    string QR string to be rendered for display to end users. QR string to image rendering are commonly available in software libraries (e.g Nodejs, PHP, Java)
    type
    required
    string Type of QR code - DYNAMIC or STATIC
    metadata
    optional
    object User defined object with JSON properties and values passed in during charge creation.
    Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
    status
    required
    string Status of payment. Possible value(s): COMPLETED

    Direct Debit

    Direct Debit enables merchants to pull payments directly from their end user’s account bank balance by linking their debit card or bank account access.

    For the integration guide, and list of supported channels and corresponding linking type, see our documentation.

    Initialize Linked Account Tokenization

    Account authorizations are represented by linked account tokens. This endpoint initializes the authorization process and linked account token creation.

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Endpoint: Initialize Linked Account Tokenization

    POST https://api.xendit.co/linked_account_tokens/auth

    Initialize Linked Account Tokenization - Request

    Example Initialize Linked Account Tokenization Request

    curl https://api.xendit.co/linked_account_tokens/auth -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -H 'Content-Type: application/json' \
       --data-raw '{
        "customer_id": "ba830b92-4177-476e-b097-2ad5ae4d3e55",
        "channel_code": "DC_BRI",
        "properties": {
            "account_mobile_number": "+62818555988",
            "card_last_four": "1234",
            "card_expiry": "06/24",
            "account_email": "email@email.com"
        }
    }'
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $linkedAccountTokenizationParams = [
        'customer_id' => '4b7b6050-0830-440a-903b-37d527dbbaa9',
        'channel_code' => 'DC_BRI',
        'properties' => [
          'account_mobile_number' => '+62818555988',
          'card_last_four' => '8888',
          'card_expiry' => '06/24',
          'account_email' => 'test.email@xendit.co'
        ],
        'metadata' => [
          'meta' => 'data'
        ]
      ];
    
      $initializeTokenization = \Xendit\DirectDebit::initializeLinkedAccountTokenization(
        $linkedAccountTokenizationParams
      );
      var_dump($initializeTokenization);
    
    ?>
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { DirectDebit } = x;
    const directDebitSpecificOptions = {};
    const dd = new DirectDebit(directDebitSpecificOptions);
    
    const resp = await dd.initializeTokenization({
      customerID: 'ba830b92-4177-476e-b097-2ad5ae4d3e55',
      channelCode: 'DC_BRI',
      properties: {
        accountMobileNumber: '+62818555988',
        cardLastFour: '1234',
        cardExpiry: '06/24',
        accountEmail: 'email@email.com',
      },
    });
    console.log(resp);
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    properties := map[string]interface{}{
      "account_mobile_number": "+62818555988",
      "card_last_four": "8888",
      "card_expiry": "06/24",
      "account_email": "test.email@xendit.co",
    }
    
    metadata := map[string]interface{}{
      "meta": "data",
    }
    
    data := linkedaccount.InitializeLinkedAccountTokenizationParams{
      CustomerID:   "791ac956-397a-400f-9fda-4958894e61b5",
      ChannelCode:  xendit.DC_BRI,
      Properties:   properties,
      Metadata:     metadata,
    }
    
    resp, err := linkedaccount.InitializeLinkedAccountTokenization(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("initialized linked account tokenization: %+v\n", resp)
    try {
      Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
      Map<String, Object> properties = new HashMap<>();
      properties.put("account_mobile_number", "+62818555988");
      properties.put("card_last_four", "8888");
      properties.put("card_expiry", "06/24");
      properties.put("account_email", "test.email@xendit.co");
    
      Map<String, Object> metadata = new HashMap<>();
      metadata.put("tes", "123");
    
      Map<String, Object> params = new HashMap<>();
      params.put("customer_id", "791ac956-397a-400f-9fda-4958894e61b5");
      params.put("channel_code", "DC_BRI");
      params.put("properties", properties);
      params.put("metadata", metadata);
    
      InitializedLinkedAccount linkedAccount = InitializedLinkedAccount.initializeLinkedAccountTokenization(params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    DirectDebit = xendit_instance.DirectDebit
    
    card_linking = DirectDebit.helper_create_card_link(
        account_mobile_number="+62818555988",
        card_last_four="8888",
        card_expiry="06/24",
        account_email="test.email@xendit.co",
    )
    linked_account = DirectDebit.initialize_tokenization(
        customer_id="ed20b5db-df04-41fc-8018-8ea4ac4d1030",
        channel_code="DC_BRI",
        properties=card_linking,   
    )
    print(linked_account)
    Request Body Parameter Type Description
    customer_id
    required
    string ID of the customer object to which the account token will be linked to. Call Customer API to generate Customer ID
    channel_code
    required
    string Identifier for the specific channel of the account to be linked. Code must be in uppercase.

    Supported banks and their respective channel codes:
    • Bank BRI (ID) - DC_BRI
    • BCA OneKlik (ID) - BCA_ONEKLIK
    • Bank of the Philippine Islands (PH) - BA_BPI
    • Unionbank (PH) - BA_UBP
    properties
    optional
    object JSON that contains information needed to proceed with authorization. Values inside properties change based on type of account:

    For BRI Debit Card Linking:
    Key Value
    account_mobile_number
    required
    Mobile number of the customer registered to the partner channel in E.164 international standard. Format: +(country code)(subscriber number)
    card_last_four
    required
    Last four digits of the debit card
    card_expiry
    required
    Expiry month and year of the debit card (in MM/YY format)
    account_email
    required
    Email address of the customer that is registered to the partner channel
    For BCA OneKlik:
    Key Value
    account_mobile_number
    required
    Mobile number of the customer registered to the partner channel in E.164 international standard. Format: +(country code)(subscriber number)
    success_redirect_url
    required
    URL where the end-customer is redirected if the authorization is successful. Linked account token ID will be included in the URL as a query parameter.
    failure_redirect_url
    optional
    URL where the end-customer is redirected if the authorization fails.
    callback_url
    optional
    URL where the successful linking webhook will be sent. If none is provided, webhook will be sent to the default set during onboarding.
    device
    optional
    Required for BCA OneKlik
    Object that contains the end-customer's device fingerprint information. This is used for fraud detection.
    Key Value
    id
    required
    The end-customer's Android or iOS specific unique device identifier.

    If accessed through web, input the string WEB
    ip_address
    required
    The end-customer's IPv4 or IPv6 address at the point of request.
    user_agent
    required
    The end-customer's extracted user-agent string from the device.
    ad_id
    optional
    Android advertising ID (AAID) or iOS Identifier for Advertisers (IDFA)
    imei
    optional
    The end-customer's device's International Mobile Equipment Identity (IMEI).
    For Online Banking Access Linking (BPI, UBP):
    Key Value
    success_redirect_url
    required
    URL where the end-customer is redirected if the authorization is successful. Linked account token ID will be included in the URL as a query parameter.
    failure_redirect_url
    optional
    URL where the end-customer is redirected if the authorization fails
    callback_url
    optional
    URL where the successful linking webhook will be sent. If none is provided, webhook will be sent to the default set during onboarding.
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Initialize Linked Account Tokenization - Response

    Example Initialize Linked Account Tokenization Success Response

    {
        "id": "lat-aa620619-124f-41db-995b-66a52abe036a",
        "customer_id": "ba830b92-4177-476e-b097-2ad5ae4d3e55",
        "channel_code": "DC_BRI",
        "authorizer_url": null,
        "status": "PENDING",
        "metadata": null
    }
    Parameter Type Description
    id string Unique ID generated by Xendit for the particular linked account token authorization
    customer_id string Customer object ID
    channel_code string Code identifier for the channel
    authorizer_url string URL to be rendered for end user to confirm authorization for linking via online banking access. For debit card linking (BRI), this will always be null; proceed to the "Validate OTP for Linked Account Token" step instead.
    status string Status of the authorization. Will always be PENDING for successful initiations.
    metadata object A free-format JSON for additional information that you provded during request.

    Initialize Linked Account Tokenization - Errors

    See other common errors here.

    Error Code Description
    CHANNEL_CODE_NOT_SUPPORTED_ERROR
    400
    Provided channel_code is not supported or has not yet activated for this account.
    CUSTOMER_NOT_FOUND_ERROR
    400
    Provided customer_id in the request does not exist or access is unauthorized
    INVALID_ACCOUNT_DETAILS
    400
    Provided values in properties in the request does not match any records with the bank
    ACCOUNT_ACCESS_BLOCKED
    400
    The bank has rejected the linking. This maybe the bank account is inaccessible or not activated for this service.
    MAX_ACCOUNT_LINKING
    400
    Cannot link the account because it has reached the maximum number of linking allowed by the bank. Please unlink any existing binding for this account.
    OTP_DELIVERY_ERROR
    400
    The bank failed to send the OTP to the end-user. Please try again.
    CHANNEL_UNAVAILABLE
    503
    The target channel is currently unavailable. This is possibly due to partner channel downtime or error.

    Validate OTP for Linked Account Token

    Account linking for debit cards requires an OTP to proceed. Upon successful initialization, the bank will send an OTP to the customer's registered mobile number directly. This endpoint validates the OTP with the bank.

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Endpoint: Validate OTP for Linked Account Token

    POST https://api.xendit.co/linked_account_tokens/{linked_account_token_id}/validate_otp

    Validate OTP for Linked Account Token - Request

    Example Validate OTP for Linked Account Token Request

    curl https://api.xendit.co/linked_account_tokens/lat-aa620619-124f-41db-995b-66a52abe036a/validate_otp -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -H 'Content-Type: application/json' \
       --data-raw '{
        "otp_code":"123456"
    }'
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $validateOTPForLinkedAccountParams = [
        'otp_code' => '333000'
      ];
    
      $validateOTPForLinkedAccount = \Xendit\DirectDebit::validateOTPForLinkedAccount(
        'lat-a08fba1b-100c-445b-b788-aaeaf8215e8f',
        $validateOTPForLinkedAccountParams
      );
      var_dump($validateOTPForLinkedAccount);
    
    ?>
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { DirectDebit } = x;
    const directDebitSpecificOptions = {};
    const dd = new DirectDebit(directDebitSpecificOptions);
    
    const resp = await dd.validateOTPforLinkedAccount({
      tokenID: 'lat-aa620619-124f-41db-995b-66a52abe036a',
      otpCode: '123456',
    });
    console.log(resp);
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := linkedaccount.ValidateOTPForLinkedAccountParams{
      LinkedAccountTokenID: "lat-f9dc34e7-153a-444e-b337-cd2599e7f670",
      OTPCode:              "333000",
    }
    
    resp, err := linkedaccount.ValidateOTPForLinkedAccount(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("validated linked account: %+v\n", resp)
    try {
      Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
      Map<String, Object> params = new HashMap<>();
      params.put("otp_code", "333000");
    
      String tokenId = "lat-ba3c5645-f134-432a-b4f4-f8972685aa03";
    
      ValidatedLinkedAccount linkedAccount = ValidatedLinkedAccount.validateOTP(tokenId, params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    DirectDebit = xendit_instance.DirectDebit
    
    linked_account = DirectDebit.validate_token_otp(
        linked_account_token_id="lat-f325b757-0aae-4c24-92c5-3661e299e154",
        otp_code="333000",
    )
    print(linked_account)
    Path Parameter Type Description
    linked_account_token_id
    required
    string Linked account token id received from Initialize Account Authorization. This has the lat- prefix.
    Request Body Parameter Type Description
    otp_code
    required
    string OTP received by the customer from the partner bank for account linking

    Validate OTP for Linked Account Token - Response

    Example Validate OTP for Linked Account Token Success Response

    {
        "id": "lat-aa620619-124f-41db-995b-66a52abe036a",
        "customer_id": "239c16f4-866d-43e8-9341-7badafbc019f",
        "channel_code": "DC_BRI",
        "status": "SUCCESS"
    }
    Parameter Type Description
    id string Unique ID generated by Xendit for the particular linked account token authorization
    customer_id string Customer object ID
    channel_code string Code identifier for the channel
    status string Status of the authorization - SUCCESS if the validation went through. Else, error will be thrown

    Validate OTP for Linked Account Token - Errors

    See other common errors here.

    Error Code Description
    DATA_NOT_FOUND_ERROR
    404
    Provided linked_account_token_id is not supported or has not yet activated for this account.
    INVALID_OTP_ERROR
    400
    The otp_code provided was incorrect.
    EXPIRED_OTP_ERROR
    400
    The otp_code provided has expired.
    MAX_OTP_ATTEMPTS_ERROR
    400
    Reached the channel’s allowed maximum attempts for OTP verification
    ACCOUNT_LINKING_ALREADY_COMPLETED
    409
    The request is a duplicate of an already processed linked account token that has been successfully completed.
    ACCOUNT_LINKING_ALREADY_FAILED
    409
    The request is a duplicate of an already processed linked account token that has failed.

    Retrieve Accessible Accounts by Linked Account Token

    This endpoint returns a list of bank accounts accessible by the linked account token. The response information from this endpoint is required for creation of payment method.

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Endpoint: Get Accessible Accounts by Linked Account Token

    GET https://api.xendit.co/linked_account_tokens/{linked_account_token_id}/accounts

    Retrieve Accessible Accounts by Linked Account Token - Request

    Example Get Accessible Accounts by Linked Account Token Request

    curl https://api.xendit.co/linked_account_tokens/lat-aa620619-124f-41db-995b-66a52abe036a/accounts -X GET \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: 
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $retrieveLinkedAccounts = \Xendit\DirectDebit::retrieveAccessibleLinkedAccounts(
        'lat-a08fba1b-100c-445b-b788-aaeaf8215e8f'
      );
      var_dump($retrieveLinkedAccounts);
    
    ?>
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { DirectDebit } = x;
    const directDebitSpecificOptions = {};
    const dd = new DirectDebit(directDebitSpecificOptions);
    
    const resp = await dd.retrieveAccountsByTokenID({
      tokenID: 'lat-aa620619-124f-41db-995b-66a52abe036a',
    });
    console.log(resp);
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := linkedaccount.RetrieveAccessibleLinkedAccountParams{
      LinkedAccountTokenID: "lat-f9dc34e7-153a-444e-b337-cd2599e7f670",
    }
    
    resp, err := linkedaccount.RetrieveAccessibleLinkedAccounts(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("retrieved accessible linked accounts: %+v\n", resp)
    try {
      Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
      AccessibleLinkedAccount[] linkedAccounts = AccessibleLinkedAccount.retrieveAccessibleLinkedAccounts(
          "lat-960e709c-bdd6-4b4a-a361-243186379c45");
      System.out.println(Arrays.toString(linkedAccounts));
    } catch (XenditException e) {
      e.printStackTrace();
    }
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    DirectDebit = xendit_instance.DirectDebit
    
    accessible_accounts = DirectDebit.get_accessible_accounts_by_token(
        linked_account_token_id="lat-f325b757-0aae-4c24-92c5-3661e299e154",
    )
    print(accessible_accounts)
    Path Parameter Type Description
    linked_account_token_id
    required
    string Linked account token id received from Initialize Account Authorization. This has the lat- prefix.

    Retrieve Accessible Accounts by Linked Account Token - Response

    This endpoint returns an array of objects with the following properties:

    Example Get Accessible Accounts by Linked Account Token Success Response

    [{
        "id": "la-aa620619-124f-41db-995b-66a52abe036a",
        "channel_code": "DC_BRI",
        "type": "DEBIT_CARD",
        "properties": {
            "card_last_four": "1234",
            "card_expiry": "06/24",
            "currency": "IDR",
            "description": ""
        }
    }]
    Parameter Type Description
    id string Unique identifier for the bank account. This has a prefix of la-.
    channel_code string Code identifier for the channel
    type string Type of account that has been linked.
    Expected values: DEBIT_CARD (BRI, BCA OneKlik) or BANK_ACCOUNT (BPI, UBP)
    properties object Object containing information regarding the account. The values inside properties change based on the type of account:


    For type BRI DEBIT_CARD:
    Key Value
    card_last_four stringLast four digits of the debit card
    card_expiry stringExpiry month and year of the debit card (in MM/YY format)
    currency stringCurrency of the account in ISO 4217
    description stringDescription of the account (provided by the bank)
    For type BCA OneKlik:
    Key Value
    account_mobile_number stringMobile number of the end-customer registered to the partner channel
    card_last_four stringLast four digits of the debit card
    card_expiry stringExpiry month and year of the debit card (in MM/YY format)
    currency stringCurrency of the account in ISO 4217
    description stringDescription of the account (provided by the bank)
    For type BANK_ACCOUNT (BPI):
    Key Value
    account_details stringMasked account details as provided by the bank. Used for displaying a portion of the account number.
    account_hash stringUnique hash for the specific account. This does not change across different authorizations or integrations.
    account_type stringType of bank account (provided by the bank)
    currency stringCurrency of the account in ISO 4217
    description stringDescription of the account (provided by the bank)

    Retrieve Accessible Accounts by Linked Account Token - Errors

    See other common errors here.

    Error Code Description
    DATA_NOT_FOUND_ERROR
    404
    Provided linked_account_token_id is not supported or has not yet activated for this account.

    Unbind a Linked Account Token

    Unlinks or unbinds a successful linked account token.

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Endpoint: Unbind a Linked Account Token

    DELETE https://api.xendit.co/linked_account_tokens/{linked_account_token_id}

    Unbind a Linked Account Token - Request

    Example Unbind a Linked Account Token Request

    curl https://api.xendit.co/linked_account_tokens/lat-aa620619-124f-41db-995b-66a52abe036a/validate_otp -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: 
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $unbindLinkedAccountToken = \Xendit\DirectDebit::unbindLinkedAccountToken(
        'lat-a08fba1b-100c-445b-b788-aaeaf8215e8f'
      );
      var_dump($unbindLinkedAccountToken);
    
    ?>
    let apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
    let linkedAccountTokenId = "lat-aa620619-124f-41db-995b-66a52abe036a";
    let url = "https://api.xendit.co/linked_account_tokens/" + linkedAccountTokenId;
    
    var headers = new Headers();
    headers.append("Authorization", "Basic " + btoa(apiKey + ":"));
    
    var requestOptions = {
      method: 'DELETE',
      headers: headers,
      redirect: 'follow'
    };
    
    fetch(url, requestOptions)
      .then(response => response.text())
      .then(result => console.log(result))
      .catch(error => console.log('error', error));
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := linkedaccount.UnbindLinkedAccountTokenParams{
      LinkedAccountTokenID: "lat-f9dc34e7-153a-444e-b337-cd2599e7f670",
    }
    
    resp, err := linkedaccount.UnbindLinkedAccountToken(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("unbinded linked account: %+v\n", resp)
    try {
      Xendit.apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
    
      UnbindedLinkedAccount linkedAccount = UnbindedLinkedAccount.unbindLinkedAccountToken ("lat-a08fba1b-100c-445b-b788-aaeaf8215e8f");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    Path Parameter Type Description
    linked_account_token_id
    required
    string Linked account token id received from Initialize Account Authorization. This has the lat- prefix.

    Unbind a Linked Account Token - Response

    Example Unbind a Linked Account Token Success Response

    {
        "id": "lat-aa620619-124f-41db-995b-66a52abe036a",
        "is_deleted": true
    }
    Parameter Type Description
    id string Unique ID generated by Xendit for the particular linked account token authorization
    is_deleted boolean Describes whether or not the linked account token was successfully deleted

    Unbind a Linked Account Token - Errors

    See other common errors here.

    Error Code Description
    DATA_NOT_FOUND_ERROR
    404
    Provided linked_account_token_id is not found or inaccessible for this account.

    Create Payment Method

    Payment methods enable you to abstract sources of funds and use them for making direct debit payments or recurring payments. Currently, only supports linked accounts.

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Endpoint: Create Payment Method

    POST https://api.xendit.co/payment_methods

    Create Payment Method - Request

    Example Create Payment Method Request

    curl https://api.xendit.co/payment_methods -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -H 'Content-Type: application/json' \
       --data-raw '{
        "customer_id": "ba830b92-4177-476e-b097-2ad5ae4d3e55",
        "type": "DEBIT_CARD",
        "properties": {
            "id": "la-aa620619-124f-41db-995b-66a52abe036a"
        }
    }'
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $createPaymentMethodParams = [
        'customer_id' => '4b7b6050-0830-440a-903b-37d527dbbaa9',
        'type' => 'DEBIT_CARD',
        'properties' => [
          'id' => 'la-052d3e2d-bc4d-4c98-8072-8d232a552299'
        ],
        'metadata' => [
          'meta' => 'data'
        ]
      ];
    
      $createPaymentMethod = \Xendit\DirectDebit::createPaymentMethod(
        $createPaymentMethodParams
      );
      var_dump($createPaymentMethod);
    
    ?>
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { DirectDebit } = x;
    const directDebitSpecificOptions = {};
    const dd = new DirectDebit(directDebitSpecificOptions);
    
    const resp = await dd.createPaymentMethod({
      customerID: 'ba830b92-4177-476e-b097-2ad5ae4d3e55',
      type: 'DEBIT_CARD',
      properties: {
        id: 'la-aa620619-124f-41db-995b-66a52abe036a',
      },
    });
    console.log(resp);
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    properties := map[string]interface{}{
      "id": "la-55048b41-a7ab-4799-9f33-6ec5cc078db0",
    }
    
    metadata := map[string]interface{}{
      "meta": "data",
    }
    
    data := paymentmethod.CreatePaymentMethodParams{
      CustomerID:  "4b7b6050-0830-440a-903b-37d527dbbaa9",
      Type:        xendit.DEBIT_CARD,
      Properties:  properties,
      Metadata:    metadata,
    }
    
    resp, err := paymentmethod.CreatePaymentMethod(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("created payment method: %+v\n", resp)
    try {
      Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
      Map<String, Object> properties = new HashMap<>();
      properties.put("id", "la-052d3e2d-bc4d-4c98-8072-8d232a552299");
      Map<String, Object> metadata = new HashMap<>();
      metadata.put("halo", "hello");
      metadata.put("tes", "123");
      Map<String, Object> params = new HashMap<>();
      params.put("customer_id", "4b7b6050-0830-440a-903b-37d527dbbaa9");
      params.put("type", "DEBIT_CARD");
      params.put("properties", properties);
      params.put("metadata", metadata);
    
      PaymentMethod paymentMethod = PaymentMethod.createPaymentMethod(params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    from xendit import Xendit, DirectDebitPaymentMethodType
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    DirectDebit = xendit_instance.DirectDebit
    
    payment_method = DirectDebit.create_payment_method(
        customer_id="ed20b5db-df04-41fc-8018-8ea4ac4d1030",
        type=DirectDebitPaymentMethodType.DEBIT_CARD,
        properties={'id': 'la-fac7e744-ab40-4100-a447-cbbb16f29ded'},
    )
    
    print(payment_method)
    Request Body Parameter Type Description
    customer_id
    conditional
    string ID of the customer object to which the account token will be linked to.
    Required for all channels except for BCA KlikPay.
    type
    required
    string Type of payment method

    For BRI, BCA OneKlik: DEBIT_CARD
    For BCA KlikPay: BANK_REDIRECT
    For BPI, Unionbank: BANK_ACCOUNT
    properties
    required
    object JSON that contains information that identifies the payment method:


    For BRI, BCA OneKlik, BPI, and Unionbank:
    Key Value
    id
    required
    ID of the account from which payments will be pulled from. You can retrieve account ID by using this API
    For BCA KlikPay:
    Key Value
    channel_code
    required
    Xendit indentifier code for the specific channel partner
    For BCA KlikPay: BCA_KLIKPAY
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Create Payment Method - Response

    Example Create Payment Method Success Response

    {    
        "id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
        "type": "DEBIT_CARD",
        "properties": {
            "id": "la-aa620619-124f-41db-995b-66a52abe036a",
            "channel_code": "DC_BRI",
            "currency": "IDR",
            "card_last_four": "1234",
            "card_expiry": "06/24",
            "description": null,
        },
        "customer_id": "ba830b92-4177-476e-b097-2ad5ae4d3e55",
        "status": "ACTIVE",
        "created": "2020-03-19T05:34:55+0800",
        "updated": "2020-03-19T05:24:55+0800",
        "metadata": null  
    }
    Parameter Type Description
    id string Unique identifier for the payment method. This has a prefix of pm-.
    type string Type of account that has been linked.
    For BRI, BCA OneKlik: DEBIT_CARD
    For BCA KlikPay: BANK_REDIRECT
    For BPI, Unionbank: BANK_ACCOUNT
    properties object Object containing information regarding the account. The values inside properties change based on the type of account:


    For BRI:
    Key Value
    channel_code Identifier for the specific channel of the account to be linked. Code must be in uppercase.

    Supported banks and their respective channel codes:
    • Bank BRI (ID) - DC_BRI
    card_last_four stringLast four digits of the debit card
    card_expiry stringExpiry month and year of the debit card (in MM/YY format)
    currency stringCurrency of the account in ISO 4217
    description stringDescription of the account (provided by the bank)
    For BCA OneKlik:
    Key Value
    channel_code Identifier for the specific channel of the account to be linked. Code must be in uppercase.

    Supported banks and their respective channel codes:
    • BCA OneKlik (ID) - BCA_ONEKLIK
    account_mobile_number stringMobile number of the end-customer registered to the partner channel
    card_last_four stringLast four digits of the debit card
    card_expiry stringExpiry month and year of the debit card (in MM/YY format)
    currency stringCurrency of the account in ISO 4217
    description stringDescription of the account (provided by the bank)
    For type BCA KlikPay:
    Key Value
    channel_code Identifier for the specific channel of the account to be linked. Code must be in uppercase.

    Supported banks and their respective channel codes:
    • BCA KlikPay (PH) - BCA_KLIKPAY
    For type BPI, Unionbank:
    Key Value
    channel_code Identifier for the specific channel of the account to be linked. Code must be in uppercase.

    Supported banks and their respective channel codes:
    • Bank of the Philippine Islands (PH) - BA_BPI
    • Unionbank (PH) - BA_UBP
    account_details stringMasked account details as provided by the bank. Used for displaying a portion of the account number.
    account_hash stringUnique hash for the specific account. This does not change across different authorizations or integrations.
    account_type stringType of bank account (provided by the bank)
    currency stringCurrency of the account in ISO 4217
    description stringDescription of the account (provided by the bank)
    customer_id string ID of the customer object in which this payment method is linked to
    status
    required
    string Status of the payment method.
    Will be equal to ACTIVE upon creation.
    created string Timestamp in ISO 8601 when the request was made
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    updated string Timestamp in ISO 8601 when transaction information was updated
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    metadata object A free-format JSON for additional information that you provded during request.

    Create Payment Method - Errors

    See other common errors here.

    Error Code Description
    CHANNEL_CODE_NOT_SUPPORTED_ERROR
    400
    Provided channel_code does not exist
    LIINKED_ACCOUNT_NOT_FOUND_ERROR
    400
    Provided properties and type combination in the request does not exist or access is unauthorized
    CUSTOMER_NOT_FOUND_ERROR
    400
    Provided customer_id in the request does not exist or access is unauthorized
    DUPLICATE_ERROR
    409
    There is already an existing ACTIVE payment method that relates to the same account

    Create Direct Debit Payment

    Create a debit to pull funds from the end customer's account using an active payment method. BRI (ID) and BPI (PH) supports sending OTPs to complete a payment; UBP (PH) does not require any OTP.

    Endpoint: Create Direct Debit Payment

    POST https://api.xendit.co/direct_debits

    Create Payment - Request

    Example Create Payment Request

    curl https://api.xendit.co/direct_debits -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -H 'Content-Type: application/json' \
       -H 'Idempotency-key: Test_Idempotent_Key'\
       --data-raw '{
        "reference_id": "customer_test_reference_id",
        "payment_method_id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
        "currency": "IDR",
        "amount": 1500,
        "enable_otp": true,
        "callback_url": "https://payment-callback-listener/"
    }'
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $createDirectDebitPaymentParams = [
        'reference_id' => 'test-direct-debit-ref',
        'payment_method_id' => 'pm-ebb1c863-c7b5-4f20-b116-b3071b1d3aef',
        'currency' => 'IDR',
        'amount' => 15000,
        'callback_url' => 'http://webhook.site/',
        'enable_otp' => true,
        'description' => 'test description',
        'basket' => [
          [
            'reference_id' => 'basket-product-ref-id',
            'name' => 'product name',
            'category' => 'mechanics',
            'market' => 'ID',
            'price' => 50000,
            'quantity' => 5,
            'type' => 'product type',
            'sub_category' => 'product sub category',
            'description' => 'product description',
            'url' => 'https://product.url'
          ]
        ],
        'device' => [
          'id' => 'device_id',
          'ip_address' => '0.0.0.0',
          'ad_id' => 'ad-id',
          'imei' => '123a456b789c'
        ],
        'success_redirect_url' => 'https://success-redirect.url',
        'failure_redirect_url' => 'https://failure-redirect.url',
        'metadata' => [
          'meta' => 'data'
        ],
        'Idempotency-key' => '' . time()
      ];
    
      $createDirectDebitPayment = \Xendit\DirectDebit::createDirectDebitPayment(
        $createDirectDebitPaymentParams
      );
      var_dump($createDirectDebitPayment);
    
    ?>
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { DirectDebit } = x;
    const directDebitSpecificOptions = {};
    const dd = new DirectDebit(directDebitSpecificOptions);
    
    const resp = await dd.createDirectDebitPayment({
      idempotencyKey: 'Test_Idempotent_Key',
      referenceID: 'customer_test_reference_id',
      paymentMethodID: 'pm-c30d4800-afe4-4e58-ad5f-cc006d169139',
      currency: 'IDR',
      amount: 10000,
      callbackURL: 'https://payment-callback-listener/',
      enableOTP: true,
    });
    console.log(resp);
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    metadata := map[string]interface{}{
      "meta": "data",
    }
    
    data := directdebitpayment.CreateDirectDebitPaymentParams{
      ReferenceID:      "test-direct-debit-ref-0100",
      PaymentMethodID:  "pm-ebb1c863-c7b5-4f20-b116-b3071b1d3aef",
      Currency:         "IDR",
      Amount:           15000,
      CallbackURL:      "http://webhook.site/",
      EnableOTP:        true,
      Description:      "test description",
      Basket:           []xendit.DirectDebitBasketItem{
        {
          ReferenceID:  "basket-product-ref-id",
          Name:         "product-name",
          Category:     "mechanics",
          Market:       "ID",
          Price:        50000,
          Quantity:     5,
          Type:         "product type",
          SubCategory:  "product sub category",
          Description:  "product description",
          URL:          "https://product.url",
        },
      },
      Device:           xendit.DirectDebitDevice{
        ID:         "device-id",
        IPAddress:  "0.0.0.0",
        UserAgent:  "user-agent",
        ADID:       "ad-id",
        Imei:       "123a456b789c",
      },
      SuccessRedirectURL: "https://success-redirect.url",
      FailureRedirectURL: "https://failure-redirect.url",
      Metadata:           metadata,
      IdempotencyKey:     time.Now().String(),
    }
    
    resp, err := directdebitpayment.CreateDirectDebitPayment(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("created direct debit payment: %+v\n", resp)
    try {
      Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
      DirectDebitBasketItem basketItem =  DirectDebitBasketItem.builder()
          .referenceId("basket-product-ref-id")
          .name("product-name")
          .category("mechanics")
          .market("ID")
          .price(50000)
          .quantity(5)
          .type("product type")
          .subCategory("product sub category")
          .description("product description")
          .url("https://product.url")
          .build();
      DirectDebitBasketItem[] basketItemArray = new DirectDebitBasketItem[]{basketItem};
    
      DirectDebitDevice device = DirectDebitDevice.builder()
          .id("device-id")
          .ipAddress("0.0.0.0")
          .userAgent("user-agent")
          .adId("ad-id")
          .imei("123a456b789c")
          .build();
    
      Map<String, Object> metadata = new HashMap<>();
      metadata.put("halo", "hello");
      metadata.put("tes", "123");
    
      Map<String, Object> params = new HashMap<>();
      params.put("reference_id", "test-direct-debit-ref-4");
      params.put("payment_method_id", "pm-ebb1c863-c7b5-4f20-b116-b3071b1d3aef");
      params.put("currency", "IDR");
      params.put("amount", 15000);
      params.put("callback_url", "http://webhook.site/");
      params.put("enable_otp", true);
      params.put("description", "test description");
      params.put("basket", basketItemArray);
      params.put("success_redirect_url", "https://success-redirect.url");
      params.put("failure_redirect_url", "https://failure-redirect.url");
      params.put("device", device);
      params.put("metadata", metadata);
    
      String idempotencyKey = "idempotency-key-4";
    
      DirectDebitPayment directDebitPayment = DirectDebitPayment.createDirectDebitPayment(params, idempotencyKey);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    DirectDebit = xendit_instance.DirectDebit
    
    payment = DirectDebit.create_payment(
      reference_id="direct-debit-ref-1594718940",
      payment_method_id="pm-b6116aea-8c23-42d0-a1e6-33227b52fccd",
      currency="IDR",
      amount="60000",
      callback_url="http://webhook.site/",
      enable_otp=True,
      idempotency_key="idemp_key-1594718940",
    )
    
    print(payment)
    Header Type Description
    Idempotency-key
    required
    string Provided by the merchant to prevent duplicate requests. May be equal to any GUID. Note: Max 100 characters
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Request Body Parameter Type Description
    reference_id
    required
    string Merchant-provided identifier for this transaction
    Note: Max 255 characters
    payment_method_id
    required
    string Xendit’s identifier for specific payment method. You can create one using Create Payment Method API if you haven't already generated one. Use Get Payment Method API to retrieve the ID
    currency
    required
    string Currency of amount to debit in ISO 4217. e.g. "IDR", "PHP"
    amount
    required
    number Amount to debit from the end-customer’s account
    Note: Maximum amount that can be charged without OTP is 999,999
    callback_url
    optional
    string URL where payment notification will be sent after transaction process
    Note: Max 255 characters
    enable_otp
    optional
    boolean
    true to charge end customer's account with OTP
    false to charge end customer's account without OTP
    Defaults to true for DC_BRI.
    Not supported for BA_BPI, BA_UBP, and BCA_KLIKPAY.

    Note for BCA OneKlik:
    If set to true, the transaction will require an OTP to be validated regardless of the device object.
    If not provided, it will follow the device object validation logic set by BCA.
    description
    optional
    string Description for the direct debit transaction.
    device
    conditional
    object Required for BCA OneKlik

    Object that contains the end-customer's device fingerprint information. This is used for fraud detection.
    Key Value
    id
    required
    stringThe end-customer's Android or iOS specific unique device identifier.

    If accessed through web, input the string WEB
    ip_address
    required
    stringThe end-customer's IPv4 or IPv6 address at the point of request.
    user_agent
    required
    stringThe end-customer's extracted user-agent string from the device.
    ad_id
    optional
    stringAndroid advertising ID (AAID) or iOS Identifier for Advertisers (IDFA)
    imei
    optional
    stringThe end-customer's device's International Mobile Equipment Identity (IMEI).
    basket
    optional
    array Array of objects describing the item/s purchased using direct debit
    Key Value
    reference_id
    required
    stringMerchant’s identifier for specific product (ie. SKU)
    name
    required
    stringName of product
    market
    required
    string2-letter ISO 3166-2 country code indicating target merchant’s country of operations
    type
    required
    stringType of product
    description
    optional
    stringDescription of product
    category
    optional
    stringMerchant category for item
    sub-category
    optional
    stringMerchant sub-category for item
    price
    optional
    stringPrice per unit in basket currency
    url
    optional
    stringProduct URL with product details
    metadata
    optional
    stringAdditional object that may be used for additional product attributes
    quantity
    optional
    stringNumber of units of this item in the basket
    success_redirect_url
    conditional
    string Required for BCA OneKlik and BCA KlikPay

    The end-customer gets redirected to this URL on successful transaction.
    If OTP is not required and the transaction was successful, the end-customer gets redirected to this immediately.
    failure_redirect_url
    conditional
    string Required for BCA OneKlik and BCA KlikPay

    The end-customer gets redirected to this URL on failed or cancelled transaction.
    If OTP is not required and the transaction fails, the end-customer gets redirected to this after displaying the error message.
    metadata
    optional
    object Object of additional information the user may use. User defines the JSON properties and values. You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long

    Create Payment - Response

    Example Create Payment Success Response

    {
        "id": "ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14",
        "reference_id": "e17a0ac8-6fed-11ea-bc55-0242ac130003",
        "channel_code": "DC_BRI",
        "payment_method_id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
        "currency": "IDR",
        "amount": "10000",
        "description": null,
        "status": "PENDING",
        "basket": null,
        "failure_code": null,
        "is_otp_required": true,
        "otp_mobile_number": "+6287774441111",
        "otp_expiration_timestamp": null,
        "required_action": "VALIDATE_OTP",
        "checkout_url": null,
        "success_redirect_url": null,
        "failure_redirect_url": null, 
        "refunded_amount": null,
        "refunds": null,
        "created": "2020-03-26T05:44:26+0800",
        "updated": null,
        "metadata": null
    }
    Parameter Type Description
    id string Unique identifier for the transaction
    reference_id string Reference ID provided by merchant
    channel_code string Code identifier for the channel
    payment_method_id string Payment method ID of end-customer source of funds
    currency string Currency of the payment
    amount string Amount to debit from the end-customer’s account
    description string Description provided by merchant
    status string Status of the payment - PENDING, COMPLETED, FAILED
    failure_code string Reason if direct debit has failed. List of failure codes can be found here
    is_otp_required boolean The flag for merchant to know whether OTP is required for the particular direct debit transaction
    otp_mobile_number string Masked mobile number of the OTP recipient from the channel. Empty string if OTP was not enabled.
    otp_expiration_timestamp string Timestamp until when the OTP is valid. Empty string if OTP was not enabled.
    required_action string Describes the required action in order to complete the linking.

    If VALIDATE_ON_REDIRECT, the end-customer must be redirected to the provided checkout_url to complete the direct debit payment.

    If VALIDATE_OTP, an OTP will be sent to the end-customer and must be validated through the /direct_debits/:id/validate_otp endpoint to complete the direct debit payment.

    If null, the capture is already in progress.
    checkout_url string If required_action is VALIDATE_ON_REDIRECT, the end-customer must be redirected to this URL in order to complete the payment.

    For BCA OneKlik, this will be the page wherein the end-customer will select their mobile number and input the OTP. The URL will be sent out asynchronously via the Payment Initialized Callback.
    success_redirect_url string Only applicable for BCA OneKlik, BCA KlikPay
    The end-customer gets redirected to this URL on successful transaction.
    failure_redirect_url string Only for BCA OneKlik, BCA KlikPay
    The end-customer gets redirected to this URL on failed transactions.

    The failure_redirect_url will have a failure-code as part of the query string. This describes the reason why the transaction failed. You may use this to dynamically update your failure_redirect_url page based on the failure-code.
    refunded_amount number Amount that was successfully refunded from the transaction.
    refunds object When refunds are made, this will contain information about the refunds done to the transaction. The will have the following properties:

    Key Description
    data array Array of pending, succeeded, and failed refund ids
    Only a maximum of 10 will be returned.
    has_more boolean Value will be true if the number of refund ids are more than 10. Use List of Refunds API to get the list
    url array Make a GET request to this endpoint to get more information about the refunds
    created string Timestamp in ISO 8601 when transaction information was updated
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    updated string Timestamp in ISO 8601 when transaction information was updated
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    basket array Array of basket objects provided by merchant
    metadata object Metadata provided by merchant

    Create Payment - Errors

    Example Create Payment Error Response

    {
        "error_code" : "DUPLICATE_ERROR",
        "message" : "Idempotency key has been used before. Use a unique idempotency key and try again"
    }
    Error Code Description
    DUPLICATE_ERROR
    409
    Idempotency key has been used before. Use a unique idempotency key and try again.
    PAYMENT_METHOD_NOT_FOUND_ERROR
    400
    Provided payment_method_id is invalid, not found or access is unauthorized
    INVALID_PAYMENT_METHOD_ERROR
    400
    The payment method has expired or has been invalidated.
    INSUFFICIENT_BALANCE
    400
    The source payment method doesn't have enough balance to complete the transaction
    ACCOUNT_ACCESS_BLOCKED
    400
    The source account is blocked and cannot be accessed.
    MAX_AMOUNT_LIMIT_ERROR
    400
    The amount for the transaction exceeds the account's aggregated limits set by the partner bank.
    PAYMENT_STATUS_FAILED
    400
    The bank partner was unable to process the transaction successfully due to a timeout or an unexpected error on the bank partner’s end.

    Validate OTP for Direct Debit Payment

    Validate OTP provided by end customer via this endpoint to complete the transaction when OTP is enabled.

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Endpoint: Validate OTP for Direct Debit Payment

    POST https://api.xendit.co/direct_debits/:direct_debit_id/validate_otp/

    Validate Payment OTP - Request

    Example Validate Payment OTP Request

    curl https://api.xendit.co/direct_debits/ddpy-623dca10-5dad-4916-test/validate_otp/ -X GET \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       --data-raw '{
        "otp_code": "111222"
        }'
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $validateOTPForDirectDebitPaymentParams = [
        'otp_code' => '222000'
      ];
    
      $validateOTPForDirectDebitPayment = \Xendit\DirectDebit::validateOTPForDirectDebitPayment(
        'ddpy-7e61b0a7-92f9-4762-a994-c2936306f44c',
        $validateOTPForDirectDebitPaymentParams
      );
      var_dump($validateOTPForDirectDebitPayment);
    
    ?>
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { DirectDebit } = x;
    const directDebitSpecificOptions = {};
    const dd = new DirectDebit(directDebitSpecificOptions);
    
    const resp = await dd.validateOTPforPayment({
      directDebitID: 'ddpy-623dca10-5dad-4916-test',
      otpCode: '111222',
    });
    console.log(resp);
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := directdebitpayment.ValidateOTPForDirectDebitPaymentParams{
      DirectDebitID:  "ddpy-7e61b0a7-92f9-4762-a994-c2936306f44c",
      OTPCode:        "222000",
    }
    
    resp, err := directdebitpayment.ValidateOTPForDirectDebitPayment(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("validated direct debit payment: %+v\n", resp)
    try {
      Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
      Map<String, Object> params = new HashMap<>();
      params.put("otp_code", "222000");
    
      String directDebitPaymentId = "ddpy-b150da90-2121-44a6-a836-5eebf0d7ab55";
    
      DirectDebitPayment directDebitPayment = DirectDebitPayment.validateOTP(directDebitPaymentId, params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    DirectDebit = xendit_instance.DirectDebit
    
    payment = DirectDebit.validate_payment_otp(
        direct_debit_id="ddpy-eaa093b6-b669-401a-ba2e-61ac644b2aff",
        otp_code="222000",
    )
    
    print(payment)
    Path Parameter Type Description
    direct_debit_id
    required
    string Merchant provided identifier for specified direct debit transaction
    Request Body Parameter Type Description
    otp_code
    required
    string One-time-password input from end customer

    Validate Payment OTP - Response

    Will return a successful 200 HTTP response as soon as the bank has validated the OTP, otherwise an error is returned.

    Example Get Payment Status by ID Success Response

    {
        "id": "ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14",
        "reference_id": "e17a0ac8-6fed-11ea-bc55-0242ac130003",
        "channel_code": "BA_BPI",
        "payment_method_id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
        "currency": "PHP",
        "amount": "1000.00",
        "description": "",
        "status": "PENDING",
        "basket": [],
        "failure_code": "",
        "is_otp_required": true,
        "otp_mobile_number": "+63907XXXX123",
        "otp_expiration_timestamp": "2020-03-26T05:45:06+0800",
        "created": "2020-03-26T05:44:26+0800",
        "updated": "2020-03-26T05:44:46+0800",
        "metadata": {}
    }
    Parameter Type Description
    id string Unique identifier for the transaction
    reference_id string Reference ID provided by merchant
    channel_code string Code identifier for the channel
    payment_method_id string Payment method ID of end-customer source of funds
    currency string Currency of the payment
    amount number Amount to debit from the end-customer’s account
    description string Description provided by merchant
    status string Status of the payment
    failure_code string Reason if direct debit has failed. List of failure codes can be found here
    is_otp_required boolean The flag for merchant to know OTP is required for the particular direct debit transaction
    otp_mobile_number string Masked mobile number of the OTP recipient from the channel. Empty string if OTP was not enabled.
    otp_expiration_timestamp string Timestamp until when the OTP is valid. Empty string if OTP was not enabled.
    created string Timestamp in ISO 8601 when the request was madeFormat: YYYY-MM-DDTHH:mm:ssZTimezone: UTC+0
    updated string Timestamp in ISO 8601 when transaction information was updated
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    basket array Array of basket objects provided by merchant
    metadata object Metadata provided by merchant

    Validate Payment OTP - Errors

    Example Create Payment Error Response

    {
        "error_code" : "DUPLICATE_ERROR",
        "message" : "Idempotency key has been used before. Use a unique idempotency key and try again"
    }
    Error Code Description
    DATA_NOT_FOUND_ERROR
    404
    Provided direct_debit_id does not exist
    INVALID_OTP_ERROR
    400
    OTP provided is invalid
    EXPIRED_OTP_ERROR
    400
    OTP provided has expired
    MAX_OTP_ATTEMPTS_ERROR
    400
    Payment method reached the channel’s allowed maximum attempts for OTP verification
    INSUFFICIENT_BALANCE
    400
    The source payment method doesn't have enough balance to complete the transaction
    ACCOUNT_ACCESS_BLOCKED
    400
    The source account is blocked and cannot be accessed.
    MAX_AMOUNT_LIMIT_ERROR
    400
    The amount for the transaction exceeds the account's aggregated limits set by the partner bank.
    DIRECT_DEBIT_ALREADY_COMPLETED
    409
    The request is a duplicate of an already processed linked account token that has been successfully completed.
    DIRECT_DEBIT_ALREADY_FAILED
    409
    The request is a duplicate of an already processed linked account token that has failed.

    Create Recurring Payment with Direct Debit

    Endpoint: Create Recurring Payment

    POST https://api.xendit.co/recurring_payments

    Recurring payments allow you to use the auto debit feature in direct debit to pull funds from your customers bank account on a scheduled basis.

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Request Parameters

    Example: Create Recurring Request

    curl https://api.xendit.co/recurring_payments -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -d external_id=recurring_31451441 \
       -d payment_method_id=pm_testing_id_123\
       -d payer_email=sample_email@xendit.co \
       -d interval=MONTH \
       -d interval_count=1 \
       -d description='Monthly room cleaning service' \
       -d total_recurrence=10\
       -d charge_immediately=true\
       -d invoice_duration=300\
       -d amount=125000
    <?php
      require 'vendor/autoload.php';
    
      $options['secret_api_key'] = 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==';
    
      $xenditPHPClient = new XenditClient\XenditPHPClient($options);
    
      $external_id = 'recurring_31451441';
      $amount = 125000;
      $payment_method_id='pm_testing_id_123';
      $payer_email = 'sample_email@xendit.co';
      $interval = 'MONTH';
      $interval_count = 1;
      $description = 'Monthly room cleaning service';
      $total_recurrence=10;
      $charge_immediately=true;
      $invoice_duration=300;
    
      $response = $xenditPHPClient->createRecurringPayment($external_id, $amount, $payer_email, $interval, $interval_count, $description);
      print_r($response);
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { RecurringPayment } = x;
    const rpSpecificOptions = {};
    const rp = new RecurringPayment(rpSpecificOptions);
    
    const resp = await rp.createPayment({
      externalID: 'recurring_31451441',
      amount: 125000,
      payerEmail: 'sample_email@xendit.co',
      interval: RecurringPayment.Interval.Month,
      intervalCount: 1,
      description: 'Monthly room cleaning service',
      payment_method_id: 'pm_testing_id_123',
      total_recurrence: 10,
      charge_immediately: true,
      invoice_duration: 300
    });
    console.log(resp);
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := recurringpayment.CreateParams{
      ExternalID:    "recurringpayment-" + time.Now().String(),
      Amount:        200000,
      PayerEmail:    "customer@customer.com",
      Description:   "recurringpayment #1",
      Interval:      xendit.RecurringPaymentIntervalDay,
      IntervalCount: 3,
    }
    
    resp, err := recurringpayment.Create(&createData)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("created recurring payment: %+v\n", resp)
    try {
      Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
      Map<String , Object> params = new HashMap<>();
      params.put("external_id", "recurring_31451441");
      params.put("payer_email", "sample_email@xendit.co");
      params.put("interval", "MONTH");
      params.put("interval_count", 1);
      params.put("description", "Test desc");
      params.put("amount", 100000);
      params.put("currency", "IDR");
    
      RecurringPayment recurringPayment = RecurringPayment.create(params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    RecurringPayment = xendit_instance.RecurringPayment
    
    recurring_payment = RecurringPayment.create_recurring_payment(
        external_id="recurring_12345",
        payer_email="test@x.co",
        description="Test Curring Payment",
        amount=100000,
        interval="MONTH",
        interval_count=1,
        payment_method_id="pm_testing_id_123",
    )
    print(recurring_payment)
    Body Parameter Type Description
    external_id
    required
    string ID of your choice (typically the unique identifier of a recurring payment in your system)
    payment_method_id
    optional
    string Fill this with the payment method id created for the customer in create payment method
    payer_email
    required
    string Email of the end user you're charging
    description
    required
    string Description for the recurring payment and invoices
    amount
    required
    number Amount per invoice per interval.
    The minimum amount to create an invoice is 10.000 IDR. The maximum amount is 1.000.000 IDR for direct debit
    interval
    required
    string One of DAY, WEEK, MONTH. The frequency with which a recurring payment invoice should be billed.
    interval_count
    required
    number The number of intervals (specified in the interval property) between recurring. For example, interval=MONTH and interval_count=3 bills every 3 months.
    invoice_duration
    required
    number Set this value to 300 for direct debit recurring to work. Duration of time that end user have in order to pay the invoice before it's expired (in Second).
    total_recurrence
    optional
    number The number of times you will charge your customer. If you input it as 3, Xendit will charge your customer 3 times. If you input total_recurrence as 3, interval_count as 1 and interval as "DAY", Xendit will charge customer 3 times in first day after you trigger create recurring api, the day after and 2 days after you trigger create recurring api.
    should_send_email
    optional
    boolean Specify should the end user get email when invoice is created, paid, or expired; or not
    default: false
    missed_payment_action
    optional
    string One of IGNORE, STOP. If there is an invoice from a recurring payment that expired, IGNORE will continue with the recurring payment as usual. STOP will stop the recurring payment.
    default: IGNORE
    start_date
    optional
    string (ISO 8601) time when the first invoice will be issued. When left blank, the invoice will be created immediately
    charge_immediately
    optional

    boolean Specify should the first invoice created immediately when creating recurring payment with a valid start_date,
    The next invoice will be created at start_date and the calculation for the following recurring invoice will be at
    interval*interval_count + start_date

    Response Parameters

    Example: Create Recurring Response

    {
        "id": "579c8d61f23fa4ca35e52da3",
        "user_id": "5781d19b2e2385880609791c",
        "external_id": "recurring_31451441",
        "status": "ACTIVE",
        "amount": 125000,
        "payer_email": "sample_email@xendit.co",
        "description": "Monthly room cleaning service",
        "interval": "MONTH",
        "interval_count": 1,
        "recurrence_progress": 1,
        "should_send_email": false,
        "missed_payment_action": "IGNORE",
        "last_created_invoice_url": "https://invoice-staging.xendit.co/web/invoices/5dddeea6bdb99f4b23e5eef7",
        "created": "2017-06-12T14:00:00.306Z",
        "updated": "2017-06-12T14:00:00.306Z",
        "start_date": "2017-07-12T14:00:00.306Z",
        "recharge": true,
        "payment_method_id": "pm_testing_id_123"
    }
    Parameter Type Description
    id string An recurring ID generated by Xendit
    user_id string Your Xendit Business ID
    external_id string The recurring ID in your server, that can be used to reconcile between you and Xendit
    status string ACTIVE the recurring payment is currently active
    STOPPED the recurring payment has been stopped
    PAUSED the recurring payment is currently paused and will not automatically creating invoices. resume to reactivate
    amount number Nominal amount of the recurring payment in IDR
    payer_email string Email of the payer, we get this information from your API call
    description string Description for the recurring payment and invoices
    should_send_email boolean A flag showing should payer get email when invoice is created, paid, or expired; or not
    interval string One of DAY, WEEK, MONTH. The frequency with which a recurring payment invoice should be billed.
    interval_count number The number of intervals (specified in the interval property) between recurring. For example, interval=MONTH and interval_count=3 bills every 3 months.
    recurrence_progress number The current cycle of recurring payment. If your end customer is on the 4th cycle of the recurring, you will get 4 from recurrence_progress response
    last_created_invoice_url string url leading to the last invoice create by this recurring payment
    invoice_duration number Ensure that this value is 300duration of time that end user have in order to pay the invoice before it's expired (in Second).
    created string (ISO 8601) An ISO timestamp that tracks when the recurring payment was created. Timezone is UTC+0
    updated string (ISO 8601) An ISO timestamp that tracks when the recurring payment was updated. Timezone is UTC+0
    charge_immediately
    optional

    boolean A flag showing should the first invoice created immediately when creating recurring payment with a valid start_date
    recharge boolean This parameter will be true for direct debit payments.
    payment_method_id string the payment_method_id assigned to this recurring payment

    Error Codes

    Error Code Description
    API_VALIDATION_ERROR
    400
    Inputs are failing validation The errors field contains details about which fields are violating validation
    INVALID_JSON_FORMAT
    400
    The request body is not a valid JSON format
    INVALID_PAYMENT_METHOD_ID_ERROR
    400
    Payment method id is invalid
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here

    Other Recurring Operations

    For post recurring payment creation operations like get, edit, pause, resume, stop - refer to recurring payments

    List Payment Methods

    This endpoint returns an array of payment methods that are linked to the provided customer_id

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Endpoint: Get Payment Methods by Customer ID

    GET https://api.xendit.co/payment_methods?customer_id={customer_id}

    Get Payment Methods by Customer ID - Request

    Example Get Payment Methods by Customer ID Request

    curl https://api.xendit.co/payment_methods?customer_id=ba830b92-4177-476e-b097-2ad5ae4d3e55 -X GET \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: 
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $getPaymentMethods = \Xendit\DirectDebit::getPaymentMethodsByCustomerID('4b7b6050-0830-440a-903b-37d527dbbaa9');
      var_dump($getPaymentMethods);
    
    ?>
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { DirectDebit } = x;
    const directDebitSpecificOptions = {};
    const dd = new DirectDebit(directDebitSpecificOptions);
    
    const resp = await dd.getPaymentMethodsByCustomerID({
      customerID: 'ba830b92-4177-476e-b097-2ad5ae4d3e55',
    });
    console.log(resp);
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := paymentmethod.GetPaymentMethodsByCustomerIDParams{
      CustomerID: "4b7b6050-0830-440a-903b-37d527dbbaa9",
    }
    
    resp, err := paymentmethod.CreatePaymentMethod(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("retrieved payment method: %+v\n", resp)
    try {
      Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
      PaymentMethod[] paymentMethods = PaymentMethod.getPaymentMethodsByCustomerId("4b7b6050-0830-440a-903b-37d527dbbaa9");
      System.out.println(Arrays.toString(paymentMethods));
    } catch (XenditException e) {
      e.printStackTrace();
    }
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    DirectDebit = xendit_instance.DirectDebit
    
    payment_methods = DirectDebit.get_payment_methods_by_customer_id(
        customer_id="ed20b5db-df04-41fc-8018-8ea4ac4d1030",
    )
    
    print(payment_methods)
    Query String Parameter Type Description
    customer_id
    required
    string Customer object ID of interest

    Get Payment Methods by Customer ID - Response

    This endpoint returns an array of matching objects with the following properties:

    Example Get Payment Methods by Customer ID Success Response

    [{    
        "id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
        "type": "DEBIT_CARD",
        "properties": {
            "id": "la-aa620619-124f-41db-995b-66a52abe036a",
            "channel_code": "DC_BRI",
            "currency": "IDR",
            "card_last_four": "1234",
            "card_expiry": "06/24",
            "description": null,
        },
        "customer_id": "ba830b92-4177-476e-b097-2ad5ae4d3e55",
        "status": "ACTIVE",
        "created": "2020-03-19T05:34:55+0800",
        "updated": "2020-03-19T05:24:55+0800",
        "metadata": null  
    }]
    Parameter Type Description
    id string Unique identifier for the payment method. This has a prefix of pm-.
    type string Type of account that has been linked.
    For BRI, BCA OneKlik: DEBIT_CARD
    For BCA KlikPay: BANK_REDIRECT
    For BPI, Unionbank: BANK_ACCOUNT
    properties object Object containing information regarding the account. The values inside properties change based on the type of account:


    For BRI:
    Key Value
    channel_code Identifier for the specific channel of the account to be linked. Code must be in uppercase.

    Supported banks and their respective channel codes:
    • Bank BRI (ID) - DC_BRI
    card_last_four stringLast four digits of the debit card
    card_expiry stringExpiry month and year of the debit card (in MM/YY format)
    currency stringCurrency of the account in ISO 4217
    description stringDescription of the account (provided by the bank)
    For BCA OneKlik:
    Key Value
    channel_code Identifier for the specific channel of the account to be linked. Code must be in uppercase.

    Supported banks and their respective channel codes:
    • BCA OneKlik (ID) - BCA_ONEKLIK
    account_mobile_number stringMobile number of the end-customer registered to the partner channel
    card_last_four stringLast four digits of the debit card
    card_expiry stringExpiry month and year of the debit card (in MM/YY format)
    currency stringCurrency of the account in ISO 4217
    description stringDescription of the account (provided by the bank)
    For type BCA KlikPay:
    Key Value
    channel_code Identifier for the specific channel of the account to be linked. Code must be in uppercase.

    Supported banks and their respective channel codes:
    • BCA KlikPay (PH) - BCA_KLIKPAY
    For type BPI, Unionbank:
    Key Value
    channel_code Identifier for the specific channel of the account to be linked. Code must be in uppercase.

    Supported banks and their respective channel codes:
    • Bank of the Philippine Islands (PH) - BA_BPI
    • Unionbank (PH) - BA_UBP
    account_details stringMasked account details as provided by the bank. Used for displaying a portion of the account number.
    account_hash stringUnique hash for the specific account. This does not change across different authorizations or integrations.
    account_type stringType of bank account (provided by the bank)
    currency stringCurrency of the account in ISO 4217
    description stringDescription of the account (provided by the bank)
    customer_id string ID of the customer object in which this payment method is linked to
    status
    required
    string Status of the payment method.
    Will be equal to ACTIVE upon creation.
    created string Timestamp in ISO 8601 when the request was made
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    updated string Timestamp in ISO 8601 when transaction information was updated
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    metadata object A free-format JSON for additional information that you provded during request.

    Get Payment Methods by Customer ID - Errors

    See other common errors here.

    Get Payment by ID

    Retrieve the details of a direct debit payment by Xendit transaction ID

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Endpoint: Get Payment Status by ID

    GET https://api.xendit.co/direct_debits/:direct_debit_id/

    Get Payment Status by ID - Request

    Example Payment Status by ID Request

    curl https://api.xendit.co/direct_debits/ddpy-623dca10-5dad-4916-test/ -X GET \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: 
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $getDirectDebitPaymentByID = \Xendit\DirectDebit::getDirectDebitPaymentByID(
        'ddpy-7e61b0a7-92f9-4762-a994-c2936306f44c'
      );
      var_dump($getDirectDebitPaymentByID);
    
    ?>
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { DirectDebit } = x;
    const directDebitSpecificOptions = {};
    const dd = new DirectDebit(directDebitSpecificOptions);
    
    const resp = await dd.getDirectDebitPaymentStatusByID({
      directDebitID: 'ddpy-623dca10-5dad-4916-test',
    });
    console.log(resp);
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := directdebitpayment.GetDirectDebitPaymentStatusByIDParams{
      ID: "ddpy-7e61b0a7-92f9-4762-a994-c2936306f44c",
    }
    
    resp, err := directdebitpayment.GetDirectDebitPaymentStatusByIDParams(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("retrieved direct debit payment: %+v\n", resp)
    try {
      Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
      DirectDebitPayment directDebitPayment = DirectDebitPayment.getDirectDebitPaymentStatusById("ddpy-7e61b0a7-92f9-4762-a994-c2936306f44c");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    `
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    DirectDebit = xendit_instance.DirectDebit
    
    payment = DirectDebit.get_payment_status(
        direct_debit_id="ddpy-38ef50a8-00f0-4019-8b28-9bca81f2cbf1",
    )
    
    print(payment)
    Path Parameter Type Description
    direct_debit_id
    required
    string Xendit identifier for specified direct debit transaction

    Get Payment Status by ID - Response

    Example Get Payment Status by ID Success Response

    {
        "id": "ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14",
        "reference_id": "e17a0ac8-6fed-11ea-bc55-0242ac130003",
        "channel_code": "DC_BRI",
        "payment_method_id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
        "currency": "IDR",
        "amount": "10000",
        "description": "",
        "status": "PENDING",
        "basket": [],
        "failure_code": "",
        "is_otp_required": true,
        "otp_mobile_number": "",
        "otp_expiration_timestamp": "",
        "created": "2020-03-26T05:44:26+0800",
        "updated": "",
        "metadata": {}
    }
    Parameter Type Description
    id string Unique identifier for the transaction
    reference_id string Reference ID provided by merchant
    channel_code string Code identifier for the channel
    payment_method_id string Payment method ID of end-customer source of funds
    currency string Currency of the payment
    amount number Amount to debit from the end-customer’s account
    description string Description provided by merchant
    status string Status of the payment
    failure_code string Reason if direct debit has failed. List of failure codes can be found here
    is_otp_required boolean The flag for merchant to know whether OTP is required for the particular direct debit transaction
    otp_mobile_number string Masked mobile number of the OTP recipient from the channel. Empty string if OTP was not enabled.
    otp_expiration_timestamp string Timestamp until when the OTP is valid. Empty string if OTP was not enabled.
    created string Timestamp in ISO 8601 when the request was madeFormat: YYYY-MM-DDTHH:mm:ssZTimezone: UTC+0
    updated string Timestamp in ISO 8601 when transaction information was updated
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    basket array Array of basket objects provided by merchant
    metadata object Metadata provided by merchant

    Get Payment by Reference ID

    Retrieve the details of a direct debit payment by merchant provided transaction ID

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Endpoint: Get Payment Status by Reference ID

    POST https://api.xendit.co/direct_debits?reference_id={reference_id}

    Get Payment Status by Reference ID - Request

    Example Payment Status by Reference ID Request

    curl https://api.xendit.co/direct_debits?reference_id=test_merchant_reference_id/ -X GET \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: 
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $getDirectDebitPaymentByReferenceID = \Xendit\DirectDebit::getDirectDebitPaymentByReferenceID(
        'test-direct-debit-ref'
      );
      var_dump($getDirectDebitPaymentByReferenceID);
    
    ?>
    const x = new require("xendit-node")({
      secretKey:
        "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
    });
    
    const { DirectDebit } = x;
    const directDebitSpecificOptions = {};
    const dd = new DirectDebit(directDebitSpecificOptions);
    
    const resp = await dd.getDirectDebitPaymentStatusByReferenceID({
      referenceID: 'test_merchant_reference_id',
    });
    console.log(resp);
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := directdebitpayment.GetDirectDebitPaymentStatusByReferenceIDParams{
      ReferenceID: "direct-debit-ref-id",
    }
    
    resp, err := directdebitpayment.GetDirectDebitPaymentStatusByReferenceIDParams(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("retrieved direct debit payments: %+v\n", resp)
    try {
      Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
      DirectDebitPayment[] directDebitPayments = DirectDebitPayment.getDirectDebitPaymentStatusByReferenceId("test-direct-debit-ref-4");
      System.out.println(Arrays.toString(directDebitPayments));
    } catch (XenditException e) {
      e.printStackTrace();
    }
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    DirectDebit = xendit_instance.DirectDebit
    
    payments = DirectDebit.get_payment_status_by_ref_id(
        reference_id="direct-debit-ref-1594717458",
    )
    
    print(payments)
    Query String Parameter Type Description
    reference_id
    required
    string Merchant provided identifier for specified direct debit transaction

    Get Payment Status by ID - Response

    Example Get Payment Status by ID Success Response

    {
        "id": "ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14",
        "reference_id": "e17a0ac8-6fed-11ea-bc55-0242ac130003",
        "channel_code": "DC_BRI",
        "payment_method_id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
        "currency": "IDR",
        "amount": "10000",
        "description": "",
        "status": "PENDING",
        "basket": [],
        "failure_code": "",
        "is_otp_required": true,
        "otp_mobile_number": "",
        "otp_expiration_timestamp": "",
        "created": "2020-03-26T05:44:26+0800",
        "updated": "",
        "metadata": {}
    }
    Parameter Type Description
    id string Unique identifier for the transaction
    reference_id string Reference ID provided by merchant
    channel_code string Code identifier for the channel
    payment_method_id string Payment method ID of end-customer source of funds
    currency string Currency of the payment
    amount number Amount to debit from the end-customer’s account
    description string Description provided by merchant
    status string Status of the payment
    failure_code string Reason if direct debit has failed. List of failure codes can be found here
    is_otp_required boolean The flag for merchant to know whether OTP is required for the particular direct debit transaction
    otp_mobile_number string Masked mobile number of the OTP recipient from the channel. Empty string if OTP was not enabled.
    otp_expiration_timestamp string Timestamp until when the OTP is valid. Empty string if OTP was not enabled.
    created string Timestamp in ISO 8601 when the request was madeFormat: YYYY-MM-DDTHH:mm:ssZTimezone: UTC+0
    updated string Timestamp in ISO 8601 when transaction information was updated
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    basket array Array of basket objects provided by merchant
    metadata object Metadata provided by merchant

    Refund Object

    Refund API allows you to fully or partially refund a successfully completed direct debit payment. It is possible to do multiple refunds for a single transaction as long as the amount does not exceed the original transaction amount.

    A callback will be sent when a refund has been determined to have succeeded or failed.

    Note: Transaction fees will not be refunded.

    Example Refund a Direct Debit Payment Success Response

    {
        "id": "ddrfd-c3970211-f73a-49c4-a3e5-7e93ea49b85f",
        "direct_debit_id": "ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14",
        "channel_code": "DC_BRI",
        "currency": "IDR",
        "amount": "1500",
        "status": "PENDING",
        "reason": "REQUESTED_BY_CUSTOMER",
        "failure_code": null,
        "created": "2020-03-26T05:44:26+0800",
        "updated": null,
        "metadata": null
    }

    Parameter Type Description
    id string Unique identifier for the refund. Starts with ddrfd-
    direct_debit_id string ID of the original payment transaction.
    channel_code string Code identifier for the channel
    currency string Currency of the refund in ISO4217 format
    amount string Amount to be refunded
    status string Status of the refund - PENDING, COMPLETED, FAILED
    reason string Reason why refund was made

    Possible values:
    • FRAUDULENT
    • DUPLICATE
    • REQUESTED_BY_CUSTOMER
    • CANCELLATION
    • OTHER
    failure_code string Contains an error code if refund fails. null by default. See possible failure codes here.
    created string Timestamp in ISO 8601 when transaction information was updated
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    updated string Timestamp in ISO 8601 when transaction information was updated
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    metadata object Metadata provided by merchant

    Refund a Direct Debit Payment - Failure Codes

    Failure Code Description
    REFUND_FAILED
    The bank was unable to process the refund successfully
    ACCOUNT_ACCESS_BLOCKED
    Access to the bank account has been blocked by the bank. The bank account may be frozen, closed, or blocked.
    ACCOUNT_NOT_FOUND
    Refund failed because bank account find the bank account
    INSUFFICIENT_BALANCE
    Source bank account does not have enough balance to perform a refund.

    Create Refund

    This API will allow you to refund BRI Direct Debit transactions in Indonesia through Xendit. Currently, only full refunds are allowed.

    It will accept information such as direct_debit_id and an optional reason for refunds, and will produce PENDING status in the response. PENDING status represents that the refunds is being processed by the bank.

    A webhook or callback will be sent to your system after the payment has SUCCEEDED or FAILED.

    Endpoint: Refund a Direct Debit Payment

    POST https://api.xendit.co/direct_debits/:direct_debit_id/refunds

    Request Parameters

    Example Refund a Direct Debit Payment Request

    curl https://api.xendit.co/direct_debits/ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14/refunds -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -H 'Content-Type: application/json' \
       -H 'Idempotency-key: Test_Idempotent_Key'\
       --data-raw '{
        "currency": "IDR",
        "amount": 1500,
        "reason": "REQUESTED_BY_CUSTOMER"
    }'
    <?php
      $url = "https://api.xendit.co/direct_debits/ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14/refunds";
      $apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
      $headers = $headers = [
        "Content-Type: application/json",
        "Idempotency-key: Test_Idempotent_Key",
        ];
      $data = [
        "currency" => "IDR",
        "amount" => 1500,
        "reason" => "REQUESTED_BY_CUSTOMER",
        ];
    
      $curl = curl_init();
    
      $payload = json_encode($data);
      curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
      curl_setopt($curl, CURLOPT_USERPWD, $apiKey.":");
      curl_setopt($curl, CURLOPT_URL, $url);
      curl_setopt($curl, CURLOPT_POST, true);
      curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    
      $result = curl_exec($curl);
      echo $result;
    Path Parameter Type Description
    direct_debit_id
    required
    string Xendit identifier for specified direct debit transaction
    Header Parameter Type Description
    Idempotency-key
    required
    string Provided by the merchant to prevent duplicate requests. May be equal to any GUID. Note: Max 100 characters
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Request Body Parameter Type Description
    reason
    required
    string Reason why refund is made

    Accepted values:
    • FRAUDULENT
    • DUPLICATE
    • REQUESTED_BY_CUSTOMER
    • CANCELLATION
    • OTHER
    amount
    optional
    number Amount to be refunded
    If none is provided, it will default to the maximum possible amount to be refunded
    currency
    optional
    string Currency of the refund. Should be in ISO4217 format.
    If none is provided, it will follow the currency of the direct debit transaction.
    Only supports IDR
    metadata
    optional
    object Object of additional information the user may use. User defines the JSON properties and values. You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long

    Response Parameters

    Returns Refund Object with status code 200

    Errors

    Example Refund a Direct Debit Payment Error Response

    {
        "error_code" : "IDEMPOTENCY_ERROR",
        "message" : "Idempotency key has been used before. Use a unique idempotency key and try again"
    }
    Error Code Description
    IDEMPOTENCY_ERROR
    409
    Provided Idempotency-key already exists but the request body provided does not match the original request
    DATA_NOT_FOUND
    404
    We couldn’t find a valid payment matching the payment id given.
    MAXIMUM_REFUND_AMOUNT_REACHED
    400
    The refund amount you have entered is greater than the refundable amount.
    REFUND_NOT_SUPPORTED
    400
    Refund request failed because refunds are not supported by the channel.
    INELIGIBLE_TRANSACTION
    400
    Refund request failed because the original transaction was not completed successfully or the refund period has passed.
    PARTIAL_REFUND_NOT_SUPPORTED
    400
    Refund request failed because partial refunds are not supported by the channel
    INSUFFICIENT_BALANCE
    400
    Xendit balance is not enough to perform a refund

    Get Refund by ID

    You may use this endpoint to retrieve information regarding a specific refund request by its refund ID.

    Endpoint: Get Direct Debit Refund by ID

    GET https://api.xendit.co/direct_debits/:direct_debit_id/refunds/:refund_id

    Request Parameters

    Example Get Direct Debit Refund by ID Request

    curl https://api.xendit.co/direct_debits/ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14/refunds/ddrfd-c3970211-f73a-49c4-a3e5-7e93ea49b85f -X GET \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
    }'
    <?php
      $direct_debit_id = "ddpy-623dca10-5dad-4916-test";
      $refund_id = "ddrfd-c3970211-f73a-49c4-a3e5-7e93ea49b85f";
      $url = "https://api.xendit.co/direct_debits/" . $direct_debit_id . "/refunds" . $refund_id;
      $apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
      $headers = [];
      $headers[] = "Content-Type: application/json";
    
      $curl = curl_init();
    
      $payload = json_encode($data);
      curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
      curl_setopt($curl, CURLOPT_USERPWD, $apiKey.":");
      curl_setopt($curl, CURLOPT_URL, $url);
      curl_setopt($curl, CURLOPT_POST, true);
      curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    
      $result = curl_exec($curl);
      echo $result;
    Path Parameter Type Description
    direct_debit_id
    required
    string Xendit identifier for specified direct debit transaction. Starts with ddpy-.
    refund_id
    required
    string Unique identifier for the refund generated by Xendit. Starts with ddrfd-.

    Response Parameters

    Returns Refund Object with status code 200

    Errors

    Example Get Direct Debit Refund by ID Error Response

    {
        "error_code" : "DATA_NOT_FOUND",
        "message" : "We couldn’t find a valid payment matching the payment id given."
    }
    Error Code Description
    DATA_NOT_FOUND
    404
    We couldn’t find a valid payment matching the payment id given.

    List Refunds

    You may use this endpoint to retrieve all associated refund requests for a specific direct debit payment.

    Endpoint: List Refunds by Direct Debit ID

    GET https://api.xendit.co/direct_debits/:direct_debit_id/refunds

    Request Parameters

    Example List Refunds by Direct Debit ID Request

    curl https://api.xendit.co/direct_debits/ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14/refunds -X GET \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
    }'
    <?php
      $direct_debit_id = "ddpy-623dca10-5dad-4916-test";
      $url = "https://api.xendit.co/direct_debits/" . $direct_debit_id . "/refunds";
      $apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
      $headers = [];
      $headers[] = "Content-Type: application/json";
    
      $curl = curl_init();
    
      $payload = json_encode($data);
      curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
      curl_setopt($curl, CURLOPT_USERPWD, $apiKey.":");
      curl_setopt($curl, CURLOPT_URL, $url);
      curl_setopt($curl, CURLOPT_POST, true);
      curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    
      $result = curl_exec($curl);
      echo $result;
    Path Parameter Type Description
    direct_debit_id
    required
    string Xendit identifier for specified direct debit transaction. Starts with ddpy-.

    List Refunds by Direct Debit ID - Response

    Example List Refunds by Direct Debit ID Success Response

    [
        {
            "data": [
                {
                    "id": "ddrfd-c3970211-f73a-49c4-a3e5-7e93ea49b85f",
                    "direct_debit_id": "ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14",
                    "channel_code": "DC_BRI",
                    "currency": "IDR",
                    "amount": "1500",
                    "status": "PENDING",
                    "failure_code": null,
                    "reason": "REQUESTED_BY_CUSTOMER",
                    "created": "2020-03-26T05:44:26+0800",
                    "updated": null,
                    "metadata": null
                }
            ],
            "has_more": false,
            "links": null
        }
    ]
    Parameter Type Description
    data array Array containing refund object that matches the query provided
    has_more boolean Indicates whether there are more items to be queried with last_id of the last item from the current result.
    links object Array of objects containing target links to access the rest of the data. Will be null if there is no further data available.

    Each object will have the following properties:
    Parameter Description
    href string Representation of link that contains the next set of data
    ref string The link relation type describes how the current data is related to the target href.
    Only next is supported.
    method string HTTP method to be used to call the href. Only GET is supported.

    List Refunds by Direct Debit ID - Errors

    Example List Refunds by Direct Debit ID Error Response

    {
        "error_code" : "DATA_NOT_FOUND",
        "message" : "We couldn’t find a valid payment matching the payment id given."
    }
    Error Code Description
    DATA_NOT_FOUND
    404
    We couldn’t find a valid payment matching the payment id given.

    Callback Notifications

    In our direct debit flow, there are up to 2 types of callbacks that could be sent. We will send callback to your system during Linked Account Tokenization and Direct Debit Payment process. Merchants need to set up URL to receive callback notifications from our system.

    Linked Account Tokenization Callback

    Linked Account Tokenization callback is only supported for BPI, Unionbank, and BCA OneKlik. Merchants can skip this flow if they are only integrating for BRI Direct Debit.

    Example: Linked Account Tokenization Callback Payload (BCA OneKlik)

    {
        "event": "linked_account_token.successful",
        "timestamp": "2020-03-19T05:34:55+0800",
        "id": "lat-aa620619-4177-476e-b097-2ad5ae4d3e55",
        "channel_code": "BCA_ONEKLIK",
        "type": "DEBIT_CARD",
        "accounts": [
            {
                "id": "la-aa620619-124f-41db-995b-66a52abe036a",
                "card_last_four": "1234",
                "card_expiry": "06/24",
                "account_mobile_number": "+62818555988",
                "currency": "IDR",
                "description": null
            }
        ]
    }

    Example: Linked Account Tokenization Callback Payload (BPI)

    {
        "event": "linked_account_token.successful",
        "timestamp": "2020-03-27T05:45:06+0800",
        "id": "lat-aa620619-124f-41db-995b-66a52abe036a",
        "channel_code": "BA_BPI",
        "type": "BANK_ACCOUNT",
        "accounts": [
            {
                "id": "la-7f2bc3ad-8049-42ff-8b57-6578088e9641",
                "account_details": "XXXXXXX123",
                "account_hash": "5789fb5c4b051701928af5ac268c8178",
                "currency": "PHP",
                "account_type": "SAVINGS",
                "description": null
            }
        ]
    }
    Parameter Type Description
    event string Identifier of the event - "linked_account_token.successful"
    timestamp string ISO 8601 timestamp of the event. Timezone is UTC+0
    id string Unique identifier for the Linked Account Tokenization. This has a prefix of lat-.
    channel_code string Code identifier for the channel
    type string Payment method type. Possible values: DEBIT_CARD, BANK_ACCOUNT
    accounts array An array of objects containing bank account informations linked to the authorization.

    For BCA OneKlik:
    Key Value
    id string Unique identifier for bank account specific to this object. This has a prefix of la-.
    card_last_four string Last four digits of the linked debit card
    card_expiry string Will be null for BCA OneKlik
    account_mobile_number string Masked mobile number registered with the bank.
    currency string Currency of the account in ISO 4217
    description string Description of the account (provided by the bank)
    For BPI and Unionbank:
    Key Value
    id string Unique identifier for bank account specific to this object. This has a prefix of la-.
    account_details string Masked account details as provided by the bank. Used for displaying a portion of the account number.
    account_hash string Unique hash for the specific account. This does not change across different authorizations or integrations, providing a consistent reference to end user bank account through rounds of renewal.
    currency string Currency of the account in ISO 4217
    account_type string Type of bank account (provided by the bank)
    description string Description of the account (provided by the bank)

    Expiring Payment Method Callback

    This callback will be sent if the currently linked payment method object is discovered to be invalidated in 7 days. When received, you may notify your user to relink. This is only supported for BPI and Unionbank.

    Example: Expiring Payment Method Callback

    {
        "event": "payment_method.expiry.expiring",
        "timestamp": "2020-03-26T05:44:26+0800",
        "id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
        "channel_code": "BA_BPI",
        "customer_id": "e17a0ac8-6fed-11ea-bc55-0242ac130003",
        "expiration_timestamp": "2021-03-26T05:44:26+0800",
        "business_id": "5f21361959ef2b788cbbe97f"
    }
    Parameter Type Description
    event string Identifier of the event - payment_method.expiry.expiring
    timestamp string ISO 8601 timestamp of the event. Timezone is UTC+0
    id string Unique identifier for the transaction. Will have pm- as prefix.
    channel_code string Code identifier for the channel
    expiration_timestamp string ISO 8601 timestamp of when the payment method will be expired.
    customer_id string ID of the customer object that owns the payment method object
    business_id string Xendit-internal business ID identifying the merchant

    Expired Payment Method Callback

    This will be sent when a specific payment method has expired or has been invalidated. You may use this to notify your customers to relink. This feature is only supported for BPI and Unionbank.

    Example: Expired Payment Method Callback

    {
        "event": "payment_method.expiry.expired",
        "timestamp": "2020-03-26T05:44:26+0800",
        "id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
        "customer_id": "e17a0ac8-6fed-11ea-bc55-0242ac130003",
        "business_id": "5f21361959ef2b788cbbe97f"
    }
    Parameter Type Description
    event string Identifier of the event - payment_method.expiry.expired
    timestamp string ISO 8601 timestamp of the event. Timezone is UTC+0
    id string Unique identifier for the transaction. Will have pm- as prefix.
    customer_id string ID of the customer object that owns the payment method object
    business_id string Xendit-internal business ID identifying the merchant

    Direct Debit Payment Callback

    Example: Direct Debit Payment Callback

    {
        "event": "direct_debit.payment",
        "timestamp": "2020-03-26T05:44:26+0800",
        "id": "ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14",
        "reference_id": "e17a0ac8-6fed-11ea-bc55-0242ac130003",
        "channel_code": "BA_BPI",
        "payment_method_id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
        "currency": "PHP",
        "amount": "1000.00",
        "description": null,
        "status": "COMPLETED",
        "failure_code": null,
        "metadata": null
    }
    Parameter Type Description
    event string Identifier of the event - "direct_debit.payment"
    timestamp string ISO 8601 timestamp of the event. Timezone is UTC+0
    id string Unique identifier for the transaction
    reference_id string Reference ID provided by merchant
    channel_code string Code identifier for the channel
    payment_method_id string Payment method ID of end-customer source of funds
    currency string Currency of the payment
    amount number Amount to debited from the end-customer’s account
    description string Description provided by merchant
    status string Status of the payment - PENDING, COMPLETED, FAILED
    failure_code string Reason if direct debit has failed. List of failure codes can be found here
    metadata object Metadata provided by merchant

    Payment Failure Reasons

    Example: Payment Status Failure Examples

    {
        "event": "direct_debit.payment",
        "timestamp": "2020-03-26T05:44:26+0800",
        "id": "ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14",
        "reference_id": "e17a0ac8-6fed-11ea-bc55-0242ac130003",
        "channel_code": "BA_BPI",
        "payment_method_id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
        "currency": "PHP",
        "amount": 1000.00,
        "description": "",
        "status": "FAILED",
        "failure_code": "INSUFFICIENT_BALANCE",
        "metadata": {}
    }
    Failure Code Description
    MAX_AMOUNT_LIMIT_ERROR
    End customer's daily limit has been reached, unable to process debit request. End user required to increase daily limit or retry another day
    INSUFFICIENT_BALANCE
    End customer has insufficient balance, unable to process debit request. End user required to top up balance
    CHANNEL_UNAVAILABLE
    Bank service for direct debit is currently unavailable, unable to process debit request.
    ACCOUNT_ACCESS_BLOCKED
    End customer bank account has been blocked, end user should contact the bank for resolution.
    MAX_OTP_ATTEMPTS_ERROR
    The transaction has been failed because the maximum attempts for validating the OTP has been reached.
    INVALID_PAYMENT_METHOD_ERROR
    The payment_method_id provided either does not exist or has already expired.
    SERVER_ERROR
    There was an unexpected error while processing with the bank.

    Recurring Payment Callback

    {
      "id": "5ebd6test32631dda4ef73",
      "external_id": "testing_123_123-1589472179990",
      "user_id": "5ebd26b7da0bf912db2fc716",
      "is_high": false,
      "payment_method": "DIRECT_DEBIT",
      "status": "PAID",
      "merchant_name": "Live Validation Test 2",
      "amount": 15000,
      "paid_amount": 15000,
      "paid_at": "2020-05-14T16:03:00.504Z",
      "payer_email": "test@xendit.co",
      "description": "description",
      "adjusted_received_amount": 15000,
      "fees_paid_amount": 0,
      "created": "2020-05-14T16:03:00.154Z",
      "updated": "2020-05-14T16:03:02.765Z",
      "recurring_payment_id": "5ebd6bb37d674631dda4ef72",
      "currency": "IDR",
      "payment_channel": "DC_BRI"
    }
    Parameter Type Description
    id string An invoice ID generated by Xendit
    user_id string Your Xendit Business ID
    external_id string The reference ID used to generate the recurring payment. This can be used to reconcile between you and Xendit
    is_high (DEPRECATED) boolean Should unique numbers go above or below the amount.
    merchant_name string The name of your company or website
    amount number Nominal amount for the invoice (without taxes, fees)
    status string PAID the recurring direct debit has successfully been paid or
    EXPIRED the recurring direct debit has failed
    payer_email string Email of the payer, we get this information from your API call
    description string Description for the invoice, we get this information from your API call
    fees_paid_amount number Xendit fees that was directly paid from this invoice - thanks for supporting a better world of payments :)
    adjusted_received_amount number Amount attributable to you net of our fees.
    recurring_payment_id string ID of the recurring that created this invoice
    paid_amount number Total amount paid for the invoice
    updated string (ISO 8601) An ISO timestamp that tracks when the invoice was updated. Timezone is UTC+0
    created string (ISO 8601) An ISO timestamp that tracks when the invoice was created. Timezone is UTC+0
    currency string (ISO 4217) Currency of the amount that you created.
    paid_at string (ISO 8601) Date time data when your customer pay the invoice. You will get this response when your invoice is paid
    payment_method string Payment method that is used when a customer pays the invoice. You will get this response when your invoice is paid - DIRECT_DEBIT
    payment_channel string The payment channel used when a customer pays the invoice. You will get this response when your invoice is paid
    Example : DC_BRI

    Direct Debit Refund Callback

    Example: Direct Debit Refund Callback

    {
        "event": "“direct_debit.refund",
        "created": "2020-03-26T05:44:26+0800",
        "business_id": "5f21361959ef2b788cbbe97f",
        "data": {
            "id": "ddrfd-c3970211-f73a-49c4-a3e5-7e93ea49b85f",
            "direct_debit_id": "ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14",
            "channel_code": "DC_BRI",
            "currency": "IDR",
            "amount": "1500",
            "status": "COMPLETED",
            "failure_code": null,
            "reason": "REQUESTED_BY_CUSTOMER",
            "created": "2020-03-26T05:44:26+0800",
            "updated": null,
            "metadata": null
        }
    }


    Parameter Type Description
    event string Identifier of the event - "direct_debit.refund"
    created string ISO 8601 timestamp of when the event was created. Timezone is UTC+0
    busines_id string Xendit-internal business ID identifying the merchant
    data object Returns Refund Object with status COMPLETED or FAILED

    Virtual Accounts

    Virtual Accounts are virtual bank accounts that can be created and assigned to your customers and act as medium to receive payments where your customers will pay via Bank Transfer.

    You have 2 environments to try and use Virtual Account APIs: TEST mode and LIVE mode. In TEST mode, Virtual Account is ready and available for you to integrate. For LIVE mode, activate Virtual Account in Dashboard to start using your preferred Virtual Account. Read more about virtual accounts.

    Looking for your virtual accounts to be tied to a transaction rather than a user? Use our invoices API.

    Virtual Account Object

    Example of Virtual Account Object

    {
      "id": "57f6fbf26b9f064272622aa6",
      "external_id": "va-1475804036622",
      "owner_id": "57b4e5181473eeb61c11f9b9",
      "bank_code": "BRI",
      "merchant_code": "26215",
      "account_number": "262159939380502",
      "name": "Michael Chen",
      "currency": "IDR",
      "is_single_use": true,
      "is_closed": true,
      "expected_amount": 50000,
      "suggested_amount": 50000,
      "expiration_date": "2021-09-27T17:00:00.000Z",
      "description": "Utensils Payment 27 September 2021",
      "status": "PENDING"
    }
    Parameter Type Description
    id
    required
    string Unique Xendit ID for the Virtual Account. Use this ID for support escalation and reconciliation. Can be used to link VA to Invoice using create Invoices API
    external_id
    required
    string An ID of your choice which you provided upon request
    owner_id
    required
    string Your Xendit Business ID
    bank_code
    required
    string Bank code for the relevant bank,
    Available values: BCA, BNI, BRI, BJB, CIMB, MANDIRI, PERMATA, SAHABAT_SAMPOERNA
    merchant_code
    required
    string Prefix for the Virtual Account. This is Xendit's merchant code for aggregator model or your merchant code retrieved from bank for switcher model. Learn more about Virtual Account models here
    account_number
    required
    string Complete Virtual Account number (including merchant code as prefix). This is what a user will use to pay Virtual Account
    name
    required
    string Name for the Virtual Account
    currency
    required
    string The currency in which the Virtual Account operates. Available for API version 2018-12-21
    is_single_use
    required
    boolean There are 2 types of Virtual Account:
  • Single-use Virtual Account will be inactive automatically upon successful payment.
  • Multiple-use Virtual Account (is_single_use: false) remain active upon successful payment and can continue to receive payments using the same Virtual Account
  • is_closed
    required
    boolean There are 2 types of Virtual Account amount: open or closed amount
  • Open amount means your customer can pay any amount to the Virtual Account
  • Closed amount means your customer can only pay amount specified by you. Payment will be rejected if attempted payment amount deviates from the amount you specified. Specify the amount using expected_amount parameter below
  • expected_amount
    optional
    number Required amount to be paid by your customer for closed Virtual Account
    suggested_amount
    optional
    number Suggested amount for the Virtual Account. Only supported for Mandiri and BRI Virtual Account
    expiration_date
    optional
    string ISO8601 timestamp of Virtual Account expiration time. Timezone UTC+0
    description
    optional
    string Description of the Virtual Account that will be displayed in payment interface. Only supported for BRI Virtual Account
    status
    required
    string Status of Virtual Account that defines if it’s PENDING, INACTIVE, or ACTIVE
  • Status is PENDING if Virtual Account creation request has been sent and request is being processed by the bank
  • Status is INACTIVE either the single use Virtual Account has been paid or already expired
  • If status is ACTIVE the Virtual Account is ready to be used by the end user
  • Virtual Account Payment Object

    Example Virtual Account Payment Object

    {
        "id": "598d91b1191029596846047f",
        "payment_id": "5f218745736e619164dc8608",
        "callback_virtual_account_id": "598d5f71bf64853820c49a18",
        "external_id": "demo-1502437214715",
        "bank_code": "BNI",
        "merchant_code": "8808",
        "account_number": "8808999939380502",
        "amount": 50000,
        "transaction_timestamp": "2021-07-24T05:22:55.115Z",
        "sender_name": "Michael Chen"
    }
    Parameter Type Description
    id
    required
    string ID of the Virtual Account Payment. Use this ID for support escalation and reconciliation
    payment_id
    required
    string Our internal system’s payment ID
    callback_virtual_account_id
    required
    string ID of the Virtual Account that was paid
    external_id
    required
    string External ID of the Virtual Account
    bank_code
    required
    string Bank code of the Virtual Account
    merchant_code
    required
    string Virtual Account merchant code identified via the first 4-5 digits of Virtual Account number
    account_number
    required
    string Virtual Account number
    amount
    required
    integer positive Amount that was paid to the Virtual Account
    transaction_timestamp
    required
    string Date time of the Virtual Account transaction
    sender_name
    string Name of the end user that paid into the Virtual Account. This field is only supported for Sahabat Sampoerna Virtual Accounts.

    Create Virtual Account

    Endpoint: Create Virtual Account

    POST https://api.xendit.co/callback_virtual_accounts

    Request Parameters

    Example Create Virtual Accounts Request

    curl https://api.xendit.co/callback_virtual_accounts -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -d external_id=demo_virtual_account_1475459775872 \
       -d bank_code=BNI \
       -d name='Michael Chen'
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $params = [ 
        "external_id" => "va-1475804036622",
        "bank_code" => "BNI",
        "name" => "Michael Chen"
      ];
    
      $createVA = \Xendit\VirtualAccounts::create($params);
      var_dump($createVA);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { VirtualAcc } = x;
    const vaSpecificOptions = {};
    const va = new VirtualAcc(vaSpecificOptions);
    
    const resp = await va.createFixedVA({
      externalID: 'va-1475804036622',
      bankCode: 'BNI',
      name: 'Michael Chen',
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Map<String, Object> params = new HashMap<>();
      params.put("external_id", "demo_virtual_account_1475459775872");
      params.put("bank_code", BankCode.BNI.getText());
      params.put("expected_amount", 100000);
      params.put("name", "Michael Chen");
    
      //For closed virtual account
      FixedVirtualAccount closedVirtualAccount = FixedVirtualAccount.createClosed(params);
    
      //For open virtual account
      FixedVirtualAccount openVirtualAccount = FixedVirtualAccount.createOpen(params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := virtualaccount.CreateFixedVAParams{
      ExternalID: "va-1475804036622",
      BankCode:   "BNI",
      Name:       "Michael Chen",
    }
    
    resp, err := virtualaccount.CreateFixedVA(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("created fixed va: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    VirtualAccount = xendit_instance.VirtualAccount
    
    virtual_account = VirtualAccount.create(
        external_id="va-1475804036622",
        bank_code="BNI",
        name="Michael Chen",
    )
    print(virtual_account)

    Example Request of BNI Open VA

    {
       "external_id": "va-1475804036622",
       "bank_code": "BNI",
       "name": "Michael Chen"
    }

    Example Request of BRI Closed VA

    {
      "external_id": "va-1475804036622",
      "bank_code": "BRI",
      "name": "Michael Chen",
      "is_closed": true,
      "expected_amount": 50000,
      "expiration_date": "2021-09-27T17:00:00.000Z"
    }
    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    with-fee-rule
    optional
    string Fee Rule ID that you would like to apply to payments coming into this VA

    Please note: If you include this parameter, we will return the fee_rule_id and the fee_id in the header of the API response. Currently supports is_closed, is_single_use VA only

    This header is only used if you have access to xenPlatform. See xenPlatform for more information
    Body Parameter Type Description
    external_id
    required
    string An ID of your choice. Often it is unique identifier like a phone number, email or transaction ID
    Note: External IDs cannot be changed once set

    Characters: Special and alphanumeric
    Minimum character: 1 character
    Maximum characters: 950 characters
    bank_code
    required
    string Bank code of the virtual account you want to create
    Note: We recommend you to create BNI Virtual Account for interbank transfers for higher success rate

    Available bank codes: BCA, BNI, BRI, BJB, CIMB, MANDIRI, PERMATA, SAHABAT_SAMPOERNA
    name
    required
    string Name of user/virtual account, - this will be displayed in the bank's user interface, e.g. ATM confirmation screens. Note that this field can only contain letters and spaces and has length restriction depending on the banks. And also cannot contains name from bank/institution/government.

    Characters Only alphabet
    Minimum length 1 character, except BCA the minimum length is 3 characters
    Note: BNI VA name will be included a prefix "XDT-" in the response. This prefix is mandatory from BNI.
    virtual_account_number
    optional. default: random
    string You can assign specific Virtual Account number using this parameter. If you do not send one, one will be picked at random.

    Make sure the number you specify is within your Virtual Account range. Check your Virtual Account range in Virtual Account Settings. API will throw error if you include merchant code (first 4 or 5 digits of your VA range, ie 26215 for BRI).

    Example: If your BRI Virtual Account range: 26215 9999000001 - 26215 9999999999, request virtual_account_number: 9999100101 will be accepted as the value is within VA range, while virtual_account_number: 262159999100101 will throw VIRTUAL_ACCOUNT_NUMBER_OUTSIDE_RANGE

    Note: Your VA range in TEST and LIVE mode might be different. When going live, double check and adjust your request to follow the respective VA range
    is_single_use
    optional. default: false
    boolean There are 2 types of Virtual Account: single-use and multiple-use Virtual Account
  • Single-use Virtual Account (is_single_use: true) can only be paid once. Used VA number can be recreated for other customer/invoice/transaction
  • Multiple-use Virtual Account (is_single_use: false) allows your customer to pay to the same Virtual Account continuously
  • is_closed
    optional. default: false
    boolean There are 2 types of Virtual Account amount: open or closed amount
  • Open amount means your customer can pay any amount to the Virtual Account
  • Closed amount means your customer can only pay amount specified by you. Payment will be rejected if attempted payment amount deviates from the amount you specified. Specify the amount using expected_amount parameter below
  • expected_amount
    optional
    number Required amount to be paid by your customer for closed Virtual Account. For MANDIRI, BNI, and BRI:
  • Minimum amount: Rp 1
  • Maximum amount: Rp 50,000,000,000
  • suggested_amount
    optional
    number The suggested amount you want to assign
    Note: Suggested amounts is the amounts that can see as a suggestion, but user can still put any numbers (only supported for Mandiri and BRI)

    expiration_date
    optional. default: +31 years from creation date
    string ISO8601 timestamp of Virtual Account expiration time

    Timezone: UTC+0
    description
    optional
    string Description for the Virtual Account. Only BRI supports this feature

    Characters Special and alphanumeric
    Minimum length 1 character

    Response Parameters

    Example of BNI Open VA Response

    {
      "id": "57f6fbf26b9f064272622aa6",
      "external_id": "va-1475804036622",
      "owner_id": "57b4e5181473eeb61c11f9b9",
      "bank_code": "BNI",
      "merchant_code": "8808",
      "account_number": "8808999939380502",
      "name": "Michael Chen",
      "currency": "IDR",
      "is_single_use": false,
      "is_closed": false,
      "expiration_date": "2051-09-27T17:00:00.000Z",
      "status": "PENDING"
    }

    Example of BRI Single Use Close VA Response

    {
      "id": "57f6fbf26b9f064272622aa6",
      "external_id": "va-1475804036622",
      "owner_id": "57b4e5181473eeb61c11f9b9",
      "bank_code": "BRI",
      "merchant_code": "26215",
      "account_number": "262159939380502",
      "name": "Michael Chen",
      "currency": "IDR",
      "is_single_use": true,
      "is_closed": true,
      "expected_amount": 50000,
      "suggested_amount": 50000,
      "expiration_date": "2021-09-27T17:00:00.000Z",
      "description": "Utensils Payment 27 September 2021",
      "status": "PENDING"
    }

    Returns Virtual Account Object with status 200

    Error Codes

    Example of Error Message

    {
        "error_code": "BANK_NOT_SUPPORTED_ERROR",
        "message": "That bank code is not currently supported. Use Get Virtual Account Banks API to check available banks"
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    INVALID_JSON_FORMAT
    400
    The request body is not a valid JSON format. Change your body format to JSON to proceed.
    VIRTUAL_ACCOUNT_NUMBER_OUTSIDE_RANGE
    400
    The virtual account number you want is outside your range. Check your VA range in Virtual Accounts Settings and make sure the account_number is within your VA range
    BANK_NOT_SUPPORTED_ERROR
    400
    The bank code is not currently supported. You can check the available bank with Get virtual account banks endpoint.
    EXPIRATION_DATE_NOT_SUPPORTED_ERROR
    400
    Custom expiration date (the time when the virtual account will be expired) for the virtual account is not currently supported.
    EXPIRATION_DATE_INVALID_ERROR
    400
    Invalid custom expiration date because it's earlier than current time.
    SUGGESTED_AMOUNT_NOT_SUPPORTED_ERROR
    400
    The suggested amount for the virtual account is not currently supported.
    EXPECTED_AMOUNT_REQUIRED_ERROR
    400
    The expected_amount is required for Closed Virtual Account (is_closed: true). Specify required amount to proceed.
    CLOSED_VA_NOT_SUPPORTED_ERROR
    400
    The closed option for this virtual account is not currently supported.
    DUPLICATE_CALLBACK_VIRTUAL_ACCOUNT_ERROR
    400
    The Virtual Account number already exist. Check your Virtual Account in Virtual Account tab in Dashboard or Get Virtual Account API. Expire existing Virtual Account first if persists to proceed.
    MINIMUM_EXPECTED_AMOUNT_ERROR
    400
    The minimum expected amount is Rp. 1 for BNI, BRI and MANDIRI
    MAXIMUM_EXPECTED_AMOUNT_ERROR
    400
    The maximum expected amount is Rp. 50,000,000,000 for BNI, BRI and MANDIRI
    CALLBACK_VIRTUAL_ACCOUNT_NAME_NOT_ALLOWED_ERROR
    400
    The name cannot contain bank or institution name. Use non-bank and non-institutions name to proceed.
    DESCRIPTION_NOT_SUPPORTED_ERROR
    400
    The requested Virtual Account bank doesn't support description feature. Description field is only supported for BRI
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here

    Get Virtual Account

    Endpoint: Get Virtual Account

    GET https://api.xendit.co/callback_virtual_accounts/:id

    Example Get Virtual Account Request

    curl https://api.xendit.co/callback_virtual_accounts/:id -X GET \
      -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $id = '59e03a976fab8b1850fdf347';
      $getVA = \Xendit\VirtualAccounts::retrieve($id);
      var_dump($getVA);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { VirtualAcc } = x;
    const vaSpecificOptions = {};
    const va = new VirtualAcc(vaSpecificOptions);
    
    const resp = await va.getFixedVA({ id: '59e03a976fab8b1850fdf347' });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      FixedVirtualAccount fpa = FixedVirtualAccount.getFixedVA("EXAMPLE_ID");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := virtualaccount.GetFixedVAParams{
      ID: "59e03a976fab8b1850fdf347",
    }
    
    resp, err := virtualaccount.GetFixedVA(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("retrieved fixed va: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    VirtualAccount = xendit_instance.VirtualAccount
    
    virtual_account = VirtualAccount.get(
        id="5eec3a3e8dd9ea2fc97d6728",
    )
    print(virtual_account)

    Sometime, you need to know the detail for your virtual account. This endpoint can be used to get the latest details from your virtual account

    Request Parameters

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Path Parameter Type Description
    id
    required
    string ID of the Virtual Account object

    Response Parameters

    Example Get Virtual Account Response

    {
      "id": "57f6fbf26b9f064272622aa6",
      "external_id": "va-1475804036622",
      "owner_id": "57b4e5181473eeb61c11f9b9",
      "bank_code": "BNI",
      "merchant_code": "8808",
      "account_number": "8808999939380502",
      "name": "Michael Chen",
      "currency": "IDR",
      "is_single_use": false,
      "is_closed": false,
      "expiration_date": "2051-09-27T17:00:00.000Z",
      "status": "PENDING"
    }

    Returns Virtual Account Object with status 200

    Error Codes

    Example of Error Message

    {
        "error_code": "CALLBACK_VIRTUAL_ACCOUNT_NOT_FOUND_ERROR",
        "message": "Callback virtual account not found"
    }
    Error Code Description
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here
    CALLBACK_VIRTUAL_ACCOUNT_NOT_FOUND_ERROR
    404
    Could not find callback virtual account.

    Update Virtual Account

    Endpoint: Update Virtual Account (VA)

    PATCH https://api.xendit.co/callback_virtual_accounts/:id

    Example Update Fixed Virtual Accounts Request

    curl https://api.xendit.co/callback_virtual_accounts/57f6fbf26b9f064272622aa6 -X PATCH \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -d expected_amount=150000
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $id = 'VA-id';
      $updateParams = ["suggested_amount" => 150000];
    
      $updateVA = \Xendit\VirtualAccounts::update($id, $updateParams);
      var_dump($updateVA);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { VirtualAcc } = x;
    const vaSpecificOptions = {};
    const va = new VirtualAcc(vaSpecificOptions);
    
    const resp = await va.updateFixedVA({
      id: '57f6fbf26b9f064272622aa6',
      expectedAmt: 150000,
    })
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Map<String, Object> params = new HashMap<>();
      params.put("is_single_use", true);
    
      FixedVirtualAccount fixedVirtualAccount = FixedVirtualAccount.update("EXAMPLE_ID", params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    expirationDate := time.Now().AddDate(0, 0, 1)
    
    updateFixedVAData := virtualaccount.UpdateFixedVAParams{
      ID:             "57f6fbf26b9f064272622aa6",
      ExpirationDate: &expirationDate,
      ExpectedAmount: 150000,
    }
    
    resp, err := virtualaccount.UpdateFixedVA(&updateFixedVAData)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("updated fixed va: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    VirtualAccount = xendit_instance.VirtualAccount
    
    virtual_account = VirtualAccount.update(
        id="57f6fbf26b9f064272622aa6",
        is_single_use=True,
    )
    print(virtual_account)

    Update Virtual Account API allows you to update Virtual Account type and information according to your business need. You can update VA when the VA status is ACTIVE. API will throw error when you update INACTIVE VA.

    Request Parameters

    Example Update Virtual Accounts Request

    {
        "expiration_date": "2021-09-27T17:00:00.000Z",
        "expected_amount": 150000
    }
    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Path Parameter Type Description
    id
    required
    string ID of the Virtual Account object
    Body Parameter Type Description
    is_single_use
    optional. default: false
    boolean When set to true, the virtual account status will be inactive after it is paid

    expected_amount
    optional
    number The amount that the virtual account will expect if is_closed is set to true
    suggested_amount
    optional
    number Suggested amount you want to assign

    expiration_date
    optional. default: +31 years from creation date
    string The time when the virtual account will be expired. You can set it to be days in the past to expire virtual account immediately

    Timezone: UTC
    description
    optional
    string Virtual account description shown to end user during payment. This field is only supported for BRI

    Characters Special and alphanumeric
    Minimum length 1 character

    Response Parameters

    Example Update Virtual Account Response

    {
      "id": "57f6fbf26b9f064272622aa6",
      "external_id": "va-1475804036622",
      "owner_id": "57b4e5181473eeb61c11f9b9",
      "bank_code": "BRI",
      "merchant_code": "26215",
      "account_number": "262159939380502",
      "name": "Michael Chen",
      "currency": "IDR",
      "is_single_use": true,
      "is_closed": true,
      "expected_amount": 150000,
      "expiration_date": "2021-09-27T17:00:00.000Z",
      "description": "Utensils Payment 27 September 2021",
      "status": "PENDING"
    }

    Returns Virtual Account Object with status 200

    Error Codes

    Example of Error Message

    {
        "error_code": "BANK_NOT_SUPPORTED_ERROR",
        "message": "That bank code is not currently supported. Use Get Virtual Account Banks API to check available banks"
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    INVALID_JSON_FORMAT
    400
    The request body is not a valid JSON format. Change your body format to JSON to proceed.
    VIRTUAL_ACCOUNT_NUMBER_OUTSIDE_RANGE
    400
    The virtual account number you want is outside your range. Check your VA range in Virtual Accounts Settings and make sure the account_number is within your VA range
    BANK_NOT_SUPPORTED_ERROR
    400
    The bank code is not currently supported. You can check the available bank with Get virtual account banks endpoint.
    EXPIRATION_DATE_NOT_SUPPORTED_ERROR
    400
    Custom expiration date (the time when the virtual account will be expired) for the virtual account is not currently supported.
    EXPIRATION_DATE_INVALID_ERROR
    400
    Invalid custom expiration date because it's earlier than current time.
    SUGGESTED_AMOUNT_NOT_SUPPORTED_ERROR
    400
    The suggested amount for the virtual account is not currently supported.
    EXPECTED_AMOUNT_REQUIRED_ERROR
    400
    The expected_amount is required for Closed Virtual Account (is_closed: true). Specify required amount to proceed.
    INACTIVE_VIRTUAL_ACCOUNT_ERROR
    400
    Account number that you want to update is inactive.
    MINIMUM_EXPECTED_AMOUNT_ERROR
    400
    The minimum expected amount is Rp. 1 for BNI, BRI and MANDIRI
    MAXIMUM_EXPECTED_AMOUNT_ERROR
    400
    The maximum expected amount is Rp. 50,000,000,000 for BNI, BRI and MANDIRI
    DESCRIPTION_NOT_SUPPORTED_ERROR
    400
    The requested Virtual Account bank doesn't support description feature. Description field is only supported for BRI
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here

    Get Virtual Account Banks

    Endpoint: Get Virtual Account Available Banks

    GET https://api.xendit.co/available_virtual_account_banks

    Example Get Virtual Account Banks Request

    curl https://api.xendit.co/available_virtual_account_banks -X GET \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $getVABanks = \Xendit\VirtualAccounts::getVABanks();
      var_dump($getVABanks);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { VirtualAcc } = x;
    const vaSpecificOptions = {};
    const va = new VirtualAcc(vaSpecificOptions);
    
    const resp = await va.getVABanks();
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      AvailableBank[] availableBanks = FixedVirtualAccount.getAvailableBanks();
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    availableBanks, err := virtualaccount.GetAvailableBanks()
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("available va banks: %+v\n", availableBanks)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    VirtualAccount = xendit_instance.VirtualAccount
    
    virtual_account_banks = VirtualAccount.get_banks()
    print(virtual_account_banks)

    Request Parameters

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Response Parameters

    Example Get Virtual Account Banks Response

    [
        {
            "name": "Bank Mandiri",
            "code": "MANDIRI",
        "is_activated": true
        },
        {
            "name": "Bank Negara Indonesia",
            "code": "BNI",
        "is_activated": true
        },
        {
            "name": "Bank Rakyat Indonesia",
            "code": "BRI",
        "is_activated": true
        },
        {
            "name": "Bank Permata",
            "code": "PERMATA",
        "is_activated": false
        },
        {
            "name": "Bank Central Asia",
            "code": "BCA",
        "is_activated": false
        }
    ]

    Returns array of the following object:

    Parameter Type Description
    name
    required
    string Full name of the bank

    code
    required
    string Code of the bank, relevant during creation of virtual accounts

    is_activated
    required
    string Activation status of the bank, relevant during creation of virtual accounts

    Simulate Payment

    Simulate Virtual Account Payment API allows you to mimic your customer behavior to pay to your Virtual Account in TEST mode. This is similar to your customers paying your Virtual Account using ATM/internet banking/mobile banking in LIVE mode. A callback will be sent to your callback URL upon payment completion.

    Endpoint: Simulate VA Payment

    POST https://api.xendit.co/callback_virtual_accounts/external_id={external_id}/simulate_payment

    Request Parameters

    Simulation Example

    {
        "amount": 50000
    }
    Path Parameter Type Description
    external_id
    required
    string External ID of the Virtual Account

    Response Parameters

    Simulation Response

    {
        "status": "COMPLETED",
        "message": "Payment for the Fixed VA with external id {{$external_id}} is currently being processed. Please ensure that you have set a callback URL for VA payments via Dashboard Settings and contact us if you do not receive a VA payment callback within the next 5 mins."
    }
    Parameters Type Description
    status
    required
    string Status of the payment simulation
    message
    required
    string Additional information regarding the payment simulation process

    Get Virtual Account Payment

    Endpoint: Get Virtual Account Payment

    GET https://api.xendit.co/callback_virtual_account_payments/payment_id={payment_id}

    Example Get Virtual Account Payment Request

    curl https://api.xendit.co/callback_virtual_account_payments/payment_id={payment_id} -X GET \
        -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $paymentID = '1502450097080';
      $getFVAPayment = \Xendit\VirtualAccounts::getFVAPayment($paymentID);
      var_dump($getFVAPayment);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { VirtualAcc } = x;
    const vaSpecificOptions = {};
    const va = new VirtualAcc(vaSpecificOptions);
    
    const resp = await va.getVAPayment({
      paymentID: '598d91b1191029596846047f',
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      FixedVirtualAccountPayment payment = FixedVirtualAccount.getPayment("EXAMPLE_PAYMENT_ID");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    payment, err := virtualaccount.GetPayment(&virtualaccount.GetPaymentParams{
      PaymentID: "1502450097080",
    })
    
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("retrieved va payment: %+v\n", payment)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    VirtualAccount = xendit_instance.VirtualAccount
    
    virtual_account_payment = VirtualAccount.get_payment(
        payment_id="5ef18efca7d10d1b4d61fb52",
    )
    print(virtual_account_payment)

    When you receive our callback in your URL, you can verify that the callback you receive is coming from us.

    Request Parameters

    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to make this transaction for.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information

    Path Parameter Type Description
    payment_id
    required
    string ID of the payment retrieved from Virtual Account Payment object

    Response Parameters

    Example Get Virtual Account Payment Response

    {
        "id": "598d91b1191029596846047f",
        "payment_id": "5f218745736e619164dc8608",
        "callback_virtual_account_id": "598d5f71bf64853820c49a18",
        "external_id": "demo-1502437214715",
        "bank_code": "BNI",
        "merchant_code": "8808",
        "account_number": "8808999939380502",
        "amount": 50000,
        "transaction_timestamp": "2021-07-24T05:22:55.115Z",
        "sender_name": "Michael Chen"
    }

    Returns Virtual Account Payment object with status 200

    Error Codes

    Error Code Description
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here
    CALLBACK_VIRTUAL_ACCOUNT_PAYMENT_NOT_FOUND_ERROR
    404
    Could not find callback virtual account payment by payment id.

    Virtual Account Callback

    Endpoint: Virtual Account Callback

    POST https://yourcompany.com/virtual_account_paid_callback_url

    Xendit notifies your system upon successful payments via callback. You need to provide an URL to receive callback. Please specify your URL in Callback Settings in Xendit Dashboard.

    The payment notification will be sent as POST request to the URL you set. Xendit attach x-callback-token header that you can validate against Verification Token in Callback Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks callback event as failed if there is no response within 30s. When events failed, automatic retry will kick-off for the next 24h. Alternatively, you can resend any event in Callback tab at anytime. You can also receive notification via email every 6h to check your callback health.

    Learn more about Callback

    Header Parameters

    Header Parameter Type Description
    x-callback-token
    required
    string Your Xendit unique callback token to verify the origin of the callback

    Payment Callback Payload

    Example Virtual Account Payment Callback Payload

    {
      "id": "598d91b1191029596846047f",
      "created": "2021-07-24T05:22:55.115Z",
      "updated": "2021-07-24T05:22:55.115Z",
      "payment_id": "5f218745736e619164dc8608",
      "owner_id": "5a02cd4798ccd5c92ce44353",
      "callback_virtual_account_id": "598d5f71bf64853820c49a18",
      "external_id": "demo-1502437214715",
      "bank_code": "BNI",
      "merchant_code": "8808",
      "account_number": "8808999939380502",
      "amount": 50000,
      "transaction_timestamp": "2021-07-24T05:22:55.115Z",
      "sender_name": "Michael Chen"
    }

    Returns Virtual Account Payment Object with additional parameters:

    Body Parameter Type Description
    created
    required
    string ISO8601 timestamp of when the Virtual Account payment was created. Timezone UTC+0
    updated
    required
    string ISO8601 timestamp of the Virtual Account payment last updated. Timezone UTC+0
    owner_id
    required
    string Owner of the payment with the value of your Xe