NAV Navbar
javascript json

Introduction

SNAP or Standar Nasional Open API is a regulation established by Bank Indonesia through the Governor of Bank Indonesia Decree No.23/10/KEP.GBI/2021 dated August 16 2021, concerning the establishment of Standar Nasional Open API (Application Programming Interface), managed by ASPI (Indonesian Payment System Association).

SNAP is a national protocol and instruction that facilitates interconnection between applications in the payment transaction process standard for payment gateway and it is determined by Bank Indonesia.

Currently, Duitku as one of the payment gateways is on the move to implement these standards. Here is the flow that has been prepared and adjusted for you.

SNAP API

Here is the host that used for API:

SNAP Registration at Duitku

To use the standarized API by SNAP, merchant need to obtain approval from ASPI in the form of a recommendation letter. To receive this letter, merchant must conduct developer site test and functionality test.

  1. Developer Site Test: This test is conducted on the ASPI page to ensure that the API complies with SNAP's technical and security standards. To conduct the developer site test, merchant must register on the registration page at ASPI. Merchant can perform the test by following the developer site test guideline on the ASPI website. The developer site test includes at least 1 positive test scenario and 1 negative scenario for each sub-API used.

  2. Functionality Test: Once the developer site test results meet the standards, merchant can proceed with the provided Functionality Test. The functionality test is conducted to test the SNAP API components that have been integrated with Duitku end-to-end.

Before starting SNAP integration, you need to register for SNAP at Duitku. Please send the public key, information, and required documents using the email registered with Duitku to [email protected].

You need to send 2 separate emails to Duitku. To facilitate the registration process, you must use the primary email registered with Duitku. Below are the information and documents you need to attach when sending these emails:

First Email:

  1. Project code sandbox
  2. API Services. The API services provided by Duitku:
    1. Virtual Account
    2. Direct Debit Redirect
    3. Direct Debit Linking
    4. QRIS-MPM
  3. Zip file containing Public Key in .pem format and protected by a password. For instructions on creating a public key, refer to the Public Key and Private Key guidelines.
  4. SNAP payment URL to receive payment notifications. This URL must follow the payment notification standard and match the required API services:
    1. Payment Virtual Account
    2. Payment Notify Direct Debit
    3. Payment Notify QRIS-MPM

You can use the email format here .

Second Email:

  1. Password to open the zip file containing the public key sent previously

API Authentication

The authentication in the SNAP API there is:

  1. Private Key and Public Key
  2. Bearer Token
  3. Signature

Public Key and Private Key

Create an RSA key pair for your access. Save the private key and keep it safe and secure. Then you need to send the public key to Duitku to give you access to request the API. Make sure you generate the key within 2048-bit.

Here is an example of how you can create an RSA public and private key:

  1. You could use Git OpenSSL.
  2. Git OpenSSL usually needs to run on its directory. Run the command below. (Windows Example)
    cd "..\..\Program Files\Git\usr\bin"
  3. Then, create the private key using these commands:
    openssl genrsa -out C:\Users\{your_users}\Desktop\PrivateKey.pem 2048
  4. After you create the private key you can create the public key using the private key with the commands below:
    openssl rsa -in C:\Users\{your_users}\Desktop\PrivateKey.pem -pubout -out C:\Users\{your_users}\Desktop\Publickey.pem

Now, you should have the RSA key pair. Next, you need to save and put the private key on your project and send the public key to Duitku. You might need the private key in your project so your project would have to keep the access.

Bearer Token

When you're working with web APIs, a Bearer Token is an access token that is often used for authorization purposes. This token acts like a security key that a server uses to verify that the request is coming from an authenticated user or service.

To use a Bearer Token with the SNAP API, you need to obtain the token by providing your credentials to the authentication endpoint.

Get Token API

To use this code example you might need to install npm axios and jsrsasign.
Install the package on your project using npm:

npm install axios jsrsasign jsrsasign-util

Copy the code below:
(select javascript tag to show the example code)

const axios = require("axios")
const rs = require('jsrsasign')
const rsu = require('jsrsasign-util')
const CryptoJS = require('crypto-js')
const partnerId = "DXXXX"
const date = new Date()
const headers = headersAuthGenerator(partnerId, date)
const body = {
    "grantType": "client_credentials"
}
axios.post("https://snapdev.duitku.com/auth/v1.0/access-token/b2b/", body, {headers: headers })
    .then(response => res.json(response.data))
    .catch(err => res.json(err.response.data))

//Function to create headers
function headersAuthGenerator(partnerId, date){
    let stringToSign = `${partnerId}|${toIsoString(date)}`

    //read your private key from your private key file
    let privateKey = rs.KEYUTIL.getKey(rsu.readFile("./mykey/privatekey.pem"))
    let sign = new rs.KJUR.crypto.Signature({"alg": "SHA256withRSA"});
    sign.init(privateKey)
    let hash = sign.signString(stringToSign)
    const signature = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(hash))
    let headers = {
        "X-TIMESTAMP": toIsoString(date),
        "X-SIGNATURE": signature,
        "X-CLIENT-KEY": partnerId
    }
    return headers
}

//function to iso string helper
function toIsoString(date) {
    var tzo = -date.getTimezoneOffset(),
        dif = tzo >= 0 ? '+' : '-',
        pad = function(num) {
            return (num < 10 ? '0' : '') + num;
        };

    return date.getFullYear() +
        '-' + pad(date.getMonth() + 1) +
        '-' + pad(date.getDate()) +
        'T' + pad(date.getHours()) +
        ':' + pad(date.getMinutes()) +
        ':' + pad(date.getSeconds()) +
        dif + pad(Math.floor(Math.abs(tzo) / 60)) +
        ':' + pad(Math.abs(tzo) % 60);
}

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/auth/v1.0/access-token/b2b

Production : https://snap.duitku.com/auth/v1.0/access-token/b2b

Service Code : 73

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Non-Repudiation & Integrity checking X-Signature with asymmetric algorithm.
Formula:
stringToSign = Client Key + “|” + Timestamp
signature = SHA256withRSA(Private_Key, stringToSign)
X-CLIENT-KEY string

Project Id provided by Duitku. DXXXX

Body :

{
    "grantType": "client_credentials"
}
Parameter Type Required Description Example
grantType string

The value is "client_credentials" "client_credentials"

Response :

{
    "responseCode": "2007300",
    "responseMessage": "Successful",
    "accessToken": "ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0",
    "tokenType": "Bearer",
    "expiresIn": "900"
}
Code Message Keterangan
2007300 Successful Successful processing and obtaining the accessToken.
4007301 Invalid Field Format {grantType} Incorrect value for the parameter grantType.
4007302 Invalid Mandatory Field {grantType} Missing parameter grantType.
4007302 Invalid Client Key or Timestamp or Signature Error occurred among Client Key, Timestamp, or Signature.
4017300 Invalid Client Key Error in the Client Key.
4017300 Invalid Signature Error in the Signature.

Signature

The Signature security mechanism for the Payment API offers two distinct approaches. Firstly, utilizing the symmetric HMAC_512 cryptographic function, where an access token is integral to the process. Alternatively, the asymmetric SHA256withRSA cryptographic function can be employed, functioning independently of an access token.

It is advisable for clients to adopt the symmetric HMAC_512 cryptographic function in conjunction with an access token when generating signatures for the Payment Method API. This method ensures a robust and secure approach.

Conversely, the Notify Payment API will exclusively leverage the asymmetric SHA256withRSA cryptographic function, ensuring a specific and tailored security measure implemented by Duitku.

It is crucial to note that these specifications align with the Payment API SNAP document provided by Bank Indonesia, which can be accessed here.

Duitku's SNAP API relies on the use of API keys for request authentication, a crucial aspect that warrants special attention due to its numerous security features. Ensuring the utmost security of these API keys is paramount.

In the transaction process involving Duitku's API, it is imperative for our partners to furnish the API Key as the designated credential, provided by Duitku. This key serves as the means of authenticating transactions through the bearer auth method, employing the header -H "Authorization: Bearer ". It is essential to note that all API requests must be made via HTTPS to guarantee a secure communication channel. Requests made through HTTP will not be successful.

Furthermore, any attempt to access the API without proper authentication will result in failure, emphasizing the significance of adhering to the authentication protocols in place.

Your cooperation in following these security measures is greatly appreciated, as it ensures a robust and secure environment for API transactions.

Symmetric

To use this code example you might need to install npm crypto-js.
Install the package on your project using npm:

npm i crypto-js

Copy the code below:
(select javascript tag to show the example code)

const CryptoJS = require('crypto-js')
function symetricGenerator(date, method, endpoint, body, accessToken, clientSecret){
    let minifyBody = JSON.stringify(body)
    let encBody = CryptoJS.SHA256(minifyBody).toString()
    let stringToSign = `${method}:${endpoint}:${accessToken}:${encBody.toLowerCase()}:${date}`
    let signature = CryptoJS.HmacSHA512(stringToSign, clientSecret).toString(CryptoJS.enc.Base64)
    console.log("minifyBody : ", minifyBody)
    console.log("encBody : ", encBody)
    console.log("stringToSign : ", stringToSign)
    return signature 
}

The formula:

stringToSign = HttpMethod + “:” + Endpoint + “:” + AccessToken + “:” + LowerCase(HexEncode(SHA-256(Minify(RequestBody)))) + “:” + Timestamp
hash = HMAC_SHA512(stringToSign, secretKey)
signature = Base64(hash)

Explanation:

Compose a variable stringToSign.

  1. HttpMethod is a string of a method name that is in use. They could be POST, PUT, or DELETE.
  2. The endpoint is a relative URL or full path of URL without host or domain.
  3. AccessToken is a token value that you get from API Get Token.
  4. RequestBody is a payload that you would like to send.
  5. Timestamp uses ISO-8601.
  6. secretKey is client secret or project API key.

Hash stringToSign using HMAC_SHA512 cryptographic and your secret key (the current other name is the API key). Then, encode with Base 64.

Put the value to X-SIGNATURE.





Asymmetric

Asymmetric for the get auth token API

To use this code example you might need to install npm crypto-js and jsrsasign.
Install the package on your project using npm:

npm i crypto-js jsrsasign jsrsasign-util

Copy the code below:
(select javascript tag to show the example code)

const rs = require('jsrsasign')
const rsu = require('jsrsasign-util')
const CryptoJS = require('crypto-js')
function asymmetricGetAuthHelper(partnerId, date){
    let stringToSign = `${partnerId}|${toIsoString(date)}`
    let privateKey = rs.KEYUTIL.getKey(rsu.readFile("./mykey/privatekey.pem")) //your private key
    let sign = new rs.KJUR.crypto.Signature({"alg": "SHA256withRSA"});
    sign.init(privateKey)
    let hash = sign.signString(stringToSign)
    const signature = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(hash))

    return signature 
}

The formula:

stringToSign = ClientKey + “|” + Timestamp
hash = SHA256withRSA(stringToSign,privateKey)
signature = Base64(hash)

Explanation:

Compose a variable stringToSign.

  1. ClientKey is a project ID.
  2. Timestamp uses ISO-8601.
  3. privateKey is a generated RSA key by you. See Public Key and Private Key to see how generate this.

Hash stringToSign using SHA256withRSA cryptographic and your secret key (the current other name is the API key). Then, encode with Base 64.

Put the value to X-SIGNATURE.









Asymmetric for payment or notification

To use this code example you might need to install npm crypto-js and jsrsasign.
Install the package on your project using npm:

npm i crypto-js jsrsasign jsrsasign-util

Copy the code below:
(select javascript tag to show the example code)

const rs = require('jsrsasign')
const rsu = require('jsrsasign-util')
const CryptoJS = require('crypto-js')

