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.
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 inusername
and leave thepassword
empty
Basic Auth format
{{username}}:{{password}}
Following the format (with colon)
xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==:
Encode
Basic Auth
format above intoBase64
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:
- Generate secret API key
- Obtain your secret API key from Dashboard
- Select Basic Access Authentication or
BASIC AUTH
authentication BASIC AUTH
format will be{{username}}:{{password}}
- Input Secret API key as
username
and leave thepassword
empty. Make sure to include:
at the end - Encode the value above into Base64 format
- 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
- Credit / Debit cards (via Payments API)
- E-Wallets (via Payments API)
- QR Codes (via Payments API)
- Direct Debit (via Payments API)
- Bank Transfer / Virtual Accounts (via Payments API)
- Retail Outlets (via Payments API)
- Invoices
- Payouts
- 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:
- Tokenize credit/debit cards with single-use token
- Tokenize credit/debit cards with multiple-use token
- 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:
- Tokenize credit/debit cards with single-use token
- Tokenize credit/debit cards with multiple-use token
- 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:
- Adding new API resources
- Adding new optional request parameters to existing API methods
- Adding new properties to existing API responses
- Changing the order of properties in existing API responses
- Changing the length or format of any object IDs
- Adding new error codes
- Adding new webhook event types
- Adding new properties to webhook payloads
Migration Guide
The following guide will help you to migrate from your current version to latest version safely
- 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 - 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 - Repeat #1 and #2 respectively in Live mode
- 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:
- 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.
- 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. - 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.
- 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:
- Content errors occur because the content in the API request was invalid in some way. They return an HTTP response with a
4xx
error code. For example, the API servers might return a401
if an invalid API key was provided, or a400
if a required parameter was missing - Network errors occur as a result of intermittent communication problems between client and server. They return low-level errors, like socket or timeout exceptions. For example, a client might time out while trying to read from Xendit's servers, or an API response might never be received because a connection terminates prematurely. Note that a network errors wouldn't necessarily have otherwise been a successful request --- it can also be another type of error that's been cloaked by an intermittent problem
- Server errors occur because of a problem on Xendit's servers. Server errors return an HTTP response with a
5xx
error code. Xendit works to make these errors as rare as posslble, but integrations should be able to handle them when they do arise
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 |
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:
- Use an algorithm that generates a token with good randomness, like UUID v4
- Derive the key from a user-attached object like the ID of a shopping cart. This provides a relatively easy way to protect against double submissions
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-idoptional |
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:
- A Type of customer (Individual or Business)
- Basic descriptive details of that customer
- Addresses of the customer
- Identity accounts and KYC documents to prove the legitimacy of the customer
- Other metadata
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_idrequired |
string |
Merchant-provided identifier for the customer | ||||||||||||||||||||||||||||||||||||||||||||||||
typerequired |
string |
Type of customer. Supported values: INDIVIDUAL , BUSINESS |
||||||||||||||||||||||||||||||||||||||||||||||||
individual_detailoptional |
object |
JSON object containing details of the individual. Will be null if type is not INDIVIDUAL
Individual detail child parameters
|
||||||||||||||||||||||||||||||||||||||||||||||||
business_detailoptional |
object |
JSON object containing details of the business. Will be null if type is not BUSINESS
Business detail child parameters
|
||||||||||||||||||||||||||||||||||||||||||||||||
mobile_numberoptional |
string |
Mobile number of customer in E.164 format
|
||||||||||||||||||||||||||||||||||||||||||||||||
phone_numberoptional |
string |
Additional contact number of customer in E.164 format. May be a landline
|
||||||||||||||||||||||||||||||||||||||||||||||||
hashed_phone_numberoptional |
string |
Hashed phone number
|
||||||||||||||||||||||||||||||||||||||||||||||||
emailoptional |
string |
E-mail address of customer
|
||||||||||||||||||||||||||||||||||||||||||||||||
addressesoptional |
array |
Array of address JSON objects containing the customer's various address information.Addresses child parameters
|
||||||||||||||||||||||||||||||||||||||||||||||||
identity_accountsrequired |
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
|
||||||||||||||||||||||||||||||||||||||||||||||||
kyc_documentsrequired |
array |
Array of JSON objects with documents collected for KYC of this customer. KYC documents child parameters
|
||||||||||||||||||||||||||||||||||||||||||||||||
descriptionoptional |
string |
Merchant-provided description for the customer.
|
||||||||||||||||||||||||||||||||||||||||||||||||
date_of_registrationoptional |
string |
Date of which the account that the shopper had to create/sign up on the merchant’s website
|
||||||||||||||||||||||||||||||||||||||||||||||||
domicile_of_registrationoptional |
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.
|
||||||||||||||||||||||||||||||||||||||||||||||||
metadataoptional |
object |
Object of additional information as provided in customer creation | ||||||||||||||||||||||||||||||||||||||||||||||||
createdrequired |
string |
Timestamp of customer creation in ISO format | ||||||||||||||||||||||||||||||||||||||||||||||||
updatedrequired |
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-KEYoptional |
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.
|
API-VERSIONoptional |
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-idoptional |
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_idrequired |
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.
|
||||||||||||||||||||||||||||||||||||||||||||||||
typerequired |
string |
Type of customer. Supported values: INDIVIDUAL , BUSINESS |
||||||||||||||||||||||||||||||||||||||||||||||||
individual_detailconditionally required |
object |
JSON object containing details of the individual. Required if type is INDIVIDUAL
Individual detail child parameters
|
||||||||||||||||||||||||||||||||||||||||||||||||
business_detailconditionally required |
object |
JSON object containing details of the business. Required if type is BUSINESS
Business detail child parameters
|
||||||||||||||||||||||||||||||||||||||||||||||||
mobile_numberoptional |
string |
Mobile number of customer in E.164 format
|
||||||||||||||||||||||||||||||||||||||||||||||||
phone_numberoptional |
string |
Additional contact number of customer in E.164 format. May be a landline
|
||||||||||||||||||||||||||||||||||||||||||||||||
hashed_phone_numberoptional |
string |
Hashed phone number
|
||||||||||||||||||||||||||||||||||||||||||||||||
emailoptional |
string |
E-mail address of customer
|
||||||||||||||||||||||||||||||||||||||||||||||||
addressesoptional |
array |
Array of address JSON objects containing the customer's various address information.Addresses child parameters
|
||||||||||||||||||||||||||||||||||||||||||||||||
identity_accountsoptional |
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
|
||||||||||||||||||||||||||||||||||||||||||||||||
kyc_documentsoptional |
array |
Array of JSON objects with documents collected for KYC of this customer. KYC documents child parameters
|
||||||||||||||||||||||||||||||||||||||||||||||||
descriptionoptional |
string |
Merchant-provided description for the customer.
|
||||||||||||||||||||||||||||||||||||||||||||||||
date_of_registrationoptional |
string |
Date of which the account that the shopper had to create/sign up on the merchant’s website
|
||||||||||||||||||||||||||||||||||||||||||||||||
domicile_of_registrationoptional |
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.
|
||||||||||||||||||||||||||||||||||||||||||||||||
metadataoptional |
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_ERROR409 |
The provided reference_id has been used before. Please enter a unique reference_id . |
IDEMPOTENCY_ERROR409 |
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-VERSIONoptional |
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-idoptional |
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_FOUND404 |
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_idrequired |
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-VERSIONoptional |
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-idoptional |
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-VERSIONoptional |
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-idoptional |
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_detailoptional |
object |
JSON object containing details of the individual. Will fail API validation if type is not INDIVIDUAL
Individual detail child parameters
|
||||||||||||||||||||||||||||||||||||||||||||||||
business_detailoptional |
object |
JSON object containing details of the business. Will fail API validation if type is not BUSINESS
Business detail child parameters
|
||||||||||||||||||||||||||||||||||||||||||||||||
mobile_numberoptional |
string |
Mobile number of customer in E.164 format
|
||||||||||||||||||||||||||||||||||||||||||||||||
phone_numberoptional |
string |
Additional contact number of customer in E.164 format. May be a landline
|
||||||||||||||||||||||||||||||||||||||||||||||||
emailoptional |
string |
E-mail address of customer
|
||||||||||||||||||||||||||||||||||||||||||||||||
addressesoptional |
array |
Array of address JSON objects containing the customer's various address information.Addresses child parameters
|
||||||||||||||||||||||||||||||||||||||||||||||||
identity_accountsoptional |
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
|
||||||||||||||||||||||||||||||||||||||||||||||||
kyc_documentsoptional |
array |
Array of JSON objects with documents collected for KYC of this customer. KYC documents child parameters
|
||||||||||||||||||||||||||||||||||||||||||||||||
descriptionoptional |
string |
Merchant-provided description for the customer.
|
||||||||||||||||||||||||||||||||||||||||||||||||
date_of_registrationoptional |
string |
Date of which the account that the shopper had to create/sign up on the merchant’s website
|
||||||||||||||||||||||||||||||||||||||||||||||||
domicile_of_registrationoptional |
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.
|
||||||||||||||||||||||||||||||||||||||||||||||||
metadataoptional |
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_FOUND404 |
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 |
---|---|---|
purposerequired |
string |
Purpose of the file being uploaded Supported values: KYC_DOCUMENT , CHARGEBACK_EVIDENCE |
filerequired |
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 |
---|---|---|
idrequired |
string |
Unique ID generated by Xendit for the particular file |
business_idrequired |
string |
Your Xendit business id |
purposerequired |
string |
Purpose of the file |
createdrequired |
string |
UTC Timestamp of file upload in ISO format |
updatedrequired |
string |
UTC Timestamp of last file update in ISO format |
typerequired |
string |
Type of the file |
sizerequired |
integer |
Size of the file in bytes |
urlrequired |
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_LARGE413 |
The file size is greater than 2000000 bytes and exceeded size limits. Please compress the payload before retrying |
UNSUPPORTED_CONTENT_TYPE415 |
The file format is not supported. Please review the file type before retrying |
REQUEST_FORBIDDEN403 |
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 |
---|---|---|
idrequired |
string |
Unique ID generated by Xendit for the particular file |
business_idrequired |
string |
Your Xendit business id |
purposerequired |
string |
Purpose of the file |
createdrequired |
string |
UTC Timestamp of file upload in ISO format |
updatedrequired |
string |
UTC Timestamp of last file update in ISO format |
typerequired |
string |
Type of the file |
sizerequired |
integer |
Size of the file in bytes |
urlrequired |
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 |
---|---|---|
idrequired |
string |
Unique ID generated by Xendit for the particular file |
business_idrequired |
string |
Your Xendit business id |
is_deletedrequired |
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:
| ||||||||
filter required |
object |
Filtering that are applied to report.Filter Parameter
|
||||||||
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.
|
||||||||
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-idoptional |
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:
| ||||||||||
filter required |
object |
Filtering that are applied to report. Filter Parameter
The combination of from and to must be less than 31 days. |
||||||||||
format optionaldefault:
|
string |
The format of the report. Available format is CSV . |
||||||||||
currency optionaldefault:
|
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: |
Response Parameters
Return Report Object with status code 201
Error Codes
See other common errors here.
Error Code | Description |
---|---|
FEATURE_NOT_AVAILABLE400 |
During this beta, some of customer may encounter this error. Please contact our customer support to enable this feature. |
INVALID_DATE_RANGE400 |
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-idoptional |
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_FOUND404 |
Report the id is not found. |
FEATURE_NOT_AVAILABLE400 |
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:
| ||||||
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
|
||||||||||||||||||||||||
Line Type | List of available line type
|
||||||||||||||||||||||||
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 |
|
||||||||||||||||||||||||
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
|
||||||||||||||
Type | The corresponding transaction type
|
||||||||||||||
Channel | The channel to identify the source of the transaction. The available channel for each type are:
|
||||||||||||||
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:
| ||||||||||||||||||||||
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:
| channel_category required |
string |
The channel category of the transaction to identify the source of the transaction. The available channel for each type are:
|
|||||||||||||||||||
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 |
| ||||||||||||||||||||||
settlement_status optional |
string |
|
||||||||||||||||||||||
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-idoptional |
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_FOUND404 |
Transaction with the id is not found. |
FEATURE_NOT_AVAILABLE400 |
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-idoptional |
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 optionaldefault:
|
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 optionaldefault:
|
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_AVAILABLE400 |
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:
- Payments API Introduction
- Payments API Object
- Payments API Endpoints
- Payments Scenario
- Tokenized Payment Scenario
- Link and Pay Payment Scenario
Download "New Payments API" Postman Collection to explore and test our APIs
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
Body Parameter | Type | Description | |||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
partnerReferenceNooptional |
string |
Transaction identifier on service consumer system | |||||||||||||||||||||||||||||
additionalDataconditionally required |
object |
Channel specific information required for the transaction to be initiated Conditional for BRI
|
|||||||||||||||||||||||||||||
merchantIdoptional |
string |
Xendit-generated identifier for the business that owns the transaction. This field is ignored by Xendit | |||||||||||||||||||||||||||||
phoneNooptional |
string |
Registered mobile number of the end-customer to the channel partner in E.164 Format. Mandatory for: OVO (ONE_TIME_USE) BRI | |||||||||||||||||||||||||||||
additionalInforequired |
object |
Additional information required to complete the transaction Object parameters details
|
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 | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
responseCoderequired |
string |
Response code | ||||||||||||||||||||||||||||||||||||||||||||
responseMessagerequired |
string |
Response description | ||||||||||||||||||||||||||||||||||||||||||||
referenceNorequired |
string |
Unique identifier for the payment method. This has a prefix of pm- | ||||||||||||||||||||||||||||||||||||||||||||
partnerReferenceNooptional |
string |
Merchant-provided identifier for this specific transaction. | ||||||||||||||||||||||||||||||||||||||||||||
nextActionoptional |
string |
URL to authentication page. | ||||||||||||||||||||||||||||||||||||||||||||
paramsoptional |
object |
Object parameters details
|
||||||||||||||||||||||||||||||||||||||||||||
userInfooptional |
object |
Object parameters details
|
||||||||||||||||||||||||||||||||||||||||||||
additionalInforequired |
object |
Payment method object details
|
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
Body Parameter | Type | Description |
---|---|---|
partnerReferenceNooptional |
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 | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
responseCoderequired |
string |
Response code | ||||||||||||||||||||||||||||||||||||||||||||
responseMessagerequired |
string |
Response description | ||||||||||||||||||||||||||||||||||||||||||||
referenceNooptional |
string |
Unique identifier for the payment method. This has a prefix of pm- | ||||||||||||||||||||||||||||||||||||||||||||
partnerReferenceNooptional |
string |
Merchant-provided identifier for this specific transaction. | ||||||||||||||||||||||||||||||||||||||||||||
accountCurrencyrequired |
string |
Always set to 'IDR'. | ||||||||||||||||||||||||||||||||||||||||||||
accountNameoptional |
string |
Registered account name. | ||||||||||||||||||||||||||||||||||||||||||||
additionalInforequired |
object |
Payment method object details
|
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
Body Parameter | Type | Description |
---|---|---|
partnerReferenceNooptional |
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 | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
responseCoderequired |
string |
Response code | ||||||||||||||||||||||||||||||||||||||||||||
responseMessagerequired |
string |
Response description | ||||||||||||||||||||||||||||||||||||||||||||
referenceNooptional |
string |
Unique identifier for the payment method. This has a prefix of pm- | ||||||||||||||||||||||||||||||||||||||||||||
partnerReferenceNooptional |
string |
Merchant-provided identifier for this specific transaction. | ||||||||||||||||||||||||||||||||||||||||||||
accountCurrencyrequired |
string |
Always set to 'IDR'. | ||||||||||||||||||||||||||||||||||||||||||||
accountNameoptional |
string |
Registered account name. | ||||||||||||||||||||||||||||||||||||||||||||
additionalInforequired |
object |
Payment method object details
|
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
Body Parameter | Type | Description |
---|---|---|
originalReferenceNorequired |
string |
Xendit Generated ID for the payment method |
otprequired |
string |
The authorization code or OTP inputted by the end customer |
typerequired |
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 |
---|---|---|
responseCoderequired |
string |
Response code |
responseMessagerequired |
string |
Response description |
originalReferenceNooptional |
string |
Unique identifier for the payment method. Prefix will vary according to the payment method used. |
originalPartnerReferenceNooptional |
string |
Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions. |
customerIdoptional |
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
FOR-USER-IDoptional |
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-RULEoptional |
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 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
partnerServiceIdoptional |
string |
This field is ignored by Xendit. | ||||||||||
customerNooptional |
string |
This field is ignored by Xendit. | ||||||||||
virtualAccountNooptional |
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. | ||||||||||
virtualAccountNamerequired |
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. |
||||||||||
trxIdrequired |
string |
Merchant-provided identifier for this specific transaction. Please note that this field needs to be unique for each Virtual Account. | ||||||||||
totalAmountconditionally 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
|
||||||||||
freeTextsoptional |
array of object |
Xendit will concatenate all text entries in this section to form the Virtual Account description. Free text objects
|
||||||||||
expiredDateoptional |
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 | ||||||||||
additionalInforequired |
object |
Additional information required to complete the transaction Object parameters details
|
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
responseCoderequired |
string |
Response code | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
responseMessagerequired |
string |
Response description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
virtualAccountDataoptional |
object |
Only for successful responses
|
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
FOR-USER-IDoptional |
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-RULEoptional |
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 |
---|---|---|
partnerServiceIdoptional |
string |
This field is ignored by Xendit. |
customerNooptional |
string |
This field is ignored by Xendit. |
virtualAccountNooptional |
string |
This field is ignored by Xendit. |
trxIdrequired |
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
responseCoderequired |
string |
Response code | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
responseMessagerequired |
string |
Response description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
virtualAccountDataoptional |
object |
Only for successful responses
|
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
FOR-USER-IDoptional |
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-RULEoptional |
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 | ||||||
---|---|---|---|---|---|---|---|---|
partnerServiceIdoptional |
string |
This field is ignored by Xendit. | ||||||
customerNooptional |
string |
This field is ignored by Xendit. | ||||||
virtualAccountNamerequired |
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. |
||||||
totalAmountconditionally 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
|
||||||
freeTextsoptional |
array of object |
Xendit will concatenate all text entries in this section to form the Virtual Account description. Free text objects
|
||||||
expiredDateoptional |
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 | ||||||
additionalInforequired |
object |
Additional information required to complete the transaction Object parameters details
|
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
responseCoderequired |
string |
Response code | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
responseMessagerequired |
string |
Response description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
virtualAccountDataoptional |
object |
Only for successful responses
|
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
FOR-USER-IDoptional |
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-RULEoptional |
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 |
---|---|---|
partnerServiceIdoptional |
string |
This field is ignored by Xendit. |
customerNooptional |
string |
This field is ignored by Xendit. |
virtualAccountNooptional |
string |
This field is ignored by Xendit. |
trxIdrequired |
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
responseCoderequired |
string |
Response code | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
responseMessagerequired |
string |
Response description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
virtualAccountDataoptional |
object |
Only for successful responses
|
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-idrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
x-external-idrequired |
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-idrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
x-signaturerequired |
string |
Non-repudiation signature for the request. See this article for more info. |
x-timestamprequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
Notifications Payload Object
Payload Object Parameter | Type | Description | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
partnerServiceIdrequired |
string |
This field is ignored by Xendit. | ||||||||||||||||||||||||||||||||||||
customerNorequired |
string |
This field is ignored by Xendit. | ||||||||||||||||||||||||||||||||||||
virtualAccountNorequired |
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. | ||||||||||||||||||||||||||||||||||||
virtualAccountNamerequired |
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. |
||||||||||||||||||||||||||||||||||||
trxIdrequired |
string |
Merchant-provided identifier for this specific transaction. Please note that this field needs to be unique for each Virtual Account. | ||||||||||||||||||||||||||||||||||||
paidAmountrequired |
object |
Actual paid amount Conditional for Closed Virtual amounts
|
||||||||||||||||||||||||||||||||||||
trxDateTimerequired |
string |
Timestamp in ISO 8601 format when the PaymentRequest was created. Example: 2020-08-29T09:12:33.001Z | ||||||||||||||||||||||||||||||||||||
referenceNorequired |
string |
The payment ID that can be used for reconciliation | ||||||||||||||||||||||||||||||||||||
freeTextsoptional |
array of object |
Xendit will concatenate all text entries in this section to form the Virtual Account description. Free text objects
|
||||||||||||||||||||||||||||||||||||
additionalInforequired |
object |
Additional information required to complete the transaction
|
Key | Value | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
paymentIdrequired |
string Internal payment ID in Xendit system |
||||||||||
countryoptional |
string 2-letter ISO 3166-2 country code indicating country of transaction. |
||||||||||
statusrequired |
string Status of the payment. Allowed values: SUCCEEDED , FAILED
|
||||||||||
createdoptional |
string Timestamp in ISO 8601 format when the PaymentRequest was created. |
||||||||||
updatedoptional |
string Timestamp in ISO 8601 format when the PaymentRequest was last updated. Example: 2020-08-29T09:12:33.001Z |
||||||||||
senderNameoptional |
string Name of the end user that paid into the Virtual Account. This field is only supported for BSS VA |
||||||||||
paymentDetailoptional |
Additional information from the bank.
|
Key | Value |
---|---|
remarkoptional |
string A remark that is inputted by the payer when they are about to make a payment, only supported for BSS. |
referenceoptional |
string Reference number from the bank that can be used for reconciliation, only supported for BCA with switcher commercial model. |
optional
object
A free-format JSON for additional information that you may use. required
object
parameters details
Key | Value |
---|---|
idrequired |
string The Virtual Account ID. |
reusabilityrequired |
string The Virtual Account type. Allowed values: ONE_TIME_USE , MULTIPLE_USE
|
channelCodeoptional |
string Identifier for the payment channel partner. Allowed values: BCA , BSI , BJB , CIMB SAHABAT_SAMPOERNA , ARTAJASA , BRI , BNI , MANDIRI , PERMATA
|
trxIdrequired |
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
FOR-USER-IDoptional |
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-RULEoptional |
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 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
partnerReferenceNooptional |
string |
Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions. | ||||||||||
amountconditionally required |
object |
Amount of the transaction. This is required for ONE_TIME_USE QR and will be ignored for MULTIPLE_USE QR. Conditional for
|
Key | Value |
---|---|
valuerequired |
string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00 |
currencyrequired |
string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed. |
required
object
Object parameters details
Key | Value |
---|---|
reusabilityrequired |
string Describes whether or not the QR Code can be reused for only one or multiple payments. Allowed values: ONE_TIME_USE , MULTIPLE_USE
|
paymentMethodReferenceIdoptional |
string Merchant-provided identifier for the created payment method. If not specified, Xendit will generate random unique id for this field. |
metadataoptional |
string Date when the QR will be expired. Format: ISO-8601. |
metadataoptional |
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 | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
responseCoderequired |
string |
Response code | ||||||||||||||||||
responseMessagerequired |
string |
Response description | ||||||||||||||||||
referenceNorequired |
string |
Unique identifier for the payment request. Prefix will vary according to the payment method used. | ||||||||||||||||||
partnerReferenceNooptional |
string |
Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions. | ||||||||||||||||||
qrContentrequired |
string |
QR string to be rendered for display to end users. | ||||||||||||||||||
additionalInforequired |
object |
Additional information required to complete the transaction Object parameters details
|
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
FOR-USER-IDoptional |
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 |
---|---|---|
originalPartnerReferenceNooptional |
string |
Original transaction identifier on service consumer system. Either originalReferenceNo or originalPartnerReferenceNo must present in the request. |
originalReferenceNooptional |
string |
Xendit Generated ID for the payment request. Either this or referenceNo must be provided. originalPartnerReferenceNo must present in the request. |
serviceCoderequired |
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 | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
responseCoderequired |
string |
Response code | ||||||||||||||||||||
responseMessagerequired |
string |
Response description | ||||||||||||||||||||
originalReferenceNooptional |
string |
Unique identifier for the payment request. Prefix will vary according to the payment method used. | ||||||||||||||||||||
originalPartnerReferenceNooptional |
string |
Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions. | ||||||||||||||||||||
serviceCoderequired |
string |
Set to '47' | ||||||||||||||||||||
latestTransactionStatusrequired |
string |
Latest transaction status. Allowed values: 00 , 03 , 04 , 06 |
||||||||||||||||||||
transactionStatusDescoptional |
string |
Description status transaction | ||||||||||||||||||||
amountconditionally required |
object |
Amount of the transaction Object information
|
||||||||||||||||||||
additionalInforequired |
object |
Additional information required to complete the transaction Object parameters details
|
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-idrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
x-external-idrequired |
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-idrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
x-signaturerequired |
string |
Non-repudiation signature for the request. See this article for more info. |
x-timestamprequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
Notifications Payload Object
Payload Object Parameter | Type | Description | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
originalReferenceNorequired |
string |
Unique identifier for the payment request. Prefix will vary according to the payment method used. | ||||||||||||||
originalPartnerReferenceNooptional |
string |
Merchant-provided identifier for this specific transaction. | ||||||||||||||
latestTransactionStatusrequired |
string |
Latest transaction status of the payment. Allowed values: 00 , 06 |
||||||||||||||
transactionStatusDescrequired |
string |
Description status transaction | ||||||||||||||
amountrequired |
object |
Actual paid amount Object information
|
||||||||||||||
additionalInforequired |
object |
Additional information about the QR payment
|
Key | Value |
---|---|
idrequired |
string Unique identifier for the payment. |
paymentMethodIdrequired |
string Unique identifier for the payment method. |
paymentMethodReferenceIdrequired |
string Merchant-provided identifier for this payment method. If it's not provided, xendit will generate unique identifier for the merchant. |
createdoptional |
string Timestamp in ISO 8601 format when the PaymentRequest was created. |
updatedoptional |
string Timestamp in ISO 8601 format when the PaymentRequest was last updated. Example: 2020-08-29T09:12:33.001Z |
metadataoptional |
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
FOR-USER-IDoptional |
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-RULEoptional |
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 | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
partnerReferenceNorequired |
string |
Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions. | ||||||||||||||||||||||||||
amountconditionally required |
object |
Amount of the transaction. This is required for ONE_TIME_USE QR and will be ignored for MULTIPLE_USE QR. Conditional for
|
Key | Value |
---|---|
valuerequired |
string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00 |
currencyrequired |
string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed. |
optional
array
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 |
---|---|
urlrequired |
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) |
typerequired |
string URL Type. Allowed values: PAY_RETURN , FAILURE_RETURN , CANCEL_RETURN
|
isDeeplinkoptional |
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. |
conditionally required
array
Object Information for each array item
Key | Value | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
payMethodrequired |
string Type of payment method. Allowed values: EWALLET , DIRECT_DEBIT |
||||||||||||||||||
payOptionrequired |
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 |
||||||||||||||||||
additionalInfoconditionally required |
object Required for OVO one time payment, BRI , JENIUSPAY
Object Information
|
optional
object
Object parameters details
Key | Value | ||||||
---|---|---|---|---|---|---|---|
customerIdrequired |
string Xendit-generated identifier for the end-customer. Will be required for certain payment channels such as Multiple-use e-wallets and direct debit. |
||||||
paymentMethodIdoptional |
string The id of a previously stored PaymentMethod to be used in this transaction. Mandatory if payOptionDetails is not specified. |
||||||
channelPropertiesoptional |
object Additional parameters based on payment channel Object parameters details
|
||||||
descriptionoptional |
string Free-text field for any additional information regarding the payment request. |
||||||
metadataoptional |
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 | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
responseCoderequired |
string |
Response code | ||||||||||||||||||||||
responseMessagerequired |
string |
Response description | ||||||||||||||||||||||
referenceNooptional |
string |
Unique identifier for the payment request. Prefix will vary according to the payment method used. | ||||||||||||||||||||||
partnerReferenceNooptional |
string |
Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions. | ||||||||||||||||||||||
approvalCodeoptional |
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. | ||||||||||||||||||||||
appRedirectUrloptional |
string |
The provided redirect url utilizes deep linking to the channel partner’s platform. | ||||||||||||||||||||||
webRedirectUrloptional |
string |
The provided redirect url is optimized for desktop or web interface. | ||||||||||||||||||||||
additionalInfooptional |
object |
Additional information for the transaction Object parameters details
|
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
FOR-USER-IDoptional |
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 |
---|---|---|
originalPartnerReferenceNooptional |
string |
Original transaction identifier on service consumer system. Either this field or originalReferenceNo must be provided |
originalReferenceNooptional |
string |
Xendit Generated ID for the payment request. Either this field or originalPartnerReferenceNo must be provided |
serviceCoderequired |
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 | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
responseCoderequired |
string |
Response code | ||||||||||||||||||||||||||||||||||||||||||||
responseMessagerequired |
string |
Response description | ||||||||||||||||||||||||||||||||||||||||||||
originalReferenceNooptional |
string |
Unique identifier for the payment request. Prefix will vary according to the payment method used. | ||||||||||||||||||||||||||||||||||||||||||||
originalPartnerReferenceNooptional |
string |
Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions. | ||||||||||||||||||||||||||||||||||||||||||||
serviceCoderequired |
string |
Set to '54' | ||||||||||||||||||||||||||||||||||||||||||||
latestTransactionStatusrequired |
string |
Latest transaction status. Allowed values: 00 , 01 , 02 , 03 , 04 , 05 , 06 , 07 |
||||||||||||||||||||||||||||||||||||||||||||
transactionStatusDescoptional |
string |
Description status transaction | ||||||||||||||||||||||||||||||||||||||||||||
transAmountconditionally required |
object |
Amount of the transaction Object information
|
||||||||||||||||||||||||||||||||||||||||||||
additionalInfooptional |
object |
Additional information for the transaction Object parameters details
|
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
Body Parameter | Type | Description | ||||||
---|---|---|---|---|---|---|---|---|
originalPartnerReferenceNooptional |
string |
Original transaction identifier on service consumer system. Either this field or originalReferenceNo must be provided | ||||||
originalReferenceNooptional |
string |
Xendit Generated ID for the payment request. Either this field or originalPartnerReferenceNo must be provided | ||||||
partnerRefundNooptional |
string |
Merchant-provided identifer for the refund request. If none is provided, a unique randomly generated string will be assigned. | ||||||
refundAmountconditionally 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
|
Key | Value |
---|---|
valuerequired |
string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00 |
currencyrequired |
string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed. |
optional
string
FRAUDULENT
, DUPLICATE
, REQUESTED_BY_CUSTOMER
, CANCELLATION
, OTHERS
optional
object
Object parameters details
Key | Value |
---|---|
metadataoptional |
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 | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
responseCoderequired |
string |
Response code | ||||||||||||||||||
responseMessagerequired |
string |
Response description | ||||||||||||||||||
originalReferenceNooptional |
string |
Unique identifier for the payment request. Prefix will vary according to the payment method used. | ||||||||||||||||||
refundNooptional |
string |
Xendit-generated identifier for the refund request | ||||||||||||||||||
partnerRefundNooptional |
string |
Merchant-provided identifer for the refund request. If none is provided, a unique randomly generated string will be assigned. | ||||||||||||||||||
refundAmountconditionally 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
|
Key | Value |
---|---|
valuerequired |
string For IDR, format should include 2 decimal places. e.g. IDR 10.000, - will be placed with 10000.00 |
currencyrequired |
string ISO 4217 three-letter code of the transaction's currency. Only IDR is allowed. |
required
object
Object parameters details
Key | Value |
---|---|
channelCoderequired |
string Identifier for the payment channel partner |
statusrequired |
string Status of the refund. Allowed values: SUCCESS , FAILED , PENDING
|
reasonrequired |
string Reason why the refund request is made. Allowed values: FRAUDULENT , DUPLICATE , REQUESTED_BY_CUSTOMER
|
failureCodeoptional |
string If the status of the transaction is failed, this describes the reason for failure. |
refundFeeAmountoptional |
string If applicable, this is the corresponding additional fee for processing the refund. |
createdoptional |
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 |
metadataoptional |
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-IDrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
X-EXTERNAL-IDrequired |
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-IDrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
X-SIGNATURErequired |
string |
Non-repudiation signature for the request. See this article for more info. |
X-TIMESTAMPrequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
Body Parameter | Type | Description |
---|---|---|
originalReferenceNooptional |
string |
Xendit Generated ID for the payment request. Either this field or originalPartnerReferenceNo must be provided |
otpoptional |
string |
The authorization code or OTP inputted by the end customer |
typeoptional |
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 |
---|---|---|
responseCoderequired |
string |
Response code |
responseMessagerequired |
string |
Response description |
originalReferenceNooptional |
string |
Unique identifier for the payment request. Prefix will vary according to the payment method used. |
originalPartnerReferenceNooptional |
string |
Merchant-provided identifier for this specific transaction. Will be extended to the actual payment transactions |
customerIdoptional |
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-idrequired |
string |
Device identification on which the API services is currently being accessed by the end user. If not available, set to 'unknown'. |
Content-Typerequired |
string |
Must be set to application/json |
x-external-idrequired |
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-idrequired |
string |
Your Xendit's Client ID. Example: 7049bc78-0600-43b8-a6be-25225bf9344c |
x-signaturerequired |
string |
Non-repudiation signature for the request. See this article for more info. |
x-timestamprequired |
string |
Timestamp for the non-repudiation signature. Format must be yyyy-MM-ddTHH:mm:ssTZD. |
Notifications Payload Object
Payload Object Parameter | Type | Description | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
originalReferenceNorequired |
string |
Unique identifier for the payment request. Prefix will vary according to the payment method used. | ||||||||||||||||||||||||
originalPartnerReferenceNooptional |
string |
Merchant-provided identifier for this specific transaction. | ||||||||||||||||||||||||
latestTransactionStatusrequired |
string |
Latest transaction status of the payment. Allowed values: 00 , 06 |
||||||||||||||||||||||||
transactionStatusDescrequired |
string |
Description status transaction | ||||||||||||||||||||||||
createdTimerequired |
string |
Timestamp in ISO 8601 format when the PaymentRequest was created. Example: 2024-08-29T09:12:33.001Z | ||||||||||||||||||||||||
amountrequired |
object |
Actual paid amount Object information
|
||||||||||||||||||||||||
additionalInforequired |
object |
Additional information about the payment.
|
Key | Value | ||||||
---|---|---|---|---|---|---|---|
idrequired |
string Unique identifier for the payment. |
||||||
paymentMethodIdrequired |
string Unique identifier for the payment method. |
||||||
paymentMethodReferenceIdrequired |
string Merchant-provided identifier for this payment method. If it's not provided, xendit will generate unique identifier for the merchant. |
||||||
createdoptional |
string Timestamp in ISO 8601 format when the PaymentRequest was created. |
||||||
updatedoptional |
string Timestamp in ISO 8601 format when the PaymentRequest was last updated. Example: 2020-08-29T09:12:33.001Z |
||||||
descriptionoptional |
string description of the payment request. |
||||||
failureCodeoptional |
string If the status of the transaction is failed, this describes the reason for failure. |
||||||
channelPropertiesoptional |
object Additional information about the channel.
|
Key | Value |
---|---|
successReturnUrlrequired |
string URL where the end-customer is redirected if the authorization is successful. |
failureReturnUrlrequired |
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-idoptional |
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
|
|||||||||||||||||||||||||||||||
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:
|
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
|
|||||||||||||||||||||||||||||||
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. | ||||||||||
statusrequired |
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
|
||||||||||
network_responseoptional |
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
|
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 |
This status means the customer tried to authenticate using 3DS but did not successfully complete the authentication. |
Error Codes
Error Code | Description |
---|---|
API_VALIDATION_ERROR400 |
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_FORMAT400 |
The request body is not valid JSON. Recommendation is to check the input and retry. |
ACCOUNT_NUMBER400 |
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_NOT400 |
Card brand is not supported. Ask user to try a Visa/Mastercard. |
AUTHENTICATION400 |
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_FORBIDDEN403 |
API key in use does not have necessary permissions to perform the request. Please assign proper permissions for the key. Learn more here |
VERIFICATION408 |
The credit card network timed out when trying to tokenize the card. |
TEMPORARY503 |
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-idoptional |
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_TOKEN404 |
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-idoptional |
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 cardcard data child parameters
|
||||||||||
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 |
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-idoptional |
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_REVERSED400 |
Charge already reversed, therefore cannot be reversed |
CHARGE_ALREADY_CAPTURED400 |
Charge already captured, therefore cannot be reversed |
CHARGE_FAILED400 |
Charge is failed, therefore cannot be reversed |
REQUEST_FORBIDDEN403 |
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_CHARGE404 |
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-idoptional |
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-ruleoptional |
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 optionaldefault:
|
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
|
|||||||||||||||||||||||||||||||
metadataoptional |
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
|
|||||||||||||||||||||||||||||||
installmentoptional |
object |
These parameters are required to mark a transaction as an installment. installment details child parameters
|
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 | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
createdrequired |
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:
|
||||||||||||||
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
|
||||||||||||||
installmentoptional |
object |
These parameters will be returned to mark a transaction as an installment. installment details child parameters
|
||||||||||||||
network_responseoptional |
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
|
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_ERROR403 |
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: |
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: |
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: |
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?
- Plays as an additional security precaution to authorize the transactions are coming from the real cardholder
- Increase issuer (bank) confidence to accept the transaction as it indicates the transaction made from the real cardholder
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-idoptional |
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-ruleoptional |
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_THAN400 |
Capture amount is larger than authorized amount. Ensure the capture amount is the same as what was authorized and retry. |
INVALID_CHARGE400 |
Charge status is not AUTHORIZED. Please authorize the transaction first then retry the capture. |
REQUEST_FORBIDDEN403 |
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_CHARGE404 |
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-KEYoptional |
string |
A unique key to prevent processing duplicate requests. Must be unique across test & live mode. |
for-user-idoptional |
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-versionrequired |
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: . |
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_AMOUNT400 |
Refunded amount would exceed total charge |
DUPLICATE_REFUND400 |
external_id has already been used |
REQUEST_FORBIDDEN403 |
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_CHARGE404 |
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-idoptional |
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_FORBIDDEN403 |
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_CHARGE404 |
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:
- Paying by installments
- Giving a discount through a Promotion
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}¤cy={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¤cy=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¤cy=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.
|
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. | ||||||||||||||||||||||
binrequired |
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
|
||||||||||||||||||||||
installments optional |
array
|
Define the available installment option. installments details child parameters
|
||||||||||||||||||||||
reward optional |
object
|
If Rewards are available for the card, this object will be returned. reward details child parameters
|
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.
|
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.
|
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.
|
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.
|
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.
|
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..
|
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.
|
discount_amount | number |
Amount of discount applicable for a specific Promotion.
|
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_ERROR403 |
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_USE409 |
This Promotion name has been used for a previous or existing Promotion. Please use a different name. |
PROMO_CODE_IN_USE409 |
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.
|
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.
|
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.
|
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-idoptional |
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-ruleoptional |
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_idrequired |
string |
Reference ID provided by merchant (255 characters) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
currencyrequired |
string |
Currency used for the transaction in ISO4217 format - IDR , PHP , VND , THB , MYR |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
amountrequired |
number |
Transaction amount to be paid Min - 1,000 for ID_JENIUSPAY and 100 IDR for all other eWallets or 1 PHPMax - based on eWallet holding limit |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
checkout_methodrequired |
string |
Checkout method determines the payment flow used to process the transactionONE_TIME_PAYMENT is used for single guest checkoutsTOKENIZED_PAYMENT can be used for recurring payment |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
channel_coderequired if checkout_method =
|
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_propertiesrequired based on
|
object |
Channel specific information required for the transaction to be initiated OVO - one time payment required fields
JENIUS PAY required fields
OVO - tokenized payment required fields
DANA, LINKAJA - one time payment, SHOPEEPAY (ID, PH & TH), WECHATPAY, LINEPAY, TRUEMONEY, TOUCHNGO - one time payment, SAKUKU required fields
SHOPEEPAY (VN), APPOTA, MOMO, ZALOPAY, VNPTWALLET, VIETTELPAY required fields
SHOPEEPAY (ID, PH & MY) - tokenized payment required fields
GCASH, GRABPAY (PH & MY), ASTRAPAY, LINKAJA, TOUCHNGO - tokenized payment required fields
MAYA (PAYMAYA) required fields
WECHATPAY (MY) required fields
GRABPAY (MY)
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
payment_method_idrequired if checkout_method =
|
string |
ID of the payment method. Payment method is being used for tokenized payment to abstract your customer's ewallet as payment method | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
customer_idoptional |
string |
ID of the customer object to which the payment method will be linked to. Use Create Customer API to create your customer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
basketoptional |
array |
Array of objects describing the item(s) purchased Object parameters details
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
metadataoptional |
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"
}
}
Body Parameter | Type | Description | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
idrequired |
string |
Unique identifier for charge request transaction. It will always have the prefix of 'ewc_', followed by a UUIDv4 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
business_idrequired |
string |
Business ID of the merchant | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
reference_idrequired |
string |
Reference ID provided by merchant | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
statusrequired |
string |
Status of charge request
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
currencyrequired |
string |
Currency used for the transaction in ISO4217 format - IDR , PHP , VND , THB , MYR |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
charge_amountrequired |
number |
Requested charge amount from merchant | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
capture_amountoptional |
number |
Requested capture amount from merchant. At the moment, capture_amount will always be the same as charge_amount |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
refunded_amountoptional |
number |
Total amount refunded by merchant to end user | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
checkout_methodrequired |
string |
Checkout method determines the payment flow used to process the transactionONE_TIME_PAYMENT is used for single guest checkouts |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
channel_coderequired |
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_propertiesoptional |
object |
Channel specific information required for the transaction to be initiated OVO - one time payment required fields
JENIUS PAY required fields
OVO - tokenized payment required fields
DANA, LINKAJA - one time payment, SHOPEEPAY (ID, PH & TH) - one time payment, WECHATPAY, LINEPAY, TRUEMONEY, TOUCHNGO - one time payment, SAKUKU required fields
SHOPEEPAY (VN), APPOTA, MOMO, ZALOPAY, VNPTWALLET, VIETTELPAY required fields
SHOPEEPAY (ID, PH & MY) - tokenized payment required fields
GCASH, GRABPAY (PH & MY), ASTRAPAY, LINKAJA, TOUCHNGO - tokenized payment required fields
MAYA (PAYMAYA) required fields
WECHATPAY (MY) required fields
GRABPAY (MY)
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
actionsoptional |
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
Channels with redirection required more info
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
is_redirect_requiredrequired |
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_urlrequired |
string |
Callback URL which payment notifications will be sent | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
createdrequired |
string |
ISO 8601 Timestamp for charge object creation. Timezone UTC+0 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
updatedrequired |
string |
ISO 8601 Timestamp for latest charge object update. Timezone UTC+0 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void_statusoptional |
string |
Status of the void request. Available values: PENDING , FAILED , SUCCEEDED |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
voided_atoptional |
string |
ISO 8601 Timestamp when transaction was voided. Timezone UTC+0 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
capture_nowrequired |
string |
Default: true . Field not in use currently |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
customer_idoptional |
string |
ID of the customer object created with Xendit. ID to will be linked to the transaction | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
payment_method_idoptional |
string |
Xendit’s identifier for end user payment tokens binded with merchant. Only used for channels which support tokenized payments | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
failure_codeoptional |
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 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
basketoptional |
array |
Array of objects describing the item(s) purchased Object parameters details
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
metadataoptional |
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_ERROR400 |
There is invalid input in one of the required request fields |
UNSUPPORTED_CURRENCY400 |
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_ID400 |
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_KEY401 |
API key format is invalid |
INVALID_MERCHANT_CREDENTIALS401 |
Merchant credentials met with an error with the eWallet provider. Please contact Xendit customer support to resolve this issue |
INVALID_TOKEN401 |
Account linking token for this end user has expired. Please reinitiate account linking before retrying. |
REQUEST_FORBIDDEN_ERROR403 |
The API key is forbidden to perform this request |
CHANNEL_NOT_ACTIVATED403 |
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_FOUND404 |
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_TYPE403 |
The content type requested is not supported |
CHARGE_LIMIT_EXCEEDED429 |
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_ERROR500 |
An unexpected error occured, our team has been notified and will troubleshoot the issue |
CHANNEL_UNAVAILABLE503 |
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
eventrequired |
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_idrequired |
string |
Business ID of the merchant | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
createdrequired |
string |
ISO 8601 Timestamp for webhook notification creation. Timezone UTC+0. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
dataoptional |
object |
eWallets charge object will be nested in this parameter. See here for full definitions Data fields
|
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. |
A |