Integration Steps


Steps Overview

Step1: Submit a Disbursement batch:

Submit a disbursement batch or basically create a disbursement batch. The disbursement needs to be submitted via submit disbursement API. There are two optional parameters that can alter the normal flow of disbursement:

  • force_disburse - Approval is automatic if we use this parameter. It will proceed to disburse once the items validation is completed. (force_disburse=true)
  • skip_validation - If this parameter is true then the bank validation will be skipped and batch items will be disbursed directly. skip_validation can be combined with force_disburse.(skip_validation=true)

(Note : How to use the above parameters is shown below in the code snippet)

Once user submits disbursement and validation is completed, Durianpay will send a disbursement.validation_completed webhook to the configured webhook url.

Use following endpoint to submit a disbursement:

/disbursements/submit
Request
curl -X POST \'https: //api.durianpay.id/v1/disbursements/submit?force_disburse=true&skip_validation=false'
-u '[Base64({Your_Server_Key}:)]' \
-H 'content-type: application/json' \
-H 'idempotency_key: <YOUR_IDEMPOTENCY_KEY>' \
-d '{
    "name": "sample disbursement",
    "description": "this is a sample disbursement",
    "items": [
        {
            "account_owner_name": "Jane Doe",
            "bank_code": "bca",
            "amount": "10000",
            "account_number": "8422647",
            "email_recipient": "jane_doe@nomail.com",
            "phone_number": "85722173217",
            "notes": "salary"
        },
        {
            "account_owner_name": "Jack",
            "bank_code": "bca",
            "amount": "10000",
            "account_number": "235464",
            "email_recipient": "jack@nomail.com",
            "phone_number": "85609873209",
            "notes": "salary"
        }
    ]
}'
Response
// Sample response
{
  {
    "data": {
        "id": "dis_LjxhDKq8Am3427",
        "name": "test disb",
        "total_amount": "20000.00",
        "total_disbursements": 2,
        "description": "description"
    }
}

Step 2: Approval of the submitted disbursement batch (Optional):

This step will help you to approve the disbursement.

If the force_disburse parameter is not used in step 1 then approve API needs to be called. Once you call the approve API the actual disbursement is triggered and money is disbursed to customer's account. Once all batch items are disbursed, durianpay will send disbursement.completed webhook.

/disbursements/:id/approve
Request
curl -u [Base64({Your_Server_Key}:)] \
-X POST https://api.durianpay.id/v1/disbursements/dis_XXXXX/approve \
-H "content-type: application/json" \
Response
{
    "data": {
        "id": "dis_XXXX",
        "name": "sample disbursement",
        "type": "batch",
        "status": "approved",
        "total_amount": "10000.00",
        "total_disbursements": 1,
        "description": "this is a sample disbursement"
    }
}

Step3: Webhooks / Store fields on your servers

Whenever certain event occurs on your Durianpay's Disbursement, we trigger webhooks which your application can listen to. A webhook is a URL on your server where we send payloads for such events. For example, if you implement webhooks, once a disbursement is successful, we will immediately notify your server with a disbursement.completed event.

You can specify your webhook URL on your dashboard (or through your dedicated Customer success manager) where we would send POST requests to whenever an event occurs. Here is a list of events we can send to your webhook URL.

Valid events

disbursement.validation.completed

This webhook is triggered after the disbursement is submitted and the validation is completed for all the items in the batch.

  • valid_disbursements: status: - > valid
    Destination account is valid, and transaction continue to be processed
  • invalid_disbursements: status: - > Invalid
    Destination account is invalid, and transaction is not processed further
disbursement.completed

This webhook is triggered when the disbursement is completed for all(valid) items in the batch disbursement.completed webhook is used to retrieve final status of the disbursement.

Status

  • success - All items in the batch is successfully completed
  • partially_success - Some items in the batch are success and some are not
  • failed - All items in batch is failed

Item Status

  • invalid - Transaction validation failed
  • done - Transaction is successfully done
  • failed - Transaction is failed to be processed by provider
account_validation.completed

This webhook is triggered after validation is completed for account details sent in the validate API request account_validation.completed webhook is used to retrieve validity of account destination and get the bank stated account holder name.

Status

  • valid - Account details are valid
  • invalid - Account details are invalid

account_holder

  • name shown according to the bank stated name

Note- please note that account_validation.completed is currently not available in sandbox, it's available only in live mode

disbursement.completed
{
  "event": "disbursement.completed",
  "data": {
    "created_at": "2021-06-22T15:20:20.840353Z",
    "currency": "IDR",
    "description": "test Apr13",
    "failed_item_amount": "200000.00",
    "failed_item_count": 2,
    "id": "dis_4hjykf9KK99186",
    "is_live": true,
    "item_status": [
      {
        "id": "dis_item_PVusz7D0jF2144",
        "status": "invalid"
      },
      {
        "id": "dis_item_0Hm7Clzh4j3788",
        "status": "invalid"
      },
      {
        "id": "dis_item_Cr8c1Rv3Kk7183",
        "status": "done"
      }
    ],
    "items_count": 3,
    "merchant_id": "mer_MsCtIPhqRc8045",
    "name": "test Apr13",
    "signature": "61a1af026de7fbed3eac0f35b5c5bb177ef35d9f1059d8ff07f98786d770adbf",
    "status": "partially_success",
    "success_item_amount": "100000.00",
    "success_item_count": 1,
    "total_amount": "300000.00",
    "type": "batch"
  },
  "retry_count": 0
}

Step4: Verify disbursement status (Optional)

You will get disbursement_id through webhook callback (if configured). You should ideally try to validate the disbursement and store the details in your server/database against the transaction accordingly.

First, you need to get verification signature from Durianpay which would have been provided to you in your webhook callback.

{  
  "event": "disbursement.completed",
  "data":{  
  "id": "dis_LjxhDKq8Am3427",
  "signature": "9e892f199d026d06a56669e658a56f264610431d24e8b4d07f7bd46f6d5062d2",    ...
}

If you didn't receive it for any reason, you can call disbursement status check API from your server/backend which will respond back with signature if status of disbursement is completed.

/disbursements/:id
"status": "completed",
"is_completed": true,
"signature": "9e892f199d026d06a56669e658a56f264610431d24e8b4d07f7bd46f6d5062d2"

This signature is computed by us using disbursement_id, amount and your secret key. You need to create the hash on your server/backend where you have all these elements and match with the signature provided by us.

Sample code for signature generation for submit disbursement

// Function to generate the signature for verification of disbursement
//use appropriate key if it is a sandbox order please use dp_test key and if it is a live order then use dp_live key
func GenerateSignature(disbursementID string, amount string, accessKey string) (generatedSignature string) {
  //message passed includes disbursement_id + “|” + amount. Amount is in “15000.00” format
  secretData := disbursementID + "|" + amount
  // Create a new HMAC by defining the hash type and the key (as byte array)
  h := hmac.New(sha256.New, []byte(accessKey))
  // Write Data to it
  h.Write([]byte(secretData))
  // Get result and encode as hexadecimal string
  generatedSignature = hex.EncodeToString(h.Sum(nil))
  return
}

Sample code for signature generation for account validation

// Function to generate the signature for verification of account validation completed webhook
func GenerateAccountValidationSignature(accountNumber string, bankCode string, status string, accessKey string) (generatedSignature string) {
    secretData := accountNumber + "|" + bankCode + "|" + status
    // Create a new HMAC by defining the hash type and the key (as byte array)
    h := hmac.New(sha256.New, []byte(accessKey))
    // Write Data to it
    h.Write([]byte(secretData))
    // Get result and encode as hexadecimal string
    generatedSignature = hex.EncodeToString(h.Sum(nil))
    return
}

Test Integration

Test disbursements

Sandbox Mode

To simulate the submit disbursement API flow in sandbox mode, merchants can use dp_test_XXXXXXXXX key. By default we will simulate the success scenario for the webhook response. If the account number entered is even then its valid else if the account number is odd it is not valid. You can set the webhook in sandbox mode to test the callback as well. https://durianpay.id/docs/integration/afterpayments/webhooks/

Verify Disbursement status

Through Dashboard

  1. Log into the Dashboard and navigate to Disbursements in sidebar.
  2. Check if a Disbursement_id has been generated. If no disbursement_id has been generated, it means that the transaction has failed (and didn't even initiate from user's end)
Durian Dashboard 1

Through APIs

/disbursements/:id
/disbursements/:id/items
Request
curl -u [Base64({Your_Server_Key}:)] \
-X GET https://api.durianpay.id/v1/disbursements/dis_XXXXXXX \
-H "content-type: application/json"'
Response
{
    "data": {
        "id": "dis_XXXXXXX",
        "name": "sample disbursement",
        "type": "batch",
        "status": "approved",
        "total_amount": "10000.00",
        "total_disbursements": 1,
        "description": "this is a sample description",
        "fees": 4000,
        "created_at": "2021-05-03T12:57:07.296575Z"
    }
}

Accept LIVE Disbursements

After testing the flow of funds end-to-end in sandbox mode, you can switch to the live mode and start disbursements . However, make sure that you swap the test API keys with the live keys.

  1. Log into Dashboard and switch to Live mode on the sidebar menu.
  2. Navigate to Settings → API Keys to access your API key for live mode.
  3. Replace the sandbox API key with the Live Key in the Disbursement and start sending real-time disbursements.