function paymentSignatureValidator(body, date, signature, url){
    let minifyBody = JSON.stringify(body)
    let encBody = CryptoJS.SHA256(minifyBody).toString()
    let stringToSign = `POST:${url}:${encBody.toLowerCase()}:${date}`
    let publicKey = rs.KEYUTIL.getKey(rsu.readFile("./duitkukey/duitku_publickey.pem"))
    let sign = new rs.KJUR.crypto.Signature({"alg": "SHA256withRSA"})
    sign.init(publicKey)
    sign.updateString(stringToSign)
    const isSignatureValid = sign.verify(CryptoJS.enc.Hex.stringify(CryptoJS.enc.Base64.parse(signature)))
    console.log("minifyBody", minifyBody)
    console.log("encBody", encBody)
    console.log("isSignatureValid", isSignatureValid)
    return isSignatureValid
}

The formula:

stringToSign = HttpMethod + “:” + Endpoint + “:” + LowerCase(HexEncode(SHA-256(Minify(RequestBody)))) + “:” + Timestamp
hash = SHA256withRSA(stringToSign, publicKey)
signature = Base64(hash)

Explanation:

Compose a variable stringToSign.

  1. HttpMethod is a string of a method name that is in use. They should be POST.
  2. The endpoint is a relative URL or full path of URL without host or domain.
  3. RequestBody is a payload that is being sent from Duitku.
  4. Timestamp uses ISO-8601.
  5. publicKey is a generated RSA key for you to validate that has been given by Duitku.

Hash stringToSign using SHA256withRSA cryptographic and your secret key (the current other name is the API key). Then, encode with Base 64.

Put the value to X-SIGNATURE.

Virtual Account

Interaction Between Virtual Account APIs

The lifecycle of a virtual account typically involves several stages, each handled by a different API. The interaction between these APIs ensures smooth management of virtual accounts.

Create Virtual Account

The process begins with the Create Virtual Account API, which is used for creating a new virtual account with a unique virtual account number (virtualAccountNo) and a transaction identifier (trxId).

Update Virtual Account

After creation, if there is a need to change details like the account name or amount, the Update Virtual Account API can be used. This API allows modifications to be made using the same virtualAccountNo and trxId provided during creation. Inquiry Virtual Account

At any point, to fetch current details of a virtual account, such as status, name, or amount, the Inquiry Virtual Account API is used. This keeps one informed about the state of a virtual account using its virtualAccountNo and associated trxId. Delete Virtual Account

Finally, when a virtual account is to be made unusable, the Delete Virtual Account API comes into play. It expires the virtual account to ensure it can no longer receive payments, leveraging the original virtualAccountNo and trxId for identification.

Each API interaction requires the virtualAccountNo and trxId to match the information initially provided, ensuring secure and accurate operations across the virtual account's lifecycle.

Create VA

Duitku SNAP API Create VA Sequence Diagram

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/va/v1.0/transfer-va/create-va

Production : https://snap.duitku.com/merchant/va/v1.0/transfer-va/create-va

Service Code : 27

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

Value should be DUITKU DUITKU
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Body :

{
    "partnerServiceId": "123456",
    "customerNo": "1234567890",
    "virtualAccountNo": "1234561234567890",
    "virtualAccountName": "John Doe",
    "trxId": "Transaction-0001",
    "totalAmount": {
        "value": "120000.00",
        "currency": "IDR"
    },
    "virtualAccountTrxType": "C",
    "expiredDate": "2022-10-18T23:27:43+0700",
    "additionalInfo": {
        "minAmount": "0.00",
        "maxAmount": "0.00"
    },
}
Parameter Type Required Description Example
partnerServiceId String(10)

Prefix from Duitku. 123456
customerNo String(20)

Number for VA. 1234567890
virtualAccountNo String(28)

PartnerServiceId + CustomerNo.
Recommendation:
For a maximum of 16 digits characters.
1234561234567890
virtualAccountName String(20)

The name will be displayed on the bank side. John Doe
trxId String(50)

Transaction ID. Unique in every create VA. Transaction-0001
ExpiredDate string

ISO-8601. 2022-09-16T13:00:00+07:00
virtualAccountTrxType String(1)

Close Amount : C
Open Amount : O
C
totalAmount Object

See the table below.
additionalInfo Object

See the table below.

totalAmount:

Parameter Type Required Description Example
value String

ISO4217
with 2 decimal
for Open Amount set “0.00”.
100000.00
currency String(3)

Currency code, only receive IDR. IDR

additionalInfo:

Parameter Type Required Description Example
minAmount String

ISO4217
Open Amount set it's equally with your minimun that has been informed by Duitku.
Close Amount set “0.00”.
10000.00
maxAmount String

ISO4217
Open Amount set it's equally with your maximum that has been informed by Duitku.
Close Amount set “0.00”.
10000.00

Response :

{
    "responseCode": "2002700",
    "responseMessage": "Successful",
    "virtualAccountData": {
        "partnerServiceId": "98886699",
        "customerNo": "20000001",
        "virtualAccountNo": "9888669920000001",
        "virtualAccountName": "SNAP VA",
        "trxId": "CHECK-002",
        "totalAmount": {
            "value": "120000.00",
            "currency": "IDR"
        },
        "expiredDate": "2022-10-18T23:27:43+0700",
        "additionalInfo": {
            "minAmount": "0.00",
            "maxAmount": "0.00"
        },
    }
}

As you can see in the JSON response example here, you should focus on the virtualAccountData variable. As for the responseCode and responseMessage, these indicate the status of your request process.

Code Message Description
2002700 Successful The process was successful, and data was obtained.
4002701 Invalid Field Format virtualAccountTrxType Incorrect value for the parameter virtualAccountTrxType.
4002701 Invalid Field Format duplicated TrxId Incorrect value for the parameter TrxId or it has already been used.
4002701 Invalid Field Format maxAmount should not be greater than 50000000 Incorrect value for the parameter maxAmount.
4002701 Invalid Field Format totalAmount should not be less than 10000 Incorrect value for the parameter totalAmount.
4002701 Invalid Field Format totalAmount should not be greater than 50000000 Incorrect value for the parameter totalAmount.
4002701 Invalid Field Format totalAmount.Currency Incorrect value for the parameter totalAmount in the Currency part
4002701 Invalid Field Format totalAmount.Value Incorrect value for the parameter totalAmount in the value part.
4002701 Invalid Field Format totalAmount Value must be greater than 0.00 for Close Amount and must be filled in 0.00 if Open Amount Incorrect value for the parameter totalAmount in the value part.
4002701 Invalid Field Format minAmount should not be less than 10000 Incorrect value for the parameter minAmount.
4002701 Invalid Field Format trxId Incorrect value for the parameter trxId.
4002701 Invalid Field Format virtualAccountNo Incorrect value for the parameter virtualAccountNo.
4002701 Invalid Field Format virtualAccountName Incorrect value for the parameter virtualAccountName.
4002701 Invalid Field Format partnerServiceId Incorrect value for the parameter partnerServiceId.
4002701 Invalid Field Format customerNo Incorrect value for the parameter customerNo.
4002701 Invalid Field Format param,totalAmount.value Incorrect format for the parameter totalAmount in the value part.
4002701 Invalid Field Format param,virtualAccountName Incorrect format for the parameter virtualAccountName.
4002701 Invalid Field Format param,customerNo Incorrect format for the parameter customerNo.
4002701 Invalid Field Format param,virtualAccountTrxType Incorrect format for the parameter virtualAccountTrxType.
4002701 Invalid Field Format param,virtualAccountNo Incorrect format for the parameter virtualAccountNo.
4002701 Invalid Field Format param,partnerServiceId Incorrect format for the parameter partnerServiceId.
4002701 Invalid Field Format param,trxId Incorrect format for the parameter trxId.
4002701 Invalid Field Format param,expiredDate Incorrect format for the parameter expiredDate.
4002702 Invalid Mandatory Field virtualAccountTrxType Missing parameter virtualAccountTrxType.
4002702 Invalid Mandatory Field expiredDate Missing parameter expiredDate.
4002702 Invalid Mandatory Field totalAmount Missing parameter totalAmount.
4002702 Invalid Mandatory Field virtualAccountName Missing parameter virtualAccountName.
4002702 Invalid Mandatory Field partnerServiceId Missing parameter partnerServiceId.
4002702 Invalid Mandatory Field customerNo Missing parameter customerNo.
4002702 Invalid Mandatory Field virtualAccountNo Missing parameter virtualAccountNo.
4002702 Invalid Mandatory Field trxId Missing parameter trxId.
4012700 Unauthorized Signature Error in the signature.
4012700 Unauthorized stringToSign Error in the signature.
4012700 Unauthorized Client Error in the Client ID.
4012701 Invalid Access Token Expired or incorrect Access Token.
4042712 Invalid Bill/Virtual Account Already Exists Virtual Account number is already registered.
4092700 Conflict Error in the External ID.

Virtual Account Type

There are two kinds of virtual account types is currently exist.

  1. Close Amount
    Initiated billed amount. The virtual account comes with the amount that has been billed.
  2. Open Amount
    There is no specific amount on the bill. It may allow the users to determine the amount to put. Such as putting a top-up amount.

Close Amount Example

For an example, you can refer to the JavaScript section.

To use this code example you might need to install npm axios and crypto-js.
Install the package on your project using npm:

npm i crypto-js axios

Copy the code below:
(select javascript tag to show the example code)

const axios = require("axios")
const CryptoJS = require('crypto-js')

const host = "https://snapdev.duitku.com"
const url = "/merchant/va/v1.0/transfer-va/create-va"
const date = new Date()
const expiredDate = new Date()
expiredDate.setDate(expiredDate.getDate() + 1)
const config = {
    partnerId: "DXXXXX",
    partnerServiceId: "123456",
    channelId: "Duitku",
    clientSecret: "x66485x31358x0e008c2dxx30f1152a6",
    accessToken: "ZmY0YWFjOTUtMWEwYi00ZjAxLTlmYmQtMDhkYzIzMTIxZmZh"
}
const customerNo = "1234567890"
const virtualAccountName = "John Doe" //displayed as name on the bank side
const trxId = "Transaction-00001" //need unique in every request
const amount = 12000
const body = {
    partnerServiceId: config.partnerServiceId,
    customerNo,
    virtualAccountNo: `${config.partnerServiceId}${customerNo}`,
    virtualAccountName,
    trxId,
    totalAmount: {
        "value": `${amount}.00`,
        "currency": "IDR"
    },
    virtualAccountTrxType: "C",
    expiredDate: toIsoString(expiredDate),
    additionalInfo: {
        "minAmount": "0.00",
        "maxAmount": "0.00"
    }
}

const headers = headersSymetricGenerator(date, "POST", url, body)
console.log(headers, body)

axios.post(host + url, body, {headers: headers })
    .then(response => {
        console.log(response.data)
    })
    .catch(err => {
        console.log(err.response.data)
    })

//Header symmetric generate
function headersSymetricGenerator(date, method, endpoint, body){
    let minifyBody = JSON.stringify(body)
    let encBody = CryptoJS.SHA256(minifyBody).toString()
    let stringToSign = `${method}:${endpoint}:${config.accessToken}:${encBody.toLowerCase()}:${toIsoString(date)}`
    let signature = CryptoJS.HmacSHA512(stringToSign, config.clientSecret).toString(CryptoJS.enc.Base64)
    let headers = {
        "X-TIMESTAMP": toIsoString(date),
        "X-SIGNATURE": signature,
        "X-PARTNER-ID": config.partnerId,
        "X-EXTERNAL-ID": Math.floor(1000000000000000000 + Math.random() * 9000000000000000000).toString(),
        "channel-id": config.channelId,
        Authorization: `bearer ${config.accessToken}`
    }
    console.log("minifyBody : ", minifyBody)
    console.log("encBody : ", encBody)
    console.log("stringToSign : ", stringToSign)
    return headers
}

//helper function for timestamp
function toIsoString(date) {
    var tzo = -date.getTimezoneOffset(),
        dif = tzo >= 0 ? '+' : '-',
        pad = function(num) {
            return (num < 10 ? '0' : '') + num;
        };

    return date.getFullYear() +
        '-' + pad(date.getMonth() + 1) +
        '-' + pad(date.getDate()) +
        'T' + pad(date.getHours()) +
        ':' + pad(date.getMinutes()) +
        ':' + pad(date.getSeconds()) +
        dif + pad(Math.floor(Math.abs(tzo) / 60)) +
        ':' + pad(Math.abs(tzo) % 60);
  }

