Integration: Bank Transfer

Basic integration process for Bank Transfer (Virtual Account) is explained in this section.
Your customers can make payments using the Bank Transfer payment method provided by Midtrans. You will be notified when customer completes the transaction using this option. A list of VA acquiring banks supported by Midtrans is given below.

  • BCA Virtual Account
  • BNI Virtual Account
  • BRI Virtual Account
  • Mandiri Bill Payment
  • Permata Virtual Account
  • CIMB Virtual Account

VA can be paid from any banks (support inter-bank transfer) for BNI, BRI, Permata and CIMB, as long as the transferred fund is received in time.

📘

Note

Please make sure to create your Midtrans account, before proceeding with this section.


Sequence Diagram

The overall Bank Transfer end-to-end payment process is illustrated in following sequence diagram.



Sandbox Environment


The steps given below use Midtrans Sandbox environment to test the integration process. Please make sure that you use the Server Key and Client Key for the Sandbox environment. For more details, refer to Retrieving API Access Keys.



Steps for Integration


To integrate with *Bank Transfer* payment method, follow the steps given below.

1. Sending Transaction Data to API Charge


Charge API request should be performed from your backend. The request is authenticated with API server key, which can be accessed through the account. After the request is sent, you will get the `va_number`.

The table given below describes the various elements required for sending the transaction data to the Charge API.

RequirementDescription
Server KeyThe server key. For more details, refer to Retrieving API Access Keys.
order_idThe order_id of the transaction.
gross_amountThe total amount of transaction.
payment_typeThe payment method.

Request Details


HTTP Headers

Accept: application/json
Content-Type: application/json
Authorization: Basic AUTH_STRING

AUTH_STRING: Base64Encode("YourServerKey"+":")

📘

Midtrans API validates HTTP request by using Basic Authentication method. The username is your Server Key while the password is empty. The authorization header value is represented by AUTH_STRING. AUTH_STRING is base-64 encoded string of your username and password separated by colon symbol (:). For more details, refer to API Authorization and Headers.


Sample Request and Request Body

The sample request for Charge API is given below. The request is in CURL but you can implement it according to your backend language. For more details, refer to available Language Libraries. The example below shows a sample code to obtain the VA number.

