NAV undefined
undefined
bash php java

Introduction

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

The Instamoney 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.

Authentication

To successfully authenticate with Instamoney'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

sk_test_PYGIfL5y0uHx5ZhLbUdSzCRb9ajpdl6lyXmRxn2zQbWlBEUQWE9218vfR0jg

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

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

Following the format (with colon)
sk_test_PYGIfL5y0uHx5ZhLbUdSzCRb9ajpdl6lyXmRxn2zQbWlBEUQWE9218vfR0jg:

Encode Basic Auth format above into Base64 format

c2tfdGVzdF9QWUdJZkw1eTB1SHg1WmhMYlVkU3pDUmI5YWpwZGw2bHlYbVJ4bjJ6UWJXbEJFVVFXRTkyMTh2ZlIwamc===

Include Base64 encoded value in HTTP(s) header

Authorization: Basic c2tfdGVzdF9QWUdJZkw1eTB1SHg1WmhMYlVkU3pDUmI5YWpwZGw2bHlYbVJ4bjJ6UWJXbEJFVVFXRTkyMTh2ZlIwamc===

Instamoney 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 Instamoney Dashboard. Here are the steps to authenticate your account:

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

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

Libraries / SDKs

Instamoney 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!

PHP

Download PHP package here

https://packagist.org/packages/instamoney/instamoney-php-clients

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.

Currently PHP library supports:

  1. Bank Transfer via Virtual Accounts
  2. Disbursements

Here are the steps to use Instamoney PHP library:

  1. Download PHP package here
  2. Include InstamoneyPHPClient.php in your code
  3. Create InstamoneyPHPClient object with secret API key as parameter
  4. Require InstamoneyPHPClient.php in your code

Errors

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

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

HTTP Status Code

Instamoney 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 Instamoney'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 Instamoney's end (These are rare)

Error Code

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