Open Amount Example

For an example, you can refer to the JavaScript section.

To use this code example you might need to install npm axios and crypto-js.
Install the package on your project using npm:

npm i crypto-js axios

Copy the code below:
(select javascript tag to show the example code)

const axios = require("axios")
const CryptoJS = require('crypto-js')

const host = "https://snapdev.duitku.com"
const url = "/merchant/va/v1.0/transfer-va/create-va"
const date = new Date()
const expiredDate = new Date()
expiredDate.setDate(expiredDate.getDate() + 1)
const config = {
    partnerId: "DXXXXX",
    partnerServiceId: "123456",
    channelId: "Duitku",
    clientSecret: "x66485x31358x0e008c2dxx30f1152a6",
    accessToken: "ZmY0YWFjOTUtMWEwYi00ZjAxLTlmYmQtMDhkYzIzMTIxZmZh"
}
const customerNo = "1234567890"
const virtualAccountName = "John Doe" //displayed as name on the bank side
const trxId = "Transaction-00001" //need unique in every request
const minAmount= 12000 //ask Duitku for your minimum transaction limit
const maxAmount= 12000 //ask Duitku for your maximum transaction limit
const body = {
    partnerServiceId: config.partnerServiceId,
    customerNo,
    virtualAccountNo: `${config.partnerServiceId}${customerNo}`,
    virtualAccountName,
    trxId,
    totalAmount: {
        "value": `0.00`,
        "currency": "IDR"
    },
    virtualAccountTrxType: "O",
    expiredDate: toIsoString(expiredDate),
    additionalInfo: {
        "minAmount": `${minAmount}.00`,
        "maxAmount": `${maxAmount}.00`
    }
}

const headers = headersSymetricGenerator(date, "POST", url, body)
console.log(headers, body)

axios.post(host + url, body, {headers: headers })
    .then(response => {
        console.log(response.data)
    })
    .catch(err => {
        console.log(err.response.data)
    })

//Header symmetric generate
function headersSymetricGenerator(date, method, endpoint, body){
    let minifyBody = JSON.stringify(body)
    let encBody = CryptoJS.SHA256(minifyBody).toString()
    let stringToSign = `${method}:${endpoint}:${config.accessToken}:${encBody.toLowerCase()}:${toIsoString(date)}`
    let signature = CryptoJS.HmacSHA512(stringToSign, config.clientSecret).toString(CryptoJS.enc.Base64)
    let headers = {
        "X-TIMESTAMP": toIsoString(date),
        "X-SIGNATURE": signature,
        "X-PARTNER-ID": config.partnerId,
        "X-EXTERNAL-ID": Math.floor(1000000000000000000 + Math.random() * 9000000000000000000).toString(),
        "channel-id": config.channelId,
        Authorization: `bearer ${config.accessToken}`
    }
    console.log("minifyBody : ", minifyBody)
    console.log("encBody : ", encBody)
    console.log("stringToSign : ", stringToSign)
    return headers
}

//helper function for timestamp
function toIsoString(date) {
    var tzo = -date.getTimezoneOffset(),
        dif = tzo >= 0 ? '+' : '-',
        pad = function(num) {
            return (num < 10 ? '0' : '') + num;
        };

    return date.getFullYear() +
        '-' + pad(date.getMonth() + 1) +
        '-' + pad(date.getDate()) +
        'T' + pad(date.getHours()) +
        ':' + pad(date.getMinutes()) +
        ':' + pad(date.getSeconds()) +
        dif + pad(Math.floor(Math.abs(tzo) / 60)) +
        ':' + pad(Math.abs(tzo) % 60);
  }

To run this project example you might need to install npm crypto-js and axios. Install the package on your project using npm:

npm i crypto-js axios

Update VA

Duitku SNAP API Update VA

const axios = require("axios")
const toIsoString = require('./toIsoString.js')
const headersSymetricGenerator = require('./headersSymetricGenerator.js')
const config = require('./config.js')

const host = "https://snapdev.duitku.com"
const url = "/merchant/va/v1.0/transfer-va/update-va"
const date = new Date()
const expiredDate = new Date()
expiredDate.setDate(expiredDate.getDate() + 1)
const customerNo = "1234567890" //need equal with the one that would like to update
const virtualAccountName = "John Doe Update" //displayed as name on the bank side
const trxId = "Transaction-00001" //need equal with the one that would like to update
const amount = 24000
const body = {
    partnerServiceId: config.partnerServiceId,
    customerNo,
    virtualAccountNo: `${config.partnerServiceId}${customerNo}`,
    virtualAccountName,
    trxId,
    totalAmount: {
        "value": `${amount}.00`,
        "currency": "IDR"
    },
    virtualAccountTrxType: "C",
    expiredDate: toIsoString(expiredDate),
    additionalInfo: {
        "minAmount": "0.00",
        "maxAmount": "0.00"
    }
}

const headers = headersSymetricGenerator(date, "PUT", url, body)
console.log(headers, body)

axios.put(host + url, body, {headers: headers })
    .then(response => {
        console.log(response.data)
    })
    .catch(err => {
        console.log(err.response.data)
    })

To modify the details of an existing virtual account, such as the account name or amount, the Update Virtual Account API is used.

Method : HTTP PUT

Type : application/json

Development : https://snapdev.duitku.com/merchant/va/v1.0/transfer-va/update-va

Production : https://snap.duitku.com/merchant/va/v1.0/transfer-va/update-va

Service Code : 28

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

Value should be DUITKU DUITKU
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Body :

{
    "partnerServiceId": "123456",
    "customerNo": "1234567890",
    "virtualAccountNo": "1234561234567890",
    "virtualAccountName": "John Doe Update",
    "trxId": "Transaction-0001",
    "totalAmount": {
        "value": "150000.00",
        "currency": "IDR"
    },
    "virtualAccountTrxType": "C",
    "expiredDate": "2022-10-18T23:27:43+0700",
    "additionalInfo": {
        "minAmount": "0.00",
        "maxAmount": "0.00"
    },
}
Parameter Type Required Description Example
partnerServiceId String(10)

Prefix from Duitku. 123456
customerNo String(20)

Number for VA. 1234567890
virtualAccountNo String(28)

PartnerServiceId + CustomerNo.
Recommendation:
For a maximum of 16 digits characters.
1234561234567890
virtualAccountName String(20)

The name will be displayed on the bank side. John Doe Update
trxId String(50)

Transaction ID. Unique in every create VA. Should be match with the one trxId that would like to be edited. Transaction-0001
ExpiredDate string

ISO-8601. 2022-09-16T13:00:00+07:00
virtualAccountTrxType String(1)

Close Amount : C
Open Amount : O
C
totalAmount Object

See the table below.
additionalInfo Object

See the table below.

totalAmount:

Parameter Type Required Description Example
value String

ISO4217
with 2 decimal
for Open Amount set “0.00”.
150000.00
currency String(3)

Currency code, only receive IDR. IDR

additionalInfo:

Parameter Type Required Description Example
minAmount String

ISO4217
Open Amount set it's equally with your minimun that has been informed by Duitku.
Close Amount set “0.00”.
10000.00
maxAmount String

ISO4217
Open Amount set it's equally with your maximum that has been informed by Duitku.
Close Amount set “0.00”.
10000.00

Response :

{
    "responseCode": "2002800",
    "responseMessage": "Successful",
    "virtualAccountData": {
       "partnerServiceId": "123456",
       "customerNo": "1234567890",
       "virtualAccountNo": "1234561234567890",
       "virtualAccountName": "John Doe Update",
       "trxId": "Transaction-0001",
       "totalAmount": {
           "value": "150000.00",
           "currency": "IDR"
       },
       "virtualAccountTrxType": "C",
       "expiredDate": "2022-10-18T23:27:43+0700",
       "additionalInfo": {
           "minAmount": "0.00",
           "maxAmount": "0.00"
       },
    }
}

The virtualAccountData will return VA information.

Code Message Description
2002800 Successful The process was successful, and data was obtained.
4002801 Invalid Field Format virtualAccountTrxType Incorrect value for the parameter virtualAccountTrxType.
4002801 Invalid Field Format maxAmount should not be greater than 50000000 Incorrect value for the parameter maxAmount.
4002801 Invalid Field Format totalAmount.Currency Incorrect value for the parameter totalAmount in the Currency part.
4002801 Invalid Field Format totalAmount.Value Incorrect value for the parameter totalAmount in the value part.
4002801 Invalid Field Format param,totalAmount.value Incorrect value for the parameter totalAmount in the value part.
4002801 Invalid Field Format param,virtualAccountName Incorrect value for the parameter virtualAccountName.
4002801 Invalid Field Format param,customerNo Incorrect value for the parameter customerNo.
4002802 Invalid Mandatory Field virtualAccountTrxType Missing parameter virtualAccountTrxType.
4002802 Invalid Mandatory Field expiredDate Missing parameter expiredDate.
4002802 Invalid Mandatory Field totalAmount Missing parameter totalAmount.
4002802 Invalid Mandatory Field virtualAccountName Missing parameter virtualAccountName.
4002802 Invalid Mandatory Field partnerServiceId Missing parameter partnerServiceId.
4012800 Unauthorized Signature Error in the signature.
4012800 Unauthorized stringToSign Error in the signature.
4012800 Unauthorized Client Error in the Client ID.
4012801 Invalid Access Token Expired or incorrect Access Token.
4032800 Transaction Expired The transaction to be updated has expired or is inactive.
4042812 Invalid Bill/Virtual Account Not Found Combination of Virtual Account number and Transaction ID not found.
4092800 Conflict Error in the External ID.

Inquiry VA

Duitku SNAP API INQUIRY VA

const axios = require("axios")
const headersSymetricGenerator = require('./headersSymetricGenerator.js')
const config = require('./config.js')

const host = "https://snapdev.duitku.com"
const url = "/merchant/va/v1.0/transfer-va/inquiry-va"
const date = new Date()
const customerNo = "1234567890" //need equal with the one that would like to update
const trxId = "Transaction-00001" //need equal with the one that would like to update
const body = {
    partnerServiceId: config.partnerServiceId,
    customerNo,
    virtualAccountNo: `${config.partnerServiceId}${customerNo}`,
    trxId,
}
const headers = headersSymetricGenerator(date, "POST", url, body)
console.log(headers, body) 

axios.post(host + url, body, {headers: headers })
.then(response => {
    console.log(response.data)
})
.catch(err => {
    console.log(err.response.data)
})

To obtain details about a specific virtual account, such as the status, name, and amount, the Inquiry Virtual Account API can be utilized.

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/va/v1.0/transfer-va/inquiry-va

Production : https://snap.duitku.com/merchant/va/v1.0/transfer-va/inquiry-va

Service Code : 30

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

Value should be DUITKU DUITKU
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Body :

{
    "partnerServiceId": "123456",
    "customerNo": "1234567890",
    "virtualAccountNo": "1234561234567890",
    "trxId": "Transaction-0001"
}
Parameter Type Required Description Example
partnerServiceId String(10)

Prefix from Duitku. 123456
customerNo String(20)

Number for VA. 1234567890
virtualAccountNo String(28)

PartnerServiceId + CustomerNo.
Recommendation:
For a maximum of 16 digits characters.
1234561234567890
trxId String(50)

Transaction ID. Unique in every create VA. Should be match with the one trxId that would like to be see. Transaction-0001

Response :

{
    "virtualAccountData": {
        "partnerServiceId": "123456",
        "customerNo": "1234567890",
        "virtualAccountNo": "1234561234567890",
        "virtualAccountName": "John Doe update",
        "trxId": "Transaction-0001",
        "totalAmount": {
            "value": "100000.00",
            "currency": "IDR"
        },
        "virtualAccountTrxType": "C",
        "expiredDate": "2022-10-18T14:01:15+07:00",
        "additionalInfo": {
            "minAmount": "0.00",
            "maxAmount": "0.00"
        },
    },
    "responseCode": "2003000",
    "responseMessage": "Successful"
}