curl -X POST \
  https://api.sandbox.midtrans.com/v2/charge \
  -H 'Accept: application/json' \
  -H 'Authorization: Basic <YOUR SERVER KEY ENCODED in Base64>' \
  -H 'Content-Type: application/json' \
  -d '{
  "payment_type": "bank_transfer",
  "transaction_details": {
      "order_id": "order-101",
      "gross_amount": 44000
  },
  "bank_transfer":{
      "bank": "bca"
  }
}'
curl -X POST \
  https://api.sandbox.midtrans.com/v2/charge \
  -H 'Accept: application/json' \
  -H 'Authorization: Basic <YOUR SERVER KEY ENCODED in Base64>' \
  -H 'Content-Type: application/json' \
  -d '{
  "payment_type": "bank_transfer",
  "transaction_details": {
      "order_id": "order-101",
      "gross_amount": 44000
  },
  "bank_transfer":{
      "bank": "bni"
  }
}'
curl -X POST \
  https://api.sandbox.midtrans.com/v2/charge \
  -H 'Accept: application/json' \
  -H 'Authorization: Basic <YOUR SERVER KEY ENCODED in Base64>' \
  -H 'Content-Type: application/json' \
  -d '{
  "payment_type": "bank_transfer",
  "transaction_details": {
      "order_id": "order-101",
      "gross_amount": 44000
  },
  "bank_transfer":{
      "bank": "bri"
  }
}'
curl -X POST \
  https://api.sandbox.midtrans.com/v2/charge \
  -H 'Accept: application/json' \
  -H 'Authorization: Basic <YOUR SERVER KEY ENCODED in Base64>' \
  -H 'Content-Type: application/json' \
  -d '{
  "payment_type": "echannel",
  "transaction_details": {
      "order_id": "order-101",
      "gross_amount": 44000
  },
  "echannel" : {
      "bill_info1" : "Payment:",
      "bill_info2" : "Online purchase"
  }
}'
curl -X POST \
  https://api.sandbox.midtrans.com/v2/charge \
  -H 'Accept: application/json' \
  -H 'Authorization: Basic <YOUR SERVER KEY ENCODED in Base64>' \
  -H 'Content-Type: application/json' \
  -d '{
  "payment_type": "permata",
  "transaction_details": {
      "order_id": "order-101",
      "gross_amount": 44000
  }
}'
curl -X POST \
  https://api.sandbox.midtrans.com/v2/charge \
  -H 'Accept: application/json' \
  -H 'Authorization: Basic <YOUR SERVER KEY ENCODED in Base64>' \
  -H 'Content-Type: application/json' \
  -d '{
  "payment_type": "bank_transfer",
  "transaction_details": {
      "order_id": "order-101",
      "gross_amount": 44000
  },
  "bank_transfer":{
      "bank": "cimb"
  }
}'
Post Body JSON Attribute Description for BCA, BNI, BRI, CIMB
ElementDescriptionTypeRequired
payment_typeThe Bank Transfer payment method.StringRequired
transaction_detailsThe details of the transaction like the order_id and gross_amount.-Required
order_idThe order ID of the transaction.StringRequired
gross_amountThe total amount of transaction, defined from your side.StringRequired
bank_transferThe bank transfer details such as name of the bank.-Required
bankThe name of the acquiring bank which process the transaction.StringRequired
Post Body JSON Attribute Description for Mandiri Bill
ElementDescriptionTypeRequired
payment_typeThe E-channel payment method.StringRequired
transaction_detailsThe details of the transaction like the order_id and gross_amount.-Required
order_idThe order ID of the transaction.StringRequired
gross_amountThe total amount of transaction, defined from your side.StringRequired
echannelCharge details using Mandiri Bill Payment.ObjectRequired
bill_info1Label 1. Mandiri allows only 10 characters. Exceeding characters will be truncated.StringRequired
bill_info2Value for Label 1. Mandiri allows only 30 characters. Exceeding characters will be truncated.StringRequired

You can customize with your own message to the customer on the bill_info params. It will usually shown when customer attempt to pay via ATM or MBanking app, during confirmation of transfer. For example you can show something like Payment: Purchase at myonlinestore.com, or Deposit: John Doe at myinvestment.com

Post Body JSON Attribute Description for Permata
ElementDescriptionTypeRequired
payment_typeThe Bank Transfer payment method.StringRequired
transaction_detailsThe details of the transaction like the order_id and gross_amount.-Required
order_idThe order ID of the transaction.StringRequired
gross_amountThe total amount of transaction, defined from your side.StringRequired

📘

Tips

You can include more information such as customer_details, item_details, and so on. It is recommended to send more details regarding the transaction, so that these details will be captured on the transaction record. Which can be viewed on the Midtrans Dashboard.

You can also customize the output virtual account number for the transaction. For more details, please refer to Specifying VA Number.

Learn more on why this API request should be securely managed from your backend.


Sample Response and Response Body

The sample response and description of response body for Bank Transfer payment method is shown below.