Error Code Description
API_VALIDATION_ERROR Invalid request errors arise when your request has invalid parameters
INVALID_API_KEY No valid API key provided
REQUEST_FORBIDDEN_ERROR
The API key doesn't have permissions to perform the request
SERVER_ERROR API errors cover any other type of problem (e.g. a temporary problem with Instamoney'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 Instamoney API guarantees the idempotency of GET requests, so it's always safe to retry them. Including an idempotency key makes POST and PATCH request idempotent, which prompts the API to do the bookkeeping required to prevent duplicate operations. For example, if a request to create disbursements does not respond due to network connection error, you can retry the request with the same idempotency key to guarantee that no more than one disbursement is created.

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

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

Content errors

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

For a POST operation using an idempotency key, as long as an API method began execution, Instamoney'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.

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.

Instamoney 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 3000 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

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

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

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

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

We may reduce limits to prevent abuse, or increase limits to enable high-traffic applications. To increase the rate limit for your account, you can contact us 4 weeks in advance via email api.instamoney.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.

Balances

Get balance

Endpoint: Get Balance

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

Balance is like your wallet since it will tell you how much money is available to you on Instamoney. You can retrieve it to see the current balance on your Instamoney cash account. Your balance is debited on any money out transaction, e.g. when performing disbursements or Instamoney fees are charged. Your balance is credited when money comes into your account, e.g. fixed virtual accounts are paid or you deposit funds. You can assign your money into different accounts according to your business logic (eg: cash account, tax account, escrow account) and each account has its own balance that can be accessed in the dashboard.

Get Balance Request

Example Get Balance Request

curl https://api.instamoney.co/balance -X GET \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:
<?php
  require 'vendor/autoload.php';

  $options['secret_api_key'] = 'sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==';

  $instamoneyPHPClient = new InstamoneyClient\InstamoneyPHPClient($options);

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

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

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

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

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

Parameter Description
account_type
optional
default: CASH
string The selected account type (CASH or HOLDING).

Get Balance Response

Example Get Balance Response

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

Virtual Accounts

Get banks for virtual accounts

This endpoint can be used to get all available banks that Instamoney supports (may have difference with your activated bank channel).

Endpoint: Get Available Banks for Virtual Accounts

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

Example Get Banks for Virtual Accounts Request

curl https://api.instamoney.co/available_virtual_account_banks -X GET \
   -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:
<?php
  require 'vendor/autoload.php';

  $options['secret_api_key'] = 'sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==';

  $instamoneyPHPClient = new InstamoneyClient\InstamoneyPHPClient($options);

  $response = $instamoneyPHPClient->getVirtualAccountBanks();
  print_r($response);
?>

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

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

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

Get Banks for Virtual Accounts Response

Example Get Banks for Virtual Accounts Response

{
  "name": "Bank Negara Indonesia",
  "code": "BNI",
  "is_activated":true
}
Parameter Description
name Full name of the bank
code Code of the bank, relevant during creation of virtual accounts
is_activated Activation status of the bank, relevant during creation of virtual accounts

Create fixed virtual accounts

Endpoint: Create Fixed Virtual Account (FVA)

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

Fixed virtual accounts are dedicated virtual accounts under a name you choose, e.g. 'YourCompany - Becca Salim'. You will receive a callback each time this fixed virtual account is paid. Read more about fixed virtual accounts.

Create Fixed Virtual Accounts Request

Example Create Fixed Virtual Accounts Request

curl https://api.instamoney.co/callback_virtual_accounts -X POST \
   -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
   -d external_id=demo_virtual_account_1475459775872 \
   -d bank_code=BNI \
   -d name='Rika Sutanto'
<?php
  require 'vendor/autoload.php';

  $options['secret_api_key'] = 'sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==';

  $instamoneyPHPClient = new InstamoneyClient\InstamoneyPHPClient($options);

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

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

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

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
Parameter Description
external_id
required
string An ID of your choice. Often it is unique identifier like a phone number, email or transaction ID. Maximum length allowed is 950 characters.
bank_code
required
string Bank code of the virtual account you want to create
Note: We highly recommend you redirect customers to pay into BNI Virtual Account for interbank transfers

Available bank codes: ARTAJASA, BNI, BNI_SYARIAH, BRI, MANDIRI, PERMATA, and SAHABAT_SAMPOERNA
name
required
string Name of user/virtual account, - this will be displayed in the bank's user interface, e.g. ATM confirmation screens. Note that this field can only contain letters and spaces and has no length restriction (though the banks will truncate as per their limitations). BNI VA name will be included a prefix "XDT-" in the response. This prefix is mandatory from BNI.
virtual_account_number
optional
string The virtual account number you want to assign. If you do not send one, one will be picked at random
suggested_amount
optional
number The suggested amount you want to assign. If you do not send one, external id will be used
Note: suggested amounts is only supported for Mandiri and BRI
is_closed
optional
boolean When set to true, the virtual account will be closed and will only accept the amount specified in expected_amount
expected_amount
optional
number The amount that the virtual account will expect if is_closed is set to true
expiration_date
optional
ISO Date The time when the virtual account will be expired
is_single_use
optional
boolean When set to true, the virtual account will be inactive after it is paid

Create Fixed Virtual Accounts Response

Example Create Fixed Virtual Accounts Response

{
   "owner_id":"57b4e5181473eeb61c11f9b9",
   "external_id":"demo-1475804036622",
   "bank_code":"BNI",
   "merchant_code":"8808",
   "name":"Rika Sutanto",
   "account_number":"88082548",
   "is_closed": false,
   "id":"57f6fbf26b9f064272622aa6",
   "is_single_use": true,
   "status": "PENDING"
}
Parameter Description
owner_id Your user ID
external_id An ID of your choice which you provided upon request
bank_code Bank code for the relevant bank, e.g. BNI
merchant_code 5-digit merchant prefix to the full virtual account number
name Name for the fixed virtual account
account_number Complete virtual account number (including prefix). This is what a user will need to enter into an ATM or their Internet/mobile banking.
suggested_amount OPTIONAL suggested amount for created fixed virtual account
is_closed value that determines whether a virtual account is closed or not
expected_amount OPTIONAL the amount that is expected when is_closed is true
id Unique ID for the fixed virtual account.
is_single_use value that determines whether a virtual account will be inactive after it is paid
status Status of fixed virtual account that defines if it’s pending or inactive. Status is inactive either because it is a paid single use fixed virtual account or it is already expired.

Create Fixed Virtual Accounts Errors

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
INVALID_JSON_FORMAT
400
The request body is not a valid JSON format.
VIRTUAL_ACCOUNT_NUMBER_OUTSIDE_RANGE
400
The virtual account number you want is outside your range.
BANK_NOT_SUPPORTED_ERROR
400
The bank code is not currently supported.
EXPIRATION_DATE_NOT_SUPPORTED_ERROR
400
Custom expiration date for the fixed virtual account is not currently supported.
EXPIRATION_DATE_INVALID_ERROR
400
Invalid custom expiration date because it's earlier than current time.
SUGGESTED_AMOUNT_NOT_SUPPORTED_ERROR
400
The suggested amount for the fixed virtual account is not currently supported.
EXPECTED_AMOUNT_REQUIRED_ERROR
400
The expected amount is required when is_closed is set to true.
CLOSED_VA_NOT_SUPPORTED_ERROR
400
The closed option for this virtual account is not currently supported.
DUPLICATE_CALLBACK_VIRTUAL_ACCOUNT_ERROR
400
The account number that you want to create is already exist
MINIMUM_EXPECTED_AMOUNT_ERROR
400
The expected amount can only be more than zero
MAXIMUM_EXPECTED_AMOUNT_ERROR
400
The expected amount can only be less than Rp.1000000000
CALLBACK_VIRTUAL_ACCOUNT_NAME_NOT_ALLOWED_ERROR
400
The name cannot contain bank or institution name

Update fixed virtual accounts

Endpoint: Update Fixed Virtual Account (FVA)

PATCH https://api.instamoney.co/callback_virtual_accounts/{fixed_virtual_account_id}

Fixed Virtual Account is so adaptable, and it's all based on your needs. Therefore, we provide you this endpoint to easily update your fixed virtual account as you like.

Update Fixed Virtual Accounts Request

Parameter Description
suggested_amount
optional
number suggested amount you want to assign
expected_amount
optional
number The amount that the virtual account will expect if is_closed is set to true
expiration_date
optional
ISO Date The time when the virtual account will be expired. You can set it to be days in the past to expire virtual account immediately
is_single_use
optional
boolean When set to true, the virtual account will be inactive after it is paid

Update Fixed Virtual Accounts Response

Example update Fixed Virtual Accounts Response

{
   "owner_id":"57b4e5181473eeb61c11f9b9",
   "external_id":"demo-1475804036622",
   "bank_code":"BNI",
   "merchant_code":"8808",
   "name":"Rika Sutanto",
   "account_number":"88082548",
   "suggested_amount":50000,
   "is_closed": false,
   "id":"57f6fbf26b9f064272622aa6",
   "is_single_use": true,
   "status": "PENDING"
}
Parameter Description
owner_id Your user ID
external_id An ID of your choice which you provided upon virtual account creation
bank_code Bank code for the relevant bank, e.g. BNI
merchant_code 5-digit merchant prefix to the full virtual account number
name Name for the fixed virtual account
account_number Complete virtual account number (including prefix). This is what a user will need to enter into an ATM or their Internet/mobile banking.
suggested_amount Suggested amount of updated fixed virtual account
id Unique ID for the fixed virtual account.
is_closed value that determines whether a virtual account is closed or not
expected_amount OPTIONAL the amount that is expected when is_closed is true
is_single_use value that determines whether a virtual account will be inactive after it is paid
status Status of fixed virtual account that defines if it’s pending or inactive. Status is inactive either because it is a paid single use fixed virtual account or it is already expired.

Update Fixed Virtual Accounts Errors

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
INVALID_JSON_FORMAT
400
The request body is not a valid JSON format.
VIRTUAL_ACCOUNT_NUMBER_OUTSIDE_RANGE
400
The virtual account number you want is outside your range.
BANK_NOT_SUPPORTED_ERROR
400
The bank code is not currently supported.
SUGGESTED_AMOUNT_NOT_SUPPORTED_ERROR
400
The suggested amount for the fixed virtual account is not currently supported.
EXPECTED_AMOUNT_REQUIRED_ERROR
400
The expected amount is required when is_closed is set to true.
CLOSED_VA_NOT_SUPPORTED_ERROR
400
The closed option for this virtual account is not currently supported.
INACTIVE_VIRTUAL_ACCOUNT_ERROR
400
Account number that you want to update is inactive.
MINIMUM_EXPECTED_AMOUNT_ERROR
400
The expected amount can only be more than zero
MAXIMUM_EXPECTED_AMOUNT_ERROR
400
The expected amount can only be less than Rp.1000000000

Fixed virtual account callback

Endpoint: Fixed Virtual Account Callback

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

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

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

When someone pays into your fixed virtual account, our callback APIs will hit your URL that you already set in dashboard. Our callback API will also hit your URL upon fixed virtual account creations and updates. Please see Create Fixed Virtual Accounts for more details. For further information about callbacks please read these docs.

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

Fixed Virtual Account Payment Callback Request

Example Fixed Virtual Account Payment Callback Request

curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "X-CALLBACK-TOKEN:
     c2tfdGVzdF9PWUNFZkw1eGdMTCtsOFp2SzdRYVNHR1ZNTjczb05FcGszeXorUnhuLzJiUy9MQ2dDUVorZ3c9PTo=" \
     --data-binary "{
    id: \"57fb4e076fa3fa296b7f5a97\",
    payment_id: \"demo-1476087608948_1476087303080\",
    callback_virtual_account_id: \"57fb4df9af86ce19778ad359\",
    owner_id: \"57b4e5181473eeb61c11f9b9\",
    external_id: \"demo-1476087608948\",
    account_number: \"1547\",
    bank_code: \"BNI\",
    amount: 99000,
    transaction_timestamp: \"2016-10-10T08:15:03.080Z\",
    merchant_code: \"8808\",
    sender_name: \"JOHN DOE\",
    updated: \"2016-10-10T08:15:03.404Z\",
    created: \"2016-10-10T08:15:03.404Z\"
}" \
'https://api.instamoney.co/virtual_account_paid_callback_url'
Header Parameter Description
x-callback-token Your Instamoney unique callback token to verify the origin of the callback
webhook-id A unique identifier of every webhook to help you to handle double callback 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 webhook
Parameter Description
payment_id Our internal system’s payment ID
callback_virtual_account_id The id field value from the response when the fixed virtual account was created. See Create Fixed Virtual Accounts
owner_id Your user ID
external_id An ID of your choice which you provided upon virtual account creation
account_number This is the virtual account number (excluding the prefix). This works just like a bank account and is what a user will need to enter in their internet banking/ATM to send funds.
bank_code Bank code for the relevant bank, e.g. BNI
amount Nominal amount to transfer
merchant_code The merchant code will be the prefix for the virtual account number, e.g 01234 your_number
id ID of fixed virtual account payment
sender_name Name of the end user that paid into the virtual account. This field is only supported for Sahabat Sampoerna virtual accounts.

Fixed Virtual Account Creation / Update Callback Request

Example Fixed Virtual Account Creation / Update Callback Request

curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "X-CALLBACK-TOKEN:
     c2tfdGVzdF9PWUNFZkw1eGdMTCtsOFp2SzdRYVNHR1ZNTjczb05FcGszeXorUnhuLzJiUy9MQ2dDUVorZ3c9PTo=" \
     --data-binary "{
    id: \"57fb4e076fa3fa296b7f5a97\",
    owner_id: \"5824128aa6f9f9b648be9d76\",
    external_id: \"fixed-va-1487156410\",
    merchant_code: \"88608\",
    account_number: \"886081000123456\",
    bank_code: \"MANDIRI\",
    name: \"John Doe\",
    is_closed: false,
    is_single_use: false,
    status: \"ACTIVE\",
    expiration_date: \"2048-02-15T11:01:52.722Z\",
    updated: \"2016-10-10T08:15:03.404Z\",
    created: \"2016-10-10T08:15:03.404Z\"
}" \
'https://api.instamoney.co/virtual_account_created_callback_url'
Parameter Description
owner_id Your user ID
external_id An ID of your choice which you provided upon request
bank_code Bank code for the relevant bank, e.g. MANDIRI
merchant_code 5-digit merchant prefix to the full virtual account number
name Name for the fixed virtual account
account_number Complete virtual account number (including prefix). This is what a user will need to enter into an ATM or their Internet/mobile banking.
suggested_amount OPTIONAL suggested amount for created fixed virtual account
is_closed value that determines whether a virtual account is closed or not
expected_amount OPTIONAL the amount that is expected when is_closed is true
id Unique ID for the fixed virtual account.
is_single_use value that determines whether a virtual account will be inactive after it is paid
status Status of fixed virtual account.

Fixed Virtual Account Callback Errors

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

Get fixed virtual account payment

Endpoint: Get Fixed Virtual Account payment

GET https://api.instamoney.co/callback_virtual_account_payments/payment_id={payment_id}

Example Get Fixed Virtual Account Request

curl https://api.instamoney.co/callback_virtual_account_payments/payment_id={payment_id} -X GET \
    -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:

When you receive our callback in your URL, you can verify that the callback you receive is coming from us.

Get Fixed Virtual Account Payment Request

Parameter Description
payment_id
required
string ID of the payment to retrieve

Get Fixed Virtual Account Payment Response

Example Get Fixed Virtual Account Response

{
    "id": "598d91b1191029596846047f",
    "payment_id": "1502450097080",
    "callback_virtual_account_id": "598d5f71bf64853820c49a18",
    "external_id": "demo-1502437214715",
    "merchant_code": "77517",
    "account_number": "1000016980",
    "bank_code": "BNI",
    "amount": 5000,
    "transaction_timestamp": "2017-08-11T11:14:57.080Z"
}
Parameter Description
id ID of the fixed virtual account payment
payment_id Our internal system’s payment ID
callback_virtual_account_id ID of the fixed virtual account payment that was paid
external_id External ID on the fixed virtual account payment
merchant_code 5-digit merchant prefix to the full virtual account number
account_number Account number of the virtual account
bank_code Bank code of the virtual account number
amount Amount that was paid to this virtual account payment
transaction_timestamp Date time that the fixed virtual account was paid

Get Fixed Virtual Account Payment Errors

Error Code Description
CALLBACK_VIRTUAL_ACCOUNT_PAYMENT_NOT_FOUND_ERROR
404
Could not find callback virtual account payment by payment id.

Get fixed virtual account

Endpoint: Get Fixed Virtual Account

GET https://api.instamoney.co/callback_virtual_accounts/{callback_virtual_account_id}

Example Get Fixed Virtual Account Request

curl https://api.instamoney.co/callback_virtual_accounts/{callback_virtual_account_id} -X GET \
  -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:

Sometime, you need to know the detail for your fixed virtual account. This endpoint can be used to get the latest details from your fixed virtual account

Get Fixed Virtual Account Request

Parameter Description
callback_virtual_account_id
required
string ID of the fixed virtual account to retrieve

Get Fixed Virtual Account Response

Example Get Fixed Virtual Account Response

{
    "owner_id": "58cd618ba0464eb64acdb246",
    "external_id": "fixed-va-1507867286",
    "bank_code": "BRI",
    "merchant_code": "26215",
    "name": "Steve Wozniak",
    "account_number": "262151000393993",
    "is_single_use": false,
    "status": "PENDING",
    "expiration_date": "2048-10-12T17:00:00.000Z",
    "is_closed": false,
    "id": "59e03a976fab8b1850fdf347"
}
Parameter Description
owner_id ID of the business that own the fixed virtual account
external_id An ID of your choice which you provided upon virtual account creation
bank_code Bank code of the virtual account number
merchant_code 4 or 5-digit merchant prefix to the full virtual account number
name Name of the virtual account
account_number Account number of the virtual account
expiration_date Expiration date of the virtual account
is_closed Flag that define the fixed virtual account is close or open
id ID of the fixed virtual account
is_single_use Flag that define the fixed virtual account is single use or multiple use
status Status of fixed virtual account that defines if it’s active or inactive. Status is inactive either because it is a paid single use fixed virtual account or it is already expired.

Get Fixed Virtual Account Payment Errors

Error Code Description
CALLBACK_VIRTUAL_ACCOUNT_NOT_FOUND_ERROR
404
Could not find callback virtual account.

Retail Outlets

Create Fixed Payment Code

Endpoint: Create Fixed Payment Code (FPC)

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

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

Create Fixed Payment Code Request

Example Create Fixed Payment Code Request

curl https://api.instamoney.co/fixed_payment_code -X POST \
   -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
   -d external_id=demo_fixed_payment_code_123 \
   -d retail_outlet_name=ALFAMART \
   -d name='Rika Sutanto' \
   -d expected_amount=10000
Parameter Description
external_id
required
string An ID of your choice. Often it is unique identifier like a phone number, email or transaction ID. Maximum length allowed is 950 characters.
retail_outlet_name
required
string Name of the fixed payment code you want to create
name
required
string Name of user - this might be used by the Retail Outlets cashier to validate the end user
Characters: alphanumeric
Special Characters: # / . " - , ' _ @ ( ) & ] [ :
expected_amount
required
number The amount that is expected to be paid by end customer. The minimum is Rp 10,000 and the maximum is Rp 2,500,000.
payment_code
optional
string The fixed payment code that you want to assign. If you do not send one, one will be picked at random
expiration_date
optional
ISO Date The time when the fixed payment code will be expired
is_single_use
optional
boolean When set to true, the fixed payment code will be inactive after it is paid

Create Fixed Payment Code Response

Example Create Fixed Payment Code Response

{
    "owner_id": "5b614aa8e79f9214007244d4",
    "external_id": "123",
    "retail_outlet_name": "ALFAMART",
    "prefix": "TEST",
    "name": "Rika Sutanto",
    "payment_code": "TEST123456",
    "type": "USER",
    "expected_amount": 10000,
    "is_single_use": true,
    "expiration_date": "2049-07-31T17:00:00.000Z",
    "id": "5b61881e6cc2770f00117f73"
}
Parameter Description
owner_id Your user ID
external_id An ID of your choice which you provided upon request
retail_outlet_name Name for the relevant Retail Outlets, e.g. ALFAMART
prefix 3-6 characters that differentiate your fixed payment code from the others
name Name for the fixed payment code
payment_code Complete fixed payment code (including prefix). This is what a user will need to tell Retail Outlets cashier or show via barcode page. You can append payment_code into the barcode page URL (barcode page currently only supports Alfamart):
expected_amount The amount that is expected to be paid by end customer
is_single_use Value that determines whether a fixed payment code will be inactive after it is paid or not
expiration_date The time when the fixed payment code will be expired
id Unique ID for the fixed payment code

Create Fixed Payment Code Errors

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
INVALID_JSON_FORMAT
400
The request body is not a valid JSON format.
PAYMENT_CODE_OUTSIDE_RANGE
400
The fixed payment code you want is outside your range.
RETAIL_OUTLET_NOT_SUPPORTED_ERROR
400
The Retail Outlets is not currently supported.
DUPLICATE_PAYMENT_CODE_ERROR
400
The payment code that you want to create is already exist
EXPIRATION_DATE_INVALID_ERROR
400
Invalid custom expiration date because it's earlier than current time.
MINIMUM_EXPECTED_AMOUNT_ERROR
400
The expected amount can only be more than or equal Rp 10,0000
MAXIMUM_EXPECTED_AMOUNT_ERROR
400
The expected amount can only be less than or equal Rp 2,500,000

Update Fixed Payment Code

Endpoint: Update Fixed Payment Code (FPC)

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

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

Update Fixed Payment Code Request

Example Create Fixed Payment Code Request

curl https://api.instamoney.co/fixed_payment_code/{fixed_payment_code_id} -X PATCH \
   -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
   -d expected_amount=20000
   -d name='Joe Contini'
Parameter Description
name
optional
string Name for the fixed payment code
expected_amount
optional
number The amount that is expected to be paid by end customer. The minimum is Rp 10,000 and the maximum is Rp 2,500,000.
expiration_date
optional
ISO Date The time when the fixed payment code will be expired. You can set it to be days in the past to expire fixed payment code immediately

Update Fixed Payment Code Response

Example Update Fixed Payment Code Response

{
    "owner_id": "5b614aa8e79f9214007244d4",
    "external_id": "123",
    "retail_outlet_name": "ALFAMART",
    "prefix": "TEST",
    "name": "Joe Contini",
    "payment_code": "TEST123456",
    "type": "USER",
    "expected_amount": 20000,
    "is_single_use": true,
    "expiration_date": "2049-07-31T17:00:00.000Z",
    "id": "5b61881e6cc2770f00117f73"
}
Parameter Description
owner_id Your user ID
external_id An ID of your choice which you provided upon request
retail_outlet_name Name for the relevant Retail Outlets, e.g. ALFAMART
prefix 3-6 characters that differentiate your fixed payment code from the others
name Name for the fixed payment code
payment_code Complete fixed payment code (including prefix). This is what a user will need to tell Retail Outlets cashier
expected_amount The amount that is expected to be paid by end customer
is_single_use Value that determines whether a fixed payment code will be inactive after it is paid or not
expiration_date The time when the fixed payment code will be expired
id Unique ID for the fixed payment code

Update Fixed Payment Code Errors

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
INVALID_JSON_FORMAT
400
The request body is not a valid JSON format.
PAYMENT_CODE_OUTSIDE_RANGE
400
The fixed payment code you want is outside your range.
INACTIVE_FIXED_PAYMENT_CODE_ERROR
400
Account number that you want to update is inactive.
MINIMUM_EXPECTED_AMOUNT_ERROR
400
The expected amount can only be more than or equal Rp 10,000
MAXIMUM_EXPECTED_AMOUNT_ERROR
400
The expected amount can only be less than or equal Rp 2,500,000

Get Fixed Payment Code

Endpoint: Get Fixed Payment Code

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

Example Get Fixed Payment Code Request

curl https://api.instamoney.co/fixed_payment_code/{fixed_payment_code_id} -X GET \
  -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:

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

Get Fixed Payment Code Request

Parameter Description
fixed_payment_code_id
required
string ID of the fixed payment code to retrieve

Get Fixed Payment Code Response

Example Get Fixed Payment Code Response

{
    "owner_id": "5b614aa8e79f9214007244d4",
    "external_id": "123",
    "retail_outlet_name": "ALFAMART",
    "prefix": "TEST",
    "name": "Joe Contini",
    "payment_code": "TEST123456",
    "type": "USER",
    "expected_amount": 20000,
    "is_single_use": true,
    "expiration_date": "2049-07-31T17:00:00.000Z",
    "id": "5b61881e6cc2770f00117f73"
}
Parameter Description
owner_id Your user ID
external_id An ID of your choice which you provided upon request
retail_outlet_name Name for the relevant Retail Outlets, e.g. ALFAMART
prefix 3-6 characters that differentiate your fixed payment code from the others
name Name for the fixed payment code
payment_code Complete fixed payment code (including prefix). This is what a user will need to tell Retail Outlets cashier
expected_amount The amount that is expected to be paid by end customer
is_single_use Value that determines whether a fixed payment code will be inactive after it is paid or not
expiration_date The time when the fixed payment code will be expired
id Unique ID for the fixed payment code

Get Fixed Payment Code Errors

Error Code Description
FIXED_PAYMENT_CODE_NOT_FOUND_ERROR
404
Could not find fixed payment code.

Fixed Payment Code Callback

Endpoint: Fixed Payment Code Callback

POST https://yourcompany.com/fixed_payment_code_paid_callback_url

When someone pays into your fixed payment code, our callback APIs will hit your URL that you already set in dashboard.

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

Fixed Payment Code Payment Callback Request

Example Fixed Payment Code Payment Callback Request

curl --include \
    --request POST \
    --url https://yourcompany.com/fixed_payment_code_paid_callback_url \
    --header 'content-type: application/json' \
    --header 'x-callback-token: MuaJALKJSDK12LASHD123kSAKSDHzjahwUWjkasJSDSA12KSNAK21n==' \
    --data '{
  "id": "58a435201b6ce2a355f46070",
  "external_id": "fixed-payment-code-14876410",
  "prefix": "TEST",
  "payment_code": "TEST123",
  "retail_outlet_name": "ALFAMART",
  "name": "John Doe",
  "amount": 123456,
  "status": "SETTLING",
  "transaction_timestamp": "2019-11-08T11:51:28.613Z",
  "payment_id": "1573213888613",
  "fixed_payment_code_payment_id": "5dc556c07a58de7c114f0347",
  "fixed_payment_code_id": "5dc5567bdf120fd64988a79b",
  "owner_id": "5be9b2f03ef77262c2bd49e6"
}'
Parameter Description
id Unique identifier for this transaction
external_id An ID of your choice which you provided upon fixed payment code creation
prefix 3-6 characters that differentiate your fixed payment code from the others
payment_code Complete fixed payment code (including prefix). This is what a user will need to tell Retail Outlets cashier
retail_outlet_name Name for the relevant Retail Outlets, e.g. ALFAMART
name Name for the fixed payment code
amount Nominal amount that is paid
status Status of payment. Possible value(s): SETTLING or COMPLETED