Status code 200
Success
The virtualAccountData will return the match information.

Delete VA

Duitku SNAP API DELETE VA

const axios = require("axios")
const headersSymetricGenerator = require('./headersSymetricGenerator.js')
const config = require('./config.js')

const host = "https://snapdev.duitku.com"
const url = "/merchant/va/v1.0/transfer-va/delete-va"
const date = new Date()
const customerNo = "1234567890" //need equal with the one that would like to update
const trxId = "Transaction-00001" //need equal with the one that would like to update
const body = {
    partnerServiceId: config.partnerServiceId,
    customerNo,
    virtualAccountNo: `${config.partnerServiceId}${customerNo}`,
    trxId,
}
const headers = headersSymetricGenerator(date, "DELETE", url, body)
console.log(headers, body) 

axios.delete(host + url, {
    headers: headers,
    data: body
})
.then(response => {
    console.log(response.data)
})
.catch(err => {
    console.log(err.response.data)
})

To render a virtual account unusable and to mark its status as expired, the Delete Virtual Account API can be invoked. This API ensures that the particular virtual account cannot receive payments anymore

Method : HTTP DELETE

Type : application/json

Development : https://snapdev.duitku.com/merchant/va/v1.0/transfer-va/delete-va

Production : https://snap.duitku.com/merchant/va/v1.0/transfer-va/delete-va

Service Code : 31

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

Value should be DUITKU DUITKU
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Body :

{
    "partnerServiceId": "123456",
    "customerNo": "1234567890",
    "virtualAccountNo": "1234561234567890",
    "trxId": "Transaction-0001"
}
Parameter Type Required Description Example
partnerServiceId String(10)

Prefix from Duitku. 123456
customerNo String(20)

Number for VA. 1234567890
virtualAccountNo String(28)

PartnerServiceId + CustomerNo.
Recommendation:
For a maximum of 16 digits characters.
1234561234567890
trxId String(50)

Transaction ID. Unique in every create VA. Should be match with the one trxId that would like to be delete. Transaction-0001

Response :

{
    "responseCode": "2002800",
    "responseMessage": "Successful",
    "virtualAccountData": {
       "partnerServiceId": "123456",
       "customerNo": "1234567890",
       "virtualAccountNo": "1234561234567890",
       "trxId": "Transaction-0001"
    }
}

Status code 200
Success
The virtualAccountData will return the deleted VA information.

Helper function and config example

const config = {
    partnerId: "DXXXXX",
    partnerServiceId: "123456",
    channelId: "Duitku",
    clientSecret: "x66485x31358x0e008c2dxx30f1152a6",
    accessToken: "ZmY0YWFjOTUtMWEwYi00ZjAxLTlmYmQtMDhkYzIzMTIxZmZh"
}
module.exports = config

//helper function for timestamp
function toIsoString(date) {
    var tzo = -date.getTimezoneOffset(),
        dif = tzo >= 0 ? '+' : '-',
        pad = function(num) {
            return (num < 10 ? '0' : '') + num;
        };

    return date.getFullYear() +
        '-' + pad(date.getMonth() + 1) +
        '-' + pad(date.getDate()) +
        'T' + pad(date.getHours()) +
        ':' + pad(date.getMinutes()) +
        ':' + pad(date.getSeconds()) +
        dif + pad(Math.floor(Math.abs(tzo) / 60)) +
        ':' + pad(Math.abs(tzo) % 60);
  }

module.exports = toIsoString

//Header symmetric generate
const CryptoJS = require('crypto-js')
const config = require('./config.js')
const toIsoString = require('./toIsoString.js')
function headersSymetricGenerator(date, method, endpoint, body){
    let minifyBody = JSON.stringify(body)
    let encBody = CryptoJS.SHA256(minifyBody).toString()
    let stringToSign = `${method}:${endpoint}:${config.accessToken}:${encBody.toLowerCase()}:${toIsoString(date)}`
    let signature = CryptoJS.HmacSHA512(stringToSign, config.clientSecret).toString(CryptoJS.enc.Base64)
    let headers = {
        "X-TIMESTAMP": toIsoString(date),
        "X-SIGNATURE": signature,
        "X-PARTNER-ID": config.partnerId,
        "X-EXTERNAL-ID": Math.floor(1000000000000000000 + Math.random() * 9000000000000000000).toString(),
        "channel-id": config.channelId,
        Authorization: `bearer ${config.accessToken}`
    }
    console.log("minifyBody : ", minifyBody)
    console.log("encBody : ", encBody)
    console.log("stringToSign : ", stringToSign)
    return headers
}

module.exports = headersSymetricGenerator

Payment VA

Duitku SNAP API Payment Sequence Diagram

Payment is a webhook or notification when the user has already paid. To receive this information, you need to create an API to receive the notification. Here are the things you need to do when you receive payment.

  1. Secure: you need to make your payment secure. Because the payment information just will always be through this API. We need to ensure a robust and secure environment. You might see the image of the sequence diagram at the top of this page.
    1. Whitelist Duitku IP if it's needed. IP range : 182.23.85.0/28 103.177.101.177/28
    2. Always validate the signature.
    3. Optionally you may check through Inquiry Status to make sure that your user has already paid the transaction.
  2. Update: you need to update your transaction status or you might register the payment on your transaction.

Payment API

To have a payment we need an API, as an example, we use express js. Here the project directory like:

.
├── app.js
├── controllers
   └── SnapController.js
├── helpers
   └── paymentSignatureValidator.js
└── routes
    └── index.js


3 directories, 4 files

To run this project example you might need to install npm express, jsrsasign, and crypto-js. Install the package on your project using npm:

npm i express crypto-js axios jsrsasign jsrsasign-util

Here is the project code example:

app.js

const express = require('express')
const app = express()
const port = 3000
const router = require('./routes')

app.use('', router);

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

routes/index.js

cconst bodyParser = require('body-parser');
const SnapController = require('../controllers/SnapController');

const router = require('express').Router();

router.post('/callback/v1.0/transfer-va/payment', bodyParser.json() , SnapController.PaymentVa)

module.exports = router

controllers/SnapController

const paymentSignatureValidator = require("../helpers/paymentSignatureValidator")

class SnapController{
    static PaymentVa(req, res){
        const body = req.body
        const url = req.url
        const date = new Date()
        const xExternalId = req.headers["x-external-id"]
        const xPartnerId = req.headers["x-partner-id"]
        const xSignature = req.headers["x-signature"]
        const xTimestamp = req.headers["x-timestamp"]
        const channelId = req.headers["channel-id"]
        let isValid = paymentSignatureValidator(body, xTimestamp, xSignature, url)
        if(isValid){
            /**
            * You may create your logic here after validating the signature
            * You also may hit inquiry status and get the value here
            */
            //Your code here
            res.send({
                message: "Received and validated"
            })
        }else{
            res.send({
                message: "Received but not validated"
            })
        }
    }
}

module.exports = SnapController

helpers/paymentSignatureValidator.js

const rs = require('jsrsasign')
const rsu = require('jsrsasign-util');
const toIsoString = require('./toIsoString');
const CryptoJS = require('crypto-js')

function paymentSignatureValidator(body, date, signature, url){
    let minifyBody = JSON.stringify(body)
    let encBody = CryptoJS.SHA256(minifyBody).toString()
    let stringToSign = `POST:${url}:${encBody.toLowerCase()}:${date}`
    let publicKey = rs.KEYUTIL.getKey(rsu.readFile("./duitkukey/duitku_publickey.pem"))
    let sign = new rs.KJUR.crypto.Signature({"alg": "SHA256withRSA"})
    sign.init(publicKey)
    sign.updateString(stringToSign)
    const isSignatureValid = sign.verify(CryptoJS.enc.Hex.stringify(CryptoJS.enc.Base64.parse(signature)))
    console.log("minifyBody", minifyBody)
    console.log("encBody", encBody)
    console.log("isSignatureValid", isSignatureValid)
    return isSignatureValid
}

module.exports = paymentSignatureValidator

Method : HTTP POST

Type : application/json

Url : https://yourdomain.com/v1.0/transfer-va/payment

Endpoint : /v1.0/transfer-va/payment

Service Code : 25

Header :

Parameter Type Required Description Example
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to Asymmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

Value should be DUITKU-PAYMENT DUITKU-PAYMENT

Body :

{
    "partnerServiceId" : "123456",
    "customerNo" : "1234567890",
    "virtualAccountNo" :  "1234561234567890",
    "paymentRequestId" : "46181",
    "trxId" :  "Transaction-0001",
    "paidAmount" : {
        "value" : "100000.00",
        "currency" : "IDR"
    },
    "additionalInfo" : {
        "reference" : "D0001YB1CUE2ET3027DK",
        "paymentCode" : "M2"
    }
}
Parameter Type Required Description Example
partnerServiceId String(10)

Prefix from Duitku. 123456
customerNo String(20)

Number for VA. 1234567890
virtualAccountNo String(28)

PartnerServiceId + CustomerNo.
Recommendation:
For a maximum of 16 digits characters.
1234561234567890
paymentRequestId String(20)

The name will be displayed on the bank side. 46181
trxId String(50)

Transaction ID. Unique from every create VA. Transaction-0001
paidAmount Object

See the table below.
additionalInfo Object

See the table below.

paidAmount:

Parameter Type Required Description Example
value String

ISO4217
with 2 decimal
for Open Amount set “0.00”.
100000.00
currency String(3)

Currency code, only receive IDR. IDR

additionalInfo:

Parameter Type Required Description Example
reference String

Reference from Duitku. D0001YB1CUE2ET3027DK
paymentCode String

Payment method. M2

Response :

{
    "responseCode" : "2002500",
    "responseMessage" : "Successful",
    "virtualAccountData" : {
        "partnerServiceId" : "123456",
        "customerNo" : "1234567890",
        "virtualAccountNo" : "1234561234567890",
        "virtualAccountName" : "John Doe",
        "paymentRequestId" : "46181",
        "paidAmount" : {
            "value" : "100000.00",
            "currency" : "IDR"
        }
    }
}

As you can see in the JSON response example here, you should focus on the virtualAccountData variable. As for the responseCode and responseMessage, these indicate the status of your request process.

Code Message Description
2002500 Successful The process was successful, and data was obtained.
4002501 Invalid Field Format {fieldName} Incorrect value for the parameter {fieldName}.
4002502 Invalid Mandatory Field {fieldName} Missing parameter {fieldName}.
4012500 Unauthorized Signature Error in the signature.
4012501 Invalid Access Token Expired or incorrect Access Token.
4012501 Invalid Bill/Virtual Account Not Found Virtual Account number not found.
4042512 Bill not found Input bill was not found.
4042513 Invalid amount Incorrect value for the amount.
4042514 Bill already paid Bill has already been paid.
4092500 Conflict Error in the External ID.
5002500 General Error Error during the request process.
5042500 Time Out Time has expired.

Inquiry Status VA

Duitku SNAP API Inquiry Status Sequence Diagram

Inquiry Status Scheme

This API will help you to inquire about the payment status. As you can see in the sequence above. You might need to inquire when there is a confirmation payment from the user. Or as security optional you might inquire about status after receiving payment. It helps you to make sure the payment status is genuine.

Inquiry Status Request

To run this project example you might need to install npm crypto-js and axios. Install the package on your project using npm:

npm i crypto-js axios

Copy the code below:
(select javascript tag to show the example code)

const axios = require("axios")
const CryptoJS = require('crypto-js')

const customerNo = "1234567890"
const trxId = "Transaction-00001"
const host = "https://snapdev.duitku.com"
const url = "/merchant/va/v1.0/transfer-va/status"
const date = new Date()
const config = {
    partnerId: "DXXXXX",
    partnerServiceId: "123456",
    channelId: "Duitku",
    clientSecret: "x66485x31358x0e008c2dxx30f1152a6",
    accessToken: "ZmY0YWFjOTUtMWEwYi00ZjAxLTlmYmQtMDhkYzIzMTIxZmZh"
}
const body = {
    partnerServiceId: config.partnerServiceId,
    customerNo,
    virtualAccountNo: `${config.partnerServiceId}${customerNo}`,
    inquiryRequestId: trxId,
}
const headers = headersSymetricGenerator(date, "POST", url, body)
console.log(headers, body) 

