NAV undefined
undefined
bash php java

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 fintech lending and eCommerce, 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.

Learn our APIs with Postman

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. See our Postman Guide to get started!

Authentication

To successfully authenticate with Xendit's API, you must append a colon and Base 64 encode the API key you find in the dashboard. For example if your API key is

xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==

First, add a colon at the end

xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==:

Finally, Base64 encode the colon appended key to get

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, we provide you API keys for both the development and production environments. All requests made in the development environment will never hit the banking networks and will not cost you anything.

Before using the API, make sure that you have registered and get your account authenticated as API requests without authentication will fail. To authenticate your account, you have to include your secret API key in the request which can be accessed in Xendit Dashboard. You can manage your API keys in the Dashboard > Settings > API Keys. Your development and production keys determine your environment. Your API keys should be kept private so do not share your secret API keys.

All the API requests should be made over HTTPS instead of HTTP (all calls made over plain HTTP will fail). We also provide PHP client libraries to save you time. We’re developing more libraries and plugins in the near future and if you write your own library, we would love to hear about it. Make sure you’ve completed the authentication before using our API.

Balances

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. You can assign your money into different accounts according to your business logic (eg: cash account, tax account, escrow account) and each account has its own balance that can be accessed in the dashboard.

Currently, the API only supports querying the balance for your cash account. Anything else related to the account (eg: adding new account, transferring money from accounts besides cash account, etc.) will be done at the beginning in initial configuration with our technical team.

Get balance

Endpoint: Get Invoice

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

Get Balance allows you to retrieve the balance of your cash account. Some use cases include: deciding when you may need to withdraw funds, determining if you have funds to disburse, and if you just like to check it’s still there :P

Example Get Invoice Request

curl https://api.xendit.co/balance -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->getBalance();
  print_r($response);
?>
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://api.xendit.co/balance")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));

Get Invoice Response

Example Get Invoice Response

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

Credit Cards

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
    }
});

Payment details are securely collected and tokenized on the front end, so that sensitive card data never passes through your systems. The minimum requirements to tokenize a card are the amount, card number, expiration date, and CVN code. Tokens are required to Charge Cards.

Example tokenData object

{        
    "amount": "10000",        
    "card_number": "4000000000000002",        
    "card_exp_month": "12",        
    "card_exp_year": "2017",        
    "card_cvn": "123",
    "is_multiple_use": false        
}

Example Tokenization Response

{
    "id": "586f0ba2ab70de5d2b409e0d",
    "status": "IN_REVIEW",
    "risk_score": 29,
    "payer_authentication_url": "https://api.xendit.co/credit_card_tokens/586f0ba2ab70de5d2b409e0d/authentication_redirect?api_key=xnd_public_development_key"
}

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. When tokenizing a card for multi-use, the amount field is not required as it is instead specified during Authentication. See Create Authentication for more details.

For single-use tokens, fraud detection can be performed at the tokenization stage. See Fraud Detection for details on submitting additional fields to enable fraud detection.

Tokenization Request

Parameter Description
amount string
The charge amount. Required unless is_multiple_use is set to true
card_number string (required)
Card number
card_exp_month string (required)
Card expiration month
card_exp_year string (required)
Card expiration year
card_cvn string (required)
Card CVN/CV2 code
xenditResponseHandler function (required)
The response handler function is called after tokenization is attempted, to receive errors and tokenization response
is_multiple_use boolean
True if you want to create token for multiple charge. Defaults to false

Tokenization Response

Parameter Description
id string (required)
The token ID. This will be used later to Charge the funds from the credit card
status string (required)
Tokenization status. See Tokenization Statuses
risk_score string (optional)
Risk score from Fraud Detection System. See Fraud Detection
payer_authentication_url string (optional)
If status is IN_REVIEW, this contains the URL to the page for users to authenticate themselves using 3DS
failure_reason string (optional)
If status is FAILED, this describes the failure. See Tokenization Failure Reasons.

Tokenization Statuses

Status Description
IN_REVIEW The customer must authenticate their identity. Xendit provides a URL which you should navigate your users to for easily performing 3DS.
VERIFIED The customer successfully authenticated their identity. Therefore, it is safe to send the token to your backend for charging.
FAILED Tokenization can fail for many reasons. See Tokenization Failure Reasons.

Tokenization Failure Reasons

Failure Reason Description
AUTHENTICATION_FAILED This status means the customer tried to authenticate using 3DS but did not successfully complete the authentication.
HIGH_RISK_TRANSACTION This status means that transaction rejected due to high fraud risk score.

Tokenization Errors

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
INVALID_JSON_FORMAT
400
The request body is not valid JSON.
ACCOUNT_NUMBER_INVALID_ERROR
400
Credit card number is invalid.
VALIDATION_ERROR
400
Data was passed in an incorrect format.
CREDIT_CARD_DATA_ERROR
400
Invalid data was sent to the credit card processor.
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.

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
    }
});

Creating authentications is only required if if a card is tokenized with is_multiple_use set to true. For single-use tokens, authentications are performed automatically during Tokenization.

To authenticate a token prior to charging, 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 charge the same card multiple times. For more details on creating a charge, see Create Charge.

Example authenticationData object

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

Example Authentication Response

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

Authentication Request

Parameter Description
amount string (required)
The charge amount
token_id string (required)
Token id that store credit card information
card_cvn string (required)
Card CVN/CVC code
xenditResponseHandler function (required)
The response handler function is called after tokenization is attempted, to receive errors and tokenization response

Authentication Response

Parameter Description
id string (required)
The authentication ID. This will be used later to Charge the funds from the credit card together with token_id
status string (required)
Tokenization status. See Tokenization Statuses
risk_score string (optional)
Risk score from Fraud Detection System. See Fraud Detection
payer_authentication_url string (optional)
If status is IN_REVIEW, this contains the URL to the page for users to authenticate themselves using 3DS
failure_reason string (optional)
If status is FAILED, this describes the failure. See Tokenization Failure Reasons.

Create Charge

Endpoint: Create Charge

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

Example Charge Request

curl https://api.xendit.co/credit_card_charges \
    -X POST \
    -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
    -d token_id=586f0ba2ab70de5d2b409e0d \
    -d amount=17000 \
    -d external_id=example-123 \
    -d authentication_id=58e2097218b815f555c8a526
<?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 = 17000;
  $authentication_id = '58e2097218b815f555c8a526';

  $response = $xenditPHPClient->captureCreditCardPayment($external_id, $token_id, $amount);
  print_r($response);
?>