SETTLING means that transaction already PAID but still waiting for settlement time
COMPLETED means that transaction already PAID and SETTLED
transaction_timestamp Date time that the fixed payment code was paid
payment_id Our internal system’s payment ID that can be used as payment reference
fixed_payment_code_payment_id Unique ID for the fixed payment code payment
fixed_payment_code_id Unique ID for the fixed payment code
owner_id Your user ID

Fixed Payment Code Callback Errors

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

Get Payments By Fixed Payment Code ID

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

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

Example Get Payments By Fixed Payment Code ID(FPC) Request

curl https://api.instamoney.co/fixed_payment_code/{fixed_payment_code_id}/payments -X GET \
   -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:

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

Get Fixed Payment Code Request

Path Parameter Description
fixed_payment_code_id
required
string ID of the fixed payment code to retrieve
Query Parameter Description
limit
optional


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

Get Fixed Payment Code Response

Example Get Payments By Fixed Payment Code ID(FPC)

{
    "data": [
        {
            "id": "61e660dfa5cebe7ec4fabe42",
            "external_id": "FPC-1642488014",
            "owner_id": "5fac8c146f67f74049fb828e",
            "fixed_payment_code_id": "61e660cf84949196d94e6431",
            "fixed_payment_code_payment_id": "61e660df0f61fe962baa18bf",
            "retail_outlet_name": "ALFAMART",
            "prefix": "TEST",
            "payment_code": "TEST404373",
            "amount": 25000,
            "name": "JOHN DOE",
            "status": "SETTLING",
            "payment_id": "1642488031655",
            "transaction_timestamp": "2022-01-18T06:40:31.655Z",
        }
    ],
    "has_more": true,
    "links": {
        "href": "https://api.instamoney.co/fixed_payment_code/61e660cf84949196d94e6431/payments?limit=1&after_id=61e660dfa5cebe7ec4fabe42",
        "rel": "next",
        "method": "GET"
    }
}
Parameter Description
data Returns an array of Payment Object. Returns empty array when there is no result.
has_more 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 The links to the next page based on HATEOAS if there is next result. The HATEOAS format are: href: URI of target, this will be to the next link. rel: The relationship between source and target. The value will be next. method: The HTTP method, the value will be GET.
Payment Object Description
id Unique ID for the payment that generated randomly by system
external_id An ID of your choice which you provided upon request
owner_id Unique user ID of the merchant
fixed_payment_code_id Unique ID for the fixed payment code which you provided upon request
fixed_payment_code_payment_id Unique ID for the payment paid by end-cusotmer with provided payment code
retail_outlet_name The name of the Retail Outlets e.g. ALFAMART and INDOMARET
prefix 3-6 characters that differentiate your fixed payment code from the others
payment_code The code given to end-customer for making payments
amount The amount that is paid by end customer
name Name for the fixed payment code
status Status of payment. Possible value(s): SETTLING or COMPLETED

SETTLING means that transaction already PAID but still waiting for settlement time
COMPLETED means that transaction already PAID and SETTLED
payment_id Our internal system’s payment ID that can be used as payment reference
transaction_timestamp Date time that the fixed payment code was paid

Get Fixed Payment Code Errors

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
REQUEST_FORBIDDEN_ERROR
403
API key in use does not have necessary permissions to perform the request.
DATA_NOT_FOUND
404
Could not find fixed payment code.

Disburse Funds

Disbursements allow you to instruct Instamoney to instantly send money to any bank account across Indonesia on your behalf.

Create disbursement

Endpoint: Create Disbursement

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

Create Disbursement Request

Example Create Disbursement Request

<?php
  require 'vendor/autoload.php';

  $options['secret_api_key'] = 'sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==';

  $instamoneyPHPClient = new InstamoneyClient\InstamoneyPHPClient($options);

  $external_id = 'demo_1475459775872';
  $amount = 17000;
  $bank_code = 'BCA';
  $account_holder_name = 'Bob Jones';
  $account_number = '1231241231';
  $disbursement_options['description'] = 'Reimbursement for shoes';

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

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

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
Header Description
X-IDEMPOTENCY-KEY
optional
string A unique key to prevent processing duplicate requests. Can be your external_id or any GUID. Must be unique across development & production environments.

Characters Special and alphanumeric
Maximum length No maximum characters
Minimum length 1 character
Parameter Description
external_id
required
string ID of the disbursement in your system, used to reconcile disbursements after they have been completed.

Characters Special and alphanumeric
Maximum length 1000 maximum characters
Minimum length 1 character
bank_code
required
string Code of the destination bank

The bank code must match the bank codes here precisely
account_holder_name
required
string Name of account holder as per the bank's or e-wallet's records. Used for verification and error/customer support scenarios.

Characters Special and alphanumeric
Maximum length No maximum characters
Minimum length 1 character
account_number
required
string Destination bank account number. If disbursing to an e-wallet, phone number registered with the e-wallet account.

Characters Numeric and hyphens
BCA required length 10 characters
Other banks maximum length No maximum characters
Other banks minimum length 1 character
E-wallets Phone number registered with the e-wallet (Example: 0812XXXXXX)

*** We support disbursements to virtual accounts of major banks (BRI, BNI, Mandiri, CIMB Niaga, Permata, BTN, and NOBU Bank).
*** We support disbursements to major e-wallets (GoPay, OVO, and Mandiri e-cash).

description
required
string Description to send with the disbursement

Characters Special and alphanumeric
Maximum length No maximum characters
Minimum length 1 character
amount
required
number Amount to disburse

Characters Numerical integers, no decimals
Maximum limit (BCA, Mandiri, BRI, BNI, BNI_SYR, CIMB, CIMB_UUS, PERMATA) No Limit***
Maximum limit (SAHABAT_SAMPOERNA) Rp 1.000.000.000***
Minimum limit (BCA, Mandiri, BRI, BNI, BNI_SYR, CIMB, CIMB_UUS, PERMATA, SAHABAT_SAMPOERNA) No Limit
Maximum Limit (Other banks) Rp. 100.000.000
Minimum Limit (Other banks) Rp. 10.000

*** While there is theoretically no maximum transfer limit for transfers to these banks, please note that we may have to report all transaction amounts above Rp 100.000.000 to the financial authorities in Indonesia along with supporting documentation regarding the underlying transactions.

email_to
optional
string[] Email addresses that get notified of disbursement details after the disbursement is completed.
Maximum 3 email addresses accepted.
email_cc
optional
string[] Email addresses that get notified as carbon copy receiver of disbursement details after the disbursement is completed.
Maximum 3 email addresses accepted.
Only allowed if email_to provided.
email_bcc
optional
string[] Email addresses that get notified as blind carbon copy receiver of disbursement details after the disbursement is completed.
Maximum 3 email addresses accepted.
Only allowed if email_to provided.

Create Disbursement Response

Example Create Disbursement Response

{
  "user_id": "5785e6334d7b410667d355c4",
  "external_id": "12345",
  "amount": 1000,
  "bank_code": "BCA",
  "account_holder_name": "RAIDY WIJAYA",
  "disbursement_description": "Refunds for shoes",
  "status": "PENDING",
  "id": "57f1ce05bb1a631a65eee662",
  "email_to": ["test+to1@instamoney.co","test+to2@instamoney.co"],
  "email_cc": ["test+cc@instamoney.co"],
  "email_bcc": ["test+bcc@instamoney.co"]
}
Parameter Description
id
required
string Unique disbursement ID
user_id
required
string Your Instamoney Business ID
external_id
required
string Custom ID of your choice to identify the transaction. Our customers often use a phone number, email address, or transaction/order ID
amount
required
number Amount to disburse
bank_code
required
string Bank code of destination bank or e-wallet. See bank codes
account_holder_name
required
string Name of account holder as per the bank's or e-wallet’s records. Used for verification and error/customer support scenarios
disbursement_description
required
This is the description you give us :)
status
required
string
PENDING Transfer is initiated but not yet completed by bank.
email_to
optional
string[] Email addresses that get notified of disbursement details after the disbursement is completed.
This response parameter is only returned if this field is filled.
email_cc
optional
string[] Email addresses that get notified as carbon copy receiver of disbursement details after the disbursement is completed.
This response parameter is only returned if this field is filled.
email_bcc
optional
string[] Email addresses that get notified as blind carbon copy receiver of disbursement details after the disbursement is completed.
This response parameter is only returned if this field is filled.