axios.post(host + url, body, {headers: headers })
    .then(response => {
        console.log(response.data)
    })
    .catch(err => {
        console.log(err.response.data)
    })

//Header symmetric generate
function headersSymetricGenerator(date, method, endpoint, body){
    let minifyBody = JSON.stringify(body)
    let encBody = CryptoJS.SHA256(minifyBody).toString()
    let stringToSign = `${method}:${endpoint}:${config.accessToken}:${encBody.toLowerCase()}:${toIsoString(date)}`
    let signature = CryptoJS.HmacSHA512(stringToSign, config.clientSecret).toString(CryptoJS.enc.Base64)
    let headers = {
        "X-TIMESTAMP": toIsoString(date),
        "X-SIGNATURE": signature,
        "X-PARTNER-ID": config.partnerId,
        "X-EXTERNAL-ID": Math.floor(1000000000000000000 + Math.random() * 9000000000000000000).toString(),
        "channel-id": config.channelId,
        Authorization: `bearer ${config.accessToken}`
    }
    console.log("minifyBody : ", minifyBody)
    console.log("encBody : ", encBody)
    console.log("stringToSign : ", stringToSign)
    return headers
}


//helper function for timestamp
function toIsoString(date) {
    var tzo = -date.getTimezoneOffset(),
        dif = tzo >= 0 ? '+' : '-',
        pad = function(num) {
            return (num < 10 ? '0' : '') + num;
        };

    return date.getFullYear() +
        '-' + pad(date.getMonth() + 1) +
        '-' + pad(date.getDate()) +
        'T' + pad(date.getHours()) +
        ':' + pad(date.getMinutes()) +
        ':' + pad(date.getSeconds()) +
        dif + pad(Math.floor(Math.abs(tzo) / 60)) +
        ':' + pad(Math.abs(tzo) % 60);
}

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/va/v1.0/transfer-va/status

Production : https://snap.duitku.com/merchant/va/v1.0/transfer-va/status

Service Code : 26

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

Value should be DUITKU DUITKU
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Body :

{
    "partnerServiceId" : "123456",
    "customerNo" : "1234567890",
    "virtualAccountNo" :  "1308301000000001",
    "inquiryRequestId" : "1234561234567890"
}
Parameter Type Required Description Example
partnerServiceId String(10)

Prefix from Duitku. 123456
customerNo String(20)

Number for VA. 1234567890
virtualAccountNo String(28)

PartnerServiceId + CustomerNo.
Recommendation:
For a maximum of 16 digits characters.
1234561234567890
inquiryRequestId String(50)

TrxID from Create VA. Transaction-0001

Response :

{
    "responseCode" : "2002600",
    "responseMessage" : "Successful",
    "virtualAccountData" : {
        "partnerServiceId" : "123456",
        "customerNo" : "1234567890",
        "virtualAccountNo" : "1234561234567890",
        "inquiryRequestId" : "46181",
        "paymentRequestId" : "46181",
        "paidAmount" : {
            "value" : "100000.00",
            "currency" : "IDR"
        },
        "totalAmount" : {
            "value" : "100000.00",
            "currency" : "IDR"
        },
        "transactionDate" : "2022-09-14T16:00:00+07:00",
        "trxDateTime" : "2022-09-29T10:00:00+07:00",
        "paymentFlagStatus" : "00",
        "paymentFlagReason" : {
            "english" : "SUCCESS",
            "indonesia" : "SUKSES"  
        }
    }
}

Status code 200
Success
See in the JSON example. You'll gonna need to focus on the variable virtualAccountData. For responseCode and responseMessage, these are indicating your process request.
See the value from paymentFlagStatus in virtualAccountData. It indicates the payment status.
Status for Payments They are:
00: SUCCESS
01: PROCESS
02: EXPIRED

Direct Debit

Account Binding

Duitku SNAP API Registration

The API service used to connect channels with merchant applications using the customer's registered phone number on their account.

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/registration/v1.0/registration-account-binding

Production : https://snap.duitku.com/merchant/registration/v1.0/registration-account-binding

Service Code : 07

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

Value should be OL or SL OL
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Body :

{
  "phoneNo": "0857181XX",
  "merchantId": "DXX01",
  "additionalInfo": {
    "customerUniqueId": "123"
  },
  "redirectUrl": "https://example.com"
}
Parameter Type Required Description Example
phoneNo String(15)

Customer's phone number. 0812345xxxx
merchantId String(10)

Merchant Code from Duitku. D00XXX
redirectUrl String(255)

The response returned after entering the PIN. http://{returnUrl}?resultCode=00&phoneNumber=0812345xxx&state=accountLink
additionalInfo Object

See the table below.

additionalInfo:

Parameter Type Required Description Example
customerUniqueId String(50)

The ID used as a unique identifier for the customer in your application. 1234567

Response :

{
    "responseCode": "2000700",
    "responseMessage": "Success",
    "redirectUrl": "https://webview.byte-stack.net/
        cellblockui/partner/activation?authType=2FA
        &submissionType=redirect"
}
Code Message Description
2000700 Successful Successful processing and obtaining redirectUrl.
4000700 Bad Request, Invalid Merchant Request Error in the request with merchantId.
4000700 Service Not Implemented Service not registered with the request CHANNEL-ID.
4000701 Invalid Field Format {,PhoneNo} Incorrect value for the parameter PhoneNo.
4000701 Invalid Field Format {,RedirectUrl} Incorrect value for the parameter RedirectUrl.
4000702 Missing Mandatory Field {additionalInfo.CustomerUniqueId} Missing parameter CustomerUniqueId.
4000702 Invalid Mandatory Field, [additionalInfo.CustomerUniqueId] Missing parameter additionalInfo.
4000702 Missing Mandatory Field {RedirectUrl} Missing parameter RedirectUrl.
4000702 Missing Mandatory Field {MerchantId} Missing parameter MerchantId.
4000702 Missing Mandatory Field {PhoneNo} Missing parameter PhoneNo.
4010700 Unauthorized Signature Error in the signature.
4010700 Unauthorized stringToSign Error in the signature.
4010700 Unauthorized Client Error in the PARTNER-ID.
4010701 Invalid Access Token Expired or incorrect Access Token.
4030700 Transaction Expired Transaction to be updated has expired or is inactive.
4030715 Transaction Not Permitted:Akun terkunci dalam waktu 30 menit Requested transaction has exceeded the maximum limit of 6 requests.
4040701 Invalid Request Incorrect value for the parameter additionalInfo.
4090700 Conflict Error in the External ID.

Account Binding Inquiry

Duitku SNAP API Direct Inquiry

The API service used for checking the account status with the merchant application using the customer's registered phone number that has been registered with the account.

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/registration/v1.0/registration-account-inquiry

Production : https://snap.duitku.com/merchant/registration/v1.0/registration-account-inquiry

Service Code : 08

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

Value should be OL or SL OL
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Body :

{
    "additionalInfo": {
        "credentialCode": "95e8ad58-7acc-ee11-9f5e-9440c9319978"
    }
}
Parameter Type Required Description Example
additionalInfo Object

See the table below.

additionalInfo:

Parameter Type Required Description Example
credentialCode String(50)

Credential code for authentication. C0B32F16-2A51-ED11-8135-96724827090C

Response :

{
    "responseCode": "2000800",
    "responseMessage": "Success",
    "accountNo": "0xxxxxx9006",
    "additionalInfo": {
        "balanceCash": 1181712,
        "accountStatus": "LINKED"
    }
}
Code Message Description
2000800 Successful Successfully processed.
2000801 Invalid Token:Anda Tidak Memiliki Akses Error in the request with credentialCode.
4000802 Missing Mandatory Field {AdditionalInfo.CredentialCode} Missing parameter CredentialCode.
4000802 Invalid Mandatory Header X-EXTERNAL-ID Missing parameter X-EXTERNAL-ID.
4000802 Invalid Mandatory Header CHANNEL-ID Missing parameter CHANNEL-ID.
4010800 Unauthorized Signature Error in the signature.
4010800 Unauthorized stringToSign Error in the signature.
4010800 Unauthorized Client Error in the PARTNER-ID.
4010801 Invalid Access Token Expired or incorrect Access Token.
4040801 Invalid Request Format error during the request.
5000801 Internal Server Error Error during the request process.

Account Unbinding

Duitku SNAP API Direct Inquiry

The API service used when customers want to terminate their channel connection with the merchant application using the customer's registered phone number on their account.

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/registration/v1.0/registration-account-unbinding

Production : https://snap.duitku.com/merchant/registration/v1.0/registration-account-unbinding

Service Code : 09

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

Value should be OL or SL OL
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Body :

{
    "merchantId": "DXX01",
    "tokenId": "C0B32F16-2A51-ED11-8135-96724827090C"
}
Parameter Tipe Required Description Example
merchantId String(10)

Merchant Code from Duitku. D00XXX
tokenId String(25)

Credential code for authentication. C0B32F16-2A51-ED11-8135-96724827090C

Response :

{
    "responseCode": "2000900",
    "responseMessage": "Success",
    "unlinkResult": "Success"
}
Code Message Description
2000900 Successful Successfully processed.
4000902 Invalid Mandatory Header X-EXTERNAL-ID Missing parameter X-EXTERNAL-ID
4000902 Invalid Mandatory Header CHANNEL-ID Missing parameter CHANNEL-ID.
4010900 Unauthorized Signature Error in the signature.
4010900 Unauthorized stringToSign Error in the signature.
4010900 Unauthorized Client Error in the PARTNER-ID.
4010901 Invalid Access Token Expired or incorrect Access Token
5000901 Internal Server Error Error during the request process.

Debit Payment Linking

Duitku SNAP API Direct Debit linking

This API is used for Debit Payment services, utilizing an Account Linking process beforehand for the request process. There are 2 types of transactions in this API: Manual Debit and Auto Debit. This API supports ShopeePay and OVO payment methods, using the values SL and OL respectively.

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/debit/v1.0/debit/payment-host-to-host

Production : https://snap.duitku.com/merchant/debit/v1.0/debit/payment-host-to-host

Service Code : 54

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

Value should be OL or SL OL
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Request Body:

{
    "partnerReferenceNo": "INV1708588643",
    "chargeToken": "OL",
    "bankCardToken": "4a17a847-94d0-ee11-9f5e-9440c9319978",
    "merchantId": "D0XXX",
    "amount": {
        "value": "1000.00",
        "currency": "IDR"
    },
    "additionalInfo": {
        "productDetails": "Tes pembayaran Direct debit Duitku",
        "additionalParam": "test additional param",
        "phoneNumber": "0821XXXXXXX",
        "email": "[email protected]",
        "returnUrl": "http:\/\/example.com\/return",
        "itemDetails": [
            {
                "name": "Test Item 1",
                "price": 500,
                "quantity": 1
            },
            {
                "name": "Test Item 2",
                "price": 500,
                "quantity": 1
            }
        ],
        "transactionType": "M",
        "merchantUserInfo": "",
        "customerDetail": {
            "firstName": "John",
            "lastName": "Doe",
            "email": "[email protected]",
            "phoneNumber": "0821XXXXXXX",
            "billingAddress": {
                "firstName": "John",
                "lastName": "Doe",
                "address": "Jl. Kembangan Raya",
                "city": "Jakarta",
                "postalCode": "11530",
                "phone": "0821XXXXXXX",
                "countryCode": "ID"
            },
            "shippingAddress": {
                "firstName": "John",
                "lastName": "Doe",
                "address": "Jl. Kembangan Raya",
                "city": "Jakarta",
                "postalCode": "11530",
                "phone": "0821XXXXXXX",
                "countryCode": "ID"
            }
        }
    },
    "payOptionDetails": [
        {
            "payMethod": "CASH",
            "transAmount": {
                "value": "1000.00",
                "currency": "IDR"
            }
        }
    ]
}
Parameter Type Required Description Example
partnerReferenceNo String(64)