Example Charge Response

{
    "id": "5872f07cdd75f9e1722f850c",
    "external_id": "Xendit",
    "capture_amount": 17000,
    "business_id": "5785e6334d7b410667d355c4",
    "merchant_reference_code": "5785e6334d7b410667d355c4-Xendit",
    "merchant_id": "your_business",
    "created": "2017-01-09T02:07:56.401Z",
    "status": "CAPTURED",
    "eci": "05",
}

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

Charge Request

Parameter Description
token_id string (required)
The token ID used to charge the card.
amount number (required)
The charge amount
external_id string (required)
A unique identifier of your choice
authentication_id string
Authentication ID. Required if charging a card multiple times.

Charge Response

Parameter Description
id string (required)
ID of the charge captured.
external_id string (required)
A unique identifier of your choice
capture_amount number (required)
The charge amount
business_id string (required)
The ID of your business in Xendit.
merchant_reference_code string (required)
An ID used to reconcile transactions with the bank.
merchant_id string (required)
Your merchant ID used for processing credit cards with the bank.
created string (required)
An ISO timestamp that tracks when the charge was made
status string (required)
Status of the charge. See Charge Statuses
eci string (optional)
Status of 3DS authentication. See ECI codes
charge_type string (required)
Types of charges. See Charge types
failure_reason string (optional)
If status is FAILED, this describes the failure. See Charge Failure Reasons

Charge Statuses

Status Description
CAPTURED Charge is successful and the funds will be settled according to the settlement schedule.
FAILED Charge failed. See Charge Failure Reasons

Charge Failure Reasons

Failure Reason Description
EXPIRED_CARD The card you are trying to capture is expired. Ask your customer for a different card
CARD_DECLINED The card you are trying to capture has been declined by the bank. Ask your customer for a different card
INSUFFICIENT_BALANCE The card you are trying to capture does not have enough balance to complete the capture
STOLEN_CARD The card you are trying to capture has been marked as stolen. Ask your customer for a different card
INACTIVE_CARD The card you are trying to capture is inactive. Ask your customer for a different card

Charge Errors

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
INVALID_JSON_FORMAT
400
The request body is not valid JSON.
TOKEN_ALREADY_USED_ERROR
400
The single-use token ID has already been used in a charge.
AUTHENTICATION_ALREADY_USED_ERROR
400
The authentication ID has already been used in a charge.
INVALID_TOKEN_ID_ERROR
400
The token ID format is invalid.
TOKEN_NOT_FOUND_ERROR
404
The token ID was not found in the system.

Charge Types

Status Description
SINGLE_USE_TOKEN Charge created with single-use token.

ECI Codes

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

Create Refund

Endpoint: 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" \
    -d amount=15000
    -d external_id=unique-external-id
<?php
  require 'vendor/autoload.php';

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

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

  $credit_card_charge_id = '5877255293ff67900c6aa64e';
  $amount = 15000;
  $external_id = 'unique-external-id';

  $response = $xenditPHPClient->issueCreditCardRefund($credit_card_charge_id, $amount, $external_id);
  print_r($response);
?>

Example Refund Response

{
  "updated": "2017-04-21T04:05:09.755Z",
  "created": "2017-04-21T04:05:04.936Z",
  "credit_card_charge_id": "58f89041780d51ed097896c5",
  "user_id": "57c5aa7a36e3b6a709b6e148",
  "amount": 15000,
  "external_id": "unique-external-id",
  "status": "SUCCEEDED",
  "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 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.

Refund Request

Header 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.
Parameter Description
amount string (required)
The amount to be refunded
external_id string (required)
A unique identifier of your choice

Refund Response

Parameter Description
updated string (required)
An ISO timestamp that tracks when the last time refund was updated
created string (required)
An ISO timestamp that tracks when the refund was made
credit_card_charge_id string (required)
The charge ID, used to unique identify every charge.
user_id string (required)
Your ID in xendit system
amount number (required)
Amount of the refund
external_id string (required)
Unique identifier that you provide in the request
status string (required)
Status of the refund. See Refund Statuses
fee_refund_amount number (required)
Amount of fee refunded (proportional to the refund amount)
id string (required)
Unique ID referencing the refund request

Refund Statuses

Status Description
SUCCEEDED Refund succeeded
FAILED Refund failed

Refund Errors

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.
INSUFFICIENT_BALANCE_ERROR
400
Insufficient balance to create refund
REFUND_AMOUNT_EXCEEDED_ERROR
400
refunded amount would exceed total charge
DUPLICATE_REFUND_ERROR
400
external_id already being used before
CREDIT_CARD_CHARGE_NOT_FOUND_ERROR
404
credit_card_charge_id not found

Fraud Detection

Javascript Function: createToken (with Fraud Detection)

Xendit.card.createToken(tokenData, fraudData, 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
    }
});

Javascript Function: createAuthentication (with Fraud Detection)

Xendit.card.createAuthentication(authenticationData, fraudData, 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
    }
});

Example fraudData object

{        
    "billing_first_name": "Giuseppe",
    "billing_last_name": "Contini",
    "billing_street_1": "123 Elm St.",
    "billing_city": "Cambridge",
    "billing_state": "MA",
    "billing_country": "US",
    "billing_postal_code": "02139",
    "billing_email": "joe@xendit.co",
    "billing_customer_id": "joe_16171235678",
    "billing_phone_number": "+16171235678",
    "shipping_first_name": "Joe",
    "shipping_last_name": "Contini",
    "shipping_street_1": "Jl. Casablanca Raya 88",
    "shipping_city": "Jakarta Selatan",
    "shipping_state": "Jakarta",
    "shipping_country": "ID",
    "shipping_postal_code": "12870",
    "shipping_phone_number": "+6281213831234",
    "shipping_method": "JNE",
    "items" : [
       {    
         "product_sku" : "106101100105",
         "product_code" : "Lightsaber_green_02",
         "product_name" : "Electrum Lightsaber",
         "quantity" : "1",
         "unit_price" : "4000000"
       }
    ]
}

Example Tokenization Response (with Fraud Detection)

{
    "id": "586f4a15dd75f9e1722f8488",
    "status": "VERIFIED",
    "risk_score": 29,
    "payer_authentication_url": "https://api.xendit.co/credit_card_tokens/586f4a15dd75f9e1722f8488/authentication_redirect?api_key=xnd_public_development_O4iFfuQhgLOsl8M9eeEYGzeWYNH3otV5w3Dh%2FBFj%2FmHW%2B72nCQR%2F"
}

