Idempotent Request Implementation Guide


The current API version is equipped with idempotency support on both request and object level. This allows merchant to safely retry requests without accidentally performing the same operation twice. It should be used when creating, updating an object, or triggering transaction. In case of network or system issue, merchants can repeat the request without risk of performing the update twice and creating identical second object.

What is idempotency key on request level (X-Idempotency-Key)?

X-Idempotency-Key is a unique token that is submitted alongside each API request made to Durianpay and will be assigned as identifier of that request. This key should be attached on the header of each API request.

Why implementing X-Idempotency-Key on request level is mandatory?

To avoid accidental request to perform same operation twice in case of network or system issue.

This is especially important for disbursement transaction as it may incur double transaction for merchant if merchant is retrying transaction without proper idempotency-key.

For example, if disbursement creation fails due to network issue, ideally merchant will retry the disbursement. Unique X-Idempotency-Key will ensure that only one transaction is created upon retry.

We are making this optional (backward compatible) until July 31, 2023 for existing merchants who integrate via API. By August 1, 2023, `X-Idempotency-Key` will be mandatory. Once it becomes mandatory, for all API enabled with `X-Idempotency-Key`, the requests without the header will retrieve error message.

For now, X-Idempotency-Key has only been implemented to top up and disbursement APIs.

How to implement X-Idempotency-Key?

  1. When creating new transaction

Provide X-Idempotency-Key on the header of each of your request. We recommend merchants to use UUID format. Remember, the idempotency key should be unique and hasn't been used for successful transaction before.

  1. When retrying transaction request that receives error response

Please retry request using the same X-Idempotency-Key. Else, it will be counted as a different request. For further explanation on the cases please review the next questions.

What is the difference between X-Idempotency-Key (request level) and idempotency_key (batch level)?

Both have the same purpose, to prevent accidentally processing unintended identical disbursement transaction.

However, they have different purposes and implementation.

a. X-Idempotency-Key is assigned to each request made to different API even if the requests are related to the same object

b. idempotency_key is assigned to the disbursement batch itself where merchants can align it with internal reference IDs created from merchant's side and is only implemented to submit disbursement API.

Request Flow

Below are the possible responses of using combination of X-Idempotency-Key and idempotency_key when sending request:

a. Original request has been successfully processed and received final status (failed/success) from submit disbursement API. Hitting the API with different X-Idempotency-Key but same idempotency_key will result in 403.

Same idempotency key flow

b. Original request has been successfully processed and received final status (failed/success) from submit disbursement API. Hitting the API with the same X-Idempotency-Key but different idempotency_key will return response that was sent to original request.

Request has been processed flow

How does the X-Idempotency-Key work on various scenario?

In short, when a transaction request is successfully processed, X-Idempotency-Key will be stored in relation to the related transaction request. If the transaction request is failed to be processed, the X-Idempotency-Key will not be stored and you can use the same X-Idempotency-Key to retry the request.

Below are the list of cases when merchant submit request with the same X-Idempotency-Key as previous request (we will use the term 'original request' here):

NoOriginal RequestResponse
1Still in processing stateStill in processing state 409, message - request in processing
2Done and have received final status (failed/success, etc)Durianpay will send the response that was returned to merchant's original request
3Failed to process original request (this is not the same as final status = 'failed', if request has received final status then it will be considered as Case number 2)New request with the same X-Idempotency-Key will be processed, message - request failed, safe to retry