{
    "status_code": "201",
    "status_message": "Success, Bank Transfer transaction is created",
    "transaction_id": "be03df7d-2f97-4c8c-a53c-8959f1b67295",
    "order_id": "1571823229",
    "merchant_id": "G812785002",
    "gross_amount": "44000.00",
    "currency": "IDR",
    "payment_type": "bank_transfer",
    "transaction_time": "2019-10-23 16:33:49",
    "transaction_status": "pending",
    "va_numbers": [
        {
            "bank": "bca",
            "va_number": "812785002530231"
        }
    ],
    "fraud_status": "accept"
}
{
    "status_code": "201",
    "status_message": "Success, Bank Transfer transaction is created",
    "transaction_id": "2194a77c-a412-4fd8-8ec8-121ff64fbfee",
    "order_id": "1571823369",
    "merchant_id": "G812785002",
    "gross_amount": "44000.00",
    "currency": "IDR",
    "payment_type": "bank_transfer",
    "transaction_time": "2019-10-23 16:36:08",
    "transaction_status": "pending",
    "va_numbers": [
        {
            "bank": "bni",
            "va_number": "9888500212345678"
        }
    ],
    "fraud_status": "accept"
}
{
    "status_code": "201",
    "status_message": "Success, Bank Transfer transaction is created",
    "transaction_id": "9aed5972-5b6a-401e-894b-a32c91ed1a3a",
    "order_id": "1466323342",
    "gross_amount": "20000.00",
    "payment_type": "bank_transfer",
    "transaction_time": "2016-06-19 15:02:22",
    "transaction_status": "pending",
    "va_numbers": [
      {
        "bank": "bri",
        "va_number": "8578000000111111"
      }
    ],
    "fraud_status": "accept",
    "currency": "IDR"
}
{
    "status_code": "201",
    "status_message": "OK, Mandiri Bill transaction is successful",
    "transaction_id": "abb2d93f-dae3-4183-936d-4145423ad72f",
    "order_id": "1571823332",
    "merchant_id": "G812785002",
    "gross_amount": "44000.00",
    "currency": "IDR",
    "payment_type": "echannel",
    "transaction_time": "2019-10-23 16:35:31",
    "transaction_status": "pending",
    "fraud_status": "accept",
    "bill_key": "778347787706",
    "biller_code": "70012"
}
{
    "status_code": "201",
    "status_message": "Success, PERMATA VA transaction is successful",
    "transaction_id": "035ca76c-b814-4264-9e63-68142351df83",
    "order_id": "1571823410",
    "gross_amount": "44000.00",
    "currency": "IDR",
    "payment_type": "bank_transfer",
    "transaction_time": "2019-10-23 16:36:49",
    "transaction_status": "pending",
    "fraud_status": "accept",
    "permata_va_number": "850003072869607",
    "merchant_id": "G812785002"
}
{
    "status_code": "201",
    "status_message": "Success, Bank Transfer transaction is created",
    "transaction_id": "2194a77c-a412-4fd8-8ec8-121ff64fbfee",
    "order_id": "1571823369",
    "merchant_id": "G812785002",
    "gross_amount": "44000.00",
    "currency": "IDR",
    "payment_type": "bank_transfer",
    "transaction_time": "2022-10-23 16:36:08",
    "transaction_status": "pending",
    "va_numbers": [
        {
            "bank": "cimb",
            "va_number": "2810490150230740"
        }
    ],
    "expiry_time": "2023-06-29 15:15:58"
}
Response Body JSON Attribute Description for BCA
ElementDescriptionTypeNotes
status_codeThe status of the API call.StringFor more details, refer to Status Codes and Error.
status_messageThe message describing the status of the transaction.String-
transaction_idThe Transaction ID of the specific transaction.String-
order_idThe specific Order ID.String-
merchant_idYour merchant ID.String-
gross_amountThe total amount of transaction for the specific order.String-
currencyThe unit of currency used for the transaction.String-
payment_typeThe type of payment method used by the customer for the transaction.String-
transaction_timeThe date and time at which the transaction occurred.StringIt is in the format, YYYY-MM-DD HH:MM:SS.
Time zone: Western Indonesian Time (GMT+7).
transaction_statusThe status of the transaction.StringFor more details, refer to Transaction Status.
va_numberThe virtual account number consisting of bank name and account number.String-
bankThe name of the acquiring bank which process the transaction.String-
fraud_statusThe fraud status of the transaction.StringFor more details, refer to Fraud Status.
Response Body JSON Attribute Description for BNI
ElementDescriptionTypeNotes
status_codeThe status of the API call.StringFor more details, refer to Status Codes and Error.
status_messageThe message describing the status of the transaction.String-
transaction_idThe Transaction ID of the specific transaction.String-
order_idThe specific Order ID.String-
merchant_idYour merchant ID.String-
gross_amountThe total amount of transaction for the specific order.String-
currencyThe unit of currency used for the transaction.String-
payment_typeThe type of payment method used by the customer for the transaction.String-
transaction_timeThe date and time at which the transaction occurred.StringIt is in the format, YYYY-MM-DD HH:MM:SS.
Time zone: Western Indonesian Time (GMT+7).
transaction_statusThe status of the transaction.StringFor more details, refer to Transaction Status.
va_numberThe virtual account number consisting of bank name and account number.String-
bankThe name of the acquiring bank which process the transaction.String-
fraud_statusThe fraud status of the transaction.StringFor more details, refer to Fraud Status.
Response Body JSON Attribute Description for BRI
ElementDescriptionTypeNotes
status_codeThe status of the API call.StringFor more details, refer to Status Codes and Error.
status_messageThe message describing the status of the transaction.String-
transaction_idThe Transaction ID of the specific transaction.String-
order_idThe specific Order ID.String-
gross_amountThe total amount of transaction for the specific order.String-
payment_typeThe type of payment method used by the customer for the transaction.String-
transaction_timeThe date and time at which the transaction occurred.StringIt is in the format, YYYY-MM-DD HH:MM:SS.
Time zone: Western Indonesian Time (GMT+7).
transaction_statusThe status of the transaction.StringFor more details, refer to Transaction Status.
va_numberThe virtual account number consisting of bank name and account number.String-
bankThe name of the acquiring bank which process the transaction.String-
fraud_statusThe fraud status of the transaction.StringFor more details, refer to Fraud Status.
currencyThe unit of currency used for the transaction.String-
Response Body JSON Attribute Description for Mandiri Bill
ElementDescriptionTypeNotes
status_codeThe status of the API call.StringFor more details, refer to Status Codes and Error.
status_messageThe message describing the status of the transaction.String-
transaction_idThe Transaction ID of the specific transaction.String-
order_idThe specific Order ID.String-
merchant_idYour merchant ID.String-
gross_amountThe total amount of transaction for the specific order.String-
currencyThe unit of currency used for the transaction.String-
payment_typeThe type of payment method used by the customer for the transaction.String-
transaction_timeThe date and time at which the transaction occurred.StringIt is in the format, YYYY-MM-DD HH:MM:SS.
Time zone: Western Indonesian Time (GMT+7).
transaction_statusThe status of the transaction.StringFor more details, refer to Transaction Status.
fraud_statusThe fraud status of the transaction.StringFor more details, refer to Fraud Status.
bill_keyMidtrans company code.String-
biller_codeThe payment (bill) number.String-