Create Disbursement Errors

Error Code Description
API_VALIDATION_ERROR
400
Inputs are failing validation. The errors field contains details about which fields are violating validation.
INVALID_JSON_FORMAT
400
The request body is not a valid JSON format.
DISBURSEMENT_DESCRIPTION_NOT_FOUND_ERROR
400
Disbursement description is not set in Dashboard > Configuration > Disbursement. Add a default description before retrying.
DIRECT_DISBURSEMENT_BALANCE_INSUFFICIENT_ERROR
400
Not enough balance to disburse. Add more balance before retrying.
DUPLICATE_TRANSACTION_ERROR
400
Idempotency key has been used before. Use a unique idempotency key and try again.
BANK_CODE_NOT_SUPPORTED_ERROR
400
Destination bank code is not supported.
RECIPIENT_ACCOUNT_NUMBER_ERROR
400
For transfers to BCA, account_number input needs to be 10 digits. Check the account number length before retrying.
RECIPIENT_AMOUNT_ERROR
400
The transfer amount requested is lower than the prescribed minimum for the chosen destination bank. Amend the transfer amount before retrying.
MAXIMUM_TRANSFER_LIMIT_ERROR
400
The transfer amount requested is higher than the prescribed maximum for the chosen destination bank. Amend the transfer amount before retrying.
INVALID_DESTINATION
400
The account number is unable to processed. Use different account number to retry.
SERVER_ERROR
500
Error connecting to our server. Please use Get disbursement by external_id API to check whether the disbursement has already been created. If you receive DIRECT_DISBURSEMENT_NOT_FOUND_ERROR, the disbursement has not been created; please retry the disbursement request in 1-2 hours.

Get disbursement by id

Endpoint: Get Disbursement by id

GET https://api.instamoney.co/disbursements/{disbursement_id}

This endpoint queries the current status of a disbursement. This is often used for checking the status of a transaction.

Get Disbursement Request

Example Get Disbursement Request

curl https://api.instamoney.co/disbursements/57c9010f5ef9e7077bcb96b6 -X GET \
  -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:
<?php
  require 'vendor/autoload.php';

  $options['secret_api_key'] = 'sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==';

  $instamoneyPHPClient = new InstamoneyClient\InstamoneyPHPClient($options);

  $disbursement_id = '587cc7ea77535fb94bb4e8eb';

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

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

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
Parameter Description
disbursement_id
required
string ID of the disbursement to retrieve
The disbursement_id must match the unique disbursement ID provided in our success response at disbursement creation precisely

Get Disbursement Response

Example Get Disbursement Response

{
  "user_id": "5785e6334d7b410667d355c4",
  "external_id": "disbursement_12345",
  "amount": 500000,
  "bank_code": "BCA",
  "account_holder_name": "Rizky",
  "disbursement_description": "Custom description",
  "status": "PENDING",
  "id": "57c9010f5ef9e7077bcb96b6",
  "email_to": ["test+to1@instamoney.co","test+to2@instamoney.co"],
  "email_cc": ["test+cc@instamoney.co"],
  "email_bcc": ["test+bcc@instamoney.co"]
}
Parameter Description
id Unique disbursement ID
user_id Your Instamoney Business ID
external_id Custom ID set at disbursement creation. Our customers often use a phone number, email address, or transaction/order ID
amount Amount to disburse
bank_code Destination bank code. See bank codes
account_holder_name Bank account name as per the bank's records. Used for verification and error/customer support scenarios
disbursement_description This is the description you give us :)
status PENDING Transfer is initiated.
COMPLETED Bank has confirmed transmission of funds.
FAILED Bank rejected disbursement. We will not retry.
failure_code (optional) INSUFFICIENT_BALANCE The balance in your account is insufficient to make the disbursement in the desired amount
UNKNOWN_BANK_NETWORK_ERROR The bank networks have returned an unknown error to us. We are unable to predict whether the disbursement will succeed should you retry the same disbursement request.
TEMPORARY_BANK_NETWORK_ERROR The bank networks are experiencing a temporary error. Please retry the disbursement in 1-3 hours
INVALID_DESTINATION The banks have reported that the destination account is unregistered or blocked. If unsure about this, please retry again or contact the destination bank directly regarding the status of the destination account
SWITCHING_NETWORK_ERROR At least one of the switching networks is encountering an issue. Please retry the disbursement in 1-3 hours
REJECTED_BY_BANK The bank has rejected this transaction for unclear reasons. We are unable to predict whether the disbursement will succeed should you retry the same disbursement request.
TRANSFER_ERROR We’ve encountered a fatal error while processing this disbursement. Certain API fields in your request may be invalid. Please contact our customer support team for more information
TEMPORARY_TRANSFER_ERROR We’ve encountered a temporary issue while processing this disbursement. Please retry the disbursement in 1-2 hours

email_to Email addresses that get notified of disbursement details after the disbursement is completed.
This response parameter is only returned if this field is filled.
email_cc Email addresses that get notified as carbon copy receiver of disbursement details after the disbursement is completed.
This response parameter is only returned if this field is filled.
email_bcc Email addresses that get notified as blind carbon copy receiver of disbursement details after the disbursement is completed.
This response parameter is only returned if this field is filled.

Get Disbursement Errors

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

Get disbursement by external_id

Endpoint: Get Disbursement by external_id

GET https://api.instamoney.co/disbursements?external_id={external_id}

This endpoint queries the current status of all disbursements with requested external_id. This is often used to check the status of a transaction with external_id.

Get Disbursement Request

Example Get Disbursement Request

curl https://api.instamoney.co/disbursements?external_id=72655 -X GET \
  -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:
<?php
  require 'vendor/autoload.php';

  $options['secret_api_key'] = 'sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==';

  $instamoneyPHPClient = new InstamoneyClient\InstamoneyPHPClient($options);

  $external_id = 'disbursement_12345';

  $response = $instamoneyPHPClient->getDisbursementByExternalId($external_id);
  print_r($response);
?>
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

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

System.out.println("status: " + response.getStatus());
System.out.println("headers: " + response.getHeaders());
System.out.println("body:" + response.readEntity(String.class));
Query Description
external_id
required
string Custom ID of the disbursement set by the customer at disbursement creation
The external_id must match the external_id used at disbursement creation precisely

Get Disbursement Response

Example Get Disbursement Response

[{
  "user_id": "5785e6334d7b410667d355c4",
  "external_id": "disbursement_12345",
  "amount": 500000,
  "bank_code": "BCA",
  "account_holder_name": "Rizky",
  "disbursement_description": "Custom description",
  "status": "PENDING",
  "id": "57c9010f5ef9e7077bcb96b6"
},{
  "user_id": "5785e6334d7b410667d355c4",
  "external_id": "disbursement_12345",
  "amount": 450000,
  "bank_code": "BNI",
  "account_holder_name": "Jajang",
  "disbursement_description": "Custom description",
  "status": "COMPLETED",
  "id": "5a963089fd5fe5b6508f0b7b",
  "email_to": ["test+to1@instamoney.co","test+to2@instamoney.co"],
  "email_cc": ["test+cc@instamoney.co"],
  "email_bcc": ["test+bcc@instamoney.co"]
}]
Parameter Description
id Unique disbursement ID
user_id Your Instamoney Business ID
external_id Custom ID set at disbursement creation. Our customers often use a phone number, email address, or transaction/order ID
amount Amount to disburse
bank_code Destination bank code. See bank codes
account_holder_name Bank account name as per the bank's records. Used for verification and error/customer support scenarios
disbursement_description This is the description you give us :)
status PENDING Transfer is initiated.
COMPLETED Bank has confirmed transmission of funds.
FAILED Bank rejected disbursement. We will not retry.
failure_code (optional) INSUFFICIENT_BALANCE The balance in your account is insufficient to make the disbursement in the desired amount
UNKNOWN_BANK_NETWORK_ERROR The bank networks have returned an unknown error to us. We are unable to predict whether the disbursement will succeed should you retry the same disbursement request.
TEMPORARY_BANK_NETWORK_ERROR The bank networks are experiencing a temporary error. Please retry the disbursement in 1-3 hours
INVALID_DESTINATION The banks have reported that the destination account is unregistered or blocked. If unsure about this, please retry again or contact the destination bank directly regarding the status of the destination account
SWITCHING_NETWORK_ERROR At least one of the switching networks is encountering an issue. Please retry the disbursement in 1-3 hours
REJECTED_BY_BANK The bank has rejected this transaction for unclear reasons. We are unable to predict whether the disbursement will succeed should you retry the same disbursement request.
TRANSFER_ERROR We’ve encountered a fatal error while processing this disbursement. Certain API fields in your request may be invalid. Please contact our customer support team for more information
TEMPORARY_TRANSFER_ERROR We’ve encountered a temporary issue while processing this disbursement. Please retry the disbursement in 1-2 hours

email_to Email addresses that get notified of disbursement details after the disbursement is completed.
This response parameter is only returned if this field is filled.
email_cc Email addresses that get notified as carbon copy receiver of disbursement details after the disbursement is completed.
This response parameter is only returned if this field is filled.
email_bcc Email addresses that get notified as blind carbon copy receiver of disbursement details after the disbursement is completed.
This response parameter is only returned if this field is filled.

Get Disbursement Errors

Error Code Description
DIRECT_DISBURSEMENT_NOT_FOUND_ERROR
404
Could not find direct disbursement.

Disbursement callback

Endpoint: Disbursement Callback

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

Client client = ClientBuilder.newClient();
Entity payload = Entity.json("{ 'id' : '57e214ba82b034c325e84d6e' , 'user_id' : '57c5aa7a36e3b6a709b6e148' , 'external_id' : 'disbursement_123124123' , 'amount' : '50000, 'bank_code' : 'BCA' , 'instamoney_fee_amount' : ', 'account_holder_name' : 'INSTAMONEY' , 'transaction_id' : '57ec8b7e906aa2606ecf8ffc' , 'transaction_sequence' : '1799' , 'disbursement_id' : '57ec8b8130d2d0243f438e11' , 'disbursement_description' : 'Instamoney disbursement' , 'failure_code' : 'INVALID_DESTINATION' , 'is_instant' : 'alse, 'status' : 'FAILED' , 'updated' : '2016-10-10T08:15:03.404Z' , 'created' : '2016-10-10T08:15:03.404Z' , 'email_to' : ' 'test+to1@instamoney.co' , 'test+to2@instamoney.co '], 'email_cc' : ' 'test+cc@instamoney.co '], 'email_bcc' : ' 'test+bcc@instamoney.co ']}");
Response response = client.target("https://yourcompany.com/disbursement_callback_url")
  .request(MediaType.APPLICATION_JSON_TYPE)
  .post(payload);

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

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

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

Disbursement Callback Request

Example Disbursement Callback Request

curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "X-CALLBACK-TOKEN: c2tfdGVzdF9PWUNFZkw1eGdMTCtsOFp2SzdRYVNHR1ZNTjczb05FcGszeXorUnhuLzJiUy9MQ2dDUVorZ3c9PTo=" \
     --data-binary "{
    \"id\": \"57e214ba82b034c325e84d6e\",
    \"user_id\": \"57c5aa7a36e3b6a709b6e148\",
    \"external_id\": \"disbursement_123124123\",
    \"amount\": 150000,
    \"bank_code\": \"BCA\",
    \"account_holder_name\": \"INSTAMONEY\",
    \"disbursement_description\": \"Instamoney disbursement\",
    \"failure_code\": \"INVALID_DESTINATION\",
    \"is_instant\": false,
    \"status\": \"FAILED\",
    \"updated\": \"2016-10-10T08:15:03.404Z\",
    \"created\": \"2016-10-10T08:15:03.404Z\",
    \"email_to\": [\"test+to1@instamoney.co\", \"test+to2@instamoney.co\"],
    \"email_cc\": [\"test+cc@instamoney.co\"],
    \"email_bcc\": [\"test+bcc@instamoney.co\"]
}" \
'https://yourcompany.com/disbursement_callback_url'
Header Parameter Description
x-callback-token Your Instamoney unique callback token to verify the origin of the callback
webhook-id A unique identifier of every webhook to help you to handle double callback 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 webhook
Parameter Description
id Unique disbursement ID
user_id Your Instamoney Business ID
external_id Custom ID set at disbursement creation. Our customers often use a phone number, email address, or transaction/order ID
amount Amount to disburse
bank_code Destination bank code. See bank codes
account_holder_name Bank account name as per the bank's records. Used for verification and error/customer support scenarios
disbursement_description This is the description you give us
status COMPLETED Bank has confirmed transmission of funds.
FAILED Disbursement failed because of failure code
failure_code (optional) INSUFFICIENT_BALANCE The balance in your account is insufficient to make the disbursement in the desired amount
UNKNOWN_BANK_NETWORK_ERROR The bank networks have returned an unknown error to us. We are unable to predict whether the disbursement will succeed should you retry the same disbursement request.
TEMPORARY_BANK_NETWORK_ERROR The bank networks are experiencing a temporary error. Please retry the disbursement in 1-3 hours
INVALID_DESTINATION The banks have reported that the destination account is unregistered or blocked. If unsure about this, please retry again or contact the destination bank directly regarding the status of the destination account
SWITCHING_NETWORK_ERROR At least one of the switching networks is encountering an issue. Please retry the disbursement in 1-3 hours
REJECTED_BY_BANK The bank has rejected this transaction for unclear reasons. We are unable to predict whether the disbursement will succeed should you retry the same disbursement request.
TRANSFER_ERROR We’ve encountered a fatal error while processing this disbursement. Certain API fields in your request may be invalid. Please contact our customer support team for more information
TEMPORARY_TRANSFER_ERROR We’ve encountered a temporary issue while processing this disbursement. Please retry the disbursement in 1-2 hours

email_to Email addresses that get notified of disbursement details after the disbursement is completed.
This callback parameter is only returned if this field is filled.
email_cc Email addresses that get notified as carbon copy receiver of disbursement details after the disbursement is completed.
This callback parameter is only returned if this field is filled.
email_bcc Email addresses that get notified as blind carbon copy receiver of disbursement details after the disbursement is completed.
This callback parameter is only returned if this field is filled.
is_instant Indicates whether the disbursement is being disbursed instantly

Disbursement Callback Errors

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

Get available disbursement banks

Endpoint: Get Available Disbursement Banks

GET https://api.instamoney.co/available_disbursements_banks

Example Get Available Disbursement Banks Request

curl https://api.instamoney.co/available_disbursements_banks -X GET \
    -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:
<?php
  require 'vendor/autoload.php';

  $options['secret_api_key'] = 'sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==';

  $instamoneyPHPClient = new InstamoneyClient\InstamoneyPHPClient($options);

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

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

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

This API endpoint will provide you the current list of banks we support for disbursements. We support transfers to 140+ banks in Indonesia, including some BPDs and BPRs, and virtual accounts of major banks (BRI, BNI, Mandiri, CIMB Niaga, Permata, BTN, and NOBU Bank). We also support disbursements to major e-wallets (GoPay, OVO, and Mandiri e-cash). If you would like us to support payment to a specific destination, please contact us at support@instamoney.co.

Get Available Disbursement Banks Response

Get Available Disbursement Banks Response

[
  {
    "name": "Bank Mandiri",
    "code": "MANDIRI",
    "can_disburse": true,
    "can_name_validate": true
  },
  {
    "name": "Bank Rakyat Indonesia (BRI)",
    "code": "BRI",
    "can_disburse": true,
    "can_name_validate": true
  },
  {
    "name": "Bank Central Asia (BCA)",
    "code": "BCA",
    "can_disburse": true,
    "can_name_validate": true
  }
]
Parameter Description
name Full name of the bank or e-wallet
code Code of the bank or e-wallet you would like to disburse to

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

Create eWallet Charge

Endpoint: Create eWallet Charge Request

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

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 Instamoney! This API will also be used to support tokenized payment flow and auth/capture payment flow in the near future. Click here to view older versions.

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

eWallet

Request Parameters

Example: Create eWallet Charge Request

curl https://api.instamoney.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 {
    Instamoney.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";

    Map<String, String> channelProperties = new HashMap<>();
    channelProperties.put("success_redirect_url", "https://dashboard.instamoney.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 (InstamoneyException e) {
    e.printStackTrace();
}
<?php
use Instamoney\Instamoney;
require 'vendor/autoload.php';

Instamoney::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.instamoney.co/register/1',
    ],
    'metadata' => [
        'branch_code' => 'tree_branch'
    ]
];
$createEWalletCharge = \Instamoney\EWallets::createEWalletCharge($ewalletChargeParams);
var_dump($createEWalletCharge);

?>
from instamoney 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.instamoney.co/register/1",
    },
    metadata={
        "branch_code": "tree_branch",
    },
)
instamoney.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrRuIruiRuiQYNCk9dN5lSfk+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.instamoney.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("instamoney-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.instamoney.co/register/1',
  },
  metadata: {
    branch_code: 'tree_branch'
  }
});
console.log(resp);
Body Parameter Type Description
reference_id
required
string Reference ID provided by merchant (255 characters)
Note: It has to be unique per charge request
currency
required
string Currency used for the transaction in ISO4217 format - IDR
amount
required
number Transaction amount to be paid
Min - 100 IDR
Max - based on eWallet holding limit
checkout_method
required
string Checkout method determines the payment flow used to process the transaction
ONE_TIME_PAYMENT is used for single guest checkouts
TOKENIZED_PAYMENT can be used for recurring payment
channel_code
required if checkout_method = ONE_TIME_PAYMENT, optional if checkout_method = TOKENIZED_PAYMENT
string Channel Code specifies which eWallet will be used to process the transaction - ID_OVO, ID_DANA, ID_LINKAJA, ID_SHOPEEPAY
channel_properties
required if checkout_method = ONE_TIME_PAYMENT, optional if checkout_method = TOKENIZED_PAYMENT
object Channel specific information required for the transaction to be initiated
OVO required fields
Key Value
mobile_number
required
string Mobile number of customer in E.164 format (e.g. +628123123123)
DANA, LINKAJA, SHOPEEPAY required fields
Key Value
success_redirect_url
required
string URL where the end-customer is redirected if the authorization is successful
payment_method_id
required if checkout_method = TOKENIZED_PAYMENT, optional if checkout_method = ONE_TIME_PAYMENT
string ID of the payment method
customer_id
optional
string ID of the customer object to which the account token will be linked to
basket
optional
array Array of objects describing the item(s) purchased
Object parameters details
Key Value
reference_id
required
string Merchant's identifer for specific product <= 255 characters
name
required
string Name of product
category
required
string Merchant category for item - e.g. Electronics
currency
required
string Currency used for the transaction in ISO4217 format - IDR
price
required
number Price per unit in basket currency
quantity
required
number Number of units of this item in the basket
type
required
string Type of product - PRODUCT or SERVICE
url
optional
string URL to e-commerce page of the item
description
optional
string Description of product
sub_category
optional
string Merchant sub-category for item - e.g. Mobile Phone
metadata
optional
object Object of additional information the user may use. Users define the JSON properties and values.
You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
This will only be used by the user and not Instamoney.
metadata
optional
object Object of additional information the user may use. Users define the JSON properties and values.
You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
This will only be used by the user and not Instamoney.

Response Parameters

Example: Create eWallet Charge Request API Success Response

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

Error Codes

Example: Create eWallet Charge Request API Error Response

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

Get eWallet Charge Status

Endpoint: Get eWallet Charge Status

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

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

Version

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

Request Parameters

Example: Check eWallet Charge Status Request

curl 'https://api.instamoney.co/ewallets/charges/ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2' \
   -X GET \
   -u xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman:
try {
    Instamoney.apiKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==";

    EWalletCharge charge = EWalletCharge.getEWalletChargeStatus("ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2");
} catch (InstamoneyException e) {
    e.printStackTrace();
}
<?php

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

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

$charge_id = 'ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2';
$getEWalletChargeStatus = \Instamoney\EWallets::getEWalletChargeStatus($charge_id);
var_dump($getEWalletChargeStatus);

?>
from instamoney import EWallet

ewallet_charge = EWallet.get_ewallet_charge_status(
    charge_id="ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2",
)
instamoney.Opt.SecretKey = "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw=="

data := ewallet.GetEWalletChargeStatusParams{
    ChargeID: "ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2",
}

charge, chargeErr := ewallet.GetEWalletChargeStatus(&data)
if chargeErr != nil {
    log.Fatal(chargeErr)
}

fmt.Printf("retrieved e-wallet charge: %+v\n", charge)
const x = new require("instamoney-node")({
  secretKey:
    "xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk+R1l9Wbe+rSiCwZ3jw==",
});

const { EWallet } = x;
const ewalletSpecificOptions = {};
const ew = new EWallet(ewalletSpecificOptions);

const resp = await ew.getEWalletChargeStatus({
  chargeID: 'ewc_bb8c3po-c3po-r2d2-c3po-r2d2c3por2d2',
});
console.log(resp);
Query Parameter Type Description
charge_id
required
string You need to specify the id in the response body when hitting create eWallet charge request

Example: Check eWallet Charge Status Success Responses

Check eWallet Charge Status Success Responses

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

Error Codes

Example: Create eWallet Charge Request API Error Response

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

Payment Status Callback

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

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

Callback Payload

Example: Success Payment Callback Payload

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

webhook-id
string A unique identifier of every webhook to help you to handle double callback 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 webhook

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

Failure Codes

Example: Failed Payment Callback Payload

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

Customers

Customers are your end-customers. This can be used to easily identify linked accounts for a specific end-customer in direct debit.

Create Customer

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

Endpoint: Create Customer

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

Create Customer - Request

Example Create Customer Request

curl https://api.instamoney.co/customers -X POST \
   -H 'Content-Type: application/json' \
   -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
   --data '
     {
      "external_id": "r-1234",
      "customer_type": "INDIVIDUAL",
      "given_name": "Ichwano",
      "surname": "Sembo",
      "address": {
          "country_code": "ID",
          "province": "DKI Jakarta",
          "city": "Jakarta Selatan",
          "line_1": "Jl. Senayan 1 No.15"
      },
      "date_of_birth": "11-01-1990",
      "identification": {
          "ktp_number": "0987654321320987",
          "npwp_number": "098765432132098"
      },
      "email": "ichwano@email.com",
      "mobile_number": "+628111555777",
      "phone_number": "+622199990000"
    }
   '
<?php
  $url = "https://api.instamoney.co/customers";
  $apiKey = "sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:";
  $headers = [];
  $headers[] = "Content-Type: application/json";
  $data = [
    "external_id" => "r-1234",
    "customer_type" => "INDIVIDUAL",
    "given_name" => "Ichwano",
    "surname" => "Sembo",
    "address" => [
      "country_code" => "ID",
      "province" => "DKI Jakarta",
      "city" => "Jakarta Selatan",
      "line_1" => "Jl. Senayan 1 No.15"
    ],
    "date_of_birth" => "11-01-1990",
    "identification" => [
      "ktp_number" => "0987654321320987",
      "npwp_number" => "098765432132098"
    ],
    "email" => "ichwano@email.com",
    "mobile_number" => "+628111555777",
    "phone_number" => "+622199990000"
  ];

  $curl = curl_init();

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

  $result = curl_exec($curl);
  echo $result;
Request Body Parameter Description
external_id
required
string Your unique id for this customer