Transaction number from merchant. INV123456
chargeToken String(50)

The payment method code provided by Duitku, for which the value must match the CHANNEL-ID in the header. OL
bankCardToken String(50)

Credential code for authentication. 67af67e7-e0ce-ee11-9f5e-9440c9319978
merchantId String(2)

Merchant code from Duitku. D00XXX
payOptionDetails Object Array

See the table payOptionDetails below.
additionalInfo Object

See the table additionalInfo below.
amount Object

See the table amount below.

additionalInfo

Parameter Type Required Description Example
productDetails String(255)

Description about product/service on sale.
transactionType String(20)

C

Here are the values used:
M: Used for Manual Debit payments that require a PIN process.
A: Used for Auto Debit payments that do not require a PIN process.
M
phoneNumber String(15)

Customer's phone number. 0857181XX
email String(60)

Customer's email. [email protected]
additionalParam String(255)

Additional parameter for merchant purpose.
returnUrl String(255)

Link to redirect after transaction is completed or cancelled. http://example.com/return
merchantUserInfo String(255)

Customer's username or email on merchant site. 1234567
itemDetails object

See the table itemDetails below.
customerDetail object

See the table customerDetail below.

Item Details

Parameter Type Required Description Example
name string(255)

Name of the item. Apel
quantity integer

Quantity of the item bought. 10
price integer

Price of the Item. Note: Don't add decimal. 50000

Customer Detail

Parameter Type Required Description Example
firstName string(255)

Customer's first name. John
lastName string(255)

Customer's last name. Doe
email string(255)

Customer's email. [email protected]
phoneNumber string(255)

Customer's phone number. 08123456789
billingAddress object

See the table address below
shippingAddress object

See the table address below

Address

Parameter Type Required Description Example
firstName string(255)

Customer's first name. John
lastName string(255)

Customer's last name. Doe
address string(255)

Billing address or shipping address. Jl. Kembangan Raya
city string(255)

City of the address. Jakarta
postalCode string(255)

Postal code of the address. 11530
phone string(255)

Phone number for billing or shipping. 08123456789
countryCode string(255)

ISO 3166-1 alpha-3. ID

payOptionDetails

Parameter Type Required Description Example
payMethod String(255)

The type of balance you use can be filled in CASH. CASH
transAmount object

See the table amount below

amount

Parameter Type Required Description Example
value String

ISO4217
with 2 decimal.
10000.00
currency String(3)

Currency code, only receive IDR. IDR

Response :

Example Response Manual Payment Linking

{
  "responseCode": "2025400",
  "responseMessage": "Request In Progress",
  "referenceNo": "DXXXXX24OWAA7JJHALBAL6J",
  "partnerReferenceNo": "INV1708597771",
  "webRedirectUrl": "https://webview.byte-stack.net/
  cellblockui/v2/paymentPin?action=payment&submission
  Type=redirect&destination=https://snapdev.duitku.com"
}

Example Response Auto Payment Linking

{
  "responseCode": "2005400",
  "responseMessage": "Success",
  "referenceNo": "DXXXXX24OWAA7JJHALBAL6J",
  "partnerReferenceNo": "INV1708597771"
}
Code Message Description
2005400 Successful Success.
2025400 Request In Progress Transaction is being processed.
4005400 Bad Request, Invalid Merchant Request Error in Request merchantId.
4005400 Service Not Implemented Service is not registered on request CHANNEL-ID.
4005401 Invalid Field Format Incorrect value for that parameter.
4005402 Missing Mandatory Field {AdditionalInfo.ReturnUrl} Parameter ReturnUrl is missing.
4015400 Unauthorized Signature Error in Signature.
4015400 Unauthorized stringToSign Error in Signature.
4015400 Unauthorized Client Error in PARTNER-ID.
4015401 Invalid Access Token Access Token expired or incorrect.
4035400 Transaction Expired Transaction to be updated has expired or is not active.
4035414 Insufficient Fund Your balance is insufficient for this transaction.
4045401 Invalid Request Incorrect value for parameter.
4045413 Invalid Amount, Amount must be equal with total price item details Error in value parameter amount and price in item detail.
4095400 Conflict Error in External ID.

Debit Payment Redirect

Duitku SNAP API Direct Debit

This API is used for Debit Payment Redirect services without requiring an Account Linking process beforehand. When making an API request, the chargeToken parameter must be included. Currently, the supported channels are ShopeePay Apps and Dana, with the values SA and DA respectively.

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/debit/v1.0/debit/payment-host-to-host

Production : https://snap.duitku.com/merchant/debit/v1.0/debit/payment-host-to-host

Service Code : 54

Header :

{
    "partnerReferenceNo": "INV1708588643",
    "chargeToken": "DA",
    "bankCardToken": "4a17a847-94d0-ee11-9f5e-9440c9319978",
    "merchantId": "D0XXX",
    "validUpTo":"2022-09-16T13:00:00+07:00",
    "amount": {
        "value": "1000.00",
        "currency": "IDR"
    },
    "additionalInfo": {
        "productDetails": "Tes pembayaran Direct debit Duitku",
        "additionalParam": "test additional param",
        "phoneNumber": "0821XXXXXXX",
        "email": "[email protected]",
        "returnUrl": "http:\/\/example.com\/return",
        "itemDetails": [
            {
                "name": "Test Item 1",
                "price": 500,
                "quantity": 1
            },
            {
                "name": "Test Item 2",
                "price": 500,
                "quantity": 1
            }
        ],
        "merchantUserInfo": "",
        "customerDetail": {
            "firstName": "John",
            "lastName": "Doe",
            "email": "[email protected]",
            "phoneNumber": "0821XXXXXXX",
            "billingAddress": {
                "firstName": "John",
                "lastName": "Doe",
                "address": "Jl. Kembangan Raya",
                "city": "Jakarta",
                "postalCode": "11530",
                "phone": "0821XXXXXXX",
                "countryCode": "ID"
            },
            "shippingAddress": {
                "firstName": "John",
                "lastName": "Doe",
                "address": "Jl. Kembangan Raya",
                "city": "Jakarta",
                "postalCode": "11530",
                "phone": "0821XXXXXXX",
                "countryCode": "ID"
            }
        }
    },
    "payOptionDetails": [
        {
            "payMethod": "CASH",
            "transAmount": {
                "value": "1000.00",
                "currency": "IDR"
            }
        }
    ]
}
Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

Value should be DA or SA DA
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Request Body:

Parameter Type Required Description Example
partnerReferenceNo String(64)

Transaction number from merchant. INV123456
chargeToken String(50)

The payment method code provided by Duitku, for which the value must match the CHANNEL-ID in the header. DA
merchantId String(2)

Merchant code from Duitku. D00XXX
payOptionDetails Object Array

See the table payOptionDetails below.
additionalInfo Object

See the table additionalInfo below.
amount Object

See the table amount below.
validUpTo String

Transaction expiry time on ISO-8601. 2022-09-16T13:00:00+07:00

additionalInfo

Parameter Type Required Description Example
productDetails String(255)

Description about product/service on sale.
phoneNumber String(15)

Customer's phone number. 0857181XX
email String(60)

Customer's email. [email protected]
additionalParam String(255)

Additional parameter for merchant purpose.
returnUrl String(255)

Link to redirect after transaction is completed or cancelled. http://example.com/return
merchantUserInfo String(255)

Customer's username or email on merchant site. 1234567
itemDetails object

See the table itemDetails below.
customerDetail object

See the table customerDetail below.

Item Details

Parameter Type Required Description Example
name string(255)

Name of the item. Apel
quantity integer

Quantity of the item bought. 10
price integer

Price of the Item. Note: Don't add decimal. 50000

Customer Detail

Parameter Type Required Description Example
firstName string(255)

Customer's first name. John
lastName string(255)

Customer's last name. Doe
email string(255)

Customer's email. [email protected]
phoneNumber string(255)

Customer's phone number. 08123456789
billingAddress object

See the table address below
shippingAddress object

See the table address below

Address

Parameter Type Required Description Example
firstName string(255)

Customer's first name. John
lastName string(255)

Customer's last name. Doe
address string(255)

Billing address or shipping address. Jl. Kembangan Raya
city string(255)

City of the address. Jakarta
postalCode string(255)

Postal code of the address. 11530
phone string(255)

Phone number for billing or shipping. 08123456789
countryCode string(255)

ISO 3166-1 alpha-3. ID

payOptionDetails

Parameter Type Required Description Example
payMethod String(255)

The type of balance you use can be filled in CASH. CASH
transAmount object

See the table amount below

amount

Parameter Type Required Description Example
value String

ISO4217
with 2 decimal.
10000.00
currency String(3)

Currency code, only receive IDR. IDR

Response :

{
    "responseCode": "2005400",
    "responseMessage": "Success",
    "referenceNo": "DXXXXX24OWAA7JJHALBAL6J",
    "partnerReferenceNo": "INV1708597771"
}
Code Message Description
2005400 Success Success.
4005400 Service Not Implemented Service is not registered on request CHANNEL-ID.
4005401 Invalid Field Format Incorrect value for that parameter.
4005402 Missing Mandatory Field {AdditionalInfo.ReturnUrl} Parameter ReturnUrl is missing.
4015400 Unauthorized Signature Error in Signature.
4015400 Unauthorized stringToSign Error in Signature.
4015400 Unauthorized Client Error in PARTNER-ID.
4015401 Invalid Access Token Access Token expired or incorrect.
4035400 Transaction Expired Transaction to be updated has expired or is not active.
4035414 Insufficient Fund Your balance is insufficient for this transaction.
4045401 Invalid Request Incorrect value for parameter.
4045413 Invalid Amount, Amount must be equal with total price item details Error in value parameter amount and price in item detail.
4095400 Conflict Error in External ID.

Debit Payment Notify (CALLBACK)

Duitku SNAP API Payment Sequence Diagram

Payment is a webhook or notification when the user has already paid. To receive this information, you need to create an API to receive the notification. Here are the things you need to do when you receive payment.

  1. Secure: you need to make your payment secure. Because the payment information just will always be through this API. We need to ensure a robust and secure environment. You might see the image of the sequence diagram at the top of this page.
    1. Whitelist Duitku IP if it's needed. IP range : 182.23.85.0/28 103.177.101.177/28
    2. Always validate the signature.
    3. Optionally you may check through Debit Payment Status to make sure that your user has already paid the transaction.
  2. Update: you need to update your transaction status or you might register the payment on your transaction.

Method : HTTP POST

Type : application/json

Url : https://yourdomain.com/v1.0/debit/notify

Endpoint : /v1.0/debit/notify

Service Code : 56

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to asymmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

The value used must correspond to the transaction details generated earlier. The value should be OL, SA, DA, or SL. OL

Body :

{
    "originalReferenceNo": "DXX116FL4KD00EBRDE5",
    "originalPartnerReferenceNo": "BMA-140",
    "latestTransactionStatus": "00",
    "amount": {
        "value": "2001.00",
        "currency": "IDR"
    },
    "additionalInfo": {
        "productDetails": "tes product",
        "additionalParam": "tes 123",
        "paymentMethod": "OL",
        "publisherOrderId": "OLZQ476GYOYZBSREF",
        "merchantUserId": "[email protected]",
        "settlementDate": "2022-11-20"
    }
}
Parameter Type Required Description Example
originalPartnerReferenceNo string(64)

The value comes from the PartnerReferenceNo parameter in the debit payment response. INV1708656785
originalReferenceNo string(64)

The value comes from the ReferenceNo parameter in the debit payment response. D00XXXWIG5BV1WW8F3RMF
latestTransactionStatus String(2)

Status code of the transaction. 00
amount Object

See the table below.
additionalInfo Object

See the table below.

amount

Parameter Type Required Description Example
value String