Fraud detection is performed by including an additional fraudData object during Tokenization for single charges, and during Authentication for multiple charges.

Fraud Fields

Parameter Description
billing_first_name string (required)
Billing first name
billing_last_name string (required)
Billing last name
billing_street_1 string (required)
Billing address
billing_city string (required)
Billing city
billing_state string (required)
Billing State. Required only for US/Canada.
billing_country string (required)
Billing Country
billing_postal_code string (required)
Billing postal code. Required only for US/Canada.
billing_email string (required)
Billing email
billing_customer_id string (optional)
Billing customer ID
billing_phone_number string (optional)
Billing phone number
shipping_first_name string (optional)
Shipping first name
shipping_last_name string (optional)
Shipping last name
shipping_street_1 string (optional)
Shipping address
shipping_city string (optional)
Shipping city
shipping_state string (optional)
Shipping state. Required for U.S. and Canada
shipping_country string (optional)
Shipping country
shipping_postal_code string (optional)
Shipping postal code. Required only for US/Canada.
shipping_phone_number string (optional)
Shipping phone number
shipping_method string (optional)
Shipping method
items array (optional)
Items in the order. See Fraud Item Fields

Fraud Item Fields

Parameter Description
product_sku string (required)
Product SKU
product_code string (required)
Product code
product_name string (required)
Product name
quantity string (required)
Quantity
unit_price string (required)
Unit price

See Create Token for the list of Tokenization Statuses, Tokenization Failure Reasons, and Tokenization Errors that can be returned when using fraud detection.

Accept Bank Transfers

Create invoices

Endpoint: Create Invoice

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

Before collecting money you have to first start by making invoices. These invoices are the basic building blocks for one-time charges, recurring billing, or some combination of both. You will use this API to create charges that your users will see and need to pay. Our invoicing system will collect all the necessary payment information to complete a payment successfully.

Learn more about invoices in our documentation

Create Invoice Request

Example Create Invoice Request

curl https://api.xendit.co/v2/invoices -X POST \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
   -d external_id=demo_1475801962607 \
   -d payer_email=sample_email@xendit.co \
   -d description='Trip to Bali' \
   -d amount=230000
<?php
  require 'vendor/autoload.php';

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

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

  $external_id = 'demo_1475801962607';
  $amount = 230000;
  $payer_email = 'sample_email@xendit.co';
  $description = 'Trip to Bali';

  $response = $xenditPHPClient->createInvoice($external_id, $amount, $payer_email, $description);
  print_r($response);
?>
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Entity payload = Entity.json("{  'external_id': 'invoice_123124123',  'amount': 500000,  'payer_email': 'payer@test.com',  'description': 'Invoice #123124123 for Nike shoes',  'should_exclude_taxes': false,  'should_exclude_fees': false}");
Response response = client.target("https://api.xendit.co/v2/invoices")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==")
  .post(payload);

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
Parameter Description
external_id
required
string ID of your choice (typically the unique identifier of an invoice in your system)
payer_email
required
string Email of the end user you're charging
description
required
string Description of the invoice
amount
required
number Amount on the invoice. The minimum amount to create an invoice is 11000.
should_exclude_taxes
optional
boolean Whether to separate out taxes for this invoice. If you would like to set this up, please talk to our lovely devs
default: false
should_exclude_fees
optional
boolean Whether to exclude additional fees for this invoice. These fees may include agent fees or convenience fees you charge on top of the base price. For most customers, this is irrelevant. If you would like to set this up, please talk to our lovely devs
default: false
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

Create Invoice Response

Example Create Invoice Response

{
  "id": "579c8d61f23fa4ca35e52da4",
  "user_id": "5781d19b2e2385880609791c",
  "external_id": "invoice_123124123",
  "is_high": true,
  "status": "PENDING",
  "merchant_name": "Xendit",
  "amount": 50000,
  "billable_amount": 54000,
  "taxable_amount": 4000,
  "received_amount": 47500,
  "payer_email": "albert@xendit.co",
  "description": "This is a description",
  "invoice_url": "http://api.xendit.co/web/invoices/57b56460b65d1a6a0f0014be",
  "xendit_fee_amount": 500,
  "expiry_date": "2016-08-01T11:20:01.017Z",
  "taxes": [
    {
      "percentage": 0.1,
      "name": "VAT"
    },
    {
      "percentage": -0.02,
      "name": "PPH"
    }
  ],
  "fees": [
    {
      "percentage": 0.04,
      "xendit_user_id": "XENDIT_FEES",
      "name": "Agent Fee"
    }
  ],
  "available_banks": [
    {
      "bank_code": "BCA",
      "collection_type": "POOL",
      "bank_account_number": 1000008,
      "transfer_amount": 54000
    },
    {
      "bank_code": "MANDIRI",
      "collection_type": "UNIQUE",
      "bank_branch": "KCP Jkt Mayestik",
      "bank_account_number": "1261006593021",
      "account_holder_name": "SENDIRI DIGITAL INDO",
      "transfer_amount": 54002,
      "identity_amount": 2
    }
  ]
}
Parameter Description
id An invoice ID generated by Xendit
user_id Your Xendit Business ID
external_id An ID of your choice we append to all transactions. Often your unique ID like a phone number, email or transaction ID
is_high Should unique numbers go above or below the amount. If true, it would mean a 100.000 invoice would display a unique amount above, e.g. 100.123
status PENDING the invoice has yet to be paid
COMPLETED the invoice has successfully been paid
merchant_name The name of your company or website
amount Nominal amount for the invoice (without taxes, fees)
billable_amount Total amount for the invoice (inclusive of all taxes, fees)
taxable_amount The amount that is taxable
received_amount Amount attributable to you net of our fees. Thanks for using us :)
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
xendit_fee_amount Xendit fees - thanks for supporting a better world of payments :)
expiry_date ISO date and time that the invoice expires. Default is 24 hours. If you'd like to change the default for your account, please contact our support team.
taxes
percentage
name
Any taxes you would like to include on your invoices
The percentage of ‘amount’ charge
Name of the tax that will display on the invoice
fees
percentage
xendit_user_id
name
Any additional fees to include on your invoices
The percentage of ‘amount’ to charge (decimal)
The entity’s Xendit user ID
The entity’s name shown on invoices/dashboard
available_banks
bank_code
collection_type

bank_branch
account_holder_name
bank_account_number
transfer_amount
identity_amount
Available payment methods as per your config
Bank code (see bank codes)
UNIQUE type is unique amounts
POOL type is nonfixed virtual account
Name of the bank branch (if unique amounts)
Name of the bank account (if unique amounts)
Bank account number for users to pay into
Amount the user should transfer
Amount to identify the payment (if unique amounts)