Characters Special and alphanumeric
Maximum length 100 maximum characters
customer_type
required
string Legal entity.
Valid values: INDIVIDUAL or BUSINESS
given_name
conditionally required
string Given name(s). Required if customer_type is INDIVIDUAL. Only allowed if customer_type is INDIVIDUAL
surname
optional
string Surname of the customer
business_name
conditionally required
string Required if customer_type is BUSINESS. Only allowed if customer_type is BUSINESS
address
optional
object Customer's address
address.country_code
optional
string Customer’s country. 2-letter ISO 3166-2 country code. Refer to code standard here. If customer_type is BUSINESS, the country in which the corporate entity is registered. If customer_type is INDIVIDUAL, a country in which the customer holds nationality/td>
address.state
optional
string Customer’s state
address.province
optional
string Customer’s province
address.city
optional
string Customer’s city
address.suburb
optional
string Customer’s suburb
address.postal_code
optional
string Customer’s postal code
address.line_1
optional
string First line of customer’s address. Typically used for building name and / or apartment number
address.line_2
optional
string Second line of customer’s address. Typically used for street name and building number
date_of_birth
optional
string Date of Birth. Only allowed if customer_type is INDIVIDUAL. ISO 8601 format YYYY-MM-DD
date_of_registration
optional
string Date of Registration. Only allowed if customer_type is BUSINESS. ISO 8601 format YYYY-MM-DD
identification
optional
object A legal document that verifies the identity of the customer
identification.ktp_number
optional
string Kartu Tanda Penduduk (national identity card number) of the customer.
Only allowed if customer_type is INDIVIDUAL
Characters 16 characters
identification.npwp_number
optional
string Nomor Pokok Wajib Pajak (tax number) of the customer
Only allowed if customer_type is INDIVIDUAL
Characters 15 characters
identification.drivers_license
optional
string Surat Izin Mengemudi (driver’s licence) number of the customer
Only allowed if customer_type is INDIVIDUAL
Characters 14 characters
identification.passport_number
optional
string Passport number of the customer.
Only allowed if customer_type is INDIVIDUAL
If provided, should provide passport_country. In the case of multiple passports, please choose the passport of the country closest to Indonesia
identification.country
conditionally required
string Passport country of the customer.
Only allowed if customer_type is INDIVIDUAL. 2-letter ISO 3166-2 country code. Refer to code standard here.
Required if passport_number is provided.
identification.business_tax_id
optional
string Tax identification number of the business in its country of registration.
Examples:
- Nomor Pokok Wajib Pajak for indonesian businesses
- Business Registration number for Hong Kong businesses
- Unique Entity Number for Singaporean businesses
Only allowed if customer_type is BUSINESS. If provided, should provide business_tax_id_country.
identification.business_tax_id_country
conditionally required
string Country for tax identification number of the business.
Only allowed if customer_type is BUSINESS. 2-letter ISO 3166-2 country code. Refer to code standard here. Required if business_tax_id is provided
email
optional
string Customer’s email address. Recommended if you want to notify the customer of the transaction status
Should include the top-level domain name
Example: abc@email.com
mobile_number
optional
string Customer’s mobile number with international prefix. Recommended if you want to notify the customer of the transaction status
Example: +62812XXXXXX
phone_number
optional
string Customer’s land line or alternate phone number with international prefix
Example: +6221XXXXXXXX

Create Customer - Response

Example Create Customer Success Response

{
  "id": "5c1774e76966b43a5b8198fb",
  "external_id": "r-1234",
  "customer_type": "INDIVIDUAL",
  "given_name": "Ichwano",
  "surname": "Sembo",
  "address": {
      "country_code": "ID",
      "province": "DKI Jakarta",
      "city": "Jakarta Selatan",
      "line_1": "Jl. Senayan 1 No.15"
  },
  "date_of_birth": "11-01-1990",
  "identification": {
      "ktp_number": "0987654321320987",
      "npwp_number": "098765432132098"
  },
  "email": "ichwano@email.com",
  "mobile_number": "+628111555777",
  "phone_number": "+622199990000",
  "created": "2018-12-12T13:50:12.000Z",
  "updated": "2018-12-12T13:50:12.000Z"
}
Parameter Description
id string Unique ID generated by Instamoney for the particular end-customer
external_id string Identifier you provided during request
customer_type string Type of customer: INDIVIDUAL or BUSINESS
given_name string If customer_type is INDIVIDUAL: Primary of first name/s of the customer
surname string If customer_type is INDIVIDUAL: Surname of the customer
business_name string If customer_type is BUSINESS: Name of business
address object Object containing the specific customer's address information
date_of_birth string If customer_type is INDIVIDUAL: Date of birth of the customer in YYYY-MM-DD format
date_of_registration string If customer_type is INDIVIDUAL: Date of registration of the business in YYYY-MM-DD format
identification object A legal document that verifies the identity of the customer
mobile_number string Mobile number of the customer
email string Email address of the customer
phone_number string Alternate or landline phone number
created object Timestamp in ISO 8601 GMT+0 when the customer object was made
updated object Timestamp in ISO 8601 GMT+0 when the customer object was last updated

Create Customer - Errors

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
INVALID_JSON_FORMAT
400
The request body is not a valid JSON format
DUPLICATE_CUSTOMER_ERROR
400
The external_id entered has been used before. Please enter a unique external_id and try again

Update Customer

Updates an existing customer

Endpoint: Update Customer

PUT https://api.instamoney.co/customers/:id

Update Customer - Request

Example Update Customer Request

curl https://api.instamoney.co/customers/5c1774e76966b43a5b8198fb -X PUT \
   -H 'Content-Type: application/json' \
   -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
   --data '{
     {
      "given_name": "Ahmad",
      "surname": "Shahab",
      "phone_number": "+622199990000"
    }
   }'
Request Body Parameter Description
external_id
optional
string Your unique id for this customer

Characters Special and alphanumeric
Maximum length 100 maximum characters
given_name
optional
string Given name(s). Required if customer_type is INDIVIDUAL. Only allowed if customer_type is INDIVIDUAL
surname
optional
string Surname of the customer
business_name
optional
string Required if customer_type is BUSINESS. Only allowed if customer_type is BUSINESS
address
optional
object Customer's address
address.country_code
optional
string Customer’s country. 2-letter ISO 3166-2 country code. Refer to code standard here. If customer_type is BUSINESS, the country in which the corporate entity is registered. If customer_type is INDIVIDUAL, a country in which the customer holds nationality/td>
address.state
optional
string Customer’s state
address.province
optional
string Customer’s province
address.city
optional
string Customer’s city
address.suburb
optional
string Customer’s suburb
address.postal_code
optional
string Customer’s postal code
address.line_1
optional
string First line of customer’s address. Typically used for building name and / or apartment number
address.line_2
optional
string Second line of customer’s address. Typically used for street name and building number
date_of_birth
optional
string Date of Birth. Only allowed if customer_type is INDIVIDUAL. ISO 8601 format YYYY-MM-DD
date_of_registration
optional
string Date of Registration. Only allowed if customer_type is BUSINESS. ISO 8601 format YYYY-MM-DD
identification
optional
object A legal document that verifies the identity of the customer
identification.ktp_number
optional
string Kartu Tanda Penduduk (national identity card number) of the customer.
Only allowed if customer_type is INDIVIDUAL
Characters 16 characters
identification.npwp_number
optional
string Nomor Pokok Wajib Pajak (tax number) of the customer
Only allowed if customer_type is INDIVIDUAL
Characters 15 characters
identification.drivers_license
optional
string Surat Izin Mengemudi (driver’s licence) number of the customer
Only allowed if customer_type is INDIVIDUAL
Characters 14 characters
identification.passport_number
optional
string Passport number of the customer.
Only allowed if customer_type is INDIVIDUAL
If provided, should provide passport_country. In the case of multiple passports, please choose the passport of the country closest to Indonesia
identification.country
conditionally required
string Passport country of the customer.
Only allowed if customer_type is INDIVIDUAL. 2-letter ISO 3166-2 country code. Refer to code standard here.
Required if passport_number is provided.
identification.business_tax_id
optional
string Tax identification number of the business in its country of registration.
Examples:
- Nomor Pokok Wajib Pajak for indonesian businesses
- Business Registration number for Hong Kong businesses
- Unique Entity Number for Singaporean businesses
Only allowed if customer_type is BUSINESS. If provided, should provide business_tax_id_country.
identification.business_tax_id_country
conditionally required
string Country for tax identification number of the business.
Only allowed if customer_type is BUSINESS. 2-letter ISO 3166-2 country code. Refer to code standard here. Required if business_tax_id is provided
email
optional
string Customer’s email address. Recommended if you want to notify the customer of the transaction status
Should include the top-level domain name
Example: abc@email.com
mobile_number
optional
string Customer’s mobile number with international prefix. Recommended if you want to notify the customer of the transaction status
Example: +62812XXXXXX
phone_number
optional
string Customer’s land line or alternate phone number with international prefix
Example: +6221XXXXXXXX

Update Customer - Response

Example Update Customer Success Response

{
  "id": "5c1774e76966b43a5b8198fb",
  "external_id": "r-1234",
  "customer_type": "INDIVIDUAL",
  "given_name": "Ahmad",
  "surname": "Shahab",
  "address": {
      "country_code": "ID",
      "province": "DKI Jakarta",
      "city": "Jakarta Selatan",
      "line_1": "Jl. Senayan 1 No.15"
  },
  "date_of_birth": "11-01-1990",
  "identification": {
      "ktp_number": "0987654321320987",
      "npwp_number": "098765432132098"
  },
  "email": "ichwano@email.com",
  "mobile_number": "+628111555777",
  "phone_number": "+622199990000",
  "created": "2018-12-12T13:50:12.000Z",
  "updated": "2018-12-12T13:50:12.000Z"
}
Parameter Description
id string Unique ID generated by Instamoney for the particular end-customer
external_id string Identifier you provided during request
customer_type string Type of customer: INDIVIDUAL or BUSINESS
given_name string If customer_type is INDIVIDUAL: Primary of first name/s of the customer
surname string If customer_type is INDIVIDUAL: Surname of the customer
business_name string If customer_type is BUSINESS: Name of business
address object Object containing the specific customer's address information
date_of_birth string If customer_type is INDIVIDUAL: Date of birth of the customer in YYYY-MM-DD format
date_of_registration string If customer_type is INDIVIDUAL: Date of registration of the business in YYYY-MM-DD format
identification object A legal document that verifies the identity of the customer
mobile_number string Mobile number of the customer
email string Email address of the customer
phone_number string Alternate or landline phone number
created object Timestamp in ISO 8601 GMT+0 when the customer object was made
updated object Timestamp in ISO 8601 GMT+0 when the customer object was last updated

Update Customer - Errors

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
INVALID_JSON_FORMAT
400
The request body is not a valid JSON format
CUSTOMER_NOT_FOUND_ERROR
400
Could not find customer.
DUPLICATE_CUSTOMER_ERROR
400
The external_id entered has been used before. Please enter a unique external_id and try again

Get Customer by Reference ID

Returns an array with a single object which contains the customer corresponding to the unique external_id. Returns an empty array if there is no customer corresponding to the external_id.

Endpoint: Get Customer by Reference ID

GET https://api.instamoney.co/customers?external_id={external_id}

Get Customer by Reference ID - Request

Example Get Customer by Reference ID Request

curl https://api.instamoney.co/customers?external_id=72655 -X GET \
  -u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:
<?php
  $url = "https://api.instamoney.co/customers";
  $apiKey = "sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:";
  $headers = [];
  $headers[] = "Content-Type: application/json";

  $queryString = "?external_id=72655";

  $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;
Query String Parameter Description
external_id
optional
string Unique ID you provided in the Create Customer request
The external_id must match the external_id used at customer creation precisely

Get Customer by External ID - Response

Example Get Customer by Reference ID Success Response

[{
  "id": "5c1774e76966b43a5b8198fb",
  "external_id": "r-1234",
  "customer_type": "INDIVIDUAL",
  "given_name": "Ichwano",
  "surname": "Sembo",
  "address": {
      "country_code": "ID",
      "province": "DKI Jakarta",
      "city": "Jakarta Selatan",
      "line_1": "Jl. Senayan 1 No.15"
  },
  "date_of_birth": "11-01-1990",
  "identification": {
      "ktp_number": "0987654321320987",
      "npwp_number": "098765432132098"
  },
  "email": "ichwano@email.com",
  "mobile_number": "+628111555777",
  "phone_number": "+622199990000",
  "created": "2018-12-12T13:50:12.000Z",
  "updated": "2018-12-12T13:50:12.000Z"
}]
Parameter Description
id string Unique ID generated by Instamoney for the particular end-customer
external_id string Identifier you provided during request
customer_type string Type of customer: INDIVIDUAL or BUSINESS
given_name string If customer_type is INDIVIDUAL: Primary of first name/s of the customer
surname string If customer_type is INDIVIDUAL: Surname of the customer
business_name string If customer_type is BUSINESS: Name of business
address object Object containing the specific customer's address information
date_of_birth string If customer_type is INDIVIDUAL: Date of birth of the customer in YYYY-MM-DD format
date_of_registration string If customer_type is INDIVIDUAL: Date of registration of the business in YYYY-MM-DD format
identification object A legal document that verifies the identity of the customer
mobile_number string Mobile number of the customer
email string Email address of the customer
phone_number string Alternate or landline phone number
created object Timestamp in ISO 8601 GMT+0 when the customer object was made
updated object Timestamp in ISO 8601 GMT+0 when the customer object was last updated