ISO4217
with 2 decimal.
10000.00
currency String(3)

Currency code, only receive IDR. IDR

additionalInfo

Parameter Type Required Description Example
productDetails String(50)

Description about product/service on sale. Tes payment
additionalParam String(255)

Additional parameter for merchant purpose.
paymentMethod String(2)

Payment method. OL
publisherOrderId String(30)

Unique transaction payment number from Duitku. OLZQ476GYOYZBSREF
merchantUserId String(255)

Customer's username or email on your site. [email protected]
settlementDate String(10)

Settlement date estimation information. Format: YYYY-MM-DD 2023-07-25

Response :

{
    "responseCode": "2005600",
    "responseMessage": "Successful",
}
Code Message Description
2005600 Successful Successfully processed and obtained data.
4005601 Invalid Field Format {fieldName} Incorrect value for parameter {fieldName}.
4005602 Invalid Mandatory Field {fieldName} Parameter {fieldName} is missing.
4015600 Unauthorized Signature Error in Signature.
4015601 Invalid Access Token Expired or incorrect Access Token.
4045614 Bill already paid Bill has already been paid.
4095600 Conflict Error in External ID.
5005600 General Error Error occurred during request processing.
5045600 Time Out Expired time.

Debit Payment Status

Duitku SNAP API Direct Debit

This API will help you to inquire about the payment status. As you can see in the sequence above. You might need to inquire when there is a confirmation payment from the user. Or as security optional you might inquire about status after receiving Debit Payment Notify. It helps you to make sure the payment status is genuine.

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/debit/v1.0/debit/status

Production : https://snap.duitku.com/merchant/debit/v1.0/debit/status

Service Code : 55

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

The value used must correspond to the transaction details generated earlier. The value should be OL, SA, DA, or SL. OL
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Body :

{
    "originalPartnerReferenceNo": "INV1708656785",
    "originalReferenceNo": "D00XXXWIG5BV1WW8F3RMF",
    "serviceCode": "55"
}
Parameter Type Required Description Example
originalPartnerReferenceNo string(64)

The value comes from the PartnerReferenceNo parameter in the debit payment response. INV1708656785
originalReferenceNo string(64)

The value comes from the ReferenceNo parameter in the debit payment response. D00XXXWIG5BV1WW8F3RMF
serviceCode string(2)

Transaction type indicator (service code for requesting transaction debit status). 55

Response :

{
    "responseCode": "2005500",
    "responseMessage": "SUCCESS",
    "originalReferenceNo": "D0XX17PGP6GGKB86UBQM",
    "originalPartnerReferenceNo": "12313131313131",
    "serviceCode": "55",
    "latestTransactionStatus": "00",
    "transactionStatusDesc": "Success",
    "transAmount": {
        "value": "1000.00",
        "currency": "IDR"
    }
}
Code Message Description
2005500 SUCCESS Successfully processed.
2005501 Invalid Token:Anda Tidak Memiliki Akses Error in Request credentialCode.
4005502 Missing Mandatory Field {originalPartnerReferenceNo} Parameter originalPartnerReferenceNo is missing.
4005502 Missing Mandatory Field {originalReferenceNo} Parameter originalReferenceNo is missing.
4005502 Missing Mandatory Field {serviceCode} Parameter serviceCode is missing.
4005502 Invalid Mandatory Header X-EXTERNAL-ID Parameter X-EXTERNAL-ID is missing.
4005502 Invalid Mandatory Header CHANNEL-ID Parameter CHANNEL-ID is missing.
4015500 Unauthorized Signature Error in Signature.
4015500 Unauthorized stringToSign Error in Signature.
4015500 Unauthorized Client Error in PARTNER-ID.
4015501 Invalid Access Token Expired or incorrect Access Token.
4045501 Invalid Request Format error during request.
5005501 Internal Server Error Error occurred during request processing.

Transactions status

For detail of response latestTransactionStatus See the table below.

Status Description
00 Successful
03 Pending
04 Refunded
06 Failed
07 Not Found

Debit Payment Refund

Duitku SNAP API Direct Refund

The API service used for refunds from completed transactions.

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/debit/v1.0/debit/refund

Production : https://snap.duitku.com/merchant/debit/v1.0/debit/refund

Service Code : 58

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

The value used must correspond to the transaction details generated earlier. The value should be OL, SA, DA, or SL. OL
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Body :

{
    "partnerRefundNo": "RFD-143",
    "originalPartnerReferenceNo": "INV-143",
    "originalReferenceNo": "DXX01OYA8GFJXA130B1P",
    "refundAmount": {
        "value": "2001.00",
        "currency": "IDR"
    }
}
Parameter Type Required Description Example
partnerRefundNo String(64)

Unique code generate from merchant. RFD-143
originalPartnerReferenceNo string(64)

The value comes from the PartnerReferenceNo parameter in the debit payment response. INV1708656785
originalReferenceNo string(64)

The value comes from the ReferenceNo parameter in the debit payment response. D00XXXWIG5BV1WW8F3RMF
refundAmount Object

See the table below.

amount

Parameter Type Required Description Example
value String

ISO4217
with 2 decimal.
10000.00
currency String(3)

Currency code, only receive IDR. IDR

Response :

{
    "responseCode": "2005800",
    "responseMessage": "SUCCESS",
    "originalReferenceNo": "D0001OYA8GFJXA130B1P",
    "originalPartnerReferenceNo": "INV-143",
    "partnerRefundNo": "RFD-143",
    "refundTime": "2023-03-01T10:08:45Z",
    "refundNo": "REFUND-OLOSFPBRGMNFI6RJS-1677665317584"
}
Code Message Description
2005800 Successful Successfully processed.
4005802 Invalid Mandatory Header X-EXTERNAL-ID Parameter X-EXTERNAL-ID is missing.
4005802 Invalid Mandatory Header CHANNEL-ID Parameter CHANNEL-ID is missing.
4015800 Unauthorized Signature Error in Signature.
4015800 Unauthorized stringToSign Error in Signature.
4015800 Unauthorized Client Error in PARTNER-ID.
4015801 Invalid Access Token Expired or incorrect Access Token.
5005801 Internal Server Error Error occurred during request processing.

QRIS

Generate QR MPM

Duitku SNAP API QR MPM

API Generate QR MPM (Merchant Presented Mode) is an API service that can be used by merchants to obtain a QR code. The merchant can then display the QR code to accept payments from customers by allowing them to scan it using the organizer's application.

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/qris/v1.0/qr/qr-mpm-generate

Production : https://snap.duitku.com/merchant/qris/v1.0/qr/qr-mpm-generate

Service Code : 47

Header :

{
    "partnerReferenceNo": "INV1709543217",
    "validityPeriod": "2022-09-16T13:00:00+07:00",
    "amount": {
        "value": "321.00",
        "currency": "IDR"
    },
    "additionalInfo": {
        "productDetails": "Tes pembayaran Qris Duitku",
        "additionalParam": "test additional param",
        "phoneNumber": "08221XXXXXXXX",
        "email": "[email protected]",
        "returnUrl": "http:\/\/example.com\/return",
        "itemDetails": [
            {
                "name": "Test Item 1",
                "price": 101,
                "quantity": 1
            },
            {
                "name": "Test Item 2",
                "price": 220,
                "quantity": 1
            }
        ],
        "customerDetail": {
            "firstName": "John",
            "lastName": "Doe",
            "email": "[email protected]",
            "phoneNumber": "08221XXXXXXXX",
            "billingAddress": {
                "firstName": "John",
                "lastName": "Doe",
                "address": "Jl. Kembangan Raya",
                "city": "Jakarta",
                "postalCode": "11530",
                "phone": "08221XXXXXXXX",
                "countryCode": "ID"
            },
            "shippingAddress": {
                "firstName": "John",
                "lastName": "Doe",
                "address": "Jl. Kembangan Raya",
                "city": "Jakarta",
                "postalCode": "11530",
                "phone": "08221XXXXXXXX",
                "countryCode": "ID"
            }
        }
    }
}
Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

Below is the list of values that can be used:
SP(ShopeePay)
GQ(GudangVoucher)
DQ(Dana)
NQ(Nobu)
SP
Authorization string

Authentication with bearer token. Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Request Body:

Parameter Type Required Description Example
partnerReferenceNo String(64)

Transaction number from merchant. INV123456
validityPeriod String(4)

Transaction expiry time on ISO-8601. 2022-09-16T13:00:00+07:00
additionalInfo Object

See the table additionalInfo below.
amount Object

See the table amount below.

additionalInfo

Parameter Type Required Description Example
productDetails String(255)

Description about product/service on sale.
phoneNumber String(15)

Customer's phone number. 0857181XX
email String(60)

Customer's email. [email protected]
additionalParam String(255)

Additional parameter for merchant purpose.
returnUrl String(255)

Link to redirect after transaction is completed or cancelled. http://example.com/return
itemDetails object

See the table itemDetails below.
customerDetail object

See the table customerDetail below.

Item Details

Parameter Type Required Description Example
name string(255)

Name of the item. Apel
quantity integer

Quantity of the item bought 10
price integer

Price of the Item. Note: Don't add decimal. 50000

Customer Detail

Parameter Type Required Description Example
firstName string(255)

Customer's first name. John
lastName string(255)

Customer's last name. Doe
email string(255)

Customer's email. [email protected]
phoneNumber string(255)

Customer's phone number. 08123456789
billingAddress object

See the table address below
shippingAddress object

See the table address below

Address

Parameter Type Required Description Example
firstName string(255)

Customer's first name. John
lastName string(255)

Customer's last name. Doe
address string(255)

Billing address or shipping address. Jl. Kembangan Raya
city string(255)

City of the address. Jakarta
postalCode string(255)

Postal code of the address. 11530
phone string(255)

Phone number for billing or shipping. 08123456789
countryCode string(255)

ISO 3166-1 alpha-3. ID

amount

Parameter Type Required Description Example
value String

ISO4217
with 2 decimal.
10000.00
currency String(3)

Currency code, only receive IDR. IDR

Response :

{
  "partnerReferenceNo": "INV1709717052",
  "referenceNo": "D1XXXXXXOWPHSWXXWTW4MP5",
  "redirectUrl": "https://sandbox.duitku.com/TopUp/v2/
    TopUpQrisPaymentPage.aspx?reference=GQ24ELJK4A78KUGJV40",
  "responseCode": "2004700",
  "responseMessage": "SUCCESS",
  "qrContent": "00020101021226730021COM.GUDANGVOUCHER.WWW0118
  93600916300373281602151142230919000010303UME51450015ID.OR.G
  PNQR.WWW02151142230919000010303UME5204970553033605403321580
  2ID5906DUITKU6015JAKARTA SELATAN610511530624101066527840520
  24030627840636662CSX0703A016304EA56"
}
Code Message Description
2004700 Success Transaction success generated.
4004700 Service Not Implemented Service is not registered on request CHANNEL-ID.
4004701 Invalid Field Format Incorrect value for that parameter.
4004702 Missing Mandatory Field, {PartnerReferenceNo} Parameter PartnerReferenceNo is missing.
4004702 Missing Mandatory Field, {Amount} Parameter Amount is missing.
4004702 Missing Mandatory Field, {AdditionalInfo.ReturnUrl} Parameter AdditionalInfo.ReturnUrl is missing.
4014700 Unauthorized Signature Error in Signature.
4014700 Unauthorized stringToSign Error in Signature.
4014700 Unauthorized Client Error in PARTNER-ID.
4014701 Invalid Access Token Access Token expired or incorrect.
4044701 Invalid Request Incorrect value for parameter.
4044713 Invalid Amount, Amount must be equal with total price item details Error in value parameter amount and price in item detail.
4094700 Conflict Error in External ID.
4094700 The expired in field must be at least 30. For the validityPeriod you can set it to a minimum of 30 minutes

Payment Notify (CALLBACK)

Duitku SNAP API Payment QR NOTIFY

Payment is a webhook or notification when the user has already paid. To receive this information, you need to create an API to receive the notification. Here are the things you need to do when you receive payment.

  1. Secure: you need to make your payment secure. Because the payment information just will always be through this API. We need to ensure a robust and secure environment. You might see the image of the sequence diagram at the top of this page.
    1. Whitelist Duitku IP if it's needed. IP range : 182.23.85.0/28 103.177.101.177/28
    2. Always validate the signature.
    3. Optionally you may check through Query Payment to make sure that your user has already paid the transaction.
  2. Update: you need to update your transaction status or you might register the payment on your transaction.

Method : HTTP POST

Type : application/json

Url : https://yourdomain.com/v1.0/qr/qr-mpm-notify

Endpoint : /v1.0/qr/qr-mpm-notify

Service Code : 52

Header :

Parameter Type Required Description Example
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

The value used must correspond to the transaction details generated previously. Below is the list of values that can be used: SP,GQ,DQ or NQ SP

Body :

{
    "originalReferenceNo": "DXX116FL4KD00EBRDE5",
    "originalPartnerReferenceNo": "BMA-140",
    "latestTransactionStatus": "00",
    "amount": {
        "value": "2001.00",
        "currency": "IDR"
    },
    "additionalInfo": {
        "productDetails": "tes product",
        "additionalParam": "tes 123",
        "issuerCode": "93600916",
        "paymentMethod": "GQ",
        "publisherOrderId": "GQ241EKHWNVPFBC86LV",
        "settlementDate": "2024-04-20"
    }
}
Parameter Type Required Description Example
originalPartnerReferenceNo string(64)

The value comes from the PartnerReferenceNo parameter in the debit payment response. INV1708656785
originalReferenceNo string(64)

The value comes from the ReferenceNo parameter in the debit payment response. D00XXXWIG5BV1WW8F3RMF
latestTransactionStatus String(2)

Status code of the transaction. 00
amount Object

See the table below.
additionalInfo Object

See the table below.

amount

Parameter Type Required Description Example
value String

ISO4217
with 2 decimal.
10000.00
currency String(3)

Currency code, only receive IDR. IDR

additionalInfo

Parameter Type Required Description Example
productDetails String(50)

Description about product/service on sale. Tes payment
additionalParam String(255)

Additional parameter for merchant purpose.
issuerCode String(15)

The payment issuer used. 972131
publisherOrderId String(30)

Unique transaction payment number from Duitku. GQ241EKHWNVPFBC86LV
paymentMethod String(40)

Payment method code for being used. GQ
settlementDate String(10)

Settlement date estimation information. Format: YYYY-MM-DD 2023-07-25

Response :

{
    "responseCode": "2005200",
    "responseMessage": "Successful",
}
Code Message Description
2005200 Successful Successfully processed and obtained data.
4005201 Invalid Field Format {fieldName} Incorrect value for parameter {fieldName}.
4005202 Invalid Mandatory Field {fieldName} Parameter {fieldName} is missing.
4015200 Unauthorized Signature Error in Signature.
4015201 Invalid Access Token Expired or incorrect Access Token.
4045214 Bill already paid Bill has already been paid.
4095200 Conflict Error in External ID.
5005200 General Error Error occurred during request processing.
5045200 Time Out Expired time.

Query Payment

Duitku SNAP API QR MPM QUERY

This API will help you to inquire about the payment status. As you can see in the sequence above. You might need to inquire when there is a confirmation payment from the user. Or as security optional you might inquire about status after receiving Payment Notify. It helps you to make sure the payment status is genuine.

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/qris/v1.0/qr/qr-mpm-query

Production : https://snap.duitku.com/merchant/qris/v1.0/qr/qr-mpm-query

Service Code : 51

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

The value used must correspond to the transaction details generated previously. Below is the list of values that can be used: SP,GQ,DQ or NQ SP
Authorization string

Authentication with bearer token. Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Body :

{
    "originalPartnerReferenceNo": "INV1708656785",
    "originalReferenceNo": "D00XXXWIG5BV1WW8F3RMF",
    "serviceCode": "51"
}
Parameter Type Required Description Example
originalPartnerReferenceNo string(64)

The value comes from the PartnerReferenceNo parameter in the debit payment response. INV1708656785
originalReferenceNo string(64)

The value comes from the ReferenceNo parameter in the debit payment response. D00XXXWIG5BV1WW8F3RMF
serviceCode string(2)

Transaction type indicator (service code for requesting transaction debit status). 51

Response :

{
  "responseCode": "2005100",
  "responseMessage": "SUCCESS",
  "originalReferenceNo": "DXXXX424A5WNCS7ZDKAHVP5",
  "originalPartnerReferenceNo": "INV1709787234",
  "serviceCode": "51",
  "transactionStatusDesc": "Success",
  "latestTransactionStatus": "00",
  "amount": {
    "value": "321.00",
    "currency": "IDR"
  }
}
Code Message Description
2005100 Success Transaction successfully processed.
2005101 Invalid Token:Anda Tidak Memiliki Akses Error in Request credentialCode.
4005101 Invalid Field Format Incorrect value for that parameter.
4005102 Missing Mandatory Field, {originalPartnerReferenceNo} Parameter originalPartnerReferenceNo is missing.
4005102 Missing Mandatory Field, {originalReferenceNo} Parameter originalReferenceNo is missing.
4005102 Missing Mandatory Field, {serviceCode} Parameter serviceCode is missing.
4005102 Invalid Mandatory Header X-EXTERNAL-ID Parameter X-EXTERNAL-ID is missing.
4005102 Invalid Mandatory Header CHANNEL-ID Parameter CHANNEL-ID is missing.
4015100 Unauthorized Signature Error in Signature.
4015100 Unauthorized stringToSign Error in Signature.
4015100 Unauthorized Client Error in PARTNER-ID.
4015101 Invalid Access Token Expired or incorrect Access Token.
4045101 Invalid Request Format error during request.
5005101 Internal Server Error Error occurred during request processing.

Transactions status

For detail of response latestTransactionStatus See the table below.

Status Description
00 Successful
03 Pending
04 Refunded
06 Failed
07 Not Found

Refund Payment

Duitku SNAP API QR MPM REFUND

The API service used for refunds from completed transactions.

Method : HTTP POST

Type : application/json

Development : https://snapdev.duitku.com/merchant/qris/v1.0/qr/qr-mpm-refund

Production : https://snap.duitku.com/merchant/qris/v1.0/qr/qr-mpm-refund

Service Code : 78

Header :

Parameter Type Required Description Example
Content-Type string

String represents indicate the media type of the resource. application/json
X-TIMESTAMP string

ISO-8601 2022-09-16T13:00:00+07:00
X-SIGNATURE string

Refer to symmetric.
X-PARTNER-ID string

Project ID. DXXXX
X-EXTERNAL-ID string

Unique request ID.
CHANNEL-ID string

The value used must correspond to the transaction details generated previously. Below is the list of values that can be used: SP,GQ,DQ or NQ SP
Authorization string

Authentication with bearer token Bearer ZGMyNDA3NWQtNmM4Ny00NGNiLTQ2NTAtMDhkYWMxNTAzNzY0

Body :

{
    "partnerRefundNo": "RFD-143",
    "originalPartnerReferenceNo": "INV-143",
    "originalReferenceNo": "DXX01OYA8GFJXA130B1P",
    "refundAmount": {
        "value": "2001.00",
        "currency": "IDR"
    }
}
Parameter Type Required Description Example
partnerRefundNo String(64)

Unique code generate from merchant. RFD-143
originalPartnerReferenceNo string(64)

The value comes from the PartnerReferenceNo parameter in the debit payment response. INV1708656785
originalReferenceNo string(64)

The value comes from the ReferenceNo parameter in the debit payment response. D00XXXWIG5BV1WW8F3RMF
refundAmount Object

See the table below.

amount

Parameter Type Required Description Example
value String

ISO4217
with 2 decimal.
10000.00
currency String(3)

Currency code, only receive IDR. IDR

Response :

{
    "responseCode": "2007800",
    "responseMessage": "SUCCESS",
    "originalReferenceNo": "D0001OYA8GFJXA130B1P",
    "originalPartnerReferenceNo": "INV-143",
    "partnerRefundNo": "RFD-143",
    "refundTime": "2023-03-01T10:08:45Z",
    "refundNo": "REFUND-OLOSFPBRGMNFI6RJS-1677665317584"
}
Code Message Description
2007800 Successful Successfully processed.
4007802 Invalid Mandatory Header X-EXTERNAL-ID Parameter X-EXTERNAL-ID is missing.
4007802 Invalid Mandatory Header CHANNEL-ID Parameter CHANNEL-ID is missing.
4017800 Unauthorized Signature Error in Signature.
4017800 Unauthorized stringToSign Error in Signature.
4017800 Unauthorized Client Error in PARTNER-ID.
4017801 Invalid Access Token Expired or incorrect Access Token.
5007801 Internal Server Error Error occurred during request processing.

Issuer List (QRIS)

Code Issuer
93600999 AHDI
93600947 Aladin Syariah
93600567 Allo Bank Indonesia
93600531 Amar
93600822 Astrapay
93600116 Bank Aceh Syariah
93600037 Bank Artha Graha Internasional
93600133 Bank BPD Bengkulu
93600124 Bank BPD Kalimantan Timur dan Kalimantan Utara
93600161 Bank Ganesha
93600513 Bank Ina Perdana
93600113 Bank Jateng
93600123 Bank Kalbar
93600122 Bank Kalsel
93600441 Bank KB Bukopin
93600121 Bank Lampung
93600157 Bank Maspion
93600553 Bank Mayora
93600548 Bank Multiarta Sentosa
93600490 Bank Neo Commerce
93600128 Bank NTB Syariah
93600019 Bank Panin
93600132 Bank Papua
93600115 Bank Pembangunan Daerah Jambi
93600494 Bank Raya
93600119 Bank Riau Kepri
93600523 Bank Sahabat Sampoerna
93600152 Bank Shinhan
93600126 Bank Sulsel
93600120 Bank Sumselbabel
93600023 Bank UOB Indonesia
93600808 Bayarind
93600014 BCA
93600536 BCA Syariah
93600501 BCAD
93600815 Bimasakti Multi Sinergi
93600110 BJB
93600425 BJB Syariah
93600919 BluePay
93600009 BNI
93600129 BPD Bali
93600112 BPD DIY
93600130 BPD NTT
93600114 BPD-JATIM
93600002 BRI
93600422 BRIS Pay
93600200 BTN
93600076 Bumi Arta
93600031 Citibank
93600950 Commonwealth
93600915 Dana
93600011 Danamon
93600046 DBS MAX QRIS
93600111 DKI
93600899 Doku
93600998 DSP
93600827 Fello
93600777 Finpay
93600813 GAJA
93600914 Go-Pay
93600916 Gudang Voucher
93600484 Hana bank
93600789 IMkas
93600920 Isaku
93600542 JAGO
93600213 Jenius
93600812 Kaspro
93600911 LinkAja
93600008 Mandiri Pay
93600016 Maybank
93600426 Mega
93600821 Midazpay
93600485 Motion Banking
93600147 Muamalat
93600118 Nagari
93600814 Netzme
93600022 Niaga
93600503 Nobu
93600028 OCBC
93600811 OTTOCASH
93600912 OVO
93600820 PAC Cash
93600818 Paydia
93600917 Paytrend
93600013 Permata
93608161 POS Indonesia
93600167 QNB Indonesia
93600921 Saldomu
93600535 Seabank
93600918 ShopeePay
93600153 Sinarmas
93600816 SPIN
93600451 Syariah Indonesia
93600898 T-Money
93600828 TrueMoney
93600835 Virgo
93600830 YODU
93600817 Yukk
93600825 Zipay

Testing

After you go through the integration steps above, you can check your payment. The following is a list of payment trials that can be used in the Sandbox Environment:

VA

Demo transaction virtual account sandbox Click-here.

E-Wallet

Shopee

For shopee testing you can download shopeeapp staging apk here.

Gudang Voucher

For Gudang Voucher can use within virtual account demo success.

Changelog

Version 1.0