📘

You will get the bill_key and bill_code attribute.

Response Body JSON Attribute Description for Permata
ElementDescriptionTypeNotes
status_codeThe status of the API call.StringFor more details, refer to Status Codes and Error.
status_messageThe message describing the status of the transaction.String-
transaction_idThe Transaction ID of the specific transaction.String-
order_idThe specific Order IDString-
gross_amountThe total amount of transaction for the specific orderString-
currencyThe unit of currency used for the transactionString-
payment_typeThe type of payment method used by the customer for the transactionString-
transaction_timeThe date and time at which the transaction occurredStringIt is in the format, YYYY-MM-DD HH:MM:SS.
Time zone: Western Indonesian Time (GMT+7).
transaction_statusThe status of the transactionStringFor more details, refer to Transaction Status.
fraud_statusThe fraud status of the transactionStringFor more details, refer to Fraud Status.
permata_va_numberThe virtual account number consisting of bank name and account numberString-
merchant_idYour merchant IDString-

📘

Note

You will get the permata_va_number attribute in place of va_number

Response Body JSON Attribute Description for CIMB
ElementDescriptionTypeNotes
status_codeThe status of the API call.StringFor more details, refer to Status Codes and Error.
status_messageThe message describing the status of the transaction.String-
transaction_idThe Transaction ID of the specific transaction.String-
order_idThe specific Order ID.String-
merchant_idYour merchant ID.String-
gross_amountThe total amount of transaction for the specific order.String-
currencyThe unit of currency used for the transaction.String-
payment_typeThe type of payment method used by the customer for the transaction.String-
transaction_timeThe date and time at which the transaction occurred.StringIt is in the format, YYYY-MM-DD HH:MM:SS.
Time zone: Western Indonesian Time (GMT+7).
transaction_statusThe status of the transaction.StringFor more details, refer to Transaction Status.
va_numberThe virtual account number consisting of bank name and account number.String-
bankThe name of the acquiring bank which process the transaction.String-
fraud_statusThe fraud status of the transaction.StringFor more details, refer to Fraud Status.
expiry_timeThe expiry time for the Virtual accountString-