Get Customer by External ID - Errors

See other common errors here.

Direct Debit

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

Initialize Linked Account Tokenization

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

Endpoint: Initialize Linked Account Tokenization

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

Initialize Linked Account Tokenization - Request

Example Initialize Linked Account Tokenization Request

curl https://api.instamoney.co/linked_account_tokens/auth -X POST \
   -u sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0: \
   -H 'Content-Type: application/json' \
   --data-raw '{
    "customer_id": "ba830b92-4177-476e-b097-2ad5ae4d3e55",
    "channel_code": "DC_BRI",
    "properties": {
        "account_mobile_number": "62818555988",
        "card_last_four": "1234",
        "card_expiry": "06/24",
        "account_email": "email@email.com"
    }
}'
<?php
  $url = "https://api.instamoney.co/linked_account_tokens/auth";
  $apiKey = "sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0:";
  $headers = [];
  $headers[] = "Content-Type: application/json";
  $data = [
    "customer_id" => "ba830b92-4177-476e-b097-2ad5ae4d3e55",
    "channel_code" => "DC_BRI",
    "properties" => [
      "account_mobile_number" => "62818555988",
      "card_last_four" => "1234",
      "card_expiry" => "06/24",
      "account_email" => "email@email.com"
    ]
  ];

  $curl = curl_init();

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

  $result = curl_exec($curl);
  echo $result;
Request Body Parameter Description
customer_id
required
string ID of the customer object to which the account token will be linked to
channel_code
required
string Identifier for the specific channel of the account to be linked. Code must be in uppercase.

Supported channel codes: DC_BRI
properties
optional
object JSON that contains information needed to proceed with authorization. Values inside properties change based on type of account:

For Debit Card Linking (BRI):
Key Value
account_mobile_number
required
Mobile number of the customer registered to the partner channel
card_last_four
required
Last four digits of the debit card
card_expiry
required
Expiry month and year of the debit card (in MM/YY format)
account_email
required
Email address of the customer that is registered to the partner channel
metadata
optional
object A free-format JSON for additional information that you may use.

Initialize Linked Account Tokenization - Response

Example Initialize Linked Account Tokenization Success Response

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

Initialize Linked Account Tokenization - Errors

See other common errors here.

Error Code Description
CHANNEL_CODE_NOT_SUPPORTED_ERROR
400
Provided channel_code is not supported or has not yet activated for this account.
CUSTOMER_NOT_FOUND_ERROR
400
Provided customer_id in the request does not exist or access is unauthorized
CHANNEL_UNAVAILABLE
503
The target channel is currently unavailable. This is possibly due to partner channel downtime or error.

Validate OTP for Linked Account Token

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

Endpoint: Validate OTP for Linked Account Token

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

Validate OTP for Linked Account Token - Request

Example Validate OTP for Linked Account Token Request

curl https://api.instamoney.co/linked_account_tokens/lat-aa620619-124f-41db-995b-66a52abe036a/validate_otp -X POST \
   -u sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0: \
   -H 'Content-Type: application/json' \
   --data-raw '{
    "otp_code":123456
}'
<?php
  $linkedAccountTokenId = "lat-aa620619-124f-41db-995b-66a52abe036a";
  $url = "https://api.instamoney.co/linked_account_tokens/" . $linkedAccountTokenId . "/validate_otp";
  $apiKey = "sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0:";
  $headers = [];
  $headers[] = "Content-Type: application/json";
  $data = [
    "otp_code" => "123456"
  ];

  $curl = curl_init();

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

  $result = curl_exec($curl);
  echo $result;
Path Parameter Description
linked_account_token_id
required
string Linked account token id received from Initialize Account Authorization. This has the lat- prefix.
Request Body Parameter Description
otp_code
required
string OTP received by the customer from the partner bank for account linking

Validate OTP for Linked Account Token - Response

Example Validate OTP for Linked Account Token Success Response

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

Validate OTP for Linked Account Token - Errors

See other common errors here.

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

Retrieve Accessible Accounts by Linked Account Token

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

Endpoint: Get Accessible Accounts by Linked Account Token

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

Retrieve Accessible Accounts by Linked Account Token - Request

Example Get Accessible Accounts by Linked Account Token Request

curl https://api.instamoney.co/linked_account_tokens/lat-aa620619-124f-41db-995b-66a52abe036a/accounts -X GET \
   -u sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0: 
<?php
  $linkedAccountTokenId = "lat-aa620619-124f-41db-995b-66a52abe036a";
  $url = "https://api.instamoney.co/linked_account_tokens/" . $linkedAccountTokenId . "/accounts";
  $apiKey = "sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0:";
  $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;
Path Parameter Description
linked_account_token_id
required
string Linked account token id received from Initialize Account Authorization. This has the lat- prefix.

Retrieve Accessible Accounts by Linked Account Token - Response

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

Example Get Accessible Accounts by Linked Account Token Success Response

[{
    "id": "la-aa620619-124f-41db-995b-66a52abe036a",
    "channel_code": "DC_BRI",
    "type": "DEBIT_CARD",
    "properties": {
        "account_mobile_number": "62818555988",
        "card_last_four": "1234",
        "card_expiry": "06/24",
        "account_email": "email@email.com"
    }
}]
Parameter Description
id string Unique identifier for the bank account. This has a prefix of la-.
channel_code string Code identifier for the channel
type string Type of account that has been linked.
Expected value: DEBIT_CARD
properties object Object containing information regarding the account. The values inside properties change based on the type of account:


For type DEBIT_CARD (BRI):
Key Value
card_last_four stringLast four digits of the debit card
card_expiry stringExpiry month and year of the debit card (in MM/YY format)
currency stringCurrency of the account in ISO 4217
description stringDescription of the account (provided by the bank)

Retrieve Accessible Accounts by Linked Account Token - Errors

See other common errors here.

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

Create Payment Method

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

Endpoint: Create Payment Method

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

Create Payment Method - Request

Example Create Payment Method Request

curl https://api.instamoney.co/payment_methods -X POST \
   -u sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0: \
   -H 'Content-Type: application/json' \
   --data-raw '{
    "customer_id": "ba830b92-4177-476e-b097-2ad5ae4d3e55",
    "type": "DEBIT_CARD",
    "properties": {
        "id": "la-aa620619-124f-41db-995b-66a52abe036a"
    }
}'
<?php
  $url = "https://api.instamoney.co/payment_methods";
  $apiKey = "sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0:";
  $headers = [];
  $headers[] = "Content-Type: application/json";
  $data = [
    "customer_id" => "ba830b92-4177-476e-b097-2ad5ae4d3e55",
    "type" => "DEBIT_CARD",
    "properties" => [
      "id" => "la-aa620619-124f-41db-995b-66a52abe036a"
    ]
  ];

  $curl = curl_init();

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

  $result = curl_exec($curl);
  echo $result;
Request Body Parameter Description
customer_id
required
string ID of the customer object to which the account token will be linked to
type
required
string Type of payment method

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


For Debit Card Linking (BRI):
Key Value
id
required
ID of the account from which payments will be pulled from. You can retrieve account ID by using this API
metadata
optional
object A free-format JSON for additional information that you may use.

Create Payment Method - Response

Example Create Payment Method Success Response

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


For type DEBIT_CARD (BRI):
Key Value
card_last_four stringLast four digits of the debit card
card_expiry stringExpiry month and year of the debit card (in MM/YY format)
currency stringCurrency of the account in ISO 4217
description stringDescription of the account (provided by the bank)
customer_id string ID of the customer object in which this payment method is linked to
status
required
string Status of the payment method.
Will be equal to ACTIVE upon creation.
created string ISO 8601 timestamp when the payment method was created
updated string ISO 8601 timestamp when the payment method information was updated
metadata object A free-format JSON for additional information that you provded during request.

Create Payment Method - Errors

See other common errors here.

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

Create Direct Debit Payment

Create a debit to pull funds from the end customer's account using an active payment method

Endpoint: Create Direct Debit Payment

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

Create Direct Debit Payment - Request

Example Create Direct Debit Payment Request

curl https://api.instamoney.co/direct_debits -X POST \
   -u sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0: \
   -H 'Content-Type: application/json' \
   -H 'Idempotency-key: Test_Idempotent_Key'\
   --data-raw '{
    "reference_id": "customer_test_reference_id",
    "payment_method_id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
    "currency": "IDR",
    "amount": 1500,
    "enable_otp": true,
    "callback_url": "https://payment-callback-listener/"
}'
<?php
  $url = "https://api.instamoney.co/direct_debits";
  $apiKey = "sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0:";
  $headers = [
    "Content-Type" => "application/json",
    "Idempotency-key" => "Test_Idempotent_Key",
    ];
  $data = [
    "reference_id" => "customer_test_reference_id",
    "payment_method_id" => "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
    "currency" => "IDR",
    "amount" => 1500,
    "enable_otp" => true,
    "callback_url" => "https://payment-callback-listener/"
    ];

  $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;
Header Description
Idempotency-key
required
string Provided by the merchant to prevent duplicate requests. May be equal to reference_id or any GUID.
Note: Max 100 characters
Request Body Parameter Description
reference_id
required
string Merchant-provided identifier for this transaction
Note: Max 255 characters
payment_method_id
required
string Instamoney’s identifier for specific payment method. You can create one using Create Payment Method API if you haven't already generated one. Use Get Payment Method API to retrieve the ID
currency
required
string Currency of amount to debit in ISO 4217. e.g. "IDR"
amount
required
number Amount to debit from the end-customer’s account
Note: Maximum amount that can be charged without OTP is 999,999
callback_url
required
string URL where payment notification will be sent after transaction process
Note: Max 255 characters
enable_otp
optional
boolean
true to charge end customer's account with OTP
false to charge end customer's account without OTP
description
optional
string Description for the direct debit transaction.
basket
optional
array Array of objects describing the item/s purchased using direct debit
Key Value
reference_id
required
stringMerchant’s identifier for specific product (ie. SKU)
name
required
stringName of product
market
required
string2-letter ISO 3166-2 country code indicating target merchant’s country of operations
type
required
stringType of product
description
optional
stringDescription of product
category
optional
stringMerchant category for item
sub-category
optional
stringMerchant sub-category for item
price
optional
stringPrice per unit in basket currency
url
optional
stringProduct URL with product details
metadata
optional
stringAdditional object that may be used for additional product attributes
quantity
optional
stringNumber of units of this item in the basket
metadata
optional
object Object of additional information the user may use. User defines the JSON properties and values. You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long

Create Payment - Response

Example Create Payment Success Response

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

Create Payment - Errors

Example Create Payment Error Response

{
    "error_code" : "DUPLICATE_ERROR",
    "message" : "Idempotency key has been used before. Use a unique idempotency key and try again"
}
Error Code Description
DUPLICATE_ERROR
409
Idempotency key has been used before. Use a unique idempotency key and try again.
PAYMENT_METHOD_NOT_FOUND_ERROR
400
Provided payment_method_id is invalid, not found or access is unauthorized
INVALID_PAYMENT_METHOD_ERROR
503
The payment method has expired or has been invalidated.

Validate OTP for Direct Debit Payment

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

Endpoint: Validate OTP for Direct Debit Payment

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

Validate Direct Debit Payment OTP - Request

Example Validate Direct Debit Payment OTP Request

curl https://api.instamoney.co/direct_debits/ddpy-623dca10-5dad-4916-test/validate_otp/ -X GET \
   -u sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0: \
   --data-raw '{
    "otp_code": "111222"
    }'
<?php
  $direct_debit_id = "ddpy-623dca10-5dad-4916-test";
  $url = "https://api.instamoney.co/direct_debits/" . $direct_debit_id . "/validate_otp";
  $apiKey = "sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0:";
  $headers = [];
  $headers[] = "Content-Type: application/json";
  $data = [
    "otp_code" => "111222"
  ];

  $curl = curl_init();

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

  $result = curl_exec($curl);
  echo $result;
