NAV undefined
bash php javascript java go python csharp

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!

List of Supported Products

  1. Credit / Debit cards (via Payments API)
  2. E-Wallets (via Payments API)
  3. QR Codes (via Payments API)
  4. Direct Debit (via Payments API)
  5. Bank Transfer / Virtual Accounts (via Payments API)
  6. Retail Outlets (via Payments API)
  7. Invoices
  8. Payouts
  9. Customers

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.

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

Installation and Upgrade Guide

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

Go

See the source on Github

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

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.

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-src

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

Request ID

Each API request has an asssociated request identifier. You can find this value in the response headers, under Request-ID. You can use Request-ID to find logs in API Logs in Dashboard. Learn more about Searching API Logs using Request-ID in API Logs Docs.

If you need to contact us about a specific request, providing the Request ID will ensure the fastest possible resolution.

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

Rate Limit

API Rate Limit is a feature that limits the number of requests that a user or account can make to an API within a specific time period. This is often used to prevent excessive or abusive usage of an API, and to ensure that all users have fair access to the resources provided by the API.

Xendit uses the Sliding Window algorithm to implement API Rate Limit. This algorithm divides a specific time period (such as an hour or a day) into smaller windows, and tracks the number of requests made within each window. For example, if the rate limit is 50 requests per second (RPS), and the window size is one minute, the algorithm will allow up to 3000 requests in each one-minute window.

In general, API Rate Limit is set 60 requests per minute (RPM) per endpoint per account in Test mode. In Live mode, the rate limit is set to 6000 requests per minute (RPM) per endpoint per account. The Rate Limit value can be different per endpoint when stated otherwise in each API section in API Reference. We return the following headers in API response to let you check Rate Limit details:

Response Header Example Value Description
Rate-Limit-Limit 6000 Containing the requests quota in the time window
Rate-Limit-Remaining 5839 Containing the remaining requests quota in the current window
Rate-Limit-Reset 58.379 Containing the time remaining in the current window, specified in seconds

Additionally, the rate limit of each unique IP address of the calling client can make a maximum of 18,000 requests per minute.

If you exceed the rate limit for an endpoint, you will receive an HTTP status code of 429 (Too Many Requests) with the error code RATE_LIMIT_EXCEEDED. It is important to handle this error and throttle your requests until the rate limit quota replenishes.

Here are some best practices for handling API Rate Limit gracefully as a client:

  1. Implement rate limiting in your application: As a client, it is important to implement rate limiting in your own application to ensure that you do not exceed the API's rate limits. This can be done by tracking the number of requests made and the time at which they were made, and comparing this to the API's rate limit policies.
  2. Handle rate limit errors: When you receive an HTTP status code of 429 (Too Many Requests) with the error code RATE_LIMIT_EXCEEDED, it is important to handle this error gracefully in your application. One way to do this is to retry the request after a certain amount of time has passed, to give the rate limit quota a chance to replenish.
  3. Use exponential backoff: When retrying a request after a rate limit error, it can be helpful to use exponential backoff. This means that you should increase the amount of time you wait between retries by a factor of two (or some other multiplier) each time you receive a rate limit error. For example, you might retry the request after 1 second, then 2 seconds, then 4 seconds, and so on. This helps to reduce the risk of overwhelming the API with too many retries in a short period of time.
  4. Use caching: Caching the results of API requests can help to reduce the number of requests made to the API, and can also improve the performance of your application. By storing the results of API requests locally and reusing them until they become stale, you can reduce the need to make frequent requests to the API.

By following these best practices, you can help to ensure that your application handles rate limits gracefully and provides a reliable and consistent experience for your users.

We may reduce limits to prevent abuse, or increase limits to enable high-traffic applications. To increase the rate limit for your account, you can contact us 4 weeks in advance via email api@xendit.co by providing your Business ID. We will review your request and may be able to increase the limit based on the needs of your application and the overall usage of the API.

Overall, it is important to carefully manage your API usage to ensure that you do not exceed the rate limits and disrupt the service for other users. By implementing proper rate limiting and error handling in your application, you can ensure that your users have a reliable and consistent experience when accessing the API.

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 set as headers in Xendit's API. The exact header for idempotency is dependant on the specific API. For example, the idempotency-key header on the Create Payouts API. A few common strategies for generating idempotency keys are:

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.

Webhook

Xendit uses webhook to notify your application any time an event happens on your account. Set up webhook 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 webhook from us. The webhook notification will be sent over POST request to your webhook URL that you have set. Setup your webhook URL in webhook settings. You can use a tool like ngrok to make your endpoint available for receiving webhook during testing.

Delivery Attempts and Retries

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

View events

When viewing information about a specific event through the Dashboard's Webhook 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 webhooks, and the respective HTTP status codes Xendit received.

Retry logic

Xendit attempts to deliver your webhook 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 webhook statistics via email

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

Event Handling

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

Acknowledge events immediately

If your webhook 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 webhook 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

Webhook 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. We provide webhook-id as a unique identifier in the header parameter of every webhook to help you to implement idempotency. Learn about idempotency.

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 webhook endpoint, Xendit will validate that the connection to your server is secure before sending your webhook 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 webhook 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 webhook token to verify the origin of the webhook

Before you can verify tokens, you need to retrieve your webhook token from Dashboard's Webhook 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)
string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";

XenditClient xendit = new XenditClient(apiKey);
BalanceClient balance = xendit.Balance;

BalanceResponse holdingBalance = await balance.Get(BalanceAccountType.Holding);

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
currency
optional
string Currency filter for customers with multi currency accounts type. This field is only optional if you have only 1 currency. If you have more than 1 currency, please specify your desired currency.

sample values: IDR, PHP, USD
at_timestamp
optional
string Datetime format
Balance returned in the response will be based on the timestamp provided

sample value: 2024-01-01T00:00:00.000Z

Response Parameters

Example Get Balance Response

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

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

The Customer Object is a standard data structure to hold information relating to one of your customers. It has the following major components:

When one (or more) customers is returned by endpoints in this section, the response body will contain a Customer Object (or an array of Customer Objects). Each object has the following structure:

Example Customer Object - Individual

{
    "id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
    "reference_id": "demo_1475801962607",
    "type": "INDIVIDUAL",
    "individual_detail": {
        "given_names": "John",
        "surname": "Doe",
        "nationality": "ID",
        "place_of_birth": "Jakarta",
        "date_of_birth": "1980-01-01",
        "gender": "MALE",
        "employment": {
            "employer_name": "Xendit",
            "nature_of_business": "Payment Gateway",
            "role_description": "Test dummy"
        }
    },
    "business_detail": null,
    "email": "customer@website.com",
    "mobile_number": "+628121234567890",
    "phone_number": "+628121234567890",
    "hashed_phone_number": null,
    "addresses": [{
        "street_line1": "Panglima Polim IV",
        "street_line2": "Ruko Grand Panglima Polim, Blok E",
        "city": "Jakarta Selatan",
        "province_state": "DKI Jakarta",
        "postal_code": "993448",
        "country": "ID",
        "category": "HOME",
        "is_primary": true
    }],
    "identity_accounts": [{
        "type": "CREDIT_CARD",
        "company": "OCBC",
        "description": "My account",
        "country": "ID",
        "properties":{
            "token_id": "586f0ba2ab70de5d2b409e0d"
        }
    }],
    "kyc_documents": [{
        "type": "IDENTITY_CARD",
        "sub_type": "NATIONAL_ID",
        "country": "ID",
        "document_name": "KTP",
        "document_number": "12356789012456",
        "expires_at": null,
        "holder_name": "John Doe",
        "document_images": [
            "file-ec700c1c-db17-4496-b1fb-04ebe551b412"
        ]
    }],
    "description": "My first customer",
    "date_of_registration": "2020-03-30",
    "domicile_of_registration": "ID",
    "metadata": {
        "foo": "bar"
    },
    "created": "2020-03-30T06:12:47.212Z",
    "updated": "2020-03-30T06:12:47.212Z"
}

Example Customer Object - Business

{
    "id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
    "reference_id": "demo_1475801962607",
    "type": "BUSINESS",
    "individual_detail": null,
    "business_detail": {
        "business_name": "ACME Corp",
        "trading_name": null,
        "business_type": "CORPORATION",
        "nature_of_business": null,
        "business_domicile": null,
        "date_of_registration": null
    },
    "email": "customer@website.com",
    "mobile_number": null,
    "phone_number": null,
    "hashed_phone_number": null,
    "addresses": [],
    "identity_accounts": [],
    "kyc_documents": [],
    "description": null,
    "metadata": null,
    "created": "2020-03-30T06:12:47.212Z",
    "updated": "2020-03-30T06:12:47.212Z"
}

Version

You are currently viewing API version 2020-10-31. Click here to view older versions.

Version Changelog
2020-10-31 (Latest) Update to support BUSINESS type customers and generic identity accounts
2020-05-19 Original version
Body Parameter Type Description
id string Xendit-generated Customer ID. Will start with cust-...
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer.
Supported values: INDIVIDUAL, BUSINESS
individual_detail
optional
object JSON object containing details of the individual. Will be null if type is not INDIVIDUAL
Individual detail child parameters
given_names
required
string Primary or first name/s of customer
surname
optional
string Last or family name of customer
nationality
optional
string Country code for customer's nationality

Format ISO 3166-2 Country Code
place_of_birth
optional
string City or other relevant location for the customer’s birth place
date_of_birth
optional
string Date of birth of the customer

Format YYYY-MM-DD string
gender
optional
string Gender of customer. Supported values: MALE,
FEMALE,
OTHER
employment
optional
string Name of account holder as per the account provider
employer_name
optional
string Name of the employer
nature_of_business
optional
string Industry or nature of business
role_description
optional
string Occupation or title
business_detail
optional
object JSON object containing details of the business. Will be null if type is not BUSINESS
Business detail child parameters
business_name
required
string Name of business
trading_name
optional
string Trading name
business_type
required
string Legal entity type of the business
Supported values: CORPORATION,
SOLE_PROPRIETOR,
PARTNERSHIP,
COOPERATIVE,
TRUST,
NON_PROFIT,
GOVERNMENT
nature_of_business
optional
string Free text description of the type of business this entity pursues. Examples are: Ecommerce, Travel
business_domicile
optional
string Registered country of the business

Format ISO 3166-2 Country Code
date_of_registration
optional
string Business registration date

Format YYYY-MM-DD string
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 15 digits (not including "+")
phone_number
optional
string Additional contact number of customer in E.164 format. May be a landline

Maximum length 15 digits (not including "+")
FormatE.164 international standard +(country code)(subscriber number)
hashed_phone_number
optional
string Hashed phone number

Maximum length 255 characters
email
optional
string E-mail address of customer

Maximum length 50 characters
addresses
optional
array Array of address JSON objects containing the customer's various address information.
Addresses child parameters
Field Description
country
required
string Country of residence of customer

Format ISO 3166-2 Country Code
street_line1
optional
string Line 1 of street address e.g., building name and apartment number

Maximum length 255 characters
street_line2
optional
string Line 2 of street address e.g., street number and name

Maximum length 255 characters
city
optional
string City, village or town of residence of customer

Maximum length 255 characters
province_state
optional
string Province, state or region of residence of customer

Maximum length 255 characters
postal_code
optional
string ZIP/Postal Code of customer

Maximum length 255 characters
category
optional
string Address type. Supported values: HOME,
WORK,
PROVINCIAL
is_primary
optional
boolean Defaults to false. Indicates that the information provided refers to the customer’s primary address
identity_accounts
required
array Array of JSON objects with information relating to financial, social media or other accounts associated with the customer. This array can store details for KYC purposes and can support storing of account details for execution of payments within the Xendit API ecosystem.
Identity accounts child parameters
Field Description
type
required
string The account type. Supported values: BANK_ACCOUNT,
EWALLET,
CREDIT_CARD,
PAY_LATER,
OTC,
QR_CODE,
SOCIAL_MEDIA
company
optional
string The issuing institution associated with the account (e.g., OCBC, GOPAY, 7-11). If adding financial accounts that Xendit supports, we recommend you use the channel_code for this field

Maximum length 100 characters
description
optional
string Free text description for the account

Maximum length 255 characters
country
optional
string Issuing country for the account, if relevant

Format ISO 3166-2 Country Code
properties
optional
string JSON object with any account-specific content as required e.g.,

For BANK_ACCOUNT types:
Bank account parameters
account_number
required
string Unique account identifier as per the bank records
account_holder_name
required
string Name of account holder as per the bank records. Should match the registered account name exactly
swift_code
optional
string The swift code for international payments
account_type
optional
string Free text account type, e.g., Savings, Transaction, Virtual Account
account_details
optional
string Potentially masked account detail, for display purposes only
currency
optional
string Primary currency of the account, if relevant.

Format ISO 4217 Currency Code

For EWALLET types:
eWallet parameters
account_number
required
string Unique account identifier as per the ewallet records
account_holder_name
optional
string Name of account holder as per the ewallet records. Should match the registered account name exactly
currency
optional
string Primary currency of the account, if relevant.

Format ISO 4217 Currency Code

For CREDIT_CARD types:
Credit card parameters
token_id
required
string The token id returned in tokenisation

For OTC types:
Over The Counter parameters
payment_code
required
string Complete fixed payment code (including prefix)
expires_at
optional
string Expiry date for the payment code

Format YYYY-MM-DD string

For QR_CODE types:
QR code parameters
qr_string
required
string String representation of the unique QR code

For PAY_LATER types:
Pay later parameters
account_id
required
string Alphanumeric string identifying this account. Usually an email address or phone number
account_holder_name
optional
string Name of account holder as per the account provider
currency
optional
string Primary currency of the account, if relevant.

Format ISO 4217 Currency Code

For SOCAL_MEDIA types:
Social media parameters
account_id
required
string Alphanumeric string identifying this account. Usually an email address or phone number
account_handle
optional
string Name of account as per the account provider
kyc_documents
required
array Array of JSON objects with documents collected for KYC of this customer.
KYC documents child parameters
Field Description
country
required
string Issuing country of the document

Format ISO 3166-2 Country Code
type
required
string Generic ID type
Supported values: BIRTH_CERTIFICATE,
BANK_STATEMENT,
DRIVING_LICENSE,
IDENTITY_CARD,
PASSPORT,
VISA,
BUSINESS_REGISTRATION,
BUSINESS_LICENSE
sub_type
optional
string Specific ID type for IDENTITY_CARD types.
Supported values: NATIONAL_ID,
CONSULAR_ID,
VOTER_ID,
POSTAL_ID,
RESIDENCE_PERMIT,
TAX_ID,
STUDENT_ID,
MILITARY_ID,
MEDICAL_ID
document_name
optional
string Free text description of the type of document (e.g., NIB, SIUP, AKTA)

Maximum length 255 characters
document_number
optional
string Unique alphanumeric identity document number or code

Maximum length 255 characters
expires_at
optional
string Expiry date, if relevant.

Format YYYY-MM-DD string
holder_name
optional
string Free text to capture the full name(s) of the individual or business as defined on the document, if relevant

Maximum length 255 characters
document_images
required
string[] Array of file ids returned from uploads to the files endpoint, representing images of the front/back of the document, in png/jpg/jpeg/pdf format
description
optional
string Merchant-provided description for the customer.

Maximum length 500 characters
date_of_registration
optional
string Date of which the account that the shopper had to create/sign up on the merchant’s website

Format YYYY-MM-DD string
domicile_of_registration
optional
string Country within which the account that the shopper had to create/sign up on the merchant’s website resides (e.g. accounts created on Shopee SG have SG as the value for this field.

Format ISO 3166-2 Country Code
metadata
optional
object Object of additional information as provided in customer creation
created
required
string Timestamp of customer creation in ISO format
updated
required
string Timestamp of customer update in ISO format

Create Customer

Make a POST request to this endpoint to create a customer for later use with a payments endpoint.

Endpoint: Create Customer

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

Version

You are currently viewing API version 2020-10-31. Click here to view older versions.

Version Changelog
2020-10-31 (Latest) Update to support BUSINESS type customers and generic identity accounts
2020-05-19 Original version

Request Parameters

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'
   --data-raw '{
     "reference_id": "demo_1475801962607",
     "type": "INDIVIDUAL",
     "individual_detail": {
       "given_names": "John",
       "surname": "Doe"
     },
     "email": "customer@website.com",
     "mobile_number": "+628121234567890"
     }'
<?php
  $url = "https://api.xendit.co/customers";
  $apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
  $headers = [];
  $headers[] = "Content-Type: application/json";
  $data = [
    "reference_id" => "demo_1475801962607",
    "type" => "INDIVIDUAL",
    "individual_detail" => [
       "given_names" => "John",
       "surname" => "Doe"
    ],
    "email" => "customer@website.com",
    "mobile_number" => "+628121234567890"
  ];

  $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/customers";

var headers = new Headers();
headers.append("Authorization", "Basic " + btoa(apiKey + ":"));
headers.append("Content-Type", "application/json");

var reqBody = JSON.stringify({
  "reference_id": "demo_1475801962607",
  "type": "INDIVIDUAL",
  "individual_detail": {
    "given_names": "John",
    "surname": "Doe"
  },
  "email": "customer@website.com",
  "mobile_number": "+628121234567890"});

var requestOptions = {
  method: 'POST',
  headers: headers,
  body: reqBody,
  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/customers"

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

payload = {
  "reference_id": "demo_1475801962607",
  "type": "INDIVIDUAL",
  "individual_detail": {
    "given_names": "John",
    "surname": "Doe"
  },
  "email": "customer@website.com",
  "mobile_number": "+628121234567890"
}
auth_token = 'Basic ' + base64_token
headers = {
  'Authorization': auth_token
}

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

print(response.text)
string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";

XenditClient xendit = new XenditClient(apiKey);
CustomerClient customer = xendit.Customer;

CustomerParameter individualParameter = new CustomerParameter
{
  ReferenceId = "demo_11212163",
  Type = CustomerType.Individual,
  IndividualDetail = new IndividualDetail
  {
    GivenNames = "John",
    Gender = CustomerGender.Male,
  },
  IdentityAccount = new IdentityAccount[]
  {
    new IdentityAccount
    {
      Country = Country.Indonesia,
      Type = CustomerIdentityAccountType.BankAccount,
      Properties = new IdentityAccountProperties { AccountNumber = "account_number" }
    }
  },
  KycDocuments = new KycDocument[]
  {
    new KycDocument
    {
      Country = Country.Indonesia,
      Type = CustomerKycDocumentType.IdentityCard,
      SubType = CustomerKycDocumentSubType.NationalId,
    }
  },
};

CustomerResponse individualCustomerVersion20201031 = await customer.Create(individualParameter);
Header Parameter Type Description
IDEMPOTENCY-KEY
optional
string A unique key to prevent processing duplicate requests. Can be your reference_id or any GUID. Must be unique across development & production environments. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.

Characters Special and alphanumeric
Maximum length 100 characters
Minimum length 1 character
API-VERSION
optional
string API version in date semantic (e.g. 2020-10-31). Attach this parameter when calling a specific API version. List of API versions can be found here.
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 Merchant-provided identifier for the customer.
Requests with a duplicate reference_id will return an error. You should PATCH the customer object resource instead.

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
type
required
string Type of customer.
Supported values: INDIVIDUAL, BUSINESS
individual_detail
conditionally required
object JSON object containing details of the individual. Required if type is INDIVIDUAL
Individual detail child parameters
given_names
required
string Primary or first name/s of customer.

Characters Alphanumeric. No special characters is allowed.
surname
optional
string Last or family name of customer.

Characters Alphanumeric. No special characters is allowed.
nationality
optional
string Country code for customer's nationality

Format ISO 3166-2 Country Code
place_of_birth
optional
string City or other relevant location for the customer’s birth place.

Characters Alphanumeric. No special characters is allowed.
date_of_birth
optional
string Date of birth of the customer

Format YYYY-MM-DD string
gender
optional
string Gender of customer. Supported values: MALE,
FEMALE,
OTHER
employment
optional
string Name of account holder as per the account provider.
employer_name
optional
string Name of the employer.

Characters Alphanumeric. No special characters is allowed.
nature_of_business
optional
string Industry or nature of business.

Characters Alphanumeric. No special characters is allowed.
role_description
optional
string Occupation or title.

Characters Alphanumeric. No special characters is allowed.
business_detail
conditionally required
object JSON object containing details of the business. Required if type is BUSINESS
Business detail child parameters
business_name
required
string Name of business. Required if type is BUSINESS.

Characters Alphanumeric. No special characters is allowed.
trading_name
optional
string Trading name.
Characters Alphanumeric. No special characters is allowed.
business_type
required
string Legal entity type of the business
Supported values: CORPORATION,
SOLE_PROPRIETOR,
PARTNERSHIP,
COOPERATIVE,
TRUST,
NON_PROFIT,
GOVERNMENT
nature_of_business
optional
string Free text description of the type of business this entity pursues. Examples are: Ecommerce, Travel

Characters Alphanumeric. No special characters is allowed.
business_domicile
optional
string Registered country of the business

Format ISO 3166-2 Country Code
date_of_registration
optional
string Business registration date

Format YYYY-MM-DD string
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
phone_number
optional
string Additional contact number of customer in E.164 format. May be a landline

Maximum length 50 characters
FormatE.164 international standard +(country code)(subscriber number)
hashed_phone_number
optional
string Hashed phone number

Maximum length 255 characters
email
optional
string E-mail address of customer

Maximum length 50 characters
addresses
optional
array Array of address JSON objects containing the customer's various address information.
Addresses child parameters
Field Description
country
required
string Country of residence of customer

Format ISO 3166-2 Country Code
street_line1
optional
string Line 1 of street address e.g., building name and apartment number.

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
street_line2
optional
string Line 2 of street address e.g., street number and name

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
city
optional
string City, village or town of residence of customer

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
province_state
optional
string Province, state or region of residence of customer

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
postal_code
optional
string ZIP/Postal Code of customer

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
category
optional
string Address type. Supported values: HOME,
WORK,
PROVINCIAL
is_primary
optional
boolean Defaults to false. Indicates that the information provided refers to the customer’s primary address
identity_accounts
optional
array Array of JSON objects with information relating to financial, social media or other accounts associated with the customer. This array can store details for KYC purposes and can support storing of account details for execution of payments within the Xendit API ecosystem.
Identity accounts child parameters
Field Description
type
required
string The account type. Supported values: BANK_ACCOUNT,
EWALLET,
CREDIT_CARD,
PAY_LATER,
OTC,
QR_CODE,
SOCIAL_MEDIA
company
optional
string The issuing institution associated with the account (e.g., OCBC, GOPAY, 7-11). If adding financial accounts that Xendit supports, we recommend you use the channel_code for this field

Maximum length 100 characters
description
optional
string Free text description for the account

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
country
optional
string Issuing country for the account, if relevant

Format ISO 3166-2 Country Code
properties
optional
string JSON object with any account-specific content as required e.g.,

For BANK_ACCOUNT types:
Bank account parameters
account_number
required
string Unique account identifier as per the bank records

Characters Alphanumeric. No special characters is allowed.
account_holder_name
required
string Name of account holder as per the bank records. Should match the registered account name exactly

Characters Alphanumeric. No special characters is allowed.
swift_code
optional
string The swift code for international payments

Characters Alphanumeric. No special characters is allowed.
account_type
optional
string Free text account type, e.g., Savings, Transaction, Virtual Account

Characters Alphanumeric. No special characters is allowed.
account_details
optional
string Potentially masked account detail, for display purposes only

Characters Alphanumeric. No special characters is allowed.
currency
optional
string Primary currency of the account, if relevant.

Format ISO 4217 Currency Code

For EWALLET types:
eWallet parameters
account_number
required
string Unique account identifier as per the ewallet records

Characters Alphanumeric. No special characters is allowed.
account_holder_name
optional
string Name of account holder as per the ewallet records. Should match the registered account name exactly

Characters Alphanumeric. No special characters is allowed.
currency
optional
string Primary currency of the account, if relevant.

Format ISO 4217 Currency Code

For CREDIT_CARD types:
Credit card parameters
token_id
required
string The token id returned in tokenisation

For OTC types:
Over The Counter parameters
payment_code
required
string Complete fixed payment code (including prefix)
expires_at
optional
string Expiry date for the payment code

Format YYYY-MM-DD string

For QR_CODE types:
QR code parameters
qr_string
required
string String representation of the unique QR code

For PAY_LATER types:
Pay later parameters
account_id
required
string Alphanumeric string identifying this account. Usually an email address or phone number
account_holder_name
optional
string Name of account holder as per the account provider

Characters Alphanumeric. No special characters is allowed.
currency
optional
string Primary currency of the account, if relevant.

Format ISO 4217 Currency Code

For SOCAL_MEDIA types:
Social media parameters
account_id
required
string Alphanumeric string identifying this account. Usually an email address or phone number
account_handle
optional
string Name of account as per the account provider
kyc_documents
optional
array Array of JSON objects with documents collected for KYC of this customer.
KYC documents child parameters
Field Description
country
required
string Issuing country of the document

Format ISO 3166-2 Country Code
type
required
string Generic ID type
Supported values: BIRTH_CERTIFICATE,
BANK_STATEMENT,
DRIVING_LICENSE,
IDENTITY_CARD,
PASSPORT,
VISA,
BUSINESS_REGISTRATION,
BUSINESS_LICENSE
sub_type
optional
string Specific ID type for IDENTITY_CARD types.
Supported values: NATIONAL_ID,
CONSULAR_ID,
VOTER_ID,
POSTAL_ID,
RESIDENCE_PERMIT,
TAX_ID,
STUDENT_ID,
MILITARY_ID,
MEDICAL_ID
document_name
optional
string Free text description of the type of document (e.g., NIB, SIUP, AKTA)

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
document_number
optional
string Unique alphanumeric identity document number or code

Maximum length 255 characters
expires_at
optional
string Expiry date, if relevant.

Format YYYY-MM-DD string
holder_name
optional
string Free text to capture the full name(s) of the individual or business as defined on the document, if relevant

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
document_images
optional
string[] Array of file ids returned from uploads to the files endpoint, representing images of the front/back of the document, in png/jpg/jpeg/pdf format
description
optional
string Merchant-provided description for the customer.

Maximum length 500 characters
Characters Alphanumeric. No special characters is allowed.
date_of_registration
optional
string Date of which the account that the shopper had to create/sign up on the merchant’s website

Format YYYY-MM-DD string
domicile_of_registration
optional
string Country within which the account that the shopper had to create/sign up on the merchant’s website resides (e.g. accounts created on Shopee SG have SG as the value for this field.

Format ISO 3166-2 Country Code
metadata
optional
object Object of additional information related to the customer. Define the JSON properties and values as required to pass information through the APIs.
You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
This is only for your use and will not be used by Xendit.

Response Parameters

Success responses will contain a single Customer Object

Error Codes

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.
IDEMPOTENCY_ERROR
409
Provided Idempotency-key already exists but the request body provided does not match the original request

Get Customer

Retrieves a single customer object

Endpoint: Get Customer

GET https://api.xendit.co/customers/:id

Version

You are currently viewing API version 2020-10-31. Click here to view older versions.

Version Changelog
2020-10-31 (Latest) Update to support BUSINESS type customers and generic identity accounts
2020-05-19 Original version

Request Parameters

Example Get Customer Request

curl https://api.xendit.co/customers/cust-239c16f4-866d-43e8-9341-7badafbc019f -X GET \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
   --header 'API-VERSION: 2020-10-31'
<?php
  $url = "https://api.xendit.co/customers/cust-239c16f4-866d-43e8-9341-7badafbc019f";
  $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_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 url = "https://api.xendit.co/customers/cust-239c16f4-866d-43e8-9341-7badafbc019f";

var headers = new Headers();
headers.append("Authorization", "Basic " + btoa(apiKey + ":"));
headers.append("Content-Type", "application/json");
headers.append("API-VERSION", "2020-10-31");

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));
xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="

data := customer.getCustomer{
  id: 'cust-239c16f4-866d-43e8-9341-7badafbc019f'
}

resp, err := customer.getCustomer(&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.getCustomer("cust-239c16f4-866d-43e8-9341-7badafbc019f");
} catch (XenditException e) {
    e.printStackTrace();
}
import requests
import base64

api_key = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:"
url = "https://api.xendit.co/customers/239c16f4-866d-43e8-9341-7badafbc019f"

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

auth_token = 'Basic ' + base64_token
headers = {
  'Authorization': auth_token,
  'API-VERSION': '2020-10-31'
}

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

print(response.text)
Header Parameter Type Description
API-VERSION
optional
string API version in date semantic (e.g. 2020-10-31). Attach this parameter when calling a specific API version. List of API versions can be found here.
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 Type Description
id string Xendit-generated Customer ID. Will start with cust-...

Response Parameters

Success responses will contain a single Customer Object

Error Codes

See other common errors here.

Error Code Description
DATA_NOT_FOUND
404
The provided id does not exist. Please review the 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-10-31. Click here to view older versions.

Version Changelog
2020-10-31 (Latest) Update to support BUSINESS type customers and generic identity accounts
2020-05-19 Original version

Request Parameters

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
  $url = "https://api.xendit.co/customers";
  $apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
  $headers = [];
  $headers[] = "Content-Type: application/json";

  $queryString = "?reference_id=demo_1475801962607";

  $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.$queryString);
  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 url = "https://api.xendit.co/customers";

var headers = new Headers();
headers.append("Authorization", "Basic " + btoa(apiKey + ":"));
headers.append("Content-Type", "application/json");

let queryString = "?reference_id=demo_1475801962607";

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

fetch(url + queryString, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
Query Parameter Type Description
reference_id
required
string Your identifier for the customer

Response Parameters

Example Get Customer by Reference ID Success Response

{
    "data": [{
        "id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
        "reference_id": "demo_1475801962607",
        "type": "INDIVIDUAL",
        "individual_detail": {
            "given_names": "John",
            "surname": "Doe",
            "nationality": null,
            "place_of_birth": null,
            "date_of_birth": null,
            "gender": null,
            "employment": null
        },
        "business_detail": null,
        "email": "customer@website.com",
        "mobile_number": null,
        "phone_number": null,
        "hashed_phone_number": null,
        "addresses": [],
        "identity_accounts": [],
        "kyc_documents": [],
        "description": null,
        "metadata": null,
        "created": "2020-03-30T06:12:47.212Z",
        "updated": "2020-03-30T06:12:47.212Z"
    }],
    "has_more": false
}
Header Parameter Type Description
API-VERSION
optional
string API version in date semantic (e.g. 2020-10-31). Attach this parameter when calling a specific API version. List of API versions can be found here.
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
data array Array of Customer Objects returned by the query. May be an empty array
has_more boolean Indicates whether there are more items to be queried with after_id of the last item from current result

Error Codes

See other common errors here.

Update Customer

Make a PATCH request to this endpoint to update the details on a customer. Only fields present in the request will be updated. Any changes to fields on the customer object will replace that item in its entirety. If you wish to append to an array, your PATCH request should contain the desired end state array (i.e., both the current content and the new array element to append to it). Pass a NULL value to remove the existing content.

Note that the reference_id and type on a customer cannot be updated.

Endpoint: Update Customer

PATCH https://api.xendit.co/customers/:id

Version

You are currently viewing API version 2020-10-31. Click here to view older versions.

Version Changelog
2020-10-31 (Latest) Update to support BUSINESS type customers and generic identity accounts
2020-05-19 Original version

Request Parameters

Example Update Customer Request

curl https://api.xendit.co/customers/cust-239c16f4-866d-43e8-9341-7badafbc019f -X PATCH \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
   -H 'Content-Type: application/json'
   --data-raw '{
     "individual_detail": {
       "given_names": "Jane",
       "surname": "Doe"
     }
     }'
<?php
  $url = "https://api.xendit.co/customers/cust-239c16f4-866d-43e8-9341-7badafbc019f";
  $apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
  $headers = [];
  $headers[] = "Content-Type: application/json";
  $data = [
    "individual_detail" => [
       "given_names" => "Jane",
       "surname" => "Doe"
    ]
  ];

  $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, 'PATCH');
  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/customers/cust-239c16f4-866d-43e8-9341-7badafbc019f";

var headers = new Headers();
headers.append("Authorization", "Basic " + btoa(apiKey + ":"));
headers.append("Content-Type", "application/json");

var reqBody = JSON.stringify({
  "type": "INDIVIDUAL",
  "individual_detail": {
    "given_names": "John",
    "surname": "Doe"
  },
  "email": "customer@website.com",
  "mobile_number": "+628121234567890"});

var requestOptions = {
  method: 'PATCH',
  headers: headers,
  body: reqBody,
  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/customers"

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

payload = {
  "type": "INDIVIDUAL",
  "individual_detail": {
    "given_names": "John",
    "surname": "Doe"
  },
  "email": "customer@website.com",
  "mobile_number": "+628121234567890"
}
auth_token = 'Basic ' + base64_token
headers = {
  'Authorization': auth_token
}

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

print(response.text)
string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";

XenditClient xendit = new XenditClient(apiKey);
CustomerClient customer = xendit.Customer;

CustomerParameter individualParameter = new CustomerParameter
{
  Type = CustomerType.Individual,
  IndividualDetail = new IndividualDetail
  {
    GivenNames = "John",
    Gender = CustomerGender.Male,
  }
};

CustomerResponse individualCustomerVersion20201031 = await customer.Update(individualParameter);
Header Parameter Type Description
API-VERSION
optional
string API version in date semantic (e.g. 2020-10-31). Attach this parameter when calling a specific API version. List of API versions can be found here.
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
individual_detail
optional
object JSON object containing details of the individual. Will fail API validation if type is not INDIVIDUAL
Individual detail child parameters
given_names
required
string Primary or first name/s of customer

Characters Alphanumeric. No special characters is allowed.
surname
optional
string Last or family name of customer

Characters Alphanumeric. No special characters is allowed.
nationality
optional
string Country code for customer's nationality

Format ISO 3166-2 Country Code
place_of_birth
optional
string City or other relevant location for the customer’s birth place

Characters Alphanumeric. No special characters is allowed.
date_of_birth
optional
string Date of birth of the customer

Format YYYY-MM-DD string
gender
optional
string Gender of customer. Supported values: MALE,
FEMALE,
OTHER
employment
optional
string Name of account holder as per the account provider
employer_name
optional
string Name of the employer

Characters Alphanumeric. No special characters is allowed.
nature_of_business
optional
string Industry or nature of business

Characters Alphanumeric. No special characters is allowed.
role_description
optional
string Occupation or title

Characters Alphanumeric. No special characters is allowed.
business_detail
optional
object JSON object containing details of the business. Will fail API validation if type is not BUSINESS
Business detail child parameters
business_name
required
string Name of business

Characters Alphanumeric. No special characters is allowed.
business_type
required
string Legal entity type of the business
Supported values: CORPORATION,
SOLE_PROPRIETOR,
PARTNERSHIP,
COOPERATIVE,
TRUST,
NON_PROFIT,
GOVERNMENT
nature_of_business
optional
string Free text description of the type of business this entity pursues. Examples are: Ecommerce, Travel

Characters Alphanumeric. No special characters is allowed.
business_domicile
optional
string Registered country of the business

Format ISO 3166-2 Country Code
date_of_registration
optional
string Business registration date

Format YYYY-MM-DD string
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
phone_number
optional
string Additional contact number of customer in E.164 format. May be a landline

Maximum length 50 characters
FormatE.164 international standard +(country code)(subscriber number)
email
optional
string E-mail address of customer

Maximum length 50 characters
addresses
optional
array Array of address JSON objects containing the customer's various address information.
Addresses child parameters
Field Description
country
required
string Country of residence of customer

Format ISO 3166-2 Country Code
street_line1
optional
string Line 1 of street address e.g., building name and apartment number

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
street_line2
optional
string Line 2 of street address e.g., street number and name

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
city
optional
string City, village or town of residence of customer

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
province_state
optional
string Province, state or region of residence of customer

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
postal_code
optional
string ZIP/Postal Code of customer

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
category
optional
string Address type. Supported values: HOME,
WORK,
PROVINCIAL
is_primary
optional
boolean Defaults to false. Indicates that the information provided refers to the customer’s primary address
identity_accounts
optional
array Array of JSON objects with information relating to financial, social media or other accounts associated with the customer. This array can store details for KYC purposes and can support storing of account details for execution of payments within the Xendit API ecosystem.
Identity accounts child parameters
Field Description
type
required
string The account type. Supported values: BANK_ACCOUNT,
EWALLET,
CREDIT_CARD,
PAY_LATER,
OTC,
QR_CODE,
SOCIAL_MEDIA
company
optional
string The issuing institution associated with the account (e.g., OCBC, GOPAY, 7-11). If adding financial accounts that Xendit supports, we recommend you use the channel_code for this field

Maximum length 100 characters
Characters Alphanumeric. No special characters is allowed.
description
optional
string Free text description for the account

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
country
optional
string Issuing country for the account, if relevant

Format ISO 3166-2 Country Code
properties
optional
string JSON object with any account-specific content as required e.g.,

For BANK_ACCOUNT types:
Bank account parameters
account_number
required
string Unique account identifier as per the bank records

Characters Alphanumeric. No special characters is allowed.
account_holder_name
required
string Name of account holder as per the bank records. Should match the registered account name exactly

Characters Alphanumeric. No special characters is allowed.
swift_code
optional
string The swift code for international payments

Characters Alphanumeric. No special characters is allowed.
account_type
optional
string Free text account type, e.g., Savings, Transaction, Virtual Account

Characters Alphanumeric. No special characters is allowed.
account_details
optional
string Potentially masked account detail, for display purposes only

Characters Alphanumeric. No special characters is allowed.
currency
optional
string Primary currency of the account, if relevant.

Format ISO 4217 Currency Code

For EWALLET types:
eWallet parameters
account_number
required
string Unique account identifier as per the ewallet records

Characters Alphanumeric. No special characters is allowed.
account_holder_name
optional
string Name of account holder as per the ewallet records. Should match the registered account name exactly

Characters Alphanumeric. No special characters is allowed.
currency
optional
string Primary currency of the account, if relevant.

Format ISO 4217 Currency Code

For CREDIT_CARD types:
Credit card parameters
token_id
required
string The token id returned in tokenisation

For OTC types:
Over The Counter parameters
payment_code
required
string Complete fixed payment code (including prefix)
expires_at
optional
string Expiry date for the payment code

Format YYYY-MM-DD string

For QR_CODE types:
QR code parameters
qr_string
required
string String representation of the unique QR code

For PAY_LATER types:
Pay later parameters
account_id
required
string Alphanumeric string identifying this account. Usually an email address or phone number
account_holder_name
optional
string Name of account holder as per the account provider

Characters Alphanumeric. No special characters is allowed.
currency
optional
string Primary currency of the account, if relevant.

Format ISO 4217 Currency Code

For SOCAL_MEDIA types:
Social media parameters
account_id
required
string Alphanumeric string identifying this account. Usually an email address or phone number
account_handle
optional
string Name of account as per the account provider

Characters Alphanumeric. No special characters is allowed.
kyc_documents
optional
array Array of JSON objects with documents collected for KYC of this customer.
KYC documents child parameters
Field Description
country
required
string Issuing country of the document

Format ISO 3166-2 Country Code
type
required
string Generic ID type
Supported values: BIRTH_CERTIFICATE,
BANK_STATEMENT,
DRIVING_LICENSE,
IDENTITY_CARD,
PASSPORT,
VISA,
BUSINESS_REGISTRATION,
BUSINESS_LICENSE
sub_type
optional
string Specific ID type for IDENTITY_CARD types.
Supported values: NATIONAL_ID,
CONSULAR_ID,
VOTER_ID,
POSTAL_ID,
RESIDENCE_PERMIT,
TAX_ID,
STUDENT_ID,
MILITARY_ID,
MEDICAL_ID
document_name
optional
string Free text description of the type of document (e.g., NIB, SIUP, AKTA)

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
document_number
optional
string Unique alphanumeric identity document number or code

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
expires_at
optional
string Expiry date, if relevant.

Format YYYY-MM-DD string
holder_name
optional
string Free text to capture the full name(s) of the individual or business as defined on the document, if relevant

Maximum length 255 characters
Characters Alphanumeric. No special characters is allowed.
document_images
optional
string[] Array of file ids returned from uploads to the files endpoint, representing images of the front/back of the document, in png/jpg/jpeg/pdf format
description
optional
string Merchant-provided description for the customer.

Maximum length 500 characters
Characters Alphanumeric. No special characters is allowed.
date_of_registration
optional
string Date of which the account that the shopper had to create/sign up on the merchant’s website

Format YYYY-MM-DD string
domicile_of_registration
optional
string Country within which the account that the shopper had to create/sign up on the merchant’s website resides (e.g. accounts created on Shopee SG have SG as the value for this field.

Format ISO 3166-2 Country Code
metadata
optional
object Object of additional information related to the customer. Define the JSON properties and values as required to pass information through the APIs.
You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
This is only for your use and will not be used by Xendit.

Response Parameters

Success responses will contain a single Customer Object with the updated content

Error Codes

See other common errors here.

Error Code Description
DATA_NOT_FOUND
404
The provided id does not exist. Please review the id and try again

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.
DETAILED_TRANSACTIONS All in one transactions report which includes richer payments data and full payment lifecycle statuses (refunded/partially refunded/refund pending/failed).
Previously known as TRANSACTION_ANALYSIS, this value will still be accepted and will return the same report as DETAILED_TRANSACTIONS.
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.
report_version
optional
string Report version indicates which version of report you need. This parameter is only applicable to Transaction Report.
Default value: VERSION_0

Version value <> changelog:
  • VERSION_0: Original version
  • VERSION_1: Includes Settlement Status, Actual Settlement Time, and Estimated Settlement Time
  • VERSION_2: Includes Early Settlement Fee Columns, swapped Payment ID with Product ID
  • 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/reports/{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 Webhook

    Endpoint: Report Webhook

    POST https://yourcompany.com/report_webhook_url

    Xendit notifies your system upon the completed or failed report via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

    Example Report Webhook 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}}/{{webhook_url}}'
    Header Parameter Type Description
    x-callback-token
    string Your Xendit unique webhook token to verify the origin of the webhook

    webhook-id
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    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
    REVERSED The transaction is reversed by Xendit
    Type The corresponding transaction type
    DISBURSEMENT The disbursement transaction
    PAYMENT The payment transaction. All channels of money-in transactions
    REMITTANCE_PAYOUT The remittance pay-out transactions
    TRANSFER The transfer transaction between Xendit account. This can be transfer in or out
    REFUND The money-in transaction is refunded by you
    TOP UP The money-in transaction to add money to your balance
    WITHDRAWAL The money-out transaction to withdraw the money to your bank account
    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": 500000,
        "cashflow": "MONEY_IN",
        "status": "SUCCESS",
        "business_id": "5fc9f5b246f820517e38c84d",
        "created": "2021-06-23T02:42:15.601Z",
        "updated": "2021-06-23T02:42:15.601Z",
        "fee":{
            "xendit_fee": 1500,
            "value_added_tax": 500,
            "xendit_withholding_tax": 0,
            "third_party_withholding_tax": 0,
            "status": "COMPLETED"
        }
    }
    
    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.
    REFUND A refund transaction created to refund amount from money-in transaction
    channel_code
    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.
    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
    fee
    required
    object
    Body Parameter Description
    xendit_fee number Amount of the Xendit fee for this transaction.
    value_added_tax number Amount of the VAT for this transaction.
    xendit_withholding_tax number Amount of the Xendit Withholding Tax for this transaction if applicable.
    See Tax Documentation for more information.
    third_party_withholding_tax number Amount of the 3rd Party Withholding Tax for this transaction if applicable.
    3rd party example: Bank
    status string Status of fee
    Status Description
    PENDING The fee is still pending to be charged
    COMPLETED The fee is successfully charged
    CANCELED The transaction failed and fee is cancelled
    REVERSED The transaction is reversed and fee is reversed
    settlement_status
    optional
    string
    Settlement Status Description
    PENDING Transaction amount has not been settled to merchant's balance
    SETTLED Transaction has been settled to merchant's balance
    estimated_settlement_time
    optional
    string (ISO 8601) Estimated settlement time will only apply to money-in transactions.
    For money-out transaction, value will be NULL
    Estimated settlement time in which transaction amount will be settled to merchant's balance.
    example: "2022-04-26T08:44:39.566Z"

    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.
    REFUND: A refund transaction created to refund amount from money-in Transaction.
    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.
    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.

    Payments API

    Xendit's Payments API is an enhanced interface that enables merchants to integrate seamlessly with our supported money-in payment channels using a single, unified set of APIs. With these APIs, merchants can utilize a uniform endpoint for various payment methods across all supported markets.

    Check out Payments API Reference page ⏩ to explore Payments API. We will cover the following details:

    Download "New Payments API" Postman Collection to explore and test our APIs

    Run in Postman

    Supported Channels

    E-wallet 🇮🇩 🇵🇭 🇻🇳 🇲🇾

    The following channels are supported for payment method type EWALLET. For more information about e-wallet channels, you may visit our docs page.

    COUNTRY
    CHANNEL NAME
    CHANNEL CODE
    ONE TIME USE
    MULTIPLE USE
    REFUND
    🇮🇩 ID DANA DANA
    🇮🇩 ID LinkAja LINKAJA
    🇮🇩 ID OVO OVO
    🇮🇩 ID ASTRAPAY ASTRAPAY
    🇮🇩 ID JENIUSPAY JENIUSPAY
    🇮🇩 ID ShopeePay SHOPEEPAY
    🇮🇩 ID NEXCASH NEXCASH
    🇵🇭 PH GrabPay GRABPAY
    🇵🇭 PH GCash GCASH
    🇵🇭 PH Maya (PayMaya) PAYMAYA
    🇵🇭 PH ShopeePay SHOPEEPAY
    🇻🇳 VN Appota APPOTA
    🇻🇳 VN MOMO MOMO
    🇻🇳 VN ZaloPay ZALOPAY
    🇻🇳 VN VNPTWALLET VNPTWALLET
    🇻🇳 VN ShopeePay SHOPEEPAY
    🇻🇳 VN ViettelPay VIETTELPAY
    🇹🇭 TH WechatPay WECHATPAY
    🇹🇭 TH LINE Pay LINEPAY
    🇹🇭 TH ShopeePay SHOPEEPAY
    🇹🇭 TH TrueMoney TRUEMONEY
    🇲🇾 MY Touch n Go TOUCHNGO
    🇲🇾 MY ShopeePay SHOPEEPAY
    🇲🇾 MY GrabPay GRABPAY
    🇲🇾 MY WechatPay WECHATPAY

    Direct Debit 🇲🇨 🇵🇭 🇹🇭 🇲🇾

    The following channels are supported for payment method type DIRECT_DEBIT. You may visit our docs page for more information about direct debit channels.

    COUNTRY
    CHANNEL NAME
    CHANNEL CODE
    ONE TIME USE
    MULTIPLE USE
    REFUND
    🇲🇨 ID BRI BRI
    🇲🇨 ID MANDIRI MANDIRI
    🇵🇭 PH BPI BPI
    🇵🇭 PH RCBC RCBC
    🇵🇭 PH Unionbank UBP
    🇵🇭 PH Chinabank CHINABANK
    🇵🇭 PH BDO EPAY BDO_EPAY
    🇹🇭 TH Siam Commercial Bank SCB
    🇹🇭 TH Krungthai Bank KTB
    🇹🇭 TH Bangkok Bank BBL
    🇹🇭 TH Bank of Ayudhya BAY
    🇹🇭 TH K-Bank KBANK_MB
    🇹🇭 TH Bank of Ayudhya BAY_MB
    🇹🇭 TH Krungthai Bank KTB_MB
    🇹🇭 TH Siam Commercial Bank SCB_MB
    🇹🇭 TH Bangkok Bank BBL_MB
    🇲🇾 MY AFFIN AFFIN_FPX
    🇲🇾 MY AGRO AGRO_FPX
    🇲🇾 MY ALLIANCE ALLIANCE_FPX
    🇲🇾 MY AMBANK AMBANK_FPX
    🇲🇾 MY ISLAM ISLAM_FPX
    🇲🇾 MY MUAMALAT MUAMALAT_FPX
    🇲🇾 MY BOC BOC_FPX
    🇲🇾 MY RAKYAT RAKYAT_FPX
    🇲🇾 MY BSN BSN_FPX
    🇲🇾 MY CIMB CIMB_FPX
    🇲🇾 MY HLB HLB_FPX
    🇲🇾 MY HSBC HSBC_FPX
    🇲🇾 MY KFH KFH_FPX
    🇲🇾 MY MAYB2E MAYB2E_FPX
    🇲🇾 MY MAYB2U MAYB2U_FPX
    🇲🇾 MY OCBC OCBC_FPX
    🇲🇾 MY PUBLIC PUBLIC_FPX
    🇲🇾 MY RHB RHB_FPX
    🇲🇾 MY SCH SCH_FPX
    🇲🇾 MY UOB UOB_FPX
    🇲🇾 MY Affin Bank B2B AFFIN_FPX_BUSINESS
    🇲🇾 MY AGRONetBIZ AGRO_FPX_BUSINESS
    🇲🇾 MY Alliance Bank (Business) ALLIANCE_FPX_BUSINESS
    🇲🇾 MY AmBank AMBANK_FPX_BUSINESS
    🇲🇾 MY Bank Islam ISLAM_FPX_BUSINESS
    🇲🇾 MY Bank Muamalat MUAMALAT_FPX_BUSINESS
    🇲🇾 MY BNP Paribas BNP_FPX_BUSINESS
    🇲🇾 MY CIMB Bank CIMB_FPX_BUSINESS
    🇲🇾 MY Citibank Corporate Banking CITIBANK_FPX_BUSINESS
    🇲🇾 MY Deutsche Bank DEUTSCHE_FPX_BUSINESS
    🇲🇾 MY Hong Leong Bank HLB_FPX_BUSINESS
    🇲🇾 MY HSBC Bank HSBC_FPX_BUSINESS
    🇲🇾 MY i-bizRAKYAT RAKYAT_FPX_BUSINESS
    🇲🇾 MY KFH KFH_FPX_BUSINESS
    🇲🇾 MY Maybank2E MAYB2E_FPX_BUSINESS
    🇲🇾 MY OCBC Bank OCBC_FPX_BUSINESS
    🇲🇾 MY Public Bank PB enterprise PUBLIC_FPX_BUSINESS
    🇲🇾 MY RHB Bank RHB_FPX_BUSINESS
    🇲🇾 MY Standard Chartered SCH_FPX_BUSINESS
    🇲🇾 MY UOB Regional UOB_FPX_BUSINESS

    Over-the-Counter/Retail Outlet 🇲🇨 🇵🇭

    The following channels are supported for payment method type OVER_THE_COUNTER. You may visit our docs page for more information about over-the-counter or retail outlet channels.

    COUNTRY
    CHANNEL NAME
    CHANNEL CODE
    ONE TIME USE
    MULTIPLE USE
    REFUND
    🇲🇨 ID Alfamart ALFAMART
    🇲🇨 ID Indomaret INDOMARET
    🇵🇭 PH 7-Eleven via 7-Connect Code 7ELEVEN
    🇵🇭 PH 7-Eleven via CliQQ 7ELEVEN_CLIQQ
    🇵🇭 PH Cebuana Lhuillier CEBUANA
    🇵🇭 PH ECPay ECPAY
    🇵🇭 PH Palawan Express PALAWAN
    🇵🇭 PH MLhuillier MLHUILLIER
    🇵🇭 PH ECPay via Dragonloan¹ ECPAY_DRAGONLOAN
    🇵🇭 PH LBC LBC
    🇵🇭 PH RD_PAWNSHOP RD_PAWNSHOP
    🇵🇭 PH CVM CVM
    🇵🇭 PH ECPAY_SCHOOL ECPAY_SCHOOL
    🇵🇭 PH USSC USSC
    🇵🇭 PH SM_BILLS SM_BILLS
    🇵🇭 PH ROBINSONS_BILLS ROBINSONS_BILLS

    Virtual Account 🇲🇨 🇻🇳 🇹🇭 🇵🇭 🇲🇾

    The following channels are supported for payment method type VIRTUAL_ACCOUNT. For more information about virtual accounts, you may visit our docs page.

    COUNTRY
    CHANNEL NAME
    CHANNEL CODE
    ONE TIME USE
    MULTIPLE USE
    REFUND
    🇲🇨 ID BCA BCA
    🇲🇨 ID BJB BJB
    🇲🇨 ID BNI BNI
    🇲🇨 ID BRI BRI
    🇲🇨 ID BSI BSI
    🇲🇨 ID BSS (BANK SAHABAT SAMPOERNA) BSS (BANK SAHABAT SAMPOERNA)
    🇲🇨 ID CIMB CIMB
    🇲🇨 ID MANDIRI MANDIRI
    🇲🇨 ID PERMATA PERMATA
    🇻🇳 VN PV PV
    🇻🇳 VN VIET CAPITAL VIETCAPITAL
    🇻🇳 VN WOORI WOORI
    🇻🇳 VN MSB MSB
    🇻🇳 VN VPB VPB
    🇻🇳 VN BIDV BIDV
    🇹🇭 TH STANDARD CHARTERED STANDARD_CHARTERED
    🇵🇭 PH INSTAPAY / PESONET BANK_TRANSFER
    🇲🇾 MY UOB UOB
    🇲🇾 MY AMBANK AMBANK

    QR Code 🇮🇩 🇹🇭

    The following channels are supported for payment method type QR_CODE. You may visit our docs page for more information about QR Code payments.

    COUNTRY
    CHANNEL NAME
    CHANNEL CODE
    ONE TIME USE
    MULTIPLE USE
    REFUND
    🇮🇩 ID DANA (QRIS) DANA
    🇮🇩 ID Linkaja (QRIS) LINKAJA
    🇹🇭 TH PromptPay PROMPTPAY
    🇵🇭 PH QRPH QRPH

    Supported Issuers for QR Code Refunds

    COUNTRY
    ISSUER
    FULL AMOUNT (WITHIN 24 HOURS)
    FULL AMOUNT (AFTER 24 HOURS)
    PARTIAL AMOUNT
    🇮🇩 ID DANA
    🇮🇩 ID ShopeePay
    🇮🇩 ID OVO
    🇮🇩 ID LinkAja
    🇮🇩 ID Mandiri
    🇮🇩 ID Permata
    🇮🇩 ID CIMB
    🇮🇩 ID Jenius / BTPN
    🇮🇩 ID BSI

    Card 🇮🇩 🇵🇭

    The following channels are supported for payment method type CARD. You may visit our docs page for more information about Card payments.

    Country
    Currencies
    ONE TIME USE
    MULTIPLE USE
    REFUND
    🇮🇩 ID Indonesian Rupiah (IDR)
    🇵🇭 PH Philippines Peso (PHP)
    United States Dollar (USD)

    BI SNAP

    Our BI SNAP API allows you to charge and receive payments compliantly in Indonesia. BI SNAP is used for Indonesian merchants collecting payments from Ewallets, QRIS and Bank payment methods in Indonesia.

    Create Account Binding

    Endpoint: Create Account Binding Request

    POST https://api.xendit.co/snap/v1.0/registration-account-binding

    SNAP Account Binding

    This API will be used to create a account binding without doing a payment. Account binding returns a token that can be used for subsequent payments.

    Request Parameters

    Example: Create Account Binding Request

    curl https://api.xendit.co//snap/v1.0/registration-account-binding -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
        "partnerReferenceNo": "371d8a6e-587c-4789-bea5-fac4319b2409",
        "phoneNo": "+628123123123",
        "additionalData": {
            "userId": "fc4c060b-3c41-4707-b7b2-df9c3376edde"
        },
        "additionalInfo": {
            "payMethod": "EWALLET",
            "payOption": "OVO",
            "reusability": "ONE_TIME_USE",
            "metadata": {
            "sku": "ABCDEFGH"
            }
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    Body Parameter Type Description
    partnerReferenceNo
    optional
    string Transaction identifier on service consumer system
    additionalData
    conditionally required
    object Channel specific information required for the transaction to be initiated
    Conditional for BRI
    Key Value
    userId
    required
    string Xendit-generated identifier for the end-customer. Will be required for certain payment channels such as Multiple-use e-wallets and direct debit.
    email
    required
    string Email address of the customer that is registered to the partner channel. Mandatory for BRI Direct Debit.
    merchantId
    optional
    string Xendit-generated identifier for the business that owns the transaction. This field is ignored by Xendit
    phoneNo
    optional
    string Registered mobile number of the end-customer to the channel partner in E.164 Format. Mandatory for: OVO (ONE_TIME_USE) BRI
    additionalInfo
    required
    object Additional information required to complete the transaction
    Object parameters details
    Key Value
    payMethod
    required
    string Type of payment method. Allowed values: EWALLET, DIRECT_DEBIT
    payOption
    required
    string Identifier for the payment channel partner. Allowed values for payOption EWALLET: OVO, DANA, LINKAJA, JENIUSPAY, ASTRAPAY, SHOPEEPAY. Allowed values for payOption DIRECT_DEBIT: BRI
    reusability
    optional
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again. Allowed values: ONE_TIME_USE, MULTIPLE_USE. Default value: ONE_TIME_USE
    description
    optional
    string Free-text field for any additional information regarding the payment method
    metadata
    optional
    object A free-format JSON for additional information that you may use.
    channelProperties
    optional
    object Channel specific information required for the transaction to be initiated
    Object parameters details
    Key Value
    successReturnUrl
    optional
    string URL where the end-customer is redirected if the authorization is successful
    failureReturnUrl
    optional
    string URL where the end-customer is redirected if the authorization has failed
    cancelReturnUrl
    optional
    string URL where the end-customer is redirected if the authorization has been cancelled
    cashtag
    optional
    string Cashtag registered for JENIUSPAY. Mandatory for JENIUSPAY
    cardLastFour
    optional
    string Last four digits of the debit card. Mandatory for BRI
    cardExpiry
    optional
    string Expiry month and year of the debit card (in MM/YY format). Mandatory for BRI

    Response Parameters

    Example: Create Account Binding Request API Success Response

    {
      "responseCode": "2020700",
      "responseMessage": "Request In Progress",
      "referenceNo": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
      "partnerReferenceNo": "371d8a6e-587c-4789-bea5-fac4319b2409",
      "additionalInfo": {
        "paymentMethod": {
          "id": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
          "type": "EWALLET",
          "reusability": "ONE_TIME_USE",
          "customerId": "fc4c060b-3c41-4707-b7b2-df9c3376edde",
          "businessId": "5f27a14a9bf05c73dd040bc8",
          "status": "PENDING",
          "country": "ID",
          "ewallet": {
            "channelCode": "OVO",
            "channelProperties": {
              "mobileNumber": "+628123123123"
            },
            "account": {
              "accountDetails": null,
              "name": null,
              "balance": null,
              "pointBalance": null
            }
          },
          "referenceId": "371d8a6e-587c-4789-bea5-fac4319b2409",
          "created": "2020-08-29T09:12:33.001Z",
          "updated": "2020-08-29T09:12:33.001Z",
          "metadata": {
            "sku": "ABCDEFGH"
          }
        }
      }
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    referenceNo
    required
    string Unique identifier for the payment method. This has a prefix of pm-
    partnerReferenceNo
    optional
    string Merchant-provided identifier for this specific transaction.
    nextAction
    optional
    string URL to authentication page.
    params
    optional
    object
    Object parameters details
    Key Value
    action
    optional
    string Action to take
    redirectToDeeplink
    optional
    string The provided redirect url utilizes deep linking to the channel partner’s platform. May be present even if nextAction is provided.
    userInfo
    optional
    object
    Object parameters details
    Key Value
    publicUserId
    optional
    string Masked public identifier for the e-wallet account. This typically contains the masked mobile number registered to the e-wallet account.
    additionalInfo
    required
    object
    Payment method object details
    Key Value
    id
    required
    string Unique identifier for the payment method. This has a prefix of pm-. Example: pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
    business_id
    required
    string Xendit-generated identifier for the business that owns the transaction
    customer_id
    nullable
    string ID of the customer object to which the account token will be linked to
    reference_id
    nullable
    string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
    Maximum length: 255 characters
    reusability
    required
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

    Possible values:
    • ONE_TIME_USE
    • MULTIPLE_USE
    country
    required
    string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
    status
    required
    string Status of the payment method.

    Possible values:
    • REQUIRES_ACTION - The request passed validation but requires additional steps in order to activate the payment method for use. Typical actions are for merchant to trigger OTP validation or redirect your customer to authentication page.
    • ACTIVE - The payment method can be used for payment requests (for Cards, E-wallets, Direct Debit) or can now accept payments (for Virtual Account, Over-the-Counter, QR Code)
    • INACTIVE - Merchant-toggled status to temporarily prevent further transactions from the payment method. This status is reversible.
    • EXPIRED - The underlying authorization has expired, invalidated, or has been unlinked. This status is not reversible.
    • PENDING - The request is successfully passed, and need to acivate asynchronously. Please listen to our callback to get the updated status.
    • FAILED - For Cards Payment Methods, this means the card was not successfully tokenized. For Direct Debit Payment Methods, this indicates that the account is already linked for the cend customer.
    actions
    required
    object array If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to activate a payment method. Only one of the provided actions is required to be fulfilled. If no further action is needed, this parameter will be an empty array [].

    Each object will have the following properties:
    Key Value
    method
    required
    string HTTP method for calling the url.

    Possible values:
    • GET
    • POST
    url_type
    required
    string Type of url for the specific action.

    Possible values:
    • API - The provided url is a server-side API, merchant will need to provide necessary information to the API
    • WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
    • MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
    • DEEPLINK - The provided redirect url utilizes deep linking to the channel partner’s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
    action
    required
    string Describes the purpose the corresponding action

    Possible values:
    • AUTH - Trigger this action in order to authorize linking or payment.
    • RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer.
    url
    required
    string The generated URL to hit in order to perform the action
    type
    required
    string Type of payment method. Refer to the corresponding object to access further information

    Possible values:
    • EWALLET
    • DIRECT_DEBIT
    • CARD
    • VIRTUAL_ACCOUNT
    • OVER_THE_COUNTER
    • QR_CODE
    ewallet
    nullable
    object For type='EWALLET', this contains the necessary information to describe an ewallet payment method. This will be null otherwise.
    Please refer to Ewallet Object for more parameter details.
    direct_debit
    nullable
    object For type='DIRECT_DEBIT', this contains the necessary information to describe a direct debit payment method. This will be null otherwise.
    Please refer to Direct debit Object for more parameter details.
    description
    nullable
    string Free-text field for any additional information regarding the payment method.
    Maximum length: 255 characters
    failure_code
    nullable
    string If the status of the transaction is FAILED, this describes the reason for failure.
    Will be null if the transaction did not fail.
    See possible codes here.
    created
    required
    string ISO 8601 Timestamp for Payment Method object creation. Timezone UTC+0
    updated
    required
    string ISO 8601 Timestamp for latest Payment Method object update. Timezone UTC+0
    metadata
    nullable
    object User defined object with JSON properties and values passed in during Payment Method creation.

    Error Codes

    Example: Create Binding Request API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4000700 Generic parsing error
    400 4000701 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4000702 Missing mandatory field or header
    401 4010700 Generic authorization error
    401 4010701 The provided Authorization bearer token is invalid
    403 4010701 The merchant is not allowed to perform this request
    403 4010715 Generic forbidden error
    403 4010723 The amount specified is either smaller or greater than supported by the channel.
    409 4090700 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4090701 An object with the same reference already exists

    Inquire Account Binding Status

    Endpoint: Inquire Account Binding Status

    POST https://api.xendit.co/snap/v1.0/registration-account-inquiry

    Request Parameters

    Example: Inquire Account Binding Status

    curl https://api.xendit.co/snap/v1.0/registration-account-inquiry -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
        "partnerReferenceNo": "371d8a6e-587c-4789-bea5-fac4319b2409"
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    Body Parameter Type Description
    partnerReferenceNo
    optional
    string Transaction identifier on service consumer system

    Response Parameters

    Example: Inquire Account Binding Status API Success Response

    {
      "responseCode": "2000800",
      "responseMessage": "Successful",
      "referenceNo": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
      "partnerReferenceNo": "371d8a6e-587c-4789-bea5-fac4319b2409",
      "accountCurrency": "IDR",
      "additionalInfo": {
        "paymentMethod": {
          "id": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
          "type": "DIRECT_DEBIT",
          "reusability": "MULTIPLE_USE",
          "customerId": "fc4c060b-3c41-4707-b7b2-df9c3376edde",
          "businessId": "5f27a14a9bf05c73dd040bc8",
          "status": "REQUIRES_ACTION",
          "country": "ID",
          "actions": [
            {
              "action": "AUTH",
              "urlType": "API",
              "url": "https://api.xendit.co/payment_methods/d0860b92-a72e-41ff-a758-33850a6f8683/auth",
              "method": "POST"
            }
          ],
          "directDebit": {
            "channelCode": "BRI",
            "type": "DEBIT_CARD",
            "channelProperties": {
              "mobileNumber": "+62818555988",
              "cardLastFour": "8888",
              "cardExpiry": "06/24",
              "email": "test.email@xendit.co"
            },
            "debitCard": {
              "mobileNumber": "+62818555988",
              "cardLastFour": "8888",
              "cardExpiry": "06/24",
              "email": "test.email@xendit.co"
            },
            "bankAccount": null
          },
          "referenceId": "371d8a6e-587c-4789-bea5-fac4319b2409",
          "created": "2020-08-29T09:12:33.001Z",
          "updated": "2020-08-29T09:12:33.001Z",
          "metadata": {
            "sku": "ABCDEFGH"
          }
        }
      }
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    referenceNo
    optional
    string Unique identifier for the payment method. This has a prefix of pm-
    partnerReferenceNo
    optional
    string Merchant-provided identifier for this specific transaction.
    accountCurrency
    required
    string Always set to 'IDR'.
    accountName
    optional
    string Registered account name.
    additionalInfo
    required
    object
    Payment method object details
    Key Value
    id
    required
    string Unique identifier for the payment method. This has a prefix of pm-. Example: pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
    business_id
    required
    string Xendit-generated identifier for the business that owns the transaction
    customer_id
    nullable
    string ID of the customer object to which the account token will be linked to
    reference_id
    nullable
    string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
    Maximum length: 255 characters
    reusability
    required
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

    Possible values:
    • ONE_TIME_USE
    • MULTIPLE_USE
    country
    required
    string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
    status
    required
    string Status of the payment method.

    Possible values:
    • REQUIRES_ACTION - The request passed validation but requires additional steps in order to activate the payment method for use. Typical actions are for merchant to trigger OTP validation or redirect your customer to authentication page.
    • ACTIVE - The payment method can be used for payment requests (for Cards, E-wallets, Direct Debit) or can now accept payments (for Virtual Account, Over-the-Counter, QR Code)
    • INACTIVE - Merchant-toggled status to temporarily prevent further transactions from the payment method. This status is reversible.
    • EXPIRED - The underlying authorization has expired, invalidated, or has been unlinked. This status is not reversible.
    • PENDING - The request is successfully passed, and need to acivate asynchronously. Please listen to our callback to get the updated status.
    • FAILED - For Cards Payment Methods, this means the card was not successfully tokenized. For Direct Debit Payment Methods, this indicates that the account is already linked for the cend customer.
    actions
    required
    object array If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to activate a payment method. Only one of the provided actions is required to be fulfilled. If no further action is needed, this parameter will be an empty array [].

    Each object will have the following properties:
    Key Value
    method
    required
    string HTTP method for calling the url.

    Possible values:
    • GET
    • POST
    url_type
    required
    string Type of url for the specific action.

    Possible values:
    • API - The provided url is a server-side API, merchant will need to provide necessary information to the API
    • WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
    • MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
    • DEEPLINK - The provided redirect url utilizes deep linking to the channel partner’s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
    action
    required
    string Describes the purpose the corresponding action

    Possible values:
    • AUTH - Trigger this action in order to authorize linking or payment.
    • RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer.
    url
    required
    string The generated URL to hit in order to perform the action
    type
    required
    string Type of payment method. Refer to the corresponding object to access further information

    Possible values:
    • EWALLET
    • DIRECT_DEBIT
    • CARD
    • VIRTUAL_ACCOUNT
    • OVER_THE_COUNTER
    • QR_CODE
    ewallet
    nullable
    object For type='EWALLET', this contains the necessary information to describe an ewallet payment method. This will be null otherwise.
    Please refer to Ewallet Object for more parameter details.
    direct_debit
    nullable
    object For type='DIRECT_DEBIT', this contains the necessary information to describe a direct debit payment method. This will be null otherwise.
    Please refer to Direct debit Object for more parameter details.
    description
    nullable
    string Free-text field for any additional information regarding the payment method.
    Maximum length: 255 characters
    failure_code
    nullable
    string If the status of the transaction is FAILED, this describes the reason for failure.
    Will be null if the transaction did not fail.
    See possible codes here.
    created
    required
    string ISO 8601 Timestamp for Payment Method object creation. Timezone UTC+0
    updated
    required
    string ISO 8601 Timestamp for latest Payment Method object update. Timezone UTC+0
    metadata
    nullable
    object User defined object with JSON properties and values passed in during Payment Method creation.

    Error Codes

    Example: Inquire Binding Request API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4000800 Generic parsing error
    400 4000801 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4000802 Missing mandatory field or header
    401 4010800 Generic authorization error
    401 4010801 The provided Authorization bearer token is invalid
    403 4010801 The merchant is not allowed to perform this request
    403 4010815 Generic forbidden error
    403 4010823 The amount specified is either smaller or greater than supported by the channel.
    409 4090800 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4090801 An object with the same reference already exists

    Unbind Account

    Endpoint: Unbind Account

    POST https://api.xendit.co/snap/v1.0/registration-account-unbinding

    Request Parameters

    Example: Unbind Account

    curl https://api.xendit.co/snap/v1.0/registration-account-inquiry -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
        "partnerReferenceNo": "371d8a6e-587c-4789-bea5-fac4319b2409"
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    Body Parameter Type Description
    partnerReferenceNo
    optional
    string Transaction identifier on service consumer system

    Response Parameters

    Example: Unbind Account API Success Response

    {
      "responseCode": "2000800",
      "responseMessage": "Successful",
      "referenceNo": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
      "partnerReferenceNo": "371d8a6e-587c-4789-bea5-fac4319b2409",
      "accountCurrency": "IDR",
      "additionalInfo": {
        "paymentMethod": {
          "id": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
          "type": "DIRECT_DEBIT",
          "reusability": "MULTIPLE_USE",
          "customerId": "fc4c060b-3c41-4707-b7b2-df9c3376edde",
          "businessId": "5f27a14a9bf05c73dd040bc8",
          "status": "INACTIVE",
          "country": "ID",
          "actions": [
            {
              "action": "AUTH",
              "urlType": "API",
              "url": "https://api.xendit.co/payment_methods/d0860b92-a72e-41ff-a758-33850a6f8683/auth",
              "method": "POST"
            }
          ],
          "directDebit": {
            "channelCode": "BRI",
            "type": "DEBIT_CARD",
            "channelProperties": {
              "mobileNumber": "+62818555988",
              "cardLastFour": "8888",
              "cardExpiry": "06/24",
              "email": "test.email@xendit.co"
            },
            "debitCard": {
              "mobileNumber": "+62818555988",
              "cardLastFour": "8888",
              "cardExpiry": "06/24",
              "email": "test.email@xendit.co"
            },
            "bankAccount": null
          },
          "referenceId": "371d8a6e-587c-4789-bea5-fac4319b2409",
          "created": "2020-08-29T09:12:33.001Z",
          "updated": "2020-08-29T09:12:33.001Z",
          "metadata": {
            "sku": "ABCDEFGH"
          }
        }
      }
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    referenceNo
    optional
    string Unique identifier for the payment method. This has a prefix of pm-
    partnerReferenceNo
    optional
    string Merchant-provided identifier for this specific transaction.
    accountCurrency
    required
    string Always set to 'IDR'.
    accountName
    optional
    string Registered account name.
    additionalInfo
    required
    object
    Payment method object details
    Key Value
    id
    required
    string Unique identifier for the payment method. This has a prefix of pm-. Example: pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
    business_id
    required
    string Xendit-generated identifier for the business that owns the transaction
    customer_id
    nullable
    string ID of the customer object to which the account token will be linked to
    reference_id
    nullable
    string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
    Maximum length: 255 characters
    reusability
    required
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

    Possible values:
    • ONE_TIME_USE
    • MULTIPLE_USE
    country
    required
    string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
    status
    required
    string Status of the payment method.

    Possible values:
    • REQUIRES_ACTION - The request passed validation but requires additional steps in order to activate the payment method for use. Typical actions are for merchant to trigger OTP validation or redirect your customer to authentication page.
    • ACTIVE - The payment method can be used for payment requests (for Cards, E-wallets, Direct Debit) or can now accept payments (for Virtual Account, Over-the-Counter, QR Code)
    • INACTIVE - Merchant-toggled status to temporarily prevent further transactions from the payment method. This status is reversible.
    • EXPIRED - The underlying authorization has expired, invalidated, or has been unlinked. This status is not reversible.
    • PENDING - The request is successfully passed, and need to acivate asynchronously. Please listen to our callback to get the updated status.
    • FAILED - For Cards Payment Methods, this means the card was not successfully tokenized. For Direct Debit Payment Methods, this indicates that the account is already linked for the cend customer.
    actions
    required
    object array If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to activate a payment method. Only one of the provided actions is required to be fulfilled. If no further action is needed, this parameter will be an empty array [].

    Each object will have the following properties:
    Key Value
    method
    required
    string HTTP method for calling the url.

    Possible values:
    • GET
    • POST
    url_type
    required
    string Type of url for the specific action.

    Possible values:
    • API - The provided url is a server-side API, merchant will need to provide necessary information to the API
    • WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
    • MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
    • DEEPLINK - The provided redirect url utilizes deep linking to the channel partner’s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
    action
    required
    string Describes the purpose the corresponding action

    Possible values:
    • AUTH - Trigger this action in order to authorize linking or payment.
    • RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer.
    url
    required
    string The generated URL to hit in order to perform the action
    type
    required
    string Type of payment method. Refer to the corresponding object to access further information

    Possible values:
    • EWALLET
    • DIRECT_DEBIT
    • CARD
    • VIRTUAL_ACCOUNT
    • OVER_THE_COUNTER
    • QR_CODE
    ewallet
    nullable
    object For type='EWALLET', this contains the necessary information to describe an ewallet payment method. This will be null otherwise.
    Please refer to Ewallet Object for more parameter details.
    direct_debit
    nullable
    object For type='DIRECT_DEBIT', this contains the necessary information to describe a direct debit payment method. This will be null otherwise.
    Please refer to Direct debit Object for more parameter details.
    description
    nullable
    string Free-text field for any additional information regarding the payment method.
    Maximum length: 255 characters
    failure_code
    nullable
    string If the status of the transaction is FAILED, this describes the reason for failure.
    Will be null if the transaction did not fail.
    See possible codes here.
    created
    required
    string ISO 8601 Timestamp for Payment Method object creation. Timezone UTC+0
    updated
    required
    string ISO 8601 Timestamp for latest Payment Method object update. Timezone UTC+0
    metadata
    nullable
    object User defined object with JSON properties and values passed in during Payment Method creation.

    Error Codes

    Example: Cancel Binding Request API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4000800 Generic parsing error
    400 4000801 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4000802 Missing mandatory field or header
    401 4010800 Generic authorization error
    401 4010801 The provided Authorization bearer token is invalid
    403 4010801 The merchant is not allowed to perform this request
    403 4010815 Generic forbidden error
    403 4010823 The amount specified is either smaller or greater than supported by the channel.
    409 4090800 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4090801 An object with the same reference already exists

    OTP Verify Account Binding

    Endpoint: OTP Verify Account Binding

    POST https://api.xendit.co/snap/v1.0/otp-verification

    Request Parameters

    Example: OTP Verify Account Binding

    curl https://api.xendit.co/snap/v1.0/registration-account-inquiry -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
        "originalReferenceNo": "pm-bc9faa22-23e5-486e-bfee-869c46d32cc3",
        "otp": "123456",
        "type": "binding"
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    Body Parameter Type Description
    originalReferenceNo
    required
    string Xendit Generated ID for the payment method
    otp
    required
    string The authorization code or OTP inputted by the end customer
    type
    required
    string Must be set to 'binding'

    Response Parameters

    Example: Inquire Account Binding Status API Success Response

    {
      "responseCode": "2000400",
      "responseMessage": "Successful",
      "originalReferenceNo": "pm-bc9faa22-23e5-486e-bfee-869c46d32cc3",
      "originalPartnerReferenceNo": "0f38e017-007f-4134-9e5d-86657ec0cf77"
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    originalReferenceNo
    optional
    string Unique identifier for the payment method. Prefix will vary according to the payment method used.
    originalPartnerReferenceNo
    optional
    string Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions.
    customerId
    optional
    string Xendit-generated identifier for the end-customer.

    Error Codes

    Example: Validate Binding Request API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4000400 Generic parsing error
    400 4000401 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4000402 Missing mandatory field or header
    401 4010400 Generic authorization error
    401 4010401 The provided Authorization bearer token is invalid
    403 4010401 The merchant is not allowed to perform this request
    403 4010415 Generic forbidden error
    403 4010423 The amount specified is either smaller or greater than supported by the channel.
    409 4090400 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4090401 An object with the same reference already exists

    VA - Create

    Endpoint: Create VA Request

    POST https://api.xendit.co/snap/v1.0/transfer-va/create-va

    SNAP Create Virtual Account

    This API will be used to create a new Virtual Account (Service code: 27)

    Request Parameters

    Example: Create Virtual Account Request

    curl https://api.xendit.co/snap/v1.0/transfer-va/create-va -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
            "virtualAccountName": "John Doe",
            "trxId": "12349876",
            "totalAmount": {
                "value": "10000.00",
                "currency": "IDR"
            },
            "freeTexts": [
                {
                "english": "Please pay for service"
                }
            ],
            "expiredDate": "2020-12-31T23:59:59-07:00",
            "additionalInfo": {
                "channelCode": "MANDIRI",
                "reusability": "ONE_TIME_USE"
            }
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    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.
    WITH-SPLIT-RULE
    optional
    string Split Rule ID that you would like to apply to this charge. This header is only used if you are a xenPlatform user. Please note: If you include this parameter, we will return the split_rule_id in the header of the API response. If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account.
    Body Parameter Type Description
    partnerServiceId
    optional
    string This field is ignored by Xendit.
    customerNo
    optional
    string This field is ignored by Xendit.
    virtualAccountNo
    optional
    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 and don't include the merchant code as prefix.
    virtualAccountName
    required
    string Complete name of the payor. May be used by the channel partner to verify their identity.
    Characters Only alphabet. For BCA Aggregator, alphabet and number are allowed. Minimum length 1 character, except BCA the minimum length is 3 characters.
    trxId
    required
    string Merchant-provided identifier for this specific transaction. Please note that this field needs to be unique for each Virtual Account.
    totalAmount
    conditionally required
    object Expected amount of the transaction in the actual value in the provided currency. Can be left blank for Open Virtual Account amounts.
    Conditional for Closed Virtual amounts
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    freeTexts
    optional
    array of object Xendit will concatenate all text entries in this section to form the Virtual Account description.
    Free text objects
    Object Key Value
    english
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    indonesia
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    expiredDate
    optional
    string ISO-8601 Expiration date for Virtual Account. Example: 2023-12-12T23:59:59+07:00. The default expiration date will be 31 years from creation date
    additionalInfo
    required
    object Additional information required to complete the transaction
    Object parameters details
    Key Value
    channelCode
    required
    string Identifier for the payment channel partner. Allowed values: BCA, BSI, BJB, CIMB, SAHABAT_SAMPOERNA, ARTAJASA, BRI, BNI, MANDIRI, PERMATA
    suggestedAmount
    optional
    number The suggested amount you want to assign. It is the amounts that will be displayed to the payor, but payor can still put any number (only supported for MANDIRI and BRI).
    reusability
    optional
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again. Allowed values: ONE_TIME_USE, MULTIPLE_USE. Default value: ONE_TIME_USE
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Response Parameters

    Example: Create Virtual Account Request API Success Response

    {
      "responseCode": "2002700",
      "responseMessage": "Success",
      "virtualAccountData": {
        "partnerServiceId": "123459",
        "customerNo": "99993701870",
        "virtualAccountNo": "1234599993701870",
        "virtualAccountName": "John Doe",
        "trxId": "12349876",
        "expiredDate": "2023-12-31T23:59:59.000Z",
        "additionalInfo": {
          "id": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
          "status": "ACTIVE",
          "reusability": "MULTIPLE_USE",
          "channelCode": "BRI"
        }
      }
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    virtualAccountData
    optional
    object
    Only for successful responses
    Key Type Value
    partnerServiceId
    required
    string Prefix for the Virtual Account.
    customerNo
    required
    string Virtual Account number (excluding the partnerServiceId / prefix).
    virtualAccountNo
    required
    string The complete Virtual Account number (including the partnerServiceId / prefix). This is what a user will use to pay Virtual Account.
    virtualAccountName
    required
    string Complete name of the payer. May be used by the channel partner to verify their identity.
    trxId
    required
    string Merchant-provided identifier for this specific transaction.
    totalAmount
    conditionally required
    object Expected amount of the transaction in the actual value in the provided currency. Can be left blank for Open Virtual Account amounts.
    Conditional for Closed Virtual amounts
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    freeTexts
    optional
    array of object Xendit will concatenate all text entries in this section to form the Virtual Account description.
    Free text objects
    Object Key Value
    english
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    indonesia
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    expiredDate
    optional
    string ISO-8601 Expiration date for Virtual Account. Example: 2023-12-12T23:59:59+07:00. The default expiration date will be 31 years from creation date
    additionalInfo
    required
    object Additional information required to complete the transaction
    Object parameters details
    Key Value
    id
    required
    string Generated ID for the payment method. It has pm- as its prefix.
    status
    required
    string Status of the payment method. Allowed values: PENDING, ACTIVE, EXPIRED
    channelCode
    required
    string Identifier for the payment channel partner. Allowed values: BCA, BSI, BJB, CIMB, SAHABAT_SAMPOERNA, ARTAJASA, BRI, BNI, MANDIRI, PERMATA
    suggestedAmount
    optional
    number The suggested amount you want to assign. It is the amounts that will be displayed to the payor, but payor can still put any number (only supported for MANDIRI and BRI).
    reusability
    optional
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again. Allowed values: ONE_TIME_USE, MULTIPLE_USE. Default value: ONE_TIME_USE
    created
    optional
    string Timestamp in ISO 8601 format when the PaymentMethod was created.
    updated
    optional
    string Timestamp in ISO 8601 format when the PaymentMethod was last updated.
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Error Codes

    Example: Create Virtual Account Request API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4002700 Generic parsing error
    400 4002701 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4002702 Missing mandatory field or header
    401 4012700 Generic authorization error
    401 4012701 The provided Authorization bearer token is invalid
    403 4012701 The merchant is not allowed to perform this request
    403 4012715 Generic forbidden error
    403 4012723 The amount specified is either smaller or greater than supported by the channel.
    409 4092700 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4092701 An object with the same reference already exists

    VA - Inquire Status

    Endpoint: Inquire VA Request Status

    POST https://api.xendit.co/snap/v1.0/transfer-va/inquiry-va

    SNAP Inquire Virtual Account Status

    Inquire on the status of an existing Virtual Account. (Service code: 30)

    Request Parameters

    Example: Inquire Virtual Account Request Status

    curl https://api.xendit.co/snap/v1.0/transfer-va/inquiry-va -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
          "trxId": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39"
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    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.
    WITH-SPLIT-RULE
    optional
    string Split Rule ID that you would like to apply to this charge. This header is only used if you are a xenPlatform user. Please note: If you include this parameter, we will return the split_rule_id in the header of the API response. If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account.
    Body Parameter Type Description
    partnerServiceId
    optional
    string This field is ignored by Xendit.
    customerNo
    optional
    string This field is ignored by Xendit.
    virtualAccountNo
    optional
    string This field is ignored by Xendit.
    trxId
    required
    string Merchant-provided identifier for this specific transaction. Please note that this field needs to be unique for each Virtual Account.

    Response Parameters

    Example: Create Virtual Account Request API Success Response

    {
      "responseCode": "2002700",
      "responseMessage": "Success",
      "virtualAccountData": {
        "partnerServiceId": "123459",
        "customerNo": "99993701870",
        "virtualAccountNo": "1234599993701870",
        "virtualAccountName": "John Doe",
        "trxId": "12349876",
        "expiredDate": "2023-12-31T23:59:59.000Z",
        "additionalInfo": {
          "id": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
          "status": "ACTIVE",
          "reusability": "MULTIPLE_USE",
          "channelCode": "BRI"
        }
      }
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    virtualAccountData
    optional
    object
    Only for successful responses
    Key Type Value
    partnerServiceId
    required
    string Prefix for the Virtual Account.
    customerNo
    required
    string Virtual Account number (excluding the partnerServiceId / prefix).
    virtualAccountNo
    required
    string The complete Virtual Account number (including the partnerServiceId / prefix). This is what a user will use to pay Virtual Account.
    virtualAccountName
    required
    string Complete name of the payer. May be used by the channel partner to verify their identity.
    trxId
    required
    string Merchant-provided identifier for this specific transaction.
    totalAmount
    conditionally required
    object Expected amount of the transaction in the actual value in the provided currency. Can be left blank for Open Virtual Account amounts.
    Conditional for Closed Virtual amounts
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    freeTexts
    optional
    array of object Xendit will concatenate all text entries in this section to form the Virtual Account description.
    Free text objects
    Object Key Value
    english
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    indonesia
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    expiredDate
    optional
    string ISO-8601 Expiration date for Virtual Account. Example: 2023-12-12T23:59:59+07:00. The default expiration date will be 31 years from creation date
    additionalInfo
    required
    object Additional information required to complete the transaction
    Object parameters details
    Key Value
    id
    required
    string Generated ID for the payment method. It has pm- as its prefix.
    status
    required
    string Status of the payment method. Allowed values: PENDING, ACTIVE, EXPIRED
    channelCode
    required
    string Identifier for the payment channel partner. Allowed values: BCA, BSI, BJB, CIMB, SAHABAT_SAMPOERNA, ARTAJASA, BRI, BNI, MANDIRI, PERMATA
    suggestedAmount
    optional
    number The suggested amount you want to assign. It is the amounts that will be displayed to the payor, but payor can still put any number (only supported for MANDIRI and BRI).
    reusability
    optional
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again. Allowed values: ONE_TIME_USE, MULTIPLE_USE. Default value: ONE_TIME_USE
    created
    optional
    string Timestamp in ISO 8601 format when the PaymentMethod was created.
    updated
    optional
    string Timestamp in ISO 8601 format when the PaymentMethod was last updated.
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Error Codes

    Example: Inquire Virtual Account Request API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4003000 Generic parsing error
    400 4003001 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4003002 Missing mandatory field or header
    401 4013000 Generic authorization error
    401 4013001 The provided Authorization bearer token is invalid
    403 4013001 The merchant is not allowed to perform this request
    403 4013015 Generic forbidden error
    403 4013023 The amount specified is either smaller or greater than supported by the channel.
    409 4093000 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4093001 An object with the same reference already exists

    VA - Update

    Endpoint: Update VA Request

    POST https://api.xendit.co/snap/v1.0/transfer-va/update-va

    SNAP Update Virtual Account

    Update an existing Virtual Account. Please also note that closed VAs can not be changed to open VAs and vice versa. (Service code: 28)

    Request Parameters

    Example: Update Virtual Account Request

    curl https://api.xendit.co/snap/v1.0/transfer-va/update-va -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
            "virtualAccountName": "John Doe",
            "totalAmount": {
                "value": "10000.00",
                "currency": "IDR"
            },
            "freeTexts": [
                {
                "english": "Please pay for service"
                }
            ],
            "expiredDate": "2020-12-31T23:59:59-07:00"
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    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.
    WITH-SPLIT-RULE
    optional
    string Split Rule ID that you would like to apply to this charge. This header is only used if you are a xenPlatform user. Please note: If you include this parameter, we will return the split_rule_id in the header of the API response. If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account.
    Body Parameter Type Description
    partnerServiceId
    optional
    string This field is ignored by Xendit.
    customerNo
    optional
    string This field is ignored by Xendit.
    virtualAccountName
    required
    string Complete name of the payor. May be used by the channel partner to verify their identity.
    Characters Only alphabet. For BCA Aggregator, alphabet and number are allowed. Minimum length 1 character, except BCA the minimum length is 3 characters.
    totalAmount
    conditionally required
    object Expected amount of the transaction in the actual value in the provided currency. Can be left blank for Open Virtual Account amounts.
    Conditional for Closed Virtual amounts
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    freeTexts
    optional
    array of object Xendit will concatenate all text entries in this section to form the Virtual Account description.
    Free text objects
    Object Key Value
    english
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    indonesia
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    expiredDate
    optional
    string ISO-8601 Expiration date for Virtual Account. Example: 2023-12-12T23:59:59+07:00. The default expiration date will be 31 years from creation date
    additionalInfo
    required
    object Additional information required to complete the transaction
    Object parameters details
    Key Value
    suggestedAmount
    optional
    number The suggested amount you want to assign. It is the amounts that will be displayed to the payor, but payor can still put any number (only supported for MANDIRI and BRI).
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Response Parameters

    Example: Update Virtual Account Request API Success Response

    {
      "responseCode": "2002700",
      "responseMessage": "Success",
      "virtualAccountData": {
        "partnerServiceId": "123459",
        "customerNo": "99993701870",
        "virtualAccountNo": "1234599993701870",
        "virtualAccountName": "John Doe",
        "trxId": "12349876",
        "expiredDate": "2023-12-31T23:59:59.000Z",
        "additionalInfo": {
          "id": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
          "status": "ACTIVE",
          "reusability": "MULTIPLE_USE",
          "channelCode": "BRI"
        }
      }
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    virtualAccountData
    optional
    object
    Only for successful responses
    Key Type Value
    partnerServiceId
    required
    string Prefix for the Virtual Account.
    customerNo
    required
    string Virtual Account number (excluding the partnerServiceId / prefix).
    virtualAccountNo
    required
    string The complete Virtual Account number (including the partnerServiceId / prefix). This is what a user will use to pay Virtual Account.
    virtualAccountName
    required
    string Complete name of the payer. May be used by the channel partner to verify their identity.
    trxId
    required
    string Merchant-provided identifier for this specific transaction.
    totalAmount
    conditionally required
    object Expected amount of the transaction in the actual value in the provided currency. Can be left blank for Open Virtual Account amounts.
    Conditional for Closed Virtual amounts
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    freeTexts
    optional
    array of object Xendit will concatenate all text entries in this section to form the Virtual Account description.
    Free text objects
    Object Key Value
    english
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    indonesia
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    expiredDate
    optional
    string ISO-8601 Expiration date for Virtual Account. Example: 2023-12-12T23:59:59+07:00. The default expiration date will be 31 years from creation date
    additionalInfo
    required
    object Additional information required to complete the transaction
    Object parameters details
    Key Value
    id
    required
    string Generated ID for the payment method. It has pm- as its prefix.
    status
    required
    string Status of the payment method. Allowed values: PENDING, ACTIVE, EXPIRED
    channelCode
    required
    string Identifier for the payment channel partner. Allowed values: BCA, BSI, BJB, CIMB, SAHABAT_SAMPOERNA, ARTAJASA, BRI, BNI, MANDIRI, PERMATA
    suggestedAmount
    optional
    number The suggested amount you want to assign. It is the amounts that will be displayed to the payor, but payor can still put any number (only supported for MANDIRI and BRI).
    reusability
    optional
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again. Allowed values: ONE_TIME_USE, MULTIPLE_USE. Default value: ONE_TIME_USE
    created
    optional
    string Timestamp in ISO 8601 format when the PaymentMethod was created.
    updated
    optional
    string Timestamp in ISO 8601 format when the PaymentMethod was last updated.
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Error Codes

    Example: Update Virtual Account Request API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4002800 Generic parsing error
    400 4002801 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4002802 Missing mandatory field or header
    401 4012800 Generic authorization error
    401 4012801 The provided Authorization bearer token is invalid
    403 4012801 The merchant is not allowed to perform this request
    403 4012815 Generic forbidden error
    403 4012823 The amount specified is either smaller or greater than supported by the channel.
    409 4092800 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4092801 An object with the same reference already exists

    VA - Deactivate

    Endpoint: Deactivate VA Request

    POST https://api.xendit.co/snap/v1.0/transfer-va/delete-va

    SNAP Deactivate Virtual Account

    Deactivate an existing Virtual Account. (Service code: 31)

    Request Parameters

    Example: Inquire Virtual Account Request Status

    curl https://api.xendit.co/snap/v1.0/transfer-va/delete-va -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
          "trxId": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39"
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    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.
    WITH-SPLIT-RULE
    optional
    string Split Rule ID that you would like to apply to this charge. This header is only used if you are a xenPlatform user. Please note: If you include this parameter, we will return the split_rule_id in the header of the API response. If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account.
    Body Parameter Type Description
    partnerServiceId
    optional
    string This field is ignored by Xendit.
    customerNo
    optional
    string This field is ignored by Xendit.
    virtualAccountNo
    optional
    string This field is ignored by Xendit.
    trxId
    required
    string Merchant-provided identifier for this specific transaction. Please note that this field needs to be unique for each Virtual Account.

    Response Parameters

    Example: Create Virtual Account Request API Success Response

    {
      "responseCode": "2003100",
      "responseMessage": "Success",
      "virtualAccountData": {
        "partnerServiceId": "123459",
        "customerNo": "99993701870",
        "virtualAccountNo": "1234599993701870",
        "virtualAccountName": "John doe",
        "trxId": "12349876",
        "expiredDate": "2020-12-31T23:59:59-07:00",
        "additionalInfo": {
          "channelCode": "BRI",
          "id": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
          "status": "EXPIRED"
        }
      }
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    virtualAccountData
    optional
    object
    Only for successful responses
    Key Type Value
    partnerServiceId
    required
    string Prefix for the Virtual Account.
    customerNo
    required
    string Virtual Account number (excluding the partnerServiceId / prefix).
    virtualAccountNo
    required
    string The complete Virtual Account number (including the partnerServiceId / prefix). This is what a user will use to pay Virtual Account.
    virtualAccountName
    required
    string Complete name of the payer. May be used by the channel partner to verify their identity.
    trxId
    required
    string Merchant-provided identifier for this specific transaction.
    totalAmount
    conditionally required
    object Expected amount of the transaction in the actual value in the provided currency. Can be left blank for Open Virtual Account amounts.
    Conditional for Closed Virtual amounts
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    freeTexts
    optional
    array of object Xendit will concatenate all text entries in this section to form the Virtual Account description.
    Free text objects
    Object Key Value
    english
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    indonesia
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    expiredDate
    optional
    string ISO-8601 Expiration date for Virtual Account. Example: 2023-12-12T23:59:59+07:00. The default expiration date will be 31 years from creation date
    additionalInfo
    required
    object Additional information required to complete the transaction
    Object parameters details
    Key Value
    id
    required
    string Generated ID for the payment method. It has pm- as its prefix.
    status
    required
    string Status of the payment method. Allowed values: PENDING, ACTIVE, EXPIRED
    channelCode
    required
    string Identifier for the payment channel partner. Allowed values: BCA, BSI, BJB, CIMB, SAHABAT_SAMPOERNA, ARTAJASA, BRI, BNI, MANDIRI, PERMATA
    suggestedAmount
    optional
    number The suggested amount you want to assign. It is the amounts that will be displayed to the payor, but payor can still put any number (only supported for MANDIRI and BRI).
    reusability
    optional
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again. Allowed values: ONE_TIME_USE, MULTIPLE_USE. Default value: ONE_TIME_USE
    created
    optional
    string Timestamp in ISO 8601 format when the PaymentMethod was created.
    updated
    optional
    string Timestamp in ISO 8601 format when the PaymentMethod was last updated.
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Error Codes

    Example: Deactivate Virtual Account Request API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4003100 Generic parsing error
    400 4003101 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4003102 Missing mandatory field or header
    401 4013100 Generic authorization error
    401 4013101 The provided Authorization bearer token is invalid
    403 4013101 The merchant is not allowed to perform this request
    403 4013115 Generic forbidden error
    403 4013123 The amount specified is either smaller or greater than supported by the channel.
    409 4093100 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4093101 An object with the same reference already exists

    VA - Callback

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


    The expected response is a HTTP 200 status. Xendit marks webhook event as failed if there is no response within 30s.

    Learn more about Webhook.

    Notifications Headers Object

    Example: Success Payment Webhook Payload

    {
      "type": "snap_virtual_account.payment",
      "payload": {
          "partnerServiceId": "38165",
          "customerNo": "9999900674",
          "virtualAccountNo": "381659999900674",
          "virtualAccountName": "John Doe",
          "trxId": "trx-1726657919",
          "paymentRequestId": "pm-2803bb6c-f1e1-4d38-ad09-da25d5bdcf4a",
          "paidAmount": {
              "value": "10000.00",
              "currency": "IDR"
          },
          "trxDateTime": "2024-09-18T11:12:19.000Z",
          "referenceNo": "95ee9898-e6f6-4dba-aeb3-3198fcdf3cf9",
          "freeTexts": [
              {
                  "english": "Please pay for service"
              }
          ],
          "additionalInfo": {
              "id": "95ee9898-e6f6-4dba-aeb3-3198fcdf3cf9",
              "paymentId": "95ee9898-e6f6-4dba-aeb3-3198fcdf3cf9",
              "country": "ID",
              "status": "SUCCEEDED",
              "created": "2024-09-18T11:12:20.631Z",
              "updated": "2024-09-18T11:12:20.631Z",
              "virtualAccountInfo": {
                  "id": "pm-2803bb6c-f1e1-4d38-ad09-da25d5bdcf4a",
                  "reusability": "MULTIPLE_USE",
                  "channelCode": "BCA",
                  "trxId": "trx-1726657919"
              }
          }
      },
      "headers": {
          "x-partner-id": "64e8508e3a4184dd951c2f29",
          "x-external-id": "XENDIT",
          "channel-id": "XENDIT"
      }
    }
    Header Object Parameter Type Description
    channel-id
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    x-external-id
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    x-partner-id
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    x-signature
    required
    string Non-repudiation signature for the request. See this article for more info.
    x-timestamp
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.

    Notifications Payload Object

    Payload Object Parameter Type Description
    partnerServiceId
    required
    string This field is ignored by Xendit.
    customerNo
    required
    string This field is ignored by Xendit.
    virtualAccountNo
    required
    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 and don't include the merchant code as prefix.
    virtualAccountName
    required
    string Complete name of the payor. May be used by the channel partner to verify their identity.
    Characters Only alphabet. For BCA Aggregator, alphabet and number are allowed. Minimum length 1 character, except BCA the minimum length is 3 characters.
    trxId
    required
    string Merchant-provided identifier for this specific transaction. Please note that this field needs to be unique for each Virtual Account.
    paidAmount
    required
    object Actual paid amount
    Conditional for Closed Virtual amounts
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    trxDateTime
    required
    string Timestamp in ISO 8601 format when the PaymentRequest was created. Example: 2020-08-29T09:12:33.001Z
    referenceNo
    required
    string The payment ID that can be used for reconciliation
    freeTexts
    optional
    array of object Xendit will concatenate all text entries in this section to form the Virtual Account description.
    Free text objects
    Object Key Value
    english
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    indonesia
    optional
    string Free-text field for any additional information regarding the Virtual Account.
    additionalInfo
    required
    object Additional information required to complete the transaction
    object parameters details
    Key Value
    paymentId
    required
    string Internal payment ID in Xendit system
    country
    optional
    string 2-letter ISO 3166-2 country code indicating country of transaction.
    status
    required
    string Status of the payment. Allowed values: SUCCEEDED, FAILED
    created
    optional
    string Timestamp in ISO 8601 format when the PaymentRequest was created.
    updated
    optional
    string Timestamp in ISO 8601 format when the PaymentRequest was last updated. Example: 2020-08-29T09:12:33.001Z
    senderName
    optional
    string Name of the end user that paid into the Virtual Account. This field is only supported for BSS VA
    paymentDetail
    optional
    Additional information from the bank.
    object parameters details
    Key Value
    remark
    optional
    string A remark that is inputted by the payer when they are about to make a payment, only supported for BSS.
    reference
    optional
    string Reference number from the bank that can be used for reconciliation, only supported for BCA with switcher commercial model.
    metadata
    optional
    object A free-format JSON for additional information that you may use.
    virtualAccountInfo
    required
    Information about the Virtual Account.
    object parameters details
    Key Value
    id
    required
    string The Virtual Account ID.
    reusability
    required
    string The Virtual Account type. Allowed values: ONE_TIME_USE, MULTIPLE_USE
    channelCode
    optional
    string Identifier for the payment channel partner. Allowed values: BCA, BSI, BJB, CIMB SAHABAT_SAMPOERNA, ARTAJASA, BRI, BNI, MANDIRI, PERMATA
    trxId
    required
    string Virtual Account Transaction ID.

    QR - Create

    Endpoint: Create QR Request

    POST https://api.xendit.co/snap/v1.0/qr/qr-mpm-generate

    SNAP QR codes

    This API can be used to generate QR Codes. (Service code: 47)

    Request Parameters

    Example: Create QR Code Request

    curl https://api.xendit.co/snap/v1.0/qr/qr-mpm-generate -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
            "partnerReferenceNo": "0f38e017-007f-4134-9e5d-86657ec0cf7",
            "amount": {
                "value": "10000.00",
                "currency": "IDR"
            },
            "additionalInfo": {
                "reusability": "ONE_TIME_USE"
            }
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    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.
    WITH-SPLIT-RULE
    optional
    string Split Rule ID that you would like to apply to this charge. This header is only used if you are a xenPlatform user. Please note: If you include this parameter, we will return the split_rule_id in the header of the API response. If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account.
    Body Parameter Type Description
    partnerReferenceNo
    optional
    string Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions.
    amount
    conditionally required
    object Amount of the transaction. This is required for ONE_TIME_USE QR and will be ignored for MULTIPLE_USE QR.
    Conditional for ONE_TIME_USE QR
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    additionalInfo
    required
    object Additional information required to complete the transaction
    Object parameters details
    Key Value
    reusability
    required
    string Describes whether or not the QR Code can be reused for only one or multiple payments. Allowed values: ONE_TIME_USE, MULTIPLE_USE
    paymentMethodReferenceId
    optional
    string Merchant-provided identifier for the created payment method. If not specified, Xendit will generate random unique id for this field.
    metadata
    optional
    string Date when the QR will be expired. Format: ISO-8601.
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Response Parameters

    Example: Create QR code Request API Success Response

    {
      "responseCode": "2004700",
      "responseMessage": "Successful",
      "referenceNo": "2020102900000000000002",
      "partnerReferenceNo": "f5e6bb35-2c51-4880-9f19-883856031c30",
      "qrContent": "random-qr-string",
      "additionalInfo": {
        "paymentMethodId": "pm-8c5edad9-32f6-40fa-a24e-0c4e6874c943",
        "paymentMethodReferenceId": "620b9df4-fe69-4bfd-b9d4-5cba6861dc7d",
        "paymentMethodStatus": "PENDING",
        "reusability": "ONE_TIME_USE",
        "created": "2023-01-05T13:15:45.265367951Z",
        "updated": "2023-01-05T13:15:45.265367951Z"
      }
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    referenceNo
    required
    string Unique identifier for the payment request. Prefix will vary according to the payment method used.
    partnerReferenceNo
    optional
    string Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions.
    qrContent
    required
    string QR string to be rendered for display to end users.
    additionalInfo
    required
    object Additional information required to complete the transaction
    Object parameters details
    Key Value
    paymentMethodId
    required
    string The id of a previously stored PaymentMethod to be used in this transaction. Mandatory if payOptionDetails is not specified.
    paymentMethodReferenceId
    required
    string Merchant-provided identifier for the created payment method. If not specified, Xendit will generate random unique id for this field.
    paymentMethodStatus
    required
    string Status of the created Payment method. Can be used to determine whether QR can start accept payment or not. Allowed values: REQUIRES_ACTION, PENDING, ACTIVE, INACTIVE, EXPIRED
    paymentMethodExpiresAt
    optional
    string Date when the QR will be expired. Format: ISO-8601
    reusability
    optional
    string Describes whether or not the QR Code can be reused for only one or multiple payments. Allowed values: ONE_TIME_USE, MULTIPLE_USE
    created
    optional
    string Timestamp in ISO 8601 format when the PaymentMethod was created.
    updated
    optional
    string Timestamp in ISO 8601 format when the PaymentMethod was last updated.
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Error Codes

    Example: Create QR Code API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4004700 Generic parsing error
    400 4004701 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4004702 Missing mandatory field or header
    401 4014700 Generic authorization error
    401 4014701 The provided Authorization bearer token is invalid
    403 4014701 The merchant is not allowed to perform this request
    403 4014715 Generic forbidden error
    403 4014723 The amount specified is either smaller or greater than supported by the channel.
    409 4094700 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4094701 An object with the same reference already exists

    QR - Inquire Status

    Endpoint: Inquire QR Request

    POST https://api.xendit.co/snap/v1.0/qr/qr-mpm-query

    SNAP QR codes

    This API can be used to query the status of specific QR Payment Request. (Service code: 51)

    Request Parameters

    Example: Inquire QR Code Request

    curl https://api.xendit.co/snap/v1.0/qr/qr-mpm-query -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
        "serviceCode": "47",
        "originalPartnerReferenceNo": "0f38e017-007f-4134-9e5d-86657ec0cf77"
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    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.
    Body Parameter Type Description
    originalPartnerReferenceNo
    optional
    string Original transaction identifier on service consumer system. Either originalReferenceNo or originalPartnerReferenceNo must present in the request.
    originalReferenceNo
    optional
    string Xendit Generated ID for the payment request. Either this or referenceNo must be provided. originalPartnerReferenceNo must present in the request.
    serviceCode
    required
    string Must be set to '47'

    Response Parameters

    Example: Inquire QR code Request API Success Response

    {
      "responseCode": "2005100",
      "responseMessage": "Successful",
      "originalReferenceNo": "pr-bc9faa22-23e5-486e-bfee-869c46d32cc3",
      "originalPartnerReferenceNo": "0f38e017-007f-4134-9e5d-86657ec0cf77",
      "serviceCode": "47",
      "latestTransactionStatus": "00",
      "transactionStatusDesc": "Success",
      "amount": {
        "value": "10000.00",
        "currency": "IDR"
      },
      "additionalInfo": {
        "paymentMethodId": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
        "paymentMethodReferenceId": "2020102900000000000001",
        "reusability": "ONE_TIME_USE",
        "paymentMethodStatus": "INACTIVE",
        "created": "2020-08-29T09:12:33.001Z",
        "updated": "2020-08-29T09:12:33.001Z",
        "metadata": {
          "sku": "ABCDEFGH"
        }
      }
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    originalReferenceNo
    optional
    string Unique identifier for the payment request. Prefix will vary according to the payment method used.
    originalPartnerReferenceNo
    optional
    string Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions.
    serviceCode
    required
    string Set to '47'
    latestTransactionStatus
    required
    string Latest transaction status. Allowed values: 00, 03, 04, 06
    transactionStatusDesc
    optional
    string Description status transaction
    amount
    conditionally required
    object Amount of the transaction
    Object information
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    additionalInfo
    required
    object Additional information required to complete the transaction
    Object parameters details
    Key Value
    paymentMethodId
    required
    string The id of a previously stored PaymentMethod to be used in this transaction. Mandatory if payOptionDetails is not specified.
    paymentMethodReferenceId
    required
    string Merchant-provided identifier for the created payment method. If not specified, Xendit will generate random unique id for this field.
    paymentMethodStatus
    required
    string Status of the created Payment method. Can be used to determine whether QR can start accept payment or not. Allowed values: REQUIRES_ACTION, PENDING, ACTIVE, INACTIVE, EXPIRED
    paymentMethodExpiresAt
    optional
    string Date when the QR will be expired. Format: ISO-8601
    reusability
    optional
    string Describes whether or not the QR Code can be reused for only one or multiple payments. Allowed values: ONE_TIME_USE, MULTIPLE_USE
    failureCode
    optional
    string If the status of the transaction is FAILED, this describes the reason for failure.
    created
    optional
    string Timestamp in ISO 8601 format when the PaymentMethod was created.
    updated
    optional
    string Timestamp in ISO 8601 format when the PaymentMethod was last updated.
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Error Codes

    Example: Create QR Code API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4005100 Generic parsing error
    400 4005101 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4005102 Missing mandatory field or header
    401 4015100 Generic authorization error
    401 4015101 The provided Authorization bearer token is invalid
    403 4015101 The merchant is not allowed to perform this request
    403 4015115 Generic forbidden error
    403 4015123 The amount specified is either smaller or greater than supported by the channel.
    409 4095100 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4095101 An object with the same reference already exists

    QR - Callback

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


    The expected response is a HTTP 200 status. Xendit marks webhook event as failed if there is no response within 30s.

    Learn more about Webhook.

    Notifications Headers Object

    Example: Success Payment Webhook Payload

    {
      "type": "snap_qr.payment",
      "payload": {
        "originalReferenceNo": "pr-bc9faa22-23e5-486e-bfee-869c46d32cc3",
        "originalPartnerReferenceNo": "0f38e017-007f-4134-9e5d-86657ec0cf77",
        "latestTransactionStatus": "00",
        "transactionStatusDesc": "Success",
        "amount": {
            "value": "10000.00",
            "currency": "IDR"
        },
        "additionalInfo": {
            "id": "qrpy-av8faa22-145e5-4766e-bdee-867c46f32cc4",
            "paymentMethodId": "pm-0fec5f39-de53-42f0-8443-6bc037138e32",
            "paymentMethodReferenceId": "331b2b98-2adf-43b5-8c3f-9b0d76026c9d",
            "created": "2023-03-07T12:05:02.894821985Z",
            "updated": "2023-03-07T12:05:02.894821985Z"
        },
      "headers": {
          "x-partner-id": "64e8508e3a4184dd951c2f29",
          "x-external-id": "XENDIT",
          "channel-id": "XENDIT"
      }
    }
    Header Object Parameter Type Description
    channel-id
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    x-external-id
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    x-partner-id
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    x-signature
    required
    string Non-repudiation signature for the request. See this article for more info.
    x-timestamp
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.

    Notifications Payload Object

    Payload Object Parameter Type Description
    originalReferenceNo
    required
    string Unique identifier for the payment request. Prefix will vary according to the payment method used.
    originalPartnerReferenceNo
    optional
    string Merchant-provided identifier for this specific transaction.
    latestTransactionStatus
    required
    string Latest transaction status of the payment. Allowed values: 00, 06
    transactionStatusDesc
    required
    string Description status transaction
    amount
    required
    object Actual paid amount
    Object information
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    additionalInfo
    required
    object Additional information about the QR payment
    object parameters details
    Key Value
    id
    required
    string Unique identifier for the payment.
    paymentMethodId
    required
    string Unique identifier for the payment method.
    paymentMethodReferenceId
    required
    string Merchant-provided identifier for this payment method. If it's not provided, xendit will generate unique identifier for the merchant.
    created
    optional
    string Timestamp in ISO 8601 format when the PaymentRequest was created.
    updated
    optional
    string Timestamp in ISO 8601 format when the PaymentRequest was last updated. Example: 2020-08-29T09:12:33.001Z
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Direct Debit - Create

    Endpoint: Create Direct Debit Payment Request

    POST https://api.xendit.co/snap/v1.0/debit/payment-host-to-host

    SNAP Direct Debit Payment

    This API can be used to initiate a one time payment request or a payment request using previously bound account (i.e. a payment method must already exist). Based on the response code an additional action might be required, e.g. to redirect the shopper or to verify the payment with an OTP. This API can be used for all E-Wallet and Direct Debit payment channels. (Service code: 54)

    Request Parameters

    Example: Create Direct Debit Request

    curl https://api.xendit.co/snap/v1.0/debit/payment-host-to-host -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
        "partnerReferenceNo": "2020102900000000000001",
        "amount": {
            "value": "10000.00",
            "currency": "IDR"
        },
        "additionalInfo": {
            "customerId": "fc4c060b-3c41-4707-b7b2-df9c3376edde",
            "paymentMethodId": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
            "channelProperties": {
            "redeemPoints": "REDEEM_ALL"
            },
            "metadata": {
            "sku": "ABCDEFGH"
            }
        }
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    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.
    WITH-SPLIT-RULE
    optional
    string Split Rule ID that you would like to apply to this charge. This header is only used if you are a xenPlatform user. Please note: If you include this parameter, we will return the split_rule_id in the header of the API response. If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account.
    Body Parameter Type Description
    partnerReferenceNo
    required
    string Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions.
    amount
    conditionally required
    object Amount of the transaction. This is required for ONE_TIME_USE QR and will be ignored for MULTIPLE_USE QR.
    Conditional for ONE_TIME_USE QR
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    urlParam
    optional
    array Conditional, urlParam with type PAY_RETURN required for: OVO (MULTIPLE_USE), DANA, SHOPEEPAY.
    urlParam with type FAILURE_RETURN required for: OVO (MULTIPLE_USE), DANA (MULTIPLE_USE), SHOPEEPAY (MULTIPLE_USE)
    Object Information for each array item
    Key Value
    url
    required
    string URL where the end-customer is redirected if the authorization is successful (in case of type PAY_RETURN), unsuccessful (in case of type FAILURE_RETURN) or cancellation (in case of CANCEL_RETURN)
    type
    required
    string URL Type. Allowed values: PAY_RETURN, FAILURE_RETURN, CANCEL_RETURN
    isDeeplink
    optional
    boolean Whether the URL is a deeplink URL or not. Xendit does not support deeplink URL for merchant-provided URLs so this field is ignored.
    payOptionDetails
    conditionally required
    array Only 1 object allowed. Can only be present if paymentMethodId is not specified.
    Object Information for each array item
    Key Value
    payMethod
    required
    string Type of payment method. Allowed values: EWALLET, DIRECT_DEBIT
    payOption
    required
    string Identifier for the payment channel partner. Allowed values for payMethod EWALLET: OVO, DANA, LINKAJA, JENIUSPAY, ASTRAPAY, SHOPEEPAY. Allowed values for payMethod DIRECT_DEBIT: BRI
    additionalInfo
    conditionally required
    object Required for OVO one time payment, BRI, JENIUSPAY
    Object Information
    Key Value
    reusability
    optional
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again. Allowed values: ONE_TIME_USE, MULTIPLE_USE
    channelProperties
    optional
    object Additional information required to complete the transaction
    Object parameters details
    Key Value
    mobileNumber
    required
    string Registered mobile number of the end-customer to the channel partner in E.164 Format. Mandatory for: OVO (ONE_TIME_USE), BRI
    cardLastFour
    optional
    string Last four digits of the debit card. Mandatory for: BRI
    cardExpiry
    optional
    string Expiry month and year of the debit card (in MM/YY format). Mandatory for: BRI
    email
    optional
    string Email address of the customer that is registered to the partner channel. Mandatory for: BRI
    cashtag
    optional
    string Mandatory for: JENIUSPAY. This is the registered cashtag of the wallet.
    additionalInfo
    optional
    object Additional information for the transaction
    Object parameters details
    Key Value
    customerId
    required
    string Xendit-generated identifier for the end-customer. Will be required for certain payment channels such as Multiple-use e-wallets and direct debit.
    paymentMethodId
    optional
    string The id of a previously stored PaymentMethod to be used in this transaction. Mandatory if payOptionDetails is not specified.
    channelProperties
    optional
    object Additional parameters based on payment channel
    Object parameters details
    Key Value
    requireAuth
    optional
    boolean Only for Direct Debit to BRI. Toggle used to require end-customer to input undergo OTP validation before completing a payment. OTP will always be required for transactions greater than 1,000,000 IDR.
    redeemPoints
    optional
    string Only for OVO and SHOPEEPAY EWallets. Allowed values: REDEEM_NONE, REDEEM_AL. Whether or not to use the ewallet’s points balance in the transaction.
    Possible values: REDEEM_NONE - no points will be used
    REDEEM_ALL - points will be used to offset payment amount before cash balance is used.
    OVO: REDEEM_ALL can only be used when approved for promotions.
    SHOPEEPAY: Only 50% of transaction amount (rounded down) can paid using SHOPEEPAY coins.
    description
    optional
    string Free-text field for any additional information regarding the payment request.
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Response Parameters

    Example: Create Direct Debit Request API Success Response

    {
      "responseCode": "2005400",
      "responseMessage": "Successful",
      "referenceNo": "ewc_6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
      "partnerReferenceNo": "2020102900000000000001",
      "webRedirectUrl": "https://link-web.xendit.co/oauth/lat-4ec01c8d-0326-4a35-bc11-b64c85f7408e/confirm",
      "additionalInfo": {
        "paymentMethodId": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
        "actions": [
          {
            "action": "AUTH",
            "method": "GET",
            "url": "https://link-web.xendit.co/oauth/lat-4ec01c8d-0326-4a35-bc11-b64c85f7408e/confirm",
            "urlType": "WEB"
          }
        ],
        "metadata": {
          "sku": "ABCDEFGH"
        }
      }
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    referenceNo
    optional
    string Unique identifier for the payment request. Prefix will vary according to the payment method used.
    partnerReferenceNo
    optional
    string Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions.
    approvalCode
    optional
    string If the status of the transaction is FAILED, this describes the reason for failure. Will not be present if the transaction did not fail.
    appRedirectUrl
    optional
    string The provided redirect url utilizes deep linking to the channel partner’s platform.
    webRedirectUrl
    optional
    string The provided redirect url is optimized for desktop or web interface.
    additionalInfo
    optional
    object Additional information for the transaction
    Object parameters details
    Key Value
    paymentMethodId
    required
    string Returns the payment method ID, which is either the one specified in the request, or a new payment method created from the payOptionDetails in the request
    actions
    optional
    array This contains objects that detail the possible next steps in order to proceed with the payment.
    Object Information for each array item
    Key Value
    action
    optional
    string Allowed values: AUTH, RESEND_AUTH
    urlType
    optional
    string Allowed values: API, WEB, MOBILE, DEEPLINK
    url
    optional
    string URL value for action to be taken
    method
    optional
    string HTTP method to perform the action
    created
    optional
    string Timestamp in ISO 8601 format when the payment request was created
    updated
    optional
    string Timestamp in ISO 8601 format when the payment request was last updated
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Error Codes

    Example: Create Direct Debit API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4005400 Generic parsing error
    400 4005401 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4005402 Missing mandatory field or header
    401 4015400 Generic authorization error
    401 4015401 The provided Authorization bearer token is invalid
    403 4015401 The merchant is not allowed to perform this request
    403 4015415 Generic forbidden error
    403 4015423 The amount specified is either smaller or greater than supported by the channel.
    409 4095400 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4095401 An object with the same reference already exists

    Direct Debit - Inquire Status

    Endpoint: Create Direct Debit Payment Request

    POST https://api.xendit.co/snap/v1.0/debit/status

    SNAP Inquire Direct Debit Payment

    This API can be used to request the status of a specific Payment request. (Service code: 55)

    Request Parameters

    Example: Inquire Direct Debit Request

    curl https://api.xendit.co/snap/v1.0/debit/status -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
        "originalPartnerReferenceNo": "0f38e017-007f-4134-9e5d-86657ec0cf77",
        "serviceCode": "54"
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    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.
    Body Parameter Type Description
    originalPartnerReferenceNo
    optional
    string Original transaction identifier on service consumer system. Either this field or originalReferenceNo must be provided
    originalReferenceNo
    optional
    string Xendit Generated ID for the payment request. Either this field or originalPartnerReferenceNo must be provided
    serviceCode
    required
    string Must be set to ‘54’

    Response Parameters

    Example: Inquire Direct Debit Request API Success Response

    {
      "responseCode": "2005500",
      "responseMessage": "Successful",
      "originalReferenceNo": "pr-bc9faa22-23e5-486e-bfee-869c46d32cc3",
      "originalPartnerReferenceNo": "0f38e017-007f-4134-9e5d-86657ec0cf77",
      "serviceCode": "54",
      "latestTransactionStatus": "03",
      "transactionStatusDesc": "REQUIRES_ACTION",
      "transAmount": {
        "value": "10000.00",
        "currency": "IDR"
      },
      "additionalInfo": {
        "customerId": "fc4c060b-3c41-4707-b7b2-df9c3376edde",
        "paymentMethodId": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
        "paymentMethodReferenceId": "2020102900000000000001",
        "actions": [
          {
            "action": "RESEND_AUTH",
            "method": "POST",
            "url": "https://merchant-url/resent-otp",
            "urlType": "DEEPLINK"
          }
        ],
        "channelProperties": {},
        "metadata": {
          "sku": "ABCDEFGH"
        }
      }
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    originalReferenceNo
    optional
    string Unique identifier for the payment request. Prefix will vary according to the payment method used.
    originalPartnerReferenceNo
    optional
    string Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions.
    serviceCode
    required
    string Set to '54'
    latestTransactionStatus
    required
    string Latest transaction status. Allowed values: 00, 01, 02, 03, 04, 05, 06, 07
    transactionStatusDesc
    optional
    string Description status transaction
    transAmount
    conditionally required
    object Amount of the transaction
    Object information
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    additionalInfo
    optional
    object Additional information for the transaction
    Object parameters details
    Key Value
    customerId
    optional
    string Xendit-generated identifier for the end-customer. It will be required for MULTIPLE_USE payment channels.
    description
    optional
    string Free-text field for any additional information regarding the payment request.
    paymentMethodId
    required
    string The Xendit-generated payment method ID
    paymentMethodId
    required
    string Merchant-provided identifier for this payment method.
    channelProperties
    optional
    object Specific settings to be applied to the payment request.
    Object Information for each array item
    Key Value
    redeemPoints
    optional
    string Whether or not to use the PaymentMethod's points_balance in the transaction.
    successReturnUrl
    optional
    string URL where the end-customer is redirected if the authorization is successful.
    failureReturnUrl
    optional
    string URL where the end-customer is redirected if the authorization has failed.
    cancelReturnUrl
    optional
    string URL where the end-customer is redirected if the authorization has been cancelled.
    requireAuth
    optional
    string Toggle used to require end-customer to input undergo OTP validation before completing a payment. Only applicable for BRI.
    actions
    optional
    array This contains objects that detail the possible next steps in order to proceed with the payment.
    Object Information for each array item
    Key Value
    action
    optional
    string Allowed values: AUTH, RESEND_AUTH
    urlType
    optional
    string Allowed values: API, WEB, MOBILE, DEEPLINK
    url
    optional
    string URL value for action to be taken
    method
    optional
    string HTTP method to perform the action
    failureCode
    optional
    string If the status of the transaction is failed, this describes the reason for failure.
    created
    optional
    string Timestamp in ISO 8601 format when the payment request was created
    updated
    optional
    string Timestamp in ISO 8601 format when the payment request was last updated
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Error Codes

    Example: Inquire Direct Debit Payment API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4005500 Generic parsing error
    400 4005501 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4005502 Missing mandatory field or header
    401 4015500 Generic authorization error
    401 4015501 The provided Authorization bearer token is invalid
    403 4015501 The merchant is not allowed to perform this request
    403 4015515 Generic forbidden error
    403 4015523 The amount specified is either smaller or greater than supported by the channel.
    409 4095500 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4095501 An object with the same reference already exists

    Direct Debit - Refund

    Endpoint: Refund Direct Debit Payment Request

    POST https://api.xendit.co/snap/v1.0/debit/refund

    SNAP Refund Direct Debit Payment

    This API can be used to refund a payment (Service code: 58)

    Request Parameters

    Example: Refund Direct Debit Request

    curl https://api.xendit.co/snap/v1.0/debit/refund -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
            "originalPartnerReferenceNo": "0f38e017-007f-4134-9e5d-86657ec0cf77",
            "partnerRefundNo": "5eea215e-e116-439a-a087-76fc906501e1",
            "reason": "FRAUDULENT",
            "refundAmount": {
                "value": "100000.00",
                "currency": "IDR"
            }
        }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    Body Parameter Type Description
    originalPartnerReferenceNo
    optional
    string Original transaction identifier on service consumer system. Either this field or originalReferenceNo must be provided
    originalReferenceNo
    optional
    string Xendit Generated ID for the payment request. Either this field or originalPartnerReferenceNo must be provided
    partnerRefundNo
    optional
    string Merchant-provided identifer for the refund request. If none is provided, a unique randomly generated string will be assigned.
    refundAmount
    conditionally required
    object If refundAmount is not provided, the refund request will default to the maximum possible amount to be refunded from the provided transaction.
    Conditional for ONE_TIME_USE QR
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    reason
    optional
    string Reason why the refund request is made. Allowed values: FRAUDULENT, DUPLICATE, REQUESTED_BY_CUSTOMER, CANCELLATION, OTHERS
    additionalInfo
    optional
    object Additional information for the transaction
    Object parameters details
    Key Value
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Response Parameters

    Example: Inquire Direct Debit Request API Success Response

    {
      "responseCode": "2005800",
      "responseMessage": "Successful",
      "originalReferenceNo": "pr-bc9faa22-23e5-486e-bfee-869c46d32cc3",
      "refundNo": "rfd-b0abb4fe-4b98-4c07-92d4-3f33fc79aefc",
      "partnerRefundNo": "5eea215e-e116-439a-a087-76fc906501e1",
      "refundAmount": {
        "value": "100000.00",
        "currency": "IDR"
      },
      "additionalInfo": {
        "channelCode": "SHOPEEPAY",
        "status": "SUCCESS",
        "reason": "FRAUDULENT"
      }
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    originalReferenceNo
    optional
    string Unique identifier for the payment request. Prefix will vary according to the payment method used.
    refundNo
    optional
    string Xendit-generated identifier for the refund request
    partnerRefundNo
    optional
    string Merchant-provided identifer for the refund request. If none is provided, a unique randomly generated string will be assigned.
    refundAmount
    conditionally required
    object If refundAmount is not provided, the refund request will default to the maximum possible amount to be refunded from the provided transaction.
    Conditional for ONE_TIME_USE QR
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    additionalInfo
    required
    object Additional information for the transaction
    Object parameters details
    Key Value
    channelCode
    required
    string Identifier for the payment channel partner
    status
    required
    string Status of the refund. Allowed values: SUCCESS, FAILED, PENDING
    reason
    required
    string Reason why the refund request is made. Allowed values: FRAUDULENT, DUPLICATE, REQUESTED_BY_CUSTOMER
    failureCode
    optional
    string If the status of the transaction is failed, this describes the reason for failure.
    refundFeeAmount
    optional
    string If applicable, this is the corresponding additional fee for processing the refund.
    created
    optional
    string Timestamp in ISO 8601 format when the payment request was created
    updated
    optional
    string Timestamp in ISO 8601 format when the payment request was last updated
    metadata
    optional
    object A free-format JSON for additional information that you may use.

    Error Codes

    Example: Refund Direct Debit API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4005800 Generic parsing error
    400 4005801 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4005802 Missing mandatory field or header
    401 4015800 Generic authorization error
    401 4015801 The provided Authorization bearer token is invalid
    403 4015801 The merchant is not allowed to perform this request
    403 4015815 Generic forbidden error
    403 4015823 The amount specified is either smaller or greater than supported by the channel.
    409 4095800 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4095801 An object with the same reference already exists

    Direct Debit - Verify OTP

    Endpoint: Verify Direct Debit Payment OTP Request

    POST https://api.xendit.co/snap/v1.0/otp-verification

    SNAP Verify OTP

    This API can be used to verify an OTP if required in the payment process. (Service code: 04)

    Request Parameters

    Example: Verify Direct Debit OTP Request

    curl https://api.xendit.co/snap/v1.0/otp-verification -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'CHANNEL-ID: 123123' \
      --header 'Content-Type: application/json' \
      --header 'X-EXTERNAL-ID: 123123' \
      --header 'X-PARTNER-ID: 123123' \
      --header 'X-SIGNATURE: fc4c060b3c414707b7b2df9c3376edde' \
      --header 'X-TIMESTAMP: 2020-08-29T09:12:33.001Z' \
      --data '{
        "originalReferenceNo": "pr-bc9faa22-23e5-486e-bfee-869c46d32cc3",
        "otp": "123456",
        "type": "payment"
      }' \
    Header Parameter Type Description
    CHANNEL-ID
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    X-EXTERNAL-ID
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    X-PARTNER-ID
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    X-SIGNATURE
    required
    string Non-repudiation signature for the request. See this article for more info.
    X-TIMESTAMP
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.
    Body Parameter Type Description
    originalReferenceNo
    optional
    string Xendit Generated ID for the payment request. Either this field or originalPartnerReferenceNo must be provided
    otp
    optional
    string The authorization code or OTP inputted by the end customer
    type
    optional
    string Must be set to 'payment'. Allowed value: payment

    Response Parameters

    Example: Inquire Direct Debit Request API Success Response

    {
      "responseCode": "2000400",
      "responseMessage": "Successful",
      "originalReferenceNo": "pr-bc9faa22-23e5-486e-bfee-869c46d32cc3",
      "originalPartnerReferenceNo": "0f38e017-007f-4134-9e5d-86657ec0cf77"
    }
    Body Parameter Type Description
    responseCode
    required
    string Response code
    responseMessage
    required
    string Response description
    originalReferenceNo
    optional
    string Unique identifier for the payment request. Prefix will vary according to the payment method used.
    originalPartnerReferenceNo
    optional
    string Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions
    customerId
    optional
    string Xendit-generated identifier for the end-customer.

    Error Codes

    Example: Verify OTP API Error Response

    {
        "responseCode": "4000000",
        "responseMessage": "Bad Request"
    }
    HTTP error Response Code Response Message
    400 4000400 Generic parsing error
    400 4000401 Invalid field format (i.e. a string is used whereas a number was expected, or an invalid enum value is used, etc.)
    400 4000402 Missing mandatory field or header
    401 4010400 Generic authorization error
    401 4010401 The provided Authorization bearer token is invalid
    403 4010401 The merchant is not allowed to perform this request
    403 4010415 Generic forbidden error
    403 4010423 The amount specified is either smaller or greater than supported by the channel.
    409 4090400 The same X-EXTERNAL-ID token has been used within the last 24 hours
    409 4090401 An object with the same reference already exists

    Direct Debit - Callback

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


    The expected response is a HTTP 200 status. Xendit marks webhook event as failed if there is no response within 30s.

    Learn more about Webhook.

    Notifications Headers Object

    Example: Success Payment Webhook Payload

    {
      "type": "snap.direct_debit.succeeded",
      "payload": {
        "amount": {
          "value": "10000.00",
          "currency": "IDR"
        },
        "createdTime": "2020-08-29T09:12:33.001Z",
        "additionalInfo": {
          "id": "ddpy-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
          "updated": "2020-08-29T09:12:33.001Z",
          "paymentMethodId": "pm-5f964f11-3a74-4df2-bdc4-0778b3e836d4",
          "paymentMethodReferenceId": "c2a6c16f-84b9-4f21-8db3-dc0ddcbbfec7"
        },
        "originalReferenceNo": "ddpy-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
        "transactionStatusDesc": "Success",
        "latestTransactionStatus": "00",
        "originalPartnerReferenceNo": "c2a6c16f-84b9-4f21-8db3-dc0ddcbbfec7"
        },
      "headers": {
          "x-partner-id": "64e8508e3a4184dd951c2f29",
          "x-external-id": "XENDIT",
          "channel-id": "XENDIT"
      }
    }
    Header Object Parameter Type Description
    channel-id
    required
    string Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'.
    Content-Type
    required
    string Must be set to application/json
    x-external-id
    required
    string Also known as idempotency key. Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request.Example: f4d53a90-86aa-46f4-8738-169a4912eff0
    x-partner-id
    required
    string Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c
    x-signature
    required
    string Non-repudiation signature for the request. See this article for more info.
    x-timestamp
    required
    string Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD.

    Notifications Payload Object

    Payload Object Parameter Type Description
    originalReferenceNo
    required
    string Unique identifier for the payment request. Prefix will vary according to the payment method used.
    originalPartnerReferenceNo
    optional
    string Merchant-provided identifier for this specific transaction.
    latestTransactionStatus
    required
    string Latest transaction status of the payment. Allowed values: 00, 06
    transactionStatusDesc
    required
    string Description status transaction
    createdTime
    required
    string Timestamp in ISO 8601 format when the PaymentRequest was created. Example: 2024-08-29T09:12:33.001Z
    amount
    required
    object Actual paid amount
    Object information
    Key Value
    value
    required
    string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00
    currency
    required
    string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed.
    additionalInfo
    required
    object Additional information about the payment.
    object parameters details
    Key Value
    id
    required
    string Unique identifier for the payment.
    paymentMethodId
    required
    string Unique identifier for the payment method.
    paymentMethodReferenceId
    required
    string Merchant-provided identifier for this payment method. If it's not provided, xendit will generate unique identifier for the merchant.
    created
    optional
    string Timestamp in ISO 8601 format when the PaymentRequest was created.
    updated
    optional
    string Timestamp in ISO 8601 format when the PaymentRequest was last updated. Example: 2020-08-29T09:12:33.001Z
    description
    optional
    string description of the payment request.
    failureCode
    optional
    string If the status of the transaction is failed, this describes the reason for failure.
    channelProperties
    optional
    object Additional information about the channel.
    object parameters details
    Key Value
    successReturnUrl
    required
    string URL where the end-customer is redirected if the authorization is successful.
    failureReturnUrl
    required
    string URL where the end-customer is redirected if the authorization has failed

    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

    {        
        "amount": "10000",        
        "card_data": {
            "account_number": "4456530000001096",        
            "exp_month": "12",        
            "exp_year": "2029",
            "card_holder_first_name": "John",
            "card_holder_last_name": "Doe",
            "card_holder_email": "johndoe@gmai.com",
            "card_holder_phone_number": "628212223242526"
        },
        "external_id":"TEST1234",
        "card_cvn": "123",
        "is_multiple_use": false,
        "should_authenticate": true,
        "currency": "IDR",
        "mid_label": "XBANK_TIDNEX"
    }

    Example tokenData request for retokenize

    {        
        "amount": "10000",        
        "credit_card_token_id": "58e2096018b815f555c8a524",
        "card_cvn": "123",
        "is_multiple_use": false,
        "should_authenticate": true,
        "external_id": "TEST1234"
    }

    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.

    Retokenize

    When performing credit card authorization/charge, sending CVV can help to improve the success rate. Following PCIDSS policy where CVV should not be processed server to server (unless you are a PCIDSS certified company), the retokenize flow can help to collect the CVV from your customer, then pass it to Xendit retokenize function, so that CVV will be passed to the processor when the authorization request is performed.

    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_data
    required
    object Customer's card details informations
    card details child parameters
    Key Value
    account_number
    required
    string Card number which will be converted into a secured token
    exp_month
    required
    string Card expiration month
    exp_year
    required
    string Card expiration year
    card_holder_first_name
    required
    string Card holder's first name shown in card. Issuer will use this information to assess the transaction.
    character: Alphanumeric. No special characters are allowed.
    minimum length: 1 character
    maximum length: 50 characters
    card_holder_last_name
    required
    string Card holder's last name shown in card. Issuer will use this information to assess the transaction.
    character: Alphanumeric. No special characters are allowed.
    minimum length: 1 character
    maximum length: 50 characters
    card_holder_email
    required
    string Card holder's email. Issuer will use this information to assess the transaction.
    minimum length: 3 character
    maximum length: 254 characters
    card_holder_phone_number
    required
    string Card holder's phone number or mobile number. Issuer will use this information to assess the transaction.
    character: use +(country_code) as prefix. No - and/or blank space is allowed. Follow ITU-E.164 Standard
    minimum length: 7 character
    maximum length: 15 characters
    external_id
    optional
    string Your reference ID for identifying the created token
    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
    string Currency which you want to process the transaction in. Use a three-letter ISO currency code.
    Supported currencies:
    IDR for Indonesia
    PHP and USD for Philippines
    MYR for Malaysia
    THB for Thailand
    VND for Vietnam
    Other currencies are supported only if you are using your own MIDs. If left blank, defaults to currency based on your business country.
    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 recommended for increased likelihood of frictionless authentication on 3DS 2.0.
    billing details child parameters
    Key Value
    given_names
    optional
    WILL BE DEPRECATED BY 1ST OCTOBER 2024. Please use card_data.card_holder_first_name parameter

    string Primary or first name/s of the customer
    minimum length: 1 character
    maximum length: 255 characters
    Note: Required for AVS and recommended for 3DS 2.0
    surname
    optional
    WILL BE DEPRECATED BY 1ST OCTOBER 2024. Please use card_data.card_holder_last_name parameter

    string Surname or last name of the customer
    minimum length: 1 character
    maximum length: 255 characters
    Note: Required for AVS and recommended for 3DS 2.0
    email
    optional
    WILL BE DEPRECATED BY 1ST OCTOBER 2024. Please use card_data.card_holder_email parameter

    string Enduser's email address which associated with the card
    mobile_number
    optional
    WILL BE DEPRECATED BY 1ST OCTOBER 2024. Please use card_data.card_holder_phone_number parameter

    string Enduser's mobile phone number which associated with the card
    phone_number
    optional
    WILL BE DEPRECATED BY 1ST OCTOBER 2024. Please use card_data.card_holder_phone_number parameter

    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 recommended for 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 recommended for 3DS 2.0
    street_line2
    optional
    string Building street address
    minimum length: 1 character
    maximum length: 255 characters
    Note: Required for AVS and recommended for 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 recommended for 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 recommended for 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 recommended for 3DS 2.0
    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 authentication will proceed using your prioritized MID (first MID on your list)).
    Note:
    Only available in the response for switcher merchant

    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",
        "network_response": {
          "three_ds_trans_status": "Y",
          "three_ds_flow": "CHALLENGE"
        }
    }

    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
    external_id
    optional
    string Your reference ID for identifying the created token
    masked_card_number
    required
    string The first 6 or 8 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
    network_response
    optional
    object These error codes are returned as additional data and insights. Check our card declines and error code documentation for more details.
    network_response details child parameters
    three_ds_trans_status
    optional
    transStatus result, directly coming from the 3DS2 response.
    three_ds_flow
    optional
    If authenticated (3DS flow was followed), the authentication flow this transaction followed. Either frictionless or authenticated.

    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 performed 3DS. Merchant could check the ECI code to ensure the liability shift before proceeding to charge.
    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. Recommendation is to check the input and retry.
    INVALID_JSON_FORMAT
    400
    The request body is not valid JSON. Recommendation is to check the input and retry.
    ACCOUNT_NUMBER_INVALID_ERROR
    400
    Credit card number is invalid. Make sure to input the correct credit card number and retry.
    VALIDATION_ERROR
    400
    Data was passed in an incorrect format. Recommendation is to check the input and retry.
    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. Please retry in a few minutes.
    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",
        "external_id": "TEST1234",
        "card_data": {
            "card_holder_first_name": "John",
            "card_holder_last_name": "Doe",
            "card_holder_email": "johndoe@gmai.com",
            "card_holder_phone_number": "628212223242526"
        },
        "mid_label": "XBANK_TIDNEX"
    }

    Example Authentication Response

    {
        "id": "58e2097218b815f555c8a526",
        "external_id": "TEST1234",
        "status": "VERIFIED",
        "network_response": {
          "three_ds_trans_status": "Y",
          "three_ds_flow": "CHALLENGE"
        }
    }

    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
    optional
    string The amount that will be authenticated and processed on charge. Only required for single use tokens with bundled authentication.
    card_data
    optional
    object Additional information of the card
    card data child parameters
    Key Value
    card_holder_first_name
    required when card_data is present
    string Card holder's first name shown in card. Issuer will use this information to assess the transaction.
    character: Alphanumeric. No special characters are allowed.
    minimum length: 1 character
    maximum length: 50 characters
    card_holder_last_name
    required when card_data is present
    string Card holder's last name shown in card. Issuer will use this information to assess the transaction.
    character: Alphanumeric. No special characters are allowed.
    minimum length: 1 character
    maximum length: 50 characters
    card_holder_email
    required when card_data is present
    string Card holder's email. Issuer will use this information to assess the transaction.
    minimum length: 3 character
    maximum length: 254 characters
    card_holder_phone_number
    required when card_data is present
    string Card holder's phone number or mobile number. Issuer will use this information to assess the transaction.
    character: use +(country_code) as prefix. No - and/or blank space is allowed. Follow ITU-E.164 Standard
    minimum length: 7 character
    maximum length: 15 characters
    external_id
    optional
    string Your reference ID for identifying the created token
    token_id
    optional
    string ID of the token that you've created
    currency
    optional
    string Currency which you want to process the transaction in. Use a three-letter ISO currency code.
    Supported currencies:
    IDR for Indonesia
    PHP and USD for Philippines
    MYR for Malaysia
    THB for Thailand
    VND for Vietnam
    Other currencies are supported only if you are using your own MIDs. If left blank, defaults to currency based on your business country.
    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 authentication will proceed using your prioritized MID (first MID on your list)).
    Note:
    Only available in the response for switcher merchant

    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
    external_id
    optional
    string Your reference ID for identifying the authentication
    payer_authentication_url
    optional
    string If status is IN_REVIEW, this contains the URL for authenticating users with 3DS
    mid_label
    optional
    string MID label used to process the authentication.
    failure_reason
    optional
    string If status is FAILED, this describes the failure. See Tokenization Failure Reasons.
    network_response
    optional
    string These error codes are returned as additional data and insights. Check our card declines and error code documentation for more details.

    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",
          "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
      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
    )
    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",
        "network_response": {
          "card_network_response_code": "65",
          "card_network_descriptor": "Exceeds withdrawal count limit",
          "network_transaction_id": "123456",
          "merchant_advice_code": "28",
          "merchant_advice_descriptor": "Retry after 6 days",
          "three_ds_trans_status": "Y",
          "three_ds_flow": "CHALLENGE"
        }
    }

    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"
        }'
    <?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
      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. Recommendation is to check the input and retry
    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",
          "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_state": "DKI Jakarta",
              "postal_code": "993448",
              "country": "ID"
            }
          },
          "promotion": {
              "reference_id": "BCA_10",
              "original_amount": 1000000
          },
          "installment": {
              "count": 3,
                "interval": "month"
          },
          "metadata": {}
        }'
    <?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,
          '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',
      descriptor: "My new store",
      currency: "IDR",
      midLabel: "IDR_MID",
      billingDetails: {
          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_state: "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
        "XDT*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
    )
    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-split-rule
    optional
    string Split Rule ID that you would like to apply to this card charge in order to split and route payments to multiple accounts.

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

    If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

    Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

    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.
    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 XDT*[MERCHANT_NAME]-DESCRIPTOR
    For switcher merchant, it will always return [MERCHANT_NAME]-DESCRIPTOR
    currency
    optional

    string Currency which you want to process the transaction in. Use a three-letter ISO currency code. Xendit by default supports IDR for Indonesia and PHP for Philippines. Other currencies are supported only if you are using your own MIDs. If left blank, defaults to currency based on your business country.
    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 recommended for 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 recommended for 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_state
    optional
    string Geographic area, province, state, or region, 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
    metadata
    optional
    object A free-format JSON for additional information that you want to provide in the request.
    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 ID that was used at the Create Promotion API.
    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": "XDT*MYBUSINESS-MY NEW STORE",
        "id": "598d5dba51e0870d44c61539",
        "mid_label": "IDR_MID",
        "promotion": {
            "reference_id": "BCA_10",
            "original_amount": "1000000"
        },
        "installment": {
            "count": 3,
            "interval": "month"
        },
        "network_response": {
          "card_network_response_code": "65",
          "card_network_descriptor": "Exceeds withdrawal count limit",
          "network_transaction_id": "123456",
          "merchant_advice_code": "28",
          "merchant_advice_descriptor": "Retry after 6 days",
          "three_ds_trans_status": "Y",
          "three_ds_flow": "CHALLENGE"
        }
    }

    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": "XDT*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
    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 that is being charged. Can be CREDIT, DEBIT, PREPAID, and UNKNOWN.
    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 or 8 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 XDT*[MERCHANT_NAME]-DESCRIPTOR
    For switcher merchant, it will always return [MERCHANT_NAME]-DESCRIPTOR
    currency
    optional

    string Currency which you want to process the transaction in. Use a three-letter ISO currency code. Xendit by default supports IDR for Indonesia and PHP for Philippines. Other currencies are supported only if you are using your own MIDs. If left blank, defaults to currency based on your business country.
    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."
    network_response
    optional
    object These error codes are returned as additional data and insights. Check our card declines and error code documentation for more details.
    detil objek network_response
    card_network_response_code
    optional
    The response code returned by the scheme (Visa, Mastercard, JCB, China Unionpay or Amex).
    card_network_descriptor
    optional
    Description of the response code.
    network_transaction_id
    optional
    Transaction identifier returned by the scheme. When the network transaction ID is not provided, please take a look at the card_network_response_code and, if provided, the merchant_advice_code
    merchant_advice_code
    optional
    Only returned when present, only returned for Mastercard. These Mastercard codes describe what action to take.
    merchant_advice_descriptor
    optional
    Only returned when present. Only returned for Mastercard. Description / action to take for the merchant advice code.
    three_ds_trans_status
    optional
    transStatus result, directly coming from the 3DS2 response.
    three_ds_flow
    optional
    If authenticated (3DS flow was followed), the authentication flow this transaction followed. Either frictionless or authenticated.

    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
    AUTHENTICATION_FAILED Payment was declined because transaction is not authenticated yet. Recommend cardholder to to re-authenticate the transaction with 3DS. Alternatively, they can try to use a different card, other form of payment, or contact their card issuing bank to resolve the problem on online transaction.
    DECLINED_BY_ISSUER Payment was declined by the issuer with no additional information provided to Xendit. Ask your customer to contact issuing bank. Alternatively, they can try using different card or other form of payment
    DECLINED_BY_PROCESSOR Payment was declined by the processor. Ask your customer to try again. Alternatively, they can try to use a different card or other form of payment.
    EXPIRED_CARD The card you are trying to capture is expired. Ask your customer for a different card.
    ISSUER_SUSPECT_FRAUD Payment was declined by the issuer because them suspecting this payment to be fraudulent. Review the cardholder. If you believe the cardholder to be legitimate, recommend them to use a different card or other form of payment. Otherwise, avoid processing transaction from them to prevent chargeback.
    INACTIVE_OR_UNAUTHORIZED_CARD Payment was declined by the issuer because card is not authorized for online transactions. Recommend cardholder to contact their card issuing bank to resolve the problem on online transaction. Alternatively, they can try to use a different card or other form of payment.
    INSUFFICIENT_BALANCE The card you are trying to capture does not have enough balance to complete the capture
    INVALID_CARD Payment was declined by the issuer because incorrect card information being provided. Recommend cardholder to review the card information and try again. Alternatively, they can try to use a different card or other form of payment.
    INVALID_CVV Payment was declined by the issuer because incorrect card CVN / CVV / CSC being provided. Recommend cardholder to review the card CVV / CVN / CSC (3-4 digit code on the back of the card) and try again. Alternatively, they can try to use a different card or other form of payment.
    ISSUER_UNAVAILABLE Payment was declined by the processor because card issuer is unreachable. Recommend cardholder to contact their card issuing bank to resolve the problem on online transaction. Alternatively, they can try to use a different card or other form of payment.
    PROCESSOR_ERROR Payment was declined by the processor because intermittent error on processor side. Recommend cardholder to try again in a few minutes. Alternatively, they can try to use other form of payment.
    STOLEN_CARD The card you are trying to capture has been marked as stolen. Ask your customer for a different card.
    PROCESSOR_TIMEOUT We got timeout from our processor when requested the charge which indicated as intermittent connection problem. Advise customer to retry the transaction.
    FRAUD_RISK_BLOCKED Payment was declined by Xendit risk assessment. Please refer to the Fraud Risk Assessment section for more detail. Review the cardholder, as the payment was blocked by your blocklist. If you believe the cardholder to be legitimate, remove the identifier from the blocklist and ask them to try again. Otherwise, avoid processing transaction from them to prevent chargeback.

    Error Codes

    Error Code Description
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation. Recommendation is to check the input and retry.
    INVALID_JSON_FORMAT
    400
    The request body is not valid JSON. Recommendation is to check the input and retry.
    TOKEN_ALREADY_USED_ERROR
    400
    The single-use token ID has already been used in a charge. Recommendation is to create charge with different token_id.
    AUTHENTICATION_ALREADY_USED_ERROR
    400
    The authentication ID has already been used in a charge. Recommendation is to use different authentication_id to proceed charge.
    INVALID_TOKEN_ID_ERROR
    400
    The token ID format is invalid. Recommendation is to check if token_id format is correct and retry.
    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. Recommendation is to check if the CVN is already following the correct format and retry.
    AUTHENTICATION_ID_MISSING_ERROR
    400
    Authentication ID is required for this charge. Recommendation is to include authentication_id in the charge request.
    AMOUNT_GREATER_THAN_AUTHENTICATED_ERROR
    400
    Charge amount was greater than what was authenticated. Ensure the charge amount is the same as what was authenticated and retry.
    INVALID_AUTHENTICATION_ID_ERROR
    400
    The authentication ID format is invalid. Please check if your authentication_id is already following the correct format.
    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. Please check if you already include the correct API key in the request header. For charge, the API key you are using should be secret API key.
    AUTHENTICATION_NOT_FOUND_ERROR
    404
    Authenticated token with given authentication ID is not found. Please check if you already input the existing authentication_id in the request.
    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.

  • INCOMPLETE_AUTHENTICATION
    400
    The authentication_id sent cannot be used as authentication could not be completed. This usually happens when there is an issue preventing generation of the 2FA page, if the user did not complete the 3DS process, or something else happened such as a bank timeout. Please attempt the payment again, or exclude authentication_id from the Charge request if optional 3DS has been enabled for you.

    (If you’d like to skip authentication for optional or dynamic 3DS, please contact us so we can enable this feature for you. Refer to our Authentication documentation for instructions on integration and testing.)

    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)

    Charge with CVV for Multi-Use Token

    Example Charge with CVV using Xendit.js

    const tokenData = {
        token_id: “sample-token-id-6ab4hmu832j8oenx71b”,
        card_cvn: “123”,
        billing_details: object, 
        customer: object
    };

    Example Charge with CVV using Android SDK

    final Xendit xendit = new Xendit(getApplicationContext(), <PUBLISHABLE_KEY>, this);
    
    xendit.storeCVN(
            <tokenId>,
            <cardCVN>,
            <billingDetails>,
            <customerDetails>,
            null,
            callback);

    Example Charge with CVV using iOS SDK

    let storeCVNRequest = XenditStoreCVNRequest.init(tokenId: <tokenId>);
    authenticationRequest.cardCvn = <cardCvn>;
    
    Xendit.storeCVN(
            fromViewController: self,
            storeCVNRequest: storeCVNRequest,
            onBehalfOf: nil,
            completion: completion)

    CVV is part of the requirement that’s included specifically in card transactions, with cardholders providing three or four digit code to authorize the transaction. Why is including CVV important?

    If a merchant would want to perform a transaction with CVN/CVV for multi-use token, please follow along this guide.

    What is CVV?

    CVV stands for “Card Verification Value,” is a three- or four-digit code on the front or back of the card. CVV is being used by the issuer as an additional layer of security, and thus providing it might increase the success rate and reduce the chance of fraud.

    CVV is part of a Sensitive Authentication Data (SAD) and is highly regulated by PCI. According to the PCI rule, the business is not allowed to store the CVN/CVV after the authorization takes place and the system must be following the PCI regulation and processing CVN/CVV must be within the Card Data Environment (CDE) that’s being audited.

    How to use

    Prepare multiple use token ID that you would want to use to perform charge. Use the token ID by referring to the sample code on the right section.

    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",
      "network_response": {
        "card_network_response_code": "65",
        "card_network_descriptor": "Exceeds withdrawal count limit",
        "network_transaction_id": "123456",
        "merchant_advice_code": "28",
        "merchant_advice_descriptor": "Retry after 6 days",
        "three_ds_trans_status": "Y",
        "three_ds_flow": "CHALLENGE"
      }
    }

    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

    with-split-rule
    optional
    string Split Rule ID that you would like to apply to this card charge in order to split and route payments to multiple accounts.

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

    If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

    Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

    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. Recommendation is to check the input and retry.
    INVALID_JSON_FORMAT
    400
    The request body is not valid JSON. Recommendation is to check the input and retry.
    AMOUNT_GREATER_THAN_AUTHORIZED_ERROR
    400
    Capture amount is larger than authorized amount. Ensure the capture amount is the same as what was authorized and retry.
    INVALID_CHARGE_STATUS_ERROR
    400
    Charge status is not AUTHORIZED. Please authorize the transaction first then retry the capture.
    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 below
    failure_reason
    optional
    string Reason provided if refund request fails. See Refund Failure Reasons below
    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",
      "network_response": {
        "card_network_response_code": "65",
        "card_network_descriptor": "Exceeds withdrawal count limit",
        "network_transaction_id": "123456",
        "merchant_advice_code": "28",
        "merchant_advice_descriptor": "Retry after 6 days",
        "three_ds_trans_status": "Y",
        "three_ds_flow": "CHALLENGE"
      }
    }

    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. Recommendation is to check the input and retry.
    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 or 8 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 or 8 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.
    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.

    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 or 8 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

    API 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
    You can access the new API easily by calling POST /ewallets/charges

    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);
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    EWalletChargeClient eWalletCharge = xendit.EWalletCharge;
    
    EWalletChargeParameter parameter = new EWalletChargeParameter
    {
      ReferenceId = "demo-reference-id",
      Currency = Currency.IDR,
      Amount = 1000,
      CheckoutMethod = EWalletEnum.CheckoutMethod.OneTimePayment,
      ChannelCode = EWalletEnum.ChannelCode.IdOvo,
      ChannelProperties = new EWalletChargeProperties
      {
        MobileNumber = "+628123123123",
      },
    };
    
    EWalletChargeResponse eWalletChargeResponse = await eWalletCharge.Create(parameter);
    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-split-rule
    optional
    string Split Rule ID that you would like to apply to this eWallet charge

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

    If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

    Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

    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)
    currency
    required
    string Currency used for the transaction in ISO4217 format - IDR, PHP, VND, THB, MYR
    amount
    required
    number Transaction amount to be paid
    Min - 1,000 for ID_JENIUSPAY and 100 IDR for all other eWallets 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_ASTRAPAY, ID_JENIUSPAY, ID_SAKUKU, PH_PAYMAYA, PH_GCASH, PH_GRABPAY, PH_SHOPEEPAY, VN_APPOTA, VN_MOMO, VN_SHOPEEPAY, VN_VNPTWALLET, VN_VIETTELPAY, VN_ZALOPAY, TH_WECHATPAY, TH_LINEPAY, TH_TRUEMONEY, TH_SHOPEEPAY, MY_TOUCHNGO, MY_SHOPEEPAY, MY_GRABPAY, MY_WECHATPAY
    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)
    JENIUS PAY required fields
    Key Value
    cashtag
    required
    string Unique identifier for each Jenius account, similar to username. Always start with the “$” sign. 3-15 characters excluding the “$” sign. Alphanumeric and the “_" sign
    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 - one time payment, SHOPEEPAY (ID, PH & TH), WECHATPAY, LINEPAY, TRUEMONEY, TOUCHNGO - one time payment, SAKUKU required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    SHOPEEPAY (VN), APPOTA, MOMO, ZALOPAY, VNPTWALLET, VIETTELPAY required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    pending_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is pending
    SHOPEEPAY (ID, PH & MY) - 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. Not applicable for PH_SHOPEEPAY currently.
    GCASH, GRABPAY (PH & MY), ASTRAPAY, LINKAJA, TOUCHNGO - 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
    MAYA (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.
    WECHATPAY (MY) required fields
    Key Value
    device_type
    required
    string determines the device type of the end user. Accepts the following values:
    • DESKTOP
    • MOBILE
    payer_ip_address
    optional
    string The IP address of the end user's client (e.g. 192.168.0.1)
    Required if device_type is set to MOBILE
    pending_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is pending
    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
    GRABPAY (MY)
    Key Value
    allowed_payment_options
    optional
    Array of enums
    PAYLATER_POSTPAID - Pay next month
    PAYLATER_INSTALLMENTS_4MO - Pay with installments

    Usage for each checkout_method
    ONE_TIME_PAYMENT - Choose which payment option to show, default will show all. To hide all payment options, use empty Array []. Ewallat balance option will always visible.
    TOKENIZED_PAYMENT - Choose One payment option to use, default will use GrabPay Ewallet balance
    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, VND, THB, MYR
    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,
      "refunded_amount": null,
      "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",
      "void_status": null,
      "voided_at": null,
      "capture_now": true,
      "customer_id": null,
      "payment_method_id": null,
      "failure_code": null,
      "basket": null,
      "metadata": {
        "branch_code": "tree_branch"
      }
    }
    Channel Code specifies which eWallet will be used to process the transaction
    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
    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
    REFUNDED
    Payment transaction for specified charge_id has been either partially or fully refunded
    currency
    required
    string Currency used for the transaction in ISO4217 format - IDR, PHP, VND, THB, MYR
    charge_amount
    required
    number Requested charge amount from merchant
    capture_amount
    optional
    number Requested capture amount from merchant. At the moment, capture_amount will always be the same as charge_amount
    refunded_amount
    optional
    number Total amount refunded by merchant to end user
    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 - ID_OVO, ID_DANA, ID_LINKAJA, ID_SHOPEEPAY, ID_ASTRAPAY, ID_JENIUSPAY, ID_SAKUKU, PH_PAYMAYA, PH_GCASH, PH_GRABPAY, PH_SHOPEEPAY, VN_APPOTA, VN_MOMO, VN_SHOPEEPAY, VN_VNPTWALLET, VN_VIETTELPAY, VN_ZALOPAY, TH_WECHATPAY, TH_LINEPAY, TH_TRUEMONEY, TH_SHOPEEPAY, MY_TOUCHNGO, MY_SHOPEEPAY, MY_GRABPAY, MY_WECHATPAY
    channel_properties
    optional
    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)
    JENIUS PAY required fields
    Key Value
    cashtag
    required
    string Unique identifier for each Jenius account, similar to username. Always start with the “$” sign. 3-15 characters excluding the “$” sign. Alphanumeric and the “_" sign
    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 - one time payment, SHOPEEPAY (ID, PH & TH) - one time payment, WECHATPAY, LINEPAY, TRUEMONEY, TOUCHNGO - one time payment, SAKUKU required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    SHOPEEPAY (VN), APPOTA, MOMO, ZALOPAY, VNPTWALLET, VIETTELPAY required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    pending_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is pending
    SHOPEEPAY (ID, PH & MY) - 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. Not applicable for PH_SHOPEEPAY currently.
    GCASH, GRABPAY (PH & MY), ASTRAPAY, LINKAJA, TOUCHNGO - 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
    MAYA (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
    WECHATPAY (MY) required fields
    Key Value
    device_type
    required
    string determines the device type of the end user. Accepts the following values:
    • DESKTOP
    • MOBILE
    payer_ip_address
    optional
    string The IP address of the end user's client (e.g. 192.168.0.1)
    Required if device_type is set to MOBILE
    pending_redirect_url
    optional
    string URL where the end-customer is redirected if the authorization is pending
    Required if device_type is set to MOBILE
    success_redirect_url
    optional
    string URL where the end-customer is redirected if the authorization is successful
    Required if device_type is set to MOBILE
    failure_redirect_url
    optional
    string URL where the end-customer is redirected if the authorization has failed
    Required if device_type is set to MOBILE
    GRABPAY (MY)
    Key Value
    allowed_payment_options
    optional
    Array of enums
    PAYLATER_POSTPAID - Pay next month
    PAYLATER_INSTALLMENTS_4MO - Pay with installments

    Usage for each checkout_method
    ONE_TIME_PAYMENT - Choose which payment option to show, default will show all. To hide all payment options, use empty Array []. Ewallat balance option will always visible.
    TOKENIZED_PAYMENT - Choose One payment option to use, default will use GrabPay Ewallet balance
    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 SHOPEEPAY (ID, PH & MY) ASTRAPAY MAYA (PAYMAYA) GCASH GRABPAY (PH & MY) SAKUKU TOUCHNGO WECHATPAY (MY)
    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
    void_status
    optional
    string Status of the void request. Available values: PENDING, FAILED, SUCCEEDED
    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, VND, THB, MYR
    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
    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_PAYMENT_METHOD_ID
    400
    There is a mismatch between the requested channel_code or customer_id against the values used during creation of the specified payment_method_id. Or that the payment_method_id does not exist in this account. Please retry with a valid payment_method_id
    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
    INVALID_TOKEN
    401
    Account linking token for this end user has expired. Please reinitiate account linking before retrying.
    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
    CHARGE_LIMIT_EXCEEDED
    429
    Maximum of 3 request attempts to Jenius Pay per cashtag within a span of 10 minutes has been exceeded. Please wait for 10 minutes before trying to initiate a new request
    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

    Xendit notifies your system upon successful payments via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook Settings in Xendit Dashboard under eWallets paid.

    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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

    Example: Success Payment Webhook 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,
        "payment_detail": {
            "fund_source": "SHOPEEPAY_BALANCE",
            "source": null
        },
        "metadata": {
          "branch_code": "tree_branch"
        }
      }
    }
    Header Parameter Type Description
    x-callback-token
    string Your Xendit unique webhook token to verify the origin of the webhook

    webhook-id
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    Body Parameter Type Description
    event
    required
    string Identifies the event that triggered a notification to the merchant. ewallet.capture occurs when eWallet provider confirms the payment status of a transaction
    business_id
    required
    string Business ID of the merchant
    created
    required
    string ISO 8601 Timestamp for webhook 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, REFUNDED
    currency
    required
    string Currency used for the transaction in ISO4217 format - IDR, PHP, VND, THB, MYR
    charge_amount
    required
    number Requested charge amount from merchant
    capture_amount
    optional
    number Requested capture amount from merchant. At the moment, capture_amount will always be the same as charge_amount
    refunded_amount
    optional
    number Total amount refunded by merchant to end user
    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_ASTRAPAY, ID_JENIUSPAY, ID_SAKUKU, PH_PAYMAYA, PH_GCASH, PH_GRABPAY, PH_SHOPEEPAY, MY_SHOPEEPAY, MY_GRABPAY, MY_WECHATPAY
    channel_properties
    optional
    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)
    JENIUS PAY required fields
    Key Value
    cashtag
    required
    string Unique identifier for each Jenius account, similar to username. Always start with the “$” sign. 3-15 characters excluding the “$” sign. Alphanumeric and the “_" sign
    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, TOUCHNGO - one time payment, SHOPEEPAY (ID & PH) - one time payment required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    SHOPEEPAY (ID, PH & MY) - 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. Not applicable for PH_SHOPEEPAY currently.
    GCASH, GRABPAY (PH & MY), ASTRAPAY, LINKAJA, TOUCHNGO - 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
    MAYA (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.
    WECHATPAY (MY) required fields
    Key Value
    device_type
    required
    string determines the device type of the end user. Accepts the following values:
    • DESKTOP
    • MOBILE
    payer_ip_address
    optional
    string The IP address of the end user's client (e.g. 192.168.0.1)
    Required if device_type is set to MOBILE
    pending_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is pending
    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
    GRABPAY (MY)
    Key Value
    allowed_payment_options
    optional
    Array of enums
    PAYLATER_POSTPAID - Pay next month
    PAYLATER_INSTALLMENTS_4MO - Pay with installments

    Usage for each checkout_method
    ONE_TIME_PAYMENT - Choose which payment option to show, default will show all. To hide all payment options, use empty Array []. Ewallat balance option will always visible.
    TOKENIZED_PAYMENT - Choose One payment option to use, default will use GrabPay Ewallet balance
    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 Webhook 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
    void_status
    optional
    string Status of the void request. Available values: PENDING, FAILED, SUCCEEDED
    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 webhook or GET payment status after transaction is attempted by end user
    payment_detail
    optional
    object Object containing additional payment details.
    Object parameters details
    Key Value
    fund_source
    optional
    string The type of the fund origin
    SHOPEEPAY ID - EWALLET_BALANCE, 1_MONTH_INSTALLMENT, 2_MONTH_INSTALLMENT, 3_MONTH_INSTALLMENT, 6_MONTH_INSTALLMENT, 12_MONTH_INSTALLMENT
    SHOPEEPAY MY - SHOPEEPAY_BALANCE, SPAYLATER_INSTALLMENTS_1MO, SPAYLATER_INSTALLMENTS_2MO, SPAYLATER_INSTALLMENTS_3MO, SPAYLATER_INSTALLMENTS_6MO, SPAYLATER_INSTALLMENTS_12MO
    source
    optional
    string The name of the channel
    SHOPEEPAY ID - Shopeepay
    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 Webhook 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,
        "refunded_amount": null,
        "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",
        "void_status": null,
        "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.
    FAILURE_DETAILS_UNAVAILABLE
    Details related to the failed payment request were not provided by the eWallet provider.

    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);
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    EWalletChargeClient eWalletCharge = xendit.EWalletCharge;
    
    EWalletChargeResponse eWalletChargeRepsonse = await eWalletCharge.Get("ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2");
    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,
      "refunded_amount": null,
      "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",
      "void_status": null,
      "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
    REFUNDED
    Payment transaction for specified charge_id has been either partially or fully refunded
    currency
    required
    string Currency used for the transaction in ISO4217 format - IDR, PHP, VND, THB, MYR
    charge_amount
    required
    number Requested charge amount from merchant
    capture_amount
    optional
    number Requested capture amount from merchant. At the moment, capture_amount will always be the same as charge_amount
    refunded_amount
    optional
    number Total amount refunded by merchant to end user
    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_ASTRAPAY, ID_JENIUSPAY, ID_SAKUKU, PH_PAYMAYA,PH_GCASH, PH_GRABPAY, PH_SHOPEEPAY, VN_APPOTA, VN_MOMO, VN_SHOPEEPAY, VN_VNPTWALLET, VN_VIETTELPAY, VN_ZALOPAY, TH_WECHATPAY, TH_LINEPAY, TH_TRUEMONEY, TH_SHOPEEPAY, MY_TOUCHNGO, MY_SHOPEEPAY, MY_GRABPAY, MY_WECHATPAY
    channel_properties
    optional
    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)
    JENIUS PAY required fields
    Key Value
    cashtag
    required
    string Unique identifier for each Jenius account, similar to username. Always start with the “$” sign. 3-15 characters excluding the “$” sign. Alphanumeric and the “_" sign
    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 - one time payment, SHOPEEPAY (ID, PH & TH), WECHATPAY, LINEPAY, TRUEMONEY, TOUCHNGO - one time payment required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    SHOPEEPAY (VN), APPOTA, MOMO, ZALOPAY, VNPTWALLET, VIETTELPAY one time payment required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    pending_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is pending
    SHOPEEPAY (ID, PH & MY) - 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. Not applicable for PH_SHOPEEPAY currently.
    GCASH, GRABPAY (PH & MY), ASTRAPAY, LINKAJA, TOUCHNGO - 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
    MAYA (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.
    WECHATPAY (MY) required fields
    Key Value
    device_type
    required
    string determines the device type of the end user. Accepts the following values:
    • DESKTOP
    • MOBILE
    payer_ip_address
    optional
    string The IP address of the end user's client (e.g. 192.168.0.1)
    Required if device_type is set to MOBILE
    pending_redirect_url
    optional
    string URL where the end-customer is redirected if the authorization is pending
    Required if device_type is set to MOBILE
    success_redirect_url
    optional
    string URL where the end-customer is redirected if the authorization is successful
    Required if device_type is set to MOBILE
    failure_redirect_url
    optional
    string URL where the end-customer is redirected if the authorization has failed
    Required if device_type is set to MOBILE
    GRABPAY (MY)
    Key Value
    allowed_payment_options
    optional
    Array of enums
    PAYLATER_POSTPAID - Pay next month
    PAYLATER_INSTALLMENTS_4MO - Pay with installments

    Usage for each checkout_method
    ONE_TIME_PAYMENT - Choose which payment option to show, default will show all. To hide all payment options, use empty Array []. Ewallat balance option will always visible.
    TOKENIZED_PAYMENT - Choose One payment option to use, default will use GrabPay Ewallet balance
    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
    void_status
    optional
    string Status of the void request. Available values: PENDING, FAILED, SUCCEEDED
    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, VND, THB, MYR
    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

    Void eWallet Charge

    This Void API allows you to void a successfully completed eWallet payment where 100% of the original amount is returned to the end user

    Voiding an eWallet charge is defined as the cancellation of eWallet payments created within the same day and before the cutoff time of 23:50:00 (UTC+07:00 for Indonesia eWallets/ UTC+08:00 for Philippines eWallets). If an eWallet charge is created at 19:00:00 on 1 September 2021, cancelling this transaction by 23:50:00 (UTC+07:00 for Indonesia eWallets/ UTC+08:00 for Philippines eWallets) on 1 September 2021 can be done using this Void API. To cancel eWallet payments after the aforementioned cutoff time, the Refund API should be used

    Indonesia


    Value OVO DANA SHOPEEPAY LINKAJA ASTRAPAY JENIUS PAY SAKUKU
    Available at Xendit?
    ✓ for One-Time Payment, ✕ for Tokenized Payment
    Validity Period
    Same Day Before 23:50:00 UTC+07:00 Same Day Before 23:50:00 UTC+07:00 Same Day Before 23:50:00 UTC+07:00 Same Day Before 23:50:00 UTC+07:00 N/A Same Day Before 23:50:00 UTC+07:00 N/A
    Transaction Fee Returned?
    N/A N/A

    Philippines

    Value GCASH MAYA (PAYMAYA) GRABPAY SHOPEEPAY
    Available at Xendit?
    Validity Period
    Same Day Before 23:50:00 UTC+08:00 Same Day Before 23:50:00 UTC+08:00 Same Day Before 23:50:00 UTC+08:00 Same Day Before 23:50:00 UTC+08:00
    Transaction Fee Returned?

    Vietnam

    Value APPOTA MOMO ZALOPAY SHOPEEPAY VNPTWALLET VIETTELPAY
    Available at Xendit?

    Thailand

    Value WECHATPAY LINEPAY SHOPEEPAY TRUEMONEY
    Available at Xendit?

    Malaysia

    Value TOUCHNGO SHOPEEPAY GRABPAY WECHATPAY
    Available at Xendit?
    x x x

    Endpoint: Create eWallet Void

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

    Request Parameters

    Example: Create eWallet Void - Request

    curl https://api.xendit.co/ewallets/charges/ewc_532as23lew2321id/void -X POST \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
       -H 'Content-Type: application/json' \
    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 the charge request transaction (returned as id in the eWallet Charge request)

    Response Parameters

    Example: Create eWallet Void - Response

    {
        "id" : "ewc_532as23lew2321id",
        "business_id" : "5easfnn23aadlmnaa42",
        "reference_id" : "test_reference_id",
        "status" : "SUCCEEDED",
        "currency" : "IDR",
        "charge_amount" : 123456,
        "capture_amount" : 123456,
        "refunded_amount" : null,
        "checkout_method" : "ONE_TIME_PAYMENT",
        "channel_code" : "ID_DANA",
        "channel_properties" : 
            {
            "mobile_number" : "+6287777771111"
            },
        "actions" : null,
        "is_redirect_required" : false,
        "callback_url" : "https://webhook.me/gethooked",
        "created" : "2020-04-20T16:23:52Z",
        "updated" : "2020-04-20T16:23:52Z",
        "void_status" : "PENDING",
        "voided_at" : null,
        "capture_now" : true,
        "customer_id" : null,
        "payment_method_id" : null,
        "failure_code" : null,
        "basket" : null,
        "metadata" : 
            {
            "branch_code" : "senayan_372"
            }
    }
    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
    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. At the moment, capture_amount will always be the same as charge_amount
    refunded_amount
    optional
    number Total amount refunded by merchant to end user
    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_JENIUSPAY, PH_PAYMAYA,PH_GCASH, PH_GRABPAY, PH_SHOPEEPAY
    channel_properties
    optional
    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)
    JENIUS PAY required fields
    Key Value
    cashtag
    required
    string Unique identifier for each Jenius account, similar to username. Always start with the “$” sign. 3-15 characters excluding the “$” sign. Alphanumeric and the “_" sign
    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 - one time payment, SHOPEEPAY (ID & PH) - one time payment required fields
    Key Value
    success_redirect_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    SHOPEEPAY (ID & PH) - 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. Not applicable for PH_SHOPEEPAY currently.
    GCASH, GRABPAY, ASTRAPAY, LINKAJA - 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
    MAYA (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 Webhook 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
    void_status
    optional
    string Status of the void request. Value should be PENDING at this point
    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 webhook 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 Void - Error Response

    {
        "error_code": "DATA_NOT_FOUND",
        "message": "Resource 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.
    VOID_NOT_SUPPORTED
    400
    Void feature is not available as the method is not provided by eWallet provider.
    VOID_TEMPORARILY_UNAVAILABLE
    400
    Void feature is unavailable between 00:00:00 and 05:00:00 UTC+07:00/UTC+08:00 each day for ShopeePay transactions. Please try again after 05:00:00 UTC+07:00/UTC+08:00.
    INVALID_API_KEY
    401
    API key format is invalid.
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request.
    INELIGIBLE_TRANSACTION
    403
    Payment has already passed its void validity period (after 23:50:00 UTC+07:00/UTC+08:00) for requested operation or status of charge is not SUCCEEDED.
    INELIGIBLE_MERCHANT
    403
    Merchant has a settlement configuration that is not eligible for voiding transactions. Please contact Xendit customer support for resolution.
    DATA_NOT_FOUND
    404
    Resource 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 eWallet provider will be notified to resolve this issue.

    Get Void

    To get the status of an eWallet void request, use the Get eWallet Charge Status API where the response includes the void_status and voided_at parameters

    Void Callback

    The void webhook notification will be sent as POST request to the same endpoint used in creating an eWallet charge. 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

    Webhook Payload

    Example: Success eWallet Void Webhook Payload

    {
      "event": "ewallet.void",
      "business_id": "5abe2389ewpejrt238",
      "created": "2020-04-20T16:25:52Z",
      "data": {
        "id": "ewc_532as23lew2321id",
        "reference_id": "test_reference_id",
        "status": "VOIDED",
        "currency": "IDR",
        "checkout_method": "ONE_TIME_PAYMENT",
        "charge_amount": 123456,
        "capture_amount": 123456,
        "refunded_amount": null,
        "channel_code": "ID_DANA",
        "channel_properties": {
          "mobile_number": "+6287777771111"
        },
        "actions": null,
        "is_redirect_required": false,
        "callback_url": "https://webhook.me/gethooked",
        "created": "2020-04-20T16:23:52Z",
        "updated": "2020-04-20T16:23:52Z",
        "void_status": "SUCCEEDED",
        "voided_at": "2020-04-20T23:24:30Z",
        "capture_now": true,
        "customer_id": null,
        "payment_method_id": null,
        "failure_code": null,
        "basket": null,
        "metadata": {
          "branch_code": "senayan_372"
        }
      }
    }
    Header Parameter Type Description
    x-callback-token
    string Your Xendit unique webhook token to verify the origin of the webhook

    webhook-id
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    Body Parameter Parameter Type Description
    event
    required
    string Identifies the event that triggered a notification to the merchant. ewallet.void occurs when eWallet provider confirms the receipt of a void request
    business_id
    required
    string Business ID of the merchant
    created
    required
    string Timestamp in ISO 8601 for webhook notification creation. Timezone UTC+0
    data
    optional
    object eWallet Charge object, with business_id abstracted out

    Refund eWallet Charge

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

    Other than the Refund API, the Void API can also be used to cancel an eWallet payment within the same day as the charge creation and before the cutoff time of 23:50:00 (UTC+07:00 for Indonesia eWallets/ UTC+08:00 for Philippines eWallets). Void guarantees that transaction fee and VAT are refunded since the cancellation happens before any real money is moved. Specifically for DANA payments, transaction fee and VAT are refunded in a successful void request but not in a successful refund request

    Indonesia


    Value OVO DANA SHOPEEPAY LINKAJA ASTRAPAY JENIUS PAY SAKUKU
    Available at Xendit?
    ✕ for One-Time Payment, ✓ for Tokenized Payment ✓ for One-Time Payment, ✕ for Tokenized Payment
    Partial Refund Allowed?
    N/A N/A
    Multiple Refunds Allowed?
    N/A ✕ (Only 1 Partial Refund Per Payment Allowed) N/A
    Validity Period
    14 Days 30 Days 365 Days 30 Days N/A Always Valid/No Expiration N/A
    Transaction Fee Returned?
    N/A ✓ for Full Refund, ✕ for Partial Refund N/A

    Philippines



    Value GCASH MAYA (PAYMAYA) GRABPAY SHOPEEPAY
    Available at Xendit?
    Partial Refund Allowed?

    (Not on Same Day)
    Multiple Refunds Allowed?

    (Capped at 7)
    Validity Period
    180 Days 365 Days 365 Days 365 Days
    Transaction Fee Returned?

    Vietnam

    Value APPOTA MOMO ZALOPAY SHOPEEPAY VNPTWALLET VIETTELPAY
    Available at Xendit?
    Partial Refund Allowed?
    N/A
    Multiple Refunds Allowed?
    N/A
    Validity Period
    Always Valid/No Expiration Always Valid/No Expiration 180 Days 90 Days Always Valid/No Expiration N/A
    Transaction Fee Returned?
    N/A

    Thailand

    Value WECHATPAY LINEPAY SHOPEEPAY TRUEMONEY
    Available at Xendit?

    Malaysia

    Value TOUCHNGO SHOPEEPAY GRABPAY WECHATPAY
    Available at Xendit?
    Partial Refund Allowed?
    Multiple Refunds Allowed?
    Validity Period
    30 Days 365 Days 365 Days 365 Days
    Transaction Fee Returned?

    Endpoint: Create eWallet Refund

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

    Request Parameters

    Example: Create eWallet Refund - Request

    curl hhttps://api.xendit.co/ewallets/charges/ewc_532as23lew2321id/refunds -X POST \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
       -H 'Content-Type: application/json' \
       --data-raw '{
        "amount": "1000",
        "reason": "REQUESTED_BY_CUSTOMER"
    }'

    Example: Sample JSON request

    {
        "amount": 1000,
        "reason": "REQUESTED_BY_CUSTOMER"
    }
    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 eWallet Charge request)
    Body Parameter Type Description
    amount
    optional
    number Amount to be refunded to your customer. Cumulative amount refunded must not exceed the original transacted amount.

    If the amount field is not present in the request body, the remaining unrefunded amount of the charge would be processed
    reason
    optional
    string Reason for refund, one of the following values can be used.
    Available values: DUPLICATE, FRAUDULENT, REQUESTED_BY_CUSTOMER, CANCELLATION, OTHERS

    Response Parameters

    Example: Create eWallet Refund - Response

    { 
        "id" : "ewr_532as23lew2321id",
        "charge_id" : "5easfnn23aadlmnaa42",
        "status" : "PENDING",
        "currency" : "IDR",
        "channel_code" : "ID_DANA",
        "capture_amount" : 123456,
        "refund_amount" : 123456,
        "reason" : "REQUESTED_BY_CUSTOMER",
        "failure_code" : null,
        "created" : "2020-04-20T16:23:52Z",
        "updated" : "2020-04-20T16:23:52Z"
    }
    Body Parameter Type Description
    id string Unique identifier for the refund transaction
    charge_id string Unique identifier for the original charge transaction
    status string Status of the refund request
    Available values: SUCCEEDED, FAILED, PENDING
    currency string Currency used for the transaction in ISO 4217 format
    Supported currency: IDR, PHP, MYR, VND
    capture_amount number Requested capture amount from merchant
    refund_amount number Amount to be refunded
    channel_code string Channel code indicating eWallet provider
    Supported channels: ID_OVO, ID_DANA, ID_SHOPEEPAY, ID_LINKAJA, ID_JENIUSPAY, PH_PAYMAYA,PH_GCASH, PH_GRABPAY, PH_SHOPEEPAY, VN_APPOTA, VN_MOMO, VN_SHOPEEPAY, VN_VNPTWALLET, VN_ZALOPAY, MY_TOUCHNGO, MY_SHOPEEPAY, MY_GRABPAY, MY_WECHATPAY
    reason string Reason for refund
    failure_code string Reason for refund transaction failing
    created string Timestamp in ISO 8601 for refund request
    updated number Timestamp in ISO 8601 for refund object update

    Error Codes

    Example: Create eWallet Refund - Error Response

    {
        "error_code": "DATA_NOT_FOUND",
        "message": "Resource 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.
    MAXIMUM_REFUND_AMOUNT_REACHED
    400
    Requested refund amount cannot exceed remaining unrefunded amount of the successful charge.
    MAXIMUM_REFUND_TRANSACTION_REACHED
    400
    You have reached the maximum refund transactions allowed for this charge. Kindly check the refund limitations for all eWallet channels here https://docs.xendit.co/ewallet/payment-flows/void-and-refund#refund-ewallet-charge.
    PARTIAL_REFUND_NOT_SUPPORTED
    400
    Partial refund feature is not available as the method is not provided by the eWallet provider.
    REFUND_TEMPORARILY_UNAVAILABLE
    400
    Refund feature is unavailable between 23:50:00 and 05:00:00 UTC+07:00/UTC+08:00 each day for ShopeePay transactions. Please try again after 05:00:00 UTC+07:00/UTC+08:00.
    REFUND_TEMPORARILY_UNAVAILABLE
    400
    Partial refund feature is not available for Maya (PayMaya) on the day of transaction. Please try again after 23:59:59 of transaction day.
    REFUND_NOT_SUPPORTED
    400
    Refund feature is not available as the method is not provided by the eWallet provider.
    REFUND_IN_PROGRESS
    400
    Concurrent refund requests to a single eWallet charge is not allowed. Please wait for the pending refund request to be completed before initiating a new one.
    INVALID_API_KEY
    401
    API key format is invalid.
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request.
    INELIGIBLE_TRANSACTION
    403
    Payment has already passed its refund validity period for the requested operation or the status of the original transaction is FAILED, PENDING, or VOIDED.
    INSUFFICIENT_BALANCE
    403
    There is insufficient balance in your account to perform a refund. Please top up your balance with a sufficient amount before retrying the refund.
    DATA_NOT_FOUND
    404
    Resource 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 eWallet provider will be notified to resolve this issue.

    Refund Callback

    The refund webhook notification will be sent as POST request to the same endpoint used in creating an eWallet charge. 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

    Webhook Payload

    Example: Success eWallet Refund Webhook Payload

    {
      "event": "ewallet.refund",
      "business_id": "5abe2389ewpejrt238",
      "created": "2020-04-20T16:25:52Z",
      "data": {
        "id": "ewr_532as23lew2321id",
        "charge_id": "ewc_5easfnn23aadlmnaa42",
        "status": "SUCCEEDED",
        "currency": "IDR",
        "channel_code": "ID_DANA",
        "capture_amount": 123456,
        "refund_amount": 123456,
        "reason": "REQUESTED_BY_CUSTOMER",
        "failure_code": null,
        "created": "2020-04-20T16:23:52Z",
        "updated": "2020-04-20T16:23:52Z"
      }
    }
    Header Parameter Type Description
    x-callback-token
    string Your Xendit unique webhook token to verify the origin of the webhook

    webhook-id
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    Body Parameter Parameter Type Description
    event
    required
    string Identifies the event that triggered a notification to the merchant. ewallet.refund occurs when eWallet provider confirms the receipt of a refund request
    business_id
    required
    string Business ID of the merchant
    created
    required
    string Timestamp in ISO 8601 for webhook notification creation. Timezone UTC+0
    data
    optional
    object eWallet Refund object, with business_id abstracted out

    Failure Codes

    Failure Code Description
    INELIGIBLE_TRANSACTION
    Transaction has already passed its validity period for the requested operation or the number of refunds requested has exceeded the allowable number of tries.
    INSUFFICIENT_BALANCE
    Switcher account does not have sufficient balance to perform a refund. Please retry after ensuring there is sufficient balance in the switcher account.
    REFUND_TEMPORARILY_UNAVAILABLE
    Refund is temporarily unavailable because of settlement constraints with the eWallet provider. Please try again later.
    MAXIMUM_USER_BALANCE_EXCEEDED
    Refund could not be processed because the amount returned will cause end user's wallet balance to exceed maximum allowable value.
    INELIGIBLE_PARTIAL_REFUND_TRANSACTION
    Transaction specified is not eligible for partial refund because of eWallet provider's limitations. You can retry refund by doing full refund. GrabPay doesn't allow partial refunds for transactions made under promos or using GrabPay points.

    Get Refund

    Get the status and details of a specific eWallet refund by its Refund ID

    Endpoint: Get eWallet Refund by Refund ID

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

    Request Parameters

    Example: GET eWallet Refund by Refund ID - Request

    curl https://api.xendit.co/ewallets/charges/ewc_5easfnn23aadlmnaa42/refunds/ewr_532as23lew2321id -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 eWallet Charge
    refund_id
    required
    string ID of eWallet Refund

    Response Parameters

    Example: GET eWallet Refund by Refund ID - Response

    { 
        "id" : "ewr_532as23lew2321id",
        "charge_id" : "5easfnn23aadlmnaa42",
        "status" : "SUCCEEDED",
        "currency" : "IDR",
        "channel_code" : "ID_DANA",
        "capture_amount" : 123456,
        "refund_amount" : 100000,
        "reason" : "REQUESTED_BY_CUSTOMER",
        "failure_code" : null,
        "created" : "2020-04-20T16:23:52Z",
        "updated" : "2020-04-20T16:23:52Z"
    }
    Body Parameter Type Description
    id string Unique identifier for the refund transaction
    charge_id string Unique identifier for the original charge transaction
    status string Status of the refund request
    Available values: SUCCEEDED, FAILED, PENDING
    currency string Currency used for the transaction in ISO 4217 format
    Supported currency: IDR, PHP, MYR, VND
    capture_amount number Requested capture amount from merchant
    refund_amount number Amount to be refunded
    channel_code string Channel code indicating eWallet provider
    Supported channels: ID_OVO, ID_DANA, ID_SHOPEEPAY, ID_LINKAJA, ID_JENIUSPAY, PH_PAYMAYA,PH_GCASH, PH_GRABPAY, PH_SHOPEEPAY, VN_APPOTA, VN_MOMO, VN_SHOPEEPAY, VN_VNPTWALLET, VN_ZALOPAY, MY_TOUCHNGO, MY_SHOPEEPAY, MY_GRABPAY, MY_WECHATPAY
    reason string Reason for refund
    failure_code string Reason for refund transaction failing
    created string Timestamp in ISO 8601 for refund request
    updated number Timestamp in ISO 8601 for refund object update

    Error Codes

    Example: GET eWallet Refund by Refund ID - Error Response

    {
        "error_code": "DATA_NOT_FOUND",
        "message": "Resource 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.
    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
    Resource 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 Refunds

    Get the details of all eWallet refunds associated with a single eWallet charge transaction by the Charge ID

    Endpoint: List eWallet Refunds by Charge ID

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

    Request Parameters

    Example: List eWallet Refunds by Charge ID - Request

    curl https://api.xendit.co/ewallets/charges/ewc_532as23lew2321id/refunds -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 eWallet 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
    string Refund status to be retrieved
    Available values: SUCCEEDED, FAILED, PENDING

    Response Parameters

    Example: List eWallet Refunds by Charge ID - Response

    {
      "data": [
        { 
            "id" : "ewr_532as23lew2321id",
            "charge_id" : "ewc_5easfnn23aadlmnaa42",
            "status" : "SUCCEEDED",
            "currency" : "IDR",
            "channel_code" : "ID_DANA",
            "capture_amount" : 123456,
            "refund_amount" : 100000,
            "reason" : "REQUESTED_BY_CUSTOMER",
            "failure_code" : null,
            "created" : "2020-04-20T16:23:52Z",
            "updated" : "2020-04-20T16:23:52Z"
        },
        { 
            "id" : "ewr_532as23lew2321id",
            "charge_id" : "5easfnn23aadlmnaa42",
            "status" : "SUCCEEDED",
            "currency" : "IDR",
            "channel_code" : "ID_DANA",
            "capture_amount" : 123456,
            "refund_amount" : 23456,
            "reason" : "OTHER",
            "failure_code" : null,
            "created" : "2020-04-20T16:23:52Z",
            "updated" : "2020-04-20T16:23:52Z"
        }
      ],
      "has_more": false
    }
    Body Parameter Type Description
    data array Data array of eWallet refund object(s) related to specified Charge ID
    Refund object parameters
    Key Value
    id string Unique identifier for the refund transaction
    charge_id string Unique identifier for the original charge transaction
    status string Status of the refund request
    Available values: SUCCEEDED, FAILED, PENDING
    currency string Currency used for the transaction in ISO4217 format
    Supported currency: IDR, PHP, MYR, VND
    capture_amount number Requested capture amount from merchant
    refund_amount number Amount refunded
    channel_code string Channel code indicating eWallet provider
    Supported channels: ID_OVO, ID_DANA, ID_SHOPEEPAY, ID_LINKAJA, ID_JENIUSPAY, PH_PAYMAYA,PH_GCASH, PH_GRABPAY, PH_SHOPEEPAY, VN_APPOTA, VN_MOMO, VN_SHOPEEPAY, VN_VNPTWALLET, VN_ZALOPAY, MY_TOUCHNGO, MY_SHOPEEPAY, MY_GRABPAY, MY_WECHATPAY
    reason string Reason for refund
    failure_code string Reason for refund transaction failing
    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 eWallet Refunds by Charge ID - Error Response

    {
        "error_code": "DATA_NOT_FOUND",
        "message": "Resource 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.
    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
    Resource 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

    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
    Payment methods account linking
    Latest
    Simplified tokenization and account linking flow is now available; ID - OVO, DANA, LINKAJA, SHOPEEPAY, PH - MAYA, GRABPAY, SHOPEEPAY, and MY - TOUCHNGO, SHOPEEPAY, GRABPAY

    No API Versioning is required. You can access the new API easily by calling POST .../v2/payment_methods
    LAT account linking flow
    version with previous account linking flow
    Tokenization and account linking flow is now available

    There are 2 steps required to perform account linking using our tokenization flow - starting with a customer object creation and creating a payment method.

    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.

    DANA / SHOPEEPAY (ID, PH & MY) / MAYA (PAYMAYA) / GRABPAY (PH & MY) / TOUCHNGO tokenization - required fields in Customer Object

    No specific eWallet channel requirements, any customer object fufilling Xendit's API requirements is sufficient

    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)

    LINKAJA tokenization - required fields in Customer Object

    Example Customer Object - LINKAJA 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",
        "mobile_number": "+6287774441111"
        }' \
    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 LinkAja for account linking. Mobile number of the customer in E.164 international standard must match with LinkAja's database.
    Format: +(country code)(subscriber number)

    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
    IDEMPOTENCY_ERROR
    409
    Provided Idempotency-key already exists, but the request body provided does not match the original request

    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 payment method 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 Xendit dashboard under payment methods section.

    The table below summarizes key onboarding information of these tokenization payment flow. By default, all tokenization flow requires approval with eWallet partners. Auto debit flows which require special approval will require escalation to the eWallet partners before merchants can access the feature.

    Indonesia

    Value OVO DANA LINKAJA SHOPEEPAY
    Redirection (PIN required) payment
    Approval required Approval required Approval required Approval required
    Auto debit payment
    Special approval required Special approval required Special approval required

    Philippines

    Value SHOPEEPAY MAYA (PAYMAYA) GRABPAY GCASH
    Auto debit payment
    Approval required Approval required Approval required Approval required

    Malaysia

    Value TOUCHNGO SHOPEEPAY GRABPAY
    Auto debit payment
    Approval required Approval required Approval required

    Endpoint: Account Linking - Create Payment Method

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

    Account Linking - Create Payment Method Request

    Example Account Linking - Create Payment Method Request

    curl https://api.xendit.co/v2/payment_methods -X POST \
       --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
       --header 'Content-Type: application/json' \
       --data-raw '{
          "type": "EWALLET",
          "reusability": "MULTIPLE_USE",
          "ewallet": {
            "channel_code": "OVO",
            "channel_properties": {
              "success_return_url": "https://your-redirect-website.com/success",
              "failure_return_url": "https://your-redirect-website.com/failure"
            }
          },
          "customer_id": "fc4c060b-3c41-4707-b7b2-df9c3376edde"
    }' \
    {
      "type": "EWALLET",
      "reusability": "MULTIPLE_USE",
      "ewallet": {
        "channel_code": "OVO",
        "channel_properties": {
          "success_return_url": "https://your-redirect-website.com/success",
          "failure_return_url": "https://your-redirect-website.com/failure"
        }
      },
      "customer_id": "fc4c060b-3c41-4707-b7b2-df9c3376edde"
    }
    Request Body Parameter Type Description
    type
    required
    string Type of payment method - to use EWALLET as value
    reusability
    required
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

    use MULTIPLE_USE as value for eWallets
    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
    country
    required
    string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. shopeepay). Available values - PH for Philippines, ID for Indonesia, MY for Malaysia
    reference_id
    optional
    string Merchant-provided identifier for this payment method. If none is provided, Xendit will randomly generate a unique reference_id
    description
    optional
    string Free-text field for any additional information regarding the payment method
    metadata
    optional
    string A free-format JSON for additional information that you may use
    ewallet
    required
    object For type='EWALLET', this contains the necessary information to describe an ewallet payment method

    Key Value
    channel_code
    required
    string Identifier for the payment channel partner
    Supported eWallets and their channel codes:
    • DANA
    • OVO
    • LINKAJA
    • SHOPEEPAY
    • GRABPAY
    • PAYMAYA
    • GCASH
    • TOUCHNGO
    channel_properties
    required
    object Object that contains the required information to perform account linking with eWallet account for payments
    OVO, DANA, LINKAJA, SHOPEEPAY (ID, PH & MY), GRABPAY (PH & MY), GCASH, and TOUCHNGO required fields
    Key Value
    success_return_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_return_url
    required
    string URL where the end-customer is redirected if the authorization failed
    MAYA (PAYMAYA) required fields
    Key Value
    success_return_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_return_url
    required
    string URL where the end-customer is redirected if the authorization failed
    cancel_return_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

    Account Linking - Create Payment Method Response

    Example Account Linking - Create Payment Method Success Response

    {
        "id": "pm-123123123-f4d9-421c-9f0b-ab3b2b6bbc39",
        "type": "EWALLET",
        "country": "ID",
        "business_id": "5f27a14a9bf05c73123123123",
        "customer_id": "fc4123123-3c41-4707-b7b2-df9c3376edde",
        "reference_id": "b63798d3-8240-48c3-af12-3b3c62c0981a",
        "reusability": "MULTIPLE_USE",
        "status": "REQUIRES_ACTION",
        "actions": [
            {
                "action": "AUTH",
                "url": "https://link-web.xendit.co/auth/lat-bcf19cc8-f097-44fb-839c-6e4aed807d00/confirm",
                "url_type": "WEB",
                "method": "GET"
            }
        ],
        "description": null,
        "created": "2021-08-18T03:52:56.936277373Z",
        "updated": "2021-08-18T03:52:56.936277373Z",
        "metadata": {
            "sku": "IPHONE20"
        },
        "ewallet": {
            "channel_code": "OVO",
            "channel_properties": {
                "failure_return_url": "https://your-redirect-website.com/failure",
                "success_return_url": "https://your-redirect-website.com/success"
            },
            "account": {
                "name": null,
                "account_details": null,
                "balance": null,
                "point_balance": null
            }
        },
        "direct_bank_transfer": null,
        "direct_debit": null,
        "card": null,
        "over_the_counter": null,
        "qr_code": null,
        "virtual_account": null
    }
    Body Parameter Type Description
    id
    required
    string Unique identifier for the payment method. This has a prefix of pm-. Example: pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
    type
    required
    string Type of payment method - to use EWALLET as value
    reusability
    required
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

    use MULTIPLE_USE as value for eWallets
    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
    business_id
    required
    string Xendit-generated identifier for the business that owns the transaction
    reference_id
    optional
    string Merchant-provided identifier for this payment method. If none is provided, Xendit will randomly generate a unique reference_id
    status
    required
    string Status of the payment method. Allowed values - PENDING, REQUIRES_ACTION, ACTIVE, INACTIVE, EXPIRED

    REQUIRES_ACTION - The request passed validation but requires additional steps in order to activate the payment method for use. Typical actions are for merchant to trigger OTP validation or redirect your customer to authentication page.
    ACTIVE - The payment method can be used for payment requests.
    INACTIVE - Merchant performing unlinking on payment method will trigger this status. This status prevents further transactions from the payment method and is reversible.
    EXPIRED - The underlying authorization has expired, invalidated, or has been unlinked. This status is not reversible
    country
    required
    string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. shopeepay). Available values - PH, ID, MY
    actions
    required
    object If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to activate a payment method
    Key Value
    method
    required
    string HTTP method for calling the url. Allowed values: GET, POST
    url_type
    required
    string Type of url for the specific action.
    API - The provided url is a server-side API, merchant will need to provide necessary information to the API
    WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
    MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
    DEEPLINK - The provided redirect url utilizes deep linking to the channel partner’s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
    action
    required
    string AUTH - Trigger this action in order to authorize linking or payment.
    RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer
    url
    required
    string The generated URL to hit in order to perform the action
    ewallet
    required
    object For type='EWALLET', this contains the necessary information to describe an ewallet payment method
    Key Value
    channel_code
    required
    string Identifier for the payment channel partner
    Supported eWallets and their channel codes:
    • DANA
    • OVO
    • LINKAJA
    • SHOPEEPAY
    • GRABPAY
    • PAYMAYA
    • TOUCHNGO
    channel_properties
    required
    object Object that contains the required information to perform account linking with eWallet account for payments
    OVO, DANA, LINKAJA, SHOPEEPAY (ID, PH & MY), GRABPAY (PH & MY), GCASH, and TOUCHNGO required fields
    Key Value
    success_return_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_return_url
    required
    string URL where the end-customer is redirected if the authorization failed
    MAYA (PAYMAYA) required fields
    Key Value
    success_return_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_return_url
    required
    string URL where the end-customer is redirected if the authorization failed
    cancel_return_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

    account
    optional
    object Object that contains information of the linked eWallet account
    Key Value
    account_details
    optional
    string Masked public identifier for the eWallet account. This typically contains the masked mobile number registered to the eWallet account. This will be null if unavailable
    name
    optional
    string Name of the eWallet account holder. This will be null if unavailable
    balance
    optional
    number Current available balance in the eWallet. This will be null if unavailable
    point_balance
    optional
    number Current available points in the eWallet for consumption. This will be null if unavailable
    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
    description
    optional
    object Free-text field for any additional information regarding the payment method
    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

    Account Linking - Create Payment Method Errors

    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
    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
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request
    DUPLICATE_ERROR
    409
    Xendit code specifying the error encountered: There's an already existing record with the provided details
    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

    Tokenized - Account Linking Status Callback

    Notification when a payment method is successfully activated. This callback is triggered when a particular payment method has been successfully created and can be used for payments. Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings. Once you receive the payment method activation webhook, you are ready to make a payment transaction via our eWallets Charge endpint.

    Callback Payload

    Example: Payment Method Activation Callback Payload

    {
      "event": "payment_method.activated",
      "business_id": "5f27a14a9bf05c73dd040bc8",
      "created": "2020-08-29T09:12:33.001Z",
      "data": {
        "id": "pm-123123123-f4d9-421c-9f0b-ab3b2b6bbc39",
        "type": "EWALLET",
        "country": "ID",
        "business_id": "5f27a14a9bf05c73123123123",
        "customer_id": "fc4123123-3c41-4707-b7b2-df9c3376edde",
        "reference_id": "b63798d3-8240-48c3-af12-3b3c62c0981a",
        "reusability": "MULTIPLE_USE",
        "status": "ACTIVE",
        "actions": [
            {
                "action": "AUTH",
                "url": "https://link-web.xendit.co/auth/lat-bcf19cc8-f097-44fb-839c-6e4aed807d00/confirm",
                "url_type": "WEB",
                "method": "GET"
            }
        ],
        "description": null,
        "created": "2021-08-18T03:52:56.936277373Z",
        "updated": "2021-08-18T03:52:56.936277373Z",
        "metadata": {
            "sku": "IPHONE20"
        },
        "ewallet": {
            "channel_code": "SHOPEEPAY",
            "channel_properties": {
                "failure_return_url": "https://your-redirect-website.com/failure",
                "success_return_url": "https://your-redirect-website.com/success"
            },
            "account": {
                "name": null,
                "account_details": "+62*****3123",
                "balance": 10000,
                "point_balance": 10000
            }
        },
        "direct_bank_transfer": null,
        "direct_debit": null,
        "card": null,
        "over_the_counter": null,
        "qr_code": null,
        "virtual_account": null
      }
    }
    Body Parameter Type Description
    event
    required
    string Identifies the event that triggered a notification to the merchant - payment_method.activated
    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 Payment method object
    Data fields
    Body Parameter Description
    id
    required
    Unique identifier for the payment method. This has a prefix of pm-. Example: pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
    type
    required
    Type of payment method - to use EWALLET as value
    reusability
    required
    Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

    use MULTIPLE_USE as value for eWallets
    customer_id
    required
    ID of the customer object to which the account token will be linked to. Call Tokenized - Create Customer to generate Customer ID
    business_id
    required
    Xendit-generated identifier for the business that owns the transaction
    reference_id
    optional
    Merchant-provided identifier for this payment method. If none is provided, Xendit will randomly generate a unique reference_id
    status
    required
    Status of the payment method. Allowed values - PENDING, REQUIRES_ACTION, ACTIVE, INACTIVE, EXPIRED

    REQUIRES_ACTION - The request passed validation but requires additional steps in order to activate the payment method for use. Typical actions are for merchant to trigger OTP validation or redirect your customer to authentication page.
    ACTIVE - The payment method can be used for payment requests.
    INACTIVE - Merchant performing unlinking on payment method will trigger this status. This status prevents further transactions from the payment method and is reversible.
    EXPIRED - The underlying authorization has expired, invalidated, or has been unlinked. This status is not reversible
    country
    required
    2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. shopeepay). Available values - PH, ID, MY
    actions
    required
    If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to activate a payment method
    Key Value
    method
    required
    string HTTP method for calling the url. Allowed values: GET, POST
    url_type
    required
    string Type of url for the specific action.
    API - The provided url is a server-side API, merchant will need to provide necessary information to the API
    WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
    MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
    DEEPLINK - The provided redirect url utilizes deep linking to the channel partner’s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication
    action
    required
    string AUTH - Trigger this action in order to authorize linking or payment.
    RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer
    url
    required
    string The generated URL to hit in order to perform the action
    ewallet
    required
    For type='EWALLET', this contains the necessary information to describe an ewallet payment method
    Key Value
    channel_code
    required
    string Identifier for the payment channel partner
    Supported eWallets and their channel codes:
    • DANA
    • OVO
    • LINKAJA
    • SHOPEEPAY
    • GRABPAY
    • PAYMAYA
    • TOUCHNGO
    channel_properties
    required
    object Object that contains the required information to perform account linking with eWallet account for payments
    OVO, DANA, LINKAJA, SHOPEEPAY (ID, PH & MY), GRABPAY (PH & MY) required fields
    Key Value
    success_return_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_return_url
    required
    string URL where the end-customer is redirected if the authorization failed
    MAYA (PAYMAYA) required fields
    Key Value
    success_return_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_return_url
    required
    string URL where the end-customer is redirected if the authorization failed
    cancel_return_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

    account
    required
    object Object that contains information of the linked eWallet account
    Key Value
    account_details
    optional
    string Masked public identifier for the eWallet account. This typically contains the masked mobile number registered to the eWallet account. This will be null if unavailable
    name
    optional
    string Name of the eWallet account holder. This will be null if unavailable
    balance
    optional
    number Current available balance in the eWallet. This will be null if unavailable
    point_balance
    optional
    number Current available points in the eWallet for consumption. This will be null if unavailable
    created
    required
    ISO 8601 Timestamp for charge object creation. Timezone UTC+0
    updated
    required
    ISO 8601 Timestamp for latest charge object update. Timezone UTC+0
    description
    optional
    Free-text field for any additional information regarding the payment method
    metadata
    optional
    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

    Tokenized - Get Account Balance/Payment Method Details

    Endpoint: Get Account Balance/Payment Method Details

    GET https://api.xendit.co/v2/payment_methods/{id}

    Get Account Balance/Payment Method Details - Request

    Example Get Account Balance by Linked Account Token Request

    curl https://api.xendit.co/v2/payment_methods/pm-EM8sad8as56dasdabk -X GET \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
    Path Parameter Type Description
    id
    required
    string Payment method id received from account linking step. This has the pm- prefix.

    Get Account Balance/ Payment Method Details - Response

    This endpoint returns the payment method object:

    Example Get Account Balance/ Payment Method Details Response

    {
        "id": "pm-123123123-f4d9-421c-9f0b-ab3b2b6bbc39",
        "type": "EWALLET",
        "country": "ID",
        "business_id": "5f27a14a9bf05c73123123123",
        "customer_id": "fc4123123-3c41-4707-b7b2-df9c3376edde",
        "reference_id": "b63798d3-8240-48c3-af12-3b3c62c0981a",
        "reusability": "MULTIPLE_USE",
        "status": "PENDING",
        "actions": [
            {
                "action": "AUTH",
                "url": "https://link-web.xendit.co/auth/lat-bcf19cc8-f097-44fb-839c-6e4aed807d00/confirm",
                "url_type": "WEB",
                "method": "GET"
            }
        ],
        "description": null,
        "created": "2021-08-18T03:52:56.936277373Z",
        "updated": "2021-08-18T03:52:56.936277373Z",
        "metadata": {
            "sku": "IPHONE20"
        },
        "ewallet": {
            "channel_code": "SHOPEEPAY",
            "channel_properties": {
                "failure_return_url": "https://your-redirect-website.com/failure",
                "success_return_url": "https://your-redirect-website.com/success"
            },
            "account": {
                "name": null,
                "account_details": "+62*****3123",
                "balance": 10000,
                "point_balance": 10000
            }
        },
        "direct_bank_transfer": null,
        "direct_debit": null,
        "card": null,
        "over_the_counter": null,
        "qr_code": null,
        "virtual_account": null
    }
    Body Parameter Type Description
    id
    required
    string Unique identifier for the payment method. This has a prefix of pm-. Example: pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
    type
    required
    string Type of payment method - to use EWALLET as value
    reusability
    required
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

    use MULTIPLE_USE as value for eWallets
    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
    business_id
    required
    string Xendit-generated identifier for the business that owns the transaction
    reference_id
    optional
    string Merchant-provided identifier for this payment method. If none is provided, Xendit will randomly generate a unique reference_id
    status
    required
    string Status of the payment method. Allowed values - PENDING, REQUIRES_ACTION, ACTIVE, INACTIVE, EXPIRED

    REQUIRES_ACTION - The request passed validation but requires additional steps in order to activate the payment method for use. Typical actions are for merchant to trigger OTP validation or redirect your customer to authentication page.
    ACTIVE - The payment method can be used for payment requests.
    INACTIVE - Merchant performing unlinking on payment method will trigger this status. This status prevents further transactions from the payment method and is reversible.
    EXPIRED - The underlying authorization has expired, invalidated, or has been unlinked. This status is not reversible
    country
    required
    string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. shopeepay). Available values - PH, ID, MY
    actions
    required
    object If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to activate a payment method
    Key Value
    method
    required
    string HTTP method for calling the url. Allowed values: GET, POST
    url_type
    required
    string Type of url for the specific action.
    API - The provided url is a server-side API, merchant will need to provide necessary information to the API
    WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
    MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
    DEEPLINK - The provided redirect url utilizes deep linking to the channel partner’s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication
    action
    required
    string AUTH - Trigger this action in order to authorize linking or payment.
    RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer
    url
    required
    string The generated URL to hit in order to perform the action
    ewallet
    required
    object For type='EWALLET', this contains the necessary information to describe an ewallet payment method
    Key Value
    channel_code
    required
    string Identifier for the payment channel partner
    Supported eWallets and their channel codes:
    • DANA
    • OVO
    • LINKAJA
    • SHOPEEPAY
    • GRABPAY
    • PAYMAYA
    • TOUCHNGO
    channel_properties
    required
    object Object that contains the required information to perform account linking with eWallet account for payments
    OVO, DANA, LINKAJA, SHOPEEPAY (ID, PH & MY), GRABPAY (PH & MY), TOUCHNGO required fields
    Key Value
    success_return_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_return_url
    required
    string URL where the end-customer is redirected if the authorization failed
    MAYA (PAYMAYA) required fields
    Key Value
    success_return_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_return_url
    required
    string URL where the end-customer is redirected if the authorization failed
    cancel_return_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

    account
    optional
    object Object that contains information of the linked eWallet account
    Key Value
    account_details
    optional
    string Masked public identifier for the eWallet account. This typically contains the masked mobile number registered to the eWallet account. This will be null if unavailable
    name
    optional
    string Name of the eWallet account holder. This will be null if unavailable
    balance
    optional
    number Current available balance in the eWallet. This will be null if unavailable
    point_balance
    optional
    number Current available points in the eWallet for consumption. This will be null if unavailable
    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
    description
    optional
    object Free-text field for any additional information regarding the payment method
    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

    Get Account Balance/Payment Method Details - Errors

    See other common errors here

    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_ERROR
    404
    Provided payment_method_id is not supported or has not yet activated for this account
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Tokenized - Unlinking

    Unlinks a successful linked account token.

    Endpoint: Unlink a Payment Method

    POST https://api.xendit.co/v2/payment_methods/{id}/expire

    Example Unlink a Payment Method Request

    curl https://api.xendit.co/v2/payment_methods/pm-EM8sad8as56dasdabk/expire -X POST \
       -u xnd_development_OSuxk743ma423balls+2fT/7GlCAN3jg==: 
    Path Parameter Type Description
    id
    required
    string Payment method id received from account linking step. This has the pm- prefix

    Example Unlink a Payment Method Response

    {
        "id": "pm-123123123-f4d9-421c-9f0b-ab3b2b6bbc39",
        "type": "EWALLET",
        "country": "ID",
        "business_id": "5f27a14a9bf05c73123123123",
        "customer_id": "fc4123123-3c41-4707-b7b2-df9c3376edde",
        "reference_id": "b63798d3-8240-48c3-af12-3b3c62c0981a",
        "reusability": "MULTIPLE_USE",
        "status": "PENDING",
        "actions": [
            {
                "action": "AUTH",
                "url": "https://link-web.xendit.co/auth/lat-bcf19cc8-f097-44fb-839c-6e4aed807d00/confirm",
                "url_type": "WEB",
                "method": "GET"
            }
        ],
        "description": null,
        "created": "2021-08-18T03:52:56.936277373Z",
        "updated": "2021-08-18T03:52:56.936277373Z",
        "metadata": {
            "sku": "IPHONE20"
        },
        "ewallet": {
            "channel_code": "OVO",
            "channel_properties": {
                "failure_return_url": "https://your-redirect-website.com/failure",
                "success_return_url": "https://your-redirect-website.com/success"
            },
            "account": {
                "name": null,
                "account_details": null,
                "balance": null,
                "point_balance": null
            }
        },
        "direct_bank_transfer": null,
        "direct_debit": null,
        "card": null,
        "over_the_counter": null,
        "qr_code": null,
        "virtual_account": null
    }
    Body Parameter Type Description
    id
    required
    string Unique identifier for the payment method. This has a prefix of pm-. Example: pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
    type
    required
    string Type of payment method - to use EWALLET as value
    reusability
    required
    string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again

    use MULTIPLE_USE as value for eWallets
    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
    business_id
    required
    string Xendit-generated identifier for the business that owns the transaction
    reference_id
    optional
    string Merchant-provided identifier for this payment method. If none is provided, Xendit will randomly generate a unique reference_id
    status
    required
    string Status of the payment method. Allowed values - PENDING, REQUIRES_ACTION, ACTIVE, INACTIVE, EXPIRED

    REQUIRES_ACTION - The request passed validation but requires additional steps in order to activate the payment method for use. Typical actions are for merchant to trigger OTP validation or redirect your customer to authentication page.
    ACTIVE - The payment method can be used for payment requests.
    INACTIVE - Merchant performing unlinking on payment method will trigger this status. This status prevents further transactions from the payment method and is reversible.
    EXPIRED - The underlying authorization has expired, invalidated, or has been unlinked. This status is not reversible
    country
    required
    string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. shopeepay). Available values - PH, ID, MY
    actions
    required
    object If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to activate a payment method
    Key Value
    method
    required
    string HTTP method for calling the url. Allowed values: GET, POST
    url_type
    required
    string Type of url for the specific action.
    API - The provided url is a server-side API, merchant will need to provide necessary information to the API
    WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
    MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
    DEEPLINK - The provided redirect url utilizes deep linking to the channel partner’s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication
    action
    required
    string AUTH - Trigger this action in order to authorize linking or payment.
    RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer
    url
    required
    string The generated URL to hit in order to perform the action
    ewallet
    required
    object For type='EWALLET', this contains the necessary information to describe an ewallet payment method
    Key Value
    channel_code
    required
    string Identifier for the payment channel partner
    Supported eWallets and their channel codes:
    • DANA
    • OVO
    • LINKAJA
    • SHOPEEPAY
    • GRABPAY
    • PAYMAYA
    • TOUCHNGO
    channel_properties
    required
    object Object that contains the required information to perform account linking with eWallet account for payments
    OVO, DANA, LINKAJA, SHOPEEPAY (ID, PH & MY), GRABPAY (PH & MY), TOUCHNGO required fields
    Key Value
    success_return_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_return_url
    required
    string URL where the end-customer is redirected if the authorization failed
    MAYA (PAYMAYA) required fields
    Key Value
    success_return_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_return_url
    required
    string URL where the end-customer is redirected if the authorization failed
    cancel_return_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

    account
    required
    object Object that contains information of the linked eWallet account
    Key Value
    account_details
    optional
    string Masked public identifier for the eWallet account. This typically contains the masked mobile number registered to the eWallet account. This will be null if unavailable
    name
    optional
    string Name of the eWallet account holder. This will be null if unavailable
    balance
    optional
    number Current available balance in the eWallet. This will be null if unavailable
    point_balance
    optional
    number Current available points in the eWallet for consumption. This will be null if unavailable
    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
    description
    optional
    object Free-text field for any additional information regarding the payment method
    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

    See other common errors here

    Error Code Description
    INVALID_PAYMENT_METHOD
    400
    Cannot perform action to payment method due to its status
    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_ERROR
    404
    Provided payment_method_id is not found or inaccessible for this account
    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

    Tokenized - Token Expiry Callbacks

    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. Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.


    Value OVO DANA LINKAJA SHOPEEPAY (ID & PH) MAYA (PAYMAYA) GRABPAY SHOPEEPAY (MY) GRABPAY (MY)
    Token Validity
    Never Expires (Xendit Automatically Refreshes Token at Expiry) 10 Years Never Expires 5 Years Never Expires 1 Year Never Expires 10 Years

    Example: Expired Payment Method Callback

    {
      "event": "payment_method.expiry.expired",
      "business_id": "5f27a14a9bf05c73dd040bc8",
      "created": "2020-08-29T09:12:33.001Z",
      "data": {
        "id": "pm-123123123-f4d9-421c-9f0b-ab3b2b6bbc39",
        "type": "EWALLET",
        "country": "ID",
        "business_id": "5f27a14a9bf05c73123123123",
        "customer_id": "fc4123123-3c41-4707-b7b2-df9c3376edde",
        "reference_id": "b63798d3-8240-48c3-af12-3b3c62c0981a",
        "reusability": "MULTIPLE_USE",
        "status": "EXPIRED",
        "actions": [
            {
                "action": "AUTH",
                "url": "https://link-web.xendit.co/auth/lat-bcf19cc8-f097-44fb-839c-6e4aed807d00/confirm",
                "url_type": "WEB",
                "method": "GET"
            }
        ],
        "description": null,
        "created": "2021-08-18T03:52:56.936277373Z",
        "updated": "2021-08-18T03:52:56.936277373Z",
        "metadata": {
            "sku": "IPHONE20"
        },
        "ewallet": {
            "channel_code": "SHOPEEPAY",
            "channel_properties": {
                "failure_return_url": "https://your-redirect-website.com/failure",
                "success_return_url": "https://your-redirect-website.com/success"
            },
            "account": {
                "name": null,
                "account_details": "+62*****3123",
                "balance": 10000,
                "point_balance": 10000
            }
        },
        "direct_bank_transfer": null,
        "direct_debit": null,
        "card": null,
        "over_the_counter": null,
        "qr_code": null,
        "virtual_account": null
      }
    }
    Body Parameter Type Description
    event
    required
    string Identifies the event that triggered a notification to the merchant - payment_method.expiry.expired
    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 Payment method object
    Data fields
    Body Parameter Description
    id
    required
    Unique identifier for the payment method. This has a prefix of pm-. Example: pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
    type
    required
    Type of payment method - to use EWALLET as value
    reusability
    required
    Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

    use MULTIPLE_USE as value for eWallets
    customer_id
    required
    ID of the customer object to which the account token will be linked to. Call Tokenized - Create Customer to generate Customer ID
    business_id
    required
    Xendit-generated identifier for the business that owns the transaction
    reference_id
    optional
    Merchant-provided identifier for this payment method. If none is provided, Xendit will randomly generate a unique reference_id
    status
    required
    Status of the payment method. Allowed values - PENDING, REQUIRES_ACTION, ACTIVE, INACTIVE, EXPIRED

    REQUIRES_ACTION - The request passed validation but requires additional steps in order to activate the payment method for use. Typical actions are for merchant to trigger OTP validation or redirect your customer to authentication page.
    ACTIVE - The payment method can be used for payment requests.
    INACTIVE - Merchant performing unlinking on payment method will trigger this status. This status prevents further transactions from the payment method and is reversible.
    EXPIRED - The underlying authorization has expired, invalidated, or has been unlinked. This status is not reversible
    country
    required
    2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. shopeepay). Available values - PH, ID, MY
    actions
    required
    If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to activate a payment method
    Key Value
    method
    required
    string HTTP method for calling the url. Allowed values: GET, POST
    url_type
    required
    string Type of url for the specific action.
    API - The provided url is a server-side API, merchant will need to provide necessary information to the API
    WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
    MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
    DEEPLINK - The provided redirect url utilizes deep linking to the channel partner’s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication
    action
    required
    string AUTH - Trigger this action in order to authorize linking or payment.
    RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer
    url
    required
    string The generated URL to hit in order to perform the action
    ewallet
    required
    For type='EWALLET', this contains the necessary information to describe an ewallet payment method
    Key Value
    channel_code
    required
    string Identifier for the payment channel partner
    Supported eWallets and their channel codes:
    • DANA
    • OVO
    • LINKAJA
    • SHOPEEPAY
    • GRABPAY
    • PAYMAYA
    • TOUCHNGO
    channel_properties
    required
    object Object that contains the required information to perform account linking with eWallet account for payments
    OVO, DANA, LINKAJA, SHOPEEPAY (ID & PH), GRABPAY, TOUCHNGO required fields
    Key Value
    success_return_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_return_url
    required
    string URL where the end-customer is redirected if the authorization failed
    MAYA (PAYMAYA) required fields
    Key Value
    success_return_url
    required
    string URL where the end-customer is redirected if the authorization is successful
    failure_return_url
    required
    string URL where the end-customer is redirected if the authorization failed
    cancel_return_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

    account
    required
    object Object that contains information of the linked eWallet account
    Key Value
    account_details
    optional
    string Masked public identifier for the eWallet account. This typically contains the masked mobile number registered to the eWallet account. This will be null if unavailable
    name
    optional
    string Name of the eWallet account holder. This will be null if unavailable
    balance
    optional
    number Current available balance in the eWallet. This will be null if unavailable
    point_balance
    optional
    number Current available points in the eWallet for consumption. This will be null if unavailable
    created
    required
    ISO 8601 Timestamp for charge object creation. Timezone UTC+0
    updated
    required
    ISO 8601 Timestamp for latest charge object update. Timezone UTC+0
    description
    optional
    Free-text field for any additional information regarding the payment method
    metadata
    optional
    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

    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
    will be deprecated by 1st February 2023
    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, ID_INDODANA, ID_ATOME, PH_ATOME, PH_BILLEASE, PH_CASHALO
    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
    ID_INDODANA (IDR) 10,000 25,000,000
    ID_ATOME (IDR) 50,000 6,000,000
    PH_BILLEASE (PHP) 50 150,000
    PH_CASHALO (PHP) 1,500 8,000
    PH_ATOME (PHP) 100 70,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,FEE,DISCOUNT (Atome does not support DISCOUNT)
    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, please put negative amount for DISCOUNT (e.g. -1000000)
    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, ID_INDODANA, ID_ATOME, PH_ATOME, PH_BILLEASE, PH_CASHALO
    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
    Notes: PH_CASHALO does not provide plans, Xendit will return an empty array.
    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
    required
    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/"
        },
        "expires_at": "2020-11-12T16:23:52Z",
        "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, ID_INDODANA, ID_ATOME, PH_ATOME, PH_BILLEASE, PH_CASHALO
    checkout_method string Supported checkout method: ONE_TIME_PAYMENT
    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
    status string Charge status
    PENDING, SUCCEEDED, FAILED

    Status of charge request
    Key Value
    PENDING Charge is awaiting payment attempt by your customer
    SUCCEEDED Charge is successfully paid by your customer
    FAILED Charge is failed to be paid by your customer
    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)
    expires_at string Timestamp in ISO 8601 latest object update
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    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

    Xendit notifies your system upon successful payments via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook Settings in Xendit Dashboard under Paylater paid.

    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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

    POST webhook-url

    Version

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

    Webhook Payload

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

    Example: PayLater Success Payment Webhook 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/"
            },
            "expires_at": "2020-11-12T16:23:52Z",
            "callback_url": "https://webhook.me/gethooked",
            "payment_method_id": null,
            "voided_at": null,
            "refunds": null,
            "metadata": null
        }
    }
    Header Parameter Type Description
    x-callback-token
    string Your Xendit unique webhook token to verify the origin of the webhook

    webhook-id
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    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
    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
    expires_at string Timestamp in ISO 8601 latest object update
    callback_url string Default to webhook 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/"
        },
        "expires_at": "2020-11-12T16:23:52Z",
        "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, ID_INDODANA, ID_ATOME, PH_ATOME, PH_BILLEASE, PH_CASHALO
    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
    expires_at string Timestamp in ISO 8601 latest object update
    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    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

    Cancel Paylater Charge

    Perform a cancel for a Paylater charge by Charge ID. This endpoint will only work for charges created via the /paylater/charge endpoint.

    A cancellation of a Paylater transaction will make the payments URL inaccessible to the end customer in real time. Xendit does not send callbacks when for the cancellation endpoint

    Endpoint: Cancel Paylater Charge

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

    Request Parameters

    Example: Cancel PayLater Charge - Request

    curl https://api.xendit.co/paylater/charges/plc_8cb12305-9bcf-4441-a087-ee0d446e297b/cancel -X POST \
       -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)

    Response Parameters

    Example: Cancel PayLater Charge - Response

    {
        "id": "plc_5test57-8888-45o8-abb1-123456789abcdefg",
        "business_id": "8764829fhgnb74gf63hg74dhg73",
        "reference_id": "paylater-mock-ref-12345678",
        "customer_id": "cust-9fb4af4e-d98c-40bf-bd87-abcde678901112",
        "plan_id": "plp_3d4c8823-0d2a-4c2e-892b-12345abcde1112",
        "currency": "IDR",
        "amount": 1000,
        "channel_code": "ID_KREDIVO",
        "checkout_method": "ONE_TIME_PAYMENT",
        "status": "CANCELLED",
        "actions": {
            "mobile_web_checkout_url": "https://pay.kredivo.com/signIn?tk=1234-1234-1234-1234-12345678",
            "desktop_web_checkout_url": "https://pay.kredivo.com/signIn?tk=1234-1234-1234-1234-12345678"
        },
        "expires_at": "2022-11-25T00:00:57.745Z",
        "success_redirect_url": "https://www.xendit.co/en/",
        "failure_redirect_url": "https://www.google.com/",
        "callback_url": "https://webhook.site/12345678",
        "created": "2022-11-24T00:00:57.747Z",
        "updated": "2022-11-24T00:00:26.441Z",
        "order_items": [
            {
                "type": "DIGITAL_PRODUCT",
                "reference_id": "SKU_123-456-789",
                "name": "Dyson Vacuum",
                "net_unit_amount": 50,
                "quantity": 2,
                "url": "https://www.xendit.co/en/",
                "category": "Electronics",
                "subcategory": null,
                "description": null,
                "metadata": null
            },
            {
                "type": "FEE",
                "reference_id": "PLS_FEE_aabcdef0-e4af-4b86-bf12-a31abcdef282",
                "name": "Fee",
                "net_unit_amount": 900,
                "quantity": 1,
                "subcategory": null,
                "description": null,
                "metadata": {
                    "message": "Xendit generated FEE for amount differences between sum of net unit amount and the amount"
                }
            }
        ],
        "voided_at": null,
        "payment_method_id": null,
        "metadata": {
            "campaign": "0%_installment"
        }
    }
    Body Parameter Type Description
    id string Unique identifier for the charge transaction
    It will always have the prefix of plc_, followed by a UUIDv4.
    business_id string Business ID of the merchant.
    reference_id string Reference ID provided by merchant for the transaction.
    customer_id string Unique identifier for customer.
    plan_id string Unique identifier for PayLater plan created.
    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.
    amount number Aggregated transaction amount equivalent to the sum of net_unit_amount multiplied by quantity in the order_items.
    order_items array Array of objects describing the items purchased using PayLater.
    channel_code string Channel code for PayLater provider
    Supported channels: ID_KREDIVO, ID_AKULAKU, ID_INDODANA, ID_ATOME, PH_ATOME,PH_BILLEASE,PH_CASHALO.
    currency string ISO 4217 currency code of PayLater transaction
    Supported currency: IDR, PHP.
    status enum Status of the charge request. Available values - SUCCEEDED, FAILED, PENDING, CANCELLED. Status will be CANCELLED upon successful cancellation.
    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.
    actions object PayLater Partner’s checkout URL where end-user will be redirected to complete payment.
    expires_at string Timestamp in ISO 8601 latest object update Format: YYYY-MM-DDTHH:mm:ssZ Timezone: UTC+0.
    callback_url string Default to callback URL in dashboard where the charge status will be notified.
    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.

    Error Codes

    Example: Cancel PayLater Charge - Error Response

    {
      "error_code": "DATA_NOT_FOUND",
      "message": "Cancel 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.
    INVALID_API_KEY
    401
    API key format is invalid.
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request.
    INELIGIBLE_TRANSACTION
    403
    Cancellation requests cannot be processed because the transaction is not in PENDINGstatus.
    DATA_NOT_FOUND
    404
    Cancel 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 eWallet provider will be notified to resolve this 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.

    A refund of PayLater transaction will return end-customer's credit balance in their PayLater Provider's account in real-time. Xendit will send you a callback upon successful refunds to the same Callback URL you set in the Xendit Dashboard.

    Refund Details

    PayLater Provider Refund capabilities Refund cut-off time
    Kredivo Full and partial refunds 14 days
    Indodana Full and partial refunds 30 days
    Atome Full and partial refunds N/A
    Atome will honor refunds as long as Merchant approved end-customer's request
    Akulaku Full and partial refunds N/A
    Akulaku will honor refunds as long as Merchant approved end-customer's request
    Billease Full Refunds N/A
    Billease will honor refunds as long as Merchant approved end-customer's request

    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, ID_INDODANA, ID_ATOME, PH_ATOME
    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, ID_INDODANA, ID_ATOME, PH_ATOME
    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, ID_INDODANA, ID_ATOME, PH_ATOME
    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. BCA, Mandiri, OVO, GoPay, DANA.. and more). See full list here.
    In Philippines, our merchants can receive payments from any providers connected on QRPh network.

    For full details on the features that each QRIS partner provides, please refer to our documentation.

    API Version

    You are currently viewing the newest version of our QR Codes API. In this API version, the expiry time of a dynamic QRIS code can be customized through the expires_at parameter.

    Version Changelog
    2022-07-31
    Latest
    v2 QR Codes API to support customized expiry time of a dynamic QR code
    2020-07-01
    Previous version
    v1 QR Codes API without customized expiry time of a dynamic QR code

    QR Code Object

    The QR Code Object is returned in the responses of Create QR Code and Get QR Code by QR ID.

    Example: QR Code Object

    {
        "id": "qr_61cb3576-3a25-4d35-8d15-0e8e3bdba4f2",
        "reference_id": "order-id-1666420204",
        "business_id": "58cd618ba0464eb64acdb246",
        "type": "DYNAMIC",
        "currency": "IDR",
        "amount": 10000,
        "channel_code": "ID_DANA",
        "status": "ACTIVE",
        "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
        "expires_at": "2022-10-23T09:56:43.60445Z",
        "created": "2022-10-22T06:30:05.86474Z",
        "updated": "2022-10-22T06:30:05.86474Z",
        "basket": null,
        "metadata": null
    }
    Body Parameter Type Description
    id string Unique identifier for this transaction. Prefix qr_
    reference_id string Reference ID provided by merchant (255 characters)
    business_id string Business ID of merchant
    type string DYNAMIC or STATIC
    Note:
    - Dynamic QR code contains the amount value to be paid upon scanning and can only be paid a single time
    Static QR code requires end user to input the payment value and can be paid multiple times
    - STATIC is not available for QRPh at the moment
    currency string Currency used for the transaction in ISO4217 format
    Available values: IDR, PHP
    amount number Amount specified in request
    Static QR codes require the end user to always input the amount to be paid at the point of scanning
    Note:
    - QRIS - min 1 IDR, max 10,000,000 IDR
    - QRPh - min 1 PHP, max 50,000 PHP
    channel_code string Code specifying which QR code partner will be used to process the transaction
    Available values: ID_DANA, ID_LINKAJA, QRPH
    status string ACTIVE or INACTIVE
    Note: Inactive or expired QR code can no longer accept payment
    qr_string 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)
    expires_at string ISO 8601 Timestamp for QR code expiry. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ
    Note: For ID_DANA's dynamic QR code, default is QR code expires in 48 hours from creation time if expires_at is not specified. For ID_DANA's static QR code, the QR code never expires, so expires_at value will always be null
    Custom expiry is not available for QRPh at the moment
    created string ISO 8601 Timestamp for QR code object creation. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ
    updated string ISO 8601 Timestamp for latest QR code object update. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ
    basket object Array of objects describing the item(s) purchased
    Key Value
    reference_id
    string Merchant's identifier for specific product (255 characters)
    name
    string Name of product (255 characters)
    category
    string Merchant category for item - e.g. Electronics (255 characters)
    currency
    string Currency used for the transaction in ISO4217 format
    Available values: IDR
    price
    number Price per unit in basket currency
    quantity
    number Number of units of this item in the basket
    type
    string Type of product - PRODUCT or SERVICE
    url
    string URL to the e-commerce page of the item
    description
    string Description of product (255 characters)
    sub-category
    string Merchant sub-category for item - e.g. Mobile Phone (255 characters)
    metadata
    object Object of additional information the merchant may use. Merchant defines the JSON properties and values
    Merchant can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long
    metadata object Object of additional information the merchant may use. Merchant defines the JSON properties and values
    Merchant can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long

    Create QR Code

    This POST endpoint is used to create either a dynamic (fixed amount) or a static (open amount) QR code.

    Example: Create QR Code Request

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

    Request Parameters

    curl https://api.xendit.co/qr_codes -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==: \
       -H 'api-version: 2022-07-31'
       -H 'Content-Type: application/json' \
       --data-raw '{
        "reference_id": "order-id-1666420204",
        "type": "DYNAMIC",
        "currency": "IDR",
        "amount": 10000,
        "expires_at": "2022-10-23T09:56:43.60445Z"
    }'
    Header Parameter Type Description
    api-version
    required
    string The version of the API. Use 2022-07-31 for the v2 version of the endpoint
    idempotency-key
    optional
    string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer. It expires after 24 hours from the first request
    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-split-rule
    optional
    string Split Rule ID that you would like to apply to this QR code in order to split and route payments to multiple accounts.

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

    If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

    Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information.
    webhook-url
    optional
    string Callback URL where payment notifications will be sent. Default is the callback URL in your Dashboard for QR code paid
    Body Parameter Type Description
    reference_id
    required
    string Reference ID provided by merchant. Does not need to be unique (255 characters)
    type
    required
    string DYNAMIC or STATIC
    Note:
    - Dynamic QR code contains the amount value to be paid upon scanning and can only be paid a single time
    Static QR code requires end user to input the payment value and can be paid multiple times
    - STATIC is not available for QRPh at the moment
    currency
    required
    string Currency used for the transaction in ISO4217 format
    Available values: IDR, PHP
    amount
    conditionally required
    number Amount specified in request
    Static QR codes require the end user to always input the amount to be paid at the point of scanning
    Note:
    - QRIS - min 1 IDR, max 10,000,000 IDR
    - QRPh - min 1 PHP, max 50,000 PHP
    channel_code
    optional
    string Code specifying which QR code partner will be used to process the transaction
    Available values: ID_DANA, ID_LINKAJA, QRPH
    expires_at
    optional
    string ISO 8601 Timestamp for QR code expiry. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ
    Note: For ID_DANA's dynamic QR code, default is QR code expires in 48 hours from creation time if expires_at is not specified. For ID_DANA's static QR code, the QR code never expires, so expires_at value will always be null
    Custom expiry is not available for QRPh at the moment. QRPh expiry is fixed at 15 minutes.
    basket
    optional
    object Array of objects describing the item(s) purchased
    Key Value
    reference_id
    string Merchant's identifier for specific product (255 characters)
    name
    string Name of product (255 characters)
    category
    string Merchant category for item - e.g. Electronics (255 characters)
    currency
    string Currency used for the transaction in ISO4217 format
    Available values: IDR
    price
    number Price per unit in basket currency
    quantity
    number Number of units of this item in the basket
    type
    string Type of product - PRODUCT or SERVICE
    url
    string URL to the e-commerce page of the item
    description
    string Description of product (255 characters)
    sub-category
    string Merchant sub-category for item - e.g. Mobile Phone (255 characters)
    metadata
    object Object of additional information the merchant may use. Merchant defines the JSON properties and values
    Merchant can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long
    metadata
    optional
    object Object of additional information the merchant may use. Merchant defines the JSON properties and values
    Merchant 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 QR Code Success Response (QR Code Object)

    {
        "id": "qr_61cb3576-3a25-4d35-8d15-0e8e3bdba4f2",
        "reference_id": "order-id-1666420204",
        "business_id": "58cd618ba0464eb64acdb246",
        "type": "DYNAMIC",
        "currency": "IDR",
        "amount": 10000,
        "channel_code": "ID_DANA",
        "status": "ACTIVE",
        "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
        "expires_at": "2022-10-23T09:56:43.60445Z",
        "created": "2022-10-22T06:30:05.86474Z",
        "updated": "2022-10-22T06:30:05.86474Z",
        "basket": null,
        "metadata": null
    }

    Returns QR Code Object with HTTP status code 200 and ACTIVE status.

    Error Codes

    Example: Create QR Code Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is invalid input in one of the required request fields"
    }
    Error Code Description
    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 QR code acquirer. 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
    DUPLICATE_ERROR
    409
    ID_DANA only allows 1 static QR code for each merchant
    SERVER_ERROR
    500
    An unexpected error occured. Our team has been notified and will troubleshoot the issue
    CHANNEL_UNAVAILABLE
    503
    The QR partner is currently experiencing unexpected issues. The QR partner will be notified to resolve this issue

    Get QR Code by QR ID

    This GET endpoint is used to get the details of a QR code by QR ID (qr_) returned in the response of Create QR Code.

    Example: Get QR Code by QR ID Request

    Request Parameters

    GET https://api.xendit.co/qr_codes/:id
    curl https://api.xendit.co/qr_codes/qr_61cb3576-3a25-4d35-8d15-0e8e3bdba4f2 -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==: \
       -H 'api-version: 2022-07-31'
       -H 'Content-Type: application/json' \
    Header Parameter Type Description
    api-version
    required
    string The version of the API. Use 2022-07-31 for the v2 version of the endpoint
    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 this transaction. QR ID with prefix qr_ returned in the response of Create QR Code

    Response Parameters

    Example: Get QR Code by QR ID Success Response (QR Code Object)

    {
        "id": "qr_61cb3576-3a25-4d35-8d15-0e8e3bdba4f2",
        "reference_id": "order-id-1666420204",
        "business_id": "58cd618ba0464eb64acdb246",
        "type": "DYNAMIC",
        "currency": "IDR",
        "amount": 10000,
        "channel_code": "ID_DANA",
        "status": "ACTIVE",
        "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
        "expires_at": "2022-10-23T09:56:43.60445Z",
        "created": "2022-10-22T06:30:05.86474Z",
        "updated": "2022-10-22T06:30:05.86474Z",
        "basket": null,
        "metadata": null
    }

    Returns QR Code Object with status code 200 for a valid identifier.

    Error Codes

    Example: Get QR Code by QR ID Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is invalid input in one of the required request fields"
    }
    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
    DATA_NOT_FOUND
    404
    QR 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

    QR Payment Object

    The QR Payment Object is returned in the callback of Create QR Code and in the response of List QR Payments by QR ID. For List QR Payments by QR ID, if more than one payment exists for a specific QR code, the response body will contain an array of QR Payment Objects.

    Example: QR Payment Object

    {
        "id": "qrpy_8182837te-87st-49ing-8696-1239bd4d759c",
        "business_id": "58cd618ba0464eb64acdb246",
        "currency": "IDR",
        "amount": 10000,
        "status": "SUCCEEDED",
        "created": "2022-10-22T06:30:05.86474Z",
        "qr_id": "qr_61cb3576-3a25-4d35-8d15-0e8e3bdba4f2",
        "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
        "reference_id": "order-id-1666420204",
        "type": "DYNAMIC",
        "channel_code": "ID_DANA",
        "expires_at": "2022-10-23T09:56:43.60445Z",
        "basket": null,
        "metadata": null,
        "payment_detail": {
            "receipt_id": "000111666",
            "source": "GOPAY",
            "name": null,
            "account_details": null
        }
    }
    Body Parameter Type Description
    id string Unique identifier for this transaction. Prefix qrpy_
    business_id string Business ID of merchant
    currency string Currency used for the transaction in ISO4217 format
    Available values: IDR. PHP
    amount number Amount specified in request
    Static QR codes require the end user to always input the amount to be paid at the point of scanning
    Note:
    - QRIS - min 1 IDR, max 10,000,000 IDR
    - QRPh - min 1 PHP, max 50,000 PHP
    status string Status of the QR payment
    Available values: SUCCEEDED
    created string ISO 8601 Timestamp for QR payment creation. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ
    qr_id string Unique identifier for the QR code. Prefix qr_
    qr_string 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)
    reference_id string Reference ID provided by merchant (255 characters)
    type string DYNAMIC or STATIC
    Note: Dynamic QR code contains the amount value to be paid upon scanning and can only be paid a single time
    Static QR code requires end user to input the payment value and can be paid multiple times
    channel_code string Code specifying which QR code partner will be used to process the transaction
    Available values: ID_DANA, ID_LINKAJA
    expires_at string ISO 8601 Timestamp for QR code expiry. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ
    Note: For ID_DANA's dynamic QR code, default is QR code expires in 48 hours from creation time if expires_at is not specified. For ID_DANA's static QR code, default is QR code never expires (expires_at will be accepted and ignored)
    Custom expiry is not available for QRPh at the moment
    basket object Array of objects describing the item(s) purchased
    Key Value
    reference_id
    string Merchant's identifier for specific product (255 characters)
    name
    string Name of product (255 characters)
    category
    string Merchant category for item - e.g. Electronics (255 characters)
    currency
    string Currency used for the transaction in ISO4217 format
    Available values: IDR
    price
    number Price per unit in basket currency
    quantity
    number Number of units of this item in the basket
    type
    string Type of product - PRODUCT or SERVICE
    url
    string URL to the e-commerce page of the item
    description
    string Description of product (255 characters)
    sub-category
    string Merchant sub-category for item - e.g. Mobile Phone (255 characters)
    metadata
    object Object of additional information the merchant may use. Merchant defines the JSON properties and values.
    Merchant can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long
    metadata object Object of additional information the merchant may use. Merchant defines the JSON properties and values
    Merchant can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long
    payment_detail object Object contains information about the payment that has been shared across the payment network
    Key Value
    receipt_id
    string Request reference number (RRN) that is shared across the QR network
    source
    string Source where the end user’s balance was deducted to complete the payment (e.g. BCA, OVO, GOPAY)
    name
    string Name of the account holder/end user. This will be null if unavailable
    account_details
    string Masked public identifier for the source account. This will be null if unavailable
    Example: +62*3123

    List QR Payments by QR ID

    This GET endpoint is used to return a list of payment(s) associated with a single QR code by QR ID (qr_) from the response of Create QR Code.

    Example: List QR Payments by QR ID Request

    GET https://api.xendit.co/qr_codes/:qr_id/payments

    Request Parameters

    curl https://api.xendit.co/qr_codes/qr_61cb3576-3a25-4d35-8d15-0e8e3bdba4f2/payments -X GET \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
    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
    qr_id
    required
    string Unique identifier for this transaction. QR ID with prefix qr_ returned in the response of Create QR Code
    Query Parameter Type Description
    limit
    optional
    number Number of payment transactions to be returned in response array
    Default: 10
    from
    optional
    string Starting timestamp in ISO ISO 8601 format for created. Timestamp must be earlier than to parameter. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ
    to
    optional
    string Ending timestamp in ISO ISO 8601 format for created. Timestamp must be later than from parameter. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ

    Response Parameters

    Example: List QR Payments by QR ID Success Response

    {
        "has_more": false,
        "data": [
            {
                "id": "qrpy_8182837te-87st-49ing-8696-1239bd4d759c",
                "business_id": "58cd618ba0464eb64acdb246",
                "currency": "IDR",
                "amount": 10000,
                "status": "SUCCEEDED",
                "created": "2022-10-22T06:30:05.86474Z",
                "qr_id": "qr_61cb3576-3a25-4d35-8d15-0e8e3bdba4f2",
                "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
                "reference_id": "order-id-1666420204",
                "type": "DYNAMIC",
                "channel_code": "ID_DANA",
                "expires_at": "2022-10-23T09:56:43.60445Z",
                "basket": null,
                "metadata": null,
                "payment_detail": {
                    "receipt_id": "000111666",
                    "source": "GOPAY",
                    "name": null,
                    "account_details": null
                }
            }
        ]
    }
    Body Parameter Type Description
    has_more boolean Indicates whether there are more items to be queried from the current result
    data array Returns array of QR Payment Objects when data found. Returns empty array when data not found.

    Error Codes

    Example: List QR Payments by QR ID Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is invalid input in one of the required request fields"
    }
    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
    DATA_NOT_FOUND
    404
    QR 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

    QR Payment Callback

    Xendit notifies your system upon successful payments via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook Settings in Xendit Dashboard under QR Code paid.

    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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Example: Success Payment Webhook Payload

    {
        "event": "qr.payment",
        "api_version": "2022-07-31",
        "business_id": "58cd618ba0464eb64acdb246",
        "created": "2022-10-22T06:30:05.86474Z", 
        "data": {
            "id": "qrpy_8182837te-87st-49ing-8696-1239bd4d759c",
            "business_id": "58cd618ba0464eb64acdb246",
            "currency": "IDR",
            "amount": 10000,
            "status": "SUCCEEDED",
            "created": "2022-10-22T06:30:05.86474Z",
            "qr_id": "qr_61cb3576-3a25-4d35-8d15-0e8e3bdba4f2",
            "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
            "reference_id": "order-id-1666420204",
            "type": "DYNAMIC",
            "channel_code": "ID_DANA",
            "expires_at": "2022-10-23T09:56:43.60445Z",
            "description": "",
            "basket": null,
            "metadata": null,
            "payment_detail": {
                "receipt_id": "000111666",
                "source": "GOPAY",
                "name": null,
                "account_details": null
            }
        }
    }
    Header Parameter Type Description
    x-callback-token
    string Your Xendit unique webhook token to verify the origin of the webhook

    webhook-id
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    Body Parameter Type Description
    event string Identifies the event that triggered a notification to the merchant
    Available values: qr.payment
    api-version string The version of the API. 2022-07-31 is for the v2 version of the endpoint
    business_id string Business ID of merchant
    created string ISO 8601 Timestamp for QR payment creation. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ
    data object Return QR Payment Object

    Simulate QR Payment

    This POST endpoint is used to simulate a QR payment made to a dynamic (fixed amount) or a static (open amount) QR code created in TEST mode.

    Example: Create QR Code Request

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

    Request Parameter

    curl https://api.xendit.co/qr_codes/qr_61cb3576-3a25-4d35-8d15-0e8e3bdba4f2/payments/simulate -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==: \
       -H 'api-version: 2022-07-31'
       -H 'Content-Type: application/json' \
       --data-raw '{
        "amount": 10000
    }'
    Header Parameter Type Description
    api-version
    required
    string The version of the API. Use 2022-07-31 for the v2 version of the endpoint
    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 this transaction. QR ID with prefix qr_ returned in the response of Create QR Code
    Body Parameter Type Description
    amount
    conditionally required
    number Amount paid into a static QR code
    Static QR codes require the end user to always input the amount to be paid at the point of scanning
    Note: Min amount is 1 IDR
    Max amount is 10,000,000 IDR

    Response Parameters

    Example: Simulate QR Payment Success Response (QR Code Object)

    {
        "id": "qrpy_8182837te-87st-49ing-8696-1239bd4d759c",
        "business_id": "58cd618ba0464eb64acdb246",
        "currency": "IDR",
        "amount": 10000,
        "status": "SUCCEEDED",
        "created": "2022-10-22T06:30:05.86474Z",
        "qr_id": "qr_61cb3576-3a25-4d35-8d15-0e8e3bdba4f2",
        "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
        "reference_id": "order-id-1666420204",
        "type": "DYNAMIC",
        "channel_code": "ID_DANA",
        "expires_at": "2022-10-23T09:56:43.60445Z",
        "description": "",
        "basket": null,
        "metadata": null,
        "payment_detail": {
            "receipt_id": "000111666",
            "source": "GOPAY",
            "name": null,
            "account_details": null
        }
    }

    Returns QR Payment Object with HTTP status code 200

    Callback Payload

    Example: Success Payment Callback Payload

    {
        "event": "qr.payment",
        "api_version": "2022-07-31",
        "business_id": "58cd618ba0464eb64acdb246",
        "created": "2022-10-22T06:30:05.86474Z", 
        "data": {
            "id": "qrpy_8182837te-87st-49ing-8696-1239bd4d759c",
            "business_id": "58cd618ba0464eb64acdb246",
            "currency": "IDR",
            "amount": 10000,
            "status": "SUCCEEDED",
            "created": "2022-10-22T06:30:05.86474Z",
            "qr_id": "qr_61cb3576-3a25-4d35-8d15-0e8e3bdba4f2",
            "qr_string": "0002010102##########CO.XENDIT.WWW011893600#######14220002152#####414220010303TTT####015CO.XENDIT.WWW02180000000000000000000TTT52045######ID5911XenditQRIS6007Jakarta6105121606##########3k1mOnF73h11111111#3k1mOnF73h6v53033605401163040BDB",
            "reference_id": "order-id-1666420204",
            "type": "DYNAMIC",
            "channel_code": "ID_DANA",
            "expires_at": "2022-10-23T09:56:43.60445Z",
            "description": "",
            "basket": null,
            "metadata": null,
            "payment_detail": {
                "receipt_id": "000111666",
                "source": "GOPAY",
                "name": null,
                "account_details": null
            }
        }
    }

    Merchant will receive a single QR Payment Callback.

    Error Codes

    Example: Simulate QR Payment Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is invalid input in one of the required request fields"
    }
    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
    DATA_NOT_FOUND
    404
    QR ID specified was not found. Please check your query again
    INACTIVE_QR_CODE
    410
    The specified QR code is inactive and can no longer accept payment
    SERVER_ERROR
    500
    An unexpected error occured. Our team has been notified and will troubleshoot the issue

    QR Refund Object

    The QR Refund Object is returned in the responses and callback of Refund QR Payment, Get QR Refund by Refund ID, and List QR Refund(s) by QR Payment ID. For List QR Refund(s) by QR Payment ID, if more than one partial refund exists for a specific QR payment, the response body will contain an array of QR Refund Objects.

    Example: QR Refund Object

    {
        "id": "qrrf_52b86306-7464-4fe2-8f98-967ca603f90a",
        "qrpy_id": "qrpy_319f4504-867f-45bc-aec4-8ac64fb6be78",
        "status": "PENDING",
        "currency": "IDR",
        "payment_amount": 100000,
        "refund_amount": 50000,
        "channel_code": "ID_DANA",
        "reason": "REQUESTED_BY_CUSTOMER",
        "failure_code": null,
        "created": "2022-07-15T09:56:43.60445Z",
        "updated": "2022-07-15T09:56:43.60445Z",
        "refunded_at": null
    }
    Body Parameter Type Description
    id string Unique identifier for the QR refund transaction (prefix qrrf_)
    qrpy_id string Unique identifier for the original QR payment transaction
    status string Status of the refund request
    Available values: SUCCEEDED, FAILED, PENDING
    currency string Currency used for the transaction in ISO4217 format
    Available values: IDR
    payment_amount number Amount of the original QR payment transaction
    refund_amount number Amount to be refunded
    channel_code string Channel code indicating the QR code partner
    Available values: ID_DANA
    reason string Reason for the refund
    failure_code string Reason for the refund request failing
    created string Timestamp in ISO 8601 for the refund request. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ
    updated string Timestamp in ISO 8601 for the latest refund object update. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ
    refunded_at string Timestamp in ISO 8601 for the refund completion from the QR code partner. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ

    Refund QR Payment

    This POST endpoint is used to request a full or partial refund of a QR payment. It is possible to request multiple refunds for a single transaction as long as the aggregate refund amount does not exceed the original transaction amount.

    If a refund of the full amount is requested within 24 hours of payment completion, the original payment will be VOIDED. The original fee and VAT charged will be fully returned.

    If a refund of a partial amount is requested or if a refund of any amount is requested after 24 hours of payment completion, the original payment will be REFUNDED. The original fee and VAT charged will NOT be returned at all.

    Rules and Limitations


    Value DANA QRIS LINKAJA QRIS
    Available at Xendit?
    Partial Refund Allowed?
    Multiple Refunds Allowed?
    Validity Period
    30 days from payment
    Transaction Fee Returned?
    ✓ if a refund of the full amount is requested within 24 hours of payment completion

    ✕ if a refund of the partial amount is requested or if a refund of any amount is requested after 24 hours of payment completion

    Supported Issuers


    Value Full Amount & Within 24 Hours of Payment Completion Full Amount & After 24 Hours of Payment Completion Partial Amount
    DANA
    ShopeePay
    OVO
    LinkAja
    Mandiri
    Permata
    CIMB
    Jenius / BTPN
    BSI

    Example: Refnd QR Code Request

    POST https://api.xendit.co/qr_codes/payments/:qrpy_id/refunds

    Request Parameters

    curl https://api.xendit.co/qr_codes/payments/qrpy_8182837te-87st-49ing-8696-1239bd4d759c/refunds -X POST \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
       -H 'Content-Type: application/json' \
       --data-raw '{
        "amount": "50000",
        "reason": "REQUESTED_BY_CUSTOMER"
    }'
    Header Parameter Type Description
    idempotency-key
    optional
    string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer. It expires after 24 hours from the first request
    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
    qrpy_id
    required
    string Unique identifier for the original QR payment transaction (prefix qrpy_) returned in the QR payment callback
    Body Parameter Type Description
    amount
    optional
    number Amount to be refunded to your customer. Cumulative amount refunded must not exceed the original transacted amount

    If the amount field is not present in the request body, the remaining unrefunded amount of the original transaction will be processed
    reason
    optional
    string Reason for the refund, selecting from one of the following values
    Available values: DUPLICATE, FRAUDULENT, REQUESTED_BY_CUSTOMER, CANCELLATION, OTHERS

    Response Parameters

    Example: Refund QR Payment Success Response (QR Refund Object)

    {
        "id": "qrrf_52b86306-7464-4fe2-8f98-967ca603f90a",
        "qrpy_id": "qrpy_319f4504-867f-45bc-aec4-8ac64fb6be78",
        "status": "PENDING",
        "currency": "IDR",
        "payment_amount": 100000,
        "refund_amount": 50000,
        "channel_code": "ID_DANA",
        "reason": "REQUESTED_BY_CUSTOMER",
        "failure_code": null,
        "created": "2022-07-15T09:56:43.60445Z",
        "updated": "2022-07-15T09:56:43.60445Z",
        "refunded_at": null
    }

    Returns QR Refund Object with HTTP status code 200 and PENDING status.

    Error Codes

    Example: Refund QR Payment Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server"
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    There is an error with the format submitted to the server
    MAXIMUM_REFUND_AMOUNT_REACHED
    400
    Requested refund amount cannot exceed the remaining unrefunded amount of the original payment
    REFUND_IN_PROGRESS
    400
    Concurrent full refund requests to a single QR payment transaction is not allowed. Please wait for the pending full refund request to be completed before initiating a new one
    REFUND_NOT_SUPPORTED
    400
    Refund feature is not available as the method is not provided by the QR partner
    PARTIAL_REFUND_NOT_SUPPORTED
    400
    Partial refund feature is not available as the method is not supported for this specific issuer
    INVALID_API_KEY
    401
    API key format is invalid
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request
    INELIGIBLE_TRANSACTION
    403
    Requested refund transaction cannot be processed as the transaction is in “FAILED”, “PENDING”, or “VOIDED” status
    DATA_NOT_FOUND
    404
    Resource 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 QR partner is currently experiencing unexpected issues. The QR partner will be notified to resolve this issue

    QR Refund Callback

    The refund callback notification will be sent as POST request to the same endpoint used in creating an eWallet charge. Please make sure that your callback URL used for receiving QR payment notifications can accept both qr.payment and qr.refund events. 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.

    Example: Success Refund Callback Payload

    {
        "event": "qr.refund",
        "api_version": null,
        "business_id": "58cd618ba0464eb64acdb246",
        "created": "2022-10-22T06:30:05.86474Z", 
        "data": {
            "id": "qrrf_52b86306-7464-4fe2-8f98-967ca603f90a",
            "qrpy_id": "qrpy_319f4504-867f-45bc-aec4-8ac64fb6be78",
            "status": "SUCCEEDED",
            "currency": "IDR",
            "payment_amount": 100000,
            "refund_amount": 50000,
            "channel_code": "ID_DANA",
            "reason": "REQUESTED_BY_CUSTOMER",
            "failure_code": null,
            "created": "2022-07-15T09:56:43.60445Z",
            "updated": "2022-07-15T09:56:43.60445Z",
            "refunded_at": "2022-07-15T09:57:43.60445Z"
        }
    }
    Body Parameter Type Description
    event string Identifies the event that triggered a notification to the merchant
    Available values: qr.refund
    api_version string The version of the API. Example: 2020-04-22.
    Default: NULL
    business_id string Business ID of merchant
    created string ISO 8601 Timestamp for notification creation. Timezone UTC+0
    Format: YYYY-MM-DDTHH:mm:ssZ
    data object Return QR Refund Object
    Failure Code Failure Message
    INELIGIBLE_TRANSACTION Transaction has already passed its validity period for the requested operation or the number of refunds requested has exceeded the allowable number of tries
    INSUFFICIENT_BALANCE There is insufficient balance in your Xendit account to perform a refund. Please top up your Xendit balance with a sufficient amount before retrying the refund
    INSUFFICIENT_BALANCE Switcher account does not have sufficient balance to perform a refund. Please retry after ensuring there is sufficient balance in the switcher account
    REFUND_TEMPORARILY_UNAVAILABLE Refund is temporarily unavailable because of settlement constraints with the QR partner. Please try again later
    MAXIMUM_USER_BALANCE_EXCEEDED Refund could not be processed because the amount returned will cause the end user's account balance to exceed maximum allowable value

    Get QR Refund by Refund ID

    This GET endpoint is used to get the details of a QR refund by Refund ID (qrrf_) returned in the response of Refund QR Payment.

    Example: Get QR Refund by Refund ID Request

    Request Parameters

    GET https://api.xendit.co/qr_codes/payments/:qrpy_id/refunds/:refund_id
    curl https://api.xendit.co/qr_codes/payments/qrpy_319f4504-867f-45bc-aec4-8ac64fb6be78/refunds/qrrf_52b86306-7464-4fe2-8f98-967ca603f90a -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==: \
    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
    qrpy_id
    required
    string Unique identifier for the original QR payment transaction (prefix qrpy_) returned in the QR payment callback
    refund_id
    required
    string Unique identifier for the refund transaction (prefix qrrf_) returned in the response of Refund QR Payment

    Response Parameters

    Example: Get QR Refund by Refund ID Success Response (QR Refund Object)

    {
        "id": "qrrf_52b86306-7464-4fe2-8f98-967ca603f90a",
        "qrpy_id": "qrpy_319f4504-867f-45bc-aec4-8ac64fb6be78",
        "status": "SUCCEEDED",
        "currency": "IDR",
        "payment_amount": 100000,
        "refund_amount": 50000,
        "channel_code": "ID_DANA",
        "reason": "REQUESTED_BY_CUSTOMER",
        "failure_code": null,
        "created": "2022-07-15T09:56:43.60445Z",
        "updated": "2022-07-15T09:56:43.60445Z",
        "refunded_at": "2022-07-15T09:57:43.60445Z"
    }

    Returns QR Refund Object with status code 200 for a valid identifier.

    Error Codes

    Example: Get QR Refund by Refund ID Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server"
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    There is an error with the format submitted to the server
    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
    QR 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

    List QR Refunds by QR Payment ID

    This GET endpoint is used to get the details of all refunds associated with a single QR payment ID (qrpy_) from the QR payment callback.

    Example: List QR Refunds by QR Payment ID Request

    GET https://api.xendit.co/qr_codes/payments/:qrpy_id/refunds

    Request Parameters

    curl https://api.xendit.co/qr_codes/payments/qrpy_319f4504-867f-45bc-aec4-8ac64fb6be78/refunds -X GET \
       -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
    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
    qrpy_id
    required
    string Unique identifier for the original QR payment transaction (prefix qrpy_) returned in the QR payment callback
    Query Parameter Type Description
    limit
    optional
    number Number of payment transactions to be returned in response array
    Default: 10
    Min: 1
    Max: 50
    status
    optional
    string Refund status to be retrieved
    Available values: SUCCEEDED, FAILED, PENDING

    Response Parameters

    Example: List QR Refunds by QR Payment ID Success Response

    {
        "has_more": false,
        "data": [
            {
            "id": "qrrf_52b86306-7464-4fe2-8f98-967ca603f90a",
            "qrpy_id": "qrpy_319f4504-867f-45bc-aec4-8ac64fb6be78",
            "status": "SUCCEEDED",
            "currency": "IDR",
            "payment_amount": 100000,
            "refund_amount": 50000,
            "channel_code": "ID_DANA",
            "reason": "REQUESTED_BY_CUSTOMER",
            "failure_code": null,
            "created": "2022-07-15T09:56:43.60445Z",
            "updated": "2022-07-15T09:56:43.60445Z",
            "refunded_at": "2022-07-15T09:57:43.60445Z"
            }
        ]
    }
    Body Parameter Type Description
    has_more boolean Indicates whether there are more items to be queried from the current result. If result is empty, has_more will be false
    data array Returns array of QR Refund Objects when data found. Returns empty array when data not found

    Error Codes

    Example: List QR Refunds by QR Payment ID Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server"
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    There is an error with the format submitted to the server
    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
    Resource not found. Please check your query again
    SERVER_ERROR
    500
    An unexpected error occured. Our team has been notified and will troubleshoot the issue

    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    LinkedAccountTokenClient linkedAccountToken = xendit.LinkedAccountToken;
    
    InitializedLinkedAccountTokenParameter parameter = new InitializedLinkedAccountTokenParameter
    {
        CustomerId = "customer-id",
        ChannelCode = LinkedAccountEnum.ChannelCode.DcBri,
        Properties = new LinkedAccountProperties
        {
            AccountMobileNumber = "+62818555988",
            CardLastFour = "4444",
            CardExpiry = "06/24",
            AccountEmail = "test@email.com",
        },
        Metadata = new Dictionary<string, object>()
        {
            { "example-metadata", "here is the example" },
        },
    };
    
    InitializedLinkedAccountToken initializedLinkedAccountToken = await linkedAccountToken.Initialize(parameter);
    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
    • Bank of the Philippine Islands Recurring (PH) - BPI_RECURRING
    • Unionbank (PH) - BA_UBP
    • Unionbank e-ADA (PH) - UBP_EADA
    • Bangkok Bank (TH) - BA_BBL
    • Krungsri Bank (TH) - BA_BAY
    • Krungthai Bank (TH) - BA_KTB
    • Siam Commercial Bank (TH) - BA_SCB
    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
    optional
    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.
    For Online Banking Access Linking (BBL, SCB):
    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
    required
    URL where the end-customer is redirected if the authorization fails.
    account_identity_document_number
    optional
    Thai national identification number of the customer registered to the partner channel. e.g. "4845701245280"
    For Online Banking Access Linking (Krungsri, KTB):
    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
    required
    URL where the end-customer is redirected if the authorization fails.
    account_identity_document_number
    required
    Thai national identification number of the customer registered to the partner channel. e.g. "4845701245280"
    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    LinkedAccountTokenClient linkedAccountToken = xendit.LinkedAccountToken;
    
    string otpCode = "333000";
    string linkedAccountTokenId = "lat-f325b757-0aae-4c24-92c5-3661e299e154";
    
    ValidatedLinkedAccountToken validatedLinkedAccountToken = await linkedAccountToken.ValidateOtp(otpCode, linkedAccountTokenId);
    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    LinkedAccountTokenClient linkedAccountToken = xendit.LinkedAccountToken;
    
    string linkedAccountTokenId = "lat-f325b757-0aae-4c24-92c5-3661e299e154";
    AccessibleLinkedAccountToken[] accessibleLinkedAccountTokens = await linkedAccountToken.Get(linkedAccountTokenId);
    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}

    Endpoint: Unbind a KTB Linked Account Token

    DELETE https://api.xendit.co/linked_account_tokens/{linked_account_token_id}?success_redirect_url=https://success.yourcompany.com&failure_redirect_url=https://failure.yourcompany.com

    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();
    }
    string apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==";
    
    XenditClient xendit = new XenditClient(apiKey);
    LinkedAccountTokenClient linkedAccountToken = xendit.LinkedAccountToken;
    
    string linkedAccountTokenId = "lat-f325b757-0aae-4c24-92c5-3661e299e154";
    UnbindedLinkedAccountToken unbindedLinkedAccountToken = await linkedAccountToken.Unbind(linkedAccountTokenId);
    Path Parameter Type Description
    linked_account_token_id
    required
    string Linked account token id received from Initialize Account Authorization. This has the lat- prefix.
    Query Parameter Type Description
    success_redirect_url string URL where the end customer is redirected if the unlinking authorization is successful. Required if the payment method is direct debit and the channel is KTB.
    failure_redirect_url string URL where the end customer is redirected if the unlinking authorization is failed. Required if the payment method is direct debit and the channel is KTB.

    Unbind a Linked Account Token - Response

    Example Unbind a Linked Account Token Success Response

    {
        "id": "lat-aa620619-124f-41db-995b-66a52abe036a",
        "is_deleted": true
    }

    Example Unbind a KTB Linked Account Token Success Response

    {
        "id": "lat-aa620619-124f-41db-995b-66a52abe036a",
        "is_deleted": false,
        "authorizer_url": "https://link-web.xendit.co/oauth/lat-aa620619-124f-41db-995b-66a52abe036a/confirm_unlink"
    }
    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
    authorizer_url
    optional
    string Direct debit issuer generated URL for redirecting user to authorize account unlinking. It only shown for KTB linked account token.

    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    PaymentMethodClient paymentMethod = xendit.PaymentMethod;
    
    PaymentMethodParameter parameter = new PaymentMethodParameter
    {
      Type = PaymentMethodEnum.AccountType.DebitCard,
      Properties = new PaymentMethodProperties
      {
        Id = "la-052d3e2d-bc4d-4c98-8072-8d232a552299",
        ChannelCode = PaymentMethodEnum.ChannelCode.DcBri,
        Currency = Currency.IDR,
        CardLastFour = "1234",
        CardExpiry = "06/24",
        Description = "Payment Debit Card",
      },
      CustomerId = "4b7b6050-0830-440a-903b-37d527dbbaa9",
    };
    
    PaymentMethodResponse paymentMethodResponse = await paymentMethod.Create(parameter);
    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, BBL, Krungsri, KTB, SCB: BANK_ACCOUNT
    properties
    required
    object JSON that contains information that identifies the payment method:


    For BRI, BCA OneKlik, BPI, Unionbank, BBL, Krungsri, KTB, and SCB:
    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, BBL, Krungsri, KTB, SCB: 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, BBL, Krungsri, KTB, SCB:
    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
    • Bank of the Philippine Islands Recurring (PH) - BPI_RECURRING
    • Unionbank (PH) - BA_UBP
    • Unionbank e-ADA (PH) - UBP_EADA
    • Bangkok Bank (TH) - BA_BBL
    • Krungsri Bank (TH) - BA_BAY
    • Krungthai Bank (TH) - BA_KTB
    • Siam Commercial Bank (TH) - BA_SCB
    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    DirectDebitPaymentClient directDebitPayment = xendit.DirectDebitPayment;
    
    DirectDebitPaymentParameter directDebitPaymentParameter = new DirectDebitPaymentParameter
    {
      ReferenceId = "reference-id",
      PaymentMethodId = "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
      Currency = Currency.IDR,
      Amount = 10000,
      CallbackUrl = "https://callback-url.com/",
      EnableOtp = true,
      Description = "Example Description",
      SuccessRedirectUrl = "https://success-url.com/",
      FailureRedirectUrl = "https://failure-url.com/",
      Device = new LinkedAccountDevice
      {
        Id = "device-id",
        IpAddress = "255.255.255.255",
        UserAgent = "App",
        Imei = "imei-example",
        AdId = "ad-id",
      },
      Metadata = null,
      Basket = new BasketItem[]
      {
        new BasketItem { Name = "Black shoes", Type = "goods", Price = 2000, Quantity = 1 },
        new BasketItem { Name = "Blue shirt", Type = "apparel", Price = 2000, Quantity = 1 },
      },
    };
    
    string idempotencyKey = "fa9b53a1-f81a-47ff-8fde-b2eec3546b66";
    
    DirectDebitPaymentResponse directDebitPaymentResponse = await directDebitPayment.Create(directDebitPaymentParameter, idempotencyKey);
    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
    with-split-rule
    optional
    string Split Rule ID that you would like to apply to this direct debit payment in order to split and route payments to multiple accounts.

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

    If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

    Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    DirectDebitPaymentClient directDebitPayment = xendit.DirectDebitPayment;
    
    string otpCode = "123456";
    DirectDebitPaymentResponse directDebitPaymentResponse = await directDebitPayment.ValidateOtp(otpCode, "ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14");
    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.

    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    PaymentMethodClient paymentMethod = xendit.PaymentMethod;
    
    PaymentMethodResponse[] paymentMethodResponses = await paymentMethod.Get("ed20b5db-df04-41fc-8018-8ea4ac4d1030");
    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
    • Bank of the Philippine Islands Recurring (PH) - BPI_RECURRING
    • Unionbank (PH) - BA_UBP
    • Unionbank e-ADA (PH) - UBP_EADA
    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    DirectDebitPaymentClient directDebitPayment = xendit.DirectDebitPayment;
    
    DirectDebitPaymentResponse directDebitPaymentResponse = await directDebitPayment.GetById("ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14");
    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

    GET 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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    DirectDebitPaymentClient directDebitPayment = xendit.DirectDebitPayment;
    
    DirectDebitPaymentResponse[] directDebitPayments = await directDebitPayment.GetById("direct-debit-ref-1594717458");
    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

    Xendit notifies your system during Linked Account Tokenization and Direct Debit Payment process via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

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

    webhook-id
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks

    Linked Account Tokenization Webhook

    Linked Account Tokenization webhook 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 Webhook 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 Webhook 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 Webhook

    This webhook 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 Webhook

    {
        "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 Webhook

    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 Webhook

    {
        "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 Webhook

    Example: Direct Debit Payment Webhook

    {
        "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 Webhook

    {
      "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 Webhook

    Example: Direct Debit Refund Webhook

    {
        "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.

    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    VirtualAccountClient virtualAccount = xendit.VirtualAccount;
    
    CreateVirtualAccountParameter parameter = new CreateVirtualAccountParameter
    {
      ExternalId = "va-1475804036622",
      BankCode = VirtualAccountEnum.BankCode.Bni,
      Name = "John Doe",
      ExpectedAmount = 200000,
    };
    
    VirtualAccountResponse virtualAccountResponse = await virtualAccount.Create(parameter);

    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"
    }

    Example Request of VPB Single Use, Closed VA with QR_STRING alternative display type

    {
      "external_id": "va-1329804723",
      "bank_code": "VPB",
      "name": "Michael Chen",
      "country": "VN",
      "currency": "VND",
      "is_single_use": true,
      "is_closed": true,
      "expected_amount": 10000,
      "alternative_display_types": [
        "QR_STRING"
      ]
    }
    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-split-rule
    optional
    string Split Rule ID that you would like to apply to this Virtual Account in order to split and route payments to multiple accounts.

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

    If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

    Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

    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.

    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.

    Available bank codes for Indonesia: BCA, BNI, BRI, BJB, BSI, BNC, CIMB, DBS, MANDIRI, PERMATA, SAHABAT_SAMPOERNA

    Available bank codes for Vietnam: PV, VIETCAPITAL, WOORI, MSB, PV, VPB, BIDV

    Available bank codes for Thailand: STANDARD_CHARTERED

    Available bank codes for Malaysia: UOB, AMBANK

    Note: We recommend you to create BNI Virtual Account for interbank transfers for higher success rate.
    name
    required
    string Name of user/virtual account, - this will be displayed in the bank's user interface, e.g. ATM confirmation screens.

    Characters Only alphabet. For BCA Aggregator, alphabet and number are allowed.
    Minimum length 1 character, except BCA the minimum length is 3 characters

    Note:
  • Name can only contain letters and spaces and has length restriction depending on the banks. And also cannot contains name from bank/institution/government.
  • For Individual account type, VA name is not customizable and will always follow your business name.
  • A prefix will be included in the response for BNI VA XDT- and CIMB VA Xendit. The prefix is mandatory from the bank.
  • 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
    country
    optional. default: ID
    string The country in which the virtual account operates.

    Available countries: ID, VN, TH, and MY
    currency
    optional. default: IDR
    string The currency of payment in which the virtual account can accept.

    Available currencies for Indonesia: IDR and USD

    Available currencies for Vietnam: VND

    Available currencies for Thailand: THB

    Available currencies for Malaysia: MYR
    is_single_use
    optional. default: false
    boolean There are 2 types of 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 BNI,BJB,BRI,BSI, BNC, MANDIRI, and SAHABAT_SAMPOERNA:
  • Minimum amount: IDR 1
  • Maximum amount: IDR 50,000,000,000

  • For PERMATA:
  • Minimum amount: IDR 1
  • Maximum amount: IDR 9,999,999,999

  • For BCA:
  • Minimum amount: IDR 10,000
  • Maximum amount: IDR 999,999,999,999

  • For CIMB:
  • Minimum amount: IDR 1,000
  • Maximum amount: IDR 50,000,000,000

  • For DBS:
  • Minimum amount: USD 1.00
  • Maximum amount: USD 50,000,000,000.00

  • For WOORI and VIETCAPITAL:
  • Minimum amount: VND 10,000
  • Maximum amount: VND 499,999,999
  • min_amount
    optional
    integer positive Minimum amount to be paid by your customer for open Virtual Account, it should use an amount above the minimum amount from the bank.
    Available banks: BCA, BNC, and CIMB
    max_amount
    optional
    integer positive Maximum amount to be paid by your customer for open Virtual Account, it should use an amount below the maximum amount from the bank.
    Available banks: BCA, BNC, and CIMB
    suggested_amount
    optional
    number The suggested amount you want to assign.
    Available banks: BRI and MANDIRI

    Note: Suggested amounts is the amounts that can see as a suggestion, but user can still put any numbers.
    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. Available for BRI and BSI.

    Characters Special and alphanumeric
    Minimum length 1 character
    alternative_display_types
    optional
    array of strings Alternative display types for Virtual Account.

    Note:This value is currently only applicable to Vietnam virtual accounts.

    Allowed value: QR_STRING

    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",
      "is_single_use": false,
      "is_closed": false,
      "expiration_date": "2051-09-27T17:00:00.000Z",
      "status": "PENDING",
      "currency": "IDR",
      "country": "ID"
    }

    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",
      "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",
      "currency": "IDR",
      "country": "ID"
    }

    Example of VPB Single Use Close VA Response with QR_STRING alternative display type

    {
        "id": "fc1a1fbc-1876-4dc6-b2d1-564f756312f5",
        "owner_id": "62ea3c344b29b4f5d58f634c",
        "external_id": "va-234982374",
        "account_number": "0024600000028492",
        "bank_code": "VPB",
        "merchant_code": "0024",
        "name": "Michael Chen",
        "is_closed": true,
        "expected_amount": 10000,
        "expiration_date": "2055-04-24T10:14:05.651Z",
        "is_single_use": true,
        "status": "PENDING",
        "currency": "VND",
        "country": "VN",
        "alternative_displays": [
            {
                "type": "QR_STRING",
                "data": "00020101021238600010A00000072701300006970432011600246000000284920208QRIBFTTA53037045802VN5405100006304EDF0"
            }
        ]
    }

    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 expected amount is below the maximum limit.
    MAXIMUM_EXPECTED_AMOUNT_ERROR
    400
    The expected amount is above the maximum limit.
    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.
    MINIMUM_AMOUNT_ERROR_ERROR
    400
    Parameter min_amount should be above minimum amount allowed by the bank
    MAXIMUM_AMOUNT_ERROR_ERROR
    400
    Parameter max_amount should be below maximum amount allowed by the bank
    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
    FEATURE_NOT_SUPPORTED_ERROR
    403
    Minimum and maximum amount feature is not supported by the selected bank. Check Docs/API Reference to see list of banks who support minimum and maximum amount feature.
    CHANNEL_UNAVAILABLE
    503
    The payment channel requested is currently experiencing unexpected issues. The Virtual Account provider will be notified to resolve this issue.

    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    VirtualAccountClient virtualAccount = xendit.VirtualAccount;
    
    UpdateVirtualAccountParameter parameter = new UpdateVirtualAccountParameter
    {
      IsSingleUse = true,
      ExpectedAmount = 20000,
    };
    
    VirtualAccountResponse virtualAccountResponse = await virtualAccount.Update(parameter, "57f6fbf26b9f064272622aa6");

    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
    min_amount
    optional
    string Minimum amount to be paid by your customer for open Virtual Account, it should use an amount above the minimum amount from the bank.
    max_amount
    optional
    string Maximum amount to be paid by your customer for open Virtual Account, it should use an amount below the maximum amount from the bank.
    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.

    Characters Special and alphanumeric
    Minimum length 1 character
    external_id
    optional
    string An ID of your choice. Often it is unique identifier like a phone number, email or transaction ID

    Characters: Special and alphanumeric
    Minimum Character: 1 character
    Maximum Characters: 950 Characters

    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",
      "country": "ID",
      "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 expected amount below the minimum limit.
    MAXIMUM_EXPECTED_AMOUNT_ERROR
    400
    The expected amount above the maximum limit.
    DESCRIPTION_NOT_SUPPORTED_ERROR
    400
    The requested Virtual Account bank doesn't support description feature.
    MINIMUM_AMOUNT_ERROR_ERROR
    400
    Parameter min_amount should be above minimum amount allowed by the bank
    MAXIMUM_AMOUNT_ERROR_ERROR
    400
    Parameter max_amount should be below maximum amount allowed by the bank
    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
    FEATURE_NOT_SUPPORTED_ERROR
    403
    Minimum and maximum amount feature is not supported by the selected bank. Check Docs/API Reference to see list of banks who support minimum and maximum amount feature.

    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    VirtualAccountClient virtualAccount = xendit.VirtualAccount;
    
    VirtualAccountResponse virtualAccountResponse = await virtualAccount.Get("5eec3a3e8dd9ea2fc97d6728");

    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",
      "country" : "ID",
      "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.

    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",
      "alternative_displays": [
        {
          "type": "QR_STRING",
          "data": "00020101021238600010A00000072701300006970432011600246000000284920208QRIBFTTA53037045802VN5405100006304EDF0"
        }
      ]
    }
    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 of the virtual account you want to create.
    merchant_code
    required
    string Prefix for the Virtual Account. For the aggregator model, this is Xendit's merchant code. For the switcher model, this is the merchant code that you received from the bank. 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.
    country
    required
    string The country in which the virtual account operates.
    currency
    required
    string The currency of payment in which the virtual account can accept, 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 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.
    min_amount
    optional
    string Minimum amount to be paid by your customer for open Virtual Account, it should use an amount above the minimum amount from the bank.
    max_amount
    optional
    string Maximum amount to be paid by your customer for open Virtual Account, it should use an amount below the maximum amount from the bank.
    suggested_amount
    optional
    number Suggested amount for the 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.
    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
  • alternative_displays
    optional
    object Alternative Display for the virtual account.

    Note: This field is only applicable to Vietnam virtual accounts.

    Data fields
    Key Value
    type
    required
    The alternative display type
    data
    required
    The data for the display type.

    Note: If it is QR_STRING, please use this value to generate a VietQR QR Code.

    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. See our testing page here for further guideline.

    Endpoint: Simulate VA Payment

    POST https://api.xendit.co/callback_virtual_accounts/external_id={external_id}/simulate_payment

    Request Parameters

    Simulation Example

    {
        "amount": 50000
    }
    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to simulate 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 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

    Virtual Account Callback

    Endpoint: Virtual Account Webhook

    POST https://yourcompany.com/virtual_account_paid_webhook_url

    Xendit notifies your system upon successful payments via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Header Parameters

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

    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks

    Example Virtual Account Payment Webhook Payload

    {
        "id": "598d91b1191029596846047f",
        "payment_id": "5f218745736e619164dc8608",
        "callback_virtual_account_id": "598d5f71bf64853820c49a18",
        "owner_id": "57b4e5181473eeb61c11f9b9",
        "external_id": "demo-1502437214715",
        "account_number": "999939380502",
        "bank_code": "BNC",
        "transaction_timestamp": "2021-07-24T05:22:55.115Z",
        "amount": 50000,
        "merchant_code": "90100010",
        "currency": "IDR",
        "country" : "ID",
        "sender_name": "Michael Chen",
        "payment_detail": {
            "payment_interface": "MOBILE_BANKING",
            "remark": "Sent by Michael for my package",
            "reference": "66143641700",
            "sender_account_number": "12345678912345",
            "sender_channel_code": "BNC",
            "sender_name": "Michael Chen",
            "transfer_method": "INHOUSE"
        }
    }

    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 Xendit business ID

    Creation / Update Webhook Payload

    Example of Virtual Account Active Webhook Payload

    {
      "id": "57f6fbf26b9f064272622aa6",
      "external_id": "va-1475804036622",
      "owner_id": "57b4e5181473eeb61c11f9b9",
      "bank_code": "BNI",
      "merchant_code": "8808",
      "account_number": "8808999939380502",
      "name": "Michael Chen",
      "currency": "IDR",
      "country" : "ID",
      "is_single_use": false,
      "is_closed": false,
      "expiration_date": "2051-09-27T17:00:00.000Z",
      "status": "ACTIVE"
    }

    Returns Virtual Account Object with additional parameters:

    Body Parameter Type Description
    created
    required
    string ISO8601 timestamp of when the Virtual Account was created. Timezone UTC+0
    updated
    required
    string ISO8601 timestamp of the Virtual Account last updated. Timezone UTC+0

    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    VirtualAccountPaymentClient virtualAccountPayment = xendit.VirtualAccountPayment;
    
    VirtualAccountPaymentResponse virtualAccountPaymentResponse = await virtualAccountPayment.Get("5ef18efca7d10d1b4d61fb52");

    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",
        "owner_id": "57b4e5181473eeb61c11f9b9",
        "external_id": "demo-1502437214715",
        "bank_code": "BNC",
        "merchant_code": "90100010",
        "account_number": "999939380502",
        "amount": 50000,
        "currency" : "IDR",
        "transaction_timestamp": "2021-07-24T05:22:55.115Z",
        "sender_name": "Michael Chen",
        "payment_detail": {
            "payment_interface": "MOBILE_BANKING",
            "remark": "Sent by Michael for my package",
            "reference": "66143641700",
            "sender_account_number": "12345678912345",
            "sender_channel_code": "BNC",
            "sender_name": "Michael Chen",
            "transfer_method": "INHOUSE"
        }
    }

    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 Payment Object

    Example Virtual Account Payment Object

    {
        "id": "598d91b1191029596846047f",
        "payment_id": "5f218745736e619164dc8608",
        "callback_virtual_account_id": "598d5f71bf64853820c49a18",
        "owner_id": "57b4e5181473eeb61c11f9b9",
        "external_id": "demo-1502437214715",
        "account_number": "999939380502",
        "bank_code": "BNC",
        "transaction_timestamp": "2021-07-24T05:22:55.115Z",
        "amount": 50000,
        "merchant_code": "90100010",
        "currency": "IDR",
        "country": "ID",
        "sender_name": "Michael Chen",
        "payment_detail": {
            "payment_interface": "MOBILE_BANKING",
            "remark": "Sent by Michael for my package",
            "reference": "66143641700",
            "sender_account_number": "12345678912345",
            "sender_channel_code": "BNC",
            "sender_name": "Michael Chen",
            "transfer_method": "INHOUSE"
        }
    }
    Body 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 exclude the prefix (merchant code).
    currency
    required
    string The currency of payment in which the virtual account can accept, if it's not specified, it will be using IDR by default.
    country
    required
    string The country in which the virtual account operate, if it's not specified, it will be using ID by default.
    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
    optional
    string Name of the end user that paid into the Virtual Account. Available for BNC, DBS, and SAHABAT_SAMPOERNA.
    payment_detail
    optional
    object Additional information from the bank.
    Data fields
    Key Value
    payment_interface
    optional
    String Banking channels or interface such as mobile banking, ATM, etc that being used by the end user to pay the Virtual Account. Available for BNC. The possible values are as follow: API, ATM, DEBIT_CARD, EDC, INTERNET_BANKING, MOBILE_BANKING, and TELLER.
    reference
    optional
    String Reference number from the bank that can be used for reconciliation. Available for BCA and BNC.
    remark
    optional
    String A remark that is inputted by the payer when they are about to make a payment. Available for SAHABAT_SAMPOERNA.
    sender_account_number
    optional
    String Account number of the end user that paid into the Virtual Account. Available for BNC.
    sender_channel_code
    optional
    String Channel code (generally will be a bank code) that being used by the end user to pay the Virtual Account. Available for BNC.
    sender_name
    optional
    String Name of the end user that paid into the Virtual Account. Available for BNC.
    transfer_method
    optional
    String The transfer method used to make the virtual account payment. Available for BNC. The possible values are as follows: BI_FAST, INHOUSE, RTGS, RTOL, and SKN.
    network
    optional
    String Network which the virtual account payment was made over. Available for BANK_TRANSFER channel in the Philippines. The possible values are as follows: InstaPay, PESONet.

    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)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    VirtualAccountClient virtualAccount = xendit.VirtualAccount;
    
    AvailableBank[] availableBanks = await virtualAccount.GetAvailableBanks();

    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 for Indonesia

    [
        {
            "name": "Bank Central Asia",
            "code": "BCA",
            "country": "ID",
            "currency": "IDR",
            "is_activated": false
        },
        {
            "name": "Bank Negara Indonesia",
            "code": "BNI",
            "country": "ID",
            "currency": "IDR",
            "is_activated": false
        },
        {
            "name": "Bank Mandiri",
            "code": "MANDIRI",
            "country": "ID",
            "currency": "IDR",
            "is_activated": false
        },
        {
            "name": "Bank Permata",
            "code": "PERMATA",
            "country": "ID",
            "currency": "IDR",
            "is_activated": false
        },
        {
            "name": "Bank Sahabat Sampoerna",
            "code": "SAHABAT_SAMPOERNA",
            "country": "ID",
            "currency": "IDR",
            "is_activated": false
        },
        {
            "name": "Bank Rakyat Indonesia",
            "code": "BRI",
            "country": "ID",
            "currency": "IDR",
            "is_activated": false
        },
        {
            "name": "Bank Neo Commerce",
            "code": "BNC",
            "country": "ID",
            "currency": "IDR",
            "is_activated": false
        },
        {
            "name": "Bank CIMB Niaga",
            "code": "CIMB",
            "country": "ID",
            "currency": "IDR",
            "is_activated": false
        },
        {
            "name": "Bank Syariah Indonesia",
            "code": "BSI",
            "country": "ID",
            "currency": "IDR",
            "is_activated": false
        },
        {
            "name": "Bank Jabar Banten",
            "code": "BJB",
            "country": "ID",
            "currency": "IDR",
            "is_activated": false
        },
        {
            "name": "The Development Bank of Singapore",
            "code": "DBS",
            "country": "ID",
            "currency": "IDR",
            "is_activated": false
        },
        {
            "name": "The Development Bank of Singapore",
            "code": "DBS",
            "country": "ID",
            "currency": "USD",
            "is_activated": false
        }
    ]

    Example Get Virtual Account Banks Response for Vietnam

    [
        {
            "name": "PV Bank",
            "code": "PV",
            "country": "VN",
            "currency": "VND",
            "is_activated": false
        },
        {
            "name": "Vietcapital Bank",
            "code": "VIETCAPITAL",
            "country": "VN",
            "currency": "VND",
            "is_activated": false
        },
        {
            "name": "Woori Bank",
            "code": "WOORI",
            "country": "VN",
            "currency": "VND",
            "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.

    country
    required
    string The country in which the virtual account operates.

    currency
    required
    string The currency of payment in which the virtual account can accept.

    is_activated
    required
    boolean Activation status of the bank, relevant during creation of virtual accounts.

    Retail Outlets (OTC) - ID

    Create Fixed Payment Code

    Endpoint: Create Fixed Payment Code (FPC)

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

    One way for your customer to pay through Retail Outlets is by providing them Fixed Payment Code. Fixed payment code is a dedicated payment code under a name you choose, e.g. 'YourCompany - Becca Salim'. You will receive a webhook each time this fixed payment code is paid.

    Request Parameters

    Example Create Fixed Payment Code Request

    curl https://api.xendit.co/fixed_payment_code -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -d external_id=demo_fixed_payment_code_123 \
       -d retail_outlet_name=ALFAMART \
       -d name='Rika Sutanto' \
       -d expected_amount=10000
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $params = [
        'external_id' => '123',
        'retail_outlet_name' => 'ALFAMART',
        'name' => 'Rika Sutanto',
        'expected_amount' => 10000
      ];
    
      $createFPC = \Xendit\Retail::create($params);
      var_dump($createFPC);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { RetailOutlet } = x;
    const retailOutletSpecificOptions = {};
    const ro = new RetailOutlet(retailOutletSpecificOptions);
    
    const resp = await ro.createFixedPaymentCode({
      externalID: 'demo_fixed_payment_code_123',
      retailOutletName: 'ALFAMART',
      name: 'Rika Sutanto',
      expectedAmt: 10000,
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Map<String, Object> params = new HashMap<>();
      params.put("external_id", "test");
      params.put("retail_outlet_name", "ALFAMART");
      params.put("name", "Rika Sutanto");
      params.put("expected_amount", 10000);
    
      FixedPaymentCode fpc = RetailOutlet.createFixedPaymentCode(params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := retailoutlet.CreateFixedPaymentCodeParams{
      ExternalID:       "123",
      RetailOutletName: xendit.RetailOutletNameAlfamart,
      Name:             "Rika Sutanto",
      ExpectedAmount:   10000,
    }
    
    resp, err := retailoutlet.CreateFixedPaymentCode(&data)
    if err != nil {
      log.Fatal(err.ErrorCode)
    }
    
    fmt.Printf("created retail outlet fixed payment code: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    RetailOutlet = xendit_instance.RetailOutlet
    
    retail_outlet = RetailOutlet.create_fixed_payment_code(
        external_id="demo_fixed_payment_code_123",
        retail_outlet_name="ALFAMART",
        name="Rika Sutanto",
        expected_amount=10000,
    )
    print(retail_outlet)

    JSON

    {
      "external_id": "123",
      "retail_outlet_name": "ALFAMART",
      "name": "Rika Sutanto",
      "expected_amount": 10000
    }
    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-split-rule
    optional
    string Split Rule ID that you would like to apply to this OTC payment code in order to split and route payments to multiple accounts.

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

    If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

    Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

    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. Maximum length allowed is 1000 characters.

    Characters Special and alphanumeric
    Minimum length 1 character
    retail_outlet_name
    required
    string Name of the fixed payment code you want to create

    Available Retail Outlets: ALFAMART and INDOMARET
    name
    required
    string Name of user - this might be used by the Retail Outlets cashier to validate the end user

    Characters alphanumeric
    Special Characters: # / . " - , ' _ @ ( ) & ] [ :
    Minimum length 1 character
    Maximum length For Alfamart 40 character, for Indomaret 45 character
    expected_amount
    required
    integer positive The amount that is expected to be paid by end customer
  • the minimum is Rp 10,000 and the maximum is Rp 2,500,000 for Alfamart
  • the minimum is Rp 10,000 and the maximum is Rp 5,000,000 for Indomaret
  • payment_code
    optional
    string You can assign specific fixed payment code using this parameter e.g 12345. If you do not send one, one will be picked at random

    Make sure when you want to create payment code, you do not include the prefix on this field. For example: your prefix is PSTEST and you want to create payment code PSTEST12345, you can only fill 12345 on this field

    You can check your prefix information on Retail Outlet details
    default: random string
    expiration_date
    optional
    ISO 8601 Date The time when the fixed payment code will be expired

    timezone: UTC
    default: The expired date will be 31 years from payment code generated
    is_single_use
    optional
    boolean When set to true, the fixed payment code will be inactive after it is paid

    default: false

    Response Parameters

    Example Create Fixed Payment Code Response

    {
        "is_single_use": false,
        "status": "ACTIVE",
        "owner_id": "5c2323c67d6d305ac433ba20",
        "external_id": "123",
        "retail_outlet_name": "ALFAMART",
        "prefix": "TEST",
        "name": "Rika Sutanto",
        "payment_code": "TEST906558",
        "type": "USER",
        "expected_amount": 10000,
        "expiration_date": "2051-11-01T17:00:00.000Z",
        "id": "5f9fb01c4134b42c56b034c1"
    }
    Parameter Type Description
    owner_id
    required
    string Your user ID
    external_id
    required
    string An ID of your choice which you provided upon request
    retail_outlet_name
    required
    string Name of the Retail Outlets, e.g. ALFAMART or INDOMARET
    prefix
    required
    string 3-6 characters that differentiate your fixed payment code from the others
    name
    required
    string Name for the fixed payment code
    payment_code
    required
    string Complete fixed payment code (including prefix). This is what a user will need to tell Retail Outlets cashier or show via barcode page. You can append payment_code into the barcode page URL (barcode page currently only supports Alfamart):
    TEST: https://retail-outlet-barcode-dev.xendit.co/alfamart/:payment_code
    LIVE: https://retail-outlet-barcode.xendit.co/alfamart/:payment_code
    expected_amount
    required
    integer positive The amount that is expected to be paid by end customer
  • the minimum is Rp 10,000 and the maximum is Rp 2,500,000 for Alfamart
  • the minimum is Rp 10,000 and the maximum is Rp 5,000,000 for Indomaret
  • is_single_use
    required
    boolean Value that determines whether a fixed payment code will be inactive after it is paid or not
    expiration_date
    required
    ISO 8601 Date The time when the fixed payment code will be expired
    id
    required
    string Unique ID for the fixed payment code that generated randomly by system.
    status
    required
    string Status of fixed payment code that defines if it’s ACTIVE, INACTIVE, or EXPIRED.
  • Status is ACTIVE if fixed payment code has not paid or has not expired yet.
  • Status is INACTIVE if fixed payment code is already paid.
  • Status is EXPIRED if fixed payment code that has expiration date and been updated to the date less than now.
  • type
    required
    string To define that this is user generated payment code

    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.
    PAYMENT_CODE_OUTSIDE_RANGE
    400
    The fixed payment code you want is outside your range. Can resolve by check the dashboard to see the range Retail Outlets Settings
    RETAIL_OUTLET_NOT_SUPPORTED_ERROR
    400
    The Retail Outlets is not currently supported.
    DUPLICATE_PAYMENT_CODE_ERROR
    400
    The payment code that you want to create is already exist
    EXPIRATION_DATE_INVALID_ERROR
    400
    Invalid custom expiration date because it's earlier than current time.
    MINIMUM_EXPECTED_AMOUNT_ERROR
    400
    The expected amount can only be more than or equal Rp 10,0000
    MAXIMUM_EXPECTED_AMOUNT_ERROR
    400
    The expected amount can only be less than or equal Rp 5,000,000
    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

    Update Fixed Payment Code

    Endpoint: Update Fixed Payment Code (FPC)

    PATCH https://api.xendit.co/fixed_payment_code/{fixed_payment_code_id}

    Fixed Payment Code is so adaptable, and it's all based on your needs. Therefore, we provide you this endpoint to easily update your fixed payment code as you like.

    Request Parameters

    Example Update Fixed Payment Code Request

    curl https://api.xendit.co/fixed_payment_code/{fixed_payment_code_id} -X PATCH \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -d expected_amount=20000
       -d name='Joe Contini'
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $id = '5b61881e6cc2770f00117f73';
      $updateParams = ['expected_amount' => 20000];
    
      $updateFPC = \Xendit\Retail::update($id, $updateParams);
      var_dump($updateFPC);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { RetailOutlet } = x;
    const retailOutletSpecificOptions = {};
    const ro = new RetailOutlet(retailOutletSpecificOptions);
    
    const resp = await ro.updateFixedPaymentCode({
      id: '5b61881e6cc2770f00117f73',
      name: 'Joe Contini',
      expectedAmt: 20000,
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Map<String, Object> params = new HashMap<>();
      params.put("name", "Lorem Ipsum");
    
      FixedPaymentCode fpc = RetailOutlet.updateFixedPaymentCode("EXAMPLE_ID", params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    expirationDate := time.Now().AddDate(0, 0, 1)
    
    updateFixedPaymentCodeData := retailoutlet.UpdateFixedPaymentCodeParams{
      FixedPaymentCodeID: "5b61881e6cc2770f00117f73",
      Name:               "Joe Contini",
      ExpectedAmount:     20000,
      ExpirationDate:     &expirationDate,
    }
    
    resp, err := retailoutlet.UpdateFixedPaymentCode(&updateFixedPaymentCodeData)
    if err != nil {
      log.Fatal(err.ErrorCode)
    }
    fmt.Printf("updated retail outlet fixed payment code: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    RetailOutlet = xendit_instance.RetailOutlet
    
    retail_outlet = RetailOutlet.update_fixed_payment_code(
        fixed_payment_code_id="5ef2f0f8e7f5c14077275493",
        name="Joe Contini",
    )
    print(retail_outlet)

    JSON

    {
      "expected_amount": 20000,
      "name": "Joe Contini"
    }
    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
    name
    optional
    string Name for the fixed payment code

    Characters Only alphanumeric
    Minimum length 1 character
    expected_amount
    optional
    integer positive The amount that is expected to be paid by end customer
  • the minimum is Rp 10,000 and the maximum is Rp 2,500,000 for Alfamart
  • the minimum is Rp 10,000 and the maximum is Rp 5,000,000 for Indomaret
  • expiration_date
    optional
    ISO 8601 Date The time when the fixed payment code will be expired. You can set it to be days in the past to expire fixed payment code immediately

    timezone: UTC
    default: The expired date will be 31 years from payment code generated

    Response Parameters

    Example Update Fixed Payment Code Response

    {
        "is_single_use": false,
        "status": "ACTIVE",
        "owner_id": "5c2323c67d6d305ac433ba20",
        "external_id": "123",
        "retail_outlet_name": "ALFAMART",
        "prefix": "TEST",
        "name": "JOHN DOE",
        "payment_code": "TEST906558",
        "type": "USER",
        "expected_amount": 25000,
        "expiration_date": "2051-11-01T17:00:00.000Z",
        "id": "5f9fb01c4134b42c56b034c1"
    }
    Parameter Type Description
    owner_id
    required
    string Your user ID
    external_id
    required
    string An ID of your choice which you provided upon request
    retail_outlet_name
    required
    string Name of the Retail Outlets, e.g. ALFAMART or INDOMARET
    prefix
    required
    string 3-6 characters that differentiate your fixed payment code from the others
    name
    required
    string Name for the fixed payment code
    payment_code
    required
    string Complete fixed payment code (including prefix). This is what a user will need to tell Retail Outlets cashier or show via barcode page. You can append payment_code into the barcode page URL (barcode page currently only supports Alfamart):
    TEST: https://retail-outlet-barcode-dev.xendit.co/alfamart/:payment_code
    LIVE: https://retail-outlet-barcode.xendit.co/alfamart/:payment_code
    expected_amount
    required
    integer positive The amount that is expected to be paid by end customer
  • the minimum is Rp 10,000 and the maximum is Rp 2,500,000 for Alfamart
  • the minimum is Rp 10,000 and the maximum is Rp 5,000,000 for Indomaret
  • is_single_use
    required
    boolean Value that determines whether a fixed payment code will be inactive after it is paid or not
    expiration_date
    required
    ISO 8601 Date The time when the fixed payment code will be expired
    id
    required
    string Unique ID for the fixed payment code that generated randomly by system.
    status
    required
    string Status of fixed payment code that defines if it’s ACTIVE, INACTIVE, or EXPIRED.
  • Status is ACTIVE if fixed payment code has not paid or has not expired yet.
  • Status is INACTIVE if fixed payment code is already paid.
  • Status is EXPIRED if fixed payment code that has expiration date and been updated to the date less than now.
  • type
    required
    string To define that this is user generated payment code

    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.
    INACTIVE_FIXED_PAYMENT_CODE_ERROR
    400
    Account number that you want to update is inactive.
    MINIMUM_EXPECTED_AMOUNT_ERROR
    400
    The expected amount can only be more than or equal Rp 10,000
    MAXIMUM_EXPECTED_AMOUNT_ERROR
    400
    The expected amount can only be less than or equal Rp 5,000,000
    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 Fixed Payment Code

    Endpoint: Get Fixed Payment Code

    GET https://api.xendit.co/fixed_payment_code/{fixed_payment_code_id}

    Example Get Fixed Payment Code Request

    curl https://api.xendit.co/fixed_payment_code/{fixed_payment_code_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 = '5b61881e6cc2770f00117f73';
    
      $getFPC = \Xendit\Retail::retrieve($id);
      var_dump($getFPC);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { RetailOutlet } = x;
    const retailOutletSpecificOptions = {};
    const ro = new RetailOutlet(retailOutletSpecificOptions);
    
    const resp = await ro.getFixedPaymentCode({
      id: '5b61881e6cc2770f00117f73',
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      FixedPaymentCode fpc = RetailOutlet.getFixedPaymentCode("EXAMPLE_ID");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    getFixedPaymentCodeData := retailoutlet.GetFixedPaymentCodeParams{
      FixedPaymentCodeID: "5b61881e6cc2770f00117f73",
    }
    
    resp, err := retailoutlet.GetFixedPaymentCode(&getFixedPaymentCodeData)
    if err != nil {
      log.Fatal(err.ErrorCode)
    }
    
    fmt.Printf("retrieved retail outlet fixed payment code: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    RetailOutlet = xendit_instance.RetailOutlet
    
    retail_outlet = RetailOutlet.get_fixed_payment_code(
        fixed_payment_code_id="5ef2f0f8e7f5c14077275493",
    )
    print(retail_outlet)

    Sometimes, you need to know the detail for your fixed payment code. This endpoint can be used to get the latest details from your fixed payment code

    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
    fixed_payment_code_id
    required
    string ID of the fixed payment code to retrieve

    Response Parameters

    Example Get Fixed Payment Code Response

    {
        "is_single_use": false,
        "status": "ACTIVE",
        "owner_id": "5c2323c67d6d305ac433ba20",
        "external_id": "123",
        "retail_outlet_name": "ALFAMART",
        "prefix": "TEST",
        "name": "JOHN DOE",
        "payment_code": "TEST906558",
        "type": "USER",
        "expected_amount": 25000,
        "expiration_date": "2051-11-01T17:00:00.000Z",
        "id": "5f9fb01c4134b42c56b034c1"
    }
    Parameter Type Description
    owner_id
    required
    string Your user ID
    status
    required
    string Status of fixed payment code that defines if it’s ACTIVE, INACTIVE, or EXPIRED.
  • Status is ACTIVE if fixed payment code has not paid or has not expired yet.
  • Status is INACTIVE if fixed payment code is already paid.
  • Status is EXPIRED if fixed payment code that has expiration date and been updated to the date less than now.
  • type
    required
    string To define that this is user generated payment code
    external_id
    required
    string An ID of your choice which you provided upon request
    retail_outlet_name
    required
    string Name of the Retail Outlets, e.g. ALFAMART or INDOMARET
    prefix
    required
    string 3-6 characters that differentiate your fixed payment code from the others
    name
    required
    string Name for the fixed payment code
    payment_code
    required
    string Complete fixed payment code (including prefix). This is what a user will need to tell Retail Outlets cashier or show via barcode page. You can append payment_code into the barcode page URL (barcode page currently only supports Alfamart):
    TEST: https://retail-outlet-barcode-dev.xendit.co/alfamart/:payment_code
    LIVE: https://retail-outlet-barcode.xendit.co/alfamart/:payment_code
    expected_amount
    required
    integer positive The amount that is expected to be paid by end customer
  • the minimum is Rp 10,000 and the maximum is Rp 2,500,000 for Alfamart
  • the minimum is Rp 10,000 and the maximum is Rp 5,000,000 for Indomaret
  • is_single_use
    required
    boolean Value that determines whether a fixed payment code will be inactive after it is paid or not
    expiration_date
    required
    ISO 8601 Date The time when the fixed payment code will be expired
    id
    required
    string Unique ID for the fixed payment code that generated randomly by system.

    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
    FIXED_PAYMENT_CODE_NOT_FOUND_ERROR
    404
    Could not find fixed payment code.

    Fixed Payment Code Callback

    Endpoint: Fixed Payment Code Webhook

    POST https://yourcompany.com/fixed_payment_code_paid_webhook_url

    Xendit notifies your system upon successful payments via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

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

    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks

    Example Fixed Payment Code Payment Webhook Request

    curl --include \
        --request POST \
        --url https://yourcompany.com/fixed_payment_code_paid_webhook_url \
        --header 'content-type: application/json' \
        --header 'x-callback-token: MuaJALKJSDK12LASHD123kSAKSDHzjahwUWjkasJSDSA12KSNAK21n==' \
        --data '{
      "id": "58a435201b6ce2a355f46070",
      "external_id": "fixed-payment-code-14876410",
      "prefix": "TEST",
      "payment_code": "TEST123",
      "retail_outlet_name": "ALFAMART",
      "name": "John Doe",
      "amount": 123456,
      "status": "SETTLING",
      "transaction_timestamp": "2019-11-08T11:51:28.613Z",
      "payment_id": "1573213888613",
      "fixed_payment_code_payment_id": "5dc556c07a58de7c114f0347",
      "fixed_payment_code_id": "5dc5567bdf120fd64988a79b",
      "owner_id": "5be9b2f03ef77262c2bd49e6"
    }'

    JSON

    {
      "id": "58a435201b6ce2a355f46070",
      "external_id": "fixed-payment-code-14876410",
      "prefix": "TEST",
      "payment_code": "TEST123",
      "retail_outlet_name": "ALFAMART",
      "name": "John Doe",
      "amount": 123456,
      "status": "SETTLING",
      "transaction_timestamp": "2019-11-08T11:51:28.613Z",
      "payment_id": "1573213888613",
      "fixed_payment_code_payment_id": "5dc556c07a58de7c114f0347",
      "fixed_payment_code_id": "5dc5567bdf120fd64988a79b",
      "owner_id": "5be9b2f03ef77262c2bd49e6"
    }
    Body Parameter Type Description
    id
    required
    string Unique identifier for this transaction
    external_id
    required
    string An ID of your choice which you provided upon fixed payment code creation
    prefix
    required
    string 3-6 characters that differentiate your fixed payment code from the others
    payment_code
    required
    string Complete fixed payment code (including prefix). This is what a user will need to tell Retail Outlets cashier or show via barcode page. You can append payment_code into the barcode page URL (barcode page currently only supports Alfamart):
    TEST: https://retail-outlet-barcode-dev.xendit.co/alfamart/:payment_code
    LIVE: https://retail-outlet-barcode.xendit.co/alfamart/:payment_code
    retail_outlet_name
    required
    string Name for the relevant Retail Outlets, e.g. ALFAMART or INDOMARET
    name
    required
    string Name for the fixed payment code
    amount
    required
    integer positive Nominal amount that is paid
    status
    required
    string Status of payment. Possible value(s): SETTLING or COMPLETED
  • SETTLING means that transaction already PAID but still waiting for settlement time
  • COMPLETED means that transaction already PAID and SETTLED
  • transaction_timestamp
    required
    ISO 8601 Date Date time that the fixed payment code was paid
    payment_id
    required
    string Our internal system’s payment ID that can be used as payment reference
    fixed_payment_code_payment_id
    required
    string Unique ID for the fixed payment code payment
    fixed_payment_code_id
    required
    string Unique ID for the fixed payment code
    owner_id
    required
    string Your user ID

    Get Payments By Fixed Payment Code ID

    Endpoint: Get Payments By Fixed Payment Code ID(FPC)

    GET https://api.xendit.co/fixed_payment_code/{fixed_payment_code_id}/payments

    Sometimes, you need to know the payments made for your fixed payment code. This endpoint can be used to retrieve all payments that were made into a particular fixed payment code.

    Request Parameters

    Example Get Payments by Fixed Payment Code ID Request

    curl https://api.xendit.co/fixed_payment_code/{fixed_payment_code_id}/payments -X GET \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
    To be developed
    To be developed
    To be developed
    To be developed
    To be developed

    Example Get Payments by Fixed Payment Code ID Response

    {
        "data": [
            {
                "status": "COMPLETED",
                "fixed_payment_code_payment_id": "61c53c4fdc1b825d9a58ff54",
                "fixed_payment_code_id": "61c53c3727c7a679826dd90a",
                "amount": 2500000,
                "name": "JOHN DOE",
                "prefix": "TEST",
                "payment_code": "TEST892185",
                "payment_id": "1640315983260",
                "external_id": "FPC-1640315959",
                "retail_outlet_name": "ALFAMART",
                "transaction_timestamp": "2021-12-24T03:19:43.260Z",
                "id": "61c53c4f6cc577e4038ab099",
                "owner_id": "60ca10b83ffd534ece8aa856"
            }
        ],
        "has_more": true,
        "links": {
            "href": "https://api.xendit.co/fixed_payment_code/61c53c3727c7a679826dd90a/payments?limit=1&after_id=61c53c4f6cc577e4038ab099",
            "rel": "next",
            "method": "GET"
        }
    }
    
    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
    fixed_payment_code_id
    required
    string ID of the fixed payment code to retrieve
    Query Parameter Type Description
    limit
    optional

    default: 10
    number A limit on the number of invoice objects to be returned.
    Limit can range between 1 and 100.
    after_id
    optional
    string Id of the immediately previous item. Use this with links on the response for pagination.

    Response Parameters

    Parameter Type Description
    data
    required
    array of objects Returns an array of Payment 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 value will be GET.
    Payment Object Type Description
    id
    required
    string Unique ID for the payment that generated randomly by system
    fixed_payment_code_id
    required
    string Unique ID for the fixed payment code which you provided upon request
    fixed_payment_code_payment_id
    required
    string Unique ID for the payment paid by end-cusotmer with provided payment code
    payment_code
    required
    string The code given to end-customer for making payments
    retail_outlet_name
    required
    string The name of the Retail Outlets
    e.g. ALFAMART and INDOMARET
    amount
    required
    integer positive The amount that is paid by end customer
    status
    required
    string Status of the payment.

    Possible values:
  • COMPLETED This status is if the transaction has been successful and the settlement process has been completed.
  • SETTLING This status is if the transaction has been successful and is waiting for the settlement process.
  • owner_id
    required
    string Unique user ID of the merchant
    name
    required
    string Name for the fixed payment code
    prefix
    required
    string 3-6 characters that differentiate your fixed payment code from the others
    payment_id
    required
    string Our internal system’s payment ID that can be used as payment reference
    external_id
    required
    string An ID of your choice which you provided upon request
    transaction_timestamp
    required
    ISO 8601 Date The time when the payment was paid

    Timezone: UTC+0

    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
    DATA_NOT_FOUND
    404
    Could not find fixed payment code.

    Retail Outlets (OTC) - PH

    Retail Outlets (OTC) is a payment method allowing your end customer to make payments through one of our retail outlet partners throughout Philippines.

    End customers can visit any of our partners and inform the cashier of the merchant they are paying to, quote the unique payment code for the transaction, and make a payment in cash.

    Create Payment Code

    Endpoint: Create Payment Code

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

    Payment code allows your customers to make a payment through the branches of our partners.

    Provide the payment code to your customer, and receive a webhook once the payment has been made.

    Request Parameters

    Example Create Payment Code Request

    curl https://api.xendit.co/payment_codes -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -d reference_id=demo_payment_code_123 \
       -d channel_code=7ELEVEN \
       -d customer_name='Rika Sutanto' \
       -d amount=50
       -d currency=PHP
       -d market=PH
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $params = [
        'reference_id' => 'demo_payment_code_123',
        'channel_code' => '7ELEVEN',
        'customer_name' => 'Rika Sutanto',
        'amount' => 50
        'currency' => 'PHP'
        'market' => 'PH'
      ];
    
      $createFPC = \Xendit\RegionalRetailOutlet::create($params);
      var_dump($createFPC);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { RegionalRetailOutlet } = x;
    const retailOutletSpecificOptions = {};
    const ro = new RegionalRetailOutlet(retailOutletSpecificOptions);
    
    const resp = await ro.createPaymentCode({
      referenceId: 'demo_payment_code_123',
      channelCode: '7ELEVEN',
      customerName: 'Rika Sutanto',
      amount: 50,
      currency: 'PHP',
      market: 'PH'
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Map<String, Object> params = new HashMap<>();
      params.put("reference_id", "demo_payment_code_123");
      params.put("channel_code", "7ELEVEN");
      params.put("customer_name", "Rika Sutanto");
      params.put("amount", 50);
      params.put("currency", "PHP");
      params.put("market", "PH");
    
      FixedPaymentCode fpc = RegionalRetailOutlet.createPaymentCode(params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := regionalRetailoutlet.CreatePaymentCodeParams{
      ReferenceId:  "demo_payment_code_123",
      ChannelCode:  xendit.RetailOutletName7eleven,
      CustomerName: "Rika Sutanto",
      Amount:       50,
      Currency:     "PHP",
      Market:       "PH"
    }
    
    resp, err := regionalRetailoutlet.CreatePaymentCode(&data)
    if err != nil {
      log.Fatal(err.ErrorCode)
    }
    
    fmt.Printf("created retail outlet payment code: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    RegionalRetailOutlet = xendit_instance.RegionalRetailOutlet
    
    regional_retail_outlet = RegionalRetailOutlet.create_payment_code(
        reference_id="demo_fixed_payment_code_123",
        channel_code="7ELEVEN",
        customer_name="Rika Sutanto",
        amount=50,
        currency="PHP",
        market="PH"
    )
    print(regional_retail_outlet)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    RetailOutletClient retailOutlet = xendit.RetailOutlet;
    
    CreateFixedPaymentCodeParameter parameter = new CreateFixedPaymentCodeParameter
    {
      ReferenceId = "demo_payment_code_id",
      ChannelCode = RetailOutletEnum.ChannelCode.SevenEleven,
      CustomerName = "Rika Sutanto",
      Amount = 50,
      Currency = Currency.PHP,
      Market = Country.Philippines,
      PaymentCode = "12345678",
      Description = "Example payment code",
    };
    
    FixedPaymentCode fixedPaymentCode = await retailOutlet.CreatePaymentCode(parameter);

    JSON

    {
      "reference_id": "123",
      "channel_code": "7ELEVEN",
      "customer_name": "Rika Sutanto",
      "amount": 50,
      "currency": "PHP",
      "market": "PH"
    }
    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-split-rule
    optional
    string Split Rule ID that you would like to apply to this OTC payment code in order to split and route payments to multiple accounts.

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

    If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

    Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information.
    Body Parameter Type Description
    reference_id
    required
    string An ID of your choice. Often it is unique identifier like a phone number, email or transaction ID.

    Characters Special and alphanumeric
    Minimum length 1 character
    Maximum length 1000 characters
    channel_code
    required
    string Channel code of selected payment method.

    Available Channel Codes:
  • 7ELEVEN
  • 7ELEVEN_CLIQQ
  • CEBUANA
  • ECPAY
  • LBC


  • Integration via DragonPay:
  • DP_PALAWAN
  • DP_MLHUILLIER
  • DP_ECPAY_LOAN
  • DP_RD_PAWNSHOP
  • DP_CVM
  • DP_ECPAY_SCHOOL
  • DP_USSC

  • Note: You can use DP_ECPAY_LOAN and DP_ECPAY_SCHOOL to enable Gcash & Paymaya Bill Payment
    amount
    optional
    number The amount that is expected to be paid by end customer
  • the minimum is PHP 50 and the maximum is PHP 50,000 for 7ELEVEN
  • the minimum is PHP 100 and the maximum is PHP 50,000 for 7ELEVEN_CLIQQ
  • the minimum is PHP 50 and the maximum is PHP 30,000 for CEBUANA
  • the minimum is PHP 1 and the maximum is PHP 50,000 for ECPAY
  • the minimum is PHP 50 and the maximum is PHP 200,000 for LBC


  • Integration via DragonPay
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_PALAWAN
  • the minimum is PHP 50 and the maximum is PHP 200,000 for DP_MLHUILLIER
  • the minimum is PHP 50 and the maximum is PHP 50,000 for DP_ECPAY_LOAN
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_RD_PAWNSHOP
  • the minimum is PHP 50 and the maximum is PHP 30,000 for DP_CVM
  • the minimum is PHP 50 and the maximum is PHP 50,000 for DP_ECPAY_SCHOOL
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_USSC

  • Note:
  • amount is required if you want to create closed type payment code
  • For open type payment code, amount field can be empty or null
  • currency
    required
    string ISO 4217 Currency code

    Supported currency code: PHP
    customer_name
    required
    string Name of user - this might be used by the Retail Outlets cashier to validate the end user.

    Characters Only alphanumeric
    Special Characters: # / . " - , ' _ @ ( ) & ] [ :
    Minimum length 1 character
    Maximum length 250 characters
    market
    required
    string 2-letter ISO 3166-2 country code indicating country of transaction.

    Supported market: PH
    payment_code
    optional
    string The payment code that you want to assign, e.g 12345. If you do not send one, one will be picked at random.

    You do not need to include prefix to create a payment code. For example: You want to create payment code PSTEST12345A and your prefix is PSTEST , you can only fill 12345A in this field. Lower case value will be automatically converted to upper case in the API response

    Note: 7ELEVEN does not support custom payment_code, you cannot use this parameter for 7ELEVEN
    default: 8 random alphanumeric characters (e.g. PSTESTABCD1234)

    Minimum 11 and maximum 20 character limit for payment_code including prefix
  • DP_ECPAY_LOAN
  • DP_ECPAY_SCHOOL
  • DP_MLHUILLIER
  • DP_PALAWAN
  • DP_USSC
  • DP_RD_PAWNSHOP
  • DP_CVM
  • ROBINSONS_BILLS
  • SM_BILLS
  • expires_at
    optional
    ISO 8601 Date The time when the payment code will be expired.
  • the minimum is 2 hours and the maximum is 9 days for 7ELEVEN

  • timezone: UTC+0
    default: The expired date will be 2 days from payment code generated
    is_single_use
    optional
    boolean When set to false, the payment code will be a multiple use payment code and active after it is paid.

    Channel code that supports multiple use:
  • 7ELEVEN_CLIQQ
  • CEBUANA
  • ECPAY
  • LBC
  • DP_ECPAY_LOAN
  • DP_RD_PAWNSHOP
  • DP_CVM
  • DP_ECPAY_SCHOOL
  • DP_USSC

  • default: true
    description
    optional
    string Description of the payment code.

    Minimum length 1 character
    Maximum length 250 characters
    metadata
    optional
    object Object of additional key-value pairs that the merchants may use like internal system parameters (business ID, shopping cart). 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.
    Otherwise NULL

    Response Parameters

    Example Create Payment Code Response

    {
        "id": "pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1",
        "business_id": "5f21361959ef2b788cbbe97f",
        "reference_id": "demo_payment_code_123",
        "customer_name": "Rika Sutanto",
        "payment_code": "TESTABCD1234",
        "currency": "PHP",
        "amount": 50,
        "channel_code": "7ELEVEN_CLIQQ",
        "description": "Test payment code",
        "is_single_use": true,
        "market": "PH",
        "status": "ACTIVE",
        "metadata": null,
        "created_at": "2021-01-01T02:38:01Z",
        "updated_at": "2021-01-01T02:38:01Z",
        "expires_at": "2021-05-30T02:38:01Z"
    }
    Parameter Type Description
    id
    required
    string Unique ID for the payment code that generated randomly by system.
    business_id
    required
    string Your Xendit business ID.
    reference_id
    required
    string An ID of your choice which you provided upon request.
    customer_name
    required
    string Name of customer.
    payment_code
    required
    string Complete payment code (including prefix). This is what a user will need to tell Retail Outlets cashier or show via barcode page.
    currency
    required
    string ISO 4217 Currency code

    Supported currency code: PHP
    amount
    optional
    number The amount that is expected to be paid by end customer
  • the minimum is PHP 50 and the maximum is PHP 50,000 for 7ELEVEN
  • the minimum is PHP 100 and the maximum is PHP 50,000 for 7ELEVEN_CLIQQ
  • the minimum is PHP 50 and the maximum is PHP 30,000 for CEBUANA
  • the minimum is PHP 1 and the maximum is PHP 50,000 for ECPAY
  • the minimum is PHP 50 and the maximum is PHP 200,000 for LBC


  • Integration via DragonPay
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_PALAWAN
  • the minimum is PHP 50 and the maximum is PHP 200,000 for DP_MLHUILLIER
  • the minimum is PHP 50 and the maximum is PHP 50,000 for DP_ECPAY_LOAN
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_RD_PAWNSHOP
  • the minimum is PHP 50 and the maximum is PHP 30,000 for DP_CVM
  • the minimum is PHP 50 and the maximum is PHP 50,000 for DP_ECPAY_SCHOOL
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_USSC
  • description
    required
    string Description of the payment code.
    is_single_use
    required
    boolean Value that determines whether a payment code will be inactive after it is paid or not.
    market
    required
    string 2-letter ISO 3166-2 country code indicating country of transaction.

    Supported market: PH
    status
    required
    string Status of the payment code.

    Possible values:
  • ACTIVE
  • INACTIVE
  • metadata
    required
    object Object of additional key-value pairs that the merchants may use like internal system parameters (business ID, shopping cart). 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.
    Otherwise NULL
    created_at
    required
    ISO 8601 Date The time when the payment code was created.

    timezone: UTC+0
    updated_at
    required
    ISO 8601 Date The time when the payment code was updated.

    timezone: UTC+0
    expires_at
    required
    ISO 8601 Date The time when the payment code will be expired.

    timezone: UTC+0

    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.
    CHANNEL_CODE_NOT_SUPPORTED
    400
    The Retail Outlets is not currently supported.
    Please contact Xendit customer support to resolve this issue
    DUPLICATE_ERROR
    400
    The payment code that you want to create already exist.
    Please use a different payment code.
    EXPIRATION_DATE_INVALID_ERROR
    400
    Invalid custom expiration date because it's earlier than current time.
    Update expires_at value, must be a date in the future.
    DATA_NOT_FOUND_ERROR
    404
    Retail outlet merchant not found.
    Please contact Xendit customer support to resolve this issue
    GENERATION_ERROR
    503
    Error occurred while generating payment code. This can be caused by an unspecified error by the channel - but not due to channel downtime.

    Update Payment Code

    Endpoint: Update Payment Code

    PATCH https://api.xendit.co/payment_codes/{payment_code_id}

    Payment Code is so adaptable, and it's all based on your needs. Therefore, we provide you this endpoint to easily update your payment code as you like.

    Request Parameters

    Example Update Payment Code Request

    curl https://api.xendit.co/payment_codes/{payment_code_id} -X PATCH \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -d amount=100
       -d currency=PHP
       -d customer_name='Lorem Ipsum'
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $id = 'pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1';
      $updateParams = [
        'amount' => 100,
        'currency' => 'PHP',
        'customer_name' => 'Lorem Ipsum'
      ];
    
      $updatedPaymentCode = \Xendit\RegionalRetailoutlet::update($id, $updateParams);
      var_dump($updatedPaymentCode);
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { RegionalRetailOutlet } = x;
    const retailOutletSpecificOptions = {};
    const ro = new RegionalRetailOutlet(retailOutletSpecificOptions);
    
    const resp = await ro.updatePaymentCode({
      id: 'pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1',
      customer_name: 'Lorem Ipsum',
      amount: 100,
      currency: 'PHP',
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Map<String, Object> params = new HashMap<>();
      params.put("customer_name", "Lorem Ipsum");
    
      FixedPaymentCode fpc = RegionalRetailOutlet.updatePaymentCode("EXAMPLE_ID", params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    expirationDate := time.Now().AddDate(0, 0, 1)
    
    updatePaymentCodeData := regionalretailoutlet.UpdatePaymentCodeParams{
      PaymentCodeID:  "pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1",
      CustomerName:   "Lorem Ipsum",
      ExpectedAmount: 50,
      Currency:       "PHP"
    }
    
    resp, err := regionalretailoutlet.PaymentCode(&updatePaymentCodeData)
    if err != nil {
      log.Fatal(err.ErrorCode)
    }
    fmt.Printf("updated retail outlet payment code: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    RegionalRetailOutlet = xendit_instance.RegionalRetailOutlet
    
    retail_outlet = RegionalRetailOutlet.update_payment_code(
        payment_code_id="pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1",
        customer_name="Lorem Ipsum",
        amount=100,
        currency="PHP"
    )
    print(retail_outlet)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    RetailOutletClient retailOutlet = xendit.RetailOutlet;
    
    UpdateFixedPaymentCodeParameter parameter = new UpdateFixedPaymentCodeParameter
    {
      CustomerName = "Rika Sutanto",
      Amount = 100,
      Currency = Currency.PHP,
      Description = "Example updated payment code",
    };
    
    FixedPaymentCode fixedPaymentCode = await retailOutlet.UpdatePaymentCode(parameter, "pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1");

    JSON

    {
      "amount": 100,
      "currency": "PHP",
      "customer_name": "Lorem Ipsum"
    }
    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
    customer_name
    optional
    string Name of user - this might be used by the Retail Outlets cashier to validate the end user.

    Characters Only alphanumeric
    Minimum length 1 character
    Maximum length 250 characters
    amount
    optional
    number The amount that is expected to be paid by end customer
  • the minimum is PHP 50 and the maximum is PHP 50,000 for 7ELEVEN
  • the minimum is PHP 100 and the maximum is PHP 50,000 for 7ELEVEN_CLIQQ
  • the minimum is PHP 50 and the maximum is PHP 30,000 for CEBUANA
  • the minimum is PHP 1 and the maximum is PHP 50,000 for ECPAY
  • the minimum is PHP 50 and the maximum is PHP 200,000 for LBC


  • Integration via DragonPay
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_PALAWAN
  • the minimum is PHP 50 and the maximum is PHP 200,000 for DP_MLHUILLIER
  • the minimum is PHP 50 and the maximum is PHP 50,000 for DP_ECPAY_LOAN
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_RD_PAWNSHOP
  • the minimum is PHP 50 and the maximum is PHP 30,000 for DP_CVM
  • the minimum is PHP 50 and the maximum is PHP 50,000 for DP_ECPAY_SCHOOL
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_USSC
  • currency
    optional
    string ISO 4217 Currency code

    Supported currency code: PHP
    expires_at
    optional
    ISO 8601 Date The time when the payment code will be expired. You can set it to be days in the past to expire payment code immediately

    updating of expiration days is not allowed for 7ELEVEN
    Timezone: UTC+0
    description
    optional
    string Description of the payment code.

    Minimum length 1 character
    Maximum length 250 characters

    Response Parameters

    Example Update Payment Code Response

    {
        "id": "pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1",
        "business_id": "5f21361959ef2b788cbbe97f",
        "reference_id": "demo_payment_code_123",
        "customer_name": "Rika Sutanto",
        "payment_code": "TEST906558",
        "currency": "PHP",
        "amount": 50,
        "channel_code": "7ELEVEN",
        "description": "Test payment code",
        "is_single_use": true,
        "market": "PH",
        "status": "ACTIVE",
        "metadata": null,
        "created_at": "2021-01-01T02:38:01Z",
        "updated_at": "2021-01-01T02:38:01Z",
        "expires_at": "2021-05-30T02:38:01Z"
    }
    Parameter Type Description
    id
    required
    string Unique ID for the payment code that generated randomly by system.
    business_id
    required
    string Your Xendit business ID.
    reference_id
    required
    string An ID of your choice which you provided upon request.
    customer_name
    required
    string Name of customer.
    payment_code
    required
    string Complete payment code (including prefix). This is what a user will need to tell Retail Outlets cashier or show via barcode page.
    currency
    required
    string ISO 4217 Currency code

    Supported currency code: PHP
    amount
    optional
    number The amount that is expected to be paid by end customer
  • the minimum is PHP 50 and the maximum is PHP 50,000 for 7ELEVEN
  • the minimum is PHP 100 and the maximum is PHP 50,000 for 7ELEVEN_CLIQQ
  • the minimum is PHP 50 and the maximum is PHP 30,000 for CEBUANA
  • the minimum is PHP 1 and the maximum is PHP 50,000 for ECPAY
  • the minimum is PHP 50 and the maximum is PHP 200,000 for LBC


  • Integration via DragonPay
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_PALAWAN
  • the minimum is PHP 50 and the maximum is PHP 200,000 for DP_MLHUILLIER
  • the minimum is PHP 50 and the maximum is PHP 50,000 for DP_ECPAY_LOAN
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_RD_PAWNSHOP
  • the minimum is PHP 50 and the maximum is PHP 30,000 for DP_CVM
  • the minimum is PHP 50 and the maximum is PHP 50,000 for DP_ECPAY_SCHOOL
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_USSC
  • channel_code
    required
    string Name of the Retail Outlets.
    e.g. 7ELEVEN, 7ELEVEN_CLIQQ, CEBUANA, ECPAY, LBC, DP_PALAWAN, DP_MLHUILLIER, DP_ECPAY_LOAN, DP_RD_PAWNSHOP, DP_CVM, DP_ECPAY_SCHOOL, and DP_USSC
    description
    required
    string Description of the payment code.
    is_single_use
    required
    boolean Value that determines whether a payment code will be inactive after it is paid or not.
    market
    required
    string 2-letter ISO 3166-2 country code indicating country of transaction.

    Supported market: PH
    status
    required
    string Status of the payment code.

    Possible values:
  • ACTIVE
  • INACTIVE
  • EXPIRED
  • metadata
    required
    object Object of additional key-value pairs that the merchants may use like internal system parameters (business ID, shopping cart). 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.
    Otherwise NULL
    created_at
    required
    ISO 8601 Date The time when the payment code was created.

    timezone: UTC+0
    updated_at
    required
    ISO 8601 Date The time when the payment code was updated.

    timezone: UTC+0
    expires_at
    required
    ISO 8601 Date The time when the payment code will be expired.

    timezone: UTC+0

    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.
    DATA_NOT_FOUND_ERROR
    404
    Provided payment code 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 Payment Code

    Endpoint: Get Payment Code

    GET https://api.xendit.co/payment_codes/{payment_code_id}

    Example Get Payment Code Request

    curl https://api.xendit.co/payment_codes/{payment_code_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 = '5b61881e6cc2770f00117f73';
    
      $getFPC = \Xendit\Retail::retrieve($id);
      var_dump($getFPC);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { RegionalRetailOutlet } = x;
    const retailOutletSpecificOptions = {};
    const ro = new RegionalRetailOutlet(retailOutletSpecificOptions);
    
    const resp = await ro.getPaymentCode({
      id: 'pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1',
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      PaymentCode fpc = RegionalRetailOutlet.getPaymentCode("EXAMPLE_ID");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    getPaymentCodeData := regionalretailoutlet.GetPaymentCodeParams{
      PaymentCodeID: "pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1",
    }
    
    resp, err := regionalretailoutlet.GetPaymentCode(&getPaymentCodeData)
    if err != nil {
      log.Fatal(err.ErrorCode)
    }
    
    fmt.Printf("retrieved retail outlet payment code: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    RegionalRetailOutlet = xendit_instance.RegionalRetailOutlet
    
    retail_outlet = RegionalRetailOutlet.get_payment_code(
        payment_code_id="5ef2f0f8e7f5c14077275493",
    )
    print(retail_outlet)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    RetailOutletClient retailOutlet = xendit.RetailOutlet;
    
    FixedPaymentCode fixedPaymentCode = await retailOutlet.GetPaymentCode("5ef2f0f8e7f5c14077275493");

    Sometimes, you need to know the detail for your payment code. This endpoint can be used to get the latest details from your payment code

    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_code_id
    required
    string ID of the payment code to retrieve

    Response Parameters

    Example Get Payment Code Response

    {
        "id": "pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1",
        "business_id": "5f21361959ef2b788cbbe97f",
        "reference_id": "demo_payment_code_123",
        "customer_name": "Rika Sutanto",
        "payment_code": "TEST906558",
        "currency": "PHP",
        "amount": 50,
        "channel_code": "7ELEVEN",
        "description": "Test payment code",
        "is_single_use": true,
        "market": "PH",
        "status": "ACTIVE",
        "metadata": null,
        "created_at": "2021-01-01T02:38:01Z",
        "updated_at": "2021-01-01T02:38:01Z",
        "expires_at": "2021-05-30T02:38:01Z"
    }
    Parameter Type Description
    id
    required
    string Unique ID for the payment code that generated randomly by system.
    business_id
    required
    string Your Xendit business ID.
    reference_id
    required
    string An ID of your choice which you provided upon request.
    customer_name
    required
    string Name of customer.
    payment_code
    required
    string Complete payment code (including prefix). This is what a user will need to tell Retail Outlets cashier or show via barcode page.
    currency
    optional
    string ISO 4217 Currency code

    Supported currency code: PHP
    amount
    optional
    number The amount that is expected to be paid by end customer
  • the minimum is PHP 50 and the maximum is PHP 50,000 for 7ELEVEN
  • the minimum is PHP 100 and the maximum is PHP 50,000 for 7ELEVEN_CLIQQ
  • the minimum is PHP 50 and the maximum is PHP 30,000 for CEBUANA
  • the minimum is PHP 1 and the maximum is PHP 50,000 for ECPAY
  • the minimum is PHP 50 and the maximum is PHP 200,000 for LBC


  • Integration via DragonPay
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_PALAWAN
  • the minimum is PHP 50 and the maximum is PHP 200,000 for DP_MLHUILLIER
  • the minimum is PHP 50 and the maximum is PHP 50,000 for DP_ECPAY_LOAN
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_RD_PAWNSHOP
  • the minimum is PHP 50 and the maximum is PHP 30,000 for DP_CVM
  • the minimum is PHP 50 and the maximum is PHP 50,000 for DP_ECPAY_SCHOOL
  • the minimum is PHP 50 and the maximum is PHP 20,000 for DP_USSC
  • description
    required
    string Description of the payment code.
    is_single_use
    required
    boolean Value that determines whether a payment code will be inactive after it is paid or not.
    market
    required
    string 2-letter ISO 3166-2 country code indicating country of transaction.

    Supported market: PH
    status
    required
    string Status of the payment code.

    Possible values:
  • ACTIVE
  • INACTIVE
  • EXPIRED
  • metadata
    required
    object Object of additional key-value pairs that the merchants may use like internal system parameters (business ID, shopping cart). 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.
    Otherwise NULL
    created_at
    required
    ISO 8601 Date The time when the payment code was created.

    timezone: UTC+0
    updated_at
    required
    ISO 8601 Date The time when the payment code was updated.

    timezone: UTC+0
    expires_at
    required
    ISO 8601 Date The time when the payment code will be expired.

    timezone: UTC+0

    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
    DATA_NOT_FOUND_ERROR
    404
    Could not find payment code.

    Get Payments By Payment Code ID

    Endpoint: Get Payments By Payment Code ID

    GET https://api.xendit.co/payment_codes/{payment_code_id}/payments

    Example Get Payments By Payment Code ID Request

    curl https://api.xendit.co/payment_codes/{payment_code_id}/payments -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 = '5b61881e6cc2770f00117f73';
    
      $getFPC = \Xendit\RegionalRetailOutlet::retrievePayments($id);
      var_dump($getFPC);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { RetailOutlet } = x;
    const retailOutletSpecificOptions = {};
    const ro = new RegionalRetailOutlet(retailOutletSpecificOptions);
    
    const resp = await ro.getPayments({
      id: 'pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1',
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      FixedPaymentCode fpc = RetailOutlet.getFixedPaymentCode("EXAMPLE_ID");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    getPaymentsData := regionalretailoutlet.GetPaymentsParams{
      PaymentCodeID: "pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1",
    }
    
    resp, err := retailoutlet.GetPayments(&getPaymentsData)
    if err != nil {
      log.Fatal(err.ErrorCode)
    }
    
    fmt.Printf("retrieved retail outlet payments: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    RegionalRetailOutlet = xendit_instance.RegionalRetailOutlet
    
    retail_outlet = RegionalRetailOutlet.get_payments(
        payment_code_id="pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1",
    )
    print(retail_outlet)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    RetailOutletClient retailOutlet = xendit.RetailOutlet;
    
    FixedPaymentCode[] fixedPaymentCodes = await retailOutlet.GetPaymentCode("pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1");

    Sometimes, you need to know the payments made for your payment code. This endpoint can be used to retrieve all payments that were made into a particular payment code.

    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_code_id
    required
    string ID of the payment code to retrieve payments made

    Response Parameters

    Example Get Payments By Payment Code ID Response

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

    {
        "id": "pymt-24f45c63-8cba-4aa8-a18c-1d6954c7fed2",
        "payment_code_id": "pcode-559bb2df-6ae7-4fb8-bc05-f17aa07aeae1",
        "payment_code": "TEST906558",
        "channel_code": "7ELEVEN",
        "currency": "PHP",
        "amount": 50,
        "status": "COMPLETED",
        "remarks": "payment simulation",
        "created": "2021-01-01T02:38:01Z",
        "updated": "2021-01-01T02:38:01Z",
    }
    Parameter Type Description
    id
    required
    string Unique ID for the payment that generated randomly by system.
    payment_code_id
    required
    string Unique ID for the payment code that generated randomly by system
    payment_code
    required
    string The code given to end-customer for making payments
    channel_code
    required
    string The name of the Retail Outlets
    e.g. 7ELEVEN, 7ELEVEN_CLIQQ, CEBUANA, ECPAY, LBC, DP_PALAWAN, DP_MLHUILLIER, DP_ECPAY_LOAN, DP_RD_PAWNSHOP, DP_CVM, DP_ECPAY_SCHOOL, and DP_USSC
    currency
    required
    string ISO 4217 Currency code

    Supported currency code: PHP
    amount
    optional
    number The amount that is paid by end customer
    status
    required
    string Status of the payment.

    Possible values:
  • COMPLETED
  • remarks
    required
    string Note from channel during payment
    created
    required
    ISO 8601 Date The time when the payment code was created

    timezone: UTC+0
    updated
    required
    ISO 8601 Date The time when the payment code was updated

    timezone: UTC+0

    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
    DATA_NOT_FOUND_ERROR
    404
    Could not find payment code.

    Payment Code Callback

    Endpoint: Payment Code Webhook

    POST https://yourcompany.com/fixed_payment_code_paid_webhook_url

    Xendit notifies your system upon successful payments via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

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

    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks

    Example Payment Code Payment webhook Request

    curl --include \
        --request POST \
        --url https://yourcompany.com/payment_code_paid_webhook_url \
        --header 'content-type: application/json' \
        --header 'x-callback-token: MuaJALKJSDK12LASHD123kSAKSDHzjahwUWjkasJSDSA12KSNAK21n==' \
        --data '{
      "id": "pymt-6858d71e-4bd3-4bcb-9cc4-200b34bcc86c",
      "amount": 50,
      "business_id": "5fce6c32b596a10b19aeebe2"
      "channel_code": "7ELEVEN",
      "country_code": "PH",
      "currency": "PHP",
      "event": "payment_code.payment",
      "created": "2021-05-27T11:50:37Z",
      "payment_code": "TEST123",
      "reference_id": "payment-code-14876410",
      "remarks": " ",
      "payment_code_id": "pcode-da9a68dd-d8eb-4cd3-ad30-87eade685c7f",
      "status": "COMPLETED"
    }'

    JSON

    {
      "event": "payment_code.payment",
      "id": "pymt-6858d71e-4bd3-4bcb-9cc4-200b34bcc86c",
      "reference_id": "payment-code-14876410",
      "business_id": "5fce6c32b596a10b19aeebe2",
      "payment_code_id": "pcode-da9a68dd-d8eb-4cd3-ad30-87eade685c7f",
      "channel_code": "7ELEVEN",
      "payment_code": "TEST123",
      "country_code": "PH",
      "currency": "PHP",
      "amount": 50,
      "status": "COMPLETED",
      "created": "2021-05-27T11:50:37Z",
      "remarks": " "
    }
    Body Parameter Type Description
    event
    required
    string Event that was made for the payment code

    Possible values:payment_code.payment
    id
    required
    string Unique identifier for this transaction
    reference_id
    required
    string An ID of your choice which you provided upon payment code creation
    business_id
    required
    string Your Xendit business ID
    payment_code_id
    required
    string Unique ID for the payment code
    channel_code
    required
    string Name for the relevant Retail Outlets.
    e.g. 7ELEVEN, 7ELEVEN_CLIQQ, CEBUANA, ECPAY, LBC, DP_PALAWAN, DP_MLHUILLIER, DP_ECPAY_LOAN, DP_RD_PAWNSHOP, DP_CVM, DP_ECPAY_SCHOOL, and DP_USSC
    payment_code
    required
    string Complete payment code (including prefix)
    country_code
    required
    string 2-letter ISO 3166-2 country code indicating country of transaction.

    Supported country code: PH
    currency
    required
    string ISO 4217 Currency code

    Supported currency code: PHP
    amount
    optional
    integer positive Nominal amount that is paid
    status
    required
    string Status of payment. Possible value(s): COMPLETED
    created
    required
    ISO 8601 Date Date time when transaction was created

    timezone: UTC+0
    remarks
    required
    string Note from channel during payment

    Payouts

    This Payouts API is an updated version of the existing Disbursements API product where users can send money at scale to all bank accounts & eWallets in Indonesia, Philippines, Thailand, Malaysia and Vietnam by using just a single endpoint.

    Users of the new Payouts API should be able to enjoy the existing disbursement services and any new channels or regions made available in the future without needing to do another integration.

    Payout Object

    Example of Payout Object

    {
        "id": "disb-1475459775872",
        "amount": 100,
        "channel_code": "ID_BCA",
        "currency": "IDR",
        "description": "Lotto Winner #12",
        "reference_id": "lotto-1482928194",
        "status": "ACCEPTED",
        "created": "2022-01-05T05:37:48.108Z",
        "updated": "2022-01-05T05:37:48.108Z",
        "estimated_arrival_time": "2022-01-05T05:52:48.106Z",
        "business_id": "5785e6334d7b410667d355c4",
        "channel_properties": {
            "account_number": "0000000000",
            "account_holder_name": "Michael Chen"
        },
        "receipt_notification": {
        "email_to": [
          "chen@example.co",
          "somebodyexample.co"
        ],
        "email_cc": [
          "somebodyexample.co",
          "somebodyexample.co"
        ],
        "email_bcc": [
          "somebodyexample.co",
          "somebodyexample.co"
        ]
      }
    }
    Parameter Type Description
    id
    required
    string Xendit-generated unique identifier for each payout

    Prefix: disb_
    amount
    required
    number Amount to be sent to the destination account. Should be a multiple of the minimum increment for the selected channel.

    For IDR currency, number should be integer
    For PHP currency, number can be up to 2 decimal places
    For VND currency, number should be integer
    For MYR currency, number can be up to 2 decimal places
    For THB currency, number can be up to 2 decimal places
    channel_code
    required
    string Channel code of selected destination bank, e-wallet or OTC channel.
    currency
    required
    string ISO 4217 Currency Code.
    description
    optional
    string Description to send with the payout. The recipient may see this e.g., in their bank statement (if supported) or in email receipts we send on your behalf.

    Characters Special and alphanumeric
    Maximum length 100 characters
    Minimum length 1 character
    reference_id
    required
    string A client defined payout identifier. This is the ID assigned to the payout on your system, such as a transaction or order ID. Does not need to be unique.

    Characters Special and alphanumeric
    Maximum length 255 characters
    Minimum length 1 character
    status
    required
    string Status of payout.

    The status in the response will always be ACCEPTED; meaning transfer is initiated but not yet completed by bank or e-wallet.

    The final status will be given in a callback.
    created
    required
    ISO8601 Timestamp when the payout request was made (in ISO 8601 format)

    Timezone UTC+0
    updated
    required
    ISO8601 Timestamp when the payout status was updated (in ISO 8601 format)

    Timezone UTC+0
    estimated_arrival_time
    optional
    ISO8601 Estimated time of arrival of funds in destination account (in ISO 8601 format)

    For OTC payouts: Estimated time that funds will be available for pick-up

    Timezone UTC+0
    failure_code
    optional
    string If the Payout failed, we include a failure code for more details on the failure.
    business_id
    required
    string Your Xendit Business ID
    channel_properties
    required
    object A container for properties associated with the chosen channel_code

    For digital channels (bank or e-wallet account)
    Individual detail child parameters
    Parameter Description
    account_holder_name
    required

    stringName of account holder as per the bank or e-wallet’s records. Needs to match the registered account name exactly.

    Characters Special and alphanumeric
    Maximum length 100 characters
    Minimum length 1 character
    account_number
    required

    stringAccount number of destination. Mobile numbers for e-wallet accounts.

    Characters Special and alphanumeric
    Maximum length 100 characters
    Minimum length 1 character
    For Philippines and Indonesia e-wallets, standard format should use prefix 0
    Indonesia 08XXYYYYZZZZ (ie: 081234567890)
    Philippines 0XXXYYYZZZZ (ie: 09171234567)
    account_type
    conditional
    enum Account type of the destination for currencies and channels that supports proxy transfers (ie: Using mobile number as account number)

    If you do not specify a value for this field, the default value is BANK_ACCOUNT

    Values

    For channel_code == MY_DUITNOW:
    MOBILE_NO
    NATIONAL_ID
    PASSPORT
    BUSINESS_REGISTRATION
    BANK_ACCOUNT

    For currency == THB:
    MOBILE_NO
    NATIONAL_ID
    BANK_ACCOUNT
    receipt_notification
    optional
    JSON Object containing email addresses to receive payout details upon successful payout. Maximum of three email addresses each.
    Individual detail child parameters
    Parameter Description
    email_to
    optional
    Array [string]
    Direct email recipients

    Maximum length 255 characters
    email_cc
    optional
    Array [string]
    CC-ed email recipients

    Maximum length 255 characters
    email_bcc
    optional
    Array [string]
    BCC-ed email recipients

    Maximum length 255 characters
    metadata
    optional
    Object Object of additional information you may use

    Create Payout

    Endpoint: Create Payout

    POST https://api.xendit.co/v2/payouts

    Request Parameters

    Example Create Payout Request

    Create payout request

    curl https://api.xendit.co/v2/payouts -X POST \
    -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
    --header 'Idempotency-key: some-unique-ref-for-request'
    --data-raw '{
      "reference_id": "lotto-1482928194",
      "channel_code": "ID_BCA",
      "channel_properties": {
        "account_number": "000000000099",
        "account_holder_name": "Michael Chen"
      },
      "amount": 1000,
      "description": "Lotto Winner #12",
      "currency": "IDR",
      "receipt_notification": {
        "email_to": [
          "chen@example.co",
          "somebody@example.co"
        ],
        "email_cc": [
          "somebody@example.co",
          "somebody@example.co"
        ],
        "email_bcc": [
          "somebody@example.co",
          "somebody@example.co"
        ]
      },
      "metadata": {
         "lotto_outlet": 24
      }
    }'
    Header Parameter Type Description
    Idempotency-key
    required
    string A unique key to prevent processing duplicate requests. Can be your reference_id or any GUID. Must be unique across development & production environments.

    Characters Special and alphanumeric
    Minimum length 1 character
    Maximum length 100 maximum 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

    Example of Create Payout Request to Bank

    {
        "reference_id": "sample-successful-create-idr-payout",
        "channel_code": "ID_BCA",
        "channel_properties": {
            "account_holder_name": "Test",
            "account_number": "0000000000"
        },
        "amount": 1000,
        "description": "Sample Successful Create IDR Payout",
        "currency": "IDR",
        "receipt_notification" : {
            "email_to": ["somebody@xendit.co"],
            "email_cc": ["somebody@xendit.co"]
        }
    }

    Example of Create Payout Request to eWallet

    {
        "reference_id": "sample-successful-create-php-payout",
        "channel_code": "PH_GCASH",
        "channel_properties": {
            "account_holder_name": "Test",
            "account_number": "0000000000"
        },
        "amount": 1.11,
        "description": "Sample Successful Create PHP Payout",
        "currency": "PHP",
        "receipt_notification" : {
            "email_to": ["somebody@xendit.co"],
            "email_cc": ["somebody@xendit.co"]
        }
    }

    Example of Create Payout Request with currency THB to a mobile number

    {
        "reference_id": "sample-successful-create-thb-payout",
        "channel_code": "TH_BAY",
        "channel_properties": {
            "account_holder_name": "Test",
            "account_number": "6612345678",
            "account_type": "MOBILE_NO"
        },
        "amount": 1.11,
        "description": "Sample Successful Create THB Payout",
        "currency": "THB",
        "receipt_notification" : {
            "email_to": ["somebody@xendit.co"],
            "email_cc": ["somebody@xendit.co"]
        }
    }
    Parameter Type Description
    reference_id
    required
    string A client defined payout identifier. This is the ID assigned to the payout on your system, such as a transaction or order ID. Does not need to be unique.

    Characters Special and alphanumeric
    Maximum length 255 characters
    Minimum length 1 character
    channel_code
    required
    string Channel code of destination bank, e-wallet or OTC channel. List of supported channels can be found here
    channel_properties
    required
    object A container for properties associated with the chosen channel_code

    Inputs for digital channels (bank or e-wallet account)
    Individual detail child parameters
    Parameter Description
    account_holder_name
    required
    stringName of account holder as per the bank or e-wallet’s records. Needs to match the registered account name exactly.

    Characters Special and alphanumeric
    Maximum length 100 characters
    Minimum length 1 character
    account_number
    required
    string Account number of destination. Mobile numbers for e-wallet accounts.

    Characters Special and alphanumeric
    Maximum length 100 characters
    Minimum length 1 character
    For Philippines and Indonesia e-wallets, standard format should use prefix 0
    Indonesia 08XXYYYYZZZZ (ie: 081234567890)
    Philippines 0XXXYYYZZZZ (ie: 09171234567)
    account_type
    conditional
    enum Account type of the destination for currencies and channels that supports proxy transfers (ie: Using mobile number as account number)

    If you do not specify a value for this field, the default value is BANK_ACCOUNT

    Values

    For channel_code == MY_DUITNOW:
    MOBILE_NO
    NATIONAL_ID
    PASSPORT
    BUSINESS_REGISTRATION
    BANK_ACCOUNT

    For currency == THB:
    MOBILE_NO
    NATIONAL_ID
    BANK_ACCOUNT
    amount
    required
    number Amount to be sent to the destination account. Should be a multiple of the minimum increment for the selected channel.

    For IDR currency, number should be integer
    For PHP currency, number can be up to 2 decimal places
    For VND currency, number should be integer
    For MYR currency, number can be up to 2 decimal places
    For THB currency, number can be up to 2 decimal places
    description
    optional
    string Description to send with the payout. The recipient may see this e.g., in their bank statement (if supported) or in email receipts we send on your behalf.

    Characters Special and alphanumeric
    Maximum length 100 characters
    Minimum length 1 character
    currency
    required
    string ISO 4217 Currency Code.
    receipt_notification
    optional
    array of object Object containing email addresses to receive payout details upon successful payout. Maximum of three email addresses each.
    Individual detail child parameters
    Parameter Description
    email_to
    optional
    Array[string]Direct email recipients

    Maximum length 255 characters
    email_cc
    optional
    Array[string]CC-ed email recipients

    Maximum length 255 characters
    email_bcc
    optional
    Array[string]BCC-ed email recipients

    Maximum length 255 characters
    metadata
    optional
    object Object of additional information you may use

    Response Parameters

    Example of Create Payout Response

    {
        "id": "disb-1475459775872",
        "amount": 1.11,
        "channel_code": "PH_GCASH",
        "currency": "PHP",
        "description": "Sample Successful Create PHP Payout",
        "reference_id": "sample-successful-create-php-payout",
        "status": "ACCEPTED",
        "created": "2022-01-05T05:37:48.108Z",
        "updated": "2022-01-05T05:37:48.108Z",
        "estimated_arrival_time": "2022-01-05T05:52:48.106Z",
        "business_id": "6018306aa16ad90cb3c43ba7",
        "channel_properties": {
            "account_number": "0000000000",
            "account_holder_name": "Test"
        },
        "receipt_notification": {
            "email_to": [
                "somebody@xendit.co"
            ],
            "email_cc": [
                "somebody@xendit.co"
            ]
        }
    }

    Returns Payout object with status 200

    Error Codes

    Example of payout error

    {
        "error_code": "DUPLICATE_ERROR",
        "message": "A payout with this idempotency key already exists. If you meant to execute a different request, please use another idempotency key."
    }
    Error Code Error Message
    DUPLICATE_ERROR
    400
    A payout with this idempotency key already exists. If you meant to execute a different request, please use another idempotency key.
    API_VALIDATION_ERROR
    400
    Should have required property “xxx”
    API_VALIDATION_ERROR
    400
    "amount” should have 2 decimal places or less
    API_VALIDATION_ERROR
    400
    “expires_at” should be at least 2 days from now and not exceeding 90 days
    CHANNEL_CODE_NOT_SUPPORTED
    400
    “channel_code” is not supported. See list of supported channel codes at the URL below.
    MINIMUM_TRANSFER_LIMIT_ERROR
    400
    "amount” is under the minimum amount supported for the channel. See amount limitations at the URL below.
    MAXIMUM_TRANSFER_LIMIT_ERROR
    400
    “amount” is more than the maximum amount supported for the channel. See amount limitations at the URL below.
    AMOUNT_INCREMENT_NOT_SUPPORTED
    400
    “amount” needs to be a multiple of the minimum increment supported by the channel.
    INVALID_API_KEY
    401
    API key format is invalid
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request
    SERVER_ERROR
    500
    Something unexpected, our devs have been notified to troubleshoot the issue

    Get Payout by ID

    Endpoint: Get Payout by id

    GET https://api.xendit.co/v2/payouts/:id

    This endpoint queries the current status of a payout. This is often used for checking the status of a transaction using the id from the Payout Object.

    Request Parameters

    Example Get Payout Request

    Get Payout by ID

    curl https://api.xendit.co/v2/payouts/disb-b57fff2d-9699-470b-9978-ac509c5b266c -X GET \
      -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
    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 Xendit Payout ID generated by [POST] /payouts/
    Prefix: disb-

    Response Parameters

    Example Get Payout Response

    {
        "id": "disb-1475459775872",
        "amount": 100,
        "channel_code": "ID_BCA",
        "currency": "IDR",
        "description": "Sample Failed Create Payout",
        "estimated_arrival_time": "2022-01-05T06:09:23.667Z",
        "failure_code": "TEMPORARY_TRANSFER_ERROR",
        "reference_id": "sample-failed-create-payout",
        "status": "FAILED",
        "created": "2022-01-05T05:54:23.670Z",
        "updated": "2022-01-05T05:54:35.680Z",
        "business_id": "5785e6334d7b410667d355c4",
        "channel_properties": {
            "account_number": "123456",
            "account_holder_name": "Test"
        }
    }

    Returns Payout object with status 200

    Error Codes

    Error Code Error Message
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key.
    DATA_NOT_FOUND
    404
    Could not find payout with the corresponding ID. Please try again with a valid ID.
    INVALID_API_KEY
    401
    API Key is invalid.

    Get Payouts by Reference ID

    Endpoint: Get Payouts by Reference ID

    GET https://api.xendit.co/v2/payouts?reference_id=:reference_id

    Retrieve all matching payouts with reference ID. Returns an array of matching Payout Object if a valid reference_id was provided. Returns an empty array if there is no payout corresponding to the reference_id.

    Request Parameters

    Example Get Payout Request

    Get Payout by Reference ID

    curl https://api.xendit.co/v2/payouts?reference_id=lotto-1482928194&limit=10&after_id=disb-cc7cd9c0-1971-4414-9b54-be545948a33d&before_id=disb-69d8e2ba-20f9-41af-bd04-e299237fd7ec -X GET \
      -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
    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
    reference_id
    required
    string The reference_id you provided in the Create Payout request
    limit
    optional
    number A limit on the number of objects that will be returned

    Default 10
    Min 1
    Max 100
    after_id
    optional
    UUID ID of the immediately previous item
    before_id
    optional
    UUID ID of the immediately following item

    Response Parameters

    Example Get Payout Response

    [  
      {
        "id": "disb-1475459775872",
        "amount": 100,
        "channel_code": "ID_BCA",
        "currency": "IDR",
        "description": "Sample Failed Create Payout",
        "estimated_arrival_time": "2022-01-05T06:09:23.667Z",
        "failure_code": "TEMPORARY_TRANSFER_ERROR",
        "reference_id": "sample-failed-create-payout",
        "status": "FAILED",
        "created": "2022-01-05T05:54:23.670Z",
        "updated": "2022-01-05T05:54:35.680Z",
        "business_id": "5785e6334d7b410667d355c4",
        "channel_properties": {
            "account_number": "123456",
            "account_holder_name": "Test"
        }
    },
      {
        "id": "disb-567845975142",
        "amount": 200,
        "channel_code": "ID_BCA",
        "currency": "IDR",
        "description": "Sample Failed Create Payout2",
        "estimated_arrival_time": "2022-01-05T06:14:23.667Z",
        "failure_code": "TEMPORARY_TRANSFER_ERROR",
        "reference_id": "sample-failed-create-payout2",
        "status": "FAILED",
        "created": "2022-01-05T05:58:23.670Z",
        "updated": "2022-01-05T05:58:35.680Z",
        "business_id": "5785e6334d7b410667d355c4",
        "channel_properties": {
            "account_number": "123456",
            "account_holder_name": "Test"
        }
    }
    
    ]

    Returns array of Payout object sorted by created time in descending order with HTTP status code 200. “data” will be an empty array and “has_more” equal to false when there are no match data

    Parameter Type Description
    data
    required
    array Array of Payout object that match the reference_id. Will be sorted by created time in descending order.
    has_more
    required
    boolean Indicates whether there are more items to be queried with after_id of the last item from current result
    links
    optional
    array HATEOAS implementation on after_id field
    Individual detail child parameters
    Parameter Description
    href
    optional
    string
    Target URI that should contain a target to Internationalized Resource Identifiers (IRI)
    rel
    optional
    string
    The link relation type described how the current context (source) is related to target resource
    method
    optional
    string
    HTTP method attributes for target IRI
    ie. GET, POST, DELETE, etc

    Error Codes

    Error Code Message
    REQUEST_FORBIDDEN_ERROR 403 API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key.

    Cancel Payout

    Endpoint: Cancel Payout

    GET https://api.xendit.co/v2/payouts/:id/cancel

    This endpoint allows cancellation of requested payouts that have not yet been sent to partner banks and e-wallets.

    Note: Cancellation is possible if the payout has not been sent out via our partner

    Bank and e-wallet payouts: Cancellation is only allowed when status is ACCEPTED

    Request Parameters

    Example Cancel Payout Request

    Cancel Payout

    curl https://api.xendit.co/v2/payouts/disb-b57fff2d-9699-470b-9978-ac509c5b266c/cancel -X POST \
      -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
    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 Xendit Payout ID generated by [POST] /payouts/
    Prefix: disb-

    Response Parameters

    Example Cancel Payout Response

    
    {
        "id": "disb-1475459775872",
        "amount": 250000,
        "channel_code": "PH_CITI",
        "currency": "PHP",
        "description": "rewards",
        "reference_id": "test-rewards-001",
        "status": "CANCELLED",
        "created": "2022-01-16T12:11:22.233Z",
        "updated": "2022-01-16T12:21:31.373Z",
        "estimated_arrival_time": "2022-01-16T12:26:22.155Z",
        "business_id": "5785e6334d7b410667d355c4",
        "channel_properties": {
            "payout_code": "002912362381009082189137",
            "recipient_given_names": "Michael",
            "recipient_surname": "Chen",
            "expires_at": "2022-01-23T12:11:22.156Z"
        }
    }
    
    

    Returns Payout object with status 200 and status CANCELLED.

    Error Codes

    Error Code Error Message
    CANCELLATION_NOT_ALLOWED
    400
    Payout cannot be canceled because it has already been processed by Xendit.
    DATA_NOT_FOUND
    404
    Could not find payout with the corresponding ID. Please try again with a valid ID.

    Payout Webhook

    Endpoint: Payout Webhook

    POST https://yourcompany.com/payout_webhook_url

    Xendit notifies your system upon failed and successful payouts via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

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

    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks

    Example of Success Payout Webhook

    {
       "id":"disb-1b950430-kkk-44f0-q485-641bc450c59c",
       "amount":1.23,
       "status":"SUCCEEDED",
       "created":"2022-01-11T01:39:15.465Z",
       "updated":"2022-01-11T01:39:18.773Z",
       "currency":"PHP",
       "description":"V2 Regional Payout",
       "channel_code":"PH_GCASH",
       "reference_id":"Webhook-Automation-test-49a294eb-d664-423f-9ea5-476d8201c9d8",
       "account_number":"09991231877",
       "idempotency_key":"a029fc31-02ef-4c8b-b21d-af32ceed7321",
       "channel_category":"EWALLET",
       "account_holder_name":"Michael Chen",
       "connector_reference":"SIMULATED_PARTNER_REFERENCE_1665452357445_241",
       "receipt_notification":{
          "email_cc":[
             "mikechen@xendit.co"
          ]
       },
       "estimated_arrival_time":"2022-01-11T01:54:15.464Z"
    }

    Example of Failed Payout Webhook

    {
       "id":"disb-31ff90a0-d0fe-444c-9653-44d01cbf2a0e",
       "amount":1,
       "status":"FAILED",
       "created":"2022-01-11T01:39:21.074Z",
       "updated":"2022-01-11T01:39:24.139Z",
       "currency":"PHP",
       "description":"V2 Regional Payout",
       "channel_code":"PH_UBP",
       "failure_code":"INVALID_DESTINATION",
       "reference_id":"Webhook-Test-ab2cd787-05ab-4a2f-8a89-f3604384b9ea",
       "account_number":"121212",
       "idempotency_key":"01d6d000-bc20-4630-9e3f-68312ac2272e",
       "channel_category":"BANK",
       "account_holder_name":"Michael Chen",
       "estimated_arrival_time":"2022-01-11T01:54:21.073Z"
    }

    Payouts Failed/Completed

    Parameter Type Description
    event
    required
    string Type of the event. Possible events:
    payout.succeeded - A payout’s status has already succeeded and partner bank has credited the funds to the beneficiary

    payout.failed - A payout’s status has already failed and the partner bank rejected the transaction or there was an issue processing the transaction.

    payout.reversed - A payout that was originally in succeeded status received a bounceback or reversal of funds from the partner bank. Funds have been refunded back to the merchant’s available balance.
    business_id
    required
    string Xendit's unique business ID
    created
    required
    string ISO8601 timestamp of the event created time

    Timezone UTC+0
    Format: YYYY-MM-DDThh:mm:ssZ
    data
    required
    object Return Payout object with a specific status based on the payout processing result and the following event field

    Failure Codes

    Error Message Description Should you retry?
    INSUFFICIENT_BALANCE Client has insufficient balance for the payout amount Yes, retry the payout after ensuring that you have sufficient balance in your account.
    INVALID_DESTINATION Destination account does not exist/is invalid. You are unlikely to succeed if you retry the payout request. Please confirm with the beneficiary whether the destination account is correct
    REJECTED_BY_CHANNEL Payout failed due to an error from the destination channel. This is usually because of network issues associated with the destination bank or issues crediting funds into the destination bank account Yes, retry the payout after validating that the destination bank account number is active and can receive funds in your chosen currency.
    TEMPORARY_TRANSFER_ERROR The channel networks are experiencing a temporary error. Retry the payout in 1-3 hours. Yes, retry the payout in 1-3 hours.
    TRANSFER_ERROR We’ve encountered a fatal error while processing this payout. Normally, this means that certain API fields in your request are invalid. It is unlikely that the same disbursement request will succeed if you retry.
    UNKNOWN_BANK_NETWORK_ERROR The bank has delivered an error they have not documented. By definition, this means the bank does not know the issue. Unfortunately, we are unable to predict whether the disbursement will succeed should you retry the same disbursement request. You may however choose to retry the same disbursement request at least one hour after receiving our webhook at your own discretion.

    Get Payouts Channels

    Endpoint: Get Payouts Channels

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

    Example Get Payouts Channels Request

    curl https://api.xendit.co/payouts_channels?currency=PHP&channel_category=BANK -X GET \
      -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:

    This API endpoint will provide you the current list of banks and e-wallets we support for payouts for both regions. If you would like us to support payment to a specific destination, please contact us at support@xendit.co.

    Request Parameters

    Parameter Type Description
    currency
    optional
    string Filter by currency
    Values: IDR, PHP
    channel_category
    optional
    string Filter by channel_category
    Values: BANK, EWALLET, OTC
    channel_code
    optional
    string Filter by channel_code
    ie: ID_BSI, PH_AUB

    Response Parameters

    Get Payouts Channels (Banks) Response

    [
        {
            "channel_code": "ID_BSI",
            "channel_category": "BANK",
            "currency": "IDR",
            "channel_name": "Bank Syariah Indonesia",
            "amount_limits": {
                "minimum": 10000,
                "maximum": 1999999999999,
                "minimum_increment": 1
            }
        },
        {
            "channel_code": "PH_AUB",
            "channel_category": "BANK",
            "currency": "PHP",
            "channel_name": "Asia United Bank",
            "amount_limits": {
                "minimum": 1,
                "maximum": 100000000,
                "minimum_increment": 1
            }
        }
    ]

    Returns array of Payout Channel objects sorted by alphabetical order by channel_code with HTTP status code 200. Return empty array when not found.

    If query parameters are defined, returns a filtered list of Payout Channel objects matching the query parameter.

    Parameter Type Description
    channel_name string Name of payout channel
    channel_category string Type of payout destination
    Values: BANK, EWALLET, OTC
    channel_code string Channel code of destination bank, e-wallet or OTC channel. List of supported channels can be found here
    currency string Default currency of payout channel
    Currency Format: ISO 4217
    amount_limits object Object containing amount limitations imposed by the channel.
    Individual detail child parameters
    minimum
    number Minimum amount that can be paid out to this channel
    maximum
    number Maximum amount that can be paid out to this channel
    minimum_increment
    number Smallest amount increment allowed by the channel

    Disbursements

    Send money at scale to all bank accounts & eWallets in Indonesia using Xendit’s Disbursements. We currently support disbursements to 140+ local banks, virtual accounts of the biggest banks (BRI, BNI, Mandiri, CIMB Niaga, Permata, BTN, and NOBU Bank) and eWallets (e.g. Gopay, OVO, DANA, LinkAja & Shopee Pay). View all supported destination here.

    Disbursement Object

    Example of Disbursement Object

    {
      "id": "57f1ce05bb1a631a65eee662",
      "external_id": "disb-1475459775872",
      "user_id": "5785e6334d7b410667d355c4",
      "bank_code": "BCA",
      "account_holder_name": "MICHAEL CHEN",
      "amount": 90000,
      "disbursement_description": "Reimbursement for shoes",
      "status": "PENDING",
      "email_to": [
            "somebody@email.com"
        ],
        "email_cc": [
            "somebody.else@gmail.com"
        ],
        "email_bcc": [
            "someone@mail.co"
        ]
    }
    Parameter Type Description
    id
    required
    string Unique Xendit disbursement ID. Use this ID for support escalation and reconciliation
    external_id
    required
    string Custom ID of your choice to identify the transaction. Our customers often use a phone number, email address, or transaction/order ID
    user_id
    required
    string Your Xendit Business ID
    bank_code
    required
    string Destination bank or e-wallet. View all bank and e-wallet codes here
    account_holder_name
    required
    string Name of account holder as per the bank's or e-wallet’s records. Used for verification and error/customer support scenarios
    amount
    required
    number Amount to disburse
    disbursement_description
    required
    string Description to send with the disbursement
    status
    required
    string Status of the disbursement
    - PENDING Transfer is initiated but not yet completed by bank.
    - COMPLETED Bank has confirmed transmission of funds.
    - FAILED Disbursement failed because of failure code
    failure_code
    optional
    string INSUFFICIENT_BALANCE The balance in your account is insufficient to make the disbursement in the desired amount
    UNKNOWN_BANK_NETWORK_ERROR The bank networks have returned an unknown error to us. We are unable to predict whether the disbursement will succeed should you retry the same disbursement request.
    TEMPORARY_BANK_NETWORK_ERROR The bank networks are experiencing a temporary error. Please retry the disbursement in 1-3 hours
    INVALID_DESTINATION The banks have reported that the destination account is unregistered or blocked. If unsure about this, please retry again or contact the destination bank directly regarding the status of the destination account
    SWITCHING_NETWORK_ERROR At least one of the switching networks is encountering an issue. Please retry the disbursement in 1-3 hours
    REJECTED_BY_BANK The bank has rejected this transaction for unclear reasons. We are unable to predict whether the disbursement will succeed should you retry the same disbursement request.
    TRANSFER_ERROR We’ve encountered a fatal error while processing this disbursement. Certain API fields in your request may be invalid. Please contact our customer support team for more information
    TEMPORARY_TRANSFER_ERROR We’ve encountered a temporary issue while processing this disbursement. Please retry the disbursement in 1-2 hours

    For detailed information regarding the different error codes above, please see Common Errors in Disbursements.
    email_to
    optional
    array of string Email addresses that get notified of disbursement details after the disbursement is completed.
    This response parameter is only returned if this field is filled.
    email_cc
    optional
    array of string Email addresses that get notified as carbon copy receiver of disbursement details after the disbursement is completed.
    This response parameter is only returned if this field is filled.
    email_bcc
    optional
    array of string Email addresses that get notified as blind carbon copy receiver of disbursement details after the disbursement is completed.
    This response parameter is only returned if this field is filled.

    Create Disbursement

    Endpoint: Create Disbursement

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

    Request Parameters

    Example Create Disbursement Request

    curl https://api.xendit.co/disbursements -X POST \
      -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
      -d external_id=disb-1475459775872 \
      -d amount=90000 \
      -d bank_code=BCA \
      -d account_holder_name='MICHAEL CHEN' \
      -d account_number=1234567890 \
      -d description='Reimbursement for shoes'
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $params = [
        'external_id' => '12345',
        'amount' => 90000,
        'bank_code' => 'BCA',
        'account_holder_name' => 'MICHAEL CHEN',
        'account_number' => '1234567890',
        'description' => 'Disbursement from Example',
        'X-IDEMPOTENCY-KEY' => 'unique-id'
      ];
    
      $createDisbursements = \Xendit\Disbursements::create($params);
      var_dump($createDisbursements);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Disbursement } = x;
    const disbursementSpecificOptions = {};
    const d = new Disbursement(disbursementSpecificOptions);
    
    const resp = await d.create({
      externalID: 'disb-1475459775872',
      amount: 90000,
      bankCode: 'BCA',
      accountHolderName: 'MICHAEL CHEN',
      accountNumber: '1234567890',
      description: 'Reimbursement for shoes',
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Map<String, Object> params = new HashMap<>();
      params.put("external_id", "disb-1475459775872");
      params.put("bank_code", "BCA");
      params.put("account_holder_name", "MICHAEL CHEN");
      params.put("account_number", "1234567890");
      params.put("description", "Reimbursement for shoes");
      params.put("amount", "90000");
    
      Disbursement disbursement = Disbursement.create(params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    createData := disbursement.CreateParams{
      IdempotencyKey:    "disbursement" + time.Now().String(),
      ExternalID:        "12345",
      BankCode:          "BCA",
      AccountHolderName: "MICHAEL CHEN",
      AccountNumber:     "1234567890",
      Description:       "Disbursement from Go",
      Amount:            90000,
    }
    
    resp, err := disbursement.Create(&createData)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("created disbursement: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    Disbursement = xendit_instance.Disbursement
    
    disbursement = Disbursement.create(
        external_id="disb-1475459775872",
        bank_code="BCA",
        account_holder_name="MICHAEL CHEN",
        account_number="1234567890",
        description="Reimbursement for shoes",
        amount=90000,
    )
    print(disbursement)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    DisbursementClient disbursement = xendit.Disbursement;
    
    DisbursementParameter parameter = new DisbursementParameter
    {
      ExternalId = "disb-1475459775872",
      BankCode = DisbursementChannelCode.Bca,
      AccountHolderName = "MICHAEL CHEN",
      AccountNumber = "1234567890",
      Description = "Reimbursement for shoes",
      Amount = 1000,
    };
    
    DisbursementResponse disbursementResponse = await disbursement.Create(parameter);
    Header Parameter Type Description
    X-IDEMPOTENCY-KEY
    optional
    string A unique key to prevent processing duplicate requests. Can be your external_id or any GUID. Must be unique across development & production environments.

    Characters Special and alphanumeric
    Minimum length 1 character
    Maximum length No maximum 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

    Example of Create Disbursement Request to Bank

    {
       "external_id": "disb-{{$timestamp}}",
       "amount": 90000,
       "bank_code": "BCA",
       "account_holder_name": "MICHAEL CHEN",
       "account_number": "1234567890",
       "description":"Reimbursement for shoes"
    }

    Example of Create Disbursement Request to eWallet

    {
       "external_id": "disb-{{$timestamp}}",
       "amount": 90000,
       "bank_code": "OVO",
       "account_holder_name": "MICHAEL CHEN",
       "account_number": "081228271026",
       "description":"Reimbursement for shoes"
    }
    Body Parameter Type Description
    external_id
    required
    string ID of the disbursement in your system, used to reconcile disbursements after they have been completed.

    Characters Special and alphanumeric
    Minimum length 1 character
    Maximum length 1000 maximum characters
    bank_code
    required
    string Destination bank or e-wallet. View all bank and e-wallet codes here.
    account_holder_name
    required
    string Name of account holder as per the bank's or e-wallet's records. Used for verification and error/customer support scenarios.

    Characters Special and alphanumeric
    Minimum length 1 character
    Maximum length No maximum characters
    account_number
    required
    string Destination bank or e-wallet account number. If disbursing to an e-wallet, phone number registered with the e-wallet account.

    We support disbursements to virtual accounts of major banks (BRI, BNI, Mandiri, CIMB Niaga, Permata, BTN, and NOBU Bank).
    We support disbursements to major e-wallets (GoPay, OVO, Dana, Linkaja, and Shopeepay).


    Characters Numeric and hyphens
    BCA required length 10 characters
    Other banks minimum length 1 character
    Other banks maximum length No maximum characters
    E-wallets Phone number registered with the e-wallet (Example: 0812XXXXXX)
    description
    required
    string Description to send with the disbursement

    Characters Special and alphanumeric
    Minimum length 1 character
    Maximum length No maximum characters
    amount
    required
    number Amount to disburse. See maximum and minimum amount for each destination channel

    Characters Numerical integers, no decimals
    email_to
    optional
    array of string Email addresses that get notified of disbursement details after the disbursement is completed.
    Maximum 3 email addresses accepted.
    email_cc
    optional
    array of string Email addresses that get notified as carbon copy receiver of disbursement details after the disbursement is completed.
    Maximum 3 email addresses accepted.
    Only allowed if email_to provided.
    email_bcc
    optional
    array of string Email addresses that get notified as blind carbon copy receiver of disbursement details after the disbursement is completed.
    Maximum 3 email addresses accepted.
    Only allowed if email_to provided.

    Response Parameters

    Example of Create Disbursement Response

    {
      "id": "57f1ce05bb1a631a65eee662",
      "external_id": "disb-1475459775872",
      "user_id": "5785e6334d7b410667d355c4",
      "bank_code": "BCA",
      "account_holder_name": "MICHAEL CHEN",
      "amount": 90000,
      "disbursement_description": "Reimbursement for shoes",
      "status": "PENDING",
      "email_to": [
        "somebody@email.com"
      ],
      "email_cc": [
        "somebody.else@gmail.com"
      ],
      "email_bcc": [
        "someone@mail.co"
      ]
    }

    Returns Disbursement object with status 200

    Error Codes

    Example of disbursement error

    {
      "error_code": "BANK_CODE_NOT_SUPPORTED",
      "message": "Destination bank code is not supported. See https://docs.xendit.co/xendisburse/channel-codes for all supported channel 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.
    DISBURSEMENT_DESCRIPTION_NOT_FOUND_ERROR
    400
    Disbursement description is not set in Disbursement Settings in Xendit Dashboard. Add a default description before retrying.
    DIRECT_DISBURSEMENT_BALANCE_INSUFFICIENT_ERROR
    400
    Not enough balance to disburse. Add more balance before retrying.
    DUPLICATE_TRANSACTION_ERROR
    400
    Idempotency key has been used before. Use a unique idempotency key and try again.
    BANK_CODE_NOT_SUPPORTED_ERROR
    400
    Destination bank code is not supported. See all supported channel codes
    RECIPIENT_ACCOUNT_NUMBER_ERROR
    400
    For transfers to BCA, account_number input needs to be 10 digits. Check the account number length before retrying.
    RECIPIENT_AMOUNT_ERROR
    400
    The transfer amount requested is lower than the prescribed minimum for the chosen destination bank. Amend the transfer amount before retrying. See maximum and minimum amount for each destination channel
    MAXIMUM_TRANSFER_LIMIT_ERROR
    400
    The transfer amount requested is higher than the prescribed maximum for the chosen destination bank. Amend the transfer amount before retrying. See maximum and minimum amount for each destination channel
    INVALID_DESTINATION
    400
    The account number is unable to processed. Use different account number to retry.
    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
    SERVER_ERROR
    500
    Error connecting to our server. Use Get Disbursement API to check whether the disbursement has already been created. Retry safely using X-IDEMPOTENCY-KEY header

    Get Disbursement by ID

    Endpoint: Get Disbursement by id

    GET https://api.xendit.co/disbursements/{disbursement_id}

    This endpoint queries the current status of a disbursement. This is often used for checking the status of a transaction.

    Request Parameters

    Example Get Disbursement Request

    curl https://api.xendit.co/disbursements/57c9010f5ef9e7077bcb96b6 -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 = '57c9010f5ef9e7077bcb96b6';
      $getDisbursements = \Xendit\Disbursements::retrieve($id);
      var_dump($getDisbursements);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Disbursement } = x;
    const disbursementSpecificOptions = {};
    const d = new Disbursement(disbursementSpecificOptions);
    
    const resp = await d.getByID({ disbursementID: '587cc7ea77535fb94bb4e8eb' });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Disbursement disbursement = Disbursement.getById("EXAMPLE_ID");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    getByIDData := disbursement.GetByIDParams{
      DisbursementID: "57c9010f5ef9e7077bcb96b6",
    }
    
    resp, err := disbursement.GetByID(&getByIDData)
    if err != nil {
      log.Fatal(err.ErrorCode, err.Message, err.GetStatus())
    }
    
    fmt.Printf("retrieved disbursement: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    Disbursement = xendit_instance.Disbursement
    
    disbursement = Disbursement.get(
        id="5ef1befeecb16100179e1d05",
    )
    print(disbursement)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    DisbursementClient disbursement = xendit.Disbursement;
    
    DisbursementResponse disbursementResponse = await disbursement.GetById("5ef1befeecb16100179e1d05");
    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
    disbursement_id
    required
    string ID of the disbursement to retrieve
    The disbursement_id must match the unique disbursement ID provided in our success response at disbursement creation precisely

    Response Parameters

    Example Get Disbursement Response

    {
      "id": "57f1ce05bb1a631a65eee662",
      "external_id": "disb-1475459775872",
      "user_id": "5785e6334d7b410667d355c4",
      "bank_code": "BCA",
      "account_holder_name": "MICHAEL CHEN",
      "amount": 90000,
      "disbursement_description": "Reimbursement for shoes",
      "status": "PENDING",
      "email_to": [
        "somebody@email.com"
      ],
      "email_cc": [
        "somebody.else@gmail.com"
      ],
      "email_bcc": [
        "someone@mail.co"
      ]
    }

    Returns Disbursement object with status 200

    Error Codes

    Error Code Description
    INVALID_JSON_FORMAT
    400
    The request body is not a valid JSON format.
    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
    DIRECT_DISBURSEMENT_NOT_FOUND_ERROR
    404
    Could not find direct disbursement.

    Get Disbursements by External ID

    Endpoint: Get Disbursements by External ID

    GET https://api.xendit.co/disbursements?external_id={external_id}

    This endpoint queries the current status of all disbursements with requested external_id. This is often used to check the status of a transaction with external_id.

    Request Parameters

    Example Get Disbursement Request

    curl https://api.xendit.co/disbursements?external_id=72655 -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==');
    
      $external_id = 'disbursements-ext-id';
      $getDisbursementsByExt = \Xendit\Disbursements::retrieveExternal($external_id);
      var_dump($getDisbursementsByExt);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Disbursement } = x;
    const disbursementSpecificOptions = {};
    const d = new Disbursement(disbursementSpecificOptions);
    
    const resp = await d.getByExtID({ externalID: 'disbursement_12345' });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Disbursement[] disbursement = Disbursement.getByExternalId("EXAMPLE_ID");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    getByExternalIDData := disbursement.GetByExternalIDParams{
      ExternalID: "disbursement_12345",
    }
    
    resps, err := disbursement.GetByExternalID(&getByExternalIDData)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("retrieved disbursements: %+v\n", resps)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    Disbursement = xendit_instance.Disbursement
    
    disbursement_list = Disbursement.get_by_ext_id(
        external_id="demo_1475459775872",
    )
    print(disbursement_list)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    DisbursementClient disbursement = xendit.Disbursement;
    
    DisbursementResponse[] disbursementResponses = await disbursement.GetByExternalId("demo_1475459775872");
    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
    external_id
    required
    string Custom ID of the disbursement set by the customer at disbursement creation
    The external_id must match the external_id used at disbursement creation precisely

    Response Parameters

    Example Get Disbursement Response

    [
      {
        "id": "57f1ce05bb1a631a65eee662",
        "external_id": "disb-1475459775872",
        "user_id": "5785e6334d7b410667d355c4",
        "bank_code": "BCA",
        "account_holder_name": "MICHAEL CHEN",
        "amount": 90000,
        "disbursement_description": "Refunds for shoes",
        "status": "COMPLETED",
        "email_to": [
          "somebody@email.com"
        ],
        "email_cc": [
          "somebody.else@gmail.com"
        ],
        "email_bcc": [
          "someone@mail.co"
        ]
      },
      {
        "id": "57f12e1afb1a721a65efe715",
        "external_id": "disb-1475459775872",
        "user_id": "5785e6334d7b410667d355c4",
        "bank_code": "BCA",
        "account_holder_name": "MICHAEL CHEN",
        "amount": 90000,
        "disbursement_description": "Refunds for shoes",
        "status": "FAILED",
        "failure_code": "REJECTED_BY_BANK",
        "email_to": [
          "somebody@email.com"
        ],
        "email_cc": [
          "somebody.else@gmail.com"
        ],
        "email_bcc": [
          "someone@mail.co"
        ]
      }
    ]

    Returns array of Disbursement 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
    DIRECT_DISBURSEMENT_NOT_FOUND_ERROR
    404
    Could not find direct disbursement.

    Disbursement Callback

    Endpoint: Disbursement Webhook

    POST https://yourcompany.com/disbursement_webhook_url

    Xendit notifies your system upon failed and successful disbursements via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

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

    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks

    Example of Success Disbursement Webhook

    {
        "id": "57e214ba82b034c325e84d6e",
        "created": "2021-07-10T08:15:03.404Z",
        "updated": "2021-07-10T08:15:03.404Z",
        "external_id": "disbursement_123124123",
        "user_id": "57c5aa7a36e3b6a709b6e148",
        "amount": 150000,
        "bank_code": "BCA",
        "account_holder_name": "MICHAEL CHEN",
        "disbursement_description": "Refund for shoes",
        "status": "COMPLETED",
        "is_instant": true
    }

    Example of Failed Disbursement Webhook

    {
        "id": "57e214ba82b034c325e84d6e",
        "created": "2021-07-10T08:15:03.404Z",
        "updated": "2021-07-10T08:15:03.404Z",
        "external_id": "disbursement_123124123",
        "user_id": "57c5aa7a36e3b6a709b6e148",
        "amount": 150000,
        "bank_code": "BCA",
        "account_holder_name": "MICHAEL CHEN",
        "disbursement_description": "Refund for shoes",
        "status": "FAILED",
        "failure_code": "INVALID_DESTINATION",
        "is_instant": true
    }
    Body Parameter Type Description
    id string Unique Xendit disbursement ID. Use this ID for support escalation and reconciliation
    created string ISO 8601 timestamp of the disbursement creation. Timezone UTC+0
    updated string ISO 8601 timestamp of the last updated of the disbursement object. Timezone UTC+0
    external_id string Custom ID set at disbursement creation. Our customers often use a phone number, email address, or transaction/order ID
    user_id string Your Xendit Business ID
    bank_code string Destination bank or e-wallet. See bank codes
    account_number string Destination bank or e-wallet account number
    account_holder_name string Name of account holder as per the bank's or e-wallet's records.
    amount number Amount to disburse
    disbursement_description string Description to send with the disbursement
    status string COMPLETED Bank has confirmed transmission of funds.
    FAILED Disbursement failed because of failure code
    failure_code
    string INSUFFICIENT_BALANCE The balance in your account is insufficient to make the disbursement in the desired amount
    UNKNOWN_BANK_NETWORK_ERROR The bank networks have returned an unknown error to us. We are unable to predict whether the disbursement will succeed should you retry the same disbursement request.
    TEMPORARY_BANK_NETWORK_ERROR The bank networks are experiencing a temporary error. Please retry the disbursement in 1-3 hours
    INVALID_DESTINATION The banks have reported that the destination account is unregistered or blocked. If unsure about this, please retry again or contact the destination bank directly regarding the status of the destination account
    SWITCHING_NETWORK_ERROR At least one of the switching networks is encountering an issue. Please retry the disbursement in 1-3 hours
    REJECTED_BY_BANK The bank has rejected this transaction for unclear reasons. We are unable to predict whether the disbursement will succeed should you retry the same disbursement request.
    TRANSFER_ERROR We’ve encountered a fatal error while processing this disbursement. Certain API fields in your request may be invalid. Please contact our customer support team for more information
    TEMPORARY_TRANSFER_ERROR We’ve encountered a temporary issue while processing this disbursement. Please retry the disbursement in 1-2 hours

    For detailed information regarding the different error codes above, please see Common Errors in Disbursements.
    is_instant boolean Indicates whether the disbursement is being disbursed instantly

    Get Available Banks

    Endpoint: Get Available Disbursement Banks

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

    Example Get Available Disbursement Banks Request

    curl https://api.xendit.co/available_disbursements_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==');
    
      $getDisbursementsBanks = \Xendit\Disbursements::getAvailableBanks();
      var_dump($getDisbursementsBanks);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Disbursement } = x;
    const disbursementSpecificOptions = {};
    const d = new Disbursement(disbursementSpecificOptions);
    
    const resp = await d.getBanks();
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      AvailableBank[] banks = Disbursement.getAvailableBanks();        
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    availableBanks, err := disbursement.GetAvailableBanks()
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("available disbursement banks: %+v\n", availableBanks)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    Disbursement = xendit_instance.Disbursement
    
    disbursement_banks = Disbursement.get_available_banks()
    print(disbursement_banks)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    DisbursementClient disbursement = xendit.Disbursement;
    
    AvailableBank[] availableBanks = await disbursement.GetAvailableBanks();

    This API endpoint will provide you the current list of banks and e-wallets we support for disbursements. We support transfers to 140+ banks in Indonesia, including some BPDs and BPRs, and virtual accounts of major banks (BRI, BNI, Mandiri, CIMB Niaga, Permata, BTN, and NOBU Bank). We also support disbursements to major e-wallets (GoPay, OVO, Dana, Linkaja, and Shopeepay). If you would like us to support payment to a specific destination, please contact us at support@xendit.co.

    Response Parameters

    Get Available Disbursement Banks Response

    [
      {
        "name": "Bank Mandiri",
        "code": "MANDIRI",
        "can_disburse": true,
        "can_name_validate": true
      },
      {
        "name": "Bank Rakyat Indonesia (BRI)",
        "code": "BRI",
        "can_disburse": true,
        "can_name_validate": true
      },
      {
        "name": "Bank Central Asia (BCA)",
        "code": "BCA",
        "can_disburse": true,
        "can_name_validate": true
      }
    ]
    Parameter Type Description
    name string Full name of the bank or e-wallet
    code string Code of the bank or e-wallet you would like to disburse to

    Batch Disbursement

    Batch disbursements (beta) are a set of instructions containing multiple commands to disburse funds to any banks in Indonesia.

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

    Create Batch Disbursement

    With this API endpoint you can create multiple disbursements at the same time.

    Endpoint: Create Batch Disbursement

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

    Request Parameters (Money-out write permission)

    Example Create Batch Disbursement Request

    curl https://api.xendit.co/batch_disbursements -X POST \
      -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
      -H "Content-Type: application/json" \
      -d '{
        "reference": "demo_123",
        "disbursements": [
          {
            "external_id": "demo_123_1",
            "bank_code": "BCA",
            "bank_account_name": "Stanley Nguyen",
            "bank_account_number": "12345678",
            "description": "Reimbursement for pair of shoes (1)",
            "amount": 20000
          }
        ]
      }'
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $batch_params = [
        'reference' => 'qwerty1234',
        'disbursements' => [
          [
            'amount' => 20000,
            'bank_code' => 'BCA',
            'bank_account_name' => 'Fadlan',
            'bank_account_number' => '1234567890',
            'description' => 'Batch Disbursement',
            'external_id' => 'disbursement-1'
          ],
          [
            'amount' => 10000,
            'bank_code' => 'MANDIRI',
            'bank_account_name' => 'Lutfi',
            'bank_account_number' => '1234567891',
            'description' => 'Batch Disbursement with email notifications',
            'external_id' => 'disbursement-2',
            'email_to' => ['test+to@xendit.co'],
            'email_cc' => ['test+cc@xendit.co'],
            'email_bcc' => ['test+bcc1@xendit.co', 'test+bcc2@xendit.co']
          ]
        ]
      ];
    
      $createBatchDisbursements = \Xendit\Disbursements::createBatch($batch_params);
      var_dump($createBatchDisbursements);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Disbursement } = x;
    const disbursementSpecificOptions = {};
    const d = new Disbursement(disbursementSpecificOptions);
    
    const resp = await d.createBatch({
      reference: 'demo_123',
      disbursements: [
        {
          externalID: 'demo_123_1',
          bankCode: 'BCA',
          accountHolderName: 'Stanley Nguyen',
          accountNumber: '12345678',
          description: 'Reimbursement for pair of shoes (1)',
          amount: 20000,
        }
      ]
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      String emailTo[] = new String[1];
      emailTo[0] = "test@email.com";
    
      String emailCC[] = new String[1];
      emailCC[0] = "test@email.com";
    
      String emailBcc[] = new String[1];
      emailBcc[0] = "test@email.com";
    
      BatchDisbursementItem items[] = new BatchDisbursementItem[1];
    
      BatchDisbursementItem item =
            BatchDisbursementItem.builder()
                .amount(10000)
                .bankCode("ABC")
                .bankAccountName("Lorem Ipsum")
                .bankAccountNumber("1234567890")
                .description("Lorem ipsum dolor sit amet")
                .externalId("test_id")
                .emailTo(emailTo)
                .emailCC(emailCC)
                .emailBcc(emailBcc)
                .build();
    
      items[0] = item;
    
      BatchDisbursement.create(
        "reference", //reference
        items //BatchDisbursementItem []
      );
    
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    createBatchData := disbursement.CreateBatchParams{
      Reference: "batch_disbursement" + time.Now().String(),
      Disbursements: []disbursement.DisbursementItem{
        {
          Amount:            200000,
          BankCode:          "BNI",
          BankAccountName:   "Michael Jackson",
          BankAccountNumber: "1234567890",
          Description:       "Batch disbursement from Go",
        },
        {
          Amount:            100000,
          BankCode:          "BRI",
          BankAccountName:   "Michael Jackson",
          BankAccountNumber: "1234567890",
          Description:       "Batch disbursement from Go 2",
        },
      },
    }
    
    batchDisbursementResp, err := disbursement.CreateBatch(&createBatchData)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("created batch disbursement: %+v\n", batchDisbursementResp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    BatchDisbursement = xendit_instance.BatchDisbursement
    
    batch_disbursement_items = []
    batch_disbursement_items.append(
        BatchDisbursement.helper_create_batch_item(
            amount=10000,
            bank_code="BCA",
            bank_account_name="Adyaksa W",
            bank_account_number="12345678",
            description="Sample Batch Disbursement",
            external_id=f"batch-disbursement-item-12345"
        )
    )
    batch_disbursement = BatchDisbursement.create(
        reference="batch_disbursement-1595326225",
        disbursements=batch_disbursement_items,
    )
    print(batch_disbursement)
    Header Parameter Type Description
    X-IDEMPOTENCY-KEY
    optional
    string A unique key to prevent processing duplicate requests. Can be your external_id or any GUID. Must be unique across development & production environments.
    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
    required
    string ID of the batch disbursement in your system, used to reconcile disbursements after they have been completed
    disbursements
    required
    Disbursement Item[] List of disbursements in the batch

    Disbursement Item

    Parameter Type Description
    amount
    required
    number Amount to disburse
    bank_code
    required
    string Code of the receiving bank
    bank_account_name
    required
    string Receiving bank account holder name
    bank_account_number
    required
    string Receiving bank account number
    description
    required
    string Description to accompany the disbursement
    external_id
    optional
    string ID of disbursement in your system
    email_to
    optional
    string[] Email addresses that get notified of disbursement details after the disbursement is completed
    email_cc
    optional
    string[] Email addresses that get notified as carbon copy receiver of disbursement details after the disbursement is completed
    email_bcc
    optional
    string[] Email addresses that get notified as blind carbon copy receiver of disbursement details after the disbursement is completed

    Response Parameters

    Example Create Batch Disbursement Response

    {
      "created": "2017-03-30T06:12:47.212Z",
      "reference": "qwerty1234",
      "total_uploaded_amount": 30000,
      "total_uploaded_count": 2,
      "status": "UPLOADING",
      "id": "58dca1dffee4228917d37336"
    }
    Parameter Type Description
    created
    required
    string Timestamp of batch disbursement creation in ISO format
    reference
    required
    string ID of the batch disbursement in your system, used to reconcile disbursements after they have been completed
    total_uploaded_count
    required
    number The count of all disbursements in the batch
    total_uploaded_amount
    required
    number Total amount of all disbursements in the batch
    status
    required
    string UPLOADING Batch disbursement request is received and pending for items details to be populated and verified
    id
    required
    string Unique ID of batch disbursement in our system

    Error Codes

    Error Code Description
    API_VALIDATION_ERROR
    400
    Inputs has failed in validation. The errors field in the response will contain details about which fields are violating validation.
    INVALID_JSON_FORMAT
    400
    The request body is not a valid JSON format.
    DUPLICATE_TRANSACTION_ERROR
    400
    Request failed because idempotency key has been seen before.
    INVALID_API_KEY
    401
    Wrong API key is being used.
    BATCH_DISBURSEMENT_MAXIMUM_ROWS_LIMIT_EXCEEDED_ERROR
    400
    Request failed because the disbursements contain more than 1000 items.
    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

    Batch Disbursement Callback

    Endpoint: Disbursement Webhook

    POST https://yourcompany.com/disbursement_webhook_url

    Xendit notifies your system upon failed and successful payouts via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook Settings in Xendit Dashboard.

    After creating a batch disbursement via API, to receive a webhook, you must log into your Dashboard and do the following steps:

    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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

    Example of Batch Disbursements webhook payload

    {
        "id": "5a64e8217c077f576d926038",
        "created": "2021-01-21T19:21:05.982Z",
        "updated": "2021-01-21T19:21:42.297Z",
        "reference": "Test webhook BD",
        "user_id": "5a64e81d70dd16331f65cd61",
        "total_uploaded_count": 1,
        "total_uploaded_amount": 10000,
        "approved_at": "2021-01-21T19:21:16.853Z",
        "approver_id": "5a64e82070dd16331f65cd6d",
        "status": "COMPLETED",
        "total_disbursed_count": 1,
        "total_disbursed_amount": 10000,
        "total_error_count": 0,
        "total_error_amount": 0,
        "disbursements": [
            {
                "id": "5a64e8227c077f576d926039",
                "created": "2021-01-21T19:21:06.066Z",
                "updated": "2021-01-21T19:21:33.569Z",
                "external_id": "1",
                "amount": 10000,
                "bank_code": "PANIN",
                "bank_account_number": "8888888888",
                "bank_account_name": "Albert Chen Fadlan",
                "description": "Test webhook BD",
                "email_to": "disbursement_test_example@xendit.co",
                "status": "COMPLETED",
                "valid_name": "Albert Chen Fadlan",
                "bank_reference": "123456"
            }
        ]
    }
    Header Parameter Type Description
    x-callback-token
    required
    string Your Xendit unique webhook token to verify the origin of the webhook

    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    Parameter Type Description
    id string Unique ID of batch disbursement in our system
    created string Timestamp of batch disbursement creation in ISO format
    updated string Timestamp of the latest batch disbursement status change in ISO format
    reference string ID of the batch disbursement in your system, used to reconcile disbursements after they have been completed
    user_id string Your Xendit Business ID
    total_uploaded_count number The count of all disbursements in the batch that you requested
    total_uploaded_amount number Total amount of all disbursements in the batch that you requested
    approved_at string Timestamp of batch disbursement approved in ISO format
    approver_id string User ID of the person who approves the batch disbursement
    status string COMPLETED All disbursements are successfully paid
    CHECK Some disbursements are successfully paid
    DELETED Batch disbursement has been deleted
    FAILED All disbursements are not successfully paid
    total_disbursed_count number The count of all disbursements in the batch that are succesfully paid
    total_disbursed_amount number Total amount of all disbursements in the batch that are succesfully paid
    total_error_count number The count of all disbursements in the batch that are not successfully paid
    total_error_amount number Total amount of all disbursements in the batch that are not successfully paid
    disbursements array of Disbursement object Details of each disbursement in the batch, explained below

    Disbursement

    Parameter Type Description
    id string Unique ID of the batch disbursement item in our system
    created string Timestamp of batch disbursement item creation in ISO format
    updated string Timestamp of latest batch disbursement status update in ISO format
    external_id string ID of disbursement from your system
    amount number Amount to disburse
    bank_code string Receiving bank code. See bank codes
    bank_account_number string Receiving bank account number
    bank_account_name string Receiving bank account holder name
    description string Description to accompany the disbursement
    email_to string Email addresses that get notified of disbursement details after the disbursement is completed
    email_cc string Email addresses that get notified as carbon copy receiver of disbursement details after the disbursement is completed
    email_bcc string Email addresses that get notified as blind carbon copy receiver of disbursement details after the disbursement is completed
    status string COMPLETED Disbursement is successfully paid
    FAILED Disbursement is not successfully paid
    valid_name string Valid receiving account holder name according to receiving bank
    bank_reference string Transaction reference number from the bank
    failure_code string The error code associated with the failure of disbursement
    failure_message string The error message associated with the failure of disbursement

    Get Available Banks

    Endpoint: Get Available Disbursement Banks

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

    Example Get Available Disbursement Banks Request

    curl https://api.xendit.co/available_disbursements_banks -X GET \
        -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
    <?php
      require 'vendor/autoload.php';
    
      $options['secret_api_key'] = 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==';
    
      $xenditPHPClient = new XenditClient\XenditPHPClient($options);
    
      $response = $xenditPHPClient->getAvailableDisbursementBanks();
      print_r($response);
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Disbursement } = x;
    const disbursementSpecificOptions = {};
    const d = new Disbursement(disbursementSpecificOptions);
    
    const resp = await d.getBanks();
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      AvailableBank[] banks = BatchDisbursement.getAvailableBanks();
    } catch (XenditException e) {
      e.printStackTrace();
    }
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    Disbursement = xendit_instance.Disbursement
    
    disbursement_banks = Disbursement.get_available_banks()
    print(disbursement_banks)

    This API endpoint will provide you the current list of banks we support for disbursements. The current list of supported banks is >140 just for Indonesia, including some BPDs and BPRs.

    Response Parameters

    Get Available Disbursement Banks Response

    [
      {
        "name": "Bank Central Asia (BCA)",
        "code": "BCA"
      },
      {
        "name": "Bank Mandiri",
        "code": "MANDIRI"
      },
      {
        "name": "Bank Rakyat Indonesia (BRI)",
        "code": "BRI"
      }
    ]
    Parameter Type Description
    name string Full name of the bank
    code string Code of the bank, relevant during creation of virtual accounts

    Payout Links

    Previously called Payouts. Easily send funds to customers with our payouts links UI, allowing them to choose their payout destination.

    Endpoint: Create Payout Link

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

    Request Parameters

    Example Create Payout Link Request

    curl https://api.xendit.co/payouts -X POST \
    -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
    -d external_id=demo_2392329329 \
    -d amount=23000 \
    -d email=demo@xendit.co
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $params = [
        'external_id' => 'demo_2392329329',
        'amount' => 23000
      ];
    
      $createPayout = \Xendit\Payouts::create($params);
      var_dump($createPayout);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Payout } = x;
    const payoutSpecificOptions = {};
    const p = new Payout(payoutSpecificOptions);
    
    const resp = await p.createPayout({
      externalID: 'demo_2392329329',
      amount: 23000,
      email: 'demo@xendit.co'
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Map<String, Object> params = new HashMap<>();
      params.put("external_id", "demo_2392329329");
      params.put("amount", 23000);
      params.put("email", "demo@xendit.co");
    
      Payout payout = Payout.createPayout(params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    createData := payout.CreateParams{
      ExternalID: "demo_2392329329",
      Amount:     23000,
      Email: "test@email.com",
    }
    
    resp, err := payout.Create(&createData)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("created payout: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    Payout = xendit_instance.Payout
    
    payout = Payout.create(
        external_id="payout-1595405117",
        amount=50000,
        email="test@email.co",
    )
    print(payout)
    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 ID of your choice (typically the unique identifier of a payout in your system).

    Maximum: 200 characters
    amount
    required
    integer positive Amount to be paid out.

    Minimum: 10000
    Maximum: Balance in your account
    email
    required
    string An email address of the end user you're sending the payout link to.

    Response Parameters

    Example Create Payout Link Response

    {
      "id": "67f1b30c-0262-4955-8777-95aa0478c2fc",
      "external_id": "demo_2392329329",
      "amount": 23000,
      "merchant_name": "First Business",
      "status": "PENDING",
      "expiration_timestamp": "2019-12-12T06:13:21.637Z",
      "created": "2019-12-09T06:13:20.363Z",
      "payout_url": "https://payout.xendit.co/web/67f1b30c-0262-4955-8777-95aa0478c2fc"
    }
    Parameter Type Description
    id
    required
    string A payout link ID generated by Xendit
    external_id
    required
    string The payout link ID in your server, that can be used to reconcile between you and Xendit.

    Maximum: 200 characters
    amount
    required
    integer positive Amount to be paid out.

    Minimum: 10000
    Maximum: Balance in your account
    merchant_name
    optional
    string The name of your company or website.
    status
    required
    string PENDING The payout link has successfully been created and is awaiting the end user’s response
    VOIDED The payout link has been voided. This issue is raised because the payout link has been expired or manually voided by hitting the void endpoint.
    COMPLETED The payout has completed.
    FAILED The payout has failed. The list of failures are described in the failure_reason field.
    EXPIRED The payout has expired.
    expiration_timestamp
    optional
    ISO8601 An ISO timestamp that the payout link expires. Default is 3 days after creation.

    Timezone: GMT+0
    created
    optional
    ISO8601 An ISO timestamp that tracks when the payout link was created.

    Timezone: GMT+0
    payout_url
    optional
    string Public URL for this payout, in case you want to use our UI.
    email
    optional
    string An email address of the end user you're sending the payout link to.
    bank_code
    optional
    string Bank code for the relevant bank, learn more here
    account_holder_name
    optional
    string Bank account holder name.
    account_number
    optional
    string Bank account number.
    disbursement_id
    optional
    string ID of the disbursement. You can find out here
    failure_reason
    optional
    string If the status is FAILED, this describes the failure.
    claimed_timestamp
    optional
    ISO8601 An ISO timestamp that tracks when the payout was claimed.

    Timezone: GMT+0
    completed_timestamp
    optional
    ISO8601 An ISO timestamp that tracks when the payout was completed.

    Timezone: GMT+0
    failed_timestamp
    optional
    ISO8601 An ISO timestamp that tracks when the payout was failed.

    Timezone: GMT+0
    payment_id
    optional
    string Our internal system’s payment ID that can be used as payment reference.

    Error Codes

    Error Code Description
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    INSUFFICIENT_BALANCE
    400
    The balance in your account is insufficient to make the payout in the desired amount.
    DUPLICATE_PAYOUT_ERROR
    400
    The payout link with the same external_id has already been made before.
    UNAUTHORIZED_MERCHANT_ERROR
    403
    This merchant is not authorized to perform this request.

    Endpoint: Get a Payout Link

    GET https://api.xendit.co/payouts/:id

    Request Parameters

    Example Get Payout Link Request

    curl https://api.xendit.co/payouts/: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 = '00754a09-ad00-4475-b874-1dd97f83fc24';
    
      $getPayout = \Xendit\Payouts::retrieve($id);
      var_dump($getPayout);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Payout } = x;
    const payoutSpecificOptions = {};
    const p = new Payout(payoutSpecificOptions);
    
    const resp = await p.getPayout({
        id: '67f1b30c-0262-4955-8777-95aa0478c2fc',
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Payout payout = Payout.getPayout("my_test_id");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    resp, err := payout.Get(&payout.GetParams{
      ID: "00754a09-ad00-4475-b874-1dd97f83fc24",
    })
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("retrieved payout: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    Payout = xendit_instance.Payout
    
    payout = Payout.get(
        id="a6ee1bf1-ffcd-4bda-a7ab-99c1d5cd0472",
    )
    print(payout)
    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 payout link to retrieve

    Response Parameters

    Example Get Payout Link Response

    {
      "id": "00754a09-ad00-4475-b874-1dd97f83fc24",
      "external_id": "ext-121313",
      "amount": 20000,
      "merchant_name": "First Business",
      "status": "PENDING",
      "expiration_timestamp": "2019-12-12T06:45:30.041Z",
      "created": "2019-12-09T06:45:28.628Z",
      "payout_url": "https://payout.xendit.co/web/00754a09-ad00-4475-b874-1dd97f83fc24"
    }
    Parameter Type Description
    id
    required
    string A payout link ID generated by Xendit
    external_id
    required
    string The payout link ID in your server, that can be used to reconcile between you and Xendit.

    Maximum: 200 characters
    amount
    required
    integer positive Amount to be paid out.

    Minimum: 10000
    Maximum: Balance in your account
    merchant_name
    optional
    string The name of your company or website.
    status
    required
    string PENDING The payout link has successfully been created and is awaiting the end user’s response
    VOIDED The payout link has been voided. This issue is raised because the payout link has been expired or manually voided by hitting the void endpoint.
    COMPLETED The payout has completed.
    FAILED The payout has failed. The list of failures are described in the failure_reason field.
    EXPIRED The payout link has expired.
    expiration_timestamp
    optional
    ISO8601 An ISO timestamp that the payout link expires. Default is 3 days after creation.

    Timezone: GMT+0
    created
    optional
    ISO8601 An ISO timestamp that tracks when the payout link was created.

    Timezone: GMT+0
    payout_url
    optional
    string Public URL for this payout, in case you want to use our UI.
    email
    optional
    string An email address of the end user you're sending the payout link to.
    bank_code
    optional
    string Bank code for the relevant bank, learn more here
    account_holder_name
    optional
    string Bank account holder name.
    account_number
    optional
    string Bank account number.
    disbursement_id
    optional
    string ID of the disbursement. You can find out here
    failure_reason
    optional
    string If the status is FAILED, this describes the failure.
    claimed_timestamp
    optional
    ISO8601 An ISO timestamp that tracks when the payout was claimed.

    Timezone: GMT+0
    completed_timestamp
    optional
    ISO8601 An ISO timestamp that tracks when the payout was completed.

    Timezone: GMT+0
    failed_timestamp
    optional
    ISO8601 An ISO timestamp that tracks when the payout was failed.

    Timezone: GMT+0
    payment_id
    optional
    string Our internal system’s payment ID that can be used as payment reference.
    </tr>

    Error Codes

    Error Code Description
    PAYOUT_NOT_FOUND_ERROR
    404
    The payout was not found in the system.
    UNAUTHORIZED_MERCHANT_ERROR
    403
    This merchant is not authorized to perform this request.

    Endpoint: Void a Payout Link

    POST https://api.xendit.co/payouts/:id/void

    You can cancel a pending payout by voiding it using this endpoint.

    Request Parameters

    Example Void Payout Link Request

    curl https://api.xendit.co/payouts/:id/void -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==');
    
      $id = '00754a09-ad00-4475-b874-1dd97f83fc24';
    
      $voidPayout = \Xendit\Payouts::void($id);
      var_dump($voidPayout);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Payout } = x;
    const payoutSpecificOptions = {};
    const p = new Payout(payoutSpecificOptions);
    
    const resp = await p.voidPayout({
        id: '67f1b30c-0262-4955-8777-95aa0478c2fc',
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Payout payout = Payout.voidPayout("EXAMPLE_ID");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    resp, err := payout.Void(&payout.VoidParams{
      ID: "00754a09-ad00-4475-b874-1dd97f83fc24",
    })
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("voided payout: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    Payout = xendit_instance.Payout
    
    payout = Payout.void(
        id="a6ee1bf1-ffcd-4bda-a7ab-99c1d5cd0472",
    )
    print(payout)
    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 payout link to retrieve

    Example Void Payout Link Response

    {
      "id": "00754a09-ad00-4475-b874-1dd97f83fc24",
      "external_id": "ext-121312",
      "amount": 20000,
      "merchant_name": "First Business",
      "status": "VOIDED",
      "expiration_timestamp": "2019-12-12T06:45:30.041Z",
      "created": "2019-12-09T06:45:28.628Z"
    }
    Parameter Type Description
    id
    required
    string A payout link ID generated by Xendit
    external_id
    required
    string The payout link ID in your server, that can be used to reconcile between you and Xendit.

    Maximum: 200 characters
    amount
    required
    integer positive Amount to be paid out.

    Minimum: 10000
    Maximum: Balance in your account
    merchant_name
    optional
    string The name of your company or website.
    status
    required
    string PENDING The payout link has successfully been created and is awaiting the end user’s response
    VOIDED The payout link has been voided. This issue is raised because the payout link has been expired or manually voided by hitting the void endpoint.
    COMPLETED The payout has completed.
    FAILED The payout has failed. The list of failures are described in the failure_reason field.
    EXPIRED The payout link has expired.
    expiration_timestamp
    optional
    ISO8601 An ISO timestamp that the payout link expires. Default is 3 days after creation.

    Timezone: GMT+0
    created
    optional
    ISO8601 An ISO timestamp that tracks when the payout link was created.

    Timezone: GMT+0
    payout_url
    optional
    string Public URL for this payout, in case you want to use our UI.
    email
    optional
    string An email address of the end user you're sending the payout link to.
    bank_code
    optional
    string Bank code for the relevant bank, learn more here
    account_holder_name
    optional
    string Bank account holder name.
    account_number
    optional
    string Bank account number.
    disbursement_id
    optional
    string ID of the disbursement. You can find out here
    failure_reason
    optional
    string If the status is FAILED, this describes the failure.
    claimed_timestamp
    optional
    ISO8601 An ISO timestamp that tracks when the payout was claimed.

    Timezone: GMT+0
    completed_timestamp
    optional
    ISO8601 An ISO timestamp that tracks when the payout was completed.

    Timezone: GMT+0
    failed_timestamp
    optional
    ISO8601 An ISO timestamp that tracks when the payout was failed.

    Timezone: GMT+0
    payment_id
    optional
    string Our internal system’s payment ID that can be used as payment reference.
    Error Code Description
    CLAIMED_PAYOUT_ERROR
    400
    The payout is already claimed.

    You are stopped from voiding the payout because the payout is already claimed by your customer.
    PAYOUT_NOT_FOUND_ERROR
    404
    The payout link was not found in the system.
    UNAUTHORIZED_MERCHANT_ERROR
    403
    This merchant is not authorized to perform this request.

    Cross-border Payouts

    Xendit's Multi Currency Cross-border Payout (Remittance Payout) services include sending funds to Indonesia and Philippines.

    We currently support remittances to various fund transfer channels globally, including to 200+ banks and e-wallets in Indonesia and Philippines.

    Learn more about Cross-border Payout here

    Cross-border Payout Object

    This is a Cross-border Payout object, which will be returned in API response and webhook request.

    Example of Cross-border Payout Object

    {
      "id": "rpo_cde3dcb8-37d7-4ea1-a275-8f54af81feb0",
      "created": "2024-05-01T07:15:22Z",
      "updated": "2024-05-01T07:15:22Z",
      "business_id": "5f27a14a9bf05c73dd040bc8",
      "reference_id": "49d056bd-21e5-4997-85f2-2127544c2196",
      "destination_currency": "PHP",
      "destination_amount": 35,
      "sender_customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recipient_customer_id": "cust-f71ffaa8-95a2-47ba-b486-cfe9e2c075d7",
      "status": "ACCEPTED",
      "description": "This is a sample Cross-border Payout transaction",
      "source_of_fund": "OTHER",
      "origin_currency": "IDR",
      "origin_amount": "10000",
      "purpose_code": "OTHER",
      "relationship": "CUSTOMER",
      "failure_code": "string",
      "metadata": {}
    }
    Parameter Data Type Description
    id
    required
    string Unique Cross-border Payout ID (with prefix rpo_, example: rpo_12345432432131)
    created
    required
    string Timestamp when the Cross-border Payout request was made in ISO8601 format.

    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    updated
    required
    string Timestamp when the Cross-border Payout request was last updated in ISO8601 format.

    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    business_id
    required
    string Merchant Business ID provided by Xendit
    reference_id
    required
    string ID provided by merchant to identify Cross-border Payout request
    destination_currency
    required
    string Currency Code in ISO4217 format. Available Currency: IDR, PHP, SGD, THB, VND
    destination_amount
    required
    number Transfer Amount. Minimum and maximum amount can be referred to Docs
    sender_customer_id
    required
    string The ID of the sender customer (as returned by Xendit’s Create Customer endpoint)

    The following fields are required in the sender customer object: customer_type and addresses
    - For INDIVIDUAL customer_type, then the following parameters are also required: given_names, nationality, and date_of_birth in customer_type.individual_detail object
    - For BUSINESS customer_type, then the following parameters are also required: business_name in customer_type.business_detail object.
    - For addresses object, the following fields are also required: addresses.country, addresses.city, addresses.street_line1

    Reference: Customer Object
    recipient_customer_id
    required
    string The ID of the recipient customer (as returned by Xendit’s Create Customer endpoint)

    The following fields are required in the recipient customer object: customer_type, addresses, identity_accounts, and one of phone_number or mobile_number (mobile_number is a mandatory field for PH_GCASH channel destination).
    - For INDIVIDUAL customer_type, then the following parameters are also required: given_names, nationality, and date_of_birth in customer_type.individual_detail object
    - For BUSINESS customer_type, then the following parameters are also required: business_name in customer_type.business_detail object.
    - For addresses object, the following fields are also required: addresses.country, addresses.city, addresses.street_line1
    - For identity_accounts object, the following fields are also required: type, country, company (put channel code value), and properties

    Reference: Customer Object
    status
    required
    string Status of the Cross-border Payout.
    Default is ACCEPTED: Request is being processed and assessed in the risk scoring system. See Cross-border Payout Statuses
    description
    required
    string Description to send with the Cross-border Payout. The recipient may see this e.g., in their bank statement (if supported) or in email receipts we send on your behalf.

    Alphanumber
    Min length: 1 character
    Max length: 100 characters.
    source_of_fund
    optional

    Default: OTHER
    string Source of fund. Refer to our list of Source of Funds section
    origin_currency
    required
    string Origin currency of the Cross-border Payout. Cross-border Payout from SGD to IDR will have origin_currency as SGD
    origin_amount
    required
    number Origin amount of the Cross-border Payout. Cross-border Payout from 100 SGD to IDR will have origin_amount as 100
    purpose_code
    optional

    Default: OTHER
    string Purpose of the Cross-border Payout. Refer to our list of Purpose Codes section
    relationship
    optional

    Required for PH_GCASH

    Default: OTHER
    string Relationship between sender and recipient. Refer to our list of Relationships section
    failure_code
    optional

    string Failure Code for failed Cross-border Payout. You can refer the full list in Failure Reason section
    metadata
    object
    object Object of additional information the merchant may use. Users define the JSON properties and values. This will only be used by the merchant and not Xendit

    Create Cross-border Payout

    Our Create Remittance Payout APIs allow you to send remittances from your Xendit Account on behalf of a sender to your designated recipient.

    Endpoint: Create Cross-border Payout

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

    Request Parameters

    Example Create Cross-border Payout Request

    curl --request POST \
      --url https://api.xendit.co/remittance_payouts \
      --header 'Authorization: {{base_64_of_your_secret_api_key}}' \
      --header 'Accept: application/json' \
      --header 'Content-Type: application/json' \
      --header 'IDEMPOTENCY-KEY: ' \
      --data '{
      "reference_id": "49d056bd-21e5-4997-85f2-2127544c2196",
      "destination_currency": "PHP",
      "destination_amount": "35",
      "sender_customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recipient_customer_id": "cust-f71ffaa8-95a2-47ba-b486-cfe9e2c075d7",
      "origin_currency": "IDR",
      "origin_amount": "10000",
      "source_of_fund": "OTHER",
      "purpose_code": "OTHER",
      "relationship": "CUSTOMER",
      "description": "This is a sample remittance transaction",
      "metadata": {}
    }'

    Create Cross-border Payout Request

    Header Parameter Type Description
    Idempotency-key
    required
    string A unique key to prevent processing duplicate requests. Can be your reference_id or any GUID. Must be unique across development & production environments.

    Characters Special and alphanumeric
    Minimum length 1 character
    Maximum length 100 maximum characters

    Example of Create Cross-border Payout Request

    {
      "reference_id": "49d056bd-21e5-4997-85f2-2127544c2196",
      "destination_currency": "PHP",
      "destination_amount": "35",
      "sender_customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recipient_customer_id": "cust-f71ffaa8-95a2-47ba-b486-cfe9e2c075d7",
      "origin_currency": "IDR",
      "origin_amount": "10000",
      "source_of_fund": "OTHER",
      "purpose_code": "OTHER",
      "relationship": "CUSTOMER",
      "description": "This is a sample Cross-border Payout transaction",
      "metadata": {}
    }
    Parameter Data Type Description
    reference_id
    required
    string ID provided by merchant to identify Cross-border Payout request
    destination_currency
    required
    string Currency Code in ISO4217 format. Available Currency: IDR, PHP, SGD, THB, VND
    destination_amount
    required
    number Transfer Amount. Minimum and maximum amount can be referred to Docs
    sender_customer_id
    required
    string The ID of the sender customer (as returned by Xendit’s Create Customer endpoint)

    The following fields are required in the sender customer object: customer_type and addresses
    - For INDIVIDUAL customer_type, then the following parameters are also required: given_names, nationality, and date_of_birth in customer_type.individual_detail object
    - For BUSINESS customer_type, then the following parameters are also required: business_name in customer_type.business_detail object.
    - For addresses object, the following fields are also required: addresses.country, addresses.city, addresses.street_line1

    Reference: Customer Object
    recipient_customer_id
    required
    string The ID of the recipient customer (as returned by Xendit’s Create Customer endpoint)

    The following fields are required in the recipient customer object: customer_type, addresses, identity_accounts, and one of phone_number or mobile_number (mobile_number is a mandatory field for PH_GCASH channel destination).
    - For INDIVIDUAL customer_type, then the following parameters are also required: given_names, nationality, and date_of_birth in customer_type.individual_detail object
    - For BUSINESS customer_type, then the following parameters are also required: business_name in customer_type.business_detail object.
    - For addresses object, the following fields are also required: addresses.country, addresses.city, addresses.street_line1
    - For identity_accounts object, the following fields are also required: type, country, company (put channel code value), and properties

    Reference: Customer Object
    origin_currency
    required
    string Origin currency of the Cross-border Payout. Cross-border Payout from SGD to IDR will have origin_currency as SGD
    origin_amount
    required
    number Origin amount of the Cross-border Payout. Cross-border Payout from 100 SGD to IDR will have origin_amount as 100
    source_of_fund
    optional

    Default: OTHER
    string Source of fund. Refer to our list of Source of Funds section
    purpose_code
    optional

    Default: OTHER
    string Purpose of the Cross-border Payout. Refer to our list of Purpose Codes section
    relationship
    optional

    Required for PH_GCASH

    Default: OTHER
    string Relationship between sender and recipient. Refer to our list of Relationships section
    description
    required
    string Description to send with the Cross-border Payout. The recipient may see this e.g., in their bank statement (if supported) or in email receipts we send on your behalf.

    Alphanumber
    Min length: 1 character
    Max length: 100 characters.
    metadata
    object
    object Object of additional information the merchant may use. Users define the JSON properties and values. This will only be used by the merchant and not Xendit

    Response Parameters

    Example of Create Cross-border Payout Response

    {
      "id": "rpo_cde3dcb8-37d7-4ea1-a275-8f54af81feb0",
      "created": "2024-05-01T07:15:22Z",
      "updated": "2024-05-01T07:15:22Z",
      "business_id": "5f27a14a9bf05c73dd040bc8",
      "reference_id": "49d056bd-21e5-4997-85f2-2127544c2196",
      "destination_currency": "PHP",
      "destination_amount": 35,
      "sender_customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recipient_customer_id": "cust-f71ffaa8-95a2-47ba-b486-cfe9e2c075d7",
      "status": "ACCEPTED",
      "description": "This is a sample Cross-border Payout transaction",
      "source_of_fund": "OTHER",
      "origin_currency": "IDR",
      "origin_amount": "10000",
      "purpose_code": "OTHER",
      "relationship": "CUSTOMER",
      "failure_code": "string",
      "metadata": {}
    }

    Returns Cross-border Payout object with HTTP status code 201

    Error Codes

    Example of Cross-border Payout error

    {
        "error_code": "IDEMPOTENCY_ERROR",
        "message": "Keys for idempotent requests can only be used for the same endpoint they were first used for. Try using a key if you meant to execute a different request."
    }
    Error Code Error Message
    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.
    DESTINATION_CURRENCY_NOT_SUPPORTED
    400
    Destination currency is not supported. Check that the currency is supported for your chosen channel before retrying.
    AMOUNT_FORMAT_ERROR
    400
    Given amount should contain less than or equal to 2 decimal places
    MINIMUM_TRANSFER_LIMIT_ERROR
    400
    The transfer amount requested is lower than the prescribed minimum for the recipient bank. Amend the transfer amount before retrying.
    MAXIMUM_TRANSFER_LIMIT_ERROR
    400
    The transfer amount requested is higher than the prescribed maximum for the recipient bank. Amend the transfer amount before retrying.
    AMOUNT_INCREMENT_NOT_SUPPORTED
    400
    Amount is not supported for the chosen channel. Check the Cross-border Payout amount matches the minimum increment for the chosen channel.
    ACCOUNT_BLACKLISTED_ERROR
    400
    The provided recipient bank account is blacklisted.
    PAYMENT_CHANNEL_DETAIL_ERROR
    400
    The provided recipient account type is invalid. Please use the valid values (BANK_ACCOUNT or EWALLET).
    DUPLICATE_ERROR
    400
    A payout with this idempotency key already exists. If you meant to execute a different request, please use another idempotency key.
    CUSTOMER_DATA_NOT_FOUND
    404
    Could not find any customer object with given sender_customer_id or recipient_customer_id. Try again using a valid Customer ID.
    IDEMPOTENCY_ERROR
    409
    Keys for idempotent requests can only be used for the same endpoint they were first used for. Try using a key if you meant to execute a different request.
    STILL_PROCESSING_ERROR
    409
    Similar request with similar idempotency key is still processing.
    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 <a href="https://docs.xendit.co/
    SERVER_ERROR
    500
    Error connecting to our server. Use Get Cross-border Payout API to check whether the payout has already been created. Retry safely using IDEMPOTENCY-KEY header when available

    Get Cross-border Payout by ID

    Endpoint: Get Cross-border Payout by ID

    GET https://api.xendit.co/remittance_payouts/:cross_border_payout_id

    This endpoint queries the current status of a Cross-border payout. This is often used for checking the status of a transaction.

    Request Parameters

    Path Parameter Type Description
    cross_border_payout_id
    required
    string ID of the Cross-border Payout

    Response Parameters

    Example Get Cross-border Payout by ID Response

    {
      "id": "rpo_cde3dcb8-37d7-4ea1-a275-8f54af81feb0",
      "created": "2024-05-01T07:15:22Z",
      "updated": "2024-05-01T07:15:22Z",
      "business_id": "5f27a14a9bf05c73dd040bc8",
      "reference_id": "49d056bd-21e5-4997-85f2-2127544c2196",
      "destination_currency": "PHP",
      "destination_amount": 35,
      "sender_customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recipient_customer_id": "cust-f71ffaa8-95a2-47ba-b486-cfe9e2c075d7",
      "status": "FAILED",
      "description": "This is a sample Cross-border Payout transaction",
      "source_of_fund": "OTHER",
      "origin_currency": "IDR",
      "origin_amount": "10000",
      "purpose_code": "OTHER",
      "relationship": "CUSTOMER",
      "failure_code": "INVALID_DESTINATION",
      "metadata": {}
    }

    Returns Cross-border Payout object with HTTP status code 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
    REMITTANCE_PAYOUT_NOT_FOUND
    404
    Could not find Cross-border Payout. Try again with a valid ID.

    Cancel Cross-border Payout

    Endpoint: Cancel Cross-border Payout

    POST https://api.xendit.co/remittance_payouts/:cross_border_payout_id/cancel

    Cross-border Payout can only be cancelled while in the following status :

    Request Parameters

    Path Parameter Type Description
    cross_border_payout_id
    required
    string ID of the Cross-border Payout

    Response Parameters

    Example Cancel Cross-border Payout by ID Response

    {
      "id": "rpo_cde3dcb8-37d7-4ea1-a275-8f54af81feb0",
      "created": "2024-05-01T07:15:22Z",
      "updated": "2024-05-01T07:15:22Z",
      "business_id": "5f27a14a9bf05c73dd040bc8",
      "reference_id": "49d056bd-21e5-4997-85f2-2127544c2196",
      "destination_currency": "PHP",
      "destination_amount": 35,
      "sender_customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recipient_customer_id": "cust-f71ffaa8-95a2-47ba-b486-cfe9e2c075d7",
      "status": "CANCELLED",
      "description": "This is a sample Cross-border Payout transaction",
      "source_of_fund": "OTHER",
      "origin_currency": "IDR",
      "origin_amount": "10000",
      "purpose_code": "OTHER",
      "relationship": "CUSTOMER",
      "failure_code": null,
      "metadata": {}
    }

    Returns Cross-border Payout object with HTTP status code 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
    CANCELLATION_NOT_ALLOWED
    404
    Cross-border Payout cannot be canceled because it has already been processed by Xendit.
    REMITTANCE_PAYOUT_NOT_FOUND
    404
    Could not find Cross-border Payout. Try again with a valid ID.
    SERVER_ERROR
    500
    Error connecting to our server. Use Get Cross-border Payout API to check whether the payout has already been created. Retry safely using IDEMPOTENCY-KEY header when available

    Webhooks for Cross-border Payout

    Endpoint: Cross-border Payout Webhook

    POST https://yourcompany.com/cross_border_payout_webhook_url

    Xendit notifies your system upon failed and successful disbursements via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    We send a webhook when there’s a change of your Cross-border Payout status to:

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

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

    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks

    Example of Pending Compliance Assessment Event

    {
      "event": "remittance_payout.pending_compliance_assessment",
      "id": "rpo_cde3dcb8-37d7-4ea1-a275-8f54af81feb0",
      "created": "2024-05-01T07:15:22Z",
      "updated": "2024-05-01T07:15:22Z",
      "business_id": "5f27a14a9bf05c73dd040bc8",
      "reference_id": "49d056bd-21e5-4997-85f2-2127544c2196",
      "destination_currency": "PHP",
      "destination_amount": 35,
      "sender_customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recipient_customer_id": "cust-f71ffaa8-95a2-47ba-b486-cfe9e2c075d7",
      "status": "PENDING_COMPLIANCE_ASSESSMENT",
      "description": "This is a sample Cross-border Payout transaction",
      "source_of_fund": "OTHER",
      "origin_currency": "IDR",
      "origin_amount": "10000",
      "purpose_code": "OTHER",
      "relationship": "CUSTOMER",
      "metadata": {}
    }

    Example of Cross-Border Payout Succeeded Event

    {
      "event": "remittance_payout.succeeded",
      "id": "rpo_cde3dcb8-37d7-4ea1-a275-8f54af81feb0",
      "created": "2024-05-01T07:15:22Z",
      "updated": "2024-05-01T07:15:22Z",
      "business_id": "5f27a14a9bf05c73dd040bc8",
      "reference_id": "49d056bd-21e5-4997-85f2-2127544c2196",
      "destination_currency": "PHP",
      "destination_amount": 35,
      "sender_customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recipient_customer_id": "cust-f71ffaa8-95a2-47ba-b486-cfe9e2c075d7",
      "status": "SUCCEEDED",
      "description": "This is a sample Cross-border Payout transaction",
      "source_of_fund": "OTHER",
      "origin_currency": "IDR",
      "origin_amount": "10000",
      "purpose_code": "OTHER",
      "relationship": "CUSTOMER",
      "metadata": {}
    }

    Example of Cross-Border Payout Failed Event

    {
      "event": "remittance_payout.succeeded",
      "id": "rpo_cde3dcb8-37d7-4ea1-a275-8f54af81feb0",
      "created": "2024-05-01T07:15:22Z",
      "updated": "2024-05-01T07:15:22Z",
      "business_id": "5f27a14a9bf05c73dd040bc8",
      "reference_id": "49d056bd-21e5-4997-85f2-2127544c2196",
      "destination_currency": "PHP",
      "destination_amount": 35,
      "sender_customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recipient_customer_id": "cust-f71ffaa8-95a2-47ba-b486-cfe9e2c075d7",
      "status": "FAILED",
      "description": "This is a sample Cross-border Payout transaction",
      "source_of_fund": "OTHER",
      "origin_currency": "IDR",
      "origin_amount": "10000",
      "purpose_code": "OTHER",
      "relationship": "CUSTOMER",
      "failure_code": "INVALID_DESTINATION",
      "metadata": {}
    }

    Pending Compliance Assessment Event

    We will send a webhook event with Cross-border Payout Object and additional field(s) as follow:

    Body Parameter Type Description
    event string Type of the event. Event value: remittance_payout.pending_compliance_assessment

    Compliance Rejected Event

    We will send a webhook event with Cross-border Payout Object and additional field(s) as follow:

    Body Parameter Type Description
    event string Type of the event. Event value: remittance_payout.compliance_rejected

    Cross-border Payout Failed

    We will send a webhook event with Cross-border Payout Object and additional field(s) as follow:

    Body Parameter Type Description
    event string Type of the event. Event value: remittance_payout.failed
    failure_code string Failure code for the failed Cross-border Payout. Please find the detail and description in Failure Code section

    Cross-border Payout Succeeded

    We will send a webhook event with Cross-border Payout Object and additional field(s) as follow:

    Body Parameter Type Description
    event string Type of the event. Event value: remittance_payout.succeeded

    Cross-border Payout Ready

    We will send a webhook event with Cross-border Payout Object and additional field(s) as follow:

    Body Parameter Type Description
    event string Type of the event. Event value: remittance_payout.ready
    disbursement_code string Code to be presented by the beneficiary for cash pick-up. Please share this with the beneficiary.
    Example: XENDIT-12341

    Characters: Special and alphanumeric
    Minimum length: 1 character
    Maximum length: 100 characters

    Cross-border Payout Updated

    We will send a webhook event with Cross-border Payout Object and additional field(s) as follow:

    Body Parameter Type Description
    event string Type of the event. Event value: remittance_payout.locked or remittance_payout.expired

    Statuses for Cross-border Payouts

    Status Description
    ACCEPTED Request is being processed and assessed in the risk scoring system
    PENDING_COMPLIANCE_ASSESSMENT Request is considered medium or high risk, and is being reviewed by our compliance team. Our team will contact you via email for extra information for enhanced due diligence
    REQUESTED Request has been approved and the Cross-border Payout is queued to be transferred to the recipient
    COMPLIANCE_REJECTED Request is rejected by compliance
    READY The disbursement has been sent to the channel. For cash Cross-border Payout Only: funds are ready for pick-up
    LOCKED For cash Cross-border Payout only. Cash pick-up in progress. Cancellation is not allowed.
    EXPIRED For cash Cross-border Payout only. Disbursement has expired.
    SUCCEEDED The sending bank has confirmed transmission of the Cross-border Payout
    FAILED Cross-border Payout could not be transferred to the recipient due to certain errors. See Cross-border Payouts Failure Codes
    REFUNDED Only valid for SKN/RTGS and cash cahnnel use case
    CANCELLED Cancel transactions

    Failure Codes for Cross-border Payouts

    Failure Code Description Should you retry?
    INSUFFICIENT_BALANCE Client has insufficient balance for the Cross-border Payout amount. Yes, retry the Cross-border Payout after ensuring that you have sufficient balance in your account.
    REJECTED_BY_CHANNEL Cross-border Payout failed due to error from destination channel. This is usually because of network issues associated with the destination bank or issues crediting funds into the destination bank account Yes, retry the Cross-border Payout after validating that the destination bank account number exists.
    TEMPORARY_TRANSFER_ERROR Cross-border Payout failed due to a known temporary internal error Yes, retry the Cross-border Payout in 1-3 hours.
    INVALID_DESTINATION Destination account does not exist/is invalid. You are unlikely to succeed if you retry the same Cross-border Payout request. Please confirm with the beneficiary whether the destination account is correct
    TRANSFER_ERROR We’ve encountered a fatal error while processing this Cross-border Payout. Normally, this means that certain fields in your requests are invalid. It is unlikely that the same request will succeed if you retry
    UNKNOWN_BANK_NETWORK_ERROR The bank has delivered an error they have not documented. By definition, this means the bank does not known the issue Unfortunately, we are unable to predict whether the disbursement will succeed should you retry the same Cross-border Payout request.You may however choose to retry the same Cross-border Payout request at least one hour after receiving our callback at your own discretion.

    Purpose Codes for Cross-border Payouts

    Key Description
    SELF Transfer to own account
    FAMILY Family Maintenance
    EDUCATION Education-related student expenses
    MEDICAL Medical Treatment
    HOTEL Hotel Accomodation
    TRAVEL Travel
    UTILITIES Utility Bills
    LOAN_REPAYMENT Repayment of Loans
    TAX_PAYMENT Tax Payment
    RESIDENCE_PURCHASE Purchase of Residential Property
    RESIDENCE_RENT Payment of Property Rental
    INSURANCE Insurance
    MUTUAL_FUND Mutual Fund Investment
    SHARES_INVESTMENT Investment in Shares
    DONATIONS Donations
    ADVERTISING Advertising & Public relations-related expenses
    ROYALTY_FEES Royalty fees, trademark fees, patent fees, and copyright fees
    BROKER_FEES Fees for brokers, front end fee, commitment fee, guarantee fee and custodian fee
    ADVISORS Fees for advisors, technical assistance, and academic purpose, including remuneration for specialists
    OFFICE Representative office expenses
    CONSTRUCTION Construction costs / expenses
    SHIPMENT Transportation fees for goods
    EXPORT For payment of exported goods
    DELIVERY Delivery fees for goods
    TRADES General Goods Trades - Offline trade
    SALARY Salary
    REFUND Refund
    LOAN_REPAYMENT Loan
    OTHER Other

    Source of Funds for Cross-border Payouts

    Key Description
    INVESTMENT Bonds, fixed deposits, preference shares, business ownership/equity or property ownership
    PERSONAL_SAVINGS Funds kept in an account in a bank or a similar organization
    BUSINESS_REVENUE Income from a business or a company
    LEGACY Inherited money from a will
    BUSINESS_ARRANGEMENT Any understanding, procedure, course of dealing, or arrangement between a creditor and a seller
    LOAN A sum of money that is borrowed
    SALARY A fixed regular payment made by an employer
    OTHER Other

    Relationships for Cross-border Payouts

    Key Description
    BRANCH_REPRESENTATIVE_OFFICE Branch/Representative Office
    BUSINESS_PARTNER Business Partner
    CHILDREN Children
    CREDITOR Creditor
    CUSTOMER Customer
    DEBTOR Debtor
    EMPLOYEE Employee
    EX_SPOUSE Ex-spouse
    FRANCHISEE_FRANCHISOR Franchisee/Franchisor
    GRANDPARENTS Grandparents
    HOLDING_COMPANY Holding Company
    MAID Maid
    OWNSELF Ownself
    PARENTS Parents
    RELATIVE Relative (uncle/aunt/cousin)
    SIBLING Sibling / Brother / Sister
    SPOUSE Spouse
    SUBSIDIARY_COMPANY Subsdiary company
    SUPPLIER Supplier
    FRIEND Friend
    GOVERNMENT_BODY Government Body
    EDUCATION_INSTITUTION Education Instituion
    NON_GOVERNMENT_BODY Non-government Body
    OTHER Other

    Test Scenarios for Cross-border Payout

    Positive Scenarios

    Scenario Criteria Expected Result
    Successful Cross-border Payout to Indonesia Channel First, create new customers representing the sender and recipient. Use the following values for the recipient customer:
    Option 1
    - identity_accounts.company: ID_PANIN
    - identity_accounts.properties.account_holder_name: Maria Wenger
    -identity_accounts.properties.account_number: 818181

    Option 2
    - identity_accounts.company: ID_OVO
    - identity_accounts.properties.account_holder_name: Ari Fernandes
    -identity_accounts.properties.account_number: 081234567890

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will complete Cross-border Payout and send a callback to your callback URL with status: SUCCEEDED
    Successful Cross-border Payout to Philippine Channel First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: PH_BDO
    - identity_accounts.properties.account_holder_name: Kal Stones
    -identity_accounts.properties.account_number: 828282

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will complete Cross-border Payout and send a callback to your callback URL with status: SUCCEEDED
    Successful Cross-border Payout to Singapore Channel First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: SG_BOC
    - identity_accounts.properties.account_holder_name: Ruth Langmore
    -identity_accounts.properties.account_number: 838383

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will complete Cross-border Payout and send a callback to your callback URL with status: SUCCEEDED
    Successful Cross-border Payout to Thailand Channel First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: TH_SCB
    - identity_accounts.properties.account_holder_name: Justin Morph
    -identity_accounts.properties.account_number: 267267

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will complete Cross-border Payout and send a callback to your callback URL with status: SUCCEEDED
    Cross-border Payout has been assessed to be medium or high risk and requires compliance verification. Cross-border Payout is eventually approved by compliance and succeeds First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    Option 1
    - identity_accounts.company: ID_MANDIRI
    - identity_accounts.properties.account_holder_name: Evan Dimas
    -identity_accounts.properties.account_number: 808080

    Option 2
    - identity_accounts.company: {{anything}}
    - identity_accounts.properties.account_holder_name: {{anything}}
    -identity_accounts.properties.account_number: 87778798

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will send a callback to your callback URL with status: PENDING_COMPLIANCE_ASSESSMENT. Then, will send a second callback to your callback URL with status: SUCCEEDED
    Cross-border Payout transaction is stuck in compliance assessment First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    Option 1
    - identity_accounts.company: ID_MANDIRI
    - identity_accounts.properties.account_holder_name: Shawn
    -identity_accounts.properties.account_number: 898989

    Option 2
    - identity_accounts.company: {{anything}}
    - identity_accounts.properties.account_holder_name: {{anything}}
    -identity_accounts.properties.account_number: 4455445544

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will send a callback to your callback URL with status: PENDING_COMPLIANCE_ASSESSMENT
    Successful Cross-border Payout to Indonesia Cash Channel First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: ID_ALFAMART
    -identity_accounts.properties.payment_code: 898900

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will send a callback to your callback URL with disbursement_code and status: READY. Then, will send a callback to your callback URL with status: LOCKED. Then,will complete Cross-border Payout and send a callback to your callback URL with status: SUCCEEDED
    Simulate an online Cross-border Payout cancellation flow First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: ID_MANDIRI
    - identity_accounts.properties.account_holder_name: Gustafo Vring
    -identity_accounts.properties.account_number: 10101010

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Cross-border Payout status will remain on ACCEPTED. You can then try a Cancel Cross-border Payout request
    Cash Cross-border Payout ready to pick up First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: ID_ALFAMART
    -identity_accounts.properties.payment_code: 898911

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will send a callback to your callback URL with disbursement_code and status: READY. Cross-border Payout status will remain on READY.
    Simulate a cash Cross-border Payout cancellation flow First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: ID_ALFAMART
    -identity_accounts.properties.payment_code: 898911

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Cross-border Payout status will remain on READY. You can then try a Cancel Cross-border Payout request
    Successful Cross-border Payout to Singapore Channel First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: SG_DBS
    -identity_accounts.properties.payment_code: 818181

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will complete Cross-border Payout and send a callback to your callback URL with status: SUCCEEDED

    Negative Scenarios

    Scenario Criteria Expected Result
    Cross-border Payout has been assessed to be medium or high risk and requires compliance verification. Cross-border Payout is eventually rejected by compliance First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    Option 1
    - identity_accounts.company: ID_MANDIRI
    - identity_accounts.properties.account_holder_name: Cynthia Rodriguez
    -identity_accounts.properties.account_number: 909090

    Option 2
    - identity_accounts.company: {{anything}}
    - identity_accounts.properties.account_holder_name: {{anything}}
    -identity_accounts.properties.account_number: 987654321

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will send a callback to your callback URL with status: PENDING_COMPLIANCE_ASSESSMENT. Then, we will send a second callback to your callback URL with status: COMPLIANCE_REJECTED
    Destination account does not exist/is invalid. First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: ID_MANDIRI
    - identity_accounts.properties.account_holder_name: Teo Alcantara
    -identity_accounts.properties.account_number: 4567890

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will send a callback to your callback URL with status: FAILED and failure_code: INVALID_DESTINATION
    Transaction has been rejected by the destination channel without a clear error reason First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: ID_CIMB
    - identity_accounts.properties.account_holder_name: Ichwan De Bryune
    -identity_accounts.properties.account_number: 8787878

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will send a callback to your callback URL with status: FAILED and failure_code: REJECTED_BY_CHANNEL
    Transaction failed because of a known temporary issue First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.channel_code: PH_OMNI
    - identity_accounts.properties.account_holder_name: Ayrton Da Silva
    -identity_accounts.properties.account_number: 868686

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will send a callback to your callback URL with status: FAILED and failure_code: TEMPORARY_TRANSFER_ERROR
    Insufficient Balance First, create customers representing the sender and recipient (which field detail is different with above specifications).

    Then, Create Cross-border Payout request with amount greater than the balance you have
    Will send a callback to your callback URL with status: FAILED and failure_code: INSUFFICIENT_BALANCE
    Cash Cross-border Payout expired First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: ID_ALFAMART
    - properties.payment_code: 898922

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will send a callback to your callback URL with disbursement_code and status: READY. Then,will send a callback to your callback URL with status: EXPIRED
    Singapore bank networks have rejected the transaction due to maintenance or unknown reason First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.channel_code: SG_DBS
    - properties.account_number: 999999
    Payout will be FAILED with failure_code = REJECTED_BY_CHANNEL
    Destination account does not exist/is invalid for Singapore channel First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: SG_BOC
    - properties.account_holder_name: Darlene Snell
    - properties.account_number: 733810

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will send a callback to your callback URL with status: FAILED and failure_code: INVALID_DESTINATION
    Destination account does not exist/is invalid for Thailand channel First, create customers representing the sender and recipient. Use the following values for the recipient customer:
    - identity_accounts.company: TH_SCB
    - properties.account_holder_name: Harry Johnson
    - properties.account_number: 588372

    Then create a Cross-border Payout using required params (refer to Create Cross-border Payout) and the above sender and recipient customer ids
    Will send a callback to your callback URL with status: FAILED and failure_code: INVALID_DESTINATION

    Invoices

    Xendit Hosted Checkout (Invoice) is a free pre-built payment page that provides a seamless payment experience to you and your customers. Xendit Checkout can be paid via debit/credit cards, banks, retail outlets, eWallets and direct debit. It automatically detects payments for real-time status updates on your dashboard.

    Create Invoice

    Endpoint: Create Invoice

    POST https://api.xendit.co/v2/invoices

    Invoices allow you to quickly collect payments using with all of our payment methods. When payment is complete, a callback is made regardless of the payment method used.

    Learn more about invoices in our documentation

    Request Parameters

    Example Create Invoice Request

    curl https://api.xendit.co/v2/invoices -H 'Content-Type: application/json' -X POST \
        -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
        -d '{
              "external_id": "payment-link-example",
              "amount": 510000,
              "description": "Invoice Demo #123",
              "invoice_duration": 86400,
              "customer": {
                "given_names": "John",
                "surname": "Doe",
                "email": "johndoe@example.com",
                "mobile_number": "+6287774441111",
                "addresses": [
                  {
                    "city": "Jakarta Selatan",
                    "country": "Indonesia",
                    "postal_code": "12345",
                    "state": "Daerah Khusus Ibukota Jakarta",
                    "street_line1": "Jalan Makan",
                    "street_line2": "Kecamatan Kebayoran Baru"
                  }
                ]
              },
              "customer_notification_preference": {
                "invoice_created": [
                  "whatsapp",
                  "email",
                  "viber"
                ],
                "invoice_reminder": [
                  "whatsapp",
                  "email",
                  "viber"
                ],
                "invoice_paid": [
                  "whatsapp",
                  "email",
                  "viber"
                ]
              },
              "success_redirect_url": "https://www.google.com",
              "failure_redirect_url": "https://www.google.com",
              "currency": "IDR",
              "items": [
                {
                  "name": "Air Conditioner",
                  "quantity": 1,
                  "price": 100000,
                  "category": "Electronic",
                  "url": "https://yourcompany.com/example_item"
                }
              ],
              "fees": [
                {
                  "type": "ADMIN",
                  "value": 5000
                }
              ],
              "payment_methods": [
                "CREDIT_CARD"
              ],
              "channel_properties": {
                "cards": {
                  "allowed_bins": [
                    "400000",
                    "52000000"
                  ],
                  "installment_configuration": {
                    "allow_installment": true,
                    "allow_full_payment": false,
                    "allowed_terms": [
                      {
                        "issuer": "BCA",
                        "terms": [
                          3,
                          6,
                          12
                        ]
                      },
                      {
                        "issuer": "BNI",
                        "terms": [
                          3,
                          6
                        ]
                      },
                      {
                        "issuer": "MANDIRI",
                        "terms": [
                          6
                        ]
                      }
                    ]
                  }
                }
              },
              "metadata": {
                "store_branch": "Jakarta"
              }
            }'
    <?php
    
      use Xendit\Xendit;
      require 'vendor/autoload.php';
    
      Xendit::setApiKey('xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==');
    
      $params = [ 
        'external_id' => 'demo_1475801962607',
        'amount' => 510000,
        'description' => 'Invoice Demo #123',
        'invoice_duration' => 86400,
        'customer' => [
            'given_names' => 'John',
            'surname' => 'Doe',
            'email' => 'johndoe@example.com',
            'mobile_number' => '+6287774441111',
            'addresses' => [
                [
                    'city' => 'Jakarta Selatan',
                    'country' => 'Indonesia',
                    'postal_code' => '12345',
                    'state' => 'Daerah Khusus Ibukota Jakarta',
                    'street_line1' => 'Jalan Makan',
                    'street_line2' => 'Kecamatan Kebayoran Baru'
                ]
            ]
        ],
        'customer_notification_preference' => [
            'invoice_created' => [
                'whatsapp',
                'email',
                'viber'
            ],
            'invoice_reminder' => [
                'whatsapp',
                'email',
                'viber'
            ],
            'invoice_paid' => [
                'whatsapp',
                'email',
                'viber'
            ]
        ],
        'success_redirect_url' => 'https=>//www.google.com',
        'failure_redirect_url' => 'https=>//www.google.com',
        'currency' => 'IDR',
        'items' => [
            [
                'name' => 'Air Conditioner',
                'quantity' => 1,
                'price' => 510000,
                'category' => 'Electronic',
                'url' => 'https=>//yourcompany.com/example_item'
            ]
        ],
        'fees' => [
            [
                'type' => 'ADMIN',
                'value' => 5000
            ]
        ],
        'payment_methods' => ['CREDIT_CARD'],
        'channel_properties' => [
            'cards' => [
                'allowed_bins' => [
                    '400000',
                    '52000000'
                ],
                'installment_configuration' => [
                    'allow_installment' => true,
                    'allow_full_payment' => false,
                    'allowed_terms' => [
                        [
                          'issuer' => 'BCA'
                          'terms' => [3,6,12]
                        ],
                        [
                          'issuer' => 'BNI'
                          'terms' => [3,6]
                        ],
                        [
                          'issuer' => 'MANDIRI'
                          'terms' => [6]
                        ]
                    ]
                ]
            ]
        ],
        'metadata' => [
            'store_branch' => 'Jakarta'
        ]
      ];
    
      $createInvoice = \Xendit\Invoice::create($params);
      var_dump($createInvoice);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Invoice } = x;
    const invoiceSpecificOptions = {};
    const i = new Invoice(invoiceSpecificOptions);
    
    const resp = await i.createInvoice(
      'external_id': 'payment-link-example',
      'amount': 510000,
      'description': 'Invoice Demo #123',
      'invoice_duration': 86400,
      'customer': {
        'given_names': 'John',
        'surname': 'Doe',
        'email': 'johndoe@example.com',
        'mobile_number': '+6287774441111',
        'addresses': [
          {
            'city': 'Jakarta Selatan',
            'country': 'Indonesia',
            'postal_code': '12345',
            'state': 'Daerah Khusus Ibukota Jakarta',
            'street_line1': 'Jalan Makan',
            'street_line2': 'Kecamatan Kebayoran Baru'
          }
        ]
      },
      'customer_notification_preference': {
        'invoice_created': [
          'whatsapp',
          'email',
          'viber'
        ],
        'invoice_reminder': [
          'whatsapp',
          'email',
          'viber'
        ],
        'invoice_paid': [
          'whatsapp',
          'email',
          'viber'
        ]
      },
      'success_redirect_url': 'https://www.google.com',
      'failure_redirect_url': 'https://www.google.com',
      'currency': 'IDR',
      'items': [
        {
          'name': 'Air Conditioner',
          'quantity': 1,
          'price': 510000,
          'category': 'Electronic',
          'url': 'https://yourcompany.com/example_item'
        }
      ],
      'fees': [
        {
          'type': 'ADMIN',
          'value': 5000
        }
      ],
      'payment_methods': ['CREDIT_CARD'],
      'channel_properties': {
          'cards': {
              'allowed_bins': [
                  '400000',
                  '52000000'
              ],
              'installment_configuration': {
                  'allow_installment': true,
                  'allow_full_payment': false,
                  'allowed_terms': [
                      {
                        'issuer': 'BCA',
                        'terms': [3,6,12]
                      },
                      {
                        'issuer': 'BNI',
                        'terms': [3,6]
                      },
                      {
                        'issuer': 'MANDIRI',
                        'terms': [6]
                      }
                  ]
              }
          }
      },
      "metadata": {
        "store_branch": "Jakarta"
      }
    );
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      ArrayList<Map<String, Object>> customerAddresses = new ArrayList<Map<String, Object>>();
      Map<String, Object> customerAddress1 = new HashMap<>();
      customerAddress1.put("city", "Jakarta Selatan");
      customerAddress1.put("state", "Daerah Khusus Ibukota Jakarta");
      customerAddress1.put("country", "Indonesia");
      customerAddress1.put("postal_code", "12345");
      customerAddress1.put("street_line1", "Jalan Makan");
      customerAddress1.put("street_line2", "Kecamatan Kebayoran Baru");
      customerAddresses.add(customerAddress1);
    
      Map<String, Object> customerAddress2 = new HashMap<>();
      customerAddress2.put("city", "Jakarta Selatan");
      customerAddress2.put("state", "Daerah Khusus Ibukota Jakarta");
      customerAddress2.put("country", "Indonesia");
      customerAddress2.put("postal_code", "12345");
      customerAddress2.put("street_line1", "Jalan Satu");
      customerAddress2.put("street_line2", "Kecamatan Kebayoran Baru");
    
      Map<String, Object> customerObject = new HashMap<>(); 
      customerObject.put("given_names", "John");
      customerObject.put("surname", "Doe");
      customerObject.put("email", "johndoe@example.com");
      customerObject.put("mobile_number", "+6287774441111"); 
      customerObject.put("addresses", customerAddresses);
    
      Map<String, Object> customerNotificationPreference = new HashMap<>();
      customerNotificationPreference.put("invoice_created", notifications);
      customerNotificationPreference.put("invoice_reminder", notifications);
      customerNotificationPreference.put("invoice_paid", notifications);
    
      ArrayList<Map<String, Object>> items = new ArrayList<Map<String, Object>>();
      Map<String, Object> item1 = new HashMap<>();
      item1.put("name": "Air Conditioner");
      item1.put("quantity": 1);
      item1.put("price": 510000);
      item1.put("category": "Electronic");
      item1.put("url": "https://yourcompany.com/example_item");
      items.add(item1);
    
      ArrayList<Map<String, Object>> fees = new ArrayList<Map<String, Object>>();
      Map<String, Object> fee1 = new HashMap<>();
    
      fees.add(fee1);
    
      Map<String, Object> params = new HashMap<>();
      params.put("external_id", "demo_1475801962607");
      params.put("amount", 50000);
      params.put("description", "Invoice Demo #123");
      params.put("invoice_duration", 86400);
      params.put("customer", customerObject);
      params.put("customer_notification_preference", customerNotificationPreference);
      params.put("success_redirect_url", "https://www.google.com");
      params.put("failure_redirect_url", "https://www.google.com");
      params.put("currency", "IDR");
      params.put("items", items);
      params.put("fees", fees);
    
      Invoice invoice = Invoice.create(params);
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    customerAddress := xendit.CustomerAddress{
      Country:      "Indonesia",
      StreetLine1:  "Jalan Makan",
      StreetLine2:  "Kecamatan Kebayoran Baru",
      City:         "Jakarta Selatan", 
      State:        "Daerah Khusus Ibukota Jakarta",
      PostalCode:   "12345",
    }
    
    customer := xendit.Customer{
      GivenNames:   "John",
      Surname:   "Doe",
      Email:        "johndoe@example.com",
      MobileNumber: "+6287774441111"
      Addresses:    []xendit.CustomerAddress{customerAddress},
    }
    
    item := xendit.Item{
      Name:          "Air Conditioner",
      Quantity:       1,
      Price:          510000,
      Category:       "Electronic",
      Url:            "https://yourcompany.com/example_item"
    }
    
    items := xendit.Items{
      item:         []xendit.item{item}
    }
    
    fee := xendit.fee{
      Type:         "ADMIN",
      Value:        5000,
    }
    
    fees := xendit.Fees{
      fee:          []xendit.fee{fee}
    }
    
    NotificationType := [3]string{"whatsapp", "email"}
    
    customerNotificationPreference := xendit.CustomerNotificationPreference{
      InvoiceCreated:     NotificationType,
      InvoiceReminder:    NotificationType,
      InvoicePaid:        NotificationType,
    }
    
    data := invoice.CreateParams{
      ExternalID:         "demo_1475801962607",
      Amount:             50000,
      Description:        "Invoice Demo #123",
      InvoiceDuration:    86400,
      Customer:           customer, 
      CustomerNotificationPreference:   customerNotificationPreference, 
      SuccessRedirectUrl: "https://www.google.com",
      FailureRedirectUrl: "https://www.google.com",
      Currency:           "IDR",
      Items:              items,  
      Fees:               fees 
    }
    
    resp, err := invoice.Create(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("created invoice: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    Invoice = xendit_instance.Invoice
    
    addresses = []
    address = {
        city: "Jakarta Selatan",
        country: "Indonesia",
        postal_code: "12345",
        state: "Daerah Khusus Ibukota Jakarta",
        street_line1: "Jalan Makan",
        street_line2: "Kecamatan Kebayoran Baru"
    }
    addresses.append(address)
    
    customer = {
        given_names: "John",
        surname: "Doe",
        email: "johndoe@example.com",
        mobile_number: "+6287774441111",
        address: addresses
    }
    
    NotificationType = {
      "whatsapp",
      "email",
      "viber"
    }
    
    customerNotificationPreference = {
      invoice_created:  NotificationType
      invoice_reminder: NotificationType
      invoice_paid:     NotificationType
    }
    
    items = []
    item = {
        name: "Phone Case",
        price: 510000,
        quantity: 1
        category: "Electronic",
        url: "https://yourcompany.com/example_item"
    }
    items.append(item)
    
    fees = []
    fee = {
        Type: "ADMIN",
        Value: 5000,
    }
    fees.append(fee)
    
    allowedTerms = []
    allowedTerm = {
      issuer: 'BNI',
      terms: [3,6,12]
    }
    allowedTerms.append(allowedTerm)
    
    installmentConfiguration = {
      allow_installment: true,
      allow_full_payment: false,
      allowed_terms: allowedTerms
    }
    
    cardChannelProperties = {
      allowed_bins: ['400000', '520000'],
      installment_configuration: installmentConfiguration
    }
    
    paymentMethods = ["CREDIT_CARD"]
    channelProperties = {
      card: cardChannelProperties
    }
    
    invoice = Invoice.create(
        external_id = "invoice-1593684000",
        amount = 20000,
        description =" Invoice Demo #123",
        invoice_duration = 86400,
        customer = customer,
        customer_notification_preference = customerNotificationPreference,
        SuccessRedirectUrl = "https://www.google.com",
        FailureRedirectUrl = "https://www.google.com"
        Currency = "IDR",  
        items = items,
        fees = fees,
        payment_methods = paymentMethods,
        channel_properties = channelProperties
    )
    print(invoice)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    InvoiceClient invoice = xendit.Invoice;
    
    Address addresses = new Address
    {
      Country = Country.Indonesia,
      StreetLine1 = "Jalan Makan",
      StreetLine2 = "Kecamatan Kebayoran Baru",
      State = "Daerah Khusus Ibukota Jakarta", 
      City = "Jakarta Selatan",
      Province = "Daerah Khusus Ibukota Jakarta",
      PostalCode = "12345",
    };
    
    CustomerResponse customer = new CustomerResponse
    {
      GivenNames = "John",
      Surname = "Doen",
      Email = "johndoe@example.com",
      MobileNumber = "+6287774441111",
      Addresses = new Address[] { addresses },
    };
    
    NotificationPreference preference = new NotificationPreference
    {
      InvoicePaid = new NotificationType[] { NotificationType.Email, NotificationType.Whatapp }
      InvoiceCreated = new NotificationType[] { NotificationType.Email, NotificationType.Whatapp }
      InvoiceReminder = new NotificationType[] { NotificationType.Email, NotificationType.Whatapp }
    };
    
    ItemInvoice item = new ItemInvoice
    {
      Name = "shoes",
      Quantity = 1,
      Price = 100,
      Category = "Electronic",
      Url = "https://yourcompany.com/example_item"
    };
    
    FeeInvoice fee = new FeeInvoice
    {
      Type = "ADMIN",
      Value = 200,
    };
    
    InvoiceParameter parameter = new InvoiceParameter
    {
      ExternalId = "external-id",
      Amount = 1000,
      Description = "Invoice Demo #123",
      InvoiceDuration = 86400, 
      Customer = customer,
      NotificationPreference = preference,
      SuccessRedirectUrl = "https://www.google.com",
      FailureRedirectUrl = "https://www.google.com"
      Currency = Currency.IDR,
      Items = new ItemInvoice[] { item },
      Fees = new FeeInvoice[] { fee },
    };
    
    InvoiceResponse invoiceResponse = await invoice.Create(parameter);
    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-split-rule
    optional
    string Split Rule ID that you would like to apply to this card charge in order to split and route payments to multiple accounts.

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

    If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

    Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information.
    Body Parameter Type Description
    external_id
    required
    string ID of your choice (typically the unique identifier of an invoice in your system).
    Min character: 1
    Max characters: 255 characters
    amount
    required
    number Amount on the invoice. Min and max amounts are stated here.
    The amount should be inclusive of any fees and or items that you may choose to include. If there is a difference between this amount and the sum of the price in the items parameters and or fees parameter, Xendit will refer to this amount parameter to create invoice.
    Do take note: if the currency or default currency is IDR and the amount includes decimals (e.g IDR 4550.50), the amount will be truncated to IDR 4550.
    description
    optional
    string Description of invoice - you can use this field to list what items are being paid for, or anything else of your choice that describes the function of the invoice.
    Min character: 1
    Max characters: unlimited
    customer
    optional
    object Object containing your end customer’s details. Please always include your customer’s email & mobile number if you wish to send email/WhatsApp notifications to them.
    customer child parameters
    Key Value
    given_names
    optional
    string Given name of the customer
    surname
    optional
    string Surname of the customer
    email
    optional
    string Email address of the customer
    mobile_number
    optional
    string Mobile phone number of the customer in E164 format
    addresses
    optional
    array of object Address of the customer
    customer_notification_preference
    optional
    object Object containing notification preferences for this invoice. If you wish to send notifications and reminders to your end customer, please populate the values in this object.
    You can also configure your notifications in your Invoice Settings (in your Xendit Dashboard). If you don’t set notification preferences via API, we will refer to the configurations in your Invoice Settings.
    customer_notification_preference child parameters
    Key Value
    invoice_created
    optional
    array of strings Specify which channel you want to notify your end customer through when you create a payment/invoice

    Possible enum values: ["whatsapp", "email", "viber"]

    If you do not specify values for this object, your end user will not be notified for this notification type
    invoice_reminder
    optional
    array of strings Specify which channel you want to notify your end customer through when you want to remind your customer to complete their payment

    Possible enum values: ["whatsapp", "email", "viber"]

    If you do not specify values for this object, your end user will not be notified for this notification type
    invoice_paid
    optional
    array of strings Specify which channel you want to notify your end customer through when they have successfully completed payment

    Possible enum values: ["whatsapp", "email", "viber"]

    If you do not specify values for this object, your end user will not be notified for this notification type
    invoice_duration
    optional
    number Duration of time that the end customer is given to pay the invoice before expiration (in seconds, since creation). Default is 24 hours (86,400 seconds).

    Min number: 1 second
    Max number: 31536000 seconds (1 year)
    success_redirect_url
    optional
    string URL that the end customer will be redirected to upon successful invoice payment.
    Example : https://yourcompany.com/example_item/10/success_page.

    Min character: 1
    Max characters: 255 characters
    failure_redirect_url
    optional
    string URL that end user will be redirected to upon expiration of this invoice.
    Example : https://yourcompany.com/example_item/10/failed_checkout.

    Min character: 1
    Max characters: 255 characters
    payment_methods
    optional
    array of strings Specify the payment channels that you wish to be available on your Invoice / Checkout UI. Leave this field empty if you would like all payment channels to be available on this particular invoice, or if you want to use the defaults set in your Xendit Dashboard Settings.

    Possible values for Indonesia: ["CREDIT_CARD", "BCA", "BNI", BSI, "BRI", "MANDIRI", "PERMATA", "SAHABAT_SAMPOERNA", "BNC", "ALFAMART", "INDOMARET", "OVO", "DANA", "SHOPEEPAY", "LINKAJA", "JENIUSPAY", "DD_BRI", "DD_BCA_KLIKPAY", "KREDIVO", "AKULAKU", "ATOME", "QRIS"]

    Possible values for Philippines: ["CREDIT_CARD", "7ELEVEN", "CEBUANA", "DD_BPI", "DD_UBP", "DD_RCBC", "DD_BDO_EPAY", "DP_MLHUILLIER", "DP_PALAWAN", "DP_ECPAY_LOAN", "PAYMAYA", "GRABPAY", "GCASH", "SHOPEEPAY", "BILLEASE", "CASHALO", "BDO_ONLINE_BANKING", "BPI_ONLINE_BANKING", "UNIONBANK_ONILNE_BANKING", "BOC_ONLINE_BANKING", "CHINABANK_ONLINE_BANKING", "INSTAPAY_ONLINE_BANKING", "LANDBANK_ONLINE_BANKING", "MAYBANK_ONLINE_BANKING", "METROBANK_ONLINE_BANKING", "PNB_ONLINE_BANKING", "PSBANK_ONLINE_BANKING", "PESONET_ONLINE_BANKING", "RCBC_ONLINE_BANKING", "ROBINSONS_BANK_ONLINE_BANKING", "SECURITY_BANK_ONLINE_BANKING", "QRPH"]

    Possible values for Thailand: ["CREDIT_CARD", "PROMPTPAY", "LINEPAY", "WECHATPAY", "TRUEMONEY", "SHOPEEPAY", "DD_SCB_MB", "DD_BBL_MB", "DD_KTB_MB", "DD_BAY_MB", "DD_KBANK_MB"]

    Possible values for Vietnam: ["CREDIT_CARD", "APPOTA", "ZALOPAY", "VNPTWALLET", "VIETTELPAY", "SHOPEEPAY", "WOORI", "VIETCAPITAL", "VPB", "BIDV"]

    Possible values for Malaysia: ["CREDIT_CARD", "TOUCHNGO", "WECHATPAY", "DD_UOB_FPX", "DD_PUBLIC_FPX", "DD_AFFIN_FPX", "DD_AGRO_FPX", "DD_ALLIANCE_FPX", "DD_AMBANK_FPX", "DD_ISLAM_FPX", "DD_MUAMALAT_FPX", "DD_BOC_FPX", "DD_RAKYAT_FPX", "DD_BSN_FPX", "DD_CIMB_FPX", "DD_HLB_FPX", "DD_HSBC_FPX", "DD_KFH_FPX", "DD_MAYB2U_FPX", "DD_OCBC_FPX", "DD_RHB_FPX", "DD_SCH_FPX", "AFFIN_FPX_BUSINESS", "AGRO_FPX_BUSINESS", "ALLIANCE_FPX_BUSINESS", "AMBANK_FPX_BUSINESS", "ISLAM_FPX_BUSINESS", "MUAMALAT_FPX_BUSINESS", "BNP_FPX_BUSINESS", "CIMB_FPX_BUSINESS", "CITIBANK_FPX_BUSINESS", "DEUTSCHE_FPX_BUSINESS", "HLB_FPX_BUSINESS", "HSBC_FPX_BUSINESS", "RAKYAT_FPX_BUSINESS", "KFH_FPX_BUSINESS", "MAYB2E_FPX_BUSINESS", "OCBC_FPX_BUSINESS", "PUBLIC_FPX_BUSINESS", "RHB_FPX_BUSINESS", "SCH_FPX_BUSINESS", "UOB_FPX_BUSINESS"]

    For more info on each payment method, see here
    currency
    optional
    string Currency of the amount that you created
    Possible values : IDR, PHP, THB, VND, MYR
    callback_virtual_account_id
    optional
    string To allow payment via Fixed Virtual Account, pass in the id field value from the response when the fixed virtual account was created. See Create Fixed Virtual Accounts
    mid_label
    optional
    string MID label when you have an acquiring bank, and are using credit cards.
    reminder_time_unit
    optional

    default: days
    string Signifies the unit for reminder_time field. The value can be either days or hours
    reminder_time
    optional
    integer positive Signifies when a reminder notification will be sent before the invoice expires.
    When reminder_time_unit is days, allowed values are between 1 and 30.
    When reminder_time_unit is hours, allowed values are between 1 and 24.
    locale
    optional
    string The default language to display.
    Currently supporting : en or id

    You can also configure your default language in Invoice Settings in Xendit Dashboard. If you do not set the locale, we will refer to the configurations in your Invoice Settings.
    items
    optional

    *mandatory for PayLater payment method
    array Array of items JSON objects describing the item(s) purchased. Max array size: 75. Mandatory for PayLater payment method.
    Items child parameters
    Key Value
    name
    required
    string Name of the product

    Maximum length 256 characters
    quantity
    required
    number Number of units of this item in the basket
    Maximum value 510000
    price
    required
    number Price per unit in basket currency
    category
    optional
    string Merchant category for item
    Example: Fashion, Electronic
    url
    optional
    string The public URL of the specific item detail page. Must be HTTP or HTTPS

    Example:https://yourcompany.com/example_item
    fees
    optional
    array Array of items JSON objects describing the fee(s) that you charge to your end customer. This can be an admin fee, logistics fee, etc. This amount will be included in the total invoice amount and will be transferred to your balance when the transaction settles. Max array size: 10.
    Fees child parameters
    Key Value
    type
    required
    string Specify any string value that describes the fee you are charging your customer, e.g: admin, shipping, tax, discount. We recommend you keep your fee types consistent and simple.
    value
    required
    number Amount of this specific fee. Can be positive or negative.
    Xendit recommends merchants to comply with local regulations when using this parameter to pass on transaction fees. Certain countries do not allow that (e.g. Indonesia)
    should_authenticate_credit_card
    optional
    boolean Specify whether you want this checkout transaction to go through 3DS (credit card authentication). Please make sure "Optional 3DS" is enabled in your Credit Card Settings. If Optional 3DS is disabled, all checkout transactions paid via card will go through 3DS, regardless of the value of this parameter.
    channel_properties
    optional
    object Specify the configuration of each payment method or payment channel that will be used for this payment link creation
    Cards channel child parameters
    Key Value
    allowed_bins
    optional
    array of strings Specify the credit card BIN that will be accepted by this payment link.
    Length of credit card BIN should be either 6 or 8 digits
    installment_configuration
    optional
    array of objects Specify the configuration of the credit card installment property
    installment_configuration child parameters
    Key Value
    allow_installment
    optional
    boolean Specify whether end users can pay with installments.
    Default value: true
    allow_full_payment
    optional
    boolean Specify whether you also want to allow the full payment option to be displayed in the payment link UI.
    Default value: true
    allowed_terms
    optional
    array of objects Specify the allowed terms of your installment configuration
    allowed_terms child parameters
    Key Value
    issuer
    required
    string Specify the issuing bank of the credit card that can be processed by the payment link.

    Possible values for Indonesia: BCA, BNI, MANDIRI, BRI, PERMATA, OCBCNISP, HSBCID, BTPN, DBSID, CIMB, DANAMON, UOBID, MAYBANKID, BSI
    terms
    required
    array of numbers Specify the terms of installment payment that will appear in the payment link UI
    values must be a positive number.
    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

    Response Parameters

    Example Create Invoice Response

    {
        "id": "65fc7522ff846905c2fc1c8d",
        "external_id": "payment-link-example",
        "user_id": "65e95b2b3e4690f17fab20ad",
        "status": "PENDING",
        "merchant_name": "Honey Badger Business",
        "merchant_profile_picture_url": "https://du8nwjtfkinx.cloudfront.net/xendit.png",
        "amount": 510000,
        "description": "Checkout Demo #123",
        "expiry_date": "2024-03-22T17:57:54.578Z",
        "invoice_url": "https://checkout-staging.xendit.co/v2/65fc7522ff846905c2fc1c8d",
        "available_banks": [
            {
                "bank_code": "MANDIRI",
                "collection_type": "POOL",
                "transfer_amount": 510000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "CARDS AUTOMATION TEST",
                "identity_amount": 0
            },
            {
                "bank_code": "BRI",
                "collection_type": "POOL",
                "transfer_amount": 510000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "CARDS AUTOMATION TEST",
                "identity_amount": 0
            },
            {
                "bank_code": "BNI",
                "collection_type": "POOL",
                "transfer_amount": 510000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "CARDS AUTOMATION TEST",
                "identity_amount": 0
            },
            {
                "bank_code": "PERMATA",
                "collection_type": "POOL",
                "transfer_amount": 510000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "CARDS AUTOMATION TEST",
                "identity_amount": 0
            },
            {
                "bank_code": "BCA",
                "collection_type": "POOL",
                "transfer_amount": 510000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "CARDS AUTOMATION TEST",
                "identity_amount": 0
            },
            {
                "bank_code": "SAHABAT_SAMPOERNA",
                "collection_type": "POOL",
                "transfer_amount": 510000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "CARDS AUTOMATION TEST",
                "identity_amount": 0
            },
            {
                "bank_code": "CIMB",
                "collection_type": "POOL",
                "transfer_amount": 510000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "CARDS AUTOMATION TEST",
                "identity_amount": 0
            },
            {
                "bank_code": "BSI",
                "collection_type": "POOL",
                "transfer_amount": 510000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "CARDS AUTOMATION TEST",
                "identity_amount": 0
            },
            {
                "bank_code": "BJB",
                "collection_type": "POOL",
                "transfer_amount": 510000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "CARDS AUTOMATION TEST",
                "identity_amount": 0
            },
            {
                "bank_code": "BNC",
                "collection_type": "POOL",
                "transfer_amount": 510000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "CARDS AUTOMATION TEST",
                "identity_amount": 0
            }
        ],
        "available_retail_outlets": [
            {
                "retail_outlet_name": "ALFAMART"
            },
            {
                "retail_outlet_name": "INDOMARET"
            }
        ],
        "available_ewallets": [
            {
                "ewallet_type": "SHOPEEPAY"
            },
            {
                "ewallet_type": "ASTRAPAY"
            },
            {
                "ewallet_type": "JENIUSPAY"
            },
            {
                "ewallet_type": "DANA"
            },
            {
                "ewallet_type": "LINKAJA"
            },
            {
                "ewallet_type": "OVO"
            },
            {
                "ewallet_type": "NEXCASH"
            }
        ],
        "available_qr_codes": [
            {
                "qr_code_type": "QRIS"
            }
        ],
        "available_direct_debits": [
            {
                "direct_debit_type": "DD_BRI"
            },
            {
                "direct_debit_type": "DD_MANDIRI"
            }
        ],
        "available_paylaters": [
            {
                "paylater_type": "KREDIVO"
            },
            {
                "paylater_type": "AKULAKU"
            },
            {
                "paylater_type": "ATOME"
            }
        ],
        "should_exclude_credit_card": false,
        "should_send_email": false,
        "success_redirect_url": "https://www.google.com",
        "failure_redirect_url": "https://www.google.com",
        "created": "2024-03-21T17:57:55.128Z",
        "updated": "2024-03-21T17:57:55.128Z",
        "currency": "IDR",
        "items": [
            {
                "name": "Air Conditioner",
                "quantity": 1,
                "price": 510000,
                "category": "Electronic",
                "url": "https://yourcompany.com/example_item"
            }
        ],
        "fees": [
            {
                "type": "ADMIN",
                "value": 5000
            }
        ],
        "customer": {
            "given_names": "John",
            "surname": "Doe",
            "email": "johndoe@example.com",
            "mobile_number": "+6287774441111",
            "addresses": [
                {
                    "city": "Jakarta Selatan",
                    "country": "Indonesia",
                    "postal_code": "12345",
                    "state": "Daerah Khusus Ibukota Jakarta",
                    "street_line1": "Jalan Makan",
                    "street_line2": "Kecamatan Kebayoran Baru"
                }
            ]
        },
        "customer_notification_preference": {
            "invoice_created": [
                "whatsapp",
                "email",
                "viber"
            ],
            "invoice_reminder": [
                "whatsapp",
                "email",
                "viber"
            ],
            "invoice_paid": [
                "whatsapp",
                "email",
                "viber"
            ]
        },
        "channel_properties": {
            "cards": {
                "allowed_bins": [
                    "400000",
                    "52000000"
                ],
                "installment_configuration": {
                    "allow_installment": true,
                    "allow_full_payment": false,
                    "allowed_terms": [
                        {
                            "issuer": "BRI",
                            "terms": [
                                3,
                                6,
                                12
                            ]
                        },
                        {
                            "issuer": "BNI",
                            "terms": [
                                3,
                                6
                            ]
                        }
                    ]
                }
            }
        },
        "metadata": {
          "store_branch": "Jakarta"
        }
    }
    Parameter Type Description
    id string An invoice ID generated by Xendit
    external_id string The invoice ID in your server, that can be used to reconcile between you and Xendit
    user_id string Your Xendit Business ID
    status string Status showing whether the invoice has been paid
    Possible values: PENDING, PAID, EXPIRED
    PENDING means the invoice has been successfully created but yet to be paid
    PAID means the invoice has been paid
    EXPIRED means the invoice expired before your customer paid
    merchant_name string The name of your company or website
    merchant_profile_picture_url string The URL to profile picture of your company
    amount number Nominal amount for the invoice
    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
    expiry_date string ISO date and time that the invoice expires. Default is 24 hours.
    invoice_url string Public URL for this invoice - your customer can click this link to access the Checkout UI for this invoice
    customer object Object containing your end customer’s details. Please always include your customer’s email & mobile number if you wish to send email/WhatsApp notifications to them.
    given_names
    optional
    string Given name of the customer
    surname
    optional
    string Surname of the customer
    email
    optional
    string Email address of the customer
    mobile_number
    optional
    string Mobile phone number of the customer in E164 format
    addresses
    optional
    array of object Address of the customer
    customer_notification_preference object Object containing notification preferences for this invoice. If you wish to send notifications and reminders to your end customer, please populate the values in this object.

    You can also configure your notifications in your Invoice Settings (in your Xendit Dashboard). If you don’t set notification preferences via API, we will refer to the configurations in your Invoice Settings.
    invoice_created
    optional
    array of strings Specify which channel you want to notify your end customer through when you create a payment/invoice
    Possible enum values:
    ["whatsapp", "email", "viber"]
    If you do not specify values for this object, your end user will not be notified for this notification type
    invoice_reminder
    optional
    array of strings Specify which channel you want to notify your end customer through when you want to remind your customer to complete their payment
    Possible enum values:
    ["whatsapp", "email", "viber"]
    If you do not specify values for this object, your end user will not be notified for this notification type
    invoice_paid
    optional
    array of strings Specify which channel you want to notify your end customer through when they have successfully completed payment
    Possible enum values:
    ["whatsapp", "email", "viber"]
    If you do not specify values for this object, your end user will not be notified for this notification type
    available_banks object Available bank transfer (virtual account) channels available, as per your configuration
    bank_code BCA / BNI / BSI / BRI / MANDIRI / PERMATA / BNC
    collection_type POOL type is nonfixed virtual account
    transfer_amount WILL BE DEPRECATED SOON. Amount the user should transfer
    bank_branch Bank account type
    account_holder_name Bank account holder name
    available_retail_outlets object Available retail outlets as per your configuration
    retail_outlet_name Name of the retail outlet
    transfer_amount WILL BE DEPRECATED SOON. Amount the user should transfer
    available_ewallets object Available e-ewallet channels available, as per your configuration
    ewallet_type Name of the ewallet
    OVO, DANA, SHOPEEPAY, LINKAJA, GRABPAY, GCASH, TOUCHNGO
    available_qr_codes object Available QR payment channels, as per your configuration
    qr_code_type Name of the QR payment channel
    QRIS, PROMPTPAY
    reminder_date
    optional
    string ISO8601 An ISO timestamp that the customer will be sent an invoice reminder email (when they send reminder_time for invoice creation).
    Timezone: GMT+0
    fixed_va boolean
    WILL BE DEPRECATED SOON. A flag showing whether you have chosen to bind a fixed VA to this invoice (either TRUE or FALSE)
    mid_label string MID label that you have when you are using credit card payment and have acquiring bank. You will get this response when you add this parameter when create invoice through API
    should_exclude_credit_card boolean A flag showing if credit card should be excluded in invoice UI or not
    should_send_email boolean Shows whether you will send email notifications for this invoice
    WILL BE DEPRECATED SOON. If you wish to send email notifications to your end users, please provide values in the customer_notification_preference object
    created string An ISO timestamp that tracks when the invoice was created (UTC GMT+0)
    updated string An ISO timestamp that tracks when the invoice was updated (UTC GMT+0)
    currency string Currency of the amount that you created. You will get this response when you add this parameter when create invoice through API
    items
    optional
    array Array of items JSON objects describing the item(s) purchased
    name
    required
    string Name of the product
    quantity
    required
    number Number of units of this item in the basket
    price
    required
    number Price per unit in basket currency
    category
    optional
    string Merchant category for item
    Example: Fashion, Electronic
    url
    optional
    string The public URL of the specific item detail page

    Example: https://yourcompany.com/example_item
    fees
    optional
    array Array of fees JSON objects describing the fee(s) that you charge to your end customer
    type
    required
    string Type of the fee
    value
    required
    number Amount of this specific fee
    should_authenticate_credit_card
    optional
    boolean Specify whether you want this checkout transaction to go through 3DS (credit card authentication). Please make sure "Optional 3DS" is enabled in your Credit Card Settings. If Optional 3DS is disabled, all checkout transactions paid via card will go through 3DS, regardless of the value of this parameter.
    channel_properties
    optional
    object Specify the configuration of each payment method or payment channel that will be used for this payment link creation
    Cards channel child parameters
    Key Value
    allowed_bins
    optional
    array of strings Specify the credit card BIN that will be accepted by this payment link.
    Length of credit card BIN should be either 6 or 8 digits
    installment_configuration
    optional
    array of objects Specify the configuration of the credit card installment property
    installment configuration child parameters
    Key Value
    allow_installment
    optional
    boolean Specify whether end users can pay with installments
    Default value: true
    allow_full_payment
    optional
    boolean Specify whether you also want to allow the full payment option to be displayed in the payment link UI
    Default value: true
    allowed_terms
    optional
    array of objects Specify the allowed terms of your installment configuration
    allowed terms child parameters
    Key Value
    issuer
    required
    string Specify the issuing bank of the credit card that can be processed by the payment link.

    Possible values for Indonesia: BCA, BNI, MANDIRI, BRI, PERMATA, OCBCNISP, HSBCID, BTPN, DBSID, CIMB, DANAMON, UOBID, MAYBANKID, BSI

    NOTE: By default, Xendit will support installment connection for BNI and BRI. If you want to enable the installment for the other banks, you have to connect directly with the bank, then let our CS know.
    terms
    required
    array of numbers Specify the terms of installment payment that will appear in the payment link UI.
    Values must be a positive number
    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

    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.
    NO_COLLECTION_METHODS_ERROR
    400
    Your account has no payment methods configured (virtual account, credit card). Please contact support and we will set this up for you.
    UNAVAILABLE_PAYMENT_METHOD_ERROR
    400
    The payment method choices did not match with the available one on this business.
    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
    UNIQUE_ACCOUNT_NUMBER_UNAVAILABLE_ERROR
    404
    There is no available virtual account in your non-fixed virtual account range.
    CALLBACK_VIRTUAL_ACCOUNT_NOT_FOUND_ERROR
    404
    Fixed virtual account id that you've specified not found
    AVAILABLE_PAYMENT_CODE_NOT_FOUND_ERROR
    404
    There is no available payment code in your retail outlet range.
    INVALID_REMINDER_TIME
    400
    The reminder_time value is not allowed.
    INSTALLMENT_CONFIGURATION_NOT_AVAILABLE
    400
    The installment bank_code (ABC) configuration is not available for your business. Please contact our CS to enable it
    INSTALLMENT_NOT_ENABLED
    400
    The installment option is not available for your business. Please contact our CS to enable it
    AMOUNT_BELOW_MINIMUM_LIMIT
    400
    Requested amount 51000 is lower than installment minimum limit

    Get Invoice

    Endpoint: Get an Invoice

    GET https://api.xendit.co/v2/invoices/{invoice_id}

    Request Parameters

    Example Get Invoice Request by External ID

    curl https://api.xendit.co/v2/invoices/?external_id={external_id} -X GET \
        -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:

    Example Get Invoice Request by Invoice ID (Default)

    curl https://api.xendit.co/v2/invoices/{invoice_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 = '579c8d61f23fa4ca35e52da4';
      $getInvoice = \Xendit\Invoice::retrieve($id);
      var_dump($getInvoice);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Invoice } = x;
    const invoiceSpecificOptions = {};
    const i = new Invoice(invoiceSpecificOptions);
    
    const resp = await i.getInvoice({
      invoiceID: '587cc7b4863f2b462beb31f6',
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Invoice invoice = Invoice.getById("my_external_id");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := invoice.GetParams{
      ID: "579c8d61f23fa4ca35e52da4",
    }
    
    resp, err := invoice.Get(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("retrieved invoice: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    Invoice = xendit_instance.Invoice
    
    invoice = Invoice.get(
        invoice_id="5efda8a20425db620ec35f43",
    )
    print(invoice)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    InvoiceClient invoice = xendit.Invoice;
    
    InvoiceResponse invoiceResponse = await invoice.GetById("5efda8a20425db620ec35f43");
    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
    invoice_id
    required
    string ID of the invoice to retrieve

    Response Parameters

    Example Get Invoice Response

    {
      "id": "579c8d61f23fa4ca35e52da4",
      "user_id": "5781d19b2e2385880609791c",
      "external_id": "invoice_123124123",
      "status": "PENDING",
      "merchant_name": "Xendit",
      "merchant_profile_picture_url": "https://xnd-companies.s3.amazonaws.com/prod/1493610897264_473.png",
      "amount": 50000,
      "payer_email": "alfina@xendit.co",
      "description": "This is a description",
      "invoice_url": "https://invoice.xendit.co/web/invoices/595b6248c763ac05592e3eb4",
      "expiry_date": "2020-01-31T11:20:01.017Z",
      "available_banks": [
        {
                "bank_code": "MANDIRI",
                "collection_type": "POOL",
                "bank_account_number": "8860810000525",
                "transfer_amount": 50000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "LANSUR13",
            },
            {
                "bank_code": "BRI",
                "collection_type": "POOL",
                "bank_account_number": "2621510002426",
                "transfer_amount": 50000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "LANSUR13",
            },
            {
                "bank_code": "BNI",
                "collection_type": "POOL",
                "bank_account_number": "880810000689",
                "transfer_amount": 50000,
                "bank_branch": "Virtual Account",
                "account_holder_name": "LANSUR13",
            }
      ],
      "available_retail_outlets": [
          {
              "retail_outlet_name": "ALFAMART",
              "payment_code": "ALFA123456",
              "transfer_amount": 54000
          }
      ],
      "available_paylaters": [
          {
              "paylater_type": "AKULAKU"
          }
      ],
      "should_exclude_credit_card": false,
      "should_send_email": false,
      "created": "2020-01-01T14:00:00.306Z",
      "updated": "2020-01-01T14:00:00.306Z",
      "mid_label": "test-mid",
      "currency": "IDR",
      "paid_at": "2020-01-02T11:00:00.306Z",
      "credit_card_charge_id": "579c8d61f23fa4ca35e52eas",
      "payment_method": "BANK_TRANSFER",
      "payment_channel": "BCA",
      "payment_destination": "10002233222294375",
      "success_redirect_url": "www.xendit.co",
      "failure_redirect_url": "www.xendit.co",
      "fixed_va":true,
      "locale": "en"
    }



    Parameter Description
    id An invoice ID generated by Xendit
    user_id Your Xendit Business ID
    external_id The invoice ID in your server, that can be used to reconcile between you and Xendit
    status PENDING the invoice has yet to be paid
    PAID the invoice has successfully been paid
    SETTLED the amount of paid invoice has been settled to cash balance
    EXPIRED the invoice has been expired
    merchant_name The name of your company or website
    merchant_profile_picture_url The URL to profile picture of your company
    amount Nominal amount for the invoice
    payer_email Email of the payer, we get this information from your API call
    description Description for the invoice, we get this information from your API call
    invoice_url Public URL for this invoice, it’s there in case you want to use our UI
    customer Object containing your end customer’s details.
    given_names
    Given name of the customer
    surname
    Surname of the customer
    email
    Email address of the customer
    mobile_number
    Mobile phone number of the customer in E164 format
    addresses
    Address of the customer
    customer_notification_preference Object containing notification preferences for this invoice.
    invoice_created
    Possible enum values:
    ["whatsapp", "email", "viber"]
    invoice_reminder
    Possible enum values:
    ["whatsapp", "email", "viber"]
    invoice_paid
    Possible enum values:
    ["whatsapp", "email", "viber"]
    expiry_date ISO date and time that the invoice expires. Default is 24 hours.
    available_banks Available payment methods through banks as per your config
    bank_code BCA / MANDIRI / BNI / BRI / PERMATA / BSI / BNC
    collection_type POOL type is nonfixed virtual account
    bank_account_number
    optional
    Bank account number for users to pay into
    transfer_amount WILL BE DEPRECATED SOON. Amount the user should transfer
    bank_branch Bank account type
    account_holder_name Bank account holder name
    available_retail_outlets
    Available payment methods through retail outlet as per your config
    retail_outlet_name Name of the retail outlet
    payment_code
    optional
    Unique code that you use to pay in retail outlet
    transfer_amount WILL BE DEPRECATED SOON. Amount the user should transfer
    should_exclude_credit_card

    A flag showing if credit card should be excluded in invoice UI or not

    should_send_email

    A flag showing should payer get email when invoice is created, paid, or expired; or not

    updated

    An ISO timestamp that tracks when the invoice was updated

    created

    An ISO timestamp that tracks when the invoice was created

    mid_label MID label that you have when you are using credit card payment and have acquiring bank. You will get this response when you add this parameter when create invoice through API
    currency Currency of the amount that you created. You will get this response when you add this parameter when create invoice through API
    success_redirect_url URL that end user will be redirected to upon successful invoice payment. You will get this response when you add this parameter when create invoice through API
    failure_redirect_url URL that end user will be redirected to upon expiration of this invoice. You will get this response when you add this parameter when create invoice through API
    paid_at Date time data when your customer pay the invoice. You will get this response when your invoice is paid
    credit_card_charge_id Credit card charge ID when your customer pay the invoice with credit card. You will get this response when your invoice is paid with Credit Card
    payment_method Payment method that is used when a customer pays the invoice. You will get this response when your invoice is paid
    Example : ["BANK_TRANSFER", "CREDIT_CARD", "RETAIL_OUTLET", "EWALLET"]
    payment_channel The payment channel used when a customer pays the invoice. You will get this response when your invoice is paid
    Example : ["BCA", "BRI", "MANDIRI", "BNI", "PERMATA", "BSI", "BNC", "ALFAMART", "OVO", "CREDIT_CARD"]
    payment_destination Virtual Account number or Retail Outlet payment code used to pay the invoice (will not be shown for cards and e-wallet payments). You will get this response when your invoice is paid
    fixed_va
    WILL BE DEPRECATED SOON. Input this parameter as true to enable one VA number for Your end customers.
    locale Bahasa default yang dikonfigurasi ke faktur.
    items
    optional
    Array of items JSON objects describing the item(s) purchased
    name
    required
    string Name of the product
    quantity
    required
    number Number of units of this item in the basket
    price
    required
    number Price per unit in basket currency
    category
    optional
    string Merchant category for item
    Example: Fashion, Electronic
    url
    optional
    string The public URL of the specific item detail page

    Example: https://yourcompany.com/example_item
    fees
    optional
    Array of fees JSON objects describing the fee(s) that you charge to your end customer
    type
    required
    string Unique type of the fee
    value
    required
    number Amount of this specific fee
    payment_details
    optional
    Object containing payment details. Currently supporting QRIS payment only.
    receipt_id
    optional
    string Request reference number (RRN) that is shared across the QR network. Example: "120318237"
    source
    optional
    string Source where the end user’s balance was deducted to complete the payment. Example: "OVO", "GOPAY"
    should_authenticate_credit_card
    optional
    Specify whether you want this checkout transaction to go through 3DS (credit card authentication). Please make sure "Optional 3DS" is enabled in your Credit Card Settings. If Optional 3DS is disabled, all checkout transactions paid via card will go through 3DS, regardless of the value of this parameter.
    channel_properties
    optional
    object Specify the configuration of each payment method or payment channel that will be used for this payment link creation
    Cards channel child parameters
    Key Value
    allowed_bins
    optional
    array of strings Specify credit card Bank Identification Number (BIN) that can be accepted by this payment link. The allowed BINs will override any installments's allowed_terms that have been configured.
    Length of credit card BIN should be either 6 or 8 digits
    installment_configuration
    optional
    array of objects Specify how installments configurations presented to end user
    installment_configuration child parameters
    Key Value
    allow_installment
    optional
    boolean Specify whether end users can pay with installments
    Default value: true
    allow_full_payment
    optional
    boolean Specify whether end users can pay upfront or end users must pay with installments
    Default value: true
    allowed_terms
    optional
    array of objects Specify the installment tenure/ bank combination that end users can choose from
    allowed_terms child parameters
    Key Value
    issuer
    required
    if allowed_terms field exists in the request
    string Specify the issuing bank of the credit card.

    Possible values for Indonesia: BCA, BNI, MANDIRI, BRI, PERMATA, OCBCNISP, HSBCID, BTPN, DBSID, CIMB, DANAMON, UOBID, MAYBANKID, BSI
    terms
    required
    if allowed_terms field exists in the request
    array of numbers Specify the installment terms will be surface on the payment link.
    metadata
    optional
    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

    Error Code Description
    INVALID_JSON_FORMAT
    400
    The request body is not a valid JSON format.
    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
    INVOICE_NOT_FOUND_ERROR
    404
    Could not find invoice by id.

    Expire Invoice

    Endpoint: Expire Invoice

    POST https://api.xendit.co/invoices/{invoice_id}/expire!

    You can cancel an already created invoice by expiring it immediately using this endpoint.

    Note:

    1. Expiring an invoice will close available payment methods: Pool Virtual Account, Retail Outlet, and Credit Card, but not Fixed Virtual Account.
    2. Expiring an invoice which is linked to Fixed Virtual Accounts will only unlink the Fixed Virtual Account's relation to the invoice, so further payments to this Fixed Virtual Account will be detected as Fixed Virtual Account payments instead of invoice payments. To expire Fixed Virtual Accounts, change the expiration_date using Update Fixed Virtual Account Endpoint

    Request Parameters

    Example Expire Invoice Request

    curl https://api.xendit.co/invoices/{invoice_id}/expire! -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==');
    
      $id = '579c8d61f23fa4ca35e52da4';
      $expireInvoice = \Xendit\Invoice::expireInvoice($id);
      var_dump($expireInvoice);
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Invoice } = x;
    const invoiceSpecificOptions = {};
    const i = new Invoice(invoiceSpecificOptions);
    
    const resp = await i.expireInvoice({
      invoiceID: '587cc7b4863f2b462beb31f6',
    });
    console.log(resp);
    Xendit.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    try {
      Invoice invoice = Invoice.expire("EXAMPLE_ID");
    } catch (XenditException e) {
      e.printStackTrace();
    }
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    data := invoice.ExpireParams{
      ID: "579c8d61f23fa4ca35e52da4",
    }
    
    resp, err := invoice.Expire(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("expired invoice: %+v\n", resp)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    Invoice = xendit_instance.Invoice
    
    invoice = Invoice.expire(
        invoice_id="5efda8a20425db620ec35f43",
    )
    print(invoice)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    InvoiceClient invoice = xendit.Invoice;
    
    InvoiceResponse invoiceResponse = await invoice.Expire("5efda8a20425db620ec35f43");
    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
    invoice_id
    required
    string ID of the invoice to be expired / canceled

    Response Parameters

    Example Expire Invoice Response

    {
      "id": "579c8d61f23fa4ca35e52da4",
      "user_id": "5781d19b2e2385880609791c",
      "external_id": "invoice_123124123",
      "status": "EXPIRED",
      "merchant_name": "Xendit",
      "merchant_profile_picture_url": "https://xnd-companies.s3.amazonaws.com/prod/1493610897264_473.png",
      "amount": 50000,
      "payer_email": "alfina@xendit.co",
      "description": "This is a description",
      "invoice_url": "https://invoice.xendit.co/web/invoices/595b6248c763ac05592e3eb4",
      "expiry_date": "2020-04-01T11:20:01.017Z",
      "available_banks": [
        {
          "bank_code": "BCA",
          "collection_type": "POOL",
          "bank_account_number": 1000008,
          "transfer_amount": 54000
        },
        {
          "bank_code": "MANDIRI",
          "collection_type": "POOL",
          "bank_account_number": 1000009,
          "transfer_amount": 54000
        }
      ],
      "available_retail_outlets": [
          {
              "retail_outlet_name": "ALFAMART",
              "payment_code": "ALFA123456",
              "transfer_amount": 54000
          }
      ],
      "should_exclude_credit_card": false,
      "should_send_email": false,
      "created": "2020-01-12T14:00:00.306Z",
      "updated": "2020-01-12T14:00:00.306Z"
    }
    Parameter Description
    id An invoice ID generated by Xendit
    user_id Your Xendit Business ID
    external_id The invoice ID in your server, that can be used to reconcile between you and Xendit
    status EXPIRED the invoice has been expired
    merchant_name The name of your company or website
    merchant_profile_picture_url The URL to profile picture of your company
    amount Nominal amount for the invoice
    payer_email Email of the payer, we get this information from your API call
    description Description for the invoice, we get this information from your API call
    invoice_url Public URL for this invoice, it’s there in case you want to use our UI
    customer Object containing your end customer’s details.
    given_names
    Given name of the customer
    surname
    Surname of the customer
    email
    Email address of the customer
    mobile_number
    Mobile phone number of the customer in E164 format
    addresses
    Address of the customer
    customer_notification_preference Object containing notification preferences for this invoice.
    invoice_created
    Possible enum values:
    ["whatsapp", "email", "viber"]
    invoice_reminder
    Possible enum values:
    ["whatsapp", "email", "viber"]
    invoice_paid
    Possible enum values:
    ["whatsapp", "email", "viber"]
    expiry_date ISO date and time that the invoice expires. Default is 24 hours.
    available_banks Available payment methods through banks as per your config
    bank_code BCA / MANDIRI / BNI / BRI / PERMATA / BSI / BNC
    collection_type POOL type is nonfixed virtual account
    bank_account_number
    optional
    Bank account number for users to pay into
    transfer_amount WILL BE DEPRECATED SOON. Amount the user should transfer
    bank_branch Bank account type
    account_holder_name Bank account holder name
    available_retail_outlets
    Available payment methods through retail outlet as per your config
    retail_outlet_name Name of the retail outlet
    payment_code
    optional
    Unique code that you use to pay in retail outlet
    transfer_amount WILL BE DEPRECATED SOON. Amount the user should transfer
    should_exclude_credit_card

    A flag showing if credit card should be excluded in invoice UI or not

    should_send_email

    A flag showing should payer get email when invoice is created, paid, or expired; or not

    updated

    An ISO timestamp that tracks when the invoice was updated

    created

    An ISO timestamp that tracks when the invoice was created

    items
    optional
    Array of items JSON objects describing the item(s) purchased
    name
    required
    string Name of the product
    quantity
    required
    number Number of units of this item in the basket
    price
    required
    number Price per unit in basket currency
    category
    optional
    string Merchant category for item
    Example: Fashion, Electronic
    url
    optional
    string The public URL of the specific item detail page

    Example: https://yourcompany.com/example_item
    fees
    optional
    Array of fees JSON objects describing the fee(s) that you charge to your end customer
    type
    required
    string Unique type of the fee
    value
    required
    number Amount of this specific fee
    should_authenticate_credit_card
    optional
    Specify whether you want this checkout transaction to go through 3DS (credit card authentication). Please make sure "Optional 3DS" is enabled in your Credit Card Settings. If Optional 3DS is disabled, all checkout transactions paid via card will go through 3DS, regardless of the value of this parameter.
    metadata
    optional
    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

    Error Code Description
    INVALID_JSON_FORMAT
    400
    The request body is not a valid JSON format.
    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
    INVOICE_NOT_FOUND_ERROR
    404
    Could not find invoice by id.

    List All Invoices

    Endpoint: List Invoice

    GET https://api.xendit.co/v2/invoices

    You can list all invoices, or list the invoices for a specific updated time. The invoices are returned sorted by created date, with the most recently created invoices appearing first.

    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

    Example List Invoice Request

    curl https://api.xendit.co/v2/invoices?limit=3&external_id=627&statuses=["SETTLED","EXPIRED"]&last_invoice_id=5ca186e407f3b83e34176eac&client_types=["DASHBOARD","API_GATEWAY"]&after=2016-02-24T23:48:36.697Z&before=2020-02-24T23:48:36.697Z -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==');
    
      $getAllInvoice = \Xendit\Invoice::retrieveAll();
      var_dump(($getAllInvoice));
    
    ?>
    const x = new require('xendit-node')({ secretKey: 'xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==' });
    
    const { Invoice } = x;
    const invoiceSpecificOptions = {};
    const i = new Invoice(invoiceSpecificOptions);
    
    const resp = await i.getAllInvoices({
      statuses: ["SETTLED", "EXPIRED"],
      lastInvoiceID: '5ca186e407f3b83e34176eac',
      clientTypes: ["DASHBOARD","API_GATEWAY"],
    });
    console.log(resp);
    xendit.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    
    createdAfter, _ := time.Parse(time.RFC3339, "2016-02-24T23:48:36.697Z")
    data := invoice.GetAllParams{
      Statuses:     []string{"EXPIRED", "SETTLED"},
      Limit:        5,
      CreatedAfter: createdAfter,
    }
    
    resps, err := invoice.GetAll(&data)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("invoices: %+v\n", resps)
    from xendit import Xendit
    
    api_key = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="
    xendit_instance = Xendit(api_key=api_key)
    Invoice = xendit_instance.Invoice
    
    invoices = Invoice.list_all(
        limit=3,
    )
    print(invoices)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    InvoiceClient invoice = xendit.Invoice;
    
    // Invoke GetAll without specifying parameter
    InvoiceResponse[] invoicesWithoutParams = await invoice.GetAll(null);
    
    // specify parameter using ListInvoiceParameter
    ListInvoiceParameter parameter = new ListInvoiceParameter
    {
      Limit = 1,
      ClientTypes = new InvoiceClientType[] { InvoiceClientType.ApiGateway, InvoiceClientType.Dashboard },
    };
    
    InvoiceResponse[] invoices = await invoice.GetAll(parameter);

    Example List Invoice Response

    [
        {
            "id": "5c65be6880a55b02867b2b6f",
            "external_id": "627",
            "user_id": "5bbe23e1c901a730130f5b15",
            "status": "EXPIRED",
            "merchant_name": "Your Business Name",
            "merchant_profile_picture_url": "https://xnd-companies.s3.amazonaws.com/prod/1545257692599_408.jpg",
            "amount": 838838,
            "payer_email": "alfina@xendit.co",
            "description": "Trip to Bali",
            "expiry_date": "2020-02-24T23:48:36.697Z",
            "invoice_url": "https://invoice-staging.xendit.co/web/invoices/5c65be6880a55b02867b2b6f",
            "available_banks": [
                {
                    "bank_code": "MANDIRI",
                    "collection_type": "POOL",
                    "bank_account_number": "8860838034047",
                    "transfer_amount": 838838,
                    "bank_branch": "Virtual Account",
                    "account_holder_name": "YOUR BUSINESS NAME",
                },
                {
                    "bank_code": "BRI",
                    "collection_type": "POOL",
                    "bank_account_number": "2621545817176",
                    "transfer_amount": 838838,
                    "bank_branch": "Virtual Account",
                    "account_holder_name": "YOUR BUSINESS NAME",
                },
                {
                    "bank_code": "BNI",
                    "collection_type": "POOL",
                    "bank_account_number": "880845676187",
                    "transfer_amount": 838838,
                    "bank_branch": "Virtual Account",
                    "account_holder_name": "YOUR BUSINESS NAME",
                }
            ],
            "available_ewallets": [],
            "available_paylaters": [],
            "should_exclude_credit_card": false,
            "should_send_email": false,
            "created": "2020-01-14T23:48:56.907Z",
            "updated": "2020-01-24T23:49:03.296Z"
        },
        {
            "id": "5c6398b710a54b0c867b2b52",
            "external_id": "627",
            "user_id": "5bbe23e1c901a730130f5b15",
            "status": "SETTLED",
            "merchant_name": "Your Business Name",
            "merchant_profile_picture_url": "https://xnd-companies.s3.amazonaws.com/prod/1545257692599_408.jpg",
            "amount": 67888,
            "paid_amount": 67888,
            "bank_code": "MANDIRI",
            "payer_email": "budi@xendit.co",
            "description": "Trip to Bali",
            "expiry_date": "2020-02-24T16:34:24.341Z",
            "invoice_url": "https://invoice-staging.xendit.co/web/invoices/5c6398b710a54b0c867b2b52",
            "available_banks": [
                {
                    "bank_code": "MANDIRI",
                    "collection_type": "POOL",
                    "bank_account_number": "8860838033759",
                    "transfer_amount": 67888,
                    "bank_branch": "Virtual Account",
                    "account_holder_name": "YOUR BUSINESS NAME",
                },
                {
                    "bank_code": "BRI",
                    "collection_type": "POOL",
                    "bank_account_number": "2621545816888",
                    "transfer_amount": 67888,
                    "bank_branch": "Virtual Account",
                    "account_holder_name": "YOUR BUSINESS NAME",
                },
                {
                    "bank_code": "BNI",
                    "collection_type": "POOL",
                    "bank_account_number": "880845675899",
                    "transfer_amount": 67888,
                    "bank_branch": "Virtual Account",
                    "account_holder_name": "YOUR BUSINESS NAME",
                }
            ],
            "available_ewallets": [],
            "available_paylaters": [],
            "should_exclude_credit_card": false,
            "adjusted_received_amount": 62938,
            "should_send_email": false,
            "created": "2020-01-14T16:35:03.573Z",
            "updated": "2020-01-22T04:33:14.806Z"
        }
    ]
    
    Parameter Type Description
    external_id
    optional
    string The external id used during generation of invoice. Given that external_id is non-unique, by including external_id, it will return all invoices with that specific external_id.
    statuses
    optional
    array of strings Indicates the status of the invoices that will be available in the list.
    It contains PENDING, PAID, SETTLED, EXPIRED
    limit
    optional

    default: 10
    number A limit on the number of invoice objects to be returned.
    Limit can range between 1 and 100.
    created_after
    optional
    string (ISO 8601) Return invoices where the created field is greater than this value. Both created_after and created_before field should be used in the same time for the filter to take effect
    created_before
    optional
    string (ISO 8601) Return invoices where the created field is less than this value.
    Both created_after and created_before field should be used in the same time for the filter to take effect
    paid_after
    optional
    string (ISO 8601) Return invoices where the paid_at field is greater than this value.
    Both paid_after and paid_before field should be used in the same time for the filter to take effect
    paid_before
    optional
    string (ISO 8601) Return invoices where the paid_at field is less than this value.
    Both paid_after and paid_before field should be used in the same time for the filter to take effect
    expired_after
    optional
    string (ISO 8601) Return invoices where the expiry_date field is greater than this value.
    Both expired_after and expired_before field should be used in the same time for the filter to take effect
    expired_before
    optional
    string (ISO 8601) Return invoices where the expiry_date field is less than this value.
    Both expired_after and expired_before field should be used in the same time for the filter to take effect
    last_invoice_id
    optional
    string A cursor for use in pagination.
    last_invoice_id is an invoice ID that defines your starting point for the list. For instance, if you make a list request and receive 10 objects, starting with obj_bar, your subsequent call can include last_invoice_id=obj_bar in order to fetch the previous page of the list.
    client_types
    optional
    array of strings Indicates the method used to create the invoice. It contains:
    API_GATEWAY Invoice created via create invoice API
    DASHBOARD Invoice created via dashboard
    INTEGRATION Invoice created via 3rd party integration such as Shopify and Woocommerce
    ON_DEMAND Invoice created via On Demand
    RECURRING Invoice created via Recurring Payment
    MOBILE Invoice created via Mobile App
    payment_channels
    optional
    array of strings Indicates the channels used to pay the invoice.
    on_demand_link
    optional
    string The link for the specific on demand. If you input on_demand_link, it will return invoices that created from that specific on demand link.
    recurring_payment_id
    optional
    string The recurring payment id for specific recurring payment, it will return invoices that created from that specific recurring payment id.

    Response Parameters

    List invoice response will return array of get invoices response. Please refer get an invoice for more information.

    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

    Invoice Callback

    Endpoint: Invoice Webhook

    POST https://yourcompany.com/invoice_webhook_url

    Xendit notifies your system upon successful and expired invoices via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

    Example Invoice Webhook Request for Payment Through Bank

    {
          "id": "593f4ed1c3d3bb7f39733d83",
          "external_id": "testing-invoice",
          "user_id": "5848fdf860053555135587e7",
          "is_high": false,
          "payment_method": "BANK_TRANSFER",
          "status": "PAID",
          "merchant_name": "Xendit",
          "amount": 2000000,
          "paid_amount": 2000000,
          "bank_code": "MANDIRI",
          "paid_at": "2020-01-14T02:32:50.912Z",
          "payer_email": "test@xendit.co",
          "description": "Invoice webhook test",
          "created": "2020-01-13T02:32:49.827Z",
          "updated": "2020-01-13T02:32:50.912Z",
          "currency": "IDR",
          "payment_channel": "MANDIRI",
          "payment_destination": "8458478548758748"
    }

    Example Invoice Webhook Request for Payment Through Retail Outlet

    {
          "id": "593f4ed1c3d3bb7f39733d83",
          "external_id": "testing-invoice",
          "user_id": "5848fdf860053555135587e7",
          "is_high": false,
          "payment_method": "RETAIL_OUTLET",
          "status": "PAID",
          "merchant_name": "Xendit",
          "amount": 2000000,
          "paid_amount": 2000000,
          "paid_at": "2020-01-14T02:32:50.912Z",
          "payer_email": "test@xendit.co",
          "description": "Invoice webhook test",
          "created": "2020-01-13T02:32:49.827Z",
          "updated": "2020-01-13T02:32:50.912Z",
          "currency": "IDR",
          "payment_channel": "ALFAMART",
          "payment_destination": "TEST815"
    }

    Example Invoice Webhook Request for Expired invoices (Unpaid invoice)

    {
      "id": "621887f17d9cdaa199d6e787",
      "user_id": "61d3c21692594a88b0dad56b",
      "external_id": "yumin-invoice-1645774832",
      "is_high": false,
      "status": "EXPIRED",
      "merchant_name": "fintech",
      "amount": 1000,
      "created": "2022-02-25T07:40:33.922Z",
      "updated": "2022-02-25T07:42:43.872Z",
      "description": "Invoice Demo #123",
      "currency": "PHP",
      "success_redirect_url": "https://www.google.com",
      "failure_redirect_url": "https://www.google.com",
    }
    Header Parameter Type Description
    x-callback-token
    required
    string Your Xendit unique webhook token to verify the origin of the webhook

    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    Body Parameter Type Description
    id string An invoice ID generated by Xendit
    external_id string The invoice ID in your server, that can be used to reconcile between you and Xendit
    user_id string Your Xendit Business ID
    is_high boolean Should unique numbers go above or below the amount.
    status string Status showing whether the invoice has been paid
    PAID means the invoice has been paid
    EXPIRED means the invoice expired before your customer paid
    Expired invoice webhooks are not enabled by default.

    In special cases when a payment is made after the invoice has expired (such as due to delayed bank webhooks for paid transactions), you can receive paid webhooks by enabling this on your Xendit Dashboard.
    merchant_name string The name of your company or website
    amount number Nominal amount for the invoice
    payer_email
    optional
    string Email of the payer, we get this information from your API call
    description
    optional
    string Description for the invoice, we get this information from your API call
    paid_amount
    optional
    number Total amount paid for the invoice
    updated string An ISO timestamp that tracks when the invoice was updated (UTC GMT+0)
    created string An ISO timestamp that tracks when the invoice was created (UTC GMT+0)
    currency string Currency of the amount that you created. You will get this response when you add this parameter when create invoice through API
    paid_at
    optional
    string Date time data when your customer pay the invoice. You will get this response when your invoice is paid
    payment_method
    optional
    string Payment method that is used when a customer pays the invoice. You will get this response when your invoice is paid
    Possible values: BANK_TRANSFER, CREDIT_CARD, RETAIL_OUTLET, EWALLET, DIRECT_DEBIT, PAYLATER, QR_CODE
    payment_channel
    optional
    string The specific payment channel used to pay the invoice.
    payment_destination
    optional
    string Virtual Account number or Retail Outlet payment code used to pay the invoice (will not be shown for cards and e-wallet payments). You will get this response when your invoice is paid
    payment_details
    optional
    object Object containing payment details. Currently supporting QRIS payment only.
    Object parameters
    Key Value
    receipt_id
    optional
    string Request reference number (RRN) that is shared across the QR network. Example: "120318237"
    source
    optional
    number Source where the end user’s balance was deducted to complete the payment. Example: "OVO", "GOPAY"
    payment_id string Payment unique identifier. Currently this object will only be returned when payment method that payer use are eWallets, PayLater, and QR code. You can use the value of this parameter to initiate ewallet and PayLater refunds using the eWallets and Paylater refund endpoints.
    success_redirect_url string URL that end user will be redirected to upon successful invoice payment. You will get this response when you add this parameter when create invoice through API
    failure_redirect_url string URL that end user will be redirected to upon expiration of this invoice. You will get this response when you add this parameter when create invoice through API
    credit_card_charge_id
    optional
    string Credit card charge ID when your customer pay the invoice with credit card. You will get this response when your invoice is paid with Credit Card
    items
    optional
    array Array of items JSON objects describing the item(s) purchased.
    Items child parameters
    Field Description
    name
    required
    string Name of the product
    quantity
    required
    number Number of units of this item in the basket
    price
    required
    number Price per unit in basket currency

    category
    optional
    string Merchant category for item
    Example: Fashion, Electronic
    url
    optional
    string The public URL of the specific item detail page

    Example: https://yourcompany.com/example_item
    fees
    optional
    array Array of fees JSON objects describing the fee(s) that you charge to your end customer.
    Fees child parameters
    Field Description
    type
    required
    string Unique type of the fee
    value
    required
    number Amount of this specific fee
    should_authenticate_credit_card
    optional
    boolean Specify whether you want this checkout transaction to go through 3DS (credit card authentication). Please make sure "Optional 3DS" is enabled in your Credit Card Settings. If Optional 3DS is disabled, all checkout transactions paid via card will go through 3DS, regardless of the value of this parameter.
    bank_code
    optional
    string Code of the bank used to receive invoice payment, only if payment method is BANK_TRANSFER
    ewallet_type
    optional
    string Code of the ewallet used to receive invoice payment, only if payment method is EWALLET
    on_demand_link
    optional
    string Link to the on demand invoice (multiple payment link). Only for on demand invoices.
    recurring_payment_id
    optional
    string ID of recurring invoice. Only for recurring invoices.
    fees_paid_amount
    only if payment_channel is non switching Bank Partner and all of Retail Outlet.
    number Xendit fee paid from this transaction.
    DEPRECATED SINCE 18th MAY 2022. If you need this information go to Xendit Dashboard > Balance Tab
    adjusted_received_amount
    only if payment_channel is non switching Bank Partner andall of Retail Outlet.
    number Amount attributable to you net of our fees.
    DEPRECATED SINCE 18th MAY 2022. If you need this information go to Xendit Dashboard > Balance Tab

    Subscriptions (formerly called Recurring)

    Our Subscriptions API offers our merchants the ability to collect subscription payments flexibly and seamlessly via auto debit/ merchant initiated payment methods (end users does not perform OTP/ PIN after initial account linking/ binding). Xendit’s Subscriptions delivers more than automated payments scheduling; we focus on providing the best end user experience and maximum payment success rates for our merchants.

    Supported Use Cases

    1. Fixed subscription payments (e.g. Content streaming subscription, recurring donation contributions)
    2. Usage based subscription payments/ Metered billing (e.g. Utilities bill, data roaming charges)

    Supported Autodebit Payment Methods in Indonesia (subject to payment method provider's approval)

    1. Credit Cards
    2. BRI DD
    3. OVO
    4. SHOPEEPAY

    Supported Autodebit Payment Methods in Philippines (subject to payment method provider's approval)

    1. Credit Cards
    2. SHOPEEPAY
    3. GRABPAY
    4. MAYA
    5. GCASH
    6. UBP
    7. BPI

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

    API Version

    You are currently viewing the newest version of our Subscriptions API. Integrate once to get access to all available Subscriptions features and future Subscriptions features in Xendit!

    Version Changelog
    2022-10-01
    Latest
    New Subscriptions endpoint that supports auto debit payments natively with configurable retry mechanisms. Supports cards, eWallets and direct debit payment methods
    2022-07-15
    Previous version
    Recurring endpoint powered by Xendit payment links

    Plan Object

    The key data object that will orchestrate the merchant's subscription payment flows. Subscriptions plan object will take in the customer object, schedule object (optional) to set up the subscription payments behaviour for a particular end user. Merchant will tie the end user's payment details to a Subscriptions plan using this plan object (either using the payment_method_id from the account linking process or Subscriptions's account linking UI). The Subscriptions plan also takes in other parameters from the merchant to configure how the subscription plan should behave when certain scenarios happen. The Subscriptions plan object will generate multiple Subscriptions cycle objects to orchestrate each instances of payment.

    Refer to subscriptions concepts for an overview on subscription objects and relationships.

    Example Plan Object

    {
      "id": "repl-239c16f4-866d-43e8-9341-7badafbc019f",
      "reference_id": "test_reference_id",
      "customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recurring_action": "PAYMENT",
      "recurring_cycle_count": 0,
      "currency": "IDR",
      "amount": 13579,
      "status": "PENDING",
      "created": "2020-11-20T16:23:52Z",
      "updated": "2020-11-20T16:23:52Z",
      "payment_methods": [
        {
          "payment_method_id": "pm-239c16f4-866d-43e8-9341-7badafbc019f",
          "rank": 1,
          "type": "EWALLET"
        }
      ],
      "schedule_id": "resc-239c16f4-866d-43e8-9341-7badafbc019f",
      "schedule": {
        "reference_id": "test_reference_id",
        "interval": "MONTH",
        "interval_count": 1,
        "created": "2022-02-15T16:23:52Z",
        "updated": "2022-02-15T16:23:52Z",
        "total_recurrence": 12,
        "anchor_date": "2022-02-15T16:23:52Z",
        "retry_interval": "DAY",
        "retry_interval_count": 5,
        "total_retry": 5,
        "failed_attempt_notifications": [
          2,
          4
        ]
      },
      "immediate_action_type": "FULL_AMOUNT",
      "notification_config": {
        "recurring_created": [
          "WHATSAPP",
          "EMAIL"
        ],
        "recurring_succeeded": [
          "WHATSAPP",
          "EMAIL"
        ],
        "recurring_failed": [
          "WHATSAPP",
          "EMAIL"
        ],
        "locale": "en"
      },
      "failed_cycle_action": "STOP",
      "metadata": {
        "meta_metadata": "meta_meta_metadata"
      },
      "description": "Video Game Subscription",
      "items": [
        {
          "type": "DIGITAL_PRODUCT",
          "name": "Cine Mraft",
          "net_unit_amount": 13579,
          "quantity": 1
        }
      ],
      "actions": [
        {
          "action": "AUTH",
          "url": "https://linking-dev.xendit.co/pali_e53e1ca6-3c09-4026-be2e-95ed3d4bb25b",
          "url_type": "WEB",
          "method": "GET"
        }
      ],
      "success_return_url": "https://www.xendit.co/successisthesumoffailures",
      "failure_return_url": "https://www.xendit.co/failureisthemotherofsuccess"
    }
    Body Parameter Type Description
    id
    required
    string Xendit-generated Subscriptions plan ID, with prefix repl-xxx
    reference_id
    required
    string Merchant-provided identifier for the Subscriptions plan
    Min - 1 character
    Max - 64 characters
    customer_id
    required
    string Xendit-generated customer ID, with prefix cust-xxx
    recurring_action
    required
    enum The type of Subscriptions action requested. Supported values - PAYMENT
    recurring_cycle_count
    required
    number Total number of cycles the Subscriptions plan has executed. Immediate charge cycle also counts as 1 cycle count
    currency
    required
    enum ISO 4217 currency code of Subscriptions plan. Supported currency - IDR, PHP
    amount
    required
    number Amount that Subscriptions plan will charge to end users. Subscriptions cycles will be generated based on this value. If items param is used, amount should be equivalent to the sum of net_unit_amount multiplied by quantity in the items array
    Min - Rp 1000 (Indonesia) or PHP 50 (Philippines)
    Max - Dependent on individual payment providers
    status
    required
    enum Status of Subscriptions plan:

    ACTIVE - Subscriptions plan is ongoing
    INACTIVE - Subscriptions plan will not trigger any more actions
    PENDING - awaiting for the plan to be completed
    REQUIRES_ACTION - The request passed validation but requires additional steps for completion
    created
    required
    string ISO 8601 Timestamp for Subscriptions plan creation. Timezone UTC+0. Example value: "2020-04-20T16:23:52Z"
    updated
    required
    string ISO 8601 Timestamp for latest plan object update. Timezone UTC+0. Example value: "2020-04-20T16:23:52Z"
    payment_methods
    optional
    array Array of payment_method_id that the Subscriptions plan will attempt to make payments with (attempts will be made according to the rank of each object in the array). Only one successful payment will be made

    If this parameter is not passed in, a URL to perform payment account linking will be generated for end users
    Key Value
    payment_method_id
    required
    string ID for payment_method_id generated by Create Payment Method API
    rank
    required
    number Indicate the order which payments methods will be attempted for a payment cycle instance. Available values - 1 to 5
    type
    required
    string Type of payment method. Available values - EWALLET, DIRECT_DEBIT or CARD
    schedule_id
    optional
    string Xendit-generated Subscriptions schedule ID.
    schedule
    required
    object Data object containing the configurations of how Subscriptions cycles will be scheduled.
    Key Value
    reference_id
    required
    string Merchant-provided identifier for the schedule
    Min - 1 character
    Max - n/a
    id
    required
    string Xendit-generated Subscriptions schedule ID
    business_id
    required
    string Xendit-generated identifier for the business
    interval
    required
    enum The type of interval between consecutive Subscriptions cycles. Supported values - DAY, WEEK, MONTH

    WEEK - the day of the week which anchor_date lands on (e.g. anchor_date lands on Wed, subsequent cycles will be on Wed)
    MONTH - the date of the month which anchor_date lands on (anchor_date lands on the 25th, subsequent cycles will be on the 25th)
    interval_count
    required
    number The number of units of interval between consecutive Subscriptions cycles (e.g. interval = MONTH, interval_count = 3, then Subscriptions cycle happens every 3 month)
    total_recurrence
    optional
    number Default = NULL The total number of times the end user will be charged. The immediate charge instance does not count to total_recurrence. If the parameter is not used, Subscriptions plan will run on indefinitely
    anchor_date
    optional
    string Default = the date of schedule creation (same day action). Timestamp in ISO 8601 ("2020-11-20T16:23:52+07:00"). A timestamp used to determine when a Subscriptions plan starts. The date, day of week or date of month will be used to initialize the Subscriptions cycle (back dated timestamps still works). If a timezone passed in, the Subscriptions event will be executed based on the timezone, else UTC 0 wil be used

    Supported values - Timestamps between 1st to 28th of a month

    If no anchor_date value is passed and date of schedule creation falls on 29/30/31, anchor date will be defaulted to 1st of next month
    retry_interval
    optional
    enum The type of interval between failed attempt and retries. Supported values - DAY
    retry_interval_count
    optional
    number The number of units of retry_interval between consecutive retries (e.g. retry_interval = DAY, retry_interval_count = 3, then Subscriptions cycle retries 3 days after a failed attempt)
    total_retry
    optional
    number The number of times you will retry a failed Subscriptions cycle. If no value is passed into total_retry, it will be null by default and no retries will be triggered
    Min - 1
    Max - 10
    failed_attempt_notifications
    optional
    array Specify which retry attempts will have failed Subscriptions notifications to the end user. Array values count should not be greater than total_retry number or duplicated. 1 in this param refers to the first retry attempt
    immediate_action_type
    optional
    enum The type of action the Subscriptions plan takes upon creation. If the action fails, the Subscriptions plan would be inactivated and an inactivated webhook will be sent. Supported values - FULL_AMOUNT - a full charge will be attempted upon Subscriptions plan creation
    notification_config
    optional
    Object Object containing notification preferences for the Subscriptions plan
    Key Value
    recurring_created
    optional
    array Specify which channel you want to notify your end customer through when you a Subscriptions plan is created. Supported values - ["WHATSAPP", "EMAIL"]
    recurring_succeeded
    optional
    array Specify which channel you want to notify your end customer through when you a Subscriptions cycle was successfully completed. Supported values - ["WHATSAPP", "EMAIL"]
    recurring_failed
    optional
    array Specify which channel you want to notify your end customer through when you a Subscriptions cycle has failed. Supported values - ["WHATSAPP", "EMAIL"]
    locale
    optional
    enum Default - "en". ISO 639-1: two-letter codes for language of notifications sent to end user. Supported values - en, id
    payment_link_for_failed_attempt
    optional
    boolean Default = false. Indicates whether the plan should generate a payment link to be sent to the end customer when the first attempt of the cycle fails. The schedule object of the plan must have a minimum total_retry of 1. The plan's notification_config.recurring_failed determines the channel for which the end customer will receive the notification with the payment link URL. You will also receive the payment link URL in the recurring.cycle.retrying callback. For more information about payment links, please see this section
    failed_cycle_action
    optional
    enum Default = RESUME. Indicate the behaviour the Subscriptions plan should take when Subscriptions cycles fail. RESUME will ignore failure and continue on with the next Subscriptions cycle. STOP will inactivate the Subscriptions plan and there will be no active Subscriptions cycles. Supported values - RESUME, STOP
    metadata
    optional
    object Object of additional information the merchants 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
    description
    optional
    string Description of Subscriptions plan - you can use this field to list what items are being paid for, or anything else of your choice that describes the function of the Subscriptions plan. This field will be displayed to end users for UI, email or whatsapp.
    Min - 1 character
    Max - 1000 characters
    items
    optional
    array Array of objects describing the item/s
    Key Value
    type
    required
    string Type of item

    DIGITAL_PRODUCT, PHYSICAL_PRODUCT, DIGITAL_SERVICE, PHYSICAL_SERVICE,FEE,DISCOUNT
    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, please put negative amount for DISCOUNT (e.g. -1000000)
    quantity
    required
    number Number of units of this item in the basket

    Min 1
    url
    optional
    string URL of the item

    Must be HTTPS or HTTP
    category
    optional
    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
    actions
    optional
    array Array of objects that contain URLs for end users to complete their Subscriptions plan
    Key Value
    action
    required
    string Describes the purpose the corresponding action. AUTH - Trigger this action in order to payment account linking
    url_type
    optional
    string WEB - The provided redirect url is optimized for desktop or web interface
    url
    optional
    string The generated URL to hit in order to perform the action
    method
    optional
    string HTTP method for calling the url - GET/ POST
    success_return_url
    optional
    string URL where the end user is redirected after account linking has been successful. Must be HTTPS or HTTP
    failure_return_url
    optional
    string URL where the end-customer is redirected if the account linking has failed. Must be HTTPS or HTTP

    Schedule Object

    The data object used to define how the recurring cycles are supposed to happen. The object contains information about how frequent events should happen and the intervals (day/ month/ year) between each event. The recurring plan object will read off the recurring schedule object to generate each recurring cycle.

    Refer to recurring concepts for an overview on recurring objects and relationships.

    Example Schedule Object

    {
      "id" : "resc-239c16f4-866d-43e8-9341-7badafbc019f",
      "business_id" : "5f27a14a9bf05c73dd040bc8",
      "reference_id": "test_reference_id",
      "interval": "MONTH",
      "interval_count": 1,
      "created": "2022-02-15T16:23:52Z",
      "updated": "2022-02-15T16:23:52Z",
      "total_recurrence": 12,
      "anchor_date": "2022-02-15T16:23:52Z",
      "retry_interval": "DAY",
      "retry_interval_count": 5,
      "total_retry": 5,
      "failed_attempt_notifications": [
        2,
        4
      ]
    }
    Body Parameter Type Description
    id
    required
    string Xendit-generated recurring schedule ID, with prefix resc-xxx
    reference_id
    required
    string Merchant-provided identifier for the recurring schedule
    Min - 1 character
    Max - n/a
    business_id
    required
    string Xendit-generated identifier for the business
    interval
    required
    enum The type of interval between consecutive recurring cycles. Supported values - DAY, WEEK, MONTH

    WEEK - the day of the week which anchor_date lands on (e.g. anchor_date lands on Wed, subsequent cycles will be on Wed)
    MONTH - the date of the month which anchor_date lands on (anchor_date lands on the 25th, subsequent cycles will be on the 25th)
    interval_count
    required
    number The number of units of interval between consecutive recurring cycles (e.g. interval = MONTH, interval_count = 3, then recurring cycle happens every 3 month)
    created
    required
    string ISO 8601 Timestamp for recurring schedule creation. Timezone UTC+0. Example value: "2020-04-20T16:23:52Z"
    updated
    required
    string ISO 8601 Timestamp for latest schedule object update. Timezone UTC+0. Example value: "2020-04-20T16:23:52Z"
    total_recurrence
    optional
    number Default = NULL The total number of times the end user will be charged. The immediate charge instance does not count to total_recurrence. If the parameter is not used, recurring plan will run on indefinitely
    anchor_date
    optional
    string Default = the date of schedule creation (same day action). Timestamp in ISO 8601 ("2020-11-20T16:23:52+07:00"). A timestamp used to determine when a recurring plan starts. The date, day of week or date of month will be used to initialize the recurring cycle (back dated timestamps still works). If a timezone passed in, the recurring event will be executed based on the timezone, else UTC 0 wil be used

    Supported values - Timestamps between 1st to 28th of a month

    If no anchor_date value is passed and date of schedule creation falls on 29/30/31, anchor date will be defaulted to 1st of next month
    retry_interval
    optional
    enum The type of interval between failed attempt and retries. Supported values - DAY
    retry_interval_count
    optional
    number The number of units of retry_interval between consecutive retries (e.g. retry_interval = DAY, retry_interval_count = 3, then recurring cycle retries 3 days after a failed attempt)
    total_retry
    optional
    number The number of times you will retry a failed recurring cycle. If no value is passed into total_retry, it will be null by default and no retries will be triggered
    Min - 1
    Max - 10
    failed_attempt_notifications
    optional
    string Specify which retry attempts will have failed recurring notifications to the end user. Array values count should not be greater than total_retry number or duplicated. 1 in this param refers to the first retry attempt.

    Cycle Object

    A recurring cycle refers to one specific instance of the recurring plan's action - for e.g. a specific month's billing cycle. The recurring cycle object is generated from the recurring plan object where the recurring behaviour is defined. If changes to a particular month's billing cycle is required, this object can be updated without affecting the original recurring plan. This object is especially useful for usage based billing.

    Refer to recurring concepts for an overview on recurring objects and relationships.

    Example Cycle Object

    {
      "id": "recy-239c16f4-866d-43e8-9341-7badafbc019f",
      "reference_id": "test_reference_id",
      "customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recurring_action": "PAYMENT",
      "type": "SCHEDULED",
      "cycle_number": 2,
      "attempt_count": 2,
      "attempt_details": [
        {
          "attempt_number": 1,
          "created": "2020-04-21T16:23:52Z",
          "action_id": "ewc-239c16f4-866d-43e8-9341-7badafbc019f",
          "status": "SUCCEEDED",
          "Failure_code": null,
          "next_retry_timestamp": null
        },
        {
          "attempt_number": 1,
          "created": "2020-04-20T16:23:52Z",
          "action_id": "ewc-239c16f4-866d-43e8-9341-7badafbc019f",
          "status": "FAILTED",
          "failure_code": "INSUFFICIENT_BALANCE",
          "next_retry_timestamp": "2020-04-20T16:23:52Z"
        }
      ],
      "status": "SUCCEEDED",
      "scheduled_timestamp": "2020-12-20T16:23:52Z",
      "created": "2020-11-20T16:23:52Z",
      "updated": "2020-11-20T16:23:52Z",
      "currency": "IDR",
      "amount": 13579
    }
    Body Parameter Type Description
    id
    required
    string Xendit-generated recurring cycle ID, with prefix recy-xxx
    plan_id
    required
    string Xendit-generated recurring plan ID, with prefix repl-xxx
    reference_id
    required
    string Merchant-provided identifier, inherited from the recurring plan object
    Min - 1 character
    Max - 64 characters
    customer_id
    required
    string Xendit-generated customer ID, inherited from the recurring plan object, with prefix cust-xxx
    recurring_action
    required
    enum The type of recurring action requested, inherited from the recurring plan object. Supported values - PAYMENT
    type
    required
    enum The type of recurring cycle - Available values - SCHEDULED, IMMEDIATE
    cycle_number
    required
    number A numbering that tracks the order of cycle objects generated by a recurring plan (e.g. in a monthly billing plan, the second month's cycle_number would be 2)
    Min - 1
    attempt_count
    required
    number Number of times the recurring action has been attempted for this recurring cycle object. The value is an aggregate of the first attempt and the retries attempted
    attempt_details
    required
    array Detailed information of each action attempts
    Key Value
    attempt_number
    required
    number A numbering that tracks the order of cycle attempts. The first attempt will be 1 and subsequent attempts are dependent on retry configuration. This value can be duplicated if multiple payment methods are configured in the recurring plan
    created
    required
    string ISO 8601 Timestamp (e.g. "2020-04-20T16:23:52Z") for attempted actions. Timezone UTC+0
    action_id
    required
    string ID of associated action (e.g. payment ID) This ID can be used to locate payments on Xendit dashboard or via GET payment status APIs.
    status
    required
    enum Status of action.

    Available values -
    SUCCEEDED - recurring action processed with partners successfully
    FAILED - recurring action failed to be processed by partners
    PENDING - recurring action still awaiting partner confirmation
    failure_code
    optional
    string Reason for failure of recurring action in this attempt
    next_retry_timestamp
    optional
    string ISO 8601 Estimated timestamp (e.g. "2020-04-20T16:23:52Z") for next retry. Timezone UTC+0
    status
    required
    enum Status of recurring cycle.

    Available values -
    SCHEDULED - cycle is waiting for execution time
    PENDING - execution of the recurring action has started (cycle is locked for updates)
    RETRYING - configured retries are ongoing
    FAILED - all attempts at action, including retries has failed
    SUCCEEDED - at least one attempt at action has succeeded
    CANCELLED - recurring cycle was terminated by merchant action
    scheduled_timestamp
    required
    string ISO 8601 Timestamp (e.g. "2020-04-20T00:00:00Z" UTC+0) for the upcoming action attempt for the recurring cycle - value is updated on each retry (if any). Action will be executed within 24 hours of the scheduled timestamp with timezone taken into consideration.
    created
    required
    string ISO 8601 Timestamp for recurring cycle creation. Timezone UTC+0. Example value: "2020-04-20T16:23:52Z"
    updated
    required
    string ISO 8601 Timestamp for latest cycle object update. Timezone UTC+0. Example value: "2020-04-20T16:23:52Z"
    currency
    required
    enum ISO 4217 currency code of recurring plan. Supported currency - IDR, PHP
    amount
    required
    number Amount that recurring plan will charge to end users. Recurring cycles will be generated based on this value. If items param is used, amount should be equivalent to the sum of net_unit_amount multiplied by quantity in the items array
    Min - IDR 1,000 (Indonesia) / PHP 50 (Philippines)
    maximum amount is dependent on payment providers

    Customer - Create

    Make a POST request to this endpoint to create a customer for use with recurring endpoint. The customer object will be used by recurring plan for end user notifications regarding activity updates on their recurring plan.

    Note - one customer object can be used for multiple recurring plans.

    Endpoint: Create Customer

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

    Version

    For best compatibility, please use version 2020-10-31 at Create Customer API

    Request Parameters

    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'
       --data-raw '{
         "reference_id": "demo_1475801962607",
         "type": "INDIVIDUAL",
         "individual_detail": {
           "given_names": "John",
           "surname": "Doe"
         },
         "email": "customer@website.com",
         "mobile_number": "+628121234567890"
         }'
    <?php
      $url = "https://api.xendit.co/customers";
      $apiKey = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:";
      $headers = [];
      $headers[] = "Content-Type: application/json";
      $data = [
        "reference_id" => "demo_1475801962607",
        "type" => "INDIVIDUAL",
        "individual_detail" => [
           "given_names" => "John",
           "surname" => "Doe"
        ],
        "email" => "customer@website.com",
        "mobile_number" => "+628121234567890"
      ];
    
      $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/customers";
    
    var headers = new Headers();
    headers.append("Authorization", "Basic " + btoa(apiKey + ":"));
    headers.append("Content-Type", "application/json");
    
    var reqBody = JSON.stringify({
      "reference_id": "demo_1475801962607",
      "type": "INDIVIDUAL",
      "individual_detail": {
        "given_names": "John",
        "surname": "Doe"
      },
      "email": "customer@website.com",
      "mobile_number": "+628121234567890"});
    
    var requestOptions = {
      method: 'POST',
      headers: headers,
      body: reqBody,
      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/customers"
    
    api_key_bytes = api_key.encode('ascii')
    base64_bytes = base64.b64encode(api_key_bytes)
    base64_token = base64_bytes.decode('ascii')
    
    payload = {
      "reference_id": "demo_1475801962607",
      "type": "INDIVIDUAL",
      "individual_detail": {
        "given_names": "John",
        "surname": "Doe"
      },
      "email": "customer@website.com",
      "mobile_number": "+628121234567890"
    }
    auth_token = 'Basic ' + base64_token
    headers = {
      'Authorization': auth_token
    }
    
    response = requests.request("POST", url, headers=headers, data=payload)
    
    print(response.text)
    string apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";
    
    XenditClient xendit = new XenditClient(apiKey);
    CustomerClient customer = xendit.Customer;
    
    CustomerParameter individualParameter = new CustomerParameter
    {
      ReferenceId = "demo_11212163",
      Type = CustomerType.Individual,
      IndividualDetail = new IndividualDetail
      {
        GivenNames = "John",
        Gender = CustomerGender.Male,
      },
      IdentityAccount = new IdentityAccount[]
      {
        new IdentityAccount
        {
          Country = Country.Indonesia,
          Type = CustomerIdentityAccountType.BankAccount,
          Properties = new IdentityAccountProperties { AccountNumber = "account_number" }
        }
      },
      KycDocuments = new KycDocument[]
      {
        new KycDocument
        {
          Country = Country.Indonesia,
          Type = CustomerKycDocumentType.IdentityCard,
          SubType = CustomerKycDocumentSubType.NationalId,
        }
      },
    };
    
    CustomerResponse individualCustomerVersion20201031 = await customer.Create(individualParameter);

    The following table displays parameters that will be used in recurring to notify your end users about recurring activity. Please see Create Customer API for the full feature list of Create Customer API.

    Body Parameter Type Description
    reference_id
    required
    string Merchant-provided identifier for the customer.
    Requests with a duplicate reference_id will return an error. You should PATCH the customer object resource instead.

    Maximum length 255 characters
    Characters Alphanumeric. No special characters is allowed.
    type
    required
    string Type of customer.
    Supported values: INDIVIDUAL
    individual_detail
    conditionally required
    object JSON object containing details of the individual. Required if type is INDIVIDUAL
    Individual detail child parameters
    given_names
    required
    string Primary or first name/s of customer.

    Characters Alphanumeric. No special characters is allowed.
    mobile_number
    optional
    string Mobile number of customer in E.164 format

    Maximum length 50 characters
    email
    optional
    string E-mail address of customer

    Maximum length 255 characters

    Response Parameters

    Success responses will contain a single Customer Object

    Error Codes

    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.
    IDEMPOTENCY_ERROR
    409
    Provided Idempotency-key already exists but the request body provided does not match the original request

    Plan - Create

    Create recurring plan API will require the customer object, schedule object (optional) to set up the recurring logic for a particular end user. Merchant will tie the end user's payment details to a recurring plan using this API (either using the recurring plan's account linking UI or providing payment_method_id from the create payment method API). Once the request has been validated, webhooks will be sent to notify your system on whether the plan has been activated.

    Please refer to our integration guide for more information.

    Endpoint: Create Recurring Plan Request

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

    Request Parameters

    Example: Create Recurring Plan Request

    curl https://api.xendit.co/recurring/plans -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
      --data '{
      "reference_id": "test_reference_id",
      "customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recurring_action": "PAYMENT",
      "currency": "IDR",
      "amount": 13579,
      "payment_methods": [{
        "payment_method_id": "pm-asdaso213897821hdas",
        "rank": 1
      }],
      "schedule": {
        "reference_id": "test_reference_id",
        "interval": "MONTH",
        "interval_count": 1,
        "total_recurrence": 12,
        "anchor_date": "2022-02-15T16:23:52Z",
        "retry_interval": "DAY",
        "retry_interval_count": 3,
        "total_retry": 2,
        "failed_attempt_notifications": [1,2]
      },
      "immediate_action_type": "FULL_AMOUNT",
      "notification_config": {
        "recurring_created": ["WHATSAPP","EMAIL"],
        "recurring_succeeded": ["WHATSAPP","EMAIL"],
        "recurring_failed": ["WHATSAPP","EMAIL"],
        "locale": "en"},
      "failed_cycle_action": "STOP",
      "payment_link_for_failed_attempt" : true,
      "metadata": null,
      "description": "Video Game Subscription",
      "items": [
            {
                "type": "DIGITAL_PRODUCT",
                "name": "Cine Mraft",
                "net_unit_amount": 13579,
                "quantity": 1,
                "url": "https://www.xendit.co/",
                "category": "Gaming",
                "subcategory": "Open World"
            }
        ],
      "success_return_url": "https://www.xendit.co/successisthesumoffailures",
      "failure_return_url": "https://www.xendit.co/failureisthemotherofsuccess"
    }' 
    <?php
    
    $curl = curl_init();
    
    curl_setopt_array($curl, array(
      CURLOPT_URL => 'https://api.xendit.co/recurring/plans',
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => '',
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 0,
      CURLOPT_FOLLOWLOCATION => true,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => 'POST',
      CURLOPT_POSTFIELDS =>'{
      "reference_id": "test_reference_id",
      "customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "recurring_action": "PAYMENT",
      "currency": "IDR",
      "amount": 13579,
      "payment_methods": [{
        "payment_method_id": "pm-asdaso213897821hdas",
        "rank": 1
      }],
      "schedule": {
        "reference_id": "test_reference_id",
        "interval": "MONTH",
        "interval_count": 1,
        "total_recurrence": 12,
        "anchor_date": "2022-02-15T16:23:52Z",
        "retry_interval": "DAY",
        "retry_interval_count": 3,
        "total_retry": 2,
        "failed_attempt_notifications": [1,2]
      },
      "immediate_action_type": "FULL_AMOUNT",
      "notification_config": {
        "recurring_created": ["WHATSAPP","EMAIL"],
        "recurring_succeeded": ["WHATSAPP","EMAIL"],
        "recurring_failed": ["WHATSAPP","EMAIL"],
        "locale": "en"},
      "failed_cycle_action": "STOP",
      "payment_link_for_failed_attempt" : true,
      "metadata": null,
      "description": "Video Game Subscription",
      "items": [
            {
                "type": "DIGITAL_PRODUCT",
                "name": "Cine Mraft",
                "net_unit_amount": 13579,
                "quantity": 1,
                "url": "https://www.xendit.co/",
                "category": "Gaming",
                "subcategory": "Open World"
            }
        ],
      "success_return_url": "https://www.xendit.co/successisthesumoffailures",
      "failure_return_url": "https://www.xendit.co/failureisthemotherofsuccess"
    }',
      CURLOPT_HTTPHEADER => array(
        'Authorization: Basic eG5kX2RldmVsb3BtZW50XzNRd3BPQzVrU2c4bWpKUGd2RHBqU3BEeGxnMU9PSGFwaXpVNTNHOFIxcmV4VU5oSnpQZnlGTWxTTVRDUVYxUk86',
        'Content-Type: application/json'
      ),
    ));
    
    $response = curl_exec($curl);
    
    curl_close($curl);
    echo $response;
    
    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-split-rule
    optional
    string Split Rule ID that you would like to apply to this subscriptions plan in order to split and route payments to multiple accounts.

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

    If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

    Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

    This header is only used if you have access to xenPlatform. See xenPlatform for more information.
    Body Parameter Type Description
    reference_id
    required
    string Merchant-provided identifier for the recurring plan
    Min - 1 character
    Max - 64 characters
    customer_id
    required
    string Xendit-generated customer ID with prefix cust-xxx. Only support customer with type INDIVIDUAL
    recurring_action
    required
    enum The type of recurring action requested. Supported values - "PAYMENT"
    currency
    required
    enum ISO 4217 currency code of recurring plan. Supported currency - IDR, PHP
    amount
    required
    number Amount that recurring plan will charge to end users. Recurring cycles will be generated based on this value. If items param is used, amount should be equivalent to the sum of net_unit_amount multiplied by quantity in the items array
    Min IDR - 1000, Cards Min IDR - 5000
    Min PHP - 20
    Max - Dependent on individual payment providers
    schedule
    required
    object Data object containing the configurations of how recurring cycles will be scheduled.
    Key Value
    reference_id
    required
    string Merchant-provided identifier for the schedule
    Min - 1 character
    Max - n/a
    interval
    required
    enum The type of interval between consecutive recurring cycles. Supported values - DAY, WEEK, MONTH

    WEEK - the day of the week which anchor_date lands on (e.g. anchor_date lands on Wed, subsequent cycles will be on Wed)
    MONTH - the date of the month which anchor_date lands on (anchor_date lands on the 25th, subsequent cycles will be on the 25th)
    interval_count
    required
    number The number of units of interval between consecutive recurring cycles (e.g. interval = MONTH, interval_count = 3, then recurring cycle happens every 3 month)
    total_recurrence
    optional
    number Default = NULL The total number of times the end user will be charged. The immediate charge instance does not count to total_recurrence. If the parameter is not used, recurring plan will run on indefinitely
    anchor_date
    optional
    string Default = the date of schedule creation (same day action). Timestamp in ISO 8601 ("2020-11-20T16:23:52+07:00"). A timestamp used to determine when a recurring plan starts. The date, day of week or date of month will be used to initialize the recurring cycle (back dated timestamps still works). If a timezone passed in, the recurring event will be executed based on the timezone, else UTC 0 wil be used

    Supported values - Timestamps between 1st to 28th of a month

    If no anchor_date value is passed and date of schedule creation falls on 29/30/31, anchor date will be defaulted to 1st of next month
    retry_interval
    optional
    enum The type of interval between failed attempt and retries. Supported values - DAY
    retry_interval_count
    optional
    number The number of units of retry_interval between consecutive retries (e.g. retry_interval = DAY, retry_interval_count = 3, then recurring cycle retries 3 days after a failed attempt)
    total_retry
    optional
    number The number of times you will retry a failed recurring cycle. If no value is passed into total_retry, it will be null by default and no retries will be triggered
    Min - 1
    Max - 10
    failed_attempt_notifications
    optional
    array Specify which retry attempts will have failed recurring notifications to the end user. Array values count should not be greater than total_retry number or duplicated. 1 in this param refers to the first retry attempt
    payment_methods
    optional
    array Array of payment_method_id that the recurring plan will attempt to make payments with (attempts will be made according to the rank of each object in the array). Only one successful payment will be made

    If this parameter is not passed in, a URL to perform payment account linking by Xendit will be generated for end users
    Key Value
    payment_method_id
    required
    string ID for payment_method_id generated by Create Payment Method API
    rank
    required
    number Indicate the order which payments methods will be attempted for a payment cycle instance. Available values - 1 to 5
    immediate_action_type
    optional
    enum the type of action the recurring plan takes upon creation. If the action fails the recurring plan would be inactivated and an inactivated webhook will be sent. Supported values - FULL_AMOUNT - a full charge will be attempted upon recurring plan creation
    notification_config
    optional
    Object Object containing notification preferences for the recurring plan
    Key Value
    recurring_created
    optional
    array Specify which channel you want to notify your end customer through when you a recurring plan is created. Supported values - ["WHATSAPP", "EMAIL"]
    recurring_succeeded
    optional
    array Specify which channel you want to notify your end customer through when you a recurring cycle was successfully completed. Supported values - ["WHATSAPP", "EMAIL"]
    recurring_failed
    optional
    array Specify which channel you want to notify your end customer through when you a recurring cycle has failed. Supported values - ["WHATSAPP", "EMAIL"]
    locale
    optional
    enum Default - "en". ISO 639-1: two-letter codes for language of notifications sent to end user. Supported values - en, id
    payment_link_for_failed_attempt
    optional
    boolean Default = false. Indicates whether the plan should generate a payment link to be sent to the end customer when the first attempt of the cycle fails. The schedule object of the plan must have a minimum total_retry of 1. The plan's notification_config.recurring_failed determines the channel for which the end customer will receive the notification with the payment link URL. You will also receive the payment link URL in the recurring.cycle.retrying callback. For more information about payment links, please see this section
    failed_cycle_action
    optional
    enum Default = RESUME. Indicate the behaviour the recurring plan should take when recurring cycles fail. RESUME will ignore failure and continue on with the next recurring cycle. STOP will inactivate the recurring plan and there will be no active recurring cycles. Supported values - RESUME, STOP
    metadata
    optional
    object Object of additional information the merchants 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
    description
    optional
    string Description of recurring plan - you can use this field to list what items are being paid for, or anything else of your choice that describes the function of the recurring plan. This field will be displayed to end users for UI, email or whatsapp.
    Min - 1 character
    Max - 1000 characters
    items
    optional
    array Array of objects describing the item/s
    Key Value
    type
    required
    string Type of item

    DIGITAL_PRODUCT, PHYSICAL_PRODUCT, DIGITAL_SERVICE, PHYSICAL_SERVICE,FEE,DISCOUNT
    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, please put negative amount for DISCOUNT (e.g. -1000000)
    quantity
    required
    number Number of units of this item in the basket

    Min 1
    url
    optional
    string URL of the item

    Must be HTTPS or HTTP
    category
    optional
    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
    success_return_url
    conditionally required
    string URL where the end user is redirected after account linking has been successful. Must be HTTPS or HTTP. Required when payment_method_id is not passed into the request
    failure_return_url
    conditionally required
    string URL where the end-customer is redirected if the account linking has failed. Must be HTTPS or HTTP. Required when payment_method_id is not passed into the request

    Response Parameters

    Success responses will contain a single Plan Object with PENDING status. This is followed by a webhook that will inform your system if the plan was successfully activated.

    Error Codes

    Example: Create Recurring Plan Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server."
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    There is invalid input in one of the required request fields
    API_VALIDATION_ERROR
    400
    schedule should be included in the request body for a successful response. Please check your request body
    API_VALIDATION_ERROR
    400
    To create a cycle retry logic, all values in retry_interval, retry_interval_count and total_retry must be specified. Please check your request body to specify all values or remove the parameters that were filled
    API_VALIDATION_ERROR
    400
    To configure failed_attempt_notifications, a retry logic must be specified using retry_interval, retry_interval_count and total_retry. Please check your request body to specify all values
    API_VALIDATION_ERROR
    400
    The rank for payment methods must be sequential starting at 1
    API_VALIDATION_ERROR
    400
    Values in failed_attempt_notifications array cannot be duplicated or greater than total_retry value or the array values count greater than total_retry
    API_VALIDATION_ERROR
    400
    The payment currency requested is not supported for this payment channel. Please refer to our API reference or docs to pick available currencies
    API_VALIDATION_ERROR
    400
    anchor_date does not accept dates from 29 to 31. Please check your request body to specify all values
    API_VALIDATION_ERROR
    400
    The sum of items.net_unit_amount must be equal to the plan amount
    INVALID_PAYMENT_METHOD_ID
    400
    The payment_method_id provided has a mismatched currency or it is not "ACTIVE" because it has expired/ been unlinked/ linking has not been completed. Please retry with a valid payment_method_id
    INVALID_API_KEY
    401
    API key format is invalid
    PAYMENT_METHOD_ID_NOT_FOUND
    404
    The payment_method_id provided is not found. Please retry with a payment_method_id
    CUSTOMER_NOT_FOUND
    404
    customer_id is invalid or not found. Please try again with valid customer_id
    UNSUPPORTED_CONTENT_TYPE
    415
    The content type requested is not supported
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Plan - Callback Events

    Xendit notifies your system upon activated and inactivated plans via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Header Parameter Type Description
    x-callback-token
    required
    string Your Xendit unique webhook token to verify the origin of the webhook
    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks

    Plan Activation Payload

    The plan activation webhook is triggered when the recurring plan is able to complete all requested steps defined in create recurring plan API. There are two possible processes that could be involved - 1. recurring is helping to complete an immediate action (e.g. immediate payment action) or 2. recurring is waiting for end user to complete account linking.

    Full details of webhooks can be found here

    Example: Plan Activation Webhook Payload

    {
      "created": "2022-10-01T12:37:08.251Z",
      "business_id": "62440e322008e87fb29c1fd0",
      "event": "recurring.plan.activated",
      "data": {
        "id": "repl-239c16f4-866d-43e8-9341-7badafbc019f",
        "reference_id": "test_reference_id",
        "customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
        "recurring_action": "PAYMENT",
        "recurring_cycle_count": 0,
        "currency": "IDR",
        "amount": 13579,
        "status": "ACTIVE",
        "created": "2020-11-20T16:23:52Z",
        "updated": "2020-11-20T16:23:52Z",
        "payment_methods": [
          {
            "payment_method_id": "pm-239c16f4-866d-43e8-9341-7badafbc019f",
            "rank": 1,
            "type": "EWALLET"
          }
        ],
        "schedule_id": "resc-239c16f4-866d-43e8-9341-7badafbc019f",
        "schedule": {
          "reference_id": "test_reference_id",
          "interval": "MONTH",
          "interval_count": 1,
          "created": "2022-02-15T16:23:52Z",
          "updated": "2022-02-15T16:23:52Z",
          "total_recurrence": 12,
          "anchor_date": "2022-02-15T16:23:52Z",
          "retry_interval": "DAY",
          "retry_interval_count": 5,
          "total_retry": 5,
          "failed_attempt_notifications": [
            2,
            4
          ]
        },
        "immediate_action_type": "FULL_AMOUNT",
        "notification_config": {
          "recurring_created": [
            "WHATSAPP",
            "EMAIL"
          ],
          "recurring_succeeded": [
            "WHATSAPP",
            "EMAIL"
          ],
          "recurring_failed": [
            "WHATSAPP",
            "EMAIL"
          ],
          "locale": "en"
        },
        "failed_cycle_action": "STOP",
        "metadata": {
          "meta_metadata": "meta_meta_metadata"
        },
        "description": "Video Game Subscription",
        "items": [
          {
            "type": "DIGITAL_PRODUCT",
            "name": "Cine Mraft",
            "net_unit_amount": 13579,
            "quantity": 1
          }
        ],
        "actions": [
          {
            "action": "AUTH",
            "url": "https://linking-dev.xendit.co/pali_e53e1ca6-3c09-4026-be2e-95ed3d4bb25b",
            "url_type": "WEB",
            "method": "GET"
          }
        ],
        "success_return_url": "https://www.xendit.co/successisthesumoffailures",
        "failure_return_url": "https://www.xendit.co/failureisthemotherofsuccess"
      },
      "api_version": "v1"
    }
    Body Parameter Type Description
    event
    required
    string Identifies the event that triggered a notification to the merchant - recurring.plan.activated
    business_id
    required
    string Business ID of the merchant
    created
    required
    string ISO 8601 Timestamp for webhook notification creation. Timezone UTC+0.
    data
    optional
    object Plan Object with ACTIVE status
    api_version
    optional
    string Version value fixed as v1

    Plan Inactivation Payload

    The plan activation webhook is triggered when the recurring plan is unable to complete requested step to perform an immediate action, when a cycle fails, or when a cycle reached it last recurrence. For example, when the immediate payment action fails.

    Example: Plan Inactivation Payload

    {
      "created": "2022-10-01T12:37:08.251Z",
      "business_id": "62440e322008e87fb29c1fd0",
      "event": "recurring.plan.inactivated",
      "data": {
        "id": "repl-239c16f4-866d-43e8-9341-7badafbc019f",
        "reference_id": "test_reference_id",
        "customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
        "recurring_action": "PAYMENT",
        "recurring_cycle_count": 0,
        "currency": "IDR",
        "amount": 13579,
        "status": "INACTIVE",
        "created": "2020-11-20T16:23:52Z",
        "updated": "2020-11-20T16:23:52Z",
        "payment_methods": [
          {
            "payment_method_id": "pm-239c16f4-866d-43e8-9341-7badafbc019f",
            "rank": 1
          }
        ],
        "schedule_id": "resc-239c16f4-866d-43e8-9341-7badafbc019f",
        "schedule": {
          "reference_id": "test_reference_id",
          "interval": "MONTH",
          "interval_count": 1,
          "created": "2022-02-15T16:23:52Z",
          "updated": "2022-02-15T16:23:52Z",
          "total_recurrence": 12,
          "anchor_date": "2022-02-15T16:23:52Z",
          "retry_interval": "DAY",
          "retry_interval_count": 5,
          "total_retry": 5,
          "failed_attempt_notifications": [
            2,
            4
          ]
        },
        "immediate_action_type": "FULL_AMOUNT",
        "notification_config": {
          "recurring_created": [
            "WHATSAPP",
            "EMAIL"
          ],
          "recurring_succeeded": [
            "WHATSAPP",
            "EMAIL"
          ],
          "recurring_failed": [
            "WHATSAPP",
            "EMAIL"
          ],
          "locale": "en"
        },
        "failed_cycle_action": "STOP",
        "metadata": {
          "meta_metadata": "meta_meta_metadata"
        },
        "description": "Video Game Subscription",
        "items": [
          {
            "type": "DIGITAL_PRODUCT",
            "name": "Cine Mraft",
            "net_unit_amount": 13579,
            "quantity": 1
          }
        ],
        "actions": [
          {
            "action": "AUTH",
            "url": "https://linking-dev.xendit.co/pali_e53e1ca6-3c09-4026-be2e-95ed3d4bb25b",
            "url_type": "WEB",
            "method": "GET"
          }
        ],
        "success_return_url": "https://www.xendit.co/successisthesumoffailures",
        "failure_return_url": "https://www.xendit.co/failureisthemotherofsuccess"
      },
      "api_version": "v1"
    }
    Body Parameter Type Description
    event
    required
    string Identifies the event that triggered a notification to the merchant - recurring.plan.inactivated
    business_id
    required
    string Business ID of the merchant
    created
    required
    string ISO 8601 Timestamp for webhook notification creation. Timezone UTC+0.
    data
    optional
    object Plan Object with INACTIVE status
    api_version
    optional
    string Version value fixed as v1

    Plan - Update

    Recurring plan can be updated via this API to populate changes to newly generated recurring cycles. If changes need to be applied to recurring cycles that have been scheduled, include update-scheduled-cycle parameter in request header.

    Endpoint: Update Recurring Plan

    PATCH https://api.xendit.co/recurring/plans/:id

    Request Parameters

    Example: Update Recurring Plan Request

    curl https://api.xendit.co/recurring/plans/repl-239c16f4-866d-43e8-9341-7badafbc019f -X PATCH \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
      --header 'update-scheduled-cycle: TRUE' \
      --data '{
      "customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
      "currency": "IDR",
      "amount": 100000,
      "payment_methods": [{
          "payment_method_id": "pm-239c16f4-866d-43e8-9341-7badafbc019f",
          "rank": 1
        }],
      "notification_config": {
        "recurring_created": ["WHATSAPP","EMAIL"],
        "recurring_succeeded": [],
        "recurring_failed": ["WHATSAPP","EMAIL"]
        "locale": "en"},
      "metadata": null
    }' \
    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 Xendit-generated recurring plan ID, with prefix repl-xxx
    Body Parameter Type Description
    customer_id
    optional
    string Xendit-generated customer ID, with prefix cust-xxx
    currency
    optional
    enum ISO 4217 currency code of recurring plan. Supported currency - IDR, PHP
    amount
    optional
    number Amount that recurring plan will charge to end users. Recurring cycles will be generated based on this value. If items param is used, amount should be equivalent to the sum of net_unit_amount multiplied by quantity in the items array
    Min IDR - 1000
    Min PHP - 50
    Max - Dependent on individual payment providers
    payment_methods
    optional
    array Array of payment_method_id that the recurring plan will attempt to make payments with (attempts will be made according to the rank of each object in the array). Only one successful payment will be made
    Key Value
    payment_method_id
    required
    string ID for payment_method_id generated by Create Payment Method API
    rank
    required
    number Indicate the order which payments methods will be attempted for a payment cycle instance. Available values - 1 to 5
    notification_config
    optional
    Object Object containing notification preferences for the recurring plan
    Key Value
    recurring_created
    optional
    array Specify which channel you want to notify your end customer through when you a recurring plan is created. Supported values - ["WHATSAPP", "EMAIL"]
    recurring_succeeded
    optional
    array Specify which channel you want to notify your end customer through when you a recurring cycle was successfully completed. Supported values - ["WHATSAPP", "EMAIL"]
    recurring_failed
    optional
    array Specify which channel you want to notify your end customer through when you a recurring cycle has failed. Supported values - ["WHATSAPP", "EMAIL"]
    locale
    optional
    enum Default - "en". ISO 639-1: two-letter codes for language of notifications sent to end user. Supported values - en, id
    payment_link_for_failed_attempt
    optional
    boolean Default = false. Indicates whether the plan should generate a payment link to be sent to the end customer when the first attempt of the cycle fails. The schedule object of the plan must have a minimum total_retry of 1. The plan's notification_config.recurring_failed determines the channel for which the end customer will receive the notification with the payment link URL. You will also receive the payment link URL in the recurring.cycle.retrying callback. For more information about payment links, please see this section
    metadata
    optional
    object Object of additional information the merchants 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
    description
    optional
    string Description of recurring plan - you can use this field to list what items are being paid for, or anything else of your choice that describes the function of the recurring plan. This field will be displayed to end users for UI, email or whatsapp.
    Min - 1 character
    Max - 1000 characters
    items
    optional
    array Array of objects describing the item/s
    Key Value
    type
    required
    string Type of item

    DIGITAL_PRODUCT, PHYSICAL_PRODUCT, DIGITAL_SERVICE, PHYSICAL_SERVICE,FEE,DISCOUNT
    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, please put negative amount for DISCOUNT (e.g. -1000000)
    quantity
    required
    number Number of units of this item in the basket

    Min 1
    url
    optional
    string URL of the item

    Must be HTTPS or HTTP
    category
    optional
    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

    Success responses will contain a single Plan Object.

    Error Codes

    Example: Update Recurring Plan Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server."
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    There is invalid input in one of the required request fields
    API_VALIDATION_ERROR
    400
    Each rank value for payment methods must be unique. Please check your request to deconflict the ranking.
    API_VALIDATION_ERROR
    400
    Values in failed_attempt_notifications array cannot be duplicated or greater than total_retry value or the array values count greater than total_retry
    API_VALIDATION_ERROR
    400
    The payment currency requested is not supported for this payment channel. Please refer to our API reference or docs to pick available currencies
    INVALID_PAYMENT_METHOD_ID
    400
    The payment_method_id provided has a mismatched currency or it is not "ACTIVE" because it has expired/ been unlinked/ linking has not been completed. Please retry with a valid payment_method_id
    INVALID_API_KEY
    401
    API key format is invalid
    PAYMENT_METHOD_ID_NOT_FOUND
    404
    The payment_method_id provided is not found. Please retry with a valid payment_method_id
    CUSTOMER_NOT_FOUND
    404
    customer_id is invalid or not found. Please try again with valid customer_id
    UNSUPPORTED_CONTENT_TYPE
    415
    The content type requested is not supported
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Plan - Deactivate

    Recurring plans can be made inactive via this API. This will stop any new recurring cycles from being generated and for existing SCHEULED cycles to be cancelled.

    Endpoint: Deactivate Recurring Plan

    POST https://api.xendit.co/recurring/plans/:id/deactivate

    Request Parameters

    Example: Deactivate Recurring Plan Request

    curl https://api.xendit.co/recurring/plans/repl-239c16f4-866d-43e8-9341-7badafbc019f/deactivate -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
     <?php
    
    $curl = curl_init();
    
    curl_setopt_array($curl, array(
      CURLOPT_URL => 'https://api.xendit.co/recurring/plans/repl-239c16f4-866d-43e8-9341-7badafbc019f/deactivate',
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => '',
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 0,
      CURLOPT_FOLLOWLOCATION => true,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => 'POST',
      CURLOPT_HTTPHEADER => array(
        'Authorization: Basic eG5kX2RldmVsb3BtZW50X09vbUFmT1V0aCtHb3dzWTZMZUpPSHpMQ1p0U2o4NEo5a1hEbitSeGovbUhXK2J5aERRVnhoZz09Og=='
      ),
    ));
    
    $response = curl_exec($curl);
    
    curl_close($curl);
    echo $response;
    
    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 Xendit-generated recurring plan ID, with prefix repl-xxx

    Response Parameters

    Success responses will contain a single Plan Object with INACTIVE status.

    Error Codes

    Example: Deactivate Recurring Plan Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server."
    }
    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
    DATA_NOT_FOUND
    404
    Recurring plan_id not found. Please check your query again.
    UNSUPPORTED_CONTENT_TYPE
    415
    The content type requested is not supported
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Plan - Fetch Object

    Fetch information about created recurring plans via this API.

    Endpoint: Get Recurring Plan

    GET https://api.xendit.co/recurring/plans/:id/

    Request Parameters

    Example: Get Recurring Plan Request

    curl https://api.xendit.co/recurring/plans/repl-239c16f4-866d-43e8-9341-7badafbc019f -X GET \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
    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 Xendit-generated recurring plan ID, with prefix repl-xxx

    Response Parameters

    Success responses will contain a single Plan Object.

    Error Codes

    Example: Get Recurring Plan Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server."
    }
    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
    DATA_NOT_FOUND
    404
    Recurring plan_id not found. Please check your query again.
    UNSUPPORTED_CONTENT_TYPE
    415
    The content type requested is not supported
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Plan - Get Cycles List

    Fetch information about recurring cycles generated from the recurring plan via this API.

    Endpoint: Get List of Cycles for Plan

    GET https://api.xendit.co/recurring/plans/:id/cycles

    Request Parameters

    Example: Get List of Cycles for Plan Request

    curl https://api.xendit.co/recurring/plans/repl-239c16f4-866d-43e8-9341-7badafbc019f/cycles -X GET \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
      --data '{
      "limit": 2,
      "after_id": "recy_239c16f4-866d-43e8-9341-7badafbc019f"
    }' \
    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 Xendit-generated recurring plan ID, with prefix repl-xxx
    Query Parameter Type Description
    limit
    optional
    number Indicating the maximum number of results to return at one time. This parameter MUST be optional for the client to provide and MUST have a default value of 10 (can be adjusted according to the resource that we are serving), for when the client does not provide a value
    after_id
    optional
    string ID of the immediately previous item

    Response Parameters

    Example: Get List of Cycles for Plan Response

    {
      "data": [
        {
          "id": "recy-AO12308u120jda",
          "reference_id": "test_reference_id",
          "customer_id": "cust-uhdquwy18237y213",
          "recurring_action": "PAYMENT",
          "type": "SCHEDULED",
          "cycle_number": 2,
          "attempt_count": 2,
          "attempt_details": [
            {
              "attempt_number": 1,
              "created": "2020-04-20T16:23:52Z",
              "action_id": "ewc-asdaso213897821hdas",
              "status": "SUCCEEDED",
              "failure_code": null,
              "next_retry_timestamp": null
            },
            {
              "attempt_number": 1,
              "created": "2020-04-20T16:23:52Z",
              "action_id": "ewc-asdaso2138978trysecondmethod",
              "status": "FAILTED",
              "failure_code": "INSUFFICIENT_BALANCE",
              "next_retry_timestamp": "2020-04-20T16:23:52Z"
            }
          ],
          "status": "SUCCEEDED",
          "scheduled_timestamp": "2020-12-20T16:23:52Z",
          "created": "2020-11-20T16:23:52Z",
          "updated": "2020-11-20T16:23:52Z",
          "currency": "IDR",
          "amount": 200000,
          "metadata": null
        }
      ],
      "has_more": false
    }
    Body Parameter Type Description
    data
    required
    array An array of Cycle Objects requested based on query parameters
    has_more
    required
    boolean A boolean parameter indicating whether there are more objects available but filtered out by limit of query parameters

    Error Codes

    Example: Get List of Cycles for Plan Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server."
    }
    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
    DATA_NOT_FOUND
    404
    Recurring plan_id not found. Please check your query again.
    UNSUPPORTED_CONTENT_TYPE
    415
    The content type requested is not supported
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Cycle - Callback Events

    Xendit notifies your system upon created, failed, successful, retrying cycles via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Header Parameter Type Description
    x-callback-token
    required
    string Your Xendit unique webhook token to verify the origin of the webhook
    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks

    Cycle Creation Payload

    The cycle creation webhook is a notification to inform your system of a upcoming cycle in the future. This webhook is triggered when a recurring plan has been successfully activated or when an upcoming recurring cycle has executed its first attempt at the recurring action (from SCHEDULED status to PENDING). For general use cases, it is recommended but not required to handle this webhook. For usage based subscriptions, it is required to handle this webhook.

    Full details of webhooks can be found here

    Example: Cycle Webhook Payload

    {
      "created": "2022-10-01T12:37:08.251Z",
      "business_id": "62440e322008e87fb29c1fd0",
      "event": "recurring.cycle.created",
      "data": {
        "id": "recy-239c16f4-866d-43e8-9341-7badafbc019f",
        "reference_id": "test_reference_id",
        "customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
        "recurring_action": "PAYMENT",
        "type": "SCHEDULED",
        "cycle_number": 1,
        "attempt_count": 0,
        "attempt_details": [],
        "status": "SCHEDULED",
        "scheduled_timestamp": "2020-12-20T16:23:52Z",
        "created": "2020-11-20T16:23:52Z",
        "updated": "2020-11-20T16:23:52Z",
        "currency": "IDR",
        "amount": 13579
      },
      "api_version": "v1"
    }
    Body Parameter Type Description
    event
    required
    string Identifies the event that triggered a notification to the merchant - recurring.cycle.created
    business_id
    required
    string Business ID of the merchant
    created
    required
    string ISO 8601 Timestamp for webhook notification creation. Timezone UTC+0.
    data
    optional
    object Cycle Object with SCHEDULED status
    api_version
    optional
    string Version value fixed as v1

    Cycle Success Payload

    The cycle success webhook is a notification to inform your system of a upcoming cycle in the future. This webhook is triggered when a recurring plan has been successfully activated or when an upcoming recurring cycle has executed its first attempt at the recurring action (from SCHEDULED status to PENDING)

    Example: Cycle Success Payload

    {
      "created": "2022-10-01T12:37:08.251Z",
      "business_id": "62440e322008e87fb29c1fd0",
      "event": "recurring.cycle.succeeded",
      "data": {
        "id": "recy-239c16f4-866d-43e8-9341-7badafbc019f",
        "reference_id": "test_reference_id",
        "customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
        "recurring_action": "PAYMENT",
        "type": "SCHEDULED",
        "cycle_number": 1,
        "attempt_count": 1,
        "attempt_details": [
          {
            "attempt_number": 1,
            "created": "2020-04-21T16:23:52Z",
            "action_id": "ewc-239c16f4-866d-43e8-9341-7badafbc019f",
            "status": "SUCCEEDED",
            "Failure_code": null,
            "next_retry_timestamp": null
          }],
        "status": "SUCCEEDED",
        "scheduled_timestamp": "2020-12-20T16:23:52Z",
        "created": "2020-11-20T16:23:52Z",
        "updated": "2020-11-20T16:23:52Z",
        "currency": "IDR",
        "amount": 13579
      },
      "api_version": "v1"
    }
    Body Parameter Type Description
    event
    required
    string Identifies the event that triggered a notification to the merchant - recurring.cycle.succeeded
    business_id
    required
    string Business ID of the merchant
    created
    required
    string ISO 8601 Timestamp for webhook notification creation. Timezone UTC+0.
    data
    optional
    object Cycle Object with SUCCEEDED status
    api_version
    optional
    string Version value fixed as v1

    Cycle Retrying Payload

    The cycle retrying webhook is a notification to inform your system an attempt at the recurring action has failed and the recurring cycle will attempt to perform the recurring action again. This webhook would only be triggered if a retry logic was configured in the recurring plan. For general use cases, it is recommended but not required to handle this webhook.

    Example: Cycle Retrying Payload

    {
      "created": "2022-10-01T12:37:08.251Z",
      "business_id": "62440e322008e87fb29c1fd0",
      "event": "recurring.cycle.retrying",
      "data": {
        "id": "recy-239c16f4-866d-43e8-9341-7badafbc019f",
        "reference_id": "test_reference_id",
        "customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
        "recurring_action": "PAYMENT",
        "type": "SCHEDULED",
        "cycle_number": 1,
        "attempt_count": 1,
        "attempt_details": [
          {
            "attempt_number": 1,
            "created": "2020-04-21T16:23:52Z",
            "action_id": "ewc-239c16f4-866d-43e8-9341-7badafbc019f",
            "status": "FAILED",
            "Failure_code": "INSUFFICIENT_BALANCE",
            "next_retry_timestamp": "2020-04-24T16:23:52Z"
          }],
        "status": "RETRYING",
        "scheduled_timestamp": "2020-12-20T16:23:52Z",
        "created": "2020-11-20T16:23:52Z",
        "updated": "2020-11-20T16:23:52Z",
        "currency": "IDR",
        "amount": 13579
      },
      "api_version": "v1"
    }
    Body Parameter Type Description
    event
    required
    string Identifies the event that triggered a notification to the merchant - recurring.cycle.retrying
    business_id
    required
    string Business ID of the merchant
    created
    required
    string ISO 8601 Timestamp for webhook notification creation. Timezone UTC+0.
    data
    optional
    object Cycle Object with RETRYING status
    api_version
    optional
    string Version value fixed as v1

    Cycle Failure Payload

    The cycle failure webhook is a notification to inform your system that attempts at the recurring action and all the subsequent retries has failed.

    Example: Cycle Failure Payload

    {
      "created": "2022-10-01T12:37:08.251Z",
      "business_id": "62440e322008e87fb29c1fd0",
      "event": "recurring.cycle.failed",
      "data": {
        "id": "recy-239c16f4-866d-43e8-9341-7badafbc019f",
        "reference_id": "test_reference_id",
        "customer_id": "cust-239c16f4-866d-43e8-9341-7badafbc019f",
        "recurring_action": "PAYMENT",
        "type": "SCHEDULED",
        "cycle_number": 1,
        "attempt_count": 1,
        "attempt_details": [
          {
            "attempt_number": 1,
            "created": "2020-04-21T16:23:52Z",
            "action_id": "ewc-239c16f4-866d-43e8-9341-7badafbc019f",
            "status": "FAILED",
            "Failure_code": "INSUFFICIENT_BALANCE",
            "next_retry_timestamp": null
          }],
        "status": "FAILED",
        "scheduled_timestamp": "2020-12-20T16:23:52Z",
        "created": "2020-11-20T16:23:52Z",
        "updated": "2020-11-20T16:23:52Z",
        "currency": "IDR",
        "amount": 13579
      },
      "api_version": "v1"
    }
    Body Parameter Type Description
    event
    required
    string Identifies the event that triggered a notification to the merchant - recurring.cycle.failed
    business_id
    required
    string Business ID of the merchant
    created
    required
    string ISO 8601 Timestamp for webhook notification creation. Timezone UTC+0.
    data
    optional
    object Cycle Object with FAILED status
    api_version
    optional
    string Version value fixed as v1

    Cycle - Update

    Recurring cycle can be updated via this API. Usage based subscription use cases should use this endpoint to update the amount for each specific billing instances.

    Endpoint: Update Recurring Cycle

    PATCH https://api.xendit.co/recurring/plans/:plan_id/cycles/:id

    Request Parameters

    Example: Update Recurring Cycle Request

    curl https://api.xendit.co/recurring/plans/repl-239c16f4-866d-43e8-9341-7badafbc019f/cycles/recy-239c16f4-866d-43e8-9341-7badafbc019f -X PATCH \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
      --data '{
      "scheduled_timestamp": "2020-12-20T16:23:52Z",
      "currency": "IDR",
      "amount": 200000
    }' \
    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
    plan_id
    required
    string Xendit-generated recurring plan ID, with prefix repl-xxx
    id
    required
    string Xendit-generated recurring cycle ID, with prefix recy-xxx
    Body Parameter Type Description
    scheduled_timestamp
    optional
    string ISO 8601 Timestamp (e.g. "2020-04-20T00:00:00Z" UTC+0) for the upcoming action attempt for the recurring cycle - value is updated on each retry (if any). Action will be executed within 24 hours of the scheduled timestamp with timezone taken into consideration.
    currency
    optional
    enum ISO 4217 currency code of recurring plan. Supported currency - IDR, PHP
    amount
    optional
    number Amount that recurring plan will charge to end users. Recurring cycles will be generated based on this value. If items param is used, amount should be equivalent to the sum of net_unit_amount multiplied by quantity in the items array
    Min IDR - 1000
    Min PHP - 50
    maximum amount is dependent on payment providers

    Response Parameters

    Success responses will contain a single Cycle Object.

    Error Codes

    Example: Update Recurring Cycle Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server."
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    There is invalid input in one of the required request fields
    API_VALIDATION_ERROR
    400
    Parameter scheduled_timestamp cannot be in the past. Please check your request body
    INVALID_API_KEY
    401
    API key format is invalid
    INELIGIBLE_CYCLE_REQUEST
    403
    Requested changes to cycle cannot be processed. Only cycles in "SCHEDULED" status can be cancelled or updated
    DATA_NOT_FOUND
    404
    Recurring cycle_id not found. Please check your query again.
    UNSUPPORTED_CONTENT_TYPE
    415
    The content type requested is not supported
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Cycle - Cancel

    Recurring cycles can be made cancelled via this API. This will the recurring cycles from processing any actions.

    Endpoint: Cancel Recurring Cycle

    POST https://api.xendit.co/recurring/plans/:plan_id/cycles/:id/cancel

    Request Parameters

    Example: Cancel Recurring Cycle Request

    curl https://api.xendit.co/recurring/plans/repl-239c16f4-866d-43e8-9341-7badafbc019f/cycles/recy-239c16f4-866d-43e8-9341-7badafbc019f/cancel -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' 
    <?php
    
    $curl = curl_init();
    
    curl_setopt_array($curl, array(
      CURLOPT_URL => 'https://api.xendit.co/recurring/plans/repl-239c16f4-866d-43e8-9341-7badafbc019f/cycles/recy-239c16f4-866d-43e8-9341-7badafbc019f/cancel',
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => '',
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 0,
      CURLOPT_FOLLOWLOCATION => true,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => 'POST',
      CURLOPT_HTTPHEADER => array(
        'Authorization: Basic eG5kX2RldmVsb3BtZW50X09vbUFmT1V0aCtHb3dzWTZMZUpPSHpMQ1p0U2o4NEo5a1hEbitSeGovbUhXK2J5aERRVnhoZz09Og=='
      ),
    ));
    
    $response = curl_exec($curl);
    
    curl_close($curl);
    echo $response;
    
    Path Parameter Type Description
    plan_id
    required
    string Xendit-generated recurring plan ID, with prefix repl-xxx
    id
    required
    string Xendit-generated recurring cycle ID, with prefix recy-xxx

    Response Parameters

    Success responses will contain a single Cycle Object with CANCELLED status.

    Error Codes

    Example: Cancel Recurring Cycle Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server."
    }
    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
    UNSUPPORTED_CONTENT_TYPE
    403
    The content type requested is not supported
    INELIGIBLE_CYCLE_REQUEST
    403
    Requested changes to cycle cannot be processed. Only cycles in "SCHEDULED" status can be cancelled or updated
    DATA_NOT_FOUND
    404
    Recurring plan_id not found. Please check your query again.
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Cycle - Force Cycle Attempt

    Endpoint for merchants to manually force an attempt for the specified action of a recurring cycle. Please refer to our force cycle attempt docs for more details.

    Endpoint: Force Cycle Attempt

    POST https://api.xendit.co/recurring/plans/:id/cycles/:id/force_attempt

    Request Parameters

    Example: Force Cycle Attempt Request

    curl https://api.xendit.co/recurring/plans/repl_532as23lew2321id/cycles/recy_5832948hjkeqw12/force_attempt -X POST \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
    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
    plan_id
    required
    string Xendit-generated recurring plan ID, with prefix repl-xxx
    id
    required
    string Xendit-generated recurring cycle ID, with prefix recy-xxx

    Response Parameters

    Return Cycle Object with status code 200 and status PENDING

    Example: Force Cycle Attempt Response

    {
      "id": "repl-AO12308u120jda",
      "reference_id": "test_reference_id",
      "customer_id": "cust-uhdquwy18237y213",
      "recurring_action": "PAYMENT",
      "type": "SCHEDULED",
      "cycle_number": 2,
      "attempt_count": 1,
      "attempt_details": [{
          "attempt_number": null,
          "created": "2020-04-20T16:23:52Z",
          "action_id": "ewc-asdaso213897821hdas",
          "status": "SUCCEEDED",
          "failure_code": null,
          "next_retry_timestamp": null
        },
        {
          "attempt_number": 1,
          "created": "2020-04-20T16:23:52Z",
          "action_id": "ewc-asdaso2138978trysecondmethod",
          "status": "FAILTED",
          "failure_code": "INSUFFICIENT_BALANCE",
          "next_retry_timestamp": "2020-04-20T16:23:52Z"
        }],
      "status": "PENDING",
      "scheduled_timestamp": "2020-12-20T16:23:52Z",
      "created": "2020-11-20T16:23:52Z",
      "updated": "2020-11-20T16:23:52Z",
      "currency": "IDR",
      "amount": 200000
    }
    

    Error Codes

    Example: Update Recurring Cycle Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server."
    }
    Error Code Description
    INELIGIBLE_CYCLE_REQUEST
    403
    Requested attempt trigger for this cycle cannot be processed. Only cycles in SCHEDULED or RETRYING status are eligible for Force Attempt.
    MAXIMUM_LIMIT_REACHED
    403
    Maximum number (5) of force attempts have been reached
    DATA_NOT_FOUND
    404
    Recurring cycle_id not found. Please check your query again.
    UNSUPPORTED_CONTENT_TYPE
    415
    The content type requested is not supported
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Cycle - Fetch Object

    Fetch information about generated recurring cycles via this API.

    Endpoint: Get Recurring Cycle

    GET https://api.xendit.co/recurring/plans/:plan_id/cycles/:id

    Request Parameters

    Example: Get Recurring Cycle Request

    curl https://api.xendit.co/recurring/plans/repl-239c16f4-866d-43e8-9341-7badafbc019f/cycles/recy-239c16f4-866d-43e8-9341-7badafbc019f -X GET \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
    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
    plan_id
    required
    string Xendit-generated recurring plan ID, with prefix repl-xxx
    id
    required
    string Xendit-generated recurring cycle ID, with prefix recy-xxx

    Response Parameters

    Success responses will contain a single Cycle Object.

    Error Codes

    Example: Cancel Recurring Cycle Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server."
    }
    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
    UNSUPPORTED_CONTENT_TYPE
    403
    The content type requested is not supported
    DATA_NOT_FOUND
    404
    Recurring cycle_id not found. Please check your query again.
    UNSUPPORTED_CONTENT_TYPE
    415
    The content type requested is not supported
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Cycle - Simulate Status

    (Works only in Test Mode) To enable testing for subsequent recurring cycles, this endpoint helps merchants simulate whether a recurring actions (e.g. payments) has been successful or not. Please ensure that you are using development API key for this purpose. Xendit payments uses specific numbers in amount parameter to simulate a success/ failed status. Please follow our documentation to simulate the error you need.

    Endpoint: Simulate Recurring Cycle

    POST https://api.xendit.co/recurring/plans/:plan_id/cycles/:id/simulate

    Request Parameters

    Example: Simulate Recurring Cycle Request

    curl https://api.xendit.co/recurring/plans/repl-239c16f4-866d-43e8-9341-7badafbc019f/cycles/recy-239c16f4-866d-43e8-9341-7badafbc019f -X PATCH \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
      --data '{
      "amount": 200000
    }' \
    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
    plan_id
    required
    string Xendit-generated recurring plan ID, with prefix repl-xxx
    id
    required
    string Xendit-generated recurring cycle ID, with prefix recy-xxx
    Body Parameter Type Description
    amount
    required
    number Amount to be simulated

    Response Parameters

    Success responses will contain a single Cycle Object.

    Error Codes

    Example: Update Recurring Cycle Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server."
    }
    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
    INELIGIBLE_CYCLE_REQUEST
    403
    Requested changes to cycle cannot be processed. Only cycles in "SCHEDULED" status can be cancelled or updated
    DATA_NOT_FOUND
    404
    Recurring cycle_id not found. Please check your query again.
    UNSUPPORTED_CONTENT_TYPE
    415
    The content type requested is not supported
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Schedule - Update

    Recurring schedule can be updated via this API to populate changes to newly generated recurring cycles. If changes need to be applied to recurring cycles that have been scheduled, include update-scheduled-cycle parameter in request header.

    Endpoint: Update Recurring Schedule

    PATCH https://api.xendit.co/recurring/schedules/:id

    Request Parameters

    Example: Update Recurring Schedule Request

    curl https://api.xendit.co/recurring/schedules/resc-239c16f4-866d-43e8-9341-7badafbc019f -X PATCH \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
      --data '{
        "interval" : "MONTH",
        "interval_count" : 1,
        "total_recurrence" : 12,
        "anchor_date" : "2020-11-20T16:23:52Z",
        "retry_interval" : "DAY",
        "retry_interval_count" : 5,
        "total_retry" : 5,
        "failed_attempt_notifications" : [2,4]
    }' \
    Path Parameter Type Description
    id
    required
    string Xendit-generated recurring schedule ID, with prefix resc-xxx
    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
    interval
    optional
    enum The type of interval between consecutive recurring cycles. Supported values - DAY, WEEK, MONTH

    WEEK - the day of the week which anchor_date lands on (e.g. anchor_date lands on Wed, subsequent cycles will be on Wed)
    MONTH - the date of the month which anchor_date lands on (anchor_date lands on the 25th, subsequent cycles will be on the 25th)
    interval_count
    optional
    number The number of units of interval between consecutive recurring cycles (e.g. interval = MONTH, interval_count = 3, then recurring cycle happens every 3 month)
    total_recurrence
    optional
    number Default = NULL The total number of times the end user will be charged. The immediate charge instance does not count to total_recurrence. If the parameter is not used, recurring plan will run on indefinitely
    anchor_date
    optional
    string Default = the date of schedule creation (same day action). Timestamp in ISO 8601 ("2020-11-20T16:23:52+07:00"). A timestamp used to determine when a recurring plan starts. The date, day of week or date of month will be used to initialize the recurring cycle (back dated timestamps still works). If a timezone passed in, the recurring event will be executed based on the timezone, else UTC 0 wil be used.

    Supported values - Timestamps between 1st to 28th of a month

    If no anchor_date value is passed and date of schedule creation falls on 29/30/31, anchor date will be defaulted to 1st of next month
    retry_interval
    optional
    enum The type of interval between failed attempt and retries. Supported values - DAY
    retry_interval_count
    optional
    number The number of units of retry_interval between consecutive retries (e.g. retry_interval = DAY, retry_interval_count = 3, then recurring cycle retries 3 days after a failed attempt)
    total_retry
    optional
    number The number of times you will retry a failed recurring cycle. If no value is passed into total_retry, it will be null by default and no retries will be triggered
    Min - 1
    Max - 10
    failed_attempt_notifications
    optional
    string Specify which retry attempts will have failed recurring notifications to the end user. Array values count should not be greater than total_retry number or duplicated. 1 in this param refers to the first retry attempt.

    Response Parameters

    Success responses will contain a single Schedule Object.

    Error Codes

    Example: Update Recurring Schedule Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server."
    }
    Error Code Description
    API_VALIDATION_ERROR
    400
    There is invalid input in one of the required request fields
    API_VALIDATION_ERROR
    400
    Each rank value for payment methods must be unique. Please check your request to deconflict the ranking.
    API_VALIDATION_ERROR
    400
    Values in failed_attempt_notifications array cannot be duplicated or greater than total_retry value or the array values count greater than total_retry
    API_VALIDATION_ERROR
    400
    anchor_date does not accept dates from 29 to 31. Please check your request body to specify all values
    INVALID_API_KEY
    401
    API key format is invalid
    DATA_NOT_FOUND
    404
    Recurring schedule_id not found. Please check your query again.
    UNSUPPORTED_CONTENT_TYPE
    415
    The content type requested is not supported
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    Schedule - Fetch Object

    Fetch information about created recurring schedule via this API.

    Endpoint: Get Recurring Schedule

    GET https://api.xendit.co/recurring/schedules/:id

    Request Parameters

    Example: Get Recurring Schedule Request

    curl https://api.xendit.co/recurring/schedules/resc-239c16f4-866d-43e8-9341-7badafbc019f -X GET \
      --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
      --header 'content-type: application/json' \
    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 Xendit-generated recurring schedule ID, with prefix resc-xxx

    Response Parameters

    Success responses will contain a single Schedule Object.

    Error Codes

    Example: Update Recurring Schedule Request API Error Response

    {
        "error_code": "API_VALIDATION_ERROR",
        "message": "There is an error with the format submitted to the server."
    }
    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
    DATA_NOT_FOUND
    404
    Recurring schedule_id not found. Please check your query again.
    UNSUPPORTED_CONTENT_TYPE
    415
    The content type requested is not supported
    SERVER_ERROR
    500
    An unexpected error occured, our team has been notified and will troubleshoot the issue

    xenPlatform

    Description

    xenPlatform is Xendit's solution for platform businesses that work with third-party partners. Platform businesses face complex payments challenges that range from partner onboarding, to moving funds, to payouts and billing.

    With xenPlatform, you can onboard and create accounts for your partners, transact on behalf of them, split payments, monitor their transactions, and directly bill them.

    Overview

    Once xenPlatform has been activated for your account, you may use the Account API to create sub accounts that are linked to your master account.

    Thereafter simply include a for-user-id header in any standard Xendit API call to create a transaction for those accounts.

    These accounts and their transactions will appear in the xenPlatform tab of your Xendit dashboard.

    Create Account

    The Create Account API allows you to create Accounts for your Partners that are linked to your Platform. Once an Account is created, you may accept payments on its behalf. Additionally, you can route payments to/from the Account via the Transfers API or Platform fee API.

    There are two types of Accounts that can be created: MANAGED, OWNED. Review our documentation for recommendations on which Account type to use for your business model.

    MANAGED Accounts provide your Partners with full-fledged Xendit Accounts that your Platform can transact on behalf of. Your Partners may register their Account via an invitation email is sent to the email. Thereafter, your Partners login to their own Xendit dashboard to complete the onboarding process.

    OWNED Accounts are invisible to your Partners and fully controlled by you. You may transact on behalf of an OWNED Account once they have been created using payment methods that have been enabled on your Platform.

    You can also choose to configure the account yourself using the configurations parameter below, instead of specifying a type.

    Store the returned account id value to make transactions for that Account in the future.

    Make 2 API calls to accept payments on behalf of your Partners:

    1. Create an Account (this step)
    2. Create a payment transaction and handling related Callbacks

    Note: Newly enabled payment methods and changes made to Callback URLs on the Platform do not automatically update for OWNED Accounts created before those updates. We recommend activating payment methods you need and setting up your Callback URLs on the dashboard before creating OWNED Accounts.

    Alternatively, use the Set Callback URLs API, or contact us when you need to make a change.

    Version

    This version of the API is asynchronous to improve performance and scalability. We have also added API permissions in this version. If you are using an existing API key, please edit your permissions in your Settings page.

    It is mandatory to wait for the account.created callback before attempting to create transactions. Set a Callback URL in your Dashboard to receive Account Updated Callbacks and know when payments can be processed for your Accounts.

    Endpoint: Create Account

    POST https://api.xendit.co/v2/accounts

    Request Parameters

    Example: Create Account (OWNED)

    curl --request POST \
      --url https://api.xendit.co/v2/accounts \
      --header 'Authorization: Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==' \
      --header 'Content-Type: application/json' \
      --data '{"email":"angie@pinkpanther.com","type":"OWNED","public_profile":{"business_name":"Angie lemonade stand"}}'
    <?php
    
    $curl = curl_init();
    
    curl_setopt_array($curl, [
      CURLOPT_URL => "https://api.xendit.co/v2/accounts",
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => "",
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 30,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => "POST",
      CURLOPT_POSTFIELDS => "{\"email\":\"angie@pinkpanther.com\",\"type\":\"OWNED\",\"public_profile\":{\"business_name\":\"Angie lemonade stand\"}}",
      CURLOPT_HTTPHEADER => [
        "Authorization: Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==",
        "Content-Type: application/json"
      ],
    ]);
    
    $response = curl_exec($curl);
    $err = curl_error($curl);
    
    curl_close($curl);
    
    if ($err) {
      echo "cURL Error #:" . $err;
    } else {
      echo $response;
    }
    import http.client
    
    conn = http.client.HTTPSConnection("api.xendit.co")
    
    payload = "{\"email\":\"angie@pinkpanther.com\",\"type\":\"OWNED\",\"public_profile\":{\"business_name\":\"Angie lemonade stand\"}}"
    
    headers = {
        'Content-Type': "application/json",
        'Authorization': "Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og=="
        }
    
    conn.request("POST", "/v2/accounts", payload, headers)
    
    res = conn.getresponse()
    data = res.read()
    
    print(data.decode("utf-8"))

    Example: Create Account (CUSTOM)

    curl --request POST \
      --url https://api.xendit.co/v2/accounts \
      --header 'Authorization: Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==' \
      --header 'Content-Type: application/json' \
      --data '{"email":"angie@pinkpanther.com","public_profile":{"business_name":"Angie lemonade stand"},"configurations":{"has_dashboard":true,"payment_settings_follow_platform":true,"has_withdrawal":false}}'
    Body Parameter Type Description
    email
    required
    string Email identifier for your account

    Minimum length 1 character
    Maximum length No maximum characters
    type
    optional
    string The type of account you are creating. Defaults to CUSTOM if not specified, and will require the configurations parameter.

    Available values: MANAGED, OWNED
    public_profile
    required for OWNED type or if configurations.has_dashboard is false
    object Contains information that will be seen by end-payers or end-recipients (e.g. appears on hosted checkout page, credit card statements, etc.).
    business_name
    required for OWNED

    Minimum length 1 character
    Maximum length 128 characters
    string Name of the business

    configurations
    required if type is not specified
    object Contains the configurations for CUSTOM sub-accounts
    payment_settings_follow_platform
    default false
    boolean Determines whether the sub-account will use the Platform's payment methods. Learn more about supported payment methods for each type here.
    If false, the sub-account will need to activate its own payment methods.
    has_withdrawal
    default false
    boolean Determines whether withdrawals will be enabled for the sub-account. This will require the account to complete Activation upon login.
    has_dashboard
    default false
    boolean Determines whether dashboard access will be enabled. An invitation will be sent to the sub-account's email address to sign up and login.
    Must be true if payment_settings_follow_platform is false, or if has_withdrawal is true in order to complete Activation.

    Response Parameters

    Example: Create Account Response (OWNED)

    {
      "id": "5cafeb170a2b18519b1b8761",
      "created": "2021-01-01T10:00:00Z",
      "updated": "2021-01-01T10:00:00Z",
      "type": "OWNED",
      "email": "angie@pinkpanther.com",
      "public_profile": {
        "business_name": "Angie lemonade stand"
      },
      "status": "LIVE"
    }

    Example: Create Account Response (CUSTOM)

    {
      "id": "5cafeb170a2b18519b1b8761",
      "created": "2021-01-01T10:00:00Z",
      "updated": "2021-01-01T10:00:00Z",
      "type": "CUSTOM",
      "email": "angie@pinkpanther.com",
      "public_profile": {
        "business_name": "Angie custom stand"
      },
      "status": "LIVE",
      "configurations": {
        "has_dashboard": true,
        "payment_settings_follow_platform": true,
        "has_withdrawal": false
      }
    }
    Parameter Type Description
    id
    required
    string ID of your Account, use this in the for-user-id header to create transactions on behalf of your Account
    created
    required
    string Timestamp of when the account was created

    Timezone: GMT+0
    updated
    required
    string Timestamp of when the account was updated

    Timezone: GMT+0
    type
    required
    string The type of account created

    Available values: MANAGED, OWNED, CUSTOM
    email
    required
    string Email identifier for the Account
    public_profile
    required
    object Contains information that will be seen by end-payers or end-recipients (e.g. appears on hosted checkout page, credit card statements, etc.).
    country
    required
    string The country (based on ISO 3166-1 Alpha-2) of incorporation for a business, or the country of residence for an individual.
    Available values: ID, PH


    Default value: Your country of operation
    status
    required
    string Status of the Account you are creating.

    Available values: INVITED, REGISTERED, AWAITING_DOCS, LIVE

    Learn what these statuses mean in our documentation
    configurations
    optional
    object Contains the configurations for CUSTOM sub-accounts.
    Parameters available: payment_settings_follow_platform, has_withdrawal, has_dashboard

    Error Codes

    Error Code Error Message
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    INVALID_CONFIGURATION
    400
    The configurations parameter combination is invalid. Please follow the requirement of each parameter written in Request section.
    TYPE_AND_CONFIGURATION_CONFLICT
    400
    Please provide either one of the type field or the configuration field

    Get Account by ID

    Use the Get Account by ID endpoint to retrieve the relevant Account object.

    Endpoint: Get Account

    GET https://api.xendit.co/v2/accounts/{id}

    Path Parameters

    Parameter Type Description
    id
    required
    string ID of an Account

    Example: Get Account

    curl --request GET \
      --url https://api.xendit.co/v2/accounts/5cafeb170a2b18519b1b8761 \
      --header 'Authorization: Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og=='
    <?php
    
    $curl = curl_init();
    
    curl_setopt_array($curl, [
      CURLOPT_URL => "https://api.xendit.co/v2/accounts/5cafeb170a2b18519b1b8761",
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => "",
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 30,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => "GET",
      CURLOPT_HTTPHEADER => [
        "Authorization: Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og=="
      ],
    ]);
    
    $response = curl_exec($curl);
    $err = curl_error($curl);
    
    curl_close($curl);
    
    if ($err) {
      echo "cURL Error #:" . $err;
    } else {
      echo $response;
    }
    import http.client
    
    conn = http.client.HTTPSConnection("api.xendit.co")
    
    headers = { 'Authorization': "Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==" }
    
    conn.request("GET", "/v2/accounts/5cafeb170a2b18519b1b8761", headers=headers)
    
    res = conn.getresponse()
    data = res.read()
    
    print(data.decode("utf-8"))

    Response Parameters

    Example: Create Account Response

    {
      "id": "5cafeb170a2b18519b1b8761",
      "created": "2021-01-01T10:00:00Z",
      "updated": "2021-01-01T10:00:00Z",
      "type": "OWNED",
      "email": "angie@pinkpanther.com",
      "public_profile": {
        "business_name": "Angie lemonade stand"
      },
      "status": "LIVE"
    }
    Parameter Type Description
    id
    required
    string ID of your Account, use this in the for-user-id header to create transactions on behalf of your Account
    created
    required
    string Timestamp of when the account was created

    Timezone: GMT+0
    updated
    required
    string Timestamp of when the account was updated

    Timezone: GMT+0
    type
    required
    string The type of account created

    Available values: MANAGED, OWNED
    email
    required
    string Email identifier for the Account
    public_profile
    required
    object Contains information that will be seen by end-payers or end-recipients (e.g. appears on hosted checkout page, credit card statements, etc.).
    country
    required
    string The country (based on ISO 3166-1 Alpha-2) of incorporation for a business, or the country of residence for an individual.

    Available values: ID, PH


    Default value: Your country of operation
    status
    required
    string Status of the Account you are creating.

    Available values: INVITED, REGISTERED, AWAITING_DOCS, LIVE, SUSPENDED

    List Accounts

    Endpoint: List Accounts

    GET https://api.xendit.co/v2/accounts

    Use this endpoint to gather information regarding all of your sub accounts. You can also gather information regarding a particular sub account through filtering by email, sub account creation date, sub account type, sub account name, or status. The result will be paginated and ordered by the sub account creation date.

    Request Parameters

    Example List Transactions Request

    curl --location --request GET 'https://api.xendit.co/v2/accounts' -X POST \
    --user xnd_development_ksdjimLskjdwuasndjjwas \
    --header Content-Type: application/json' \
    <?php
    
    $url = "https://api.xendit.co/v2/accounts";
    
    $payload = array();
    
    $headers = array(
      'Content-Type: application/json',
      'Authorization: Basic xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg=='
    );
    
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    
    $response = curl_exec($curl);
    
    curl_close($curl);
    if ($err) {
      echo "cURL Error #:" . $err;
    } else {
      echo $response;
    }
    import requests
    
    url = "https://api.xendit.co/v2/accounts"
    
    payload={}
    headers = {
      'Content-Type': 'application/json',
      'Authorization': 'Basic xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg=='
    }
    
    response = requests.request("GET", url, headers=headers, data=payload)
    url := "https://api.xendit.co/v2/accounts"
    
        payload := strings.NewReader("")
        req, _ := http.NewRequest("GET", url, payload)
    
        req.Header.Add("Content-Type", "application/json")
        req.Header.Add("Authorization", "Basic xnd_development_O46JfOtygef9kMNsK+ZPGT+TeStIngw3Dn+R1k+2fT/7GlCAN3jg==")
    
        res, _ := http.DefaultClient.Do(req)
    
        defer res.Body.Close()
        body, _ := ioutil.ReadAll(res.Body)
    Query Parameter Type Description
    email
    optional
    array of strings The email of the accounts that will be filtered. If not specified, all account emails will be returned.

    status
    optional
    array of strings The status of the transactions that will be filtered. If not specified, all account status will be returned.

    Available status:
    INVITED,REGISTERED,AWAITING_DOCS,LIVE,SUSPENDED.
    public_profile.business_name
    optional
    string The public profile or business name of the accounts that will be filtered. If not specified, all account business name will be returned. This is the business name specified during account creation

    type
    optional
    string The type of accounts that will be filtered. If not specified, all account types will be returned.

    Available type:
    OWNED,MANAGED.
    created[gte]
    optional
    string (ISO 8601) Start time of accounts by created date. If not specified will list all dates.
    created[lte]
    optional
    string (ISO 8601) End time of accounts by created date. If not specified will list all dates.
    updated[lte]
    optional
    string (ISO 8601) End time of accounts by updated date. If not specified will list all dates.
    updated[gte]
    optional
    string (ISO 8601) Start time of accounts 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

    Returns array of the Account object as follows:

    Example List Accounts Response

    {
        "data": [
            {
                "id": "623ace8270bbddf93816b3a1",
                "created": "2022-02-10T07:13:19.602Z",
                "updated": "2022-02-10T07:13:22.193Z",
                "email": "sample_email@sample.com",
                "type": "OWNED",
                "public_profile": {
                    "business_name": "Sample OWNED Business"
                },
                "country": "ID",
                "status": "LIVE"
            },
            {
                "id": "623ace8270bbddf93816b3g1",
                "created": "2022-03-23T07:38:42.166Z",
                "updated": "2022-03-23T07:39:55.440Z",
                "email": "sample_email2@sample.com",
                "type": "MANAGED",
                "public_profile": {
                    "business_name": "Sample MANAGED Business"
                },
                "country": "ID",
                "status": "REGISTERED"
            }
        ],
        "has_more": true,
        "links": [
            {
                "href": "/v2/accounts?after_id=623ace8270bbddf93816b3g1",
                "rel": "next",
                "method": "GET"
            }
        ]
    }
    Parameter Type Description
    id
    required
    string ID of your Account, use this in the for-user-id header to create transactions on behalf of your Account
    created
    required
    string Timestamp of when the account was created

    Timezone: GMT+0
    updated
    required
    string Timestamp of when the account was updated

    Timezone: GMT+0
    type
    required
    string The type of account created

    Available values: MANAGED, OWNED
    email
    required
    string Email identifier for the Account
    public_profile
    required
    object Contains information that will be seen by end-payers or end-recipients (e.g. appears on hosted checkout page, credit card statements, etc.).
    country
    required
    string The country (based on ISO 3166-1 Alpha-2) of incorporation for a business, or the country of residence for an individual.

    Available values: ID, PH


    Default value: Your country of operation
    status
    required
    string Status of the Account you are creating.

    Available values: INVITED, REGISTERED, AWAITING_DOCS, LIVE, SUSPENDED

    Error Codes

    See other common errors here.

    Update Account

    Use the Update Account endpoint to update your Accounts' business name and email. This operation is currently only enabled for OWNED accounts.

    Version

    You are currently viewing the newest version of our Update Accounts API.

    Endpoint: Update Account

    PATCH https://api.xendit.co/v2/accounts/{id}

    Example: Update Account

    curl https://api.xendit.co/v2/accounts/{id} -X PATCH \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -H 'Content-Type: application/json' \
       -d $'{"email":"angie@pinkpanther.com","public_profile":{"business_name":"Angie\'s lemonade stand"}}'
      <?php
          $url = 'https://api.xendit.co/v2/accounts/{id}';
          $apiKey = 'xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==';
          $headers = [];
          $headers[] = 'Content-Type: application/json';
          $data = [
              'email' => 'angie@pinkpanther.com',
              'public_profile' => [
                'business_name' => 'Angie\'s lemonade stand'
              ]
          ];
          $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, 'PATCH');
          curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
          curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
          $result = curl_exec($curl);
          echo $result;

    Path Parameters

    Path Parameter Type Description
    id
    required
    string The id of the Account created

    Request Parameters

    Request Parameter Type Description
    email
    required
    string Email identifier for your account

    Minimum length 1 character
    Maximum length No maximum characters
    public_profile
    required for OWNED, else optional
    object Contains information that will be seen by end-payers or end-recipients (e.g. appears on hosted checkout page, credit card statements, etc.).
    business_name
    required for OWNED, else optional


    Minimum length 1 character
    Maximum length 128 characters
    string Name of the business

    Response Parameters

    Example: Update Account Response

    {
      "id": "5cafeb170a2b18519b1b8761",
      "created": "2021-01-01T10:00:00Z",
      "updated": "2021-01-01T11:00:00Z",
      "type": "OWNED",
      "email": "angie@pinkpanther.com",
      "public_profile": {
        "business_name": "Angie lemonade stand"
      },
      "status": "LIVE"
    }
    Parameter Type Description
    id
    required
    string ID of your Account, use this in the for-user-id header to create transactions on behalf of your Account
    created
    required
    string Timestamp of when the account was created

    Timezone: GMT+0
    updated
    required
    string Timestamp of when the account was updated

    Timezone: GMT+0
    type
    required
    string The type of account created

    Available values: MANAGED, OWNED
    email
    required
    string Email identifier for the Account
    public_profile
    required
    object Contains information that will be seen by end-payers or end-recipients (e.g. appears on hosted checkout page, credit card statements, etc.).
    country
    required
    string The country (based on ISO 3166-1 Alpha-2) of incorporation for a business, or the country of residence for an individual.
    Available values: ID, PH


    Default value: Your country of operation
    status
    required
    string Status of the Account you are creating.

    Available values: INVITED, REGISTERED, AWAITING_DOCS, LIVE

    Learn what these statuses mean in our documentation

    Account Holder Object

    Example of Account Holder Object

    {
        "id": "4376b7b0-1c44-46be-8640-828f79cdc8be",
        "business_detail": {
            "type": "CORPORATION",
            "legal_name": "test16",
            "description": "testing",
            "trading_name": "test",
            "industry_category": "ACCOMMODATION",
            "country_of_operation": "PH",
            "date_of_registration": "2023-02-02T00:00:00.000Z"
        },
        "individual_details": {
                "email": "test@xendit.co",
                "gender": "MALE",
                "surname": "test",
                "given_names": "test",
                "nationality": "PH",
                "phone_number": "+63021234567",
                "date_of_birth": "2000-02-02T00:00:00.000Z",
                "place_of_birth": "PH",
                "type": "PIC",
                "role": "owner"
            },
        "address": {
            "city": "test1",
            "country": "PH",
            "district": "test",
            "postal_code": "1111",
            "street_line1": "test",
            "street_line2": "test",
            "sub_district": "test",
            "province_state": "test"
        },
        "kyc_documents": [
            {
                "type": "SEC_CERTIFICATE_REGISTRATION_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "ARTICLES_OF_INCORPORATION_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "NOTARIZED_SECRETARY_CERTIFICATE_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "LATEST_GIS_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "ACR_OR_IMMIGRANT_COR_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "SERVICE_AGREEMENT_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            }
        ],
        "website_url": "https://xendit.co",
        "phone_number": "+63281234567",
        "email": "test@xendit.co",
        "kyc": {
            "status": "NOT_VERIFIED"
        },
        "created": "2023-03-30T11:41:57.881Z",
        "updated": "2023-03-30T11:44:01.122Z"
    }

    Parameters

    Please note that the required object parameters differ for each country. Refer to this guide for the complete requirements. This list of parameters covers the Philippines.

    Parameter Type Description
    id
    required
    string Xendit-generated unique identifier for each Account Holder. You will need to store this ID in order to link it to an Account later

    business_detail
    required
    object An object containing the business detail of the Account Holder
    Individual detail child parameters >
    Parameter Description
    type
    required
    stringLegal entity type of the business
    Minimum length 1 character
    Allowed values: CORPORATION, LIMITED_COMPANY, INDIVIDUAL, SOLE_PROPRIETORSHIP, PARTNERSHIP, UNION, PMA, FOREIGN_INDIVIDUAL, FOREIGN_SEC, FOREIGN_NONSEC, NON_PROFIT, OTHER
    Default:CORPORATION
    legal_name
    required
    string Legal name of the business. This must match the documentation submitted
    Maximum length 255 characters
    Minimum length 1 character
    trading_name
    required
    string Trading or brand name of the business. This will be the name that appears to endpayer on payment page.
    Maximum length 255 characters
    Minimum length 1 character
    description
    required
    string Description of the business. Please specify what business model or goods and services that the business provide.
    Maximum length 1000 characters
    Minimum length 1 character
    industry_category
    required
    string Industry Category Code
    Refer to the list of accepted values here
    date_of_registration
    optional
    string Business registration date in YYYY-MM-DD
    country_of_operation
    optional
    string Country in which the business is operating at. Format ISO 3166-2 Country Code
    Maximum length 3 characters
    Minimum length 1 character
    can_accept_usd
    optional
    boolean Acceptable values =false, true. If contains true indicates that this business intends to accept USD as a currency in their payment method. This condition is required when they need to activate Cards capabilities in the Phillippines. Additional KYC documents might be required if they choose to accept USD currency. Please see more details here
    can_accept_recurring
    optional
    boolean Acceptable values =false, true. If contains true indicates that this business intends to accept recurring payments in their Cards payments. This condition is required when they need to activate Cards capabilities in the Phillippines. Additional KYC documents might be required if they choose to accept recurring payments. Please see more details here
    average_monthly_basket_size
    optional
    number projected average basket size that will be accepted by this business in PHP currency. This condition is required when they need to activate Cards capabilities in the Phillippines. Please see more details here
    projected_monthly_transaction_count
    optional
    number projected monthly transaction count that will be accepted by this business. This condition is required when they need to activate Cards capabilities. Please see more details here
    tax_identification_number
    optional
    number Tax Identification Number of this business. This condition is required when they need to activate Cards capabilities when they need USD or recurring capabilities. Please see more details here
    Example value: 000123456001
    individual_details
    required
    array[object] An object containing the individual details of the Account Holder. This could be the details of the business owner, director etc. You may submit multiple PIC (Person in Charge) for your business in this object.
    Individual detail child parameters
    Parameter Description
    given_names
    required
    stringPrimary or first name/s of the Account Holder
    Minimum length 1 character
    Maximum length 255 characters
    surname
    required
    string Last or family name of the Account Holder
    Maximum length 255 characters
    Minimum length 1 character
    Maximum length 255 characters
    phone_number
    required
    string Contact number of the Account Holder in E.164 format. This may also be a landline
    Maximum length 30 characters
    Minimum length 1 character
    email
    required
    string Email address of the Account Holder
    Maximum length 255 characters
    Minimum length 1 character
    nationality
    optional
    string Country code for customer's nationality (ISO 3166-2 Country Code)
    place_of_birth
    optional
    string City or other relevant location of the Account Holder's birth place
    date_of_birth
    optional
    string Date of birth of the customer in YYYY-MM-DD
    gender
    optional
    string Gender of the customer
    Allowed values: male female other
    tax_identification_number
    optional
    number Tax Identification Number of this individual. This condition is required when they need to activate Cards capabilities when they need USD or recurring capabilities. Please see more details here
    type
    optional
    enum Available values: PIC, Incorporator
    minimum 1 Incorporator and 1 PIC is required when they need to activate Cards capabilities. Whereas 1 PIC is required when they need to activate Gcash capabilities. Please see more details here
    role
    optional
    string This role specifies the role of the PIC or Incorporator for example it can be filled with Owner, director
    minimum 1 Incorporator and 1 PIC is required when they need to activate Cards capabilities. Whereas 1 PIC is required when they need to activate Gcash capabilities. Please see more details here
    address
    optional
    string Address of the incorporator. This is only required when they need to activate Cards with USD or recurring capabilities. Please see more details here
    Individual detail child parameters
    Parameter Description
    country
    required
    stringCountry of residence of the Incorporator Format ISO 3166-2 Country Code

    Minimum length 1 character

    Maximum length 30 characters
    district
    required
    string District of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    street_line1
    required
    string Line 1 of street address e.g street number and name

    Minimum length 1 character

    Maximum length 255 characters
    street_line2
    required
    string Line 2 of street address e.g building name and apartment number

    Minimum length 1 character

    Maximum length 255 characters
    city
    required
    string City, village or town of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    province_state
    required
    string Province, state or region of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    postal_code
    required
    string ZIP or Postal Code of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    address
    required
    object Object containing the business address of the respective Account Holder
    Individual detail child parameters
    Parameter Description
    country
    required
    stringCountry of residence of the Account Holder Format ISO 3166-2 Country Code

    Minimum length 1 character

    Maximum length 30 characters
    district
    required
    string District of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    sub_district
    required
    string Sub-district of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    street_line1
    required
    string Line 1 of street address e.g street number and name

    Minimum length 1 character

    Maximum length 255 characters
    street_line2
    required
    string Line 2 of street address e.g building name and apartment number

    Minimum length 1 character

    Maximum length 255 characters
    city
    required
    string City, village or town of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    province_state
    required
    string Province, state or region of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    postal_code
    required
    string ZIP or Postal Code of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    kyc_documents
    required
    object Object containing the any file type or documents required to be submitted by the account Account Holder (e.g National ID, Selfie etc.)
    Individual detail child parameters
    Parameter Description
    country
    required
    string Issuing country of the document with Format ISO 3166-2 Country Code

    Minimum length 1 character

    Maximum length 30 characters
    type
    required
    string The type of the legal or KYC requirements document

    Minimum length 1 character

    Maximum length 255 characters

    Refer to the list of Required KYC Documents for all countries here
    expires_at
    optional
    string Expiry date of the document if relevant. Format YYYY-MM-DD

    Minimum length 1 character

    Maximum length 255 characters
    file_id
    optional
    string File ID returned from Xendit

    Minimum length 1 character

    Maximum length 255 characters
    website_url
    required
    string Company website or social media website page URL

    Maximum length 255 characters
    Minimum length 1 character
    phone_number
    required
    string Contact number of the Account Holder in E.164 format. This may also be a landline

    Maximum length 30 characters
    Minimum length 1 character
    email
    required
    string Email address of the Account Holder

    Maximum length 255 characters
    Minimum length 1 character
    kyc
    required
    array[object] An object containing the details of the Account Holder KYC verification process
    Individual detail child parameters
    Parameter Description
    status
    required
    string Status of the Account Holder KYC verification
    Allowed values: NOT_VERIFIED PASSED VERIFICATION_IN_PROGRESS RESUBMISSION_REQUIRED FAILED
    kyc_passed_at
    required
    string Timestamp of Account Holder KYC passed in ISO format
    verified_at
    required
    string Timestamp of the Account Holder verification in ISO format
    requested_at
    required
    string Timestamp of the Account Holder KYC verification requested date in ISO format. This is the timestamp when you link your account holder to an Account.
    failure_reasons
    optional
    array[object] An array of objects containing the failure reasons of this Account Holder KYC verification
    Individual detail child parameters
    Parameter Description
    field
    optional
    string Reasons on why this Account Holder KYC verification failed
    message
    optional
    string Contains the detailed message on what the failure entails and next steps (e.g resubmitting the documents etc.)
    capabilities
    optional
    array[object] An object containing the details of the Account Holder capabilities activation process
    Individual detail child parameters
    Parameter Description
    type
    optional
    string Type of the capability requested for the Account Holder
    Allowed values: MONEY_IN
    channel_code
    optional
    string Channel code (conditional for money_in capabilities type)
    Allowed values: GCASH, CARDS
    activated_at
    optional
    string Timestamp of the Account Holder capabilities activation in ISO format
    verified_at
    required
    string Timestamp of the Account Holder capabilities verification in ISO format
    requested_at
    required
    string Timestamp of the Account Holder capabilities verification requested date in ISO format.
    status
    required
    string Activation status of the payment channel or capability requested in Account Holder
    Allowed values: LIVE RESUBMISSION_REQUIRED DECLINED VERIFICATION_IN_PROGRESS
    failure_reason
    optional
    string Message containing reason for failure. This will only be specificed if capability status is RESUBMISSION_REQUIRED

    Create Account Holder

    An Account Holder represents the legal entity that holds the Xendit Account that is created in your Platform. In order to onboard an account, you need to complete the 2 following steps:

    1. Create Account
    2. Create Account Holder

    The details that you need to provide in the request depend on the Account holders' legal entity type. Please refer to our documentation for full requirements

    Endpoint: Create Account Holder

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

    Request Parameters

    Please note that the required object parameters differ for each country. Refer to this guide for the complete requirements. This list of parameters covers the Philippines.

    Example Create Account Holder Request

    curl https://api.xendit.co/account_holders -X POST \
    -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
    --data-raw '{
      "business_detail": {
        "type": "INDIVIDUAL",
        "legal_name": "test17",
        "trading_name": "test",
        "description": "testing",
        "industry_category": "ACCOMMODATION",
        "date_of_registration": "2023-02-02",
        "country_of_operation":"PH"
      },
      "individual_details": [{
          "given_names": "test",
          "surname": "test",
          "phone_number": "+63021234567",
          "email": "test@xendit.co",
          "nationality": "PH",
          "place_of_birth": "PH",
          "date_of_birth": "2000-02-02",
          "gender": "MALE"
          "type": "PIC",
          "role": "owner"
        }],
       "address": {
            "city": "test1",
            "country": "PH",
            "district": "test",
            "postal_code": "1111",
            "street_line1": "test",
            "street_line2": "test",
            "sub_district": "test",
            "province_state": "test"
        },
      "kyc_documents": [
            {
                "type": "SELFIE_WITH_PRIMARY_ID_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2"
            },
            {
                "type": "ACR_OR_IMMIGRANT_COR_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2"
            },
            {
                "type": "SERVICE_AGREEMENT_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2"
            }
        ],
      "website_url": "https://xendit.co",
      "phone_number": "+63281234567",
      "email": "test@xendit.co"
    }'

    Example of Create Account Holder Request for Corporation entity type in the Phillippines

    {
        "business_detail": {
            "type": "CORPORATION",
            "legal_name": "test17",
            "trading_name": "test",
            "description": "testing",
            "industry_category": "ACCOMMODATION",
            "date_of_registration": "2023-02-02",
            "country_of_operation":"PH"
       },
       "individual_details": [{
          "given_names": "test",
          "surname": "test",
          "phone_number": "+63021234567",
          "email": "test@xendit.co",
          "nationality": "PH",
          "place_of_birth": "PH",
          "date_of_birth": "2000-02-02",
          "gender": "MALE",
          "type": "PIC",
          "role": "owner"
        }],
        "address": {
            "city": "test1",
            "country": "PH",
            "district": "test",
            "postal_code": "1111",
            "street_line1": "test",
            "street_line2": "test",
            "sub_district": "test",
            "province_state": "test"
        },
       "kyc_documents": [
            {
                "type": "SEC_CERTIFICATE_REGISTRATION_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
            },
            {
                "type": "ARTICLES_OF_INCORPORATION_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2"
            },
            {
                "type": "NOTARIZED_SECRETARY_CERTIFICATE_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2"
            },
            {
                "type": "LATEST_GIS_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2"
            },
            {
                "type": "ACR_OR_IMMIGRANT_COR_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2"
            },
            {
                "type": "SERVICE_AGREEMENT_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2"
            }
        ],
        "website_url": "https://xendit.co",
        "phone_number": "+63281234567",
        "email": "test@xendit.co"
    }

    Example of Create Account Holder Request for Corporation entity type in Indonesia

    {
       "business_detail": {
            "type": "CORPORATION",
            "legal_name": "test17",
            "trading_name": "test",
            "description": "testing",
            "industry_category": "EDUTECH",
            "tax_identification_number": "1234567891345678",
            "business_identification_number": "1234567",
            "initial_deed_of_establishment_status": "UNCHANGED",
            "country_of_operation": "ID"
        },
        "individual_details": [{
          "role": "owner",
          "given_names": "Adrian",
          "surname": "Fauzi",
          "phone_number": "+6281234567",
          "email": "test@xendit.co",
          "passport_number": "ABC12345",
          "ktp_number": "1234567891345678"
        }],
        "address": {
            "city": "test1",
            "country": "ID",
            "district": "test",
            "postal_code": "1111",
            "street_line1": "test",
            "street_line2": "test",
            "sub_district": "test",
            "province_state": "test"
        },
        "kyc_documents": [
            {
                "type": "AUTHORIZED_PERSON_KTP_DOCUMENT",
                "country": "ID",
                "file_id": "63f8719642f5856dcb142bd2",
            },
            {
                "type": "SELFIE_WITH_KTP_DOCUMENT",
                "country": "ID",
                "file_id": "63f8719642f5856dcb142bd2"
            },
            {
                "type": "NIB_DOCUMENT",
                "country": "ID",
                "file_id": "63f8719642f5856dcb142bd2"
            },
            {
                "type": "DEED_OF_COMPANY_ESTABLISHMENT_DOCUMENT",
                "country": "ID",
                "file_id": "63f8719642f5856dcb142bd2"
            },
            {
                "type": "CORPORATE_TAX_ID_DOCUMENT",
                "country": "ID",
                "file_id": "63f8719642f5856dcb142bd2"
            },
            {
                "type": "SERVICE_AGREEMENT_DOCUMENT",
                "country": "ID",
                "file_id": "63f8719642f5856dcb142bd2"
            }
        ],
        "website_url": "https://xendit.co",
        "phone_number": "+6281234567",
        "email": "test@xendit.co"
    }
    Parameter Type Description
    business_detail
    required
    object An object containing the business detail of the Account Holder
    Child parameters
    Parameter Description
    type
    required
    stringLegal entity type of the business
    Minimum length 1 character
    Allowed values: CORPORATION, LIMITED_COMPANY, INDIVIDUAL, SOLE_PROPRIETORSHIP, PARTNERSHIP, UNION, PMA, FOREIGN_INDIVIDUAL, FOREIGN_SEC, FOREIGN_NONSEC, NON_PROFIT, OTHER
    Default:CORPORATION
    legal_name
    required
    string Legal name of the business. This must match the documentation submitted
    Maximum length 255 characters
    Minimum length 1 character
    trading_name
    required
    string Trading or brand name of the business. This will be the name that appears to endpayer on payment page.
    Maximum length 255 characters
    Minimum length 1 character
    description
    required
    string Description of the business. Please specify what business model or goods and services that the business provide.
    Maximum length 1000 characters
    Minimum length 1 character
    industry_category
    required
    string Industry Category Code
    Refer to the list of accepted values here
    date_of_registration
    optional
    string Business registration date in YYYY-MM-DD
    country_of_operation
    optional
    string Country in which the business is operating at. Format ISO 3166-2 Country Code
    Maximum length 3 characters
    Minimum length 1 character
    individual_details
    required
    array[object] An object containing the individual details of the Account Holder. This could be the details of the business owner, director etc. You may submit multiple PIC (Person in Charge) for your business in this object.
    Child parameters
    Parameter Description
    given_names
    required
    stringPrimary or first name/s of the Account Holder
    Minimum length 1 character
    Maximum length 255 characters
    surname
    required
    string Last or family name of the Account Holder
    Maximum length 255 characters
    Minimum length 1 character
    Maximum length 255 characters
    phone_number
    required
    string Contact number of the Account Holder in E.164 format. This may also be a landline
    Maximum length 30 characters
    Minimum length 1 character
    email
    required
    string Email address of the Account Holder
    Maximum length 255 characters
    Minimum length 1 character
    nationality
    optional
    string Country code for customer's nationality (ISO 3166-2 Country Code)
    place_of_birth
    optional
    string City or other relevant location of the Account Holder's birth place
    date_of_birth
    optional
    string Date of birth of the customer in YYYY-MM-DD
    gender
    optional
    string Gender of the customer
    Allowed values: male female other
    tax_identification_number
    optional
    string Tax Identification Number of this individual. This condition is required when they need to activate Cards capabilities when they need USD or recurring capabilities. Please see more details here
    type
    optional
    enum Available values: PIC, Incorporator
    minimum 1 Incorporator and 1 PIC is required when they need to activate Cards capabilities. Whereas 1 PIC is required when they need to activate Gcash capabilities. Please see more details here
    role
    optional
    string This role specifies the role of the PIC or Incorporator for example it can be filled with Owner, director
    minimum 1 Incorporator and 1 PIC is required when they need to activate Cards capabilities. Whereas 1 PIC is required when they need to activate Gcash capabilities. Please see more details here
    address
    optional
    string Address of the incorporator. This is only required when they need to activate Cards with USD or recurring capabilities. Please see more details here
    Child parameters
    Parameter Description
    country
    required
    stringCountry of residence of the Incorporator Format ISO 3166-2 Country Code

    Minimum length 1 character

    Maximum length 30 characters
    district
    required
    string District of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    street_line1
    required
    string Line 1 of street address e.g street number and name

    Minimum length 1 character

    Maximum length 255 characters
    street_line2
    required
    string Line 2 of street address e.g building name and apartment number

    Minimum length 1 character

    Maximum length 255 characters
    city
    required
    string City, village or town of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    province_state
    required
    string Province, state or region of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    postal_code
    required
    string ZIP or Postal Code of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    address
    required
    object Object containing the business address of the respective Account Holder
    Child parameters
    Parameter Description
    country
    required
    stringCountry of residence of the Account Holder Format ISO 3166-2 Country Code

    Minimum length 1 character

    Maximum length 30 characters
    district
    required
    string District of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    sub_district
    required
    string Sub-district of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    street_line1
    required
    string Line 1 of street address e.g street number and name

    Minimum length 1 character

    Maximum length 255 characters
    street_line2
    required
    string Line 2 of street address e.g building name and apartment number

    Minimum length 1 character

    Maximum length 255 characters
    city
    required
    string City, village or town of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    province_state
    required
    string Province, state or region of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    postal_code
    required
    string ZIP or Postal Code of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    kyc_documents
    required
    object Object containing the any file type or documents required to be submitted by the account Account Holder (e.g National ID, Selfie etc.)
    Child parameters
    Parameter Description
    country
    required
    string Issuing country of the document with Format ISO 3166-2 Country Code

    Minimum length 1 character

    Maximum length 30 characters
    type
    required
    string The type of the legal or KYC requirements document

    Minimum length 1 character

    Maximum length 255 characters

    Refer to the list of Required KYC Documents for all countries here
    expires_at
    optional
    string Expiry date of the document if relevant. Format YYYY-MM-DD

    Minimum length 1 character

    Maximum length 255 characters
    file_id
    optional
    string File ID returned from Xendit

    Minimum length 1 character

    Maximum length 255 characters
    website_url
    required
    string Company website or social media website page URL

    Maximum length 255 characters
    Minimum length 1 character
    phone_number
    required
    string Contact number of the Account Holder in E.164 format. This may also be a landline

    Maximum length 30 characters
    Minimum length 1 character
    email
    required
    string Email address of the Account Holder

    Maximum length 255 characters
    Minimum length 1 character

    Response Parameters

    Example: Create Account Holder Response

    {
        "id": "4376b7b0-1c44-46be-8640-828f79cdc8be",
        "business_detail": {
            "type": "CORPORATION",
            "legal_name": "test16",
            "description": "testing",
            "trading_name": "test",
            "industry_category": "ACCOMMODATION",
            "country_of_operation": "PH",
            "date_of_registration": "2023-02-02T00:00:00.000Z"
        },
        "individual_details": {
                "email": "test@xendit.co",
                "gender": "MALE",
                "surname": "test",
                "given_names": "test",
                "nationality": "PH",
                "phone_number": "+63021234567",
                "date_of_birth": "2000-02-02T00:00:00.000Z",
                "place_of_birth": "PH"
                "type": "PIC",
                "role": "owner"
            },
            "address": {
            "city": "test1",
            "country": "PH",
            "district": "test",
            "postal_code": "1111",
            "street_line1": "test",
            "street_line2": "test",
            "sub_district": "test",
            "province_state": "test"
        },
        "kyc_documents": [
            {
                "type": "SEC_CERTIFICATE_REGISTRATION_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "ARTICLES_OF_INCORPORATION_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "NOTARIZED_SECRETARY_CERTIFICATE_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "LATEST_GIS_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "ACR_OR_IMMIGRANT_COR_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "SERVICE_AGREEMENT_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            }
        ],
        "website_url": "https://xendit.co",
        "phone_number": "+63281234567",
        "email": "test@xendit.co",
        "kyc": {
            "status": "NOT_VERIFIED"
        },
        "created_at": "2023-03-30T11:41:57.881Z",
        "updated_at": "2023-03-30T11:44:01.122Z"
    }

    Returns Account Holder object with status 200

    Error Codes

    Error Code Error Message
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request. You need to use the Platform API key with Account Holder write access.
    FEATURE_NOT_ACTIVATED
    403
    This feature has not been activated for your account. Please reach out to help@xendit.co
    INVALID_API_KEY
    401
    API key format is invalid
    SERVER_ERROR
    500
    Something unexpected, our devs have been notified to troubleshoot the issue

    Linking Account Holder

    Use the Update Account endpoint to link an Account Holder ID to this Account. This operation is currently only enabled for OWNED accounts.

    Endpoint: Update Account

    PATCH https://api.xendit.co/v2/accounts/{id}

    Example: Update Account

    curl https://api.xendit.co/v2/accounts/{id} -X PATCH \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -H 'Content-Type: application/json' \
       -d $'{"account_holder_id":"4376b7b0-1c44-46be-8640-828f79cdc8be"}'
      <?php
          $url = 'https://api.xendit.co/v2/accounts/{id}';
          $apiKey = 'xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==';
          $headers = [];
          $headers[] = 'Content-Type: application/json';
          $data = [
              'acccount_holder_id' => '4376b7b0-1c44-46be-8640-828f79cdc8be'
              ]
          ];
          $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, 'PATCH');
          curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
          curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
          $result = curl_exec($curl);
          echo $result;

    Path Parameters

    Parameter Type Description
    id
    required
    string The id of the Account created

    Body Parameters

    Parameter Type Description
    account_holder_id
    required
    string An Account Holder represents the legal entity that holds the Xendit Account.

    Response Parameters

    Example: Update Account Response

    {
      "id": "5cafeb170a2b18519b1b8761",
      "created": "2021-01-01T10:00:00Z",
      "updated": "2021-01-01T11:00:00Z",
      "type": "OWNED",
      "email": "angie@pinkpanther.com",
      "public_profile": {
        "business_name": "Angie lemonade stand"
      },
      "status": "LIVE"
      "account_holder_id": "4376b7b0-1c44-46be-8640-828f79cdc8be"
    }
    Parameter Type Description
    id
    required
    string ID of your Account, use this in the for-user-id header to create transactions on behalf of your Account
    created
    required
    string Timestamp of when the account was created

    Timezone: GMT+0
    updated
    required
    string Timestamp of when the account was updated

    Timezone: GMT+0
    type
    required
    string The type of account created

    Available values: MANAGED, OWNED
    email
    required
    string Email identifier for the Account
    public_profile
    required
    object Contains information that will be seen by end-payers or end-recipients (e.g. appears on hosted checkout page, credit card statements, etc.).
    country
    required
    string The country (based on ISO 3166-1 Alpha-2) of incorporation for a business, or the country of residence for an individual.
    Available values: ID, PH


    Default value: Your country of operation
    status
    required
    string Status of the Account you are creating.

    Available values: INVITED, REGISTERED, AWAITING_DOCS, LIVE

    Learn what these statuses mean in our documentation
    account_holder_id
    required
    string Xendit-generated unique identifier for each Account Holder. This is created using the Create Account Holder Endpoint

    Activate Account Holder Capabilities

    Use the Update Account Holder endpoint to link an Activate Account Holder Capabilities. This operation is currently only enabled for OWNED accounts.

    Endpoint: Update Account

    PATCH https://api.xendit.co/account_holders

    Example: Update Account

    curl https://api.xendit.co/account_holder -X PATCH \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -H 'Content-Type: application/json' \
       -d $'{"capabilities":{"type":"MONEY_IN", "channel_code":"GCASH"}}'
      <?php
          $url = 'https://api.xendit.co/account_holders';
          $apiKey = 'xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==';
          $headers = [];
          $headers[] = 'Content-Type: application/json';
          $data = [
              'capabilities' => [
                'type' => 'MONEY_IN'
                'channel_code' => 'GCASH'
              ]
          ];
          $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, 'PATCH');
          curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
          curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
          $result = curl_exec($curl);
          echo $result;

    Path Parameters

    Parameter Type Description
    id
    required
    string The id of the Account Holder created

    Body Parameters

    Parameter Type Description
    business_detail
    optional
    object An object containing the business detail of the Account Holder
    Individual detail child parameters
    Parameter Description
    can_accept_usd
    optional
    boolean Acceptable values =false, true. If contains true indicates that this business intends to accept USD as a currency in their payment method. This condition is required when they need to activate Cards capabilities in the Phillippines. Additional KYC documents might be required if they choose to accept USD currency. Please see more details here
    can_accept_recurring
    optional
    boolean Acceptable values =false, true. If contains true indicates that this business intends to accept recurring payments in their Cards payments. This condition is required when they need to activate Cards capabilities in the Phillippines. Additional KYC documents might be required if they choose to accept recurring payments. Please see more details here
    average_monthly_basket_size
    optional
    number projected average basket size that will be accepted by this business in PHP currency. This condition is required when they need to activate Cards capabilities in the Phillippines. Please see more details here
    projected_monthly_transaction_count
    optional
    number projected monthly transaction count that will be accepted by this business. This condition is required when they need to activate Cards capabilities. Please see more details here
    tax_identification_number
    optional
    number Tax Identification Number of this business.
    Example value: 000123456001. Please see more details here
    individual_details
    optional
    array[object] An object containing the individual details of the Account Holder. This could be the details of the business owner, director etc. You may submit multiple PIC (Person in Charge) for your business in this object.
    Individual detail child parameters
    Parameter Description
    given_names
    required
    stringPrimary or first name/s of the Account Holder
    Minimum length 1 character
    Maximum length 255 characters
    surname
    required
    string Last or family name of the Account Holder
    Maximum length 255 characters
    Minimum length 1 character
    Maximum length 255 characters
    phone_number
    required
    string Contact number of the Account Holder in E.164 format. This may also be a landline
    Maximum length 30 characters
    Minimum length 1 character
    email
    required
    string Email address of the Account Holder
    Maximum length 255 characters
    Minimum length 1 character
    nationality
    optional
    string Country code for customer's nationality (ISO 3166-2 Country Code)
    place_of_birth
    optional
    string City or other relevant location of the Account Holder's birth place
    date_of_birth
    optional
    string Date of birth of the customer in YYYY-MM-DD
    gender
    optional
    string Gender of the customer
    Allowed values: male female other
    tax_identification_number
    optional
    string Tax Identification Number of this individual.
    Example value: 000123456001.
    type
    optional
    enum Available values: PIC, Incorporator
    minimum 1 Incorporator and 1 PIC is required when they need to activate Cards capabilities. Whereas 1 PIC is required when they need to activate Gcash capabilities. Please see more details here
    role
    optional
    string This role specifies the role of the PIC or Incorporator for example it can be filled with Owner, director
    minimum 1 Incorporator and 1 PIC is required when they need to activate Cards capabilities. Whereas 1 PIC is required when they need to activate Gcash capabilities. Please see more details here
    address
    optional
    string Address of the incorporator. This is only required when they need to activate Cards with USD or recurring capabilities. Please see more details here
    Individual detail child parameters
    Parameter Description
    country
    required
    stringCountry of residence of the Incorporator Format ISO 3166-2 Country Code

    Minimum length 1 character

    Maximum length 30 characters
    district
    required
    string District of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    street_line1
    required
    string Line 1 of street address e.g street number and name

    Minimum length 1 character

    Maximum length 255 characters
    street_line2
    required
    string Line 2 of street address e.g building name and apartment number

    Minimum length 1 character

    Maximum length 255 characters
    city
    required
    string City, village or town of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    province_state
    required
    string Province, state or region of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    postal_code
    required
    string ZIP or Postal Code of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    capabilities
    optional
    object An object containing the details of the Account Holder capabilities activation process
    Individual detail child parameters
    Parameter Description
    type
    optional
    string Type of the capability requested for the Account Holder
    Allowed values: MONEY_IN
    channel_code
    optional
    string Channel code (conditional for money_in capabilities type)
    Allowed values: GCASH ,PH_CARDS
    kyc_documents
    optional
    object Object containing the any file type or documents required to be submitted by the account Account Holder (e.g National ID, Selfie etc.)
    Individual detail child parameters
    Parameter Description
    country
    required
    string Issuing country of the document with Format ISO 3166-2 Country Code

    Minimum length 1 character

    Maximum length 30 characters
    type
    required
    string The type of the legal or KYC requirements document

    Minimum length 1 character

    Maximum length 255 characters

    Refer to the list of required KYC documents for all countries here
    expires_at
    optional
    string Expiry date of the document if relevant. Format YYYY-MM-DD

    Minimum length 1 character

    Maximum length 255 characters
    file_id
    optional
    string File ID returned from Xendit

    Minimum length 1 character

    Maximum length 255 characters

    Response Parameters

    Example: Update Account Holder with Gcash capabilities response

    {
      "id": "5fa9014f44dee8737b1f05a4",
      "business_detail": {
        "type": "CORPORATION",
        "legal_name": "PT Xendit",
        "trading_name": "Xendit",
        "description": "Payment solutions provider",
        "industry_category": "Fintech",
        "date_of_registration": "1980-01-01"
      },
      "individual_details": [
        {
          "given_names": "Putri",
          "surname": "Mitja",
          "nationality": "PH",
          "phone_number": "+6385368541234",
          "email": "sample@email.com",
          "place_of_birth": "Makati",
          "date_of_birth": "1980-01-01",
          "gender": "MALE"
        },
        {
          "given_names": "Putri 2",
          "surname": "Mitja 2",
          "nationality": "PH",
          "phone_number": "+6385368541234",
          "email": "sample@email.com",
          "place_of_birth": "Makati",
          "date_of_birth": "1980-01-01",
          "gender": "MALE"
        }
      ],
      "address": {
        "country": "PH",
        "street_line1": "M.L. Quezon St.",
        "street_line2": "M.L. Quezon St.",
        "city": "Bantigue",
        "sub_district": null,
        "district": null,
        "province_state": "Bantayan",
        "postal_code": 2129
      },
      "kyc_documents": [
        {
          "country": "PH",
          "type": "SELFIE_WITH_PRIMARY_ID",
          "file_id": "file-ec700c1c-db17-4496-b1fb-04ebe551b412"
        },
        {
          "country": "PH",
          "type": "IDENTITY_CARD",
          "file_id": "file-ec700c1c-db17-4496-b1fb-04ebe551b412"
        },
        {
          "country": "PH",
          "type": "DTI_REGISTRATION",
          "file_id": "file-ec700c1c-db17-4496-b1fb-04ebe551b412"
        },
        {
          "country": "PH",
          "type": "SEC_REGISTRATION",
          "file_id": "file-ec700c1c-db17-4496-b1fb-04ebe551b412"
        },
        {
          "country": "PH",
          "type": "ARTICLE_OF_INCORPORATION",
          "file_id": "file-ec700c1c-db17-4496-b1fb-04ebe551b412"
        },
        {
          "country": "PH",
          "type": "GENERAL_INFORMATION_SHEET",
          "file_id": "file-ec700c1c-db17-4496-b1fb-04ebe551b412"
        },
        {
          "country": "PH",
          "type": "NOTARIZED_SECRETARY_CERTIFICATION",
          "file_id": "file-ec700c1c-db17-4496-b1fb-04ebe551b412"
        },
        {
          "country": "PH",
          "type": "SECONDARY_LICENSE",
          "file_id": "file-ec700c1c-db17-4496-b1fb-04ebe551b412"
        }
      ],
      "website_url": "https://api.xendit.co",
      "phone_number": "+6385368541234",
      "email": "account_holder@platform.com",
      "kyc": {
        "status": "PASSED",
        "kyc_passed_at": "2021-01-01T10:00:00Z",
        "verified_at": "2021-01-01T10:00:00Z",
        "requested_at": "2021-01-01T10:00:00Z"
      },
      "capabilities": [
        {
          "type": "MONEY_IN",
          "channel_code": "GCASH",
          "activated_at": "2021-01-01T10:00:00Z",
          "verified_at": "2021-01-01T10:00:00Z",
          "requested_at": "2021-01-01T10:00:00Z",
          "status": "VERIFICATION_IN_PROGRESS",
        }
      ]
    }

    Returns Account Holder object with status 200

    Error Codes

    Error Code Error Message
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    INSUFFICIENT_ACCOUNT_HOLDER_DATA
    400
    The information in the Account Holder object is not sufficient to request activation for this payment channel. Please update the fields with the correct information.
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request. You need to use the Platform API key with Account Holder write access.
    FEATURE_NOT_ACTIVATED
    403
    This feature has not been activated for your account. Please reach out to help@xendit.co
    KYC_VERIFICATION_IN_PROGRESS
    403
    Account Holder cannot be updated while KYC verification is in progress, please try again when the verification process has been completed.
    CHANNEL_HAS_BEEN_ACTIVATED
    403
    Payment channel has been activated for this account holder.
    CHANNEL_ACTIVATION_IN_PROGRESS
    403
    Payment channel activation is in progress for this account holder.
    KYC_VERIFICATION_REQUIRED
    403
    Accounts KYC verification has not been completed for this sub-account. Please request capabilities after this process has been completed.
    INVALID_API_KEY
    401
    API key format is invalid
    DATA_NOT_FOUND
    500
    Could not find Account Holder by the ID specified because ID may be invalid.

    Get Account Holder by ID

    Endpoint: Get Account Holder by ID

    GET https://api.xendit.co/account_holders/{id}

    This endpoint retrieves a single Account Holder that was previously created. This is often used for checking the verification status of a Account Holder using the id from the Account Holder Object.

    Request Parameters

    Example Get Account Holder Request

    curl https://api.xendit.co/account_holders/4376b7b0-1c44-46be-8640-828f79cdc8be -X GET \
      -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
    Path Parameter Type Description
    id
    required
    string Xendit Account Holder ID generated by POST /account_holders

    Response Parameters

    Example Get Account Holder Response

    {
        "id": "4376b7b0-1c44-46be-8640-828f79cdc8be",
        "business_detail": {
            "type": "CORPORATION",
            "legal_name": "test16",
            "description": "testing",
            "trading_name": "test",
            "industry_category": "ACCOMMODATION",
            "country_of_operation": "PH",
            "date_of_registration": "2023-02-02T00:00:00.000Z"
        },
        "individual_details": [
            {
                "email": "test@xendit.co",
                "gender": "MALE",
                "surname": "test",
                "given_names": "test",
                "nationality": "PH",
                "phone_number": "+63021234567",
                "date_of_birth": "2000-02-02T00:00:00.000Z",
                "place_of_birth": "PH"
            },
            {
                "email": "test@xendit.co",
                "gender": "MALE",
                "surname": "test",
                "given_names": "test",
                "nationality": "PH",
                "phone_number": "+63021234567",
                "date_of_birth": "2000-02-02T00:00:00.000Z",
                "place_of_birth": "PH"
            }
        ],
        "address": {
            "city": "test1",
            "country": "PH",
            "district": "test",
            "postal_code": "1111",
            "street_line1": "test",
            "street_line2": "test",
            "sub_district": "test",
            "province_state": "test"
        },
        "kyc_documents": [
            {
                "type": "SEC_CERTIFICATE_REGISTRATION_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "ARTICLES_OF_INCORPORATION_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "NOTARIZED_SECRETARY_CERTIFICATE_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "LATEST_GIS_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "ACR_OR_IMMIGRANT_COR_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "ADDITIONAL_PROOF_OF_BUSINESS_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            }
        ],
        "website_url": "https://xendit.co",
        "phone_number": "+63281234567",
        "email": "test@xendit.co",
        "kyc": {
            "status": "NOT_VERIFIED"
        },
        "created": "2023-03-30T11:41:57.881Z",
        "updated": "2023-03-30T11:44:01.122Z"
    }

    Returns Account Holder object with status 200

    Error Codes

    Error Code Error Message
    REQUEST_FORBIDDEN_ERROR
    403
    API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key.
    DATA_NOT_FOUND
    404
    Could not find payout with the corresponding ID. Please try again with a valid ID.
    INVALID_API_KEY
    401
    API Key is invalid.

    Update Account Holder

    Use the Update Account Holder endpoint to update your Account Holder information. This step may be needed when the your information and document submission is insufficient or invalid e.g invalid website, blurry selfie, invalid ID etc. This operation is currently only enabled for OWNED accounts.

    Endpoint: Update Account Holder

    PATCH https://api.xendit.co/account_holders/{id}

    Example: Update Account

    curl https://api.xendit.co/account_holders/{id} -X PATCH \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -H 'Content-Type: application/json' \
       -d $'{"website_url": "louisa-marketplace.xendit.com"}'

    Path Parameters

    Path Parameter Type Description
    id
    required
    string The id of the Account created

    Request Parameters

    Parameter Type Description
    business_detail
    required
    object An object containing the business detail of the Account Holder
    Individual detail child parameters
    Parameter Description
    type
    required
    stringLegal entity type of the business
    Minimum length 1 character
    Allowed values: CORPORATION, LIMITED_COMPANY, INDIVIDUAL, SOLE_PROPRIETORSHIP, PARTNERSHIP, UNION, PMA, FOREIGN_INDIVIDUAL, FOREIGN_SEC, FOREIGN_NONSEC, NON_PROFIT, OTHER
    Default:CORPORATION
    legal_name
    required
    string Legal name of the business. This must match the documentation submitted
    Maximum length 255 characters
    Minimum length 1 character
    trading_name
    required
    string Trading or brand name of the business. This will be the name that appears to endpayer on payment page.
    Maximum length 255 characters
    Minimum length 1 character
    description
    required
    string Description of the business. Please specify what business model or goods and services that the business provide.
    Maximum length 1000 characters
    Minimum length 1 character
    industry_category
    required
    string Industry Category Code
    Refer to the list of accepted values here
    date_of_registration
    optional
    string Business registration date in YYYY-MM-DD
    country_of_operation
    optional
    string Country in which the business is operating at. Format ISO 3166-2 Country Code
    Maximum length 3 characters
    Minimum length 1 character
    can_accept_usd
    optional
    boolean Acceptable values =false, true. If contains true indicates that this business intends to accept USD as a currency in their payment method. This condition is required when they need to activate Cards capabilities in the Phillippines. Additional KYC documents might be required if they choose to accept USD currency. Please see more details here
    can_accept_recurring
    optional
    boolean Acceptable values =false, true. If contains true indicates that this business intends to accept recurring payments in their Cards payments. This condition is required when they need to activate Cards capabilities in the Phillippines. Additional KYC documents might be required if they choose to accept recurring payments. Please see more details here
    average_monthly_basket_size
    optional
    number projected average basket size that will be accepted by this business in PHP currency. This condition is required when they need to activate Cards capabilities in the Phillippines. Please see more details here
    projected_monthly_transaction_count
    optional
    number projected monthly transaction count that will be accepted by this business. This condition is required when they need to activate Cards capabilities. Please see more details here
    tax_identification_number
    optional
    number Tax Identification Number of this business. This condition is required when they need to activate Cards capabilities with USD acceptance.
    Example value: 000123456001. Please see more details here
    individual_details
    required
    array[object] An object containing the individual details of the Account Holder. This could be the details of the business owner, director etc. You may submit multiple PIC (Person in Charge) for your business in this object.
    Individual detail child parameters
    Parameter Description
    given_names
    required
    stringPrimary or first name/s of the Account Holder
    Minimum length 1 character
    Maximum length 255 characters
    surname
    required
    string Last or family name of the Account Holder
    Maximum length 255 characters
    Minimum length 1 character
    Maximum length 255 characters
    phone_number
    required
    string Contact number of the Account Holder in E.164 format. This may also be a landline
    Maximum length 30 characters
    Minimum length 1 character
    email
    required
    string Email address of the Account Holder
    Maximum length 255 characters
    Minimum length 1 character
    nationality
    optional
    string Country code for customer's nationality (ISO 3166-2 Country Code)
    place_of_birth
    optional
    string City or other relevant location of the Account Holder's birth place
    date_of_birth
    optional
    string Date of birth of the customer in YYYY-MM-DD
    gender
    optional
    string Gender of the customer
    Allowed values: male female other
    tax_identification_number
    optional
    string Tax Identification Number of this individual. This condition is required when they need to activate Cards capabilities when they need USD or recurring capabilities. Please see more details here
    type
    optional
    enum Available values: PIC, Incorporator
    minimum 1 Incorporator and 1 PIC is required when they need to activate Cards capabilities. Whereas 1 PIC is required when they need to activate Gcash capabilities. Please see more details here
    role
    optional
    string This role specifies the role of the PIC or Incorporator for example it can be filled with Owner, director
    minimum 1 Incorporator and 1 PIC is required when they need to activate Cards capabilities. Whereas 1 PIC is required when they need to activate Gcash capabilities. Please see more details here
    address
    optional
    string Address of the incorporator. This is only required when they need to activate Cards with USD or recurring capabilities. Please see more details here
    Individual detail child parameters
    Parameter Description
    country
    required
    stringCountry of residence of the Incorporator Format ISO 3166-2 Country Code

    Minimum length 1 character

    Maximum length 30 characters
    district
    required
    string District of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    street_line1
    required
    string Line 1 of street address e.g street number and name

    Minimum length 1 character

    Maximum length 255 characters
    street_line2
    required
    string Line 2 of street address e.g building name and apartment number

    Minimum length 1 character

    Maximum length 255 characters
    city
    required
    string City, village or town of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    province_state
    required
    string Province, state or region of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    postal_code
    required
    string ZIP or Postal Code of the Incorporator

    Minimum length 1 character

    Maximum length 255 characters
    address
    required
    object Object containing the business address of the respective Account Holder
    Individual detail child parameters
    Parameter Description
    country
    required
    stringCountry of residence of the Account Holder Format ISO 3166-2 Country Code

    Minimum length 1 character

    Maximum length 30 characters
    district
    required
    string District of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    sub_district
    required
    string Sub-district of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    street_line1
    required
    string Line 1 of street address e.g street number and name

    Minimum length 1 character

    Maximum length 255 characters
    street_line2
    required
    string Line 2 of street address e.g building name and apartment number

    Minimum length 1 character

    Maximum length 255 characters
    city
    required
    string City, village or town of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    province_state
    required
    string Province, state or region of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    postal_code
    required
    string ZIP or Postal Code of the Account Holder

    Minimum length 1 character

    Maximum length 255 characters
    kyc_documents
    required
    object Object containing the any file type or documents required to be submitted by the account Account Holder (e.g National ID, Selfie etc.)
    Individual detail child parameters
    Parameter Description
    country
    required
    string Issuing country of the document with Format ISO 3166-2 Country Code

    Minimum length 1 character

    Maximum length 30 characters
    type
    required
    string The type of the legal or KYC requirements document

    Minimum length 1 character

    Maximum length 255 characters

    Refer to the list of Required KYC Documents for all countries here
    expires_at
    optional
    string Expiry date of the document if relevant. Format YYYY-MM-DD

    Minimum length 1 character

    Maximum length 255 characters
    file_id
    optional
    string File ID returned from Xendit

    Minimum length 1 character

    Maximum length 255 characters
    website_url
    required
    string Company website or social media website page URL

    Maximum length 255 characters
    Minimum length 1 character
    phone_number
    required
    string Contact number of the Account Holder in E.164 format. This may also be a landline

    Maximum length 30 characters
    Minimum length 1 character
    email
    required
    string Email address of the Account Holder

    Maximum length 255 characters
    Minimum length 1 character
    capabilities
    optional
    object An object containing the details of the Account Holder capabilities activation process
    Individual detail child parameters
    Parameter Description
    type
    optional
    string Type of the capability requested for the Account Holder
    Allowed values: MONEY_IN
    channel_code
    optional
    string Channel code (conditional for money_in capabilities type)
    Allowed values: GCASH , PH_CARDS

    Response Parameters

    Example: Update Account Holder Response

    {
        "id": "4376b7b0-1c44-46be-8640-828f79cdc8be",
        "business_detail": {
            "type": "CORPORATION",
            "legal_name": "test16",
            "description": "testing",
            "trading_name": "test",
            "industry_category": "ACCOMMODATION",
            "country_of_operation": "PH",
            "date_of_registration": "2023-02-02T00:00:00.000Z"
        },
        "individual_details": [{
            "email": "test@xendit.co",
            "gender": "MALE",
            "surname": "test",
            "given_names": "test",
            "nationality": "PH",
            "phone_number": "+63021234567",
            "date_of_birth": "2000-02-02T00:00:00.000Z",
            "place_of_birth": "PH",
            "type": "PIC",
            "role": "owner"
        }],
        "address": {
            "city": "test1",
            "country": "PH",
            "district": "test",
            "postal_code": "1111",
            "street_line1": "test",
            "street_line2": "test",
            "sub_district": "test",
            "province_state": "test"
        },
        "kyc_documents": [
            {
                "type": "SEC_CERTIFICATE_REGISTRATION_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "ARTICLES_OF_INCORPORATION_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "NOTARIZED_SECRETARY_CERTIFICATE_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "LATEST_GIS_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "ACR_OR_IMMIGRANT_COR_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            },
            {
                "type": "SERVICE_AGREEMENT_DOCUMENT",
                "country": "PH",
                "file_id": "63f8719642f5856dcb142bd2",
                "expires_at": "2023-02-02T19:00:00.000Z"
            }
        ],
        "website_url": "https://xendit.co",
        "phone_number": "+63281234567",
        "email": "test@xendit.co",
        "kyc": {
            "status": "NOT_VERIFIED"
        },
        "created": "2023-03-30T11:41:57.881Z",
        "updated": "2023-03-30T11:44:01.122Z"
    }

    Returns Account Holder object with status 200

    Error Codes

    Error Code Error Message
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    INSUFFICIENT_ACCOUNT_HOLDER_DATA
    400
    The information in the Account Holder object is not sufficient to request activation for this payment channel. Please update the fields with the correct information.
    REQUEST_FORBIDDEN_ERROR
    403
    The API key is forbidden to perform this request. You need to use the Platform API key with Account Holder write access.
    FEATURE_NOT_ACTIVATED
    403
    This feature has not been activated for your account. Please reach out to help@xendit.co
    KYC_VERIFICATION_IN_PROGRESS
    403
    Account Holder cannot be updated while KYC verification is in progress, please try again when the verification process has been completed.
    CHANNEL_HAS_BEEN_ACTIVATED
    403
    Payment channel has been activated for this account holder.
    CHANNEL_ACTIVATION_IN_PROGRESS
    403
    Payment channel activation is in progress for this account holder.
    KYC_VERIFICATION_REQUIRED
    403
    Accounts KYC verification has not been completed for this sub-account. Please request capabilities after this process has been completed.
    INVALID_API_KEY
    401
    API key format is invalid
    DATA_NOT_FOUND
    500
    Could not find Account Holder by the ID specified because ID may be invalid.

    Transfer Object

    Object that would be generated upon creation of a Transfer

    Example: Transfer Object

    {
        "created": "2020-01-01T08:51:44.484Z",
        "transfer_id": "60b9d810-d9a3-456c-abbf-2786ec7a9651",
        "reference": "transfer001",
        "source_user_id": "54afeb170a2b18519b1b8768",
        "destination_user_id": "5cafeb170a2b1851246b8768",
        "status": "SUCCESSFUL",
        "amount": 10000
    }
    Parameter Tipe Deskripsi
    created
    required
    string Timestamp of when the Transfer was created

    Timezone: GMT+0
    transfer_id
    required
    string A unique reference for this Transfer set by Xendit systems
    reference
    required
    string A unique reference for this Transfer that you set when making the request
    source_user_id
    required
    string The source of the transfer. This is the user_id of either your master or sub account
    destination_user_id
    required
    string The destination of the transfer. This is the user_id of either your master or sub account
    status
    required
    string The status of the Transfer

    Available values: SUCCESSFUL,PENDING, FAILED
    amount
    required
    number The amount that was transferred

    Create Transfers

    The Transfers API allows you to transfer balances: i) from your sub-accounts to your master account and vice versa, ii) between your sub-accounts. Use this to manage, or split payments between your platform and your sub accounts within the Xendit ecosystem.

    Visit your xenPlatform dashboard in order to view the user_id of your account and sub-accounts.

    Endpoint: Create Transfer

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

    Example: Create Transfer

    curl https://api.xendit.co/transfers -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -d reference=transfer001 \
       -d amount=10000 \
       -d source_user_id=54afeb170a2b18519b1b8768 \
       -d destination_user_id=5cafeb170a2b1851246b8768 \
      <?php
          $url = 'https://api.xendit.co/transfers';
          $apiKey = 'xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:';
          $headers = [];
          $headers[] = 'Content-Type: application/json';
          $data = [
              'reference' => 'transfer001',
              'amount' => 10000,
              'source_user_id' => '54afeb170a2b18519b1b8768',
              'destination_user_id' => '5cafeb170a2b1851246b8768'
          ];
    
          $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;
    from xendit import Xendit
    
    api_key = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:"
    xendit_instance = Xendit(api_key=api_key)
    XenPlatform = xendit_instance.XenPlatform
    
    xenplatform_transfers = XenPlatform.transfers(
        reference="transfer001",
        amount=10000,
        source_user_id="54afeb170a2b18519b1b8768",
        destination_user_id="5cafeb170a2b1851246b8768",
    )
    print(xenplatform_transfers)

    Request Parameters

    Body Parameter Type Description
    reference
    required
    string A unique reference for this Transfer. Use this to reconcile transactions across your master and sub-accounts
    amount
    required
    number The amount that you would like to transfer. No decimal point for IDR, and max 2 decimal points for PHP
    source_user_id
    required
    string The account balance from which you would like to send the Transfer from. This can either be your platform or sub accounts user_id
    destination_user_id
    required
    string The account balance from which you would like to send the Transfer to. This can either be your platform or sub accounts user_id

    Response Parameters

    Example: Transfers Response

    {
        "created": "2020-01-01T08:51:44.484Z",
        "transfer_id": "60b9d810-d9a3-456c-abbf-2786ec7a9651",
        "reference": "transfer001",
        "source_user_id": "54afeb170a2b18519b1b8768",
        "destination_user_id": "5cafeb170a2b1851246b8768",
        "status": "SUCCESSFUL",
        "amount": 10000
    }
    Parameter Type Description
    created
    required
    string Timestamp of when the Transfer was created

    Timezone: GMT+0
    transfer_id
    required
    string A unique reference for this Transfer set by Xendit systems
    reference
    required
    string A unique reference for this Transfer that you set when making the request
    source_user_id
    required
    string The source of the transfer. This is the user_id of either your master or sub account
    destination_user_id
    required
    string The destination of the transfer. This is the user_id of either your master or sub account
    status
    required
    string The status of the Transfer

    Available values: SUCCESSFUL,PENDING, FAILED
    amount
    required
    number The amount that was transferred

    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_SOURCE_OR_DESTINATION_ERROR
    400
    Source or destination account does not exist. Please input a valid business ID within your xenPlatform account.
    INSUFFICIENT_BALANCE
    400
    The cash balance of your source account is insufficient.
    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
    DUPLICATE_REFERENCE
    403
    The reference parameter should be unique.
    XEN_PLATFORM_SUB_ACCOUNT_NOT_LIVE403 Your source or destination account is not live yet. Please specify live accounts for live transfers
    API_KEY_ENVIRONMENT_NOT_MATCH
    403
    Use your LIVE API key to transfer between LIVE accounts, or use TEST API key to transfer between TEST accounts.
    TRANSFER_IN_PROGRESS
    425
    Transfer is currently being processed. Use GET Transfer By Reference to check its latest status
    MISMATCH_PAYLOAD_FOR_REFERENCE
    400
    Reference has been used before. If you'd like to retry this transfer, please use the same payload as your previous request.
    INVALID_AMOUNT
    400
    Transfer amount has to be greater than 0, Transfer amount of IDR currency should not have decimal point, Transfer amount of PHP currency can only have max 2 decimal point

    Get Transfer by Reference

    Endpoint: Get Transfer by Reference

    GET https://api.xendit.co/transfers/reference={reference}

    This endpoint queries the current status of a transfer. This is often used for checking the status of a transaction.

    Request Parameters

    Example Get Transfer Request

    curl https://api.xendit.co/transfers/reference=Monthly_transfers_123 -X GET \
      -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:
    Path Parameter Type Description
    reference
    required
    string reference ID of the transfer to retrieve
    The reference must match the unique reference provided upon transfer request

    Response Parameters

    Example Get Transfer Response

    {
      "created": "2020-11-30T02:47:53.061Z",
      "transfer_id": "bd1cc56b-ce7f-4ad7-8901-3eaa689e90eb",
      "source_user_id":"5cafeb170a2b18519b1b8768",
      "destination_user_id":"5f8d0c0603ffe06b7d4d9fcf",
      "status": "SUCCESSFUL",
      "amount": 90000,
      "reference": "Monthly_Transfers_1234"
    }

    Returns Transfer object with status 200

    Error Codes

    Error Code Description
    DATA_NOT_FOUND
    404
    Could not find transfer by reference because reference may be invalid.
    INVALID_API_KEY_ERROR
    401
    API key is not authorized for this API service, access to xenPlatform is needed

    Create Split Rule

    A Split Rule Object defines how payments in xenPlatform can be routed and split to multiple destinations by xenPlatform. Include the split_rule_id returned in the response in supported transaction endpoints to automatically route and split payments to multiple Account destinations once payments settle.

    Version

    You are currently viewing the newest version of Split Rule API. We have also added API permissions in this version. If you are using an existing API key, please edit your permissions in your Settings page.

    Click here to view the older version.

    Endpoint: Create Split Rule

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

    Example: Create Split Rule

    curl -- request POST \
       --url https://api.xendit.co/split_rules \
       --header 'Authorization: Basic xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:' \
       --header 'Content-Type: application/json' \
       --data-raw '{
        "name": "20210908 Test",
        "description": "Platform fee and Delivery Fee for Marketplace",
        "routes": [
          {
            "flat_amount": 3000,
            "currency": "IDR"
            "destination_account_id": "5f8d0c0603ffe06b7d4d9fcf",
            "reference_id": "reference"
          }, 
          {
            "percent_amount": 5,
            "currency": "IDR"
            "destination_account_id": "5cafeb170a2b18519b1b8768",
            "reference_id": "reference"
          }
        ]
    }'
    '
    <?php
          $url = 'https://api.xendit.co/split_rules';
          $apiKey = 'xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:';
          $headers = [];
          $headers[] = 'Content-Type: application/json';
          $data = [
              'name' => 'standard_split_rule',
              'description' => 'fee_for_all_transactions_accepted_on_behalf_of_vendors',
              'routes' => [
                  [
                    'flat_amount' => '200',
                    'currency' => 'IDR',
                    'destination_account_id':'6548afe09059f97f211047b2',
                    'reference_id' => 'reference',
                  ]
              ]
          ];
    
          $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;

    Request Parameters

    Body Parameter Type Description
    name
    required
    string Name to identify split rule. Not required to be unique. Typically based on transaction and/or sub-merchant types.

    e.g. “standard platform fee and delivery fee”, “commission”
    description
    optional
    string Description to identify fee rule

    e.g. “Fee charged to insurance agents"
    routes
    required
    array Array of objects that define how the platform wants to route the fees and to which accounts. Each Route object is equivalent to a single payment split from the end user to a destination account.
    flat_amount
    conditional
    string
    Amount of payments to be split, using flat rate as a unit.

    This will be null if not applicable. This will be required if percent_amount is null

    All units must be a positive number
    percent_amount
    conditional
    number Amount of payments to be split, using a percent rate as unit.

    This will be null if not applicable. This will be required if flat_amount is null

    All units must be a positive number, with decimals supported up to 2 decimal places.

    Percent amounts have to be between 0 and 100

    Percent amounts are rounded off to the nearest monetary unit (e.g. 0.50 IDR will be rounded to 1 IDR; 0.49 IDR will be rounded to 0 IDR)
    currency
    required
    string ISO 4217 Currency Code

    Note: Will return an error if currency does not match transaction/account currency

    Available values: IDR;PHP;THB;MYR;VND
    destination_account_id
    required
    string ID of the destination account where the amount will be routed to.
    This could be the ID of your platform or sub account.
    reference_id
    required
    string

    Reference ID which acts as an identifier of the route itself. This is used to distinguish in case one split rule has multiple routes of the same destinations.

    Its value must be unique and case sensitive for every route object under the same Split Rule.

    Maximum characters supported is 255 characters.

    Response Parameters

    Example: Fee Rules Response

    {
        "id": "splitru_d9e069f2-4da7-4562-93b7-ded87023d749",
        "name": "Standard platform fee",
        "description": "Platform fee for all transactions accepted on behalf of vendors",
        "routes": [
          {
            "flat_amount": 3000,
            "currency": "IDR",
            "destination_account_id": "5f8d0c0603ffe06b7d4d9fcf",
            "reference_id": "reference"
          }, 
          {
            "percent_amount": 5.25,
            "currency": "IDR",
            "destination_account_id": "5cafeb170a2b18519b1b8768",
            "reference_id": "reference"
          }
        ],
        "created": "2020-09-01T07:00:00.007Z",
        "updated": "2020-09-01T07:00:00.007Z",
        "metadata": {}
    }
    Parameter Type Description
    id
    required
    string Xendit system generated unique ID.

    Format: splitru_{{id}}
    e.g. splitru_NF5p90U3MQ5MXAuH1NF
    name
    required
    string Name to identify fee rule. Not required to be unique. Typically based on transaction and/or sub-merchant types
    description
    optional
    string Description to identify fee rule. Otherwise NULL
    routes
    required
    array Array of objects that define how the platform wants to route the fees and to which accounts. Each Route object is equivalent to a single fee route from the end-customer to a destination account.

    flat_amount
    conditional
    string
    Amount of payments to be split, using flat rate as a unit.

    This will be null if not applicable. This will be required if percent_amount is null

    All units must be a positive number
    percent_amount
    conditional
    number Amount of payments to be split, using a percent rate as unit.

    This will be null if not applicable. This will be required if flat_amount is null

    All units must be a positive number

    Percent amounts have to be between 0 and 100

    Percent amounts are rounded off to the nearest monetary unit (e.g. 0.50 IDR will be rounded to 1 IDR; 0.49 IDR will be rounded to 0 IDR)
    currency
    required
    string ISO 4217 Currency Code

    Note: Will return an error if currency does not match transaction/account currency

    Available values: IDR;PHP;THB;MYR;VND
    destination_account_id
    required
    string ID of the destination account where the amount will be routed to.
    This could be the ID of your platform or sub account.
    reference_id
    required
    string

    Reference ID which acts as an identifier of the route itself. This is used to distinguish in case one split rule has multiple routes of the same destinations.

    Its value must be unique and case sensitive for every route object under the same Split Rule.

    Maximum characters supported is 255 characters.
    created
    required
    string Timestamp in ISO 8601 when the fee rule object was created

    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    updated
    required
    string Timestamp in ISO 8601 when the fee rule object was updated

    Format: YYYY-MM-DDTHH:mm:ssZ
    Timezone: UTC+0
    metadata
    optional
    object Object of additional key-value pairs that the merchants may use like internal system parameters (business ID, shopping cart). 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.
    Otherwise NULL

    Error Codes

    Error Code Description
    INVALID_FEE_AMOUNT
    400
    Fee amount and/or unit is negative number or incorrect format.
    DESTINATION_ACCOUNT_NOT_FOUND
    404
    Returned when destination_account_id is invalid or not connected to this xenPlatform account
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.
    DUPLICATE_ERROR
    400
    Returned if provided reference_id is not unique for the routes

    Set Webhook URLs

    The Set Webhook URLs API allows you to set your account and sub-accounts Webhook URLs.

    The following can be used in the :type path parameters:

    Money-In

    1. invoice: Xendit notifies your system when Invoice has been paid or expired.
    2. fva_status: Xendit notifies your system when Virtual Account has been created or updated successfully. Support: Indonesia only 🇲🇨
    3. fva_paid: Xendit notifies your system when Virtual Account has been paid successfully. Support: Indonesia only 🇲🇨
    4. ro_fpc_paid: Xendit notifies your system when Retail Outlet payment code (Alfamart/Indomaret) in Indonesia has been paid successfully. Support: Indonesia only 🇲🇨
    5. regional_ro_paid: Xendit notifies your system when Over-the-Counter payment code (7 Eleven, Cebuana, ECPay) in Philippines has been paid successfully. Support: Philippines only 🇵🇭
    6. ewallet: New eWallet type to receive charge and other eWallet events across eWallets channels from /ewallets/charges API.
    7. payment_method: Xendit notifies your system when payment method is expiring and/or has expired. Payment Method is a mandatory step to abstract Debit Card/Bank Account for Direct Debit transactions.
    8. payment_method_v2: Xendit notifies your system when payment method V2 is expiring and/or has activated or expired. Learn more about Payment Method V2 here.
    9. direct_debit: A Direct Debit payment event will be sent to your system for any successful transactions. Use direct_debit type to receive Direct Debit payment event via webhook.
    10. qr_code: Xendit notifies your system when QR payment has been made or QR refund has been completed. This field is only supported for qr_codes API version 2022-07-31.
    11. recurring: Xendit notifies your system when Subscription plan has been activated/inactivated, cycle created/succeeded/retrying/failed, or force attempt failed.
    12. payment_succeeded: Xendit notifies your system when a payment has been successfully confirmed or received from the partner channel (Only for payments initiated via new Payments API). Support: All businesses
    13. payment_awaiting_capture: Xendit notifies your system when a payment request with capture_method set to MANUAL has been intialized and a call to the Payment Capture API needed to complete the payment. Support: All businesses
    14. payment_pending: Xendit notifies your system when a payment is being processed by the partner channel awaiting for the terminal status of it (Only for payments initiated via new Payments API). Support: All businesses
    15. payment_failed: Xendit notifies your system when a pending payment has failed (Only for payments initiated via new Payments API). Support: All businesses
    16. capture_succeeded: Xendit notifies your system when a manual capture via the Payment Capture API has succeeded. Support: All businesses
    17. capture_failed: Xendit notifies your system when a manual capture via the Payment Capture API has Failed. Support: All businesses
    18. payment_request_completed: Xendit notifies your system when a Direct Debit or E-Wallet payment request has succeeded or failed. Please Note that this is for the Payment Request API only. Make sure that other payment callbacks for Direct Debit or E-wallet are not set to prevent duplication. Support: Thailand 🇹🇭 and Malaysia 🇲🇾 only

    Money-Out

    1. disbursement: Xendit notifies your system when disbursement has been executed successfully by Xendit, either with COMPLETED or FAILED status. Support: Indonesia only 🇲🇨
    2. ph_disbursement: Xendit notifies your system when disbursement has been executed successfully by Xendit, either with COMPLETED or FAILED status. Support: Philippines only 🇵🇭
    3. batch_disbursement: Xendit notifies your system when Batch Disbursement has been executed successfully by Xendit. Support: Indonesia only 🇲🇨
    4. payout: Xendit notifies your system upon failed and successful payouts. Learn more about Payouts V2 webhooks here.

    Others

    1. report: Xendit notifies your system to send the report to the specified URLs. Support: All businesses

    Endpoint: Set Webhook URLs

    POST https://api.xendit.co/callback_urls/:type

    Request Parameters

    Example: Set Webhook URLs

    curl https://api.xendit.co/callback_urls/:type -X POST \
       -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
       -d url=https://www.xendit.co/webhook_catcher \
      <?php
          $url = 'https://api.xendit.co/callback_urls';
          $apiKey = 'xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:';
          $headers = [];
          $headers[] = 'Content-Type: application/json';
          $data = [
              'url' => 'https://www.xendit.co/webhook_catcher'
          ];
    
          $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;
    from xendit import Xendit, XenPlatformURLType
    
    api_key = "xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==:"
    xendit_instance = Xendit(api_key=api_key)
    XenPlatform = xendit_instance.XenPlatform
    
    xenplatform_callback_url = XenPlatform.set_callback_url(
        type=XenPlatformURLType.INVOICE,
        url="https://test-url-invoice.com",
    )
    print(xenplatform_callback_url)
    Header Parameter Type Description
    for-user-id
    optional
    string The sub-account user-id that you want to set this Webhook URL on.

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

    Path Parameter Type Description
    type
    required
    string The type of Webhook URL you want to set

    Available values: invoice, fva_status, fva_paid, ro_fpc_paid, regional_ro_paid, ewallet, payment_method, payment_method_v2, direct_debit, qr_code, recurring, disbursement, ph_disbursement, batch_disbursement, report, payment_succeeded, payment_awaiting_capture, payment_pending, payment_failed, capture_succeeded, capture_failed, payment_request_completed
    Body Parameter Type Description
    url
    required
    string URL of your server that you want to receive our Webhooks at

    Minimum length 1 character
    Maximum length No maximum characters

    Response Parameters

    Example: Set Webhook URLs Response

    {
        "status": "SUCCESSFUL",
        "user_id": "5e6b30d967627b957de8c123",
        "url": "https://www.xendit.co/webhook_catcher",
        "environment": "TEST",
        "callback_token": "66a6680348e1c33ed2b9053a8eb9291b9e2230ff4f4d3057c9f4ac26405d2123"
    }
    Parameter Type Description
    status
    required
    string The status of setting the Webhook URL

    Available values: SUCCESSFUL
    user_id
    required
    string The user_id on which the Webhook URL has been set
    url
    required
    string The Webhook URL that has been set
    environment
    required
    string The environment on which the Webhook URL has been set

    Available values: TEST, LIVE
    callback_token
    required
    string The unique Webhook token that is attached to each sub-account. Use this to validate that a Webhook is sent from Xendit's servers.

    Error Codes

    Error Code Description
    INVALID_URL_FORMAT
    400
    You have provided an invalid URL format
    CALLBACK_AUTHENTICATION_TOKEN_NOT_FOUND_ERROR
    404
    No webhook verification token found for this business, please contact help@xendit.co to resolve this issue
    API_VALIDATION_ERROR
    400
    Inputs are failing validation. The errors field contains details about which fields are violating validation.

    Account Holder KYC Verification Callback

    Endpoint: Account Holder KYC verification Webhook

    POST https://yourcompany.com/xenplatform_webhook_url

    The Account Holder KYC verification status webhook can be used to let your system know when your Account Holder KYC verification status is PASSED,FAILED, or RESUBMISSION_REQUIRED. This Webhook is only sent for OWNED accounts.

    You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

    Example Account Holder KYC verification Passed Webhook Request

    {
        "event": "account_holder.kyc.status",
        "created": "2021-01-01T10:00:00Z",
        "business_id": "5fe2b0137b7d62542fe6d7de",
        "data": {
            "id": "57fb4e076fa3fa296b7f5a97",
            "created": "2021-01-01T10:00:00Z",
            "updated": "2021-01-01T10:00:00Z",
            "kyc": {
                "status": "PASSED",
                "verified_at": "2021-01-01T10:00:00Z",
                "requested_at": "2021-01-01T10:00:00Z",
                "kyc_passed_at": "2021-01-01T10:00:00Z",
            }
        }
    }
    Header Parameter Type Description
    x-callback-token
    required
    string Your Xendit unique webhook token to verify the origin of the webhook
    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    Body Parameter Type Description
    event
    required
    string The type of event webhook that was sent

    Available values: account_holder.kyc.status
    business_id
    required
    string ID of the Account that this event occurred on. This would be your Platform account ID for Account webhooks.
    created
    required
    string Indicates when the webhook was sent
    Timezone: GMT+0
    data
    required
    array[object] Contains metadata for the event type. For account_holder.kyc.status, contains the kyc object in the Account Holder
    id
    required
    string ID of your Account Holder
    created
    required
    string Indicates when the webhook was sent
    Timezone: GMT+0
    updated
    required
    string Indicates when the webhook was updated
    Timezone: GMT+0
    kyc
    required
    string An object containing the details of the Account Holder KYC verification process
    Individual detail child parameters
    Parameter Description
    status
    required
    string Status of the Account Holder KYC verification
    Allowed values: NOT_VERIFIED PASSED VERIFICATION_IN_PROGRESS RESUBMISSION_REQUIRED FAILED
    kyc_passed_at
    required
    string Timestamp of Account Holder KYC passed in ISO format
    verified_at
    required
    string Timestamp of the Account Holder verification in ISO format
    requested_at
    required
    string Timestamp of the Account Holder KYC verification requested date in ISO format. This is the timestamp when you link your account holder to an Account.
    failure_reasons
    optional
    array[object] An array of objects containing the failure reasons of this Account Holder KYC verification
    Individual detail child parameters
    Parameter Description
    field
    optional
    string Reasons on why this Account Holder KYC verification failed
    message
    optional
    string Contains the detailed message on what the failure entails and next steps (e.g resubmitting the documents etc.)

    Account Holder Capabilities Activation Callback

    Endpoint: Account Holder Capabilities Activation Webhook

    POST https://yourcompany.com/xenplatform_webhook_url

    The Account Holder Capabilities Activation webhook can be used to let your system know when your Account Holder capabilities activaion status is LIVE,DECLINED, or RESUBMISSION_REQUIRED. This Webhook is only sent for OWNED accounts.

    You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

    Example Account Holder Capabilities Activation Webhook Request

    {
      "event": "account_holder.kyc.status",
      "created": "2021-01-01T10:00:00Z",
      "business_id": "5fe2b0137b7d62542fe6d7de",
      "data": {
        "id": "57fb4e076fa3fa296b7f5a97",
        "created": "2021-01-01T10:00:00Z",
        "updated": "2021-01-01T10:00:00Z",
        "capabilities": [
          {
            "type": "MONEY_IN",
            "channel_code": "GCASH",
            "activated_at": "2021-01-01T10:00:00Z",
            "verified_at": "2021-01-01T10:00:00Z",
            "requested_at": "2021-01-01T10:00:00Z",
            "status": "RESUBMISSION_REQUIRED",
            "failure_reason": "Your website URL is not related to your business"
          }
        ]
      }
    }
    Header Parameter Type Description
    x-callback-token
    required
    string Your Xendit unique webhook token to verify the origin of the webhook
    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    Body Parameter Type Description
    event
    required
    string The type of event webhook that was sent

    Available values: account_holder.capabilities.status
    business_id
    required
    string ID of the Account that this event occurred on. This would be your Platform account ID for Account webhooks.
    created
    required
    string Indicates when the webhook was sent
    Timezone: GMT+0
    data
    required
    array[object] Contains metadata for the event type. For account_holder.capabilities.status, contains the capabilities object in the Account Holder
    id
    required
    string ID of your Account Holder
    created
    required
    string Indicates when the webhook was sent
    Timezone: GMT+0
    updated
    required
    string Indicates when the webhook was updated
    Timezone: GMT+0
    capabilities
    required
    string An object containing the details of the Account Holder capabilities activation process
    Individual detail child parameters
    Parameter Description
    type
    optional
    string Type of the capability requested for the Account Holder
    Allowed values: MONEY_IN
    channel_code
    optional
    string Channel code of the requested Money-in Capability. This field is required when TYPE is MONEY_IN
    Allowed values: GCASH, PH_CARDS
    activated_at
    optional
    string Timestamp of the Account Holder capabilities activation in ISO format
    verified_at
    required
    string Timestamp of the Account Holder capabilities verification in ISO format
    requested_at
    required
    string Timestamp of the Account Holder capabilities verification requested date in ISO format.
    status
    required
    string Activation status of the payment channel or capability requested in Account Holder
    Allowed values: LIVE RESUBMISSION_REQUIRED DECLINED VERIFICATION_IN_PROGRESS
    failure_reason
    optional
    string Message containing reason for failure. This will only be specificed if capability status is RESUBMISSION_REQUIRED

    Account Callback

    Xendit notifies 2 types of webhook upon account creation:

    You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Version

    You are currently viewing the newest version of our Accounts API. We have made some changes to the Webhooks that we send. Click here to view the older version.

    Version Changelog
    v2
    Latest version
    Removed account.registered Callback for OWNED Accounts
    v1 First version of Accounts API

    Owned Account Created Callback

    Endpoint: Account Created Callback

    POST https://yourcompany.com/xenplatform_webhook_url

    The Account Created webhook can be used to let your system know when your Accounts have been successfully created. This Callback is only sent for OWNED accounts.

    Callback Payload

    Example Account Created Callback Request

    {
      "event": "account.created",
      "created": "2021-01-01T10:00:00Z",
      "data": {
        "id": "5cafeb170a2b18519b1b8761",
        "created": "2021-01-01T10:00:00Z",
        "updated": "2021-01-01T10:00:00Z",
        "type": "OWNED",
        "email": "test@xendit.co",
        "public_profile": {
          "business_name": "Aaron Warung"
        },
        "country": "ID",
        "status": "LIVE"
      }
    }
    curl --request POST \
      --url https://yourcompany.com/xenplatform_webhook_url \
      --data '{"event":"account.created","business_id":"6abceb170a2b18519b1b1234","created":"2021-01-01T10:00:00Z","data":{"id":"5cafeb170a2b18519b1b8761","created":"2021-01-01T10:00:00Z","updated":"2021-01-01T10:00:00Z","type":"OWNED","email":"aaron@xendit.co","public_profile":{"business_name":"Aaron Warung"},"country":"ID","status":"LIVE"}}'
        <?php
    
        $curl = curl_init();
    
        curl_setopt_array($curl, [
          CURLOPT_URL => "https://yourcompany.com/xenplatform_webhook_url",
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_ENCODING => "",
          CURLOPT_MAXREDIRS => 10,
          CURLOPT_TIMEOUT => 30,
          CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
          CURLOPT_CUSTOMREQUEST => "POST",
          CURLOPT_POSTFIELDS => "{\"event\":\"account.created\",\"business_id\":\"6abceb170a2b18519b1b1234\",\"created\":\"2021-01-01T10:00:00Z\",\"data\":{\"id\":\"5cafeb170a2b18519b1b8761\",\"created\":\"2021-01-01T10:00:00Z\",\"updated\":\"2021-01-01T10:00:00Z\",\"type\":\"OWNED\",\"email\":\"aaron@xendit.co\",\"public_profile\":{\"business_name\":\"Aaron Warung\"},\"country\":\"ID\",\"status\":\"LIVE\"}}",
        ]);
    
        $response = curl_exec($curl);
        $err = curl_error($curl);
    
        curl_close($curl);
    
        if ($err) {
          echo "cURL Error #:" . $err;
        } else {
          echo $response;
        }
    Header Parameter Type Description
    x-callback-token
    required
    string Your Xendit unique webhook token to verify the origin of the webhook
    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    Body Parameter Type Description
    event
    required
    string The type of event webhook that was sent

    Available values: account.created
    business_id
    required
    string ID of the Account that this event occurred on. This would be your Platform account ID for Account webhooks.
    created
    required
    string Indicates when the webhook was sent
    Timezone: GMT+0
    data
    required
    object Contains metadata for the event type. For account.created, this contains the Account object.
    id
    required
    string ID of your Account
    created
    required
    string Timestamp of when the Account was created
    Timezone: GMT+0
    updated
    required
    string Timestamp of when the Account was updated
    Timezone: GMT+0
    type
    required
    string Type of Account
    Available values: OWNED
    email
    required
    string Email identifier for the Account
    public_profile
    required
    object Contains information that will be seen by end-payers or end-recipients (e.g. appears on hosted checkout page, credit card statements, etc.).
    country
    required
    string The country (based on ISO 3166-1 Alpha-2) of incorporation for a business, or the country of residence for an individual.
    Available values: ID, PH

    Default value: Your country of operation
    status
    required
    string Status of the Account
    Available values: LIVE

    Managed Account Updated Callback

    Endpoint: Account Updated Callback

    POST https://yourcompany.com/xenplatform_webhook_url

    The Account Updated webhook can be used to let your system know when your MANAGED Accounts have been successfully registered and live payments enabled.

    You will receive webhooks at various points during the Account onboarding process for MANAGED Accounts:

    1. account.registered - When an Account has been registered via the invitation email
    2. account.activated - When live payments has been enabled for your Account (i.e. activated)

    Account Suspension Callback

    Endpoint: Account Suspension Webhook

    POST https://yourcompany.com/xenplatform_webhook_url

    The Account Suspension webhook can be used to let your system know when Xendit has suspected, suspended or cleared the Accounts linked to your Platform. Our teams and systems automatically and regularly review Account behaviour to help Platforms mitigate potential fraud.

    These events may occur if we have reason to believe that the Account has engaged in fraudulent activity. When these events occur, only the transactions occurring on that specific Account will be affected. This approach allows your Platform to continue accepting payments for your other Accounts normally.

    The events that may be sent through this Webhook include:

    1. account.suspected - When an Account is suspected, Xendit will disable all money-out activities from happening on the Account. The status parameter of the Account will continue to be LIVE as money-in activities can still occur.
    2. account.suspended - When an Account is suspended, Xendit will disable all money-in and money-out activities from happening on the Account. The status parameter of the Account will be changed to SUSPENDED.
    3. account.cleared - When an Account is cleared, Xendit will enable all money-in and money-out activities to happen on the Account. The status parameter of the Account will be changed to LIVE.

    You need to provide an URL to receive webhook. Please specify your URL in Webhook 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 Webhook Settings to verify message authenticity.

    Please response back with status 200 immediately. Xendit marks webhook 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 Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

    Learn more about Webhook.

    Webhook Payload

    Example Account Suspended Webhook Request

    {
      "event": "account.suspended",
      "created": "2022-01-01T02:33:56.113Z",
      "business_id": "61b1ae8459d12951b1a2d7fd",
      "api_version": null,
      "data": {
        "id": "5fe2b0134b5d62542fe6d7de",
        "email": "john@warungshop.co",
        "public_profile": {
          "business_name": "John warung shop"
        },
        "status": "SUSPENDED",
        "reason": "FRAUD_PROMO_ABUSE"
      }
    }
    curl --request POST \
      --url https://yourcompany.com/xenplatform_webhook_url \
      --data '{ "created": "2022-01-01T02:33:56.113Z", "business_id": "61b1ae8459d12951b1a2d7fd", "event": "account.suspended", "api_version": null, "data": { "id": "5fe2b0134b5d62542fe6d7de", "email": "john@warungshop.co", "public_profile": { "business_name": "John warung shop" }, "status": "SUSPENDED", "reason": "FRAUD_PROMO_ABUSE" } }'
        <?php
    
        $curl = curl_init();
    
        curl_setopt_array($curl, [
          CURLOPT_URL => "https://yourcompany.com/xenplatform_webhook_url",
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_ENCODING => "",
          CURLOPT_MAXREDIRS => 10,
          CURLOPT_TIMEOUT => 30,
          CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
          CURLOPT_CUSTOMREQUEST => "POST",
          CURLOPT_POSTFIELDS => "{\"created\":\"2022-01-01T02:33:56.113Z\",\"business_id\":\"61b1ae8459d12951b1a2d7fd\",\"event\":\"account.suspended\",\"api_version\":"NULL",\"data\":{\"id\":\"5fe2b0134b5d62542fe6d7de\",\"email\":\"john@warungshop.co\",\"public_profile\":{\"business_name\":\"John warung shop\"},\"status\":\"SUSPENDED\",\"reason\":\"FRAUD_PROMO_ABUSE\"}}",
        ]);
    
        $response = curl_exec($curl);
        $err = curl_error($curl);
    
        curl_close($curl);
    
        if ($err) {
          echo "cURL Error #:" . $err;
        } else {
          echo $response;
        }
    Header Parameter Type Description
    x-callback-token
    required
    string Your Xendit unique webhook token to verify the origin of the webhook
    webhook-id
    required
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    Body Parameter Type Description
    event
    required
    string The type of event webhook that was sent

    Available values: account.suspected, account.suspended, account.cleared
    created
    required
    string Indicates when the webhook was sent
    Timezone: GMT+0
    business_id
    required
    string ID of the Account that this event occurred on. This would be your Platform account ID for Account webhooks.
    data
    required
    object Contains metadata for the event type.
    id
    required
    string ID of your Account
    email
    required
    string Email identifier for the Account
    public_profile
    required
    object Contains information that will be seen by end-payers or end-recipients (e.g. appears on hosted checkout page, credit card statements, etc.).
    status
    required
    string Status of the Account
    Available values: LIVE, SUSPENDED
    reason
    required
    string Reason for the event

    Errors when transacting on behalf of Accounts

    This section contains general errors that you may face when attempting to transact on behalf of your Accounts (e.g. making an API request which includes the for-user-id header).

    Error Codes

    Error Code Description
    XEN_PLATFORM_SUB_ACCOUNT_NOT_LIVE
    404
    The Account is not yet live or has been suspended based on internal risk policies, please contact help@xendit.co for more information

    Test Scenarios

    This section includes test scenarios and other information to make sure your integration works as planned. Use it to trigger different flows in your integration and ensure they are handled accordingly

    Checklists

    Xendit has designed its live and test modes to function as similarly as possible. Flipping the switch is mostly a matter of swapping your API keys.

    If you are a developer, or had a developer perform an integration for you, you should also consider the following items before going live.

    Handle Edge Cases

    We have created several test cases you can use to replicate various states and responses. Beyond these options, perform your due diligence, testing your integration with:

    We also recommend you have someone else test your integration, especially if that other person is not a developer themselves.

    Review Error Handling

    Once you have gone live is an unfortunate time to discover you have not properly written your code to handle every possible error type, including those that should "never" happen. Be certain your code is defensive, handling not just the common errors, but all possibilities.

    When testing your error handling, especially watch what information is shown to your users. A card being declined (i.e., CARD_DECLINED) is a different concern than an error on your backend (e.g., an API_VALIDATION_ERROR).

    Review Your Logging

    Xendit logs every request made with you API keys. We recommend that you log all important data on your end, too, despite the apparent redundancy. Your own logs will be a life-saver if your server has a problem contacting Xendit or there's an issue with your API keys--both cases would prevent us from logging your request.

    Regularly examine your logs to ensure they're storing all the information you may need and they are not storing anything of a sensitive nature (e.g., personally identifiable information).

    Independent From Test Mode Objects

    Xendit objects created in test mode--such as charge, virtual accounts, retail outlets, etc---are not usable in live mode. This prevents your test data from being inadvertently used in your production code. When recreating necessary objects in live mode, be certain to use the same ID values (e.g. the same Virtual Account external ID) to guarantee your code will continue to work without issue

    Register Live Webhook URL

    Your Xendit account can have both test and live webhook URLs. If you are using webhook, make sure you have defined live endpoints in your Xendit account. Then confirm that the live endpoint functions exactly the same as your test endpoint.

    While examining your webhook status, also take a moment to check that your live endpoint:

    Secure Your API keys

    As a security measure, we recommend change your API keys on a regular basis, and also just before going live. This is in case they have been saved somewhere outside of your codebase during development. Make sure your workflow doesn't result in your API keys being represented or stored in multiple places--this leads to bugs--or even ending up in your version control software.

    Docs Changelog

    API Reference Changelog

    November 18, 2024

    November 5, 2024

    November 4, 2024

    October 23, 2024

    October 4, 2024

    September 18, 2024

    September 3, 2024

    September 4, 2024

    September 3, 2024

    August 16, 2024

    August 5, 2024

    August 1, 2024

    July 29, 2024

    July 10, 2024

    June 21, 2024

    June 21, 2024

    June 4, 2024

    May 14, 2024

    May 7, 2024

    May 3, 2024

    Apr 17, 2024

    Apr 11, 2024

    Apr 7, 2024

    Mar 26, 2024

    Mar 20, 2024

    Mar 05, 2024

    Feb 26, 2024

    Feb 20, 2024

    Feb 6, 2024

    Feb 5, 2024

    Feb 3, 2024

    Feb 1, 2024

    Jan 15, 2024

    Jan 19, 2024

    Dec 18, 2023

    Dec 15, 2023

    Nov 21, 2023

    Nov 15, 2023

    November 9, 2023

    November 3, 2023

    October 19, 2023

    October 16, 2023

    October 12, 2023

    October 09, 2023

    October 03, 2023

    October 03, 2023

    September 25, 2023

    September 20, 2023

    September 14, 2023

    September 6, 2023

    August 10, 2023

    July 26, 2023

    July 17, 2023

    July 3, 2023

    June 26, 2023

    June 22, 2023

    June 13, 2023

    June 12, 2023

    June 11, 2023

    June 8, 2023

    May 31, 2023

    May 23, 2023

    May 22, 2023

    May 21, 2023

    May 15, 2023

    April 17, 2023

    April 14, 2023

    April 12, 2023

    April 4, 2023

    March 29, 2023

    March 22, 2023

    March 20, 2023

    March 14, 2023

    March 7, 2023

    March 2, 2023

    February 26, 2023

    February 19, 2023

    February 14, 2023

    February 13, 2023

    February 8, 2023

    February 8, 2023

    February 7, 2023

    February 6, 2023

    January 31, 2023

    January 12, 2023

    January 6, 2023

    January 3, 2023

    December 22, 2022

    Desember 16, 2022

    December 13, 2022

    Desember 8, 2022

    November 29, 2022

    November 11, 2022

    November 11, 2022

    November 8, 2022

    November 3, 2022

    October 28, 2022

    October 27, 2022

    Oktober 18, 2022

    Oktober 12, 2022

    Oktober 11, 2022

    September 30, 2022

    September 12, 2022

    September 6, 2022

    Agusttus 23, 2022

    Agustus 22, 2022

    Agustus 15, 2022

    Agustus 9, 2022

    Agustus 5, 2022

    Juli 27, 2022

    Juli 15, 2022

    Juli 14, 2022

    Juni 20, 2022

    Juni 13, 2022

    Juni 2, 2022

    Mei 27, 2022

    Mei 12, 2022

    Mei 11, 2022

    Mei 10, 2022

    Apr 25, 2021

    Apr 21, 2021

    Apr 19, 2022

    Apr 18, 2022

    Apr 05, 2022

    Mar 21, 2022

    Mar 16, 2022

    Mar 11, 2022

    Mar 10, 2022

    Mar 09, 2022

    Feb 28, 2022

    Feb 08, 2022

    Feb 04, 2022

    Feb 03, 2022

    Jan 20, 2022

    Jan 17, 2022

    Jan 14, 2022

    Jan 13, 2022

    Jan 11, 2022

    Jan 05, 2022

    Dec 28, 2021

    Dec 24, 2021

    Dec 22, 2021

    Dec 15, 2021

    Dec 13, 2021

    Dec 10, 2021

    Dec 9, 2021

    Dec 2, 2021

    Nov 18, 2021

    Nov 15, 2021

    Nov 12, 2021

    Nov 1, 2021

    Oct 29, 2021

    Oct 21, 2021

    Oct 19, 2021

    Oct 18, 2021

    Oct 08, 2021

    Oct 07, 2021

    Oct 05, 2021

    Oct 04, 2021

    Sep 30, 2021

    Sep 28, 2021

    Sep 27, 2021

    Sep 21,2021

    Sep 19,2021

    Sep 15,2021

    Sep 10, 2021

    Aug 26, 2021

    Aug 25, 2021

    Aug 19, 2021

    Aug 18, 2021

    Aug 18, 2021

    Aug 5, 2021

    Aug 5, 2021

    Aug 4, 2021

    Jul 29, 2021

    Jul 28, 2021

    Jul 28, 2021

    Jul 27, 2021

    Jul 23, 2021

    Jul 5, 2021

    Jul 21, 2021

    Jul 13, 2021

    Jul 12, 2021

    Jun 28, 2021

    Jun 24, 2021

    Jun 21, 2021

    Jun 3, 2021

    June 2, 2021

    May 28, 2021

    May 12, 2021

    May 5, 2021

    Apr 28, 2021

    Apr 12, 2021

    Apr 08, 2021

    Apr 07, 2021

    Mar 29, 2021

    Mar 26, 2021

    Mar 25, 2021

    Mar 17, 2021

    Mar 12, 2021

    Mar 10, 2021

    Mar 05, 2021

    Mar 04, 2021

    Mar 01, 2021

    Feb 26, 2021

    Feb 22, 2021

    Feb 17, 2021

    Menambahkan kode sampel Python pada API /ewallets/charges

    Feb 15, 2021

    Feb 10, 2021

    Feb 09, 2021

    Feb 05, 2021

    API eWallet baru yang simple dan konsisten yang mendukung top provider eWallet di Indonesia dan Filipina

    Feb 4, 2021

    Feb 1, 2021

    Jan 22, 2021

    Jan 21, 2021

    Jan, 19, 2021

    Jan, 04, 2021

    Dec, 29, 2020

    Dec, 17, 2020

    Dec, 8, 2020

    Nov, 26, 2020

    Nov, 11, 2020

    Nov, 2, 2020

    Oct 22, 2020

    Oct 20, 2020

    Okt 4, 2020

    Agu 04, 2020

    Aug 3, 2020

    Sep 28, 2020

    Sep 17, 2020

    Penambahan Platform Fee sebagai fitur baru untuk xenPlatform

    Sep 14, 2020

    Upaya Pengiriman Callback Terbaru

    Agu 04, 2020

    Sept 9, 2020

    Aug 13, 2020

    Aug 12, 2020

    Agu 11, 2020

    Aug 04, 2020

    Aug 3, 2020

    Jul 31, 2020

    Jul 30, 2020

    Jul 28, 2020

    Jul 27, 2020

    Jul 24, 2020

    Jul 16, 2020

    Jul 07, 2020

    Jul 07, 2020

    Jul 07, 2020

    Jul 01, 2020

    June 30, 2020

    Jun 24, 2020

    Jun 18, 2020

    June 17, 2020

    Jun 11, 2020

    Jun 06, 2020

    May 31, 2020

    May 26, 2020

    May 21, 2020

    May 13, 2020

    May 12, 2020

    May 06, 2020

    April 28, 2020

    April 24, 2020

    April 20, 2020

    April 16, 2020

    April 16, 2020

    April 14, 2020

    March 20,2020

    March 19, 2020

    March 11, 2020

    March 5, 2020

    March 3, 2020

    March 2, 2020

    February 28, 2020

    February 26, 2020

    February 18, 2020

    February 14, 2020

    February 12, 2020

    February 04, 2020

    January 23, 2020

    January 20, 2020

    January 16, 2020

    January 14, 2020

    January 9, 2020

    January 6, 2020

    December 15, 2019

    December 14, 2019

    December 12, 2019

    December 11, 2019

    December 9, 2019

    November 27, 2019

    November 26, 2019

    November 21, 2019

    November 7, 2019

    October 31, 2019

    October 30, 2019

    October 23, 2019