Introduction
We provide APIs specifically designed for P2P Escrow.
Authentication
To successfully authenticate with Instamoney's API, you must append a colon and Base 64 encode the API key you find in the dashboard. For example if your API key is
sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==
First, add a colon at the end
sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:
Finally, Base64 encode the colon appended key to get
c2tfdGVzdF9PWUNFZkw1eGdMTCtsOFp2SzdRYVNHR1ZNTjczb05FcGszeXorUnhuLzJiUy9MQ2dDUVorZ3c9PTo=
Steps for all endpoints:
- Obtain your API key in https://dashboard.instamoney.co/security
- Activate escrow testing by clicking on "Activate Escrow for testing" button in https://dashboard.instamoney.co/settings/p2p-escrow-rdl section P2P Escrow. or else, you will get
AUTHORIZATION_ERROR
Errors
Below are some of most common errors across all our endpoints. Specific errors are located under each endpoint. If you have any questions please contact us.
Error code | Meaning |
---|---|
400 | Bad request, e.g. validation error (API_VALIDATION_ERROR ) or invalid JSON (INVALID_JSON_FORMAT ) |
401 | Unauthorised access, e.g. the wrong API key |
403 | Forbidden access, e.g. API key does not have permission for this endpoint |
404 | Page or data not found |
500 | Unhandled error - contact us when this happens. If this was a response to a request to send money, please check the status of the resource (eg. disbursement, credit card refund) before retrying to ensure that the request will not be processed twice. |
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:
- Implement rate limiting in your application: As a client, it is important to implement rate limiting in your own application to ensure that you do not exceed the API's rate limits. This can be done by tracking the number of requests made and the time at which they were made, and comparing this to the API's rate limit policies.
- Handle rate limit errors: When you receive an HTTP status code of 429 (Too Many Requests) with the error code
RATE_LIMIT_EXCEEDED
, it is important to handle this error gracefully in your application. One way to do this is to retry the request after a certain amount of time has passed, to give the rate limit quota a chance to replenish. - Use exponential backoff: When retrying a request after a rate limit error, it can be helpful to use exponential backoff. This means that you should increase the amount of time you wait between retries by a factor of two (or some other multiplier) each time you receive a rate limit error. For example, you might retry the request after 1 second, then 2 seconds, then 4 seconds, and so on. This helps to reduce the risk of overwhelming the API with too many retries in a short period of time.
- Use caching: Caching the results of API requests can help to reduce the number of requests made to the API, and can also improve the performance of your application. By storing the results of API requests locally and reusing them until they become stale, you can reduce the need to make frequent requests to the API.
By following these best practices, you can help to ensure that your application handles rate limits gracefully and provides a reliable and consistent experience for your users.
We may reduce limits to prevent abuse, or increase limits to enable high-traffic applications. To increase the rate limit for your account, you can contact us 4 weeks in advance via email api.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.
Versioning
Backward Compatibility
We consider the following changes to be backward compatible:
- Adding new API resources
- Adding new optional request parameters to existing API methods
- Adding new properties to existing API responses
- Changing the order of properties in existing API responses
- Changing the length or format of any object IDs
- Adding new error codes
- Adding new webhook event types
- Adding new properties to webhook payloads
P2P Customer
A Customer refers to your end-customer, which includes both the lenders and borrowers on your platform.
Use the following Customer APIs to manage your customers with Instamoney.
Your customers’personal data is retained to comply with regulatory requirements for IT-based lending services in Indonesia, and also allows Instamoney to fulfill Know-Your-Client obligations.
The Customer resource will be used together with our other APIs to receive funds from and send funds toyour lenders and borrowers.
Create P2P Customer
Endpoint: Create P2P Customer
POST https://api.instamoney.co/p2p-customers
Use Create P2P Customer endpoint to create Lender, Borrower, or Admin.
Create P2P Customer Request
Example Create P2P Customer Request
curl -X POST \
'https://api.instamoney.co/p2p-customers' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json' \
-d '{
"given_name": "John",
"surname": "Doe",
"mobile_number": "0812312372387",
"email": "john.doe@gmail.com",
"ktp_number": "3700898999211198988",
"npwp_number": "12.232.435.2-764.003",
"external_id": "lender_2348",
"type": "LENDER",
"customer_accounts": [
{
"account_code": "BCA",
"account_number": "1234567890",
"is_preferred": true,
"account_type": "BANK_ACCOUNT"
},
{
"account_code": "GOPAY",
"account_number": "8878787872",
"account_type": "EWALLET"
}
]
}'
Parameter | Description |
---|---|
given_namerequired |
string First name of your customer. Accepted characters a-z,A-Z; Accepted symbols .,'(space)Example: Squir'el, S.T. |
surnameoptional |
string Last name of your customer. Accepted characters a-z,A-Z; Accepted symbols .,'(space)Example: John Do'e, S.Pd. |
mobile_numberrequired |
string Mobile number. Accepted characters 0-9; Accepted symbols -+(space)Example: +62 812-3456-789 |
emailrequired |
string Email address. Should include the top-level domain nameExample: abc@email.com |
ktp_numberrequired |
string Kartu Tanda Penduduk (national identity card number). Accepted characters 0-9,a-z,A-Z; Accepted symbols -(space)Example: 1234.3456-78-ab-CD |
npwp_numberoptional |
string Nomor Pokok Wajib Pajak (tax number). Accepted characters 0-9; Accepted symbols -(space)Example: 1234.3456-789 |
external_idrequired |
string Unique ID of your customer. Accepted characters 0-9,a-z,A-Z; Accepted symbols (space)_:,.-Example: ab,cd:va-my.test_1 |
typerequired |
enum Type of customer. You can set it asLENDER - where the customer is a LenderBORROWER - where the customer is a BorrowerADMIN - a user object for your internal administrative needs (not an actual Lender or Borrower). You can create multiple ADMIN customer objects, for a variety of purposes. |
customer_accountsrequired |
array of object Accounts that belong to the customer, can be bank account or ewallet |
customer_accounts.account_coderequired |
string The code of the account, can be bank codes (BCA , MANDIRI , etc.) or ewallet codes (GOPAY , OVO , etc.) |
customer_accounts.account_numberrequired |
string The account number of the selected account. Accepted characters 0-9; Accepted symbols -(space)Example: 88 98.3456-789 |
customer_accounts.is_preferredrequired |
boolean This field must be included in at least one of the accounts belonging to a customer. Funds will be transferred to the preferred destination unless otherwise specified in a request |
customer_accounts.account_typerequired if customer_accounts is specified |
string The selected account type (BANK_ACCOUNT or EWALLET ). |
Create P2P Customer Response
Example Create Customer Response
{
"id": "b9666300-7300-11e9-8373-6753d37f1b1f",
"given_name": "John",
"surname": "Doe",
"mobile_number": "0812312372387",
"email": "john.doe@gmail.com",
"ktp_number": "3700898999211198988",
"npwp_number": "12.232.435.2-764.003",
"external_id": "lender_2348",
"type": "LENDER",
"customer_accounts": [
{
"account_code": "BCA",
"account_number": "1234567890",
"is_preferred": true,
"account_type": "BANK_ACCOUNT"
},
{
"account_code": "GOPAY",
"account_number": "8878787872",
"account_type": "EWALLET"
}
],
"customer_escrow_id": "8288000000000011",
"created": "2018-12-22T17:00:00.000Z",
"updated": "2018-12-22T17:00:00.000Z",
"current_balance": 0,
"status": "PENDING",
"failure_reason": null
}
See Customer Resource for parameter details.
Create Customer Errors
Error Code | Description |
---|---|
ACCOUNT_CODE_NOT_SUPPORTED_ERROR400 |
The code of the account is currently not supported. |
DUPLICATE_EXTERNAL_ID_ERROR400 |
The external_id entered has been used before. Please enter a unique external_id and try again. |
NAME_BLACKLISTED_ERROR400 |
The customer name is blacklisted. |
NO_PREFERRED_ACCOUNT_ERROR400 |
No preferred account is specified. |
MULTIPLE_PREFERRED_ACCOUNT_ERROR400 |
Mutliple preferred account is specified. |
Get P2P Customer
Endpoint: Get P2P Customer
GET https://api.instamoney.co/p2p-customers/{id}
Get an existing customer with by using the id
(this is the id
returned to you in the Create Customer response). You can get current balance information of the customer using this API.
Example Get P2P Customer Request
curl -X GET \
'https://api.instamoney.co/p2p-customers/b9666300-7300-11e9-8373-6753d37f1b1f' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json'
Get P2P Customer Response
See Customer Resource for parameter details.
Example Get P2P Customer Response
{
"id": "b9666300-7300-11e9-8373-6753d37f1b1f",
"given_name": "John",
"surname": "Doe",
"mobile_number": "0812312372387",
"email": "john.doe@gmail.com",
"ktp_number": "3700898999211198988",
"npwp_number": "12.232.435.2-764.003",
"external_id": "lender_2348",
"type": "LENDER",
"customer_accounts": [
{
"account_code": "BCA",
"account_number": "1234567890",
"is_preferred": true,
"account_type": "BANK_ACCOUNT"
},
{
"account_code": "GOPAY",
"account_number": "8878787872",
"account_type": "EWALLET"
}
],
"customer_escrow_id": "8288000000000011",
"created": "2018-12-22T17:00:00.000Z",
"updated": "2018-12-22T17:00:00.000Z",
"current_balance": 22000,
"status": "ACTIVE",
"failure_reason": null
}
Get P2P Customer Errors
Error Code | Description |
---|---|
CUSTOMER_NOT_FOUND_ERROR404 |
Customer with that id is not found |
Get P2P Customer by External ID
Endpoint: Get P2P Customer by External ID
GET https://api.instamoney.co/p2p-customers/external_id={external_id}
Get an existing customer by using the external_id
(this is the external id that attached when creating customer). You can get current balance information of the customer using this API.
Example Get P2P Customer by External ID Request
curl -X GET \
'https://api.instamoney.co/p2p-customers/external_id=lender_2348' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json'
Get P2P Customer by External ID Response
See Customer Resource for parameter details.
Example Get P2P Customer Response
{
"id": "b9666300-7300-11e9-8373-6753d37f1b1f",
"given_name": "John",
"surname": "Doe",
"mobile_number": "0812312372387",
"email": "john.doe@gmail.com",
"ktp_number": "3700898999211198988",
"npwp_number": "12.232.435.2-764.003",
"external_id": "lender_2348",
"type": "LENDER",
"customer_accounts": [
{
"account_code": "BCA",
"account_number": "1234567890",
"is_preferred": true,
"account_type": "BANK_ACCOUNT"
},
{
"account_code": "GOPAY",
"account_number": "8878787872",
"account_type": "EWALLET"
}
],
"customer_escrow_id": "8288000000000011",
"created": "2018-12-22T17:00:00.000Z",
"updated": "2018-12-22T17:00:00.000Z",
"current_balance": 22000,
"status": "ACTIVE",
"failure_reason": null
}
Get P2P Customer by External Id Errors
Error Code | Description |
---|---|
CUSTOMER_NOT_FOUND_ERROR404 |
Customer with that id is not found |
Update P2P Customer
Endpoint: Update P2P Customer
PATCH https://api.instamoney.co/p2p-customers/{id}
Update an existing customer.
Update P2P Customer Request
Example Update P2P Customer Request
curl -X PATCH \
'https://api.instamoney.co/p2p-customers/b9666300-7300-11e9-8373-6753d37f1b1f' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json' \
-d '{
"mobile_number": "0812312399999",
"email": "fizz.buzz@gmail.com",
"customer_accounts": [
{
"account_code": "BNI",
"account_number": "1234567890",
"is_preferred": true,
"account_type": "BANK_ACCOUNT"
}
]
}'
Parameter | Description |
---|---|
mobile_numberoptional |
string Mobile number.Accepted characters 0-9; Accepted symbols -+(space).Example: +62 812-3456-789 |
emailoptional |
string Email address. Should include the top-level domain name.Example: abc@email.com |
customer_accountsoptional |
array of object Accounts that belong to the customer, can be bank account or ewallet.Constraint: You may only provide 1 to 5 customer_accounts |
customer_accounts.account_coderequired if customer_accounts is specified |
string The code of the account, can be bank codes (BCA , MANDIRI , etc.) or ewallet codes (GOPAY , OVO , etc.). |
customer_accounts.account_numberrequired if customer_accounts is specified |
string The account number of the selected account.Accepted characters 0-9; Accepted symbols -(space)Example: 88 98.3456-789 |
customer_accounts.is_preferredrequired if customer_accounts is specified |
string This field must be included in at least one of the accounts belonging to a customer. Funds will be transferred to the preferred destination unless otherwise specified in a request. |
customer_accounts.account_typerequired if customer_accounts is specified |
string The selected account type (BANK_ACCOUNT or EWALLET ). |
Update P2P Customer Response
Example Update Customer Response
{
"id": "b9666300-7300-11e9-8373-6753d37f1b1f",
"given_name": "John",
"surname": "Doe",
"mobile_number": "0812312399999",
"email": "fizz.buzz@gmail.com",
"ktp_number": "3700898999211198988",
"npwp_number": "12.232.435.2-764.003",
"external_id": "lender_2348",
"type": "LENDER",
"customer_accounts": [
{
"account_code": "BNI",
"account_number": "1234567890",
"is_preferred": true,
"account_type": "BANK_ACCOUNT"
}
],
"customer_escrow_id": "8288000000000011",
"created": "2018-12-22T17:00:00.000Z",
"updated": "2018-12-22T17:29:30.000Z",
"current_balance": 0,
"status": "ACTIVE",
"failure_reason": null
}
See Customer Resource for parameter details.
Update Customer Errors
Error Code | Description |
---|---|
CUSTOMER_NOT_FOUND_ERROR404 |
Customer with that id is not found. |
ACCOUNT_CODE_NOT_SUPPORTED_ERROR400 |
The code of the account is currently not supported. |
NO_PREFERRED_ACCOUNT_ERROR400 |
No preferred account is specified. |
MULTIPLE_PREFERRED_ACCOUNT_ERROR400 |
Mutliple preferred account is specified. |
Customer Callbacks
Example Customer Active Callback Request
{
"event": "escrow.p2p_customer",
"created": "2022-06-09T09:29:51.918Z",
"business_id": "f59fcbb7-848d-4242-af07-a8bb7e3ab37c",
"data": {
"id": "dd061c60-1857-11ed-be1c-c3fff448ba7a",
"given_name": "John",
"surname": "Doe",
"mobile_number": "085724715978",
"email": "john.doe@gmail.com",
"ktp_number": "3314131006940001",
"npwp_number": "012345678901234",
"type": "LENDER",
"external_id": "lender_48",
"created": "2022-08-10T02:55:16.775Z",
"updated": "2022-08-10T03:06:12.970Z",
"customer_accounts": [
{
"account_code": "BNI",
"account_number": "1234512345",
"is_preferred": true,
"account_type": "BANK_ACCOUNT"
}
],
"current_balance": 0,
"status": "ACTIVE",
"failure_reason": null,
"customer_escrow_id": "8288000000000011"
}
}
You will receive notifications via a callback when customer activated or failed.
You can set your callback URL in the https://dashboard.instamoney.co/settings/developers#callbacks under P2P Escrow.
Give response with HTTP status code 2XX if you successfully processed the callback. Any other HTTP status code will be marked as failed callback, and you must resolve manually in https://dashboard.instamoney.co/callbacks.
Customer Activated Callback
We will send you a callback request with schema Customer Callback Request Resource with data.status ACTIVE
and data.failure_reason is null
You will get this callback once the customer has been successfully activated.
Customer Failed Callback
Example Customer Failed Callback Request
{
"event": "escrow.p2p_customer",
"created": "2022-06-09T09:29:51.918Z",
"business_id": "f59fcbb7-848d-4242-af07-a8bb7e3ab37c",
"data": {
"id": "caae53c0-148d-11ed-99fd-0d3da390025d",
"given_name": "John",
"surname": "Doe",
"mobile_number": "085724715978",
"email": "john.doe@gmail.com",
"ktp_number": "3314131006940001",
"npwp_number": "012345678901234",
"type": "LENDER",
"external_id": "lender_155",
"created": "2022-08-05T07:11:14.173Z",
"updated": "2022-08-05T07:11:15.675Z",
"failure_reason": "NAME_BLACKLISTED_ERROR",
"customer_accounts": [
{
"account_code": "BNI",
"account_number": "1234512345",
"is_preferred": true,
"account_type": "BANK_ACCOUNT"
}
],
"current_balance": 0,
"status": "FAILED",
"customer_escrow_id": "8288000000000011"
}
}
We will send you a callback request with schema Customer Callback Request Resource with data.status FAILED
and data.failure_reason is filled
.
You will get this Callback once the customer has failed to be activated.
Customer Callback Request Resource
Customer Callback Request Resource is the schema of callback requests.
Parameter | Description |
---|---|
event | string Callback event. |
created | string (ISO 8601) Timestamp when the event was triggered. |
business_id | string Instamoney's identifier for your business. |
data | object Customer Resource, can either hasstatus ACTIVE and failure_reason null - in a Completed Callback.status FAILED and failure_reason is filled - in a Failed Callback. |
Customer Resource
Customer resource is the schema of all customer API responses.
Parameter | Description |
---|---|
id | string The unique ID of the customer you have created, generated by Instamoney |
given_name | string First name of your customer |
surname | string Last name of your customer |
mobile_number | string Mobile numberExample: 0812XXXXXX |
string Email address |
|
ktp_number | string Kartu Tanda Penduduk (national identity card number) |
npwp_number | string Nomor Pokok Wajib Pajak (tax number) |
external_id | string Unique ID of your customer |
type | enum Type of customer. Can either beLENDER - where the customer is a LenderBORROWER - where the customer is a BorrowerADMIN - where you want to create a ADMIN customer object for administrative transactions |
customer_accounts | array of object Accounts that belong to the customer, can be bank account or ewallet |
customer_accounts.account_code | string The code of the account, can be bank codes (BCA , MANDIRI , etc.) or ewallet codes (GOPAY , OVO , etc.) |
customer_accounts.account_number | string The account number of the selected account |
customer_accounts.is_preferred | boolean This field must be included in at least one of the accounts belonging to a customer. Funds will be transferred to the preferred destination unless otherwise specified in a request |
customer_escrow_id | string We create a virtual account for each customer in the Escrow Account for better reconciliation. Use this virtual account number to identify all transactions tied to a single customer in the Escrow Account |
created | string An ISO timestamp that tracks when the new customer was created |
updated | string An ISO timestamp that tracks when the new customer was last updated |
current_balance | string Current balance of the customer |
status | string status of customer. can either be:PENDING ACTIVE FAILED |
failure_reason | string If your customer creation fails, this will explain the reason why.Default value is null .List of errors: NAME_BLACKLISTED_ERROR The customer name contains blacklisted keyword |
P2P Fixed Virtual Account
Virtual accounts allow you to accept funds via bank transfer from lenders and borrowers into the Escrow Account (controlled by you).* Use our Virtual Accounts (P2P) API calls to manage the banks at which your lenders and borrowers can make payment, as well as keep track of incoming bank transfers from lenders and borrowers.
Instamoney has 2 payment channels in Escrow System, which can be activated through dashboard https://dashboard.instamoney.co/settings/p2p-escrow-rdl#escrow. Newly created business account will use BNI payment channel activated by default and another payment channel can be activated or configured once the merchant already live.
Create P2P Fixed VA
Endpoint: Create P2P Fixed Virtual Account
POST /p2p-escrow-virtual-accounts
Create a new fixed virtual account to accept payments from lenders or borrowers into your Escrow Account using our Create Fixed Virtual Account request.
Instamoney will send you a callback when the Create P2P Fixed VA request is successful.
Create P2P Fixed Virtual Account Request
Example Create P2P Fixed Virtual Account Request
curl -X POST \
'https://api.instamoney.co/p2p-escrow-virtual-accounts' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json' \
-d '{
"external_id": "va-1233889871",
"bank_code": "BNI",
"virtual_account_number": "2541238",
"name": "Agus Payment",
"is_closed": true,
"expected_amount": 150000,
"expiration_date": "2018-12-31T17:00:00.000Z",
"customer_id": "5c1774e767400e2b76036461",
"payment_type": "REPAYMENT",
"loan_id": "cc1234356"
}'
Parameter | Description |
---|---|
external_idrequired |
string A unique ID for your virtual account |
bank_coderequired |
string Bank code of the virtual account. Refer to our supported banks here or let us know if you have a preferred bank that we do not currently support. Available bank codes: MANDIRI , BNI , PERMATA , BRI and SAHABAT_SAMPOERNA |
virtual_account_numberoptional |
string Assigned virtual account number excluding your merchant_code. If you leave this empty, we will assign one at random |
namerequired |
string Name of your virtual account. Shows up on bank interfaces |
suggested_amountoptional |
number Amount suggested to the customer for payment. Shows up on the interfaces of Mandiri and BNI |
is_closedoptional |
boolean If set to true, then expected amount must be included and it will only accept that amount. Default value is false |
expected_amountoptional |
number When used, the virtual account accepts only the amount specified here |
expiration_dateoptional |
ISO date Time when the virtual account will expire. When left empty, we will default to 31 years |
is_single_useoptional |
boolean When set to true, the virtual account will automatically expire after being paid. Default is false |
customer_idrequired |
string The unique ID of the customer paying into the virtual account. You must Create a Customer first |
payment_typerequired |
enum Type of payment collected from the customer. Can either beLOAN - for funds received from a lenderREPAYMENT - for funds received from a borrowerINTERNAL - for funds received from an admin |
loan_idoptional for REPAYMENT
|
string Loan ID related to the payment. Only relevant for repayment |
Create P2P Fixed Virtual Account Response
Example Create Fixed Virtual Account Response
{
"id": "b7f6cc0f-6b90-4cde-a8c3-7763c4feda08",
"external_id": "va-1233889871",
"bank_code": "BNI",
"merchant_code": "8808",
"account_number": "88082541238",
"name": "Agus Payment",
"is_closed": true,
"expected_amount": 150000,
"expiration_date": "2018-12-31T17:00:00.000Z",
"customer_id": "5c1774e767400e2b76036461",
"payment_type": "REPAYMENT",
"loan_id": "cc1234356",
"status": "PENDING",
"created": "2018-12-20T17:00:00.000Z",
"updated": "2018-12-20T17:00:00.000Z"
}
Our response body is Fixed VA Resource with status PENDING
Create Fixed Virtual Account Errors
Error Code | Description |
---|---|
DUPLICATE_EXTERNAL_ID400 |
The external_id entered has been used before. Please enter a unique external_id and try again |
INVALID_LOAN_ID400 |
The loan_id entered does not correspond to any loan |
VIRTUAL_ACCOUNT400 |
The virtual account number you want is outside your range. |
VIRTUAL_ACCOUNT400 |
The virtual account number you want is outside your range. |
BANK_NOT_SUPPORTED400 |
The bank code is not currently supported. |
EXPIRATION_DATE400 |
Custom expiration date for the fixed virtual account is not currently supported. |
EXPIRATION_DATE400 |
Invalid custom expiration date because it's earlier than current time. |
SUGGESTED_AMOUNT400 |
The suggested amount for the fixed virtual account is not currently supported. |
EXPECTED_AMOUNT400 |
The expected amount is required when is_closed is set to true . |
DUPLICATE_CALLBACK400 |
The account number that you want to create is already exist |
MINIMUM_EXPECTED400 |
The expected amount can only be more than zero |
MAXIMUM_EXPECTED400 |
The expected amount can only be less than Rp.1000000000 |
CALLBACK_VIRTUAL_ACCOUNT_NAME_NOT_ALLOWED400 |
The name cannot contain bank or institution name |
Get P2P Fixed VA
Endpoint: Get P2P Fixed Virtual Account by External ID
GET /p2p-escrow-virtual-accounts/external-id/{external_id}
Example Get P2P Fixed Virtual Account by External ID Request
curl -X GET \
'https://api.instamoney.co/p2p-escrow-virtual-accounts/external-id/va-1233889871' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json'
Get an existing P2P Fixed VA by using the external_id
. You can use this to query for a P2P Fixed VA, or to check the current status of P2P Fixed VA before the callback is received by your URL.
Get P2P Fixed VA Response
Example Get P2P Fixed Virtual Account by External ID Response
{
"id": "b7f6cc0f-6b90-4cde-a8c3-7763c4feda08",
"external_id": "va-1233889871",
"bank_code": "BNI",
"merchant_code": "8808",
"account_number": "88082541238",
"name": "Agus Payment",
"is_closed": true,
"is_single_use": false,
"expected_amount": 150000,
"suggested_amount": 150000,
"expiration_date": "2018-12-31T17:00:00.000Z",
"customer_id": "5c1774e767400e2b76036461",
"payment_type": "REPAYMENT",
"loan_id": "cc1234356",
"status": "ACTIVE",
"created": "2018-12-20T17:00:00.000Z",
"updated": "2018-12-20T17:00:00.000Z"
}
Our response body is Fixed VA Resource with current status represented.
Get P2P Fixed VA Errors
Error Code | Description |
---|---|
ESCROW_EXTERNAL_VIRTUAL_ACCOUNT_NOT_FOUND_ERROR404 |
Escrow Virtual Account with specified is not found |
Get P2P Fixed VA with Payment Details
Endpoint: Get P2P Fixed Virtual Account with Payment Details
GET /p2p-escrow-virtual-accounts/external-id/{external_id}/payments
Example Get P2P Fixed Virtual Account with Payment Details Request
curl -X GET \
'https://api.instamoney.co/p2p-escrow-virtual-accounts/external-id/va-1233889871/payments?limit=2&offset=1' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json'
Get an existing P2P Fixed VA with payment details by using the external_id
. You can use this to query for a P2P Fixed VA and check details of payments from the VA.
Get P2P Fixed VA with Payment Details Query
Query | Description |
---|---|
limitoptional |
integer Used to limit the number of payment details included on the VAConstraint: integer between 1 and 100 (default value: 10) |
offsetoptional |
integer Specifies the number of payment details to skipConstraint: integer greater equal than 1 |
Get P2P Fixed VA with Payment Details Response
Example Get P2P Fixed Virtual Account with Payment Details Response
{
"id": "b7f6cc0f-6b90-4cde-a8c3-7763c4feda08",
"external_id": "va-1233889871",
"bank_code": "BNI",
"merchant_code": "8808",
"account_number": "88082541238",
"name": "Agus Payment",
"is_closed": true,
"is_single_use": false,
"expected_amount": 150000,
"suggested_amount": 150000,
"expiration_date": "2018-12-31T17:00:00.000Z",
"customer_id": "5c1774e767400e2b76036461",
"payment_type": "REPAYMENT",
"loan_id": "cc1234356",
"status": "ACTIVE",
"created": "2018-12-20T17:00:00.000Z",
"updated": "2018-12-20T17:00:00.000Z",
"virtual_account_payments": [
{
"id": "c50e88e0-787d-11e9-bc8d-97acc03dc038",
"amount": 10000,
"transaction_timestamp": "2018-12-20T17:00:00.000Z",
"status": "SETTLED",
"created": "2018-12-20T17:00:00.000Z",
"updated": "2018-12-20T17:00:00.000Z"
},
{
"id": "2ba75760-5142-11ea-a020-7757000ffe5f",
"amount": 20000,
"transaction_timestamp": "2018-12-20T17:00:00.000Z",
"status": "SETTLED",
"created": "2018-12-20T17:00:00.000Z",
"updated": "2018-12-20T17:00:00.000Z"
}
]
}
Our response body is Fixed VA Resource with current status represented.
Get P2P Fixed VA with Payment Details Errors
Error Code | Description |
---|---|
ESCROW_EXTERNAL_VIRTUAL_ACCOUNT_NOT_FOUND_ERROR404 |
Escrow Virtual Account with specified is not found |
Update P2P Fixed VA
Endpoint: Update P2P Fixed Virtual Account
PATCH /p2p-escrow-virtual-accounts/{escrow_virtual_account_id}
Example Update P2P Fixed Virtual Account Request
curl -X PATCH \
'https://api.instamoney.co/p2p-escrow-virtual-accounts/b7f6cc0f-6b90-4cde-a8c3-7763c4feda08' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json' \
-d '{
"loan_id": "cc1234356",
"expected_amount": 70000,
"suggested_amount": 70000,
"expiration_date”: "2018-12-31T17:00:00.000Z",
"is_single_use": false
}'
Update an existing Fixed Virtual Account for a variety of uses cases, including (but not limited to) the following:
- Updating the
loan_id
to allow a Borrower to repay another loan using the same Fixed VA. - Updating the
expected_amount
for closed VAs, if the repayment amount changes. - Updating the
expiration_date
so that your customers can have more time to pay into the VA.
Instamoney will send you a callback when the Update P2P Fixed VA request is successful.
Update P2P Fixed Virtual Account Request
Parameter | Description |
---|---|
suggested_amountoptional |
number Amount suggested to the customer for payment. Shows up on the interfaces of Mandiri and BNI |
expected_amountoptional |
number When used, the virtual account accepts only the amount specified here |
expiration_dateoptional |
ISO date Time when the virtual account will expire. When left empty, we will default to 31 years |
is_single_useoptional |
boolean When set to true, the virtual account will automatically expire after being paid. Default is false |
loan_idoptional for REPAYMENT
|
string Loan ID related to the Fixed VA, can only be updated for a REPAYMENT type Fixed VA |
Update P2P Fixed Virtual Account Response
Example Update Fixed Virtual Account Response
{
"id": "b7f6cc0f-6b90-4cde-a8c3-7763c4feda08",
"external_id": "va-1233889871",
"bank_code": "BNI",
"merchant_code": "8808",
"account_number": "88082541238",
"name": "Agus Payment",
"is_closed": true,
"is_single_use": false,
"expected_amount": 70000,
"suggested_amount": 70000,
"expiration_date": "2018-12-31T17:00:00.000Z",
"customer_id": "5c1774e767400e2b76036461",
"payment_type": "REPAYMENT",
"loan_id": "cc1234356",
"status": "ACTIVE",
"Updated": "2018-12-20T17:00:00.000Z",
"updated": "2018-12-20T17:00:00.000Z"
}
Our response body is Fixed VA Resource with status ACTIVE
.
Update Fixed Virtual Account Errors
Error Code | Description |
---|---|
ESCROW_EXTERNAL_VIRTUAL_ACCOUNT_NOT_FOUND_ERROR404 |
The Fixed VA ID which you have entered to be updated cannot be found |
INVALID_LOAN_ID400 |
The loan_id entered does not correspond to any loan |
LOAN_ID_NOT_SUPPORTED_ERROR400 |
This error will be returned if the request body contains a loan_id but the VA being updated is not a REPAYMENT type VA |
SUGGESTED_AMOUNT400 |
The suggested amount for the fixed virtual account is not currently supported. |
EXPECTED_AMOUNT400 |
The expected amount is required when is_closed is set to true . |
MINIMUM_EXPECTED400 |
The expected amount can only be more than zero |
MAXIMUM_EXPECTED400 |
The expected amount can only be less than Rp.1000000000 |
INVALID_LOAN_ID_ERROR400 |
The loan_id entered does not correspond to any loan |
INACTIVE_VIRTUAL_ACCOUNT_ERROR400 |
The virtual account status is either PENDING or INACTIVE . If status is PENDING - please wait until VA status is ACTIVE and retry the requestINACTIVE - virtual account is not allowed to be updated |
P2P Fixed VA Callbacks
Example P2P Fixed Virtual Account Activated Callback Request
{
"id": "5d1436e14566t12z7d7789fb",
"business_id": "5c473dbeb4e5da26b391c4cf",
"external_id": "escrow_va_1548187615",
"merchant_code": "8808",
"account_number": "88089999111259",
"bank_code": "BNI",
"name": "lingga",
"is_closed": "false",
"expiration_date": "2050-01-22T17:00:00.000Z",
"is_single_use": "false",
"status": "ACTIVE",
"customer_id": "946a98f0-1e7d-11e9-8914-e96a7bd39676",
"payment_type": "LOAN",
"created": "2019-01-22T20:06:57.934Z",
"updated": "2019-01-22T20:06:58.263Z"
}
You can receive notifications via a callback whenever a virtual account has been successfully created, updated, or a new payment is made into a virtual account.
You can set your callback URL in the https://dashboard.instamoney.co/settings/developers#callbacks under P2P Escrow, and check callback statuses on https://dashboard.instamoney.co/callbacks.
Give response with HTTP status code 2XX if you successfully processed the callback. Any other HTTP status code will be marked as failed callback, and you must resolve manually in https://dashboard.instamoney.co/callbacks.
P2P Fixed Virtual Account Activated Callback
Once Fixed VA created by bank, we will send callback with request body Fixed VA Resource with status ACTIVE
.
Give response with HTTP status code 2XX if you successfully processed the callback. Any other HTTP status code will be marked as failed callback, and you must resolve manually in https://dashboard.instamoney.co/callbacks.
P2P Fixed Virtual Account Example Update P2P Customer Request updated Callback
Example P2P Fixed Virtual Account Updated Callback Request
{
"id": "5d1436e14566t12z7d7789fb",
"business_id": "5c473dbeb4e5da26b391c4cf",
"external_id": "escrow_va_1548187615",
"merchant_code": "8808",
"account_number": "88089999111259",
"bank_code": "BNI",
"name": "lingga",
"is_closed": "false",
"expiration_date": "2050-01-22T17:00:00.000Z",
"is_single_use": "false",
"status": "ACTIVE",
"customer_id": "946a98f0-1e7d-11e9-8914-e96a7bd39676",
"payment_type": "LOAN",
"created": "2019-01-22T20:06:57.934Z",
"updated": "2019-01-22T20:06:58.263Z"
}
Once Fixed VA updated by bank, we will send callback with request body Fixed VA Resource with status ACTIVE
.
Give response with HTTP status code 2XX if you successfully processed the callback. Any other HTTP status code will be marked as failed callback, and you must resolve manually in https://dashboard.instamoney.co/callbacks.
P2P Fixed VA Payment Settling Callback
Example P2P Fixed VA Payment Settling Callback Request
{
"id": "5d1436e14566t12z7d7789fb",
"amount": 45000,
"transaction_timestamp": "2019-01-22T20:08:16.559Z",
"escrow_external_virtual_account_id": "45a18ae0-1e81-11e9-8914-e96a7bd39676",
"updated": "2019-01-22T20:08:24.123Z",
"created": "2019-01-22T20:08:19.050Z",
"external_id": "escrow_va_1548187615",
"bank_code": "BNI",
"account_number": "88089999111259",
"merchant_code": "8808",
"status": "SETTLING",
"customer_id": "5c1774e767400e2b76036461",
"payment_type": "LOAN",
"updated": "2019-01-22T20:08:24.123Z",
"created": "2019-01-22T20:08:19.050Z"
}
This callback is sent when payment has been made into a P2P Fixed Virtual Account and the payment is settling into the Escrow Account.
Our request payload is Fixed VA Payment Resource with status SETTLING
.
P2P Fixed VA Payment Settled Callback
Example P2P Fixed VA Payment Settled Callback Request
{
"id": "5d1436e14566t12z7d7789fb",
"amount": 45000,
"customer_balance": 45000,
"transaction_timestamp": "2019-01-22T20:08:16.559Z",
"escrow_external_virtual_account_id": "45a18ae0-1e81-11e9-8914-e96a7bd39676",
"external_id": "escrow_va_1548187615",
"bank_code": "BNI",
"account_number": "88089999111259",
"merchant_code": "8808",
"payment_type": "LOAN",
"customer_id": "5c1774e767400e2b76036461",
"status": "SETTLED",
"created": "2019-01-22T20:08:19.050Z",
"updated": "2019-01-22T20:08:40.693Z"
}
This callback is sent when payment has been settled into the Escrow Account.
Our request payload is Fixed VA Payment Resource with status SETTLED
.
Fixed VA Resource
Fixed Virtual Account Resource is the schema of all fixed virtual account API responses.
Parameter | Description |
---|---|
id | string Unique ID for the virtual account that generated randomly by Instamoney |
external_id | string An ID of your choice which you provided upon request |
bank_code | string Bank code of the virtual account |
account_number | string Assigned virtual account number |
merchant_code | string Merchant prefix assigned to you |
name | string Name of your virtual account. Shows up on bank interfaces |
suggested_amount | number Amount suggested to the customer for payment. Shows up on the interfaces of Mandiri and BNI |
is_closed | boolean If set to true, then expected amount must be included and it will only accept that amount. Default value is false |
expected_amount | number When used, the virtual account accepts only the amount specified here |
expiration_date | ISO date Time when the virtual account will expire. When left empty, we will default to 31 years |
is_single_use | boolean When set to true, the virtual account will automatically expire after being paid. Default is false |
customer_id | string The unique ID of the customer paying into the virtual account. You must Create a Customer first |
payment_type | enum Type of payment collected from the customer. Can either beLOAN - for funds received from a lenderREPAYMENT - for funds received from a borrowerINTERNAL - for funds received from one of your ADMIN user objects |
loan_id | string Loan ID related to the payment. Only for repayment |
status | string Fixed VA statuses, can be PENDING - The virtual account is queued for creation or updateACTIVE - The virtual account is active and can receive paymentINACTIVE - The virtual account is inactive |
created | ISO date An ISO timestamp that tracks when the virtual account was created |
updated | ISO date An ISO timestamp that tracks when the virtual account was last updated |
virtual_account_paymentsOnly for Get with Payment Details |
array An array with list of virtual account payments |
Fixed VA Payment Resource
Fixed Virtual Account Payment Resource is the schema of all fixed virtual account API payment callback requests.
Parameter | Description |
---|---|
id | string The unique ID of the virtual account payment |
escrow_external_virtual_account_id | string Instamoney’s fixed virtual account ID |
customer_id | string End customer’s ID |
external_id | string Unique ID you provided for the virtual account |
bank_code | string Bank code of the virtual account |
account_number | string Assigned virtual account number |
merchant_code | string Merchant prefix assigned to you |
amount | string Amount paid |
customer_balance | number Customer’s current balance after the payment into the virtual account |
payment_type | enum Type of payment collected from the customer. Can only be LOAN or REPAYMENT |
loan_id | string Loan ID related to the payment |
status | string Virtual account payment status, in the callback it will be SETTLING then become SETTLED |
created | ISO date An ISO timestamp that tracks when the virtual account payment was created |
updated | ISO date An ISO timestamp that tracks when the virtual account payment was last updated |
transaction_timestamp | ISO date An ISO timestamp of when your end customer has paid the virtual account, according to bank |
Loan Disbursement
Loan disbursements are the funds received by a single borrower from your Escrow Account upon agreed repayment terms. Our Loans (P2P) API calls allow you to send loan funds from your Escrow Account to your borrowers.
Please note that you are unable to cancel a loan disbursement request once it has been made.
Create Loan Disbursement
Endpoint: Create Loan Disbursement
POST /p2p-loan-disbursements
Use this endpoint to disburse from escrow to a loan borrower.
Create Loan Disbursement Request
Example Create Loan Disbursement Request
curl -X POST \
'https://api.instamoney.co/p2p-loan-disbursements' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json' \
-d '{
"external_id": "loan-1233889871",
"loan_maturity_date": "2018-12-23T13:50:12.000Z",
"annual_percentage_rate": 15,
"lenders": [
{
"customer_id": "5c1774e767400e2b76036461",
"funded_amount": 1200000
},
{
"customer_id": "5c177411b51c6648594db872",
"funded_amount": 850000
},
],
"borrower_id": "5b51e6ba0071ec521008e21d",
"destination_account_code": "BCA",
"destination_account_holder_name": "John Doe",
"destination_account_number": "8982312309",
"loan_id": "cc123456",
"description": "loan-disb-123"
}'
Parameter | Description |
---|---|
external_idrequired |
string Unique ID you provided for the loan disbursement. Accepted characters a-z,0-9,A-Z; Accepted symbols (space)_:,.- Example: ab,cd:va-my.test_1 |
loan_maturity_daterequired |
ISO date Date and time on which repayment of the loan needs to be made |
annual_percentage_raterequired |
Number Annual percentage rateExample: If interest bears an APR of 20%, enter 20 |
lendersrequired |
array of objects More than one lender can be identified here since our APIs allow more than one lender to contribute funds to any given loan |
lenders.customer_idrequired |
string The unique ID of the lender (set by you using the Create Customer endpoint) |
lenders.funded_amountrequired |
number Amount funded by the lender for the loan (more than 0). The sum of the funded_amounts constitutes the principal_amount sent to the borrower for the loan. We return the principal_amount in the API response to this request.
|
borrower_idrequired |
string The unique ID of the borrower (set by you using the Create Customer endpoint) |
admin_idoptional |
string The unique ID of any of your ADMIN customer objects (created by you using the Create Customer endpoint) |
admin_amountrequired only if
|
number Amount which you want to disburse to your ADMIN customer object (more than 0). Will be deducted from the principal_amount |
destination_account_coderequired |
string Code of the destination bank or e-Wallet. Refer to our list of supported banks and e-Wallets here |
destination_account_holder_namerequired |
string Name of the account holder as per the destination bank’s or e-Wallet’s records. Accepted characters a-z,0-9,A-Z; Accepted symbols (space).,'/- Example: Fa'ni, S.T-09/2017 |
destination_account_numberrequired |
string If disbursing to a bank, destination bank account number. If it is a BCA account number, the account number must be 10 characters exactlyIf disbursing to an e-Wallet, phone number registered with the e-Wallet account. Accepted characters 0-9 Example: 9883456789 |
loan_idrequired |
string ID of the loan you provided. This is the same as the loan_id in the context of Repayments and Create Fixed Virtual Account Requests. Accepted characters a-z,0-9,A-Z; Accepted symbols (space)_:/,.- Example: ab,cd:/loan-id.test_1 |
descriptionoptional |
string Description to send with the transaction. Example: loan-disb-123 |
Create Loan Disbursement Response
Our response body is Loan Disbursement Resource with status PENDING
Example Create Loan Disbursement Response
{
"id": "c80fb93c-b9f7-419d-a221-29bedc87a778",
"external_id": "loan-1233889871",
"loan_maturity_date": "2018-12-23T13:50:12.000Z",
"annual_percentage_rate": 15,
"lenders": [
{
"customer_id": "5c1774e767400e2b76036461",
"funded_amount": 1200000,
},
{
"customer_id": "5c177411b51c6648594db872",
"funded_amount": 850000
},
],
"principal_amount": 2050000,
"borrower_id": "5b51e6ba0071ec521008e21d",
"destination_account_code": "BCA",
"destination_account_holder_name": "John Doe",
"destination_account_number": "8982312309",
"loan_id": "cc123456",
"status": "PENDING",
"user_id": "5b51e6ba0071ec521008e21d",
"created": "2018-12-12T13:50:12.000Z",
"updated": "2018-12-12T13:50:12.000Z"
}
Create Loan Disbursement Errors
Error Code | Description |
---|---|
INSUFFICIENT_LENDER_BALANCE_ERROR 400 |
One or more of the lender’s balance is insufficient to fund the loan |
LOAN_MATURITY_DATE_INVALID_ERROR 400 |
The loan maturity date in your request is invalid. Please enter a date some time in the future and try again |
ACCOUNT_CODE_NOT_SUPPORTED_ERROR 400 |
The code of the destination account is currently not supported |
INVALID_LENDER_ID_ERROR 400 |
One or more of the customer_id entered in the lenders field is invalid or does not exist |
INVALID_BORROWER_ID_ERROR 400 |
The borrower_id entered is invalid |
INVALID_ADMIN_ID_ERROR 400 |
The admin_id entered is invalid |
INVALID_ADMIN_AMOUNT 400 |
The admin_amount cannot be more than the principal_amount |
DUPLICATE_EXTERNAL_ID_ERROR 400 |
The external_id entered has been used before. Please enter a unique external_id and try again |
RECIPIENT_ACCOUNT_NUMBER_ERROR 400 |
The destination_account_number is invalid |
RECIPIENT_AMOUNT_ERROR 400 |
Invalid transfer amount, please check the limitation of the transfer amount |
BANK_CODE_NOT_SUPPORTED_ERROR 400 |
The destination_account_code is invalid |
MAXIMUM_TRANSACTION_LIMIT_ERROR 400 |
Your funded amount has been exceeding the limit. Please contact our customer support team for more information |
Get Loan Disbursement
Endpoint: Get Loan Disbursement by ID
GET /p2p-loan-disbursements/{id}
Example Get Loan Disbursement Request by ID
curl -X GET \
'https://api.instamoney.co/p2p-loan-disbursements/c80fb93c-b9f7-419d-a221-29bedc87a778' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json'
Endpoint: Get Loan Disbursement by External ID
GET /p2p-loan-disbursements/external-id/{external_id}
Example Get Loan Disbursement Request by External ID
curl -X GET \
'https://api.instamoney.co/p2p-loan-disbursements/external-id/loan-1233889871' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json'
Get an existing Loan Disbursement by using the id
or external_id
on the respective endpoint. You can use this to query for a past Loan Disbursement, or to check the current status of an ongoing Loan Disbursement before the callback is received by your URL.
Get Loan Disbursement Response
Our response body is Loan Disbursement Resource with current status represented.
Example Get Loan Disbursement Response
{
"id": "c80fb93c-b9f7-419d-a221-29bedc87a778",
"external_id": "loan-1233889871",
"loan_maturity_date": "2018-12-23T13:50:12.000Z",
"annual_percentage_rate": 15,
"lenders": [
{
"customer_id": "5c1774e767400e2b76036461",
"funded_amount": 1200000,
},
{
"customer_id": "5c177411b51c6648594db872",
"funded_amount": 850000
},
],
"principal_amount": 2050000,
"borrower_id": "5b51e6ba0071ec521008e21d",
"destination_account_code": "BCA",
"destination_account_holder_name": "John Doe",
"destination_account_number": "8982312309",
"loan_id": "cc123456",
"status": "DISBURSING",
"user_id": "5b51e6ba0071ec521008e21d",
"created": "2018-12-12T13:50:12.000Z",
"updated": "2018-12-12T13:50:12.000Z"
}
Get Loan Disbursement Errors
Error Code | Description |
---|---|
LOAN_DISBURSEMENT_NOT_FOUND_ERROR404 |
Loan Disbursement with specified ID or External ID is not found |
Loan Disbursement Callbacks
Example Loan Disbursement Disbursing Callback Request
{
"id": "7fe55af0-1e82-11e9-8914-e96a7bd39676",
"external_id": "1548188143",
"loan_maturity_date": "2020-01-10T12:00:00.000Z",
"annual_percentage_rate": 20,
"principal_amount": 90000,
"borrower_id": "ad695ee0-1e7d-11e9-8914-e96a7bd39676",
"destination_account_code": "MANDIRI",
"destination_account_holder_name": "Rizky",
"destination_account_number": "7654321",
"loan_id": "loan_164",
"created": "2019-01-22T20:15:45.184Z",
"updated": "2019-01-22T20:33:44.930Z",
"lenders": [
{
"funded_amount": 45000,
"customer_balance": 45000,
"customer_id": "a51d0ac0-1e7d-11e9-8914-e96a7bd39676"
},
{
"funded_amount": 45000,
"customer_balance": 45000,
"customer_id": "946a98f0-1e7d-11e9-8914-e96a7bd39676"
}
],
"status": "DISBURSING"
}
You will receive notifications via a callback when loan disbursement is disbursing, completed, or failed.
You can set your callback URL in the https://dashboard.instamoney.co/settings/developers#callbacks under P2P Escrow.
Give response with HTTP status code 2XX if you successfully processed the callback. Any other HTTP status code will be marked as failed callback, and you must resolve manually in https://dashboard.instamoney.co/callbacks.
Loan Disbursement Disbursing Callback
We will send you a callback request with schema Loan Disbursement Resource with status DISBURSING
once your balance has been successfully moved from the Escrow Account to Instamoney’s float account.
Loan Disbursement Completed Callback
Example Loan Disbursement Completed Callback Request
{
"id": "7fe55af0-1e82-11e9-8914-e96a7bd39676",
"external_id": "1548188143",
"loan_maturity_date": "2020-01-10T12:00:00.000Z",
"annual_percentage_rate": 20,
"principal_amount": 90000,
"borrower_id": "ad695ee0-1e7d-11e9-8914-e96a7bd39676",
"destination_account_code": "MANDIRI",
"destination_account_holder_name": "Rizky",
"destination_account_number": "7654321",
"loan_id": "loan_164",
"created": "2019-01-22T20:37:12.1315",
"updated": "2019-01-22T20:37:48.159Z",
"lenders": [
{
"funded_amount": 45000,
"customer_balance": 45000,
"customer_id": "a51d0ac0-1e7d-11e9-8914-e96a7bd39676"
},
{
"funded_amount": 45000,
"customer_balance": 45000,
"customer_id": "946a98f0-1e7d-11e9-8914-e96a7bd39676"
}
],
"status": "COMPLETED"
}
We will send you a callback request with schema Loan Disbursement Resource with status COMPLETED
and bank_reference
filled.
You will get this callback once the loan disbursement has been successfully disbursed from Instamoney’s float account to the customer’s bank account.
Loan Disbursement Failed Callback
Example Loan Disbursement Failed Callback Request
{
"id": "7fe55af0-1e82-11e9-8914-e96a7bd39676",
"external_id": "1548188143",
"loan_maturity_date": "2020-01-10T12:00:00.000Z",
"annual_percentage_rate": 20,
"principal_amount": 90000,
"borrower_id": "ad695ee0-1e7d-11e9-8914-e96a7bd39676",
"destination_account_code": "MANDIRI",
"destination_account_holder_name": "Rizky",
"destination_account_number": "7654321",
"loan_id": "loan_164",
"created": "2019-01-22T20:15:45.184Z",
"updated": "2019-01-22T20:34:20.687Z",
"lenders": [
{
"funded_amount": 45000,
"customer_balance": 45000,
"customer_id": "a51d0ac0-1e7d-11e9-8914-e96a7bd39676"
},
{
"funded_amount": 45000,
"customer_balance": 45000,
"customer_id": "946a98f0-1e7d-11e9-8914-e96a7bd39676"
}
],
"failure_code": "INVALID_DESTINATION",
"status": "FAILED"
}
We will send you a callback request with schema Loan Disbursement Resource with status FAILED
and failure_code
filled.
You will get this Callback once a Loan Disbursement has failed to be disbursed from Instamoney’s float account to the end-customer’s bank account, and the money has already been refunded to your Escrow Account.
Loan Disbursement Resource
Loan Disbursement Resource is the schema of all loan disbursement endpoint responses and callback requests.
Parameter | Description |
---|---|
id | string The unique ID of the transaction |
external_id | string A unique ID for your loan disbursement |
principal_amount | number The sum of the funded_amounts sent to the borrower |
loan_maturity_date | ISO date Date and time on which repayment of the loan needs to be made |
annual_percentage_rate | number Annual percentage rate |
lenders | array of object More than one lender can be identified here since our APIs allow more than one lender to contribute funds to any given loan |
lenders.customer_id | string The unique ID of the lender (set by you using the Create Customer endpoint) |
lenders.funded_amount | number Amount funded by the lender for the loan. The sum of the funded_amounts constitutes the principal amount sent to the borrower for the loan |
lenders.customer_balance | number Customer’s current balance after the loan disbursement request has been processed. If the withdrawal fails, the amount of the failed withdrawal will be added back to the customer’s balance |
borrower_id | string The unique ID of the borrower which this loan should be disbursed to (created by you using the Create Customer endpoint) |
admin_amount | number The amount of money you want to send to your chosen ADMIN customer object (will be deducted from the principal_amount ) |
admin_id | string The unique ID of the ADMIN customer object which the admin_amount will be sent to |
destination_account_code | string Code of the destination bank or e-Wallet. Refer to our list of supported banks and e-Wallets here |
destination_account_holder_name | string Name of the account holder as per the destination bank’s or e-Wallet’s records |
destination_account_number | string If disbursing to a bank, destination bank account number. If it is a BCA account number, the account number must be 10 characters exactlyIf disbursing to an e-Wallet, phone number registered with the e-Wallet account Example: 0812XXXXXX |
loan_id | string ID of the loan which you created the Loan DIsbursement for |
description | string Description to send with the transaction. |
status | string status of loan disbursement. can either be:PENDING DISBURSING COMPLETED FAILED |
created | ISO date An ISO timestamp that tracks when the loan payment was created |
updated | ISO date An ISO timestamp that tracks when the loan payment was last updated |
bank_reference | string Bank transfer reference provided by sender bank for successful transfer |
failure_code | string If your disbursement fails, this code will explain the reason why.list of errors: INSUFFICIENT_BALANCE The balance in your account is insufficient to make the disbursement in the desired amountUNKNOWN_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 hoursINVALID_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 accountSWITCHING_NETWORK_ERROR At least one of the switching networks is encountering an issue. Please retry the disbursement in 1-3 hoursREJECTED_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 informationTEMPORARY_TRANSFER_ERROR We’ve encountered a temporary issue while processing this disbursement. Please retry the disbursement in 1-2 hours |
Repayment
Call our Repayments API to move money from a borrower’s balance to a lender’s balance, to allow the lender to withdraw or reinvest the money.
Create Repayment
Endpoint: Create Repayment
POST /p2p-repayments
Example Create Repayment Request
curl -X POST \
'https://api.instamoney.co/p2p-repayments' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json' \
-d '{
"external_id": "repayment_875",
"amount": 976000,
"loan_id": "loan_879",
"borrower_id": "fa71ac40-417a-11e9-89d2-59190dbc8f33",
"lender_id": "ef3eb2f0-417a-11e9-89d2-59190dbc8f33",
}'
When money is paid into a “repayment” type virtual account, it settles into the Escrow account but is not immediately withdrawn to your lenders’ bank accounts. This is to allow your lenders to re-invest their monies using your P2P platform, without having to pre-fund it repeatedly (i.e. they can use money repaid from borrowers for reinvesting). Thus, in order to reflect that your lender has been repaid and that your borrower has repaid the loan, you will have to adjust the balance of your lender and borrower accordingly.
Our Loan API allows more than one lender to fund any given Loan. When your borrower repays a loan, their ledger balance in Instamoney will need to be increased by the amount repaid. In order to distribute this borrower’s ledger balance to the lenders who funded the loan, you will need to update each of the lenders’ balance according to your own algorithms (for example, according to the proportion in which they funded the Loan - if not, then however you wish to distribute the funds to the lenders).
Once you call the Create Repayment API, our system will deduct from the borrower’s balance to top up the lender’s balance. This is only an update of the ledgers and no money is actually moved.
The lender can then withdraw the money to their bank account by using our Withdrawal APIs through your P2P platform, or they can choose to reinvest in another loan.
Create Repayment Request
Parameter | Description |
---|---|
external_idrequired |
string Your unique ID for the repayment. Accepted characters a-z,0-9,A-Z; Accepted symbols (space)_:,.- Example: ab,cd:ext-id.test_1 |
amountrequired |
number Amount moved from a borrower to a lender |
borrower_idrequired |
string Instamoney’s internal customer ID for borrower (received as "ID" in the Create Customer response) |
lender_idrequired |
string Instamoney’s internal customer ID for lender (received as "ID" in the Create Customer response) |
admin_idoptional |
string Instamoney’s internal customer ID for an Admin (received as "ID" in the Create Customer response) |
admin_amountrequired only if
|
number amount which you want to transfer to your ADMIN customer object. Will be deducted from the amount |
loan_idrequired |
string ID you provided for the loan that is going to repaid. This Loan ID was set by you when calling Create Loan Disbursement API to create that Loan. Accepted characters a-z,0-9,A-Z; Accepted symbols (space)_:/,.- Example: ab,cd:/loan-id.test_1 |
Create Repayment Response
Example Create Repayment Response
{
"status": "PENDING",
"id": "1d89bd20-4186-11e9-bcdf-0b59ec82f64b",
"external_id": "repayment_875",
"amount": 976000,
"loan_id": "loan_879",
"borrower_id": "fa71ac40-417a-11e9-89d2-59190dbc8f33",
"lender_id": "ef3eb2f0-417a-11e9-89d2-59190dbc8f33",
"created": "2018-12-12T13:50:12.000Z",
"updated": "2018-12-12T13:50:12.000Z"
}
Our response body is Repayment Resource with status PENDING
.
Create Repayment Errors
Error Code | Description |
---|---|
INSUFFICIENT_BORROWER_BALANCE_ERROR 400 |
The balance of the borrower is not enough to process the do repayment. Can be caused by miscalculation of amount or incorrect borrower_id |
INVALID_LENDER_ID_ERROR 400 |
The lender_id is invalid or doesn’t exist |
INVALID_BORROWER_ID_ERROR 400 |
The borrower_id entered is invalid |
INVALID_ADMIN_ID_ERROR 400 |
The admin_id entered is invalid |
DUPLICATE_EXTERNAL_ID_ERROR 400 |
The external_id entered has been used before. Please enter a unique external_id and try again |
INVALID_LOAN_ID_ERROR 400 |
The loan_id entered does not correspond to any loan |
Get Repayment
Endpoint: Get Repayment by ID
GET /p2p-repayments/{id}
Example Get Repayment Request by ID
curl -X GET \
'https://api.instamoney.co/p2p-repayments/1d89bd20-4186-11e9-bcdf-0b59ec82f64b' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json'
Endpoint: Get Repayment by External ID
GET /p2p-repayments/external-id/{external_id}
Example Get Repayment Request by External ID
curl -X GET \
'https://api.instamoney.co/p2p-repayments/external-id/repayment_875' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json'
Get an existing Repayment by using the id
or external_id
on the respective endpoint. You can use this endpoint to query for a completed Repayment, or to check the current status of an ongoing Repayment before the callback is received by your URL.
Get Repayment Response
Our response body is Repayment Resource with current status represented.
Example Get Repayment Response
{
"status": "PENDING",
"id": "1d89bd20-4186-11e9-bcdf-0b59ec82f64b",
"external_id": "repayment_875",
"amount": 976000,
"loan_id": "loan_879",
"borrower_id": "fa71ac40-417a-11e9-89d2-59190dbc8f33",
"lender_id": "ef3eb2f0-417a-11e9-89d2-59190dbc8f33",
"created": "2018-12-12T13:50:12.000Z",
"updated": "2018-12-12T13:50:12.000Z"
}
Get Repayment Errors
Error Code | Description |
---|---|
REPAYMENT_NOT_FOUND_ERROR404 |
Repayment with specified ID or External ID is not found |
Repayment Callbacks
Example Repayment Completed Callback Request
{
"status": "COMPLETED",
"id": "1c09acd0-4186-11e9-bcdf-0b59ec82f64b",
"external_id": "repayment_670",
"amount": 976000,
"borrower_id": "fa71ac40-417a-11e9-89d2-59190dbc8f33",
"lender_id": "ef3eb2f0-417a-11e9-89d2-59190dbc8f33",
"loan_id": "loan_879",
"borrower_balance": 144000,
"lender_balance": 6941000,
"created": "2018-01-12T13:50:12.000Z",
"updated": "2018-01-12T13:50:12.000Z"
}
Example Repayment Failed Callback Request
{
"status": "FAILED",
"id": "1d89bd20-4186-11e9-bcdf-0b59ec82f64b",
"external_id": "repayment_875",
"amount": 976000,
"borrower_id": "fa71ac40-417a-11e9-89d2-59190dbc8f33",
"lender_id": "ef3eb2f0-417a-11e9-89d2-59190dbc8f33",
"loan_id": "loan_879",
"failure_code": "INSUFFICIENT_BORROWER_BALANCE_ERROR",
"created": "2018-01-12T13:50:12.000Z",
"updated": "2018-01-12T13:50:12.000Z"
}
You can receive notifications via a callback whenever the status of a Repayment has changed.
You can set your callback URL in the https://dashboard.instamoney.co/settings/developers#callbacks under P2P Escrow.
Give response with HTTP status code 2XX if you successfully processed the callback. Any other HTTP status code will be marked as failed callback, and you must resolve manually in https://dashboard.instamoney.co/callbacks.
Repayment Completed Callback
We will send you a callback request with schema Repayment Resource with status COMPLETED
. You will get this callback when the Create Repayment request is successful and the borrower and lenders’ balances have been updated.
Repayment Failed Callback
We will send you a callback request with schema Repayment Resource with status FAILED
. You will get this callback when the Create Repayment request was not successful. Check the failure code to learn more details about the error and what you should do.
Repayment Resource
Repayment Resource is the schema of all repayment endpoint responses and callback requests.
Parameter | Description |
---|---|
id | string Instamoney unique ID for the Repayment |
status | enum Repayment status. can either be:PENDING - Instamoney has received the Repayment request and it is queued to be sentCOMPLETED - The Repayment request has been processed and the borrower and lenders’ balances have been successfully updated.FAILED - The Repayment has failed. Check the failure_code for the reason. We will not retry |
external_id | string An unique ID for the Repayment provided by you |
amount | number Amount to do the Repayment |
loan_id | string ID of the loan which this Repayment request relates to |
borrower_id | string The unique ID of the borrower whose balance you are updating |
lender_id | string The unique ID of the lender whose balance you are updating |
admin_id | string The unique ID of the admin whose balance you are updating |
admin_amount | number amount transferred to your ADMIN customer object, deducted from the amount |
business_id | string Your Instamoney business ID |
borrower_balance | number The borrower’s ledger balance after being successfully updated. Only returned in a COMPLETED Repayment callback |
lender_balance | number The lender’s ledger balance after being successfully updated. Only returned in a COMPLETED Repayment callback |
admin_balance | number The admin's ledger balance after being successfully updated. Only returned in a COMPLETED Repayment callback |
failure_code | string If your Repayment fails, this will explain the reason why |
created | ISO date An ISO timestamp that tracks when the Repayment request was created |
updated | ISO date An ISO timestamp that tracks when the Repayment request was last updated |
Withdrawal
Withdrawals are withdrawals by your lenders, borrowers or admins from the Escrow Account ledger balance to their actual bank account of any lender or borrower. The primary function of a Withdrawal would be for your lenders to receive repayments of Loans made by borrowers.
Additional situations where a withdrawal is required include:
- When a lender has funds in the Escrow account that are not being used to fund any loans
- When a borrower has overpaid a repayment and needs to receive a refund
- When you wish to withdraw fees that have been paid to you by borrowers or lenders, from your admin balance to your actual bank account
Please note that you are unable to cancel a withdrawal request once it has been made.
Create Withdrawal
Endpoint: Create Withdrawal
POST /p2p-withdrawals
Use our Create Withdrawal API request to withdraw funds out of your Escrow Account back to your borrower or lender.
Create Withdrawal Request
Example Create Withdrawal Request
curl -X POST \
'https://api.instamoney.co/p2p-withdrawals' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json' \
-d '{
"external_id": "withdrawal-1233889871",
"amount": 100000,
"customer_id": "5c1774e76966b43a5b8198fc",
"destination_account_code": "BCA",
"destination_account_holder_name": "Dubu Tofu",
"destination_account_number": "0212312345",
"type": "WITHDRAWAL",
"description": "esc-wtdrw-123"
}'
Parameter | Description |
---|---|
amountrequired |
number Amount in question to be withdrawn from your Escrow Account
|
external_idrequired |
string A unique ID for the withdrawal provided by you. Accepted characters a-z,0-9,A-Z; Accepted symbols (space)_:,.- Example: ab,cd:ext-id.test_1 |
customer_idrequired |
string The unique ID of the lender, borrower, or admin who is withdrawing funds (set by you using the Create Customer endpoint) |
destination_account_coderequired |
string Code of the destination bank or e-Wallet. Refer to our list of supported banks and e-Wallets here |
destination_account_holder_namerequired |
string Name of the account holder as per the destination bank’s or e-Wallet’s records. Accepted characters a-z,0-9,A-Z; Accepted symbols (space).,'/- Example: Fa'ni, S.T-09/2017 |
destination_account_numberrequired |
string If disbursing to a bank, destination bank account number. If it is a BCA account number, the account number must be 10 characters exactlyIf disbursing to an e-Wallet, phone number registered with the e-Wallet account. Accepted characters 0-9 Example: 9883456789 |
typeoptionaldefault: WITHDRAWAL |
enum Can either be:WITHDRAWAL - from customer balance in escrow to customer’s bank / e-Wallet accountFEE - from customer balance in escrow to P2P’s operational bank accountOTHERS - for withdrawals of any other kind you may need to make |
descriptionoptional |
string Description to send with the transactionExample: esc-wtdrw-123 |
Create Withdrawal Response
Example Create Withdrawal Response
{
"id": "44e5abc9-be2a-41ce-af86-cf522ad6e260",
"external_id": "withdrawal-1233889871",
"amount": 100000,
"customer_balance": 0,
"customer_id": "5c1774e76966b43a5b8198fc",
"destination_account_code": "BCA",
"destination_account_holder_name": "Dubu Tofu",
"destination_account_number": "0212312345",
"status": "PENDING",
"type": "WITHDRAWAL",
"created": "2018-12-12T13:50:12.000Z",
"updated": "2018-12-12T13:50:12.000Z"
}
Our response body is Withdrawal Resource with status PENDING
Create Withdrawal Errors
Error Code | Description |
---|---|
INVALID_CUSTOMER_ID_ERROR 400 |
The customer_id is invalid |
ACCOUNT_CODE_NOT_SUPPORTED_ERROR 400 |
The code of the destination account is currently not supported |
DUPLICATE_EXTERNAL_ID_ERROR 400 |
The external_id entered has been used before. Please enter a unique external_id and try again |
INSUFFICIENT_BALANCE_ERROR 400 |
Balance of the customer you are trying to withdraw from is insufficient |
RECIPIENT_ACCOUNT_NUMBER_ERROR 400 |
The destination_account_number is invalid |
RECIPIENT_AMOUNT_ERROR 400 |
Invalid transfer amount, please check the limitation of the transfer amount |
BANK_CODE_NOT_SUPPORTED_ERROR 400 |
The destination_account_code is invalid |
MAXIMUM_TRANSACTION_LIMIT_ERROR 400 |
Your funded amount has been exceeding the limit. Please contact our customer support team for more information |
Get Withdrawal
Endpoint: Get Withdrawal by ID
GET /p2p-withdrawals/{id}
Example Get Withdrawal Request by ID
curl -X GET \
'https://api.instamoney.co/p2p-withdrawals/44e5abc9-be2a-41ce-af86-cf522ad6e260' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json'
Endpoint: Get Withdrawal by External ID
GET /p2p-withdrawals/external-id/{external_id}
Example Get Withdrawal Request by External ID
curl -X GET \
'https://api.instamoney.co/p2p-withdrawals/external-id/withdrawal-1233889871' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json'
Get an existing Withdrawal by using the id
or external_id
on the respective endpoint. You can use this endpoint to query for a past Withdrawal, or to check the current status of an ongoing withdrawal before the callback arrives in your URL.
Get Withdrawal Response
Our response body is Withdrawal Resource with current status represented.
Example Get Withdrawal Response
{
"id": "44e5abc9-be2a-41ce-af86-cf522ad6e260",
"external_id": "withdrawal-1233889871",
"amount": 100000,
"customer_balance": 0,
"customer_id": "5c1774e76966b43a5b8198fc",
"destination_account_code": "BCA",
"destination_account_holder_name": "Dubu Tofu",
"destination_account_number": "0212312345",
"status": "DISBURSING",
"type": "WITHDRAWAL",
"created": "2018-12-12T13:50:12.000Z",
"updated": "2018-12-12T13:50:12.000Z"
}
Get Withdrawal Errors
Error Code | Description |
---|---|
ESCROW_WITHDRAWAL_NOT_FOUND_ERROR404 |
Withdrawal with that Id is not found |
Withdrawal Callbacks
Example Withdrawal Disbursing Callback Request
{
"id": "af7e77b0-1e87-11e9-8914-e96a7bd39676",
"external_id": "wiag_1548190371",
"amount": 50000,
"customer_balance": 40000,
"destination_account_code": "MANDIRI",
"destination_destination_account_holder_name": "Lingga",
"destination_account_number": "7654321",
"type": "WITHDRAWAL",
"created": "2019-01-22T20:52:52.523Z",
"updated": "2019-01-22T20:53:08.190Z",
"customer_id": "946a98f0-1e7d-11e9-8914-e96a7bd39676",
"status": "DISBURSING"
}
Example Withdrawal Completed Callback Request
{
"id": "af7e77b0-1e87-11e9-8914-e96a7bd39676",
"external_id": "wiag_1548190371",
"amount": 50000,
"customer_balance": 40000,
"destination_account_code": "MANDIRI",
"destination_destination_account_holder_name": "Lingga",
"destination_account_number": "7654321",
"type": "WITHDRAWAL",
"created": "2019-01-22T20:57:52.347Z",
"updated": "2019-01-22T20:56:08.187Z",
"customer_id": "946a98f0-1e7d-11e9-8914-e96a7bd39676",
"status": "COMPLETED"
}
Example Withdrawal Failed Callback Request
{
"id": "af7e77b0-1e87-11e9-8914-e96a7bd39676",
"external_id": "wiag_1548190371",
"amount": 50000,
"customer_balance": 40000,
"destination_account_code": "MANDIRI",
"destination_destination_account_holder_name": "Lingga",
"destination_account_number": "7654321",
"type": "WITHDRAWAL",
"created": "2019-01-22T20:57:52.347Z",
"updated": "2019-01-22T20:56:08.187Z",
"customer_id": "946a98f0-1e7d-11e9-8914-e96a7bd39676",
"status": "FAILED"
}
You can receive notifications via a callback whenever a Withdrawal has been successfully made (to a Borrower or Lender) , or if it has failed.
You can set your callback URL in the https://dashboard.instamoney.co/settings/developers#callbacks under P2P Escrow.
Give response with HTTP status code 2XX if you successfully processed the callback. Any other HTTP status code will be marked as failed callback, and you must resolve manually in https://dashboard.instamoney.co/callbacks.
Withdrawal Disbursing Callback
We will send you a callback request with schema Withdrawal Resource with status DISBURSING
. You will get this callback once your balance has been successfully moved from escrow account to Instamoney’s float account.
Withdrawal Completed Callback
We will send you a callback request with schema Withdrawal Resource with status COMPLETED
and bank_reference
filled.
You will get this callback once the withdrawal has been successfully disbursed from Instamoney’s float account to the customer’s bank account.
Withdrawal Failed Callback
We will send you a callback request with schema Withdrawal Resource with status FAILED
and failure_code
filled.
You will get this callback once the withdrawal has failed to be disbursed from Instamoney’s float account to the end customer’s bank account, and the money has already been refunded to your escrow bank account.
Withdrawal Resource
Withdrawal Resource is the schema of all withdrawal endpoint responses and callback requests.
Parameter | Description |
---|---|
id | string Instamoney unique ID for the withdrawal |
external_id | string A unique ID for the withdrawal provided by you |
amount | number Amount withdrawn |
customer_balance | number Customer’s current balance after the withdrawal request has been processed. If the withdrawal fails, the amount of the failed withdrawal will be added back to the customer’s balance |
customer_id | string The unique ID of the lender or borrower withdrawing funds from the Escrow Account |
destination_account_code | string Code of the destination bank or e-Wallet. Refer to our list of supported banks and e-Wallets here |
destination_account_holder_name | string Name of the account holder as per the destination bank’s or e-Wallet’s records |
destination_account_number | string If disbursing to a bank, destination bank account number. If it is a BCA account number, the account number must be 10 characters exactlyIf disbursing to an e-Wallet, phone number registered with the e-Wallet account Example: 0812XXXXXX |
description | string Description to send with the transaction |
status | string Withdrawal status. Can either be:PENDING DISBURSING COMPLETED FAILED |
type | string Withdrawal type. Can either be:WITHDRAWAL - from customer balance in escrow to customer’s bank / e-Wallet account FEE - from customer balance in escrow to P2P’s operational bank account |
created | ISO date An ISO timestamp that tracks when the withdrawal was created |
updated | ISO date An ISO timestamp that tracks when the withdrawal was last updated |
bank_reference | string Bank transfer reference provided by sender bank for successful transfer |
failure_code | string If your disbursement fails, this code will explain the reason why.list of errors: INSUFFICIENT_BALANCE The balance in your account is insufficient to make the disbursement in the desired amountUNKNOWN_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 hoursINVALID_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 accountSWITCHING_NETWORK_ERROR At least one of the switching networks is encountering an issue. Please retry the disbursement in 1-3 hoursREJECTED_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 informationTEMPORARY_TRANSFER_ERROR We’ve encountered a temporary issue while processing this disbursement. Please retry the disbursement in 1-2 hours |
Bank Codes
Find the list of bank codes below for the banks we support. 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). If you would like us to support payment to a specific destination, please contact us at help@instamoney.co.
Bank | Bank Code | Swift Code |
---|---|---|
Bank Agroniaga | AGRONIAGA | AGTBIDJA |
Bank Amar Indonesiaformerly Anglomas International Bank |
AMAR | LOMAIDJ1 |
Bank ANZ Indonesia | ANZ | ANZBIDJX |
Bank Artha Graha International | ARTHA | ARTGIDJA |
Bank BCA Digital | BCA_DIGITAL | ROYBIDJ1 |
Bank Bisnis Internasional | BISNIS_INTERNASIONAL | BUSTIDJ1 |
Bank BJB | BJB | PDJBIDJA |
Bank BJB Syariah | BJB_SYR | SYJBIDJ1 |
Bank BNP Paribas | BNP_PARIBAS | BNPAIDJA |
Bank Bukopin | BUKOPIN | BBUKIDJA |
Bank Bumi Arta | BUMI_ARTA | BBAIIDJA |
Bank Capital Indonesia | CAPITAL | BCIAIDJA |
Bank Central Asia (BCA) | BCA | CENAIDJA |
Bank Central Asia (BCA) Syariah | BCA_SYR | SYCAIDJ1 |
Bank Chinatrust Indonesia | CHINATRUST | CTCBIDJA |
Bank CIMB Niaga | CIMB | BNIAIDJA |
Bank CIMB Niaga UUS | CIMB_UUS | SYNAIDJ1 |
Bank Commonwealth | COMMONWEALTH | BICNIDJA |
Bank Danamon | DANAMON | BDINIDJA |
Bank Danamon UUS | DANAMON_UUS | SYBDIDJ1 |
Bank DBS Indonesia | DBS | DBSBIDJA |
Bank Dinar Indonesia | DINAR_INDONESIA | LMANIDJ1 |
Bank DKI | DKI | BDKIIDJA |
Bank DKI UUS | DKI_UUS | SYDKIDJ1 |
Bank Fama International | FAMA | FAMAIDJ1 |
Bank Ganesha | GANESHA | GNESIDJA |
Bank Hana | HANA | HNBNIDJA |
Bank ICBC Indonesia | ICBC | ICBKIDJA |
Bank Ina Perdania | INA_PERDANA | INPBIDJ1 |
Bank Index Selindo | INDEX_SELINDO | BIDXIDJA |
Bank Jasa Jakarta | JASA_JAKARTA | JAJSIDJ1 |
Bank JTrust Indonesiaformerly Bank Mutiara |
JTRUST | CICTIDJA |
Bank Mandiri | MANDIRI | BMRIIDJA |
Bank Maspion Indonesia | MASPION | MASDIDJS |
Bank Mayapada International | MAYAPADA | MAYAIDJA |
Bank Maybank | MAYBANK | IBBKIDJA |
Bank Maybank Syariah Indonesia | MAYBANK_SYR | MBBEIDJA |
Bank Mayora | MAYORA | MAYOIDJA |
Bank Mega | MEGA | MEGAIDJA |
Bank Mestika Dharma | MESTIKA_DHARMA | MEDHIDS1 |
Bank Mizuho Indonesia | MIZUHO | MHCCIDJA |
Bank MNC Internasional | MNC_INTERNASIONAL | BUMIIDJA |
Bank Muamalat Indonesia | MUAMALAT | MUABIDJA |
Bank Multi Arta Sentosa | MULTI_ARTA_SENTOSA | BMSEIDJA |
Bank Nationalnobu | NATIONALNOBU | LFIBIDJ1 |
Bank Negara Indonesia (BNI) | BNI | BNINIDJA |
Bank OCBC NISP | OCBC | NISPIDJA |
Bank OCBC NISP UUS | OCBC_UUS | SYONIDJ1 |
Bank of America Merill-Lynch | BAML | BOFAID2X |
Bank of China (BOC) | BOC | BKCHIDJA |
Bank of India Indonesia | INDIA | BKIDIDJA |
Bank of Tokyo Mitsubishi UFJ | TOKYO | BOTKIDJX |
Bank Oke Indonesiaformerly Bank Andara |
OKE | RIPAIDJ1 |
Bank Panin | PANIN | PINBIDJA |
Bank Panin Syariah | PANIN_SYR | ARFAIDJ1 |
Bank Permata | PERMATA | BBBAIDJA |
Bank Permata UUS | PERMATA_UUS | SYBBIDJ1 |
Bank QNB Indonesiaformerly Bank QNB Kesawan |
QNB_INDONESIA | AWANIDJA |
Bank Rabobank International Indonesia | RABOBANK | RABOIDJA |
Bank Rakyat Indonesia (BRI) | BRI | BRINIDJA |
Bank Resona Perdania | RESONA | BPIAIDJA |
Bank Royal Indonesia | ROYAL | ROYBIDJ1 |
Bank Sahabat Sampoerna | SAHABAT_SAMPOERNA | BDIPIDJ1 |
Bank SBI Indonesia | SBI_INDONESIA | IDMOIDJ1 |
Bank Shinhan Indonesiaformerly Bank Metro Express |
SHINHAN | MEEKIDJ1 |
Bank Sinarmas | SINARMAS | SBJKIDJA |
Bank Sinarmas UUS | SINARMAS_UUS | SYTBIDJ1 |
Bank Syariah Bukopin | BUKOPIN_SYR | SDOBIDJ1 |
Bank Syariah Indonesia | BSI | BSMDIDJA |
Bank Syariah Mega | MEGA_SYR | BUTGIDJ1 |
Bank Tabungan Negara (BTN) | BTN | BTANIDJA |
Bank Tabungan Negara (BTN) UUS | BTN_UUS | SYBTIDJ1 |
Bank Tabungan Pensiunan Nasional | TABUNGAN_PENSIUNAN_NASIONAL | BTPNIDJA |
Bank UOB Indonesia | UOB | BBIJIDJA |
Bank Victoria Internasional | VICTORIA_INTERNASIONAL | BVICIDJA |
Bank Victoria Syariah | VICTORIA_SYR | SWAGIDJ1 |
Bank Woori Indonesia | WOORI | HVBKIDJA |
BPD Aceh | ACEH | PDACIDJ1 |
BPD Aceh UUS | ACEH_UUS | SYACIDJ1 |
BPD Bali | BALI | ABALIDBS |
BPD Bantenformerly Bank Pundi Indonesia |
BANTEN | PDBBIDJ1 |
BPD Bengkulu | BENGKULU | PDBKIDJ1 |
BPD Daerah Istimewa Yogyakarta (DIY) | DAERAH_ISTIMEWA | PDYKIDJ1 |
BPD Daerah Istimewa Yogyakarta (DIY) UUS | DAERAH_ISTIMEWA_UUS | SYYKIDJ1 |
BPD Jambi | JAMBI | PDJMIDJ1 |
BPD Jawa Tengah | JAWA_TENGAH | PDJGIDJ1 |
BPD Jawa Tengah UUS | JAWA_TENGAH_UUS | SYJGIDJ1 |
BPD Jawa Timur | JAWA_TIMUR | PDJTIDJ1 |
BPD Jawa Timur UUS | JAWA_TIMUR_UUS | SYJTIDJ1 |
BPD Kalimantan Barat | KALIMANTAN_BARAT | PDKBIDJ1 |
BPD Kalimantan Barat UUS | KALIMANTAN_BARAT_UUS | SYKBIDJ1 |
BPD Kalimantan Selatan | KALIMANTAN_SELATAN | PDKSIDJ1 |
BPD Kalimantan Selatan UUS | KALIMANTAN_SELATAN_UUS | SYKSIDJ1 |
BPD Kalimantan Tengah | KALIMANTAN_TENGAH | PDKGIDJ1 |
BPD Kalimantan Timur | KALIMANTAN_TIMUR | PDKTIDJ1 |
BPD Kalimantan Timur UUS | KALIMANTAN_TIMUR_UUS | SYKTIDJ1 |
BPD Lampung | LAMPUNG | PDLPIDJ1 |
BPD Maluku | MALUKU | PDMLIDJ1 |
BPD Nusa Tenggara Barat | NUSA_TENGGARA_BARAT | PDNBIDJ1 |
BPD Nusa Tenggara Timur | NUSA_TENGGARA_TIMUR | PDNTIDJ1 |
BPD Papua | PAPUA | PDIJIDJ1 |
BPD Riau Dan Kepri | RIAU_DAN_KEPRI | PDRIIDJA |
BPD Riau Dan Kepri UUS | RIAU_DAN_KEPRI_UUS | SYRIIDJ1 |
BPD Sulawesi Tengah | SULAWESI | PDWGIDJ1 |
BPD Sulawesi Tenggara | SULAWESI_TENGGARA | PDWRIDJ1 |
BPD Sulselbar | SULSELBAR | PDWSIDJ1 |
BPD Sulselbar UUS | SULSELBAR_UUS | SYWSIDJ1 |
BPD Sulut | SULUT | PDWUIDJ1 |
BPD Sumatera Barat | SUMATERA_BARAT | PDSBIDSP |
BPD Sumatera Barat UUS | SUMATERA_BARAT_UUS | SYSBIDJ1 |
BPD Sumsel Dan Babel | SUMSEL_DAN_BABEL | BSSPIDSP |
BPD Sumsel Dan Babel UUS | SUMSEL_DAN_BABEL_UUS | SYSSIDJ1 |
BPD Sumut | SUMUT | PDSUIDJ1 |
BPD Sumut UUS | SUMUT_UUS | SYSUIDJ1 |
BTPN Syariahformerly BTPN UUS and Bank Sahabat Purba Danarta |
BTPN_SYARIAH | PUBAIDJ1 |
China Construction Bank Indonesiaformerly Bank Antar Daerah and Bank Windu Kentjana International |
CCB | BWKIIDJA |
Citibank | CITIBANK | CITIIDJX |
Deutsche Bank | DEUTSCHE | DEUTIDJA |
Hongkong and Shanghai Bank Corporation (HSBC) UUS | HSBC_UUS | HSBCIDJA |
HSBC Indonesiaformerly Bank Ekonomi Raharja |
HSBC | HSBCIDJA |
JP Morgan Chase Bank | JPMORGAN | CHASIDJX |
Mandiri Taspen Posformerly Bank Sinar Harapan Bali |
MANDIRI_TASPEN | SIHBIDJ1 |
Prima Master Bank | PRIMA_MASTER | PMASIDJ1 |
Standard Chartered Bank | STANDARD_CHARTERED | SCBLIDJX |
GoPay | GOPAY | - |
OVO | OVO | - |
DANA | DANA | - |
ShopeePay | SHOPEEPAY | - |
Bank Aladin Syariahformerly Bank Maybank Syariah Indonesia |
ALADIN | MBBEIDJA |
Bank Neo Commerceformerly Bank Yudha Bhakti |
BNC | YUDBIDJ1 |
Bank Seabank Indonesiaformerly Bank Kesejahteraan Ekonomi |
SEABANK | KSEBIDJ1 |
Bank Jagoformerly Bank Artos Indonesia |
JAGO | ATOSIDJ1 |
Allo Bank Indonesiaformerly Bank Harda Internasional |
ALLO | HRDAIDJ1 |
Bank IBK Indonesiaformerly Bank Agris |
IBK | IBKOIDJA |
Anglomas International Bank | ANGLOMAS | LOMAIDJ1 |
Bank Himpunan Saudara 1906 | HIMPUNAN_SAUDARA | HVBKIDJA |
BPD Nusa Tenggara Barat UUS | NUSA_TENGGARA_BARAT_UUS | SYNBIDJ1 |
Internal Transfer
Internal Transfer API allows you to transfer money internally between customer objects in Escrow Account.
Please note that you are unable to cancel an internal transfer request once it has been made.
Create Internal Transfer
Endpoint: Create Internal Transfer
POST /p2p-internal-transfers
Example Create Internal Transfer Request
curl -X POST \
'https://api.instamoney.co/p2p-internal-transfers' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json' \
-d '{
"external_id": "internal_transfer_392",
"amount": 500000,
"sender_customer_id": "113c1990-5ebe-11ea-87bd-4fb8c98084a0",
"recipient_customer_id": "46536890-5ebe-11ea-87bd-4fb8c98084a0",
}'
You may use this endpoint to transfer money between types of customer object with following limitations:
- You won't be able to do Internal Transfer between same sender and recipient customer object
- You won't be able to do Internal Transfer between sender customer object with type
BORROWER
and recipient customer object with typeBORROWER
Create Internal Transfer Request
Parameter | Description |
---|---|
external_idrequired |
string Your unique ID for the internal transfer. Accepted characters a-z,0-9,A-Z; Accepted symbols (space)_:,.- Example: ab,cd:ext-id.test_1 |
amountrequired |
number Exact amount moved from the sender's balance to the recipient's balanceConstraint: integer with minimum of 1 |
sender_customer_idrequired |
string Instamoney’s internal customer ID (received as "ID" in the Create Customer response) |
recipient_customer_idrequired |
string Instamoney’s internal customer ID (received as "ID" in the Create Customer response) |
Create Internal Transfer Response
Example Create Internal Transfer Response
{
"id": "47136390-5ec6-11ea-a718-4396d3ad6b46",
"external_id": "internal_transfer_392",
"amount": 500000,
"sender_customer_id": "113c1990-5ebe-11ea-87bd-4fb8c98084a0",
"recipient_customer_id": "46536890-5ebe-11ea-87bd-4fb8c98084a0",
"status": "COMPLETED",
"created": "2018-12-12T13:50:12.000Z",
"updated": "2018-12-12T13:50:12.000Z"
}
Our response body is Internal Transfer Resource.
Create Internal Transfer Errors
Error Code | Description |
---|---|
SENDER_CUSTOMER_ID_NOT_FOUND_ERROR 404 |
The sender_customer_id entered is invalid or doesn’t exist |
RECIPIENT_CUSTOMER_ID_NOT_FOUND_ERROR 404 |
The recipient_customer_id entered is invalid or doesn't exist |
INSUFFICIENT_BALANCE_ERROR 401 |
The balance of the sender is not enough to process the internal transfers |
DUPLICATE_EXTERNAL_ID_ERROR 400 |
The external_id entered has been used before. Please enter a unique external_id and try again |
TRANSFER_NOT_ALLOWED 400 |
The transfer format that submitted is violate the restrictionsRestrictions: |
Get Internal Transfer
Endpoint: Get Internal Transfer by ID
GET /p2p-internal-transfers/{id}
Example Get Internal Transfer Request by ID
curl -X GET \
'https://api.instamoney.co/p2p-internal-transfers/47136390-5ec6-11ea-a718-4396d3ad6b46' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json'
Endpoint: Get Internal Transfer by External ID
GET /p2p-internal-transfers/external-id/{external_id}
Example Get Internal Transfer Request by External ID
curl -X GET \
'https://api.instamoney.co/p2p-internal-transfers/external-id/internal_transfer_392' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json'
Get an existing Internal Transfer by using the id
or external_id
on the respective endpoint. You can use this endpoint to query for an Internal Transfer.
Get Internal Transfer Response
Our response body is Internal Transfer Resource.
Example Get Internal Transfer Response
{
"id": "47136390-5ec6-11ea-a718-4396d3ad6b46",
"external_id": "internal_transfer_392",
"amount": 500000,
"sender_customer_id": "113c1990-5ebe-11ea-87bd-4fb8c98084a0",
"recipient_customer_id": "46536890-5ebe-11ea-87bd-4fb8c98084a0",
"status": "COMPLETED",
"created": "2018-12-12T13:50:12.000Z",
"updated": "2018-12-12T13:50:12.000Z"
}
Get Internal Transfer Errors
Error Code | Description |
---|---|
INTERNAL_TRANSFER_NOT_FOUND_ERROR404 |
Internal Transfer with specified ID or External ID is not found |
Internal Transfer Resource
Internal Transfer Resource is the schema of all Internal Transfer endpoints response.
Parameter | Description |
---|---|
id | string Instamoney unique ID for the Internal Transfer |
status | enum Internal Transfer status. can either be:COMPLETED - Internal transfer success. If there's no error occured, all internal transfer endpoints will respond with this statusPENDING - Internal transfer creation got SERVER_ERROR and the reconciliation is on progress. You will only see this status on Get Internal Transfer by External ID endpoint |
external_id | string A unique ID for the Internal Transfer provided by you |
amount | number Amount to do the Internal Transfer |
sender_customer_id | string The unique ID of the customer object that act as sender |
recipient_customer_id | string The unique ID of the customer object that act as recipient |
failure_code | string If your Internal Transfer fails, this will explain the reason |
created | ISO date An ISO timestamp that tracks when the Internal Transfer request was created |
updated | ISO date An ISO timestamp that tracks when the Internal Transfer request was last updated |
Transaction Report
Transaction reports are the report that shows all transactions that exist and created under Instamoney Escrow Product. This report will not show the non-feature transactions like manual top-up and withdrawal. This report is equivalent to the Escrow Transaction Tab on the dashboard.
Create Transaction Report
Endpoint: Create Transaction Report
POST /p2p-reports
Use this endpoint to export transaction report and as an alternative to the export CSV from P2P Escrow dashboard Transaction Tab.
Create Transaction Report Request
Example Create Transaction Report Request
curl -X POST \
'https://api.instamoney.co/p2p-reports' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==: \
-H 'Content-Type: application/json' \
-d '{
"filter": {
"from" : "2022-01-01T17:00:00.00Z",
"to": "2022-01-31T17:00:00.00Z"
},
"format": "CSV"
}'
Parameter | Description |
---|---|
filterrequired |
object Filtering that are applied to report. |
filter.fromrequired |
string (ISO 8601) The start time of the transaction to be filtered. This date should be no later than present time. |
filter.torequired |
string (ISO 8601) The end time of the transaction to be filtered. This date shouldn't be earlier than filter.from |
formatoptional |
string The format of the report, can either be: CSV .Available format is only CSV for now. |
Create Transaction Report Response
Our response body is Transaction Report Resource with status PENDING
Example Create Transaction Report Response
{
"id": "b2b9d050-e7z6-11ec-9a7f-ebc986556d07",
"filter": {
"from": "2022-01-01T17:00:00.00Z",
"to": "2022-01-31T17:00:00.00Z"
},
"format": "CSV",
"status": "PENDING",
"failure_reason": null,
"url": null,
"expires_at": null,
"updated": "2022-06-09T09:29:44.918Z",
"created": "2022-06-09T09:29:44.918Z"
}
Get Transaction Report
Endpoint: Get Transaction Report by ID
GET /p2p-reports/{id}
Example Get Transaction Report Request by ID
curl --X GET \
'https://api.instamoney.co/p2p-reports/b2b9d050-e7z6-11ec-9a7f-ebc986556d07' \
-u sk_test_OYCEfL5xgLL+l8ZvK7QaSGGVMN73oNEpk3yz+Rxn/2bS/LCgCQZ+gw==:
Get an existing Transaction Report by using the id
on the respective endpoint. You can use this to query for a past Transaction Report, or to check the current status of an ongoing Transaction Report before the callback is received by your URL.
Get Transaction Report Response
Our response body is Transaction Report Resource with current status represented.
Example Transaction Report Response
{
"id": "b2b9d050-e7z6-11ec-9a7f-ebc986556d07",
"filter": {
"from": "2022-01-01T17:00:00.00Z",
"to": "2022-01-31T17:00:00.00Z"
},
"format": "CSV",
"status": "COMPLETED",
"failure_reason": null,
"url": "https://transaction-report-files.s3.us-west-2.amazonaws.com/61f28f613dd4630780778ec1/transaction_report_1654766985342.csv?AWSAccessKeyId=AKIAWDX4EPHWHF77FGHM&Expires=1654853390&Signature=3RHIRExjAjbSAuhWlHGDKmn3A0s%3D",
"expires_at": "2022-06-10T09:29:50.134Z",
"created": "2022-06-09T09:29:44.918Z",
"updated": "2022-06-09T09:29:50.231Z"
}
Get Transaction Report Errors
Error Code | Description |
---|---|
TRANSACTION_REPORT_NOT_FOUND_ERROR404 |
Transaction Report with specified ID is not found. Please try again with valid Report ID. |
Transaction Report Callbacks
Example Transaction Report Completed Callback Request
{
"event": "escrow.report",
"created": "2022-06-09T09:29:51.918Z",
"business_id": "f59fcbb7-848d-4242-af07-a8bb7e3ab37c",
"data": {
"id": "b2b9d050-e7z6-11ec-9a7f-ebc986556d07",
"filter": {
"from": "2022-01-01T17:00:00.00Z",
"to": "2022-01-31T17:00:00.00Z"
},
"format": "CSV",
"status": "COMPLETED",
"failure_reason": null,
"url": "https://transaction-report-files.s3.us-west-2.amazonaws.com/623456789012630780778ec1/transaction_report_1654766985342.csv?AWSAccessKeyId=AKIAWDX4EPHWHF77FGHM&Expires=1654853390&Signature=3RHIRExjAjbSAuhWlHGDKmn3A0s%3D",
"expires_at": "2022-06-10T09:29:50.134Z",
"created": "2022-06-09T09:29:44.918Z",
"updated": "2022-06-09T09:29:50.231Z"
}
}
You will receive notifications via a callback when transaction report is completed or failed.
You can set your callback URL in the https://dashboard.instamoney.co/settings/developers#callbacks under P2P Escrow.
Give response with HTTP status code 2XX if you successfully processed the callback. Any other HTTP status code will be marked as failed callback, and you must resolve manually in https://dashboard.instamoney.co/callbacks.
Transaction Report Completed Callback
We will send you a callback request with schema Transaction Report Callback Request Resource with data.status COMPLETED
. data.url
and data.expires_at
are filled.
You will get this callback once the transaction report has been successfully created.
Transaction Report Failed Callback
Example Transaction Report Failed Callback Request
{
"event": "escrow.report",
"created": "2022-06-09T09:29:51.918Z",
"business_id": "f59fcbb7-848d-4242-af07-a8bb7e3ab37c",
"data": {
"id": "b2b9d050-e7z6-11ec-9a7f-ebc986556d07",
"filter": {
"from": "2020-01-01T17:00:00.00Z",
"to": "2022-01-31T17:00:00.00Z"
},
"format": "CSV",
"status": "COMPLETED",
"failure_reason": "COUNT_LIMIT_EXCEEDED",
"url": null,
"expires_at": null,
"created": "2022-06-09T09:29:44.918Z",
"updated": "2022-06-09T09:29:50.231Z"
}
}
We will send you a callback request with schema Transaction Report Callback Request Resource with data.status FAILED
and data.failure_reason
is filled.
You will get this Callback once the Transaction Report has failed to be created.
Transaction Report Callback Request Resource
Transaction Report Callback Request Resource is the schema of callback requests.
Parameter | Description |
---|---|
event | string Callback event. |
created | string (ISO 8601) Timestamp when the event was triggered. |
business_id | string Instamoney's identifier for your business. |
data | object Transaction Report Resource, can either hasstatus COMPLETED . url and expires_at are filled - in a Completed Callback.status FAILED and failure_reason is filled - in a Failed Callback. |
Transaction Report Resource
Transaction Report Resource is the schema of all transaction report endpoint responses.
Parameter | Description |
---|---|
id | string The unique ID of the transaction |
filter | object Filtering that are applied to report. |
filter.from | string (ISO 8601) The start time of the transaction to be filtered. |
filter.to | string (ISO 8601) The end time of the transaction to be filtered. |
format | string The format of the report. |
status | string status of transaction report. can either be:PENDING COMPLETED FAILED |
failure_reason | string If your request fails, this will explain the reason why.List of errors: COUNT_LIMIT_EXCEEDED The transaction data count exceeds the limit of 400,000 |
url | string URL to download the transaction report in format form when status is COMPLETED . The report itself contains information with schema Transaction Report File Template.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. |
expires_at | ISO date A timestamp that tracks when the report will be expired. |
created | ISO date An ISO timestamp that tracks when the transaction report was created |
updated | ISO date An ISO timestamp that tracks when the transaction report was last updated |
Transaction Report File Template
Transaction Report File Template is the schema of the requested report. The report template for Escrow Transaction is the same with the current result of Export CSV via IM Dashboard.
Column | Description |
---|---|
status | The status of the corresponding transaction. |
id | The unique ID assigned by Instamoney’s system to merchant’s transaction. |
created_date_iso | An ISO timestamp that tracks when the transaction was created. |
updated_date_iso | An ISO timestamp that tracks when the transaction was last updated. |
type | The type of the corresponding transaction. |
external_id | The external ID of corresponding transaction. |
amount | Amount of the transaction. |
loan_id | The Loan ID of the corresponding transaction |
virtual_bank_code | The Virtual Account Bank Code of the corresponding VA Payment Transaction (only applied for VA Payment). |
virtual_account_number | The Virtual Account Number of the corresponding VA Payment Transaction (only applied for VA Payment). |
destination_bank_code | The destination bank or e-Wallet code of the corresponding Disbursement transaction (only applied for Loan Disbursement and Escrow Withdrawal). |
destination_bank_number | The destination account number or e-Wallet of the corresponding Disbursement transaction (only applied for Loan Disbursement and Escrow Withdrawal). |
description | The description that is sent along with the transaction. |
bank_reference | Bank transfer reference provided by sender bank for successful disbursement |
payment_identifier | Payment ID from the disbursement(only applied for VA Payment, Loan Disbursement and Escrow Withdrawal). |
customer_virtual_account_number | The Virtual Account Number of the Customer Object |
sender_customer_id | The Customer ID of the sender customer object (Only applied for Internal Transfer) |
receiver_customer_id | The Customer ID of the borrower customer object (Only applied for Internal Transfer) |
is_credit | Indicator whether the corresponding transaction is Credit or Debit |
Testing P2P Escrow
For this step-by step testing, you can download our postman collection here
Step 1: Register
Register on the Instamoney Dashboard https://dashboard.instamoney.co/login
Step 2: Set your account up for testing
-
Activate escrow testing by clicking on "Activate P2P Escrow for testing" button in https://dashboard.instamoney.co/settings/p2p-escrow-rdl section P2P Escrow. or else, you will get
AUTHORIZATION_ERROR
-
After clicking the "Activate P2P Escrow for testing" button, you can set your callback URLs by pressing "Save and Test Callback" button.
Tips: you can use a free web request bucket like https://webhook.site for testing when you don't have server yet
-
In P2P Escrow section
-
Escrow Fixed Virtual Account Activated Callback URLs
-
Escrow Fixed Virtual Account Payment Callback URLs
-
Loan Disbursement Callback URLs
-
Escrow Withdrawal Callback URLs
-
Repayment Callback URLs
-
-
-
Obtain your development API key in https://dashboard.instamoney.co/security
- If you test using our postman collection, assign the API key into an environment variable called
api-key
- If you test using our postman collection, assign the API key into an environment variable called
Step 3: Create Customers for your testing flow
-
API endpoint:
https://api.instamoney.co/p2p-customers
-
Send a Create Customer request to this endpoint to test creating customer objects for your borrowers and lenders. For testing, you need at least 1 lender and 1 borrower. If entered validly, a success response will be received
-
You can also test to see what kind of Error Codes you can receive when creating Customers.
-
Check your Callback URL. If you have sent a valid request, you should receive a Customer Activated callback with the status
ACTIVE
.
Step 4: Create Fixed Virtual Accounts with type LOAN for lenders to pay into
-
API endpoint:
https://api.instamoney.co/p2p-escrow-virtual-accounts
-
Send a Create Fixed Virtual Account request to this endpoint to create virtual accounts for your lenders to prefund their balance.
-
Set the
payment_type
toLOAN
to identify these virtual accounts as Loan virtual accounts - this is important to differentiate virtual accounts created for the purposes of lenders funding, from those created for borrowers making repayments -
Check your Callback URL. If you have sent a valid request, you should receive a Fixed Virtual Account Activated callback with the status
ACTIVE
.
Step 5: Pay into the Fixed Virtual Accounts with type LOAN
Example testing payment request
POST https://api.instamoney.co/p2p-escrow-virtual-accounts/testing-payments
{
"external_id": "${external_id}",
"amount": "12000"
}
If you test in development mode, you can send testing payment request with JSON body
external_id
of the fixed VAamount
of the payment simulation
If you test in live mode, you can send real money to the VA number
Step 6: Create Loan Disbursement
-
API endpoint:
https://api.instamoney.co/p2p-loan-disbursements
-
Send a Create Loan Disbursement request to this endpoint to test creating a loan
-
You can test creating a loan that is funded by 1 lender, or 2 lenders, by changing the fields under
lenders
in the Create Loan Disbursement request -
When a Loan Disbursement is successfully created (but still in the process of sending out), you will receive a callback with status
DISBURSING
-
When a Loan Disbursement has been successfully created and disbursed out to the end borrower, you will receive a callback with status
COMPLETED
-
When a Loan Disbursement has been successfully created but the disbursement to the end borrower fails, you will receive a callback with status
FAILED
. Afailure_code
will be provided in the callback that explains the error (more details here: https://instamoney.github.io/dashboard-docs/errors.html) -
See below for a list of success/failure scenarios and how to test them in development mode
Scenario | Parameter Values |
---|---|
Successful loan disbursement | Any values other than stated in other scenarios below |
Successful SKN loan disbursement | amount: 51,000,000 |
Successful SKN loan disbursement which was later found to have been refunded | amount: 52,000,000 |
Bank account does not existLoan disbursement failed with failure INVALID_DESTINATION |
bank_code: MANDIRI account_holder_name: Rizky account_number: 7654321 |
Switching network is experiencing downtimeLoan disbursement failed with failure SWITCHING_NETWORK_ERROR |
bank_code: MANDIRI account_holder_name: Siti account_number: 12121212 |
Bank networks have rejected the transaction for an unknown reasonLoan disbursement failed with failure UNKNOWN_BANK_NETWORK_ERROR |
bank_code: MANDIRI account_holder_name: Andri account_number: 987654321 |
Bank is undergoing unscheduled maintenanceLoan disbursement failed with failure TEMPORARY_BANK_NETWORK_ERROR |
bank_code: MANDIRI account_holder_name: Yono account_number: 321321321 |
Transaction has been rejected by the destination bank without a clear error reasonLoan disbursement failed with failure REJECTED_BY_BANK |
bank_code: MANDIRI account_holder_name: Budi account_number: 8787878 |
Transaction was rejected because of a fatal errorLoan disbursement failed with failure TRANSFER_ERROR |
bank_code: MANDIRI account_holder_name: Adnin account_number: 1351357 |
Transaction failed because of a known temporary issueLoan disbursement failed with failure TEMPORARY_TRANSFER_ERROR |
bank_code: MANDIRI account_holder_name: Sutiono account_number: 868686 |
Description not found Will return API_VALIDATION_ERROR when creating loan disbursement |
Leave description empty |
Not enough balance Will return INSUFFICIENT_BALANCE when creating loan disbursement |
Try to create a loan disbursement greater than the balance available in your account |
Invalid API key Will return INVALID_API_KEY when creating loan disbursement |
Try using random API key |
Step 7: Create Fixed Virtual Accounts with type REPAYMENT for borrowers to pay into
-
API endpoint:
https://api.instamoney.co/p2p-escrow-virtual-accounts
-
Send a Create Fixed Virtual Account request to this endpoint to create a virtual account for your borrower to repay the loan
-
Set the
payment_type
torepayment
to identify this virtual account as a Repayment virtual account -
As this is a repayment Virtual Account, you’ll need to enter the
loan_id
of the Loan you created earlier to make payment for it -
Check your Callback URL. If you have sent a valid request, you should receive a Fixed Virtual Account Activated callback with the status
ACTIVE
-
If you enter a
loan_id
that does not exist, you will receive aINVALID_LOAN_ID
error
Step 8: Pay into the Fixed Virtual Account with type REPAYMENT
Example testing payment request
POST https://api.instamoney.co/p2p-escrow-virtual-accounts/testing-payments
{
"external_id": "${external_id}",
"amount": "12000"
}
If you test in development mode, you can send testing payment request with JSON body
external_id
of the fixed VAamount
of the payment simulation
If you test in live mode, you can send real money to the VA number
Step 9: Create a Repayment to update the Lender and Borrower ledgers
-
API endpoint:
https://api.instamoney.co/p2p-repayments
-
Send a Create Repayment request to this endpoint
-
A successful Create Repayment request will return a response stating the updated ledger balances of the borrower and lender(s)
Step 10: Create a Withdrawal
-
API endpoint:
https://api.instamoney.co/p2p-withdrawals
-
Send a Create Withdrawal request to this endpoint to test creating a Withdrawal
-
When a Withdrawal is successfully created (but still in the process of sending out), you will receive a callback with status
DISBURSING
-
When a Withdrawal has been successfully created and disbursed to the end user (lender / borrower / your operational account for fees), you will receive a callback with status
COMPLETED
-
When a Withdrawal has been successfully created but the disbursement to the end user fails, you will receive a callback with status “FAILED”). A
failure_code
will be provided in the callback that explains the error (more details here: https://instamoney.github.io/dashboard-docs/errors.html) -
See below for a list of success/failure scenarios and how to test them in development mode
Scenario | Parameter Values |
---|---|
Successful withdrawal | Any values other than stated in other scenarios below |
Successful SKN withdrawal | amount: 51,000,000 |
Successful SKN withdrawal which was later found to have been refunded | amount: 52,000,000 |
Bank account does not existWithdrawal failed with failure INVALID_DESTINATION |
bank_code: MANDIRI account_holder_name: Rizky account_number: 7654321 |
Switching network is experiencing downtimeWithdrawal failed with failure SWITCHING_NETWORK_ERROR |
bank_code: MANDIRI account_holder_name: Siti account_number: 12121212 |
Bank networks have rejected the transaction for an unknown reasonWithdrawal failed with failure UNKNOWN_BANK_NETWORK_ERROR |
bank_code: MANDIRI account_holder_name: Andri account_number: 987654321 |
Bank is undergoing unscheduled maintenanceWithdrawal failed with failure TEMPORARY_BANK_NETWORK_ERROR |
bank_code: MANDIRI account_holder_name: Yono account_number: 321321321 |
Transaction has been rejected by the destination bank without a clear error reasonWithdrawal failed with failure REJECTED_BY_BANK |
bank_code: MANDIRI account_holder_name: Budi account_number: 8787878 |
Transaction was rejected because of a fatal errorWithdrawal failed with failure TRANSFER_ERROR |
bank_code: MANDIRI account_holder_name: Adnin account_number: 1351357 |
Transaction failed because of a known temporary issueWithdrawal failed with failure TEMPORARY_TRANSFER_ERROR |
bank_code: MANDIRI account_holder_name: Sutiono account_number: 868686 |
Description not found Will return API_VALIDATION_ERROR when creating withdrawal |
Leave description empty |
Not enough balance Will return INSUFFICIENT_BALANCE when creating withdrawal |
Try to create a withdrawal greater than the balance available in your account |
Invalid API key Will return INVALID_API_KEY when creating withdrawal |
Try using random API key |
Step 11: Create an Internal Transfer to transfer balance between customer objects
-
API endpoint:
https://api.instamoney.co/p2p-internal-transfers
-
Send a Create Internal Transfer request to this endpoint
-
A successful Create Internal Transfer request will return a response with status
COMPLETED
More Sample Flows for Testing
-
Success flow 1: 1 lender → pays into Loan Virtual Account → Loan Disbursement is COMPLETED → Borrower pays into Repayment Virtual Account → create Repayment (involving 1 lender) → lender withdraws money into bank account
-
Success flow 2: 2 lenders → pays into Loan Virtual Account → Loan disbursement is COMPLETED → Borrower pays into Repayment Virtual Account → create Repayment (involving 2 lenders) → both lenders withdraw money into bank account
-
Loan Disbursement failed: 1 lender → pays into Loan Virtual Account → Loan Disbursement is FAILED → lender’s balance stays the same → lender withdraws money into bank account
-
Reinvestment: 1 lender → pays into Loan Virtual account → Loan Disbursement is COMPLETED → Borrower pays into Repayment Virtual Account → create Repayment (involving 1 lender) → create Loan Disbursement with different “loan_id”