2. Displaying Virtual Account Number and Expiry Time


To display the virtual account number, use the value of `va_number` retrieved from API response.

By default the expiry time for Bank Transfer / VA is 24 hours. Follow this instruction to customize the expiry time.

Creating Test Payment

Read here to simulate/test success payment on sandbox environment.


3. Handling Transaction Notification


When the transaction status changes, Midtrans notifies you at the *Redirect URL* and sends HTTP notification to the merchant backend. This ensures that you are updated of the transaction status securely.

HTTP POST request with JSON body will be sent to your server's Notification URL configured on dashboard.

Configuring Payment Notification URL

To configure the Payment Notification URL, follow the steps given below.

  1. Log in to your MAP account.
  2. On the Home page, go to Settings > Configuration. Configuration page is displayed.
  3. Enter Payment Notification URL.
  4. Click Update.
    A confirmation message is displayed.
    Core API

    The Payment Notification URL is configured.

See also : HTTP(S) Notification/Webhooks


Transaction Status Description

The description of transaction_status value for Bank Transfer payment method is given below.

Transaction StatusDescription
settlementTransaction is successfully paid, customer has completed the transaction.
pendingTransaction is created successfully but it is not completed by the customer.
expireTransaction is failed as the payment is not done by customer within the given time period.
cancelTransaction is cancelled by you.
denyTransaction is rejected by the bank.

For more detail on transaction_status & fraud_status, see here.



Specifying VA Number


Virtual Account number which is displayed to customer, contains two parts. for example, in `{91012}{12435678}` , the first part is the company-prefix-number and the second part is a unique-va-number. The second part can be customized. Following conditions need to be followed while customizing VA number :
  • Only digits are allowed.
  • Different banks have different specifications for their custom VA numbers. Please go through the documentation of the respective banks. Note: for Permata, only B2B VA type support custom VA numbers, so by default your sandbox account may not support Permata custom VA, please contact us if you wish to have this feature.
  • If the number provided is currently active for another order, then a different unique number will be used instead.
  • If the number provided is longer than required, then the unnecessary digits in the end will be trimmed.
  • If the number provided is shorter than required, then the number will be prefixed with zeros.

Midtrans creates a random VA number for transaction using Bank Transfer payment method. You can customize this VA Number, by addingbank_transfer parameters in the Charge API Request Body as shown below.

Please add bank_transfer parameter during Charge API Request.

...
  "bank_transfer":{
    "bank": "bca",
    "va_number": "12345678911",
    "bca": {
      "sub_company_code": "00000" //NOTE: Don't send this field unless BCA give you sub company code
    }
  }
...
...
  "bank_transfer":{
    "bank": "bni",
    "va_number": "12345678"
  }
...
...
  "bank_transfer":{
    "bank": "bri",
    "va_number": "12345678"
  }
...
...
  "echannel" : {
    "bill_info1" : "Payment:",
    "bill_info2" : "Online purchase",
    "bill_key" : "081211111111"
}
...
...
  "bank_transfer":{
    "bank": "permata",
    "va_number": "1234567890"
  }
...
...
  "bank_transfer":{
    "bank": "cimb",
    "va_number": "12345678"
  }
...

VA Number Specification

ParameterTypeRequiredDescription
BCA va_numberStringOptionalLength should be within 1 to 11.
BCA sub_company_codeStringOptionalBCA sub company code directed for this transactions.
NOTE: Don't send this field unless BCA give you sub company code.
Permata va_numberStringOptionalLength should be 10. Only supported for b2b VA type.
BNI va_numberStringOptionalLength should be within 1 to 8.
BRI va_numberStringOptionalLength should be within 1 to 13.
Mandiri Bill bill_keyStringOptionalLength should be within 6 to 12.
CIMB va_numberStringOptionalLength should be within 1 to 12.

📘

Note

In Production environment, not every bank may support custom VA number (e.g. Permata), as the default state. It depends on the type of VA configured for your merchant account & your business agreement with the bank. Please consult Midtrans Activation team for further information.


Documentations