Path Parameter Description
direct_debit_id
required
string Merchant provided identifier for specified direct debit transaction
Request Body Parameter Description
otp_code
required
string One-time-password input from end customer

Validate Payment OTP - Response

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

Example Get Payment Status by ID Success Response

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

Validate Payment OTP - Errors

Example Create Payment Error Response

{
    "error_code" : "DUPLICATE_ERROR",
    "message" : "Idempotency key has been used before. Use a unique idempotency key and try again"
}
Error Code Description
DATA_NOT_FOUND_ERROR
404
Provided direct_debit_id does not exist or access is unauthorized
INVALID_OTP_ERROR
400
OTP provided is invalid
EXPIRED_OTP_ERROR
400
OTP provided has expired
MAX_OTP_ATTEMPTS_ERROR
400
Payment method reached the channel’s allowed maximum attempts for OTP verification
DIRECT_DEBIT_ALREADY_COMPLETED
409
The request is a duplicate of an already processed linked account token that has been successfully completed.
DIRECT_DEBIT_ALREADY_FAILED
409
The request is a duplicate of an already processed linked account token that has failed.

Get Payment Methods by Customer ID

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

Endpoint: Get Payment Methods by Customer ID

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

Get Payment Methods by Customer ID - Request

Example Get Payment Methods by Customer ID Request

curl https://api.instamoney.co/payment_methods?customer_id=ba830b92-4177-476e-b097-2ad5ae4d3e55 -X GET \
   -u sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0: 
<?php
  $url = "https://api.instamoney.co/payment_methods";
  $apiKey = "sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0:";
  $headers = [];
  $headers[] = "Content-Type: application/json";

  $queryString = "?customer_id=ba830b92-4177-476e-b097-2ad5ae4d3e55";

  $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;
Query String Parameter Description
customer_id
required
string Customer object ID of interest

Get Payment Methods by Customer ID - Response

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

Example Get Payment Methods by Customer ID Success Response

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


For type DEBIT_CARD (BRI):
Key Value
card_last_four stringLast four digits of the debit card
card_expiry stringExpiry month and year of the debit card (in MM/YY format)
currency stringCurrency of the account in ISO 4217
description stringDescription of the account (provided by the bank)
customer_id string ID of the customer object in which this payment method is linked to
status string Status of the payment method.
Will be equal to ACTIVE upon creation.
created string ISO 8601 timestamp when the payment method was created
updated string ISO 8601 timestamp when the payment method information was updated
metadata object A free-format JSON for additional information that you provded during request.

Get Payment Methods by Customer ID - Errors

See other common errors here.

Get Direct Debit Payment Status by Reference ID

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

Endpoint: Get Payment Staus by Reference ID

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

Get Payment Status by Reference ID - Request

Example Payment Status by Reference ID Request

curl https://api.instamoney.co/direct_debits?reference_id=test_merchant_reference_id/ -X GET \
   -u sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0: 
<?php
  $url = "https://api.instamoney.co/direct_debits/";
  $apiKey = "sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0:";
  $headers = [];
  $headers[] = "Content-Type: application/json";

  $queryString = "?reference_id=test_merchant_reference_id";

  $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;
Query String Parameter Description
reference_id
required
string Merchant provided identifier for specified direct debit transaction

Get Payment Status by ID - Response

Example Get Payment Status by ID Success Response

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

Get Direct Debit Payment Status by ID

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

Endpoint: Get Payment Staus by ID

POST https://api.instamoney.co/direct_debits/:direct_debit_id/

Get Payment Status by ID - Request

Example Payment Status by ID Request

curl https://api.instamoney.co/direct_debits/ddpy-623dca10-5dad-4916-test/ -X GET \
   -u sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0: 
<?php
  $direct_debit_id = "ddpy-623dca10-5dad-4916-test";
  $url = "https://api.instamoney.co/direct_debits/" . $direct_debit_id . "/";
  $apiKey = "sk_test_vynfjIxiKTiEIJXjeMuKWSmQFTAcmwpqdV7oUvpsYWkzd6oifq3vudl3O3pjlh0:";
  $headers = [];
  $headers[] = "Content-Type: application/json";

  $curl = curl_init();

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

  $result = curl_exec($curl);
  echo $result;
Path Parameter Description
direct_debit_id
required
string Instamoney identifier for specified direct debit transaction

Get Payment Status by ID - Response

Example Get Payment Status by ID Success Response

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

Callback Notifications

In our direct debit flow, we will send callback to your system during Direct Debit Payment process. Merchants need to set up URL to receive callback notifications from our system.

Direct Debit Payment Callback

Payload

Example: Payload

{
    "event": "direct_debit.payment",
    "timestamp": "2020-03-26T05:44:26+0800",
    "id": "ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14",
    "reference_id": "e17a0ac8-6fed-11ea-bc55-0242ac130003",
    "channel_code": "DC_BRI",
    "payment_method_id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
    "currency": "IDR",
    "amount": "1000.00",
    "description": null,
    "status": "COMPLETED",
    "failure_code": null,
    "metadata": null
}
Header Parameter Description
x-callback-token string Your Instamoney unique callback token to verify the origin of the callback
webhook-id string A unique identifier of every webhook to help you to handle double callback 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 webhook
Parameter Description
event string Identifier of the event - "direct_debit.payment"
timestamp string ISO 8601 timestamp of the event. Timezone is UTC+0
id string Unique identifier for the transaction
reference_id string Reference ID provided by merchant
channel_code string Code identifier for the channel
payment_method_id string Payment method ID of end-customer source of funds
currency string Currency of the payment
amount number Amount to debited from the end-customer’s account
description string Description provided by merchant
status string Status of the payment - "PENDING", "COMPLETED", "FAILED"
failure_code string Reason if direct debit has failed. List of failure codes can be found here
metadata object Metadata provided by merchant

Payment Status Callback - Failure Reasons

Example: Payment Status Failure Examples

{
    "event": "direct_debit.payment",
    "timestamp": "2020-03-26T05:44:26+0800",
    "id": "ddpy-623dca10-5dad-4916-b14d-81aaa76b5d14",
    "reference_id": "e17a0ac8-6fed-11ea-bc55-0242ac130003",
    "channel_code": "DC_BRI",
    "payment_method_id": "pm-c30d4800-afe4-4e58-ad5f-cc006d169139",
    "currency": "IDR",
    "amount": "1000.00",
    "description": null,
    "status": "FAILED",
    "failure_code": "INSUFFICIENT_BALANCE",
    "metadata": null
}
Failure Code Description
MAX_AMOUNT_LIMIT_ERROR End customer's daily limit has been reached, unable to process debit request. End user required to increase daily limit or retry another day
INSUFFICIENT_BALANCE End customer has insufficient balance, unable to process debit request. End user required to top up balance
CHANNEL_UNAVAILABLE Bank service for direct debit is currently unavailable, unable to process debit request.
ACCOUNT_ACCESS_BLOCKED End customer bank account has been blocked, end user should contact the bank for resolution.

Callback

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

Setup

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

Delivery Attempts and Retries

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

View events

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

Retry logic

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

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

Receive callback statistics via email

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

Event Handling

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

Acknowledge events immediately

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

Handle duplicate events

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

Order of events

Instamoney 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. Instamoney provides several ways for you to verify events are coming from Instamoney in a secure manner.

Receive events with an HTTPS server

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

Verify events are sent from Instamoney

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

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

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

Reports

Report Object

Report Object Example

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

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

The file to download will only be accessible for 24 hours. When the url is expired, you will need to send a new request to generate the report.
currency
required
string The currency inside the report.
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.instamoney.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 Instamoney 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

Example Generate Report Request

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

Example Generate Report Response

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

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

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

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

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

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

default: IDR
string The currency to filter.
report_version
optional
string Report version indicates which version of report you need. This parameter is only applicable to Transaction Report.
Default value: VERSION_0

Version value <> changelog:
  • VERSION_0: Original version
  • VERSION_1: Includes Settlement Status, Actual Settlement Time, and Estimated Settlement Time
  • VERSION_2: Includes Early Settlement Fee Columns, swapped Payment ID with Product ID
  • Response Parameters

    Return Report Object with status code 201

    Error Codes

    See other common errors here.

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

    Get Report

    Endpoint: Get Report

    GET https://api.instamoney.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

    Example Get Report

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

    Example Get Report Response

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

    Response Parameters

    Return Report Object with status code 200

    Error Codes

    See other common errors here.

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

    Report Webhook

    Endpoint: Report Webhook

    POST https://yourcompany.com/report_webhook_url

    Instamoney 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 Instamoney Dashboard.

    The notification will be sent as POST request to the URL you set. Instamoney 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. Instamoney 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.

    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 Instamoney unique webhook token to verify the origin of the webhook

    webhook-id
    string A unique identifier of every webhook to help you to handle double webhooks by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
    Body Parameter Type Description
    event
    required
    string The type of the event. The available types are:
    Type Description
    reports.completed Report is completed. You can download the report from the url parameter.
    reports.failed Report is failed to generate. You are safe tor retry the report request.
    Report Object The rest of parameter is the same as report object.

    Test Scenarios

    This section includes test scenarios and other information to make sure your integration works as planned. Use it to trigger different flows in your integration and ensure they are handled accordingly

    Checklists

    Instamoney has designed its live and test modes to function as similarly as possible. Flipping the switch is mostly a matter of swapping your API keys.

    If you are a developer, or had a developer perform an integration for you, you should also consider the following items before going live.

    Handle Edge Cases

    We have created several test cases you can use to replicate various states and responses. Beyond these options, perform your due diligence, testing your integration with:

    We also recommend you have someone else test your integration, especially if that other person is not a developer themselves.

    Review Error Handling

    Once you have gone live is an unfortunate time to discover you have not properly written your code to handle every possible error type, including those that should "never" happen. Be certain your code is defensive, handling not just the common errors, but all possibilities.

    When testing your error handling, especially watch what information is shown to your users. A disbursement being failed (i.e., INVALID_DESTINATION) is a different concern than an error on your backend (e.g., an API_VALIDATION_ERROR).

    Review Your Logging

    Instamoney logs every request made with you API keys. We recommend that you log all important data on your end, too, despite the apparent redundancy. Your own logs will be a life-saver if your server has a problem contacting Instamoney or there's an issue with your API keys--both cases would prevent us from logging your request.

    Regularly examine your logs to ensure they're storing all the information you may need and they are not storing anything of a sensitive nature (e.g., personally identifiable information).

    Independent From Test Mode Objects

    Instamoney objects created in test mode--such as virtual accounts, retail outlets, etc---are not usable in live mode. This prevents your test data from being inadvertently used in your production code. When recreating necessary objects in live mode, be certain to use the same ID values (e.g. the same Virtual Account external ID) to guarantee your code will continue to work without issue

    Register Live Callback URL

    Your Instamoney account can have both test and live callback URLs. If you are using callback, make sure you have defined live endpoints in your Instamoney account. Then confirm that the live endpoint functions exactly the same as your test endpoint.

    While examining your callback status, also take a moment to check that your live endpoint:

    Secure Your API keys

    As a security measure, we recommend change your API keys on a regular basis, and also just before going live. This is in case they have been saved somewhere outside of your codebase during development. Make sure your workflow doesn't result in your API keys being represented or stored in multiple places--this leads to bugs--or even ending up in your version control software.

    Changelog

    Version 1.6.6 (Nov 02, 2021)

    Version 1.6.5 (Oct 18, 2021)

    Version 1.6.4 (Sep 22, 2021)

    Version 1.6.3 (Aug 25, 2021)

    Version 1.6.2 (Jul 30, 2021)

    Version 1.6.1 (Jul 12, 2021)

    Version 1.5.1 (May 6, 2021)

    Version 1.4.11 (February 1, 2021)

    Version 1.4.10 (September 11, 2020)

    Version 1.4.9 (August 19, 2020)

    Version 1.4.8 (August 18, 2020)

    Version 1.4.7 (August 7, 2020)

    Version 1.4.6 (August 3, 2020)

    Version 1.4.5 (June 18, 2020)

    Version 1.4.4 (May 6, 2020)

    Version 1.4.3 (March 14, 2020)

    Version 1.4.2 (February 3, 2020)

    Version 1.4.1 (January 30, 2020)

    Version 1.4.0 (December 20, 2019)

    Version 1.3.4 (December 15, 2019)