Create Invoice Errors

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.
MINIMAL_TRANSFER_AMOUNT_ERROR
400
Could not create invoice because amount is below Rp 10000.
MERCHANT_INVOICE_BANKS_NOT_FOUND_ERROR
404
The virtual account range needs to be configured for your account. Please contact support and we will set this up for you.

Get an invoice

Endpoint: Get an Invoice

GET https://api.xendit.co/v2/invoices/{invoice_id}

Get Invoice Request

Example Get Invoice Request

curl https://api.xendit.co/v2/invoices/{invoice_id} -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);

  $invoice_id = '587cc7b4863f2b462beb31f6';

  $response = $xenditPHPClient->getInvoice($invoice_id);
  print_r($response);
?>
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://api.xendit.co/v2/invoices/{invoice_id}")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
Parameter Description
invoice_id
required
string ID of the invoice to retrieve

Get Invoice Response

Example Get Invoice Response

{
  "id": "579c8d61f23fa4ca35e52da4",
  "user_id": "5781d19b2e2385880609791c",
  "external_id": "invoice_123124123",
  "is_high": true,
  "status": "PENDING",
  "merchant_name": "Xendit",
  "amount": 50000,
  "billable_amount": 54000,
  "taxable_amount": 4000,
  "received_amount": 47500,
  "payer_email": "albert@xendit.co",
  "description": "This is a description",
  "invoice_url": "https://api.xendit.co/web/invoices/57b56460b65d1a6a0f0014be",
  "xendit_fee_amount": 500,
  "expiry_date": "2016-08-01T11:20:01.017Z",
  "taxes": [
    {
      "percentage": 0.1,
      "name": "VAT"
    },
    {
      "percentage": -0.02,
      "name": "PPH"
    }
  ],
  "fees": [
    {
      "percentage": 0.04,
      "xendit_user_id": "XENDIT_FEES",
      "name": "Agent Fee"
    }
  ],
  "available_banks": [
    {
      "bank_code": "BCA",
      "collection_type": "POOL",
      "bank_account_number": 1000008,
      "transfer_amount": 54000
    },
    {
      "bank_code": "MANDIRI",
      "collection_type": "UNIQUE",
      "bank_branch": "KCP Jkt Mayestik",
      "bank_account_number": "1261006593021",
      "account_holder_name": "SENDIRI DIGITAL INDO",
      "transfer_amount": 54002,
      "identity_amount": 2
    }
  ]
}
Parameter Description
id Unique invoice ID generated by Xendit
user_id Your Xendit Business ID
external_id Custom ID set during invoice creation. Our customers often use a phone number, email address, or transaction/order ID
is_high Should unique numbers go above or below the amount. If true, it would mean a 100.000 invoice would display a unique amount above, e.g. 100.123
status PENDING the invoice has yet to be paid
COMPLETED the invoice has successfully been paid
merchant_name The name of your company or website
amount Nominal amount for the invoice (without taxes, fees)
billable_amount Total amount for the invoice (inclusive of all taxes, fees)
taxable_amount The amount that is taxable
received_amount Amount attributable to you net of our fees. Thanks for using us :)
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
xendit_fee_amount Xendit fees - thanks for supporting a better world of payments :)
expiry_date ISO date and time that the invoice expires. We reserve unique numbers only for a specific period of time. After that, we’ll reset with a different number. You can configure this expiry time in dashboard.
taxes
percentage
name
Any taxes you would like to include on your invoices
The percentage of ‘amount’ charge
Name of the tax that will display on the invoice
fees
percentage
xendit_user_id
name
Any additional fees to include on your invoices
The percentage of ‘amount’ to charge (decimal)
The entity’s Xendit user ID
The entity’s name shown on invoices/dashboard
available_banks
bank_code
collection_type

bank_branch
account_holder_name
bank_account_number
transfer_amount
identity_amount
Available payment methods as per your config
Code of the banks (we support over 140+)
UNIQUE type is unique amounts
POOL type is nonfixed virtual account
Name of the bank branch (if unique amounts)
Name of the bank account (if unique amounts)
Bank account number they should pay into
Amount the user should transfer
Amount to help identify the payment (if unique amounts)

Get Invoice Errors

Error Code Description
INVALID_JSON_FORMAT
400
The request body is not a valid JSON format.
TAXED_INVOICE_NOT_FOUND_ERROR
404
Could not find taxed invoice by id.

Invoice callback

Endpoint: Invoice Callback

POST https://yourcompany.com/invoice_callback_url
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Entity payload = Entity.json("{
    id: '579c8d61f23fa4ca35e52da4',
    user_id: '5781d19b2e2385880609791c',
    external_id: 'invoice_123124123',
    is_high: true,
    status: 'COMPLETED',
    merchant_name: 'Xendit',
    amount: 50000,
    billable_amount: 54000,
    taxable_amount: 4000,
    received_amount: 47500,
    payer_email: 'albert@xendit.co',
    description: 'This is a description',
    xendit_fee_amount: 500,
    expiry_date: '2016-08-01T11:20:01.017Z',
    taxes: [
        {
            percentage: 0.1,
            name: 'VAT'
        },
        {
            percentage: -0.02,
            name: 'PPH'
        }
    ],
    fees: [
        {
            percentage: 0.04,
            xendit_user_id: 'XENDIT_FEES',
            name: 'Agent Fee'
        }
    ],
    paid_amount: 54000,
    payment_method: 'POOL',
    adjusted_received_amount: 47500,
    adjusted_xendit_fee_amount: 500,
    updated: '2016-10-10T08:15:03.404Z',
    created: '2016-10-10T08:15:03.404Z'
}");
Response response = client.target("https://api.xendit.co/invoice_callback_url")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("X-CALLBACK-TOKEN", "eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==")
  .post(payload);

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));

When an invoice is paid, our systems will send a callback to the URL configured in the dashboard. For further instruction about callback please read the invoices documentation

This example is only used to show the body parameters that is sent from Xendit APIs to your callback URL. If you want to test this callback request, use the test feature in dashboard and go to Settings -> Configuration -> Accept Payments.

Invoice Callback Request

Example Invoice Callback Request

curl --include \
     --request POST \
     --header "X-CALLBACK-TOKEN: eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==" \
     --header "Content-Type: application/json" \
     --data-binary "{
    id: \"579c8d61f23fa4ca35e52da4\",
    user_id: \"5781d19b2e2385880609791c\",
    external_id: \"invoice_123124123\",
    is_high: true,
    status: \"COMPLETED\",
    merchant_name: \"Xendit\",
    amount: 50000,
    billable_amount: 54000,
    taxable_amount: 4000,
    received_amount: 47500,
    payer_email: \"albert@xendit.co\",
    description: \"This is a description\",
    xendit_fee_amount: 500,
    expiry_date: \"2016-08-01T11:20:01.017Z\",
    taxes: [
        {
            percentage: 0.1,
            name: \"VAT\"
        },
        {
            percentage: -0.02,
            name: \"PPH\"
        }
    ],
    fees: [
        {
            percentage: 0.04,
            xendit_user_id: \"XENDIT_FEES\",
            name: \"Agent Fee\"
        }
    ],
    paid_amount: 54000,
    payment_method: \"POOL\",
    adjusted_received_amount: 47500,
    adjusted_xendit_fee_amount: 500,
    updated: \"2016-10-10T08:15:03.404Z\",
    created: \"2016-10-10T08:15:03.404Z\"
}" \
'https://api.xendit.co/invoice_callback_url'
Parameter Description
id An invoice ID generated by Xendit
user_id Your Xendit Business ID
external_id An ID of your choice we append to all transactions. Often your unique ID like a phone number, email or transaction ID
is_high Should unique numbers go above or below the amount. If true, it would mean a 100.000 invoice would display a unique amount above, e.g. 100.123
status COMPLETED the invoice has successfully been paid
merchant_name The name of your company or website
amount Nominal amount for the invoice (without taxes, fees)
billable_amount Total amount for the invoice (inclusive of all taxes, fees)
taxable_amount The amount that is taxable
received_amount Amount attributable to you net of our fees. Thanks for using us :)
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
xendit_fee_amount Xendit fees - thanks for supporting a better world of payments :)
expiry_date ISO date and time that the invoice expires. We reserve unique numbers only for a specific period of time. After that, we’ll reset with a different number. You can configure this expiry time in dashboard.
taxes
percentage
name
Any taxes you would like to include on your invoices
The percentage of ‘amount’ charge
Name of the tax that will display on the invoice
fees
percentage
xendit_user_id
name
Any additional fees to include on your invoices
The percentage of ‘amount’ to charge (decimal)
The entity’s Xendit user ID
The entity’s name shown on invoices/dashboard
paid_amount Total amount paid for the invoice (inclusive of all taxes, fees)
payment_method The way the invoice is being paid
UNIQUE type is unique amounts
POOL type is nonfixed virtual account
adjusted_received_amount Amount attributable to you net of our fees. Thanks for using us :)
adjusted_xendit_fee_amount Xendit fees - thanks for supporting a better world of payments :)

Invoice Callback Errors

Note that in the case where we don't get a response from your servers, we will retry 5 times with a 10 second delay between each retry. After 5 failures, we get internal alerts that a callback has failed. Our team will then contact you to resolve the issue.

Get banks for virtual accounts

Endpoint: Get Available Banks for Virtual Accounts

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

Example Get Banks for Virtual Accounts Request

curl https://api.xendit.co/available_virtual_account_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->getVirtualAccountBanks();
  print_r($response);
?>

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://api.xendit.co/available_virtual_account_banks")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));

Get Banks for Virtual Accounts Response

Example Get Banks for Virtual Accounts Response

{
  "name": "Bank Central Asia (BCA)",
  "code": "BCA"
}
Parameter Description
name Full name of the bank
code Code of the bank, relevant during creation of virtual accounts

Create fixed virtual accounts

Endpoint: Create Fixed Virtual Account (FVA)

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

Fixed virtual accounts are dedicated virtual accounts under a name you choose, e.g. 'YourCompany - Becca Salim'. You will receive a callback each time this fixed virtual account is paid. These virtual accounts will take up to 24 hours to be commissioned, and will persist until a change is made. Requests made before 4PM Jakarta time (WIB / GMT+7) will be live by 8AM the next business day. Read more about fixed virtual accounts.

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

Create Fixed Virtual Accounts Request

Example Create Fixed 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=BCA \
   -d name='Rika Sutanto'
<?php
  require 'vendor/autoload.php';

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

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

  $external_id = 'demo_1475459775872';
  $bank_code = 'BCA';
  $name = 'Rika Sutanto';

  $response = $xenditPHPClient->createCallbackVirtualAccount($external_id, $bank_code, $name);
  print_r($response);
?>
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Entity payload = Entity.json("{  'external_id': 'user_1212412312',  'bank_code': 'BCA',  'name': 'William Sutanto'}");
Response response = client.target("https://api.xendit.co/callback_virtual_accounts")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==")
  .post(payload);

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
Parameter Description
external_id
required
string ID of the user in your system
bank_code
required
string Bank code of the virtual account you want to create
name
required
string Name of user/virtual account - this will be displayed as is in the UX, e.g. ATM confirmation screens
virtual_account_number
optional
string The virtual account number you want to assign. If you do not send one, one will be picked at random

Create Fixed Virtual Accounts Response

Example Create Fixed Virtual Accounts Response

{
   "owner_id":"57b4e5181473eeb61c11f9b9",
   "external_id":"demo-1475804036622",
   "bank_code":"BCA",
   "merchant_code":"02938",
   "name":"Rika Sutanto",
   "account_number":"029382548",
   "id":"57f6fbf26b9f064272622aa6"
}
Parameter Description
owner_id Your user ID
external_id An ID of your choice we append to all transactions. Often your unique ID like a phone number, email or transaction ID
bank_code Bank code for the relevant bank, e.g. BCA
merchant_code 5-digit merchant prefix to the full virtual account number
name Name for the fixed virtual account
account_number Complete virtual account number (including prefix). This is what a user will need to enter into an ATM or their Internet/mobile banking.
id Unique ID for the fixed virtual account. Can be used to create invoices linked to the FVA.

Create Fixed Virtual Accounts Errors

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.
VIRTUAL_ACCOUNT_NUMBER_OUTSIDE_RANGE
400
The virtual account number you want is outside your range.
BANK_NOT_SUPPORTED_ERROR
400
The bank code is not currently supported.

Fixed virtual account callback

Endpoint: Fixed Virtual Account Callback

POST https://yourcompany.com/virtual_account_paid_callback_url
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Entity payload = Entity.json("{
    id: '57fb4e076fa3fa296b7f5a97',
    payment_id: 'demo-1476087608948_1476087303080',
    callback_virtual_account_id: '57fb4df9af86ce19778ad359',
    owner_id: '57b4e5181473eeb61c11f9b9',
    external_id: 'demo-1476087608948',
    account_number: '1547',
    bank_code: 'BCA',
    amount: 99000,
    transaction_timestamp: '2016-10-10T08:15:03.080Z',
    merchant_code: '02938',
    updated: '2016-10-10T08:15:03.404Z',
    created: '2016-10-10T08:15:03.404Z'
}");
Response response = client.target("https://api.xendit.co/virtual_account_paid_callback_url")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("X-CALLBACK-TOKEN", "eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==")
  .post(payload);

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));

When someone pays into your fixed virtual account, our callback APIs will hit your URL that you already set in dashboard. For further information about callbacks please read these docs.

This example is only used to show the body parameters that send from Xendit APIs to your callback URL and cannot be tested in here. If you want to test this callback request, use the test feature in dashboard and go to settings -> configuration -> fixed virtual account.

Fixed Virtual Account Callback Request

Example Fixed Virtual Account Callback Request

curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "X-CALLBACK-TOKEN: eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==" \
     --data-binary "{
    id: \"57fb4e076fa3fa296b7f5a97\",
    payment_id: \"demo-1476087608948_1476087303080\",
    callback_virtual_account_id: \"57fb4df9af86ce19778ad359\",
    owner_id: \"57b4e5181473eeb61c11f9b9\",
    external_id: \"demo-1476087608948\",
    account_number: \"1547\",
    bank_code: \"BCA\",
    amount: 99000,
    transaction_timestamp: \"2016-10-10T08:15:03.080Z\",
    merchant_code: \"02938\",
    updated: \"2016-10-10T08:15:03.404Z\",
    created: \"2016-10-10T08:15:03.404Z\"
}" \
'https://api.xendit.co/virtual_account_paid_callback_url'
Parameter Description
payment_id Our internal system’s payment ID
callback_virtual_account_id The id field value from the response when the fixed virtual account was created. See Create Fixed Virtual Accounts
owner_id Your user ID
external_id An ID of your choice we append to all transactions. Often your unique ID like a phone number, email or transaction ID
account_number This is the complete virtual account number (including the prefix). This works just like a bank account and is what a user will need to enter in their internet banking/ATM to send funds.
bank_code Bank code for the relevant bank, e.g. BCA
amount Nominal amount to transfer
merchant_code The merchant code will be the prefix for the virtual account number, e.g 01234 your_number
id ID of fixed virtual account payment

Fixed Virtual Account Callback Errors

Note that in the case where we don't get a response from your servers, we will retry 5 times with a 10 second delay between each retry. After 5 failures, we get internal alerts that a callback has failed. Our team will then contact you to resolve the issue.

Disburse Funds

Disbursements are objects to instruct Xendit to instantly send money to any bank account across Indonesia on your behalf.

Create disbursement

Endpoint: Create Disbursement

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

Create Disbursement Request

Example Create Disbursement Request

curl https://api.xendit.co/disbursements -X POST \
   -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
   -H "X-IDEMPOTENCY-KEY: unique-id-12345" \
   -d external_id=demo_1475459775872 \
   -d bank_code=BCA \
   -d account_holder_name='Bob Jones' \
   -d account_number='1231241231' \
   -d description='Reimbursement for shoes' \
   -d amount=17000
<?php
  require 'vendor/autoload.php';

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

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

  $external_id = 'demo_1475459775872';
  $amount = 17000;
  $bank_code = 'BCA';
  $account_holder_name = 'Bob Jones';
  $account_number = '1231241231';

  $response = $xenditPHPClient->createDisbursement($external_id, $amount, $bank_code, $account_holder_name, $account_number);
  print_r($response);
?>
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Entity payload = Entity.json("{  'external_id': 'disbursement_12345',  'amount': 500000,  'bank_code': 'BCA',  'account_holder_name': 'Rizky',  'account_number': '1231241231',  'description': 'Custom description'}");
Response response = client.target("https://api.xendit.co/disbursements")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==")
  .post(payload);

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
Header 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.
Parameter Description
external_id
required
string ID of the disbursement in your system, used to reconcile disbursements after they have been completed
bank_code
required
string Code of the destination bank
account_holder_name
required
string Name of the destination bank account owner
account_number
required
string Number for destination bank account
description
required
string Description to send with the disbursement
amount
required
number Amount to disburse

Create Disbursement Response

Example Create Disbursement Response

{
  "user_id": "5785e6334d7b410667d355c4",
  "external_id": "12345",
  "amount": 1000,
  "bank_code": "BCA",
  "account_holder_name": "RAIDY WIJAYA",
  "disbursement_description": "Refunds for shoes",
  "status": "PENDING",
  "id": "57f1ce05bb1a631a65eee662"
}
Parameter Description
user_id
required
string Your Xendit Business ID
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
amount
required
number Amount to disburse
bank_code
required
string Destination bank code. See bank codes
account_holder_name
required
string Bank account name as per the bank's records. Used for verification and error/customer support scenarios
disbursement_description
required
This is the description you give us :)
status
required
string
PENDING Transfer is initiated but not yet completed by bank.
id
required
string Unique disbursement ID

Create Disbursement Errors

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 Dashboard > Configuration > Disbursement. 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.

Get disbursement

Endpoint: Get Disbursement

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.

Get Disbursement Request

Example Get Disbursement Request

curl https://api.xendit.co/disbursements/57c9010f5ef9e7077bcb96b6 -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);

  $disbursement_id = '587cc7ea77535fb94bb4e8eb';

  $response = $xenditPHPClient->getDisbursement($disbursement_id);
  print_r($response);
?>
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://api.xendit.co/disbursements/{disbursement_id}")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
Parameter Description
disbursement_id
required
string ID of the disbursement to retrieve

Get Disbursement Response

Example Get Disbursement Response

{
  "user_id": "5785e6334d7b410667d355c4",
  "external_id": "disbursement_12345",
  "amount": 500000,
  "bank_code": "BCA",
  "account_holder_name": "Rizky",
  "disbursement_description": "Custom description",
  "status": "PENDING",
  "id": "57c9010f5ef9e7077bcb96b6"
}
Parameter Description
user_id Your Xendit Business ID
external_id Custom ID set at disbursement creation. Our customers often use a phone number, email address, or transaction/order ID
amount Amount to disburse
bank_code Destination bank code. See bank codes
account_holder_name Bank account name as per the bank's records. Used for verification and error/customer support scenarios
disbursement_description This is the description you give us :)
status PENDING Transfer is initiated but not yet completed by bank.
COMPLETED Bank has confirmed transmission of funds.
FAILED Bank rejected disbursement. We will not retry.
id Unique disbursement ID

Get Disbursement Errors

Error Code Description
INVALID_JSON_FORMAT
400
The request body is not a valid JSON format.
INVALID_PERMISSION_ERROR
403
Could not access that disbursement.
DIRECT_DISBURSEMENT_NOT_FOUND_ERROR
404
Could not find direct disbursement.

Disbursement callback

Endpoint: Disbursement Callback

POST https://yourcompany.com/disbursement_callback_url
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Entity payload = Entity.json("{  'id': '57e214ba82b034c325e84d6e',  'user_id': '57c5aa7a36e3b6a709b6e148',  'external_id': 'disbursement_123124123',  'amount': 150000,  'bank_code': 'BCA',  'xendit_fee_amount': 0,  'xendit_fee_user_id': 'XENDIT_FEES',  'account_holder_name': 'XENDIT',  'transaction_id': '57ec8b7e906aa2606ecf8ffc',  'transaction_sequence': '1799',  'disbursement_id': '57ec8b8130d2d0243f438e11',  'disbursement_description': 'Xendit disbursement',  'failure_code': 'INVALID_DESTINATION',  'is_instant': false,  'status': 'FAILED',  'updated': '2016-10-10T08:15:03.404Z',  'created': '2016-10-10T08:15:03.404Z'}");
Response response = client.target("https://api.xendit.co/disbursement_callback_url")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .post(payload);

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));

When a disbursement transaction is successful, our callback APIs will hit your URL that you already set in dashboard. For further information about callbacks please read these docs.

This example is only used to show the body parameters that send from Xendit APIs to your callback URL. If you want to test this callback request, use the test feature in dashboard and go to Settings -> Configuration -> Disbursement.

Disbursement Callback Request

Example Disbursement Callback Request

curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "X-CALLBACK-TOKEN: eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==" \
     --data-binary "{
    \"id\": \"57e214ba82b034c325e84d6e\",
    \"user_id\": \"57c5aa7a36e3b6a709b6e148\",
    \"external_id\": \"disbursement_123124123\",
    \"amount\": 150000,
    \"bank_code\": \"BCA\",
    \"xendit_fee_amount\": 0,
    \"xendit_fee_user_id\": \"XENDIT_FEES\",
    \"account_holder_name\": \"XENDIT\",
    \"transaction_id\": \"57ec8b7e906aa2606ecf8ffc\",
    \"transaction_sequence\": \"1799\",
    \"disbursement_id\": \"57ec8b8130d2d0243f438e11\",
    \"disbursement_description\": \"Xendit disbursement\",
    \"failure_code\": \"INVALID_DESTINATION\",
    \"is_instant\": false,
    \"status\": \"FAILED\",
    \"updated\": \"2016-10-10T08:15:03.404Z\",
    \"created\": \"2016-10-10T08:15:03.404Z\"
}" \
'https://api.xendit.co/disbursement_callback_url'
Parameter Description
is_instant Indicates whether the disbursement is being disbursed instantly
user_id Your Xendit Business ID
external_id Custom ID set at disbursement creation. Our customers often use a phone number, email address, or transaction/order ID
amount Amount to disburse
bank_code Destination bank code. See bank codes
account_holder_name Bank account name as per the bank's records. Used for verification and error/customer support scenarios
disbursement_description This is the description you give us :)
status COMPLETED Bank has confirmed transmission of funds.
FAILED Bank rejected disbursement. We will not retry.
id Unique disbursement ID

Disbursement Callback Errors

Note that in the case where we don't get a response from your servers, we will retry 5 times with a 10 second delay between each retry. After 5 failures, we get internal alerts that a callback has failed. Our team will then contact you to resolve the issue.

Get available disbursement 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);
?>
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://api.xendit.co/available_disbursements_banks")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));

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.

Get Available Disbursement Banks Response

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 Description
name Full name of the bank
code Code of the bank, relevant during creation of virtual accounts

Batch Disbursement (beta)

Batch disbursements 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
Header 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.
Parameter 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 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

Create Batch Disbursement Response

Example Create Disbursement Response

{
  "created": "2017-03-30T06:12:47.212Z",
  "reference": "qwerty1234",
  "total_uploaded_amount": 30000,
  "total_uploaded_count": 2,
  "status": "NEEDS_APPROVAL",
  "id": "58dca1dffee4228917d37336"
}
Parameter 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
NEEDS_APPROVAL Batch disbursement is created but needs to be approved to be processed further
id
required
string Unique ID of batch disbursement in our system

Create Batch Disbursement Errors

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.

Batch disbursement callback

Endpoint: Disbursement Callback

POST https://yourcompany.com/disbursement_callback_url

After creating a batch disbursement via API, to receive a callback, you must log into your Dashboard and do the following steps:

When all disbursements in a batch disbursement has been processed, our system will hit the callback URL that you have already set. We will also give you callback if a batch disbursement has been deleted in the dashboard. Please contact our technical support to set your callback URL.

Disbursement Callback Request

Parameter Description
created Timestamp of batch disbursement creation in ISO format
updated Timestamp of the latest batch disbursement status change in ISO format
reference ID of the batch disbursement in your system, used to reconcile disbursements after they have been completed
total_uploaded_count The count of all disbursements in the batch that you requested
total_uploaded_amount Total amount of all disbursements in the batch that you requested
approved_at Timestamp of batch disbursement approved in ISO format
approver_id User ID of the person who approves the batch disbursement
status 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
id Unique ID of batch disbursement in our system
user_id Your Xendit Business ID
total_error_count The count of all disbursements in the batch that are not successfully paid
total_error_amount Total amount of all disbursements in the batch that are not successfully paid
total_disbursed_count The count of all disbursements in the batch that are succesfully paid
total_disbursed_amount Total amount of all disbursements in the batch that are succesfully paid
disbursements Details of each disbursement in the batch, explained below

Disbursement

Parameter Description
created Timestamp of batch disbursement item creation in ISO format
updated Timestamp of latest batch disbursement status update in ISO format
external_id ID of disbursement from your system
amount Amount to disburse
bank_code Receiving bank code. See bank codes
bank_account_number Receiving bank account number
bank_account_name Receiving bank account holder name
description Description to accompany the disbursement
email_to Email addresses that get notified of disbursement details after the disbursement is completed
email_cc Email addresses that get notified as carbon copy receiver of disbursement details after the disbursement is completed
email_bcc Email addresses that get notified as blind carbon copy receiver of disbursement details after the disbursement is completed
status COMPLETED Disbursement is successfully paid
FAILED Disbursement is not successfully paid
bank_reference Transaction reference number from the bank
valid_name Valid receiving account holder name according to receiving bank
failure_code The error code associated with the failure of disbursement
failure_message The error message associated with the failure of disbursement
id Unique ID of the batch disbursement item in our system

Batch Disbursement Callback Errors

Note that in the case where we don't get a response from your servers, we will retry 5 times with a 10 second delay between each retry. After 5 failures, we get internal alerts that a callback has failed. Our team will then contact you to resolve the issue.

Get available disbursement 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);
?>
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

Client client = ClientBuilder.newClient();
Response response = client.target("https://api.xendit.co/available_disbursements_banks")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .header("Authorization", "Basic eG5kX2RldmVsb3BtZW50X1A0cURmT3NzME9DcGw4UnRLclJPSGphUVlOQ2s5ZE41bFNmaytSMWw5V2JlK3JTaUN3WjNqdz09Og==")
  .get();

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));

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.

Get Available Disbursement Banks Response

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 Description
name Full name of the bank
code Code of the bank, relevant during creation of virtual accounts

Name Validator

Endpoint: Validate Name

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

Example Name Validator Request

curl https://api.xendit.co/bank_account_data_requests \
    -X POST \
    -u xnd_development_O46JfOtygef9kMNsK+ZPGT+ZZ9b3ooF4w3Dn+R1k+2fT/7GlCAN3jg==: \
    -d bank_account_number="1550001953382" \
    -d bank_code="MANDIRI"
<?php
  require 'vendor/autoload.php';

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

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

  $bank_account_number = '1550001953382';
  $bank_code = 'MANDIRI';

  $response = $xenditPHPClient->validateBankAccountHolderName($bank_account_number, $bank_code);
  print_r($response);
?>

The Name Validator can be used to look up the name of an account holder for any bank account in Indonesia. Because it can take a few seconds to look up the name with the banks, the result is returned in a callback. Be sure to have a callback URL configured for Bank account data in the Xendit Dashboard Configuration.

Name Validator Request

Parameter Description
bank_account_number string (required)
The bank account number
bank_code string (required)
The bank code. See Bank Codes

Name Validator Response

Name Validator Response (Uncached)

{}

Example Name Validator Response (Cached)

{
  "bank_account_number": "1234567899",
  "bank_account_holder_name": "JOE CONTINI",
  "bank_code": "MANDIRI",
  "reference": "58cd618ba0464eb64acdb246",
  "status": "SUCCESS",
  "updated": "2017-03-24T08:11:07.624Z"
}

If this bank account number has not been previously cached by Xendit, the response will be a blank JSON object. If the account number has been validated previously, the name will be cached and the response returned immediately.

Name Validator Errors

Error Code Description
MAX_RETRY_TIMES_EXCEED_ERROR
400
Our system has retry the request for several times but still failed because of an unknown error response from the bank.
UNSUPPORTED_DESTINATION_BANK_ERROR
400
Destination bank is not supported, request is using the wrong bank code.
RECIPIENT_NOT_FOUND_ERROR
404
There’s no bank recipient with this account number.
UNSUPPORTED_BANK_CODE_ERROR
404
There’s no bank recipient with this account number.

Example Name Validator Callback

{
  "bank_account_number": "1234567899",
  "bank_account_holder_name": "JOE CONTINI",
  "bank_code": "MANDIRI",
  "status": "SUCCESS",
  "updated": "2017-03-24T08:11:07.624Z"
}

Name Validator Callback Payload

Parameter Description
bank_code string (required)
The bank code. See Bank Codes
bank_account_number string (required)
The bank account number
bank_name string (required)
The bank name. See Bank Codes
bank_account_holder_name string (required)
Account Holder Name
status string (required)
Status of the Name Validation request.

Errors

Below are some of most common errors across all our endpoints. Specific errors are located under each endpoint. If you have any questions please contact us.

Error code Meaning
400 Bad request, e.g. validation error
401 Unauthorised access, e.g. the wrong API key
403 Forbidden access, e.g. API key does not have permission for this endpoint
404 Page or data not found
500 Unhandled error - contact us when this happens

Postman Collection

Postman is a HTTP client for testing web services which makes it easy to test APIs by providing a simple interface for making API requests & viewing responses. To make integrating with our API's easier, we've created a Postman collection of our APIs for easy testing.

To use our APIs, you'll need a free Xendit Dashboard account. To follow this guide, be sure to have Postman installed.

Import Collection

  1. Download API-Xendit.postman_collection.json and save it to your computer.
  2. In postman, click the Import button in the upper left.
  3. Select the API-Xendit.postman_collection.json collection that was just saved.
  4. The Collections tab should now show the Xendit collection!

Create Authorization Header

The Xendit Collection is built to take advantage of Postman Environments, which allows for easy switching between Development and Live keys. To use Environments, you'll first need to convert your Xendit Secret Key to a Base64-encoded Authorization header. Postman provides an easy way to do this:

Example API Key

xnd_development_NIiBfOQn1+T8wJVpK+UaHTGABCPwp4EauXTo+R1k9GLW/rakCgZzgw==
  1. In Xendit Dashboard, navigate to Settings > API Keys
  2. Under Development Keys > Secret Key, click 'Copy Key'
  3. In Postman, make a new tab in and click the Authorization tab
  4. Choose Basic Auth from the Type dropdown
  5. Paste your Secret Key into the Username
  6. Click the orange Update Request button
  7. Click the Headers tab
  8. Copy the newly created value from the Authorization key

Example Authorization Header

Basic eG5kX2RldmVsb3BtZW50X05JaUJmT1FuMStUOHdKVnBLK1VhSFRHQUJDUHdwNEVhdVhUbytSMWs5R0xXL3Jha0NnWnpndz09Og==

Creating Environment

  1. In Postman on the upper right, click the gear icon > Manage Environments.
  2. Click the Add button to create a new environment.
  3. Give it a name like Xendit Testing
  4. Add Authorization and api-xendit headers (see table below)
  5. Click the Add button to save
  6. In the upper right, select your new Xendit Testing environment. Image
key value
Authorization Your Authorization header
api-xendit https://api.xendit.co

Image

Testing

If you can query your balance successfully, you've got it all set up! See our implementation docs for more testing on: