Direct Debit Transfer Integration

One of the payment method offered by Midtrans is Direct Debit. By using this payment method, customers will have the option to make a payment via bank website and Midtrans will send real time notification when the customer complete the payment.

At this moment, Midtrans has integrated with 4 different direct debit payment methods:

  1. BCA Klikpay
  2. CIMB Clicks
  3. Danamon Online
  4. e-Pay BRI
  5. Akulaku

Basic integration process of Direct Debit will be explained below.

Sandbox Environment

All the steps below are using Midtrans Sandbox environment, not Production, to easily test the integration process. Make sure you are switching to Sandbox mode on your Midtrans account dashboard while retrieving Server Key and Client Key. Explained in Getting Started - Preparation.

Server Key and Client Key can be retrieved on menu Settings > Access Keys.

Diagram

Overview of the transaction flow in sequence diagram:
direct debit transaction flow .

Integration Step

  1. Send transaction data to API Charge.
  2. Redirect customer to bank's website.
  3. Create landing page after customer complete the payment.
  4. Handle transaction notification.

1. Send Transaction Data to API Charge

Charge API request should be done from Merchant's backend. Server Key (from your account's Dashboard) will be needed to authenticate the request.

Charge API request

This is example of basic /charge API request in Curl, please implement according to your backend language (you can also check our available language libraries).

# sample charge in CURL
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": "bca_klikpay",
  "transaction_details": {
      "order_id": "order-101",
      "gross_amount": 44000
  }
  "bca_klikpay": {
      "description": "Pembelian Barang"
  }
}'
# sample charge in CURL
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": "cimb_clicks",
  "transaction_details": {
      "order_id": "order-101",
      "gross_amount": 44000
  },
  "cimb_clicks": {
      "description": "Purchase of a Food Delivery"
  }
}'
# sample charge in CURL
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": "danamon_online",
  "transaction_details": {
      "order_id": "order-101",
      "gross_amount": 44000
  }
}'
# sample charge in CURL
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": "bri_epay",
  "transaction_details": {
      "order_id": "order-101",
      "gross_amount": 44000
  }
}'
# sample charge in CURL
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": "akulaku",
  "transaction_details": {
      "order_id": "order-101",
      "gross_amount": 44000
  }
}'

Optional: you can customize transaction_details data. To include data like customer_details, item_details, etc. It's recommended to send as much detail so on report/dashboard those information will be included.

Charge API response

You will get the API response like the following.

{
    "status_code": "201",
    "status_message": "OK, BCA KlikPay transaction is successful",
    "transaction_id": "d19a4bcd-ae30-49dc-bde7-57749aede090",
    "order_id": "order-101",
    "redirect_url": "https://api.sandbox.veritrans.co.id/v3/bca/klikpay/redirect/d19a4bcd-ae30-49dc-bde7-57749aede090",
    "merchant_id": "G812785002",
    "gross_amount": "44000.00",
    "currency": "IDR",
    "payment_type": "bca_klikpay",
    "transaction_time": "2019-12-12 11:03:55",
    "transaction_status": "pending",
    "fraud_status": "accept",
    "redirect_data": {
        "url": "https://simulator.sandbox.midtrans.com/bca/klikpay/index",
        "method": "post",
        "params": {
            "klikPayCode": "03KHAN816197673",
            "transactionNo": "92396",
            "totalAmount": "44000",
            "currency": "IDR",
            "payType": "01",
            "callback": "https://example.com?id=d19a4bcd-ae30-49dc-bde7-57749aede090",
            "transactionDate": "11/11/2019 11:03:55",
            "descp": "Pembelian Barang",
            "miscFee": "0.00",
            "signature": "239297204"
        }
    }
}
{
    "status_code": "201",
    "status_message": "Success, CIMB Clicks transaction is successful",
    "redirect_url": "https://api.sandbox.veritrans.co.id/cimb-clicks/request?id=2e8f8ddd-c61a-4d5f-83ad-429432383057",
    "transaction_id": "2e8f8ddd-c61a-4d5f-83ad-429432383057",
    "order_id": "order-101i-1576124787",
    "gross_amount": "44000.00",
    "currency": "IDR",
    "payment_type": "cimb_clicks",
    "transaction_time": "2019-11-11 11:26:27",
    "transaction_status": "pending",
    "merchant_id": "G812785002"
}
{
    "status_code": "201",
    "status_message": "Success, Danamon Online transaction is successful",
    "transaction_id": "9da1c095-81b2-40d3-8285-8d27c60ae56e",
    "order_id": "order-101p-1576124871",
    "redirect_url": "https://api.sandbox.veritrans.co.id/v2/danamon/online/redirect/9da1c095-81b2-40d3-8285-8d27c60ae56e",
    "merchant_id": "G812785002",
    "gross_amount": "44000.00",
    "currency": "IDR",
    "payment_type": "danamon_online",
    "transaction_time": "2019-11-11 11:27:50",
    "transaction_status": "pending",
    "fraud_status": "accept"
}
{
    "status_code": "201",
    "status_message": "Success, BRI E-Pay transaction is successful",
    "transaction_id": "01c03b08-5e77-40d3-b1df-972f20a92e09",
    "order_id": "order-101",
    "redirect_url": "https://api.sandbox.veritrans.co.id/v3/bri/epay/redirect/01c03b08-5e77-40d3-b1df-972f20a92e09",
    "merchant_id": "G812785002",
    "gross_amount": "44000.00",
    "currency": "IDR",
    "payment_type": "bri_epay",
    "transaction_time": "2019-11-11 15:09:35",
    "transaction_status": "pending",
    "fraud_status": "accept"
}
{
    "status_code": "201",
    "status_message": "Success, Akulaku transaction is created",
    "transaction_id": "f80b0974-46d6-480c-9278-8b0d473857e1",
    "order_id": "order-101s",
    "redirect_url": "https://api.sandbox.midtrans.com/v2/akulaku/redirect/f80b0974-46d6-480c-9278-8b0d473857e1",
    "merchant_id": "G812785002",
    "gross_amount": "11000.00",
    "currency": "IDR",
    "payment_type": "akulaku",
    "transaction_time": "2019-11-11 12:19:54",
    "transaction_status": "pending",
    "fraud_status": "accept"
}

You will get the redirect_url attribute which can be performed this transaction.

2. Redirect Customer to Bank's Website

To redirect customer to Bank's Website, use redirect_url that retrieved from API response.

Then customer can be redirected via server-side redirect, using javascript like window.location=[REDIRECT URL], or using HTML link <a href="[REDIRECT URL]">Pay Here!</a>.


3. Create Landing Page After Customer Complete the Payment

After the customer completes the payment via bank's website, the bank website automatically redirect customer to Finish Redirect URL which can be configured on MAP (Merchant Administration Portal). You must login to MAP. Go to setting -> configuration, and fill in the Finish Redirect URL with your landing page endpoint.

MAP settings

On the Finish Redirect URL script, we need to obtain the response sent to the finish url script. Please make sure the Finish Redirect URL endpoint can receive POST. The sample code below are written in native php. Please adjust to your own environment.

<?php
$raw_response = $_POST['response']; //get the json response
$response = preg_replace('/\\\\/', '', $_POST['raw_response']); //clean up response from backslash
$decoded_response = json_decode($response);
$order_id = $decoded_response->order_id;//how to access
?>

Raw response are formatted in JSON, however, in some rare case, sometime there are backslash () before the quotation mark (“). Below are the sample of the raw dirty response.

{
    \"status_code\" : \"200\",
    \"status_message\" : \"Success, transaction is found\",
    \"transaction_id\" : \"58b48d1c-3e51-46f8-a2fb-ad5fa668f534\",
    \"order_id\" : \"34\",
    \"gross_amount\" : \"19999998.00\",
    \"payment_type\" : \"cimb_clicks\",
    \"transaction_time\" : \"2018-01-26 08:57:45\",
    \"transaction_status\" : \"settlement\",
    \"approval_code\" : \"1516957074590\",
    \"signature_key\" : \"30b048ffff95e08c34cf265268224f0b6460d7716b3d70424a7203609a78b335280fe6137a9938cd3af24533fdafcfe8771203f6f30f21fd141a378bba1685fb\"
}

After the response being clean we got this result.

{
    "status_code" : "200",
    "status_message" : "Success, transaction is found",
    "transaction_id" : "58b48d1c-3e51-46f8-a2fb-ad5fa668f534",
    "order_id" : "34",
    "gross_amount" : "19999998.00",
    "payment_type" : "cimb_clicks",
    "transaction_time" : "2018-01-26 08:57:45",
    "transaction_status" : "settlement",
    "approval_code" : "1516957074590",
    "signature_key" : "30b048ffff95e08c34cf265268224f0b6460d7716b3d70424a7203609a78b335280fe6137a9938cd3af24533fdafcfe8771203f6f30f21fd141a378bba1685fb"
}

Below are the sample of decoded_response:

(
   [status_code] => 200
   [status_message] => Success, transaction is found
   [transaction_id] => 58b48d1c-3e51-46f8-a2fb-ad5fa668f534
   [order_id] => 34
   [gross_amount] => 19999998.00
   [payment_type] => cimb_clicks
   [transaction_time] => 2018-01-26 08:57:45
   [transaction_status] => settlement
   [approval_code] => 1516957074590
   [signature_key] => 30b048ffff95e08c34cf265268224f0b6460d7716b3d70424a7203609a78b335280fe6137a9938cd3af24533fdafcfe8771203f6f30f21fd141a378bba1685fb
)

And now, we can use this response for showing message to our customer.


3. Handle HTTP Notification

HTTP notification from Midtrans to Merchant backend will also be triggered on event of transaction_status getting updated, to ensure merchant is securely informed. Including if transaction success or expired (not paid). So apart of JSON result above, Merchant backend will be notified by Midtrans.

HTTP POST request with JSON body will be sent to Merchant's notification url configured on dashboard (Settings > Configuration > Notification URL), this is the sample JSON body that will be received by Merchant:

{
  "transaction_time": "2019-12-11 16:20:48",
  "transaction_status": "settlement",
  "transaction_id": "34be81bd-1e4f-46b6-80f0-3e0f29776c63",
  "status_message": "midtrans payment notification",
  "status_code": "200",
  "signature_key": "f75192079b47bb2a55d8307d443388f418d139bd13b447b2521fd9fe7b33ffddf9435afaa212f4ef67452fb2f2f109c1852ddd7567bb2d74cefeb2f5aa995de6",
  "settlement_time": "2019-12-11 16:21:38",
  "payment_type": "bca_klikpay",
  "order_id": "order-101",
  "merchant_id": "G812785002",
  "gross_amount": "44000.00",
  "fraud_status": "accept",
  "currency": "IDR",
  "approval_code": "112233"
}
{
  "transaction_time": "2019-12-11 16:23:18",
  "transaction_status": "settlement",
  "transaction_id": "89cb0bfd-675b-4d4a-942c-7e19ba66d442",
  "status_message": "midtrans payment notification",
  "status_code": "200",
  "signature_key": "65e02e423cca2618a8d9ec201768438684bbf7218b27ab6f05a2197ce5b3c44fc9f4a157dce5a42d49f3ed6b88ac7a163f7e6b532d876d57a4a9297c5802639c",
  "settlement_time": "2019-12-11 16:24:00",
  "payment_type": "cimb_clicks",
  "order_id": "order-101",
  "merchant_id": "G812785002",
  "gross_amount": "44000.00",
  "currency": "IDR",
  "approval_code": "1576142640542"
}
{
  "transaction_time": "2019-12-11 16:25:34",
  "transaction_status": "settlement",
  "transaction_id": "e7eb187b-c54c-4960-8558-a995253d61ca",
  "status_message": "midtrans payment notification",
  "status_code": "200",
  "signature_key": "928775783adf67b0578340dc616a30d2c2b307350475fbfbcc5bc1a5ac94892bb6bb972b7fe2394509c32fd431fd3494a358f25e24456f7414b473989ab1e66f",
  "settlement_time": "2019-12-11 16:25:49",
  "payment_type": "danamon_online",
  "order_id": "order-101p-1576142735",
  "merchant_id": "G812785002",
  "gross_amount": "44000.00",
  "fraud_status": "accept",
  "currency": "IDR",
  "approval_code": "uRaSu1XAnIm56i"
}
{
  "transaction_time": "2019-11-11 15:09:35",
  "transaction_status": "settlement",
  "transaction_id": "01c03b08-5e77-40d3-b1df-972f20a92e09",
  "status_message": "midtrans payment notification",
  "status_code": "200",
  "signature_key": "f0abe6507f42019839e028f9c5da723ff7c220c962af1f1f8fc25ac5a773c1123fd680602443e7cece83d059b9f9c13078d74cc4a79948214059394ec5d18c4b",
  "settlement_time": "2019-11-11 15:13:51",
  "payment_type": "bri_epay",
  "order_id": "order-101h-1576483775",
  "merchant_id": "G812785002",
  "gross_amount": "44000.00",
  "fraud_status": "accept",
  "currency": "IDR",
  "approval_code": "1576483775235"
}
{
  "transaction_time": "2019-11-11 12:30:35",
  "transaction_status": "settlement",
  "transaction_id": "be30d5f1-3dfa-42a0-bc23-4d48207e71f0",
  "status_message": "midtrans payment notification",
  "status_code": "200",
  "signature_key": "1ab3eb28bc4833d193871ad911a0d96d45cc0d68cdfe30c6d5a61728593aa7129b6500090b95da1606956767473806102066d090eda72e4b2ee3f082df3ba731",
  "settlement_time": "2019-12-13 12:30:48",
  "payment_type": "akulaku",
  "order_id": "order-101",
  "merchant_id": "G812785002",
  "gross_amount": "11000.00",
  "fraud_status": "accept",
  "currency": "IDR"
}

Refer here on more details of how to handle HTTP Notification.

Switching To Production

To use Midtrans production environment (accept real payment from real customer), please make sure to:

  1. Switch the API domain URL from api.sandbox.midtrans.com to api.midtrans.com
  2. Switch the Client Key and Server Key from sandbox Dashboard, with keys from production Dashboard.

Done

The Direct Debit payment integration guide is now complete. Below are some further references.

Description

transaction_status value description for direct debit transaction:

Transaction Status Description
settlement Transaction successful, customer has been completed the transaction.
pending The transaction has successfully created but has not been completed by the customer.
expire Transaction failure because customer did not complete the payment within allowed time.
cancel Transaction is canceled by trigger from Merchant.
deny The bank rejected the transaction.


Link: More detailed definition of transaction_status

For more detail: Complete Core API documentation