Skip to main content

Authentication Symmetric SNAP

To ensure secure and reliable communication between your system and DANA's SNAP API, Bank Indonesia mandates the use of Symmetric Signature Authentication combined with a B2B Access Token. This method leverages cryptographic keys to verify the identity of the sender and protect data integrity during transactions.

Overview

In the asymmetric signature scheme:

  • Private Key: Used by you (the merchant) to digitally sign API requests.
  • Public Key: Shared with DANA to verify the authenticity of your requests.
  • B2B Access Token: A temporary token retrieved via the Authorization Token Request API, used to authorize transactional API requests.

By signing your request data with your private key, you provide a secure proof that the request originates from an authorized source. This process is critical to meeting the regulatory standards mandated by Bank Indonesia.

DANA Public Key

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnaKVGRbin4Wh4KN35OPh
ytJBjYTz7QZKSZjmHfiHxFmulfT87rta+IvGJ0rCBgg+1EtKk1hX8G5gPGJs1htJ
5jHa3/jCk9l+luzjnuT9UVlwJahvzmFw+IoDoM7hIPjsLtnIe04SgYo0tZBpEmkQ
vUGhmHPqYnUGSSMIpDLJDvbyr8gtwluja1SbRphgDCoYVXq+uUJ5HzPS049aaxTS
nfXh/qXuDoB9EzCrgppLDS2ubmk21+dr7WaO/3RFjnwx5ouv6w+iC1XOJKar3CTk
X6JV1OSST1C9sbPGzMHZ8AGB51BM0mok7davD/5irUk+f0C25OgzkwtxAt80dkDo
/QIDAQAB
-----END PUBLIC KEY-----

To obtain Production DANA Public Key, please contact the DANA integration team through our Discord channel .


Obtaining Testing Credentials

  1. Visit https://dashboard.dana.id/sandbox/
  2. You will receive the following credentials:
    • URL API Sandbox
    • Merchant ID
    • Client ID known as X-PARTNER-ID
    • Client Secret
    • Public Key
    • Private Key

Using the Credential

You will receive two credentials: a Private Key and a Public Key.

The Private Key is used to authenticate and communicate securely with DANA. Keep this key confidential and do not share it. The Public Key must be shared with DANA by uploading it through the Merchant Portal during form submission. After successful submission, you will receive other credentials, including Merchant ID, Client ID (also known as X-PARTNER-ID), and Client Secret.


Symmetric Digital Signatures (X-SIGNATURE)

SNAP APIs require a specific signature string to be generated for a field called X-SIGNATURE. This signature will be validated by DANA using your public key to confirm the authenticity of the request.


Required DataFormat Example
X-CLIENT-KEY
Unique identifier for partner was generated by DANA, or known as clientId
82150823919040624621823174737537
X-TIMESTAMP
Transaction date time, in format YYYY-MM-DDTHH:mm:ss+07:00 (GMT+7)
2022-11-30T09:45:35+07:00

The following steps are used to generate the asymmetric key used in the signature process for Production environment:

Step 1: Compose the string to sign

Compose the string like the following format:

Format for string to sign
<X-CLIENT-KEY> +|+ <X-TIMESTAMP>
Example of composed string
82150823919040624621823174737537|2020-12-18T15:06:00+07:00
Step 2: Result string to sign

Take the string from Step 2 and apply SHA-256 with RSA-2048 encryption using your PKCS#8 private key. Then, encode the final result in Base64.

Example string to sign
laQUFqUd7k4NiL1ntrkyIRUSYA+Mhr2UEaDRHNt7dbySZ+FiBpf0CKyZNakgGZ1ypfTmAZuHiOzbQdpDfrmwE4TJ471Gv3Ly7VE4L0t3TRMz8p21Iczk0rNMINAvketkaRrFL6+xDH2q6YLdDv/R5vpDH5hmOyGiIIApfzcOxzUxIcumsku5HT+oyhCUsnCDCtmSUv0xah8ghPhrZzMYAzTnFDy/fJZaa2dYyhm+7HULfG6ErqDTI1tRkmPczDmm+ufPP17VKgXZCsSKXa6e3Zo6ob1MO6PIjm5Agj/TftaDtmEt9cFUT9djWzOKFrTp6OI3hcbphUwidGP81XRvtQ==
Step 3: Add the Signature to the HTTP Header “X-SIGNATURE“

Place the generated Base64 signature string into the X-SIGNATURE HTTP header when calling the Authorization Token Request API.

Example X-SIGNATURE
X-SIGNATURE: laQUFqUd7k4NiL1ntrkyIRUSYA+Mhr2UEaDRHNt7dbySZ+FiBpf0CKyZNakgGZ1ypfTmAZuHiOzbQdpDfrmwE4TJ471Gv3Ly7VE4L0t3TRMz8p21Iczk0rNMINAvketkaRrFL6+xDH2q6YLdDv/R5vpDH5hmOyGiIIApfzcOxzUxIcumsku5HT+oyhCUsnCDCtmSUv0xah8ghPhrZzMYAzTnFDy/fJZaa2dYyhm+7HULfG6ErqDTI1tRkmPczDmm+ufPP17VKgXZCsSKXa6e3Zo6ob1MO6PIjm5Agj/TftaDtmEt9cFUT9djWzOKFrTp6OI3hcbphUwidGP81XRvtQ==

Before generate the signature, prepare the required data:

Required DataFormat Example
HTTP METHOD
Method on each API, for instance GET, POST, PUT, PATCH, and DELETE
POST
RELATIVE PATH URL
URL on each API
/v1.0/emoney/account-inquiry.htm
<B2B ACCESS TOKEN>
B2B Access Token, obtained from Authorization Token Request API
DlHTC8U5urS6VDsWkNMv3ealeldgjR8H5CvYYfD8n5WxOmo1In6EkfhALRzW94HO8q+KIvG9HZfpThRHGnbQfL8Ok5tCIRFWIkGV8nJkjj087HEjnVXZIWWF2SQFY6lJX2/I54hG1MNDKeSqwXwy5ZhbU38r6X4vSbaUFyAP/dCRMAJO/ewv3O8pdWNKjKTUzmCamR+em2w5A+LZsxDh7nhl8gGezQkF02V6izIJLRbT2NbnGRqbNH2pFRPOKi5nx9elpd8mHORMQ/sqKH8Gf/MGoOiWkXoTbDgAQoJdp7E2y8LWOYwLzJ7lcqhw1sJucgy0FKhgKdYwumx7jzIfUQ==
HTTP BODY
Minify request body and hash the request body with SHA-256
e9295c3253c05560273ff305d9eea6abf77fff65229bf90b1781383c09c29d98
X-TIMESTAMP
Transaction date time, in format YYYY-MM-DDTHH:mm:ss+07:00. Time must be in GMT+7 (Jakarta time)
2022-11-30T09:45:35+07:00

The following steps are used to generate the asymmetric key used in the signature process for Production environment:

Step 1: Minify the request body

Minify the request body like the following format:

Before Minify
{
"partnerReferenceNo": "2020102900000000000001",
"customerNumber": "62810987654321",
"amount": {
"value": "10000.00",
"currency": "IDR"
},
"transactionDate": "2020-12-21T14:56:11+07:00",
"additionalInfo": {
"fundType": "AGENT_TOPUP_FOR_USER_CLEARING",
"accessToken" : "fa8sjjEj813Y9JGoqwOeOPWbnt4CUpvIJbU1mMU4a11MNDZ7Sg5u9a"
}
}
After Minify
{"partnerReferenceNo":"2020102900000000000001","customerNumber":"62810987654321","amount":{"value":"10000.00","currency":"IDR"},"transactionDate":"2020-12-21T14:56:11+07:00","additionalInfo":{"fundType":"AGENT_TOPUP_FOR_USER_CLEARING","accessToken":"fa8sjjEj813Y9JGoqwOeOPWbnt4CUpvIJbU1mMU4a11MNDZ7Sg5u9a"}} 
Step 2: Lowercase(HexEncode(SHA-256(RequestBody)))

The following is an example of a Lowercase SHA-256 HexEncode of the request body, used to ensure content integrity during signature validation

Example Lowercase(HexEncode(SHA-256(RequestBody)))
e9295c3253c05560273ff305d9eea6abf77fff65229bf90b1781383c09c29d98
Step 3: Compose the string to sign

Compose the string like the following format:

Format string to sign
<HTTP METHOD> +:+ <RELATIVE PATH URL> +:+ <B2B ACCESS TOKEN> +:+ LowerCase(HexEncode(SHA-256(Minify(<HTTP BODY>)))) +:+ <X-TIMESTAMP>
Example of composed string
POST:/v1.0/emoney/account-inquiry.htm:DlHTC8U5urS6VDsWkNMv3ealeldgjR8H5CvYYfD8n5WxOmo1In6EkfhALRzW94HO8q+KIvG9HZfpThRHGnbQfL8Ok5tCIRFWIkGV8nJkjj087HEjnVXZIWWF2SQFY6lJX2/I54hG1MNDKeSqwXwy5ZhbU38r6X4vSbaUFyAP/dCRMAJO/ewv3O8pdWNKjKTUzmCamR+em2w5A+LZsxDh7nhl8gGezQkF02V6izIJLRbT2NbnGRqbNH2pFRPOKi5nx9elpd8mHORMQ/sqKH8Gf/MGoOiWkXoTbDgAQoJdp7E2y8LWOYwLzJ7lcqhw1sJucgy0FKhgKdYwumx7jzIfUQ==:e9295c3253c05560273ff305d9eea6abf77fff65229bf90b1781383c09c29d98:2022-11-30T09:45:35+07:00
Step 4: Result string to sign

Take the string from Step 4 and apply HMAC_SHA512 hashing using the secret key provided by DANA. Then, encode the final result in Base64.

Example result
iSkd8HPpdeeQSnq5lSRM46l8w/C4ZhNq7ordOv2dfDC0A0rGWxqz+9j864gcuVhu0tgTHJUuV9k5wsluig/sJ4W5Yy1EZPzbpeeUwFxSK0WgnW5LLq/h5RQAgVEyJL5MI1KrByzBQIv+5IYgKaLFmTLeo4xy7ToLJKND/6Ja+HRuo+SpnzNA2NNJEcc+PI87pAo0yXItZhjUXhyz9rkv0P8Ra8tDar2asHVGxA5BiGthy/eyPbe9VYavfMrOKAZpISw9VVoZ1axHgqvLCVEPodIx45nWUqF96PUyIB2H51VZCTPaxeefpdKzgPR0Ji24zIeFhaowk7i2znPnNDINvA==
Step 5: Add the Signature to the HTTP Header “X-SIGNATURE“

Place the generated signature into your request header under the field X-SIGNATURE.

Example X-SIGNATURE
X-SIGNATURE: iSkd8HPpdeeQSnq5lSRM46l8w/C4ZhNq7ordOv2dfDC0A0rGWxqz+9j864gcuVhu0tgTHJUuV9k5wsluig/sJ4W5Yy1EZPzbpeeUwFxSK0

Validating Signatures

Here's a guideline for validating a digital signature in API requests. Follow these steps to ensure the authenticity and integrity of the request.


Step 1: Get the Digital Signature
Retrieve the digital signature from the HTTP header under the key X-SIGNATURE.

Example
X-SIGNATURE: laQUFqUd7k4NiL1ntrkyIRUSYA+Mhr2UEaDRHNt7dbySZ+FiBpf0CKyZNakgGZ1ypfTmAZuHiOzbQdpDfrmwE4TJ471Gv3Ly7VE4L0t3TRMz8p21Iczk0rNMINAvketkaRrFL6+xDH2q6YLdDv/R5vpDH5hmOyGiIIApfzcOxzUxIcumsku5HT+oyhCUsnCDCtmSUv0xah8ghPhrZzMYAzTnFDy/fJZaa2dYyhm+7HULfG6ErqDTI1tRkmPczDmm+ufPP17VKgXZCsSKXa6e3Zo6ob1MO6PIjm5Agj/TftaDtmEt9cFUT9djWzOKFrTp6OI3hcbphUwidGP81XRvtQ==

Step 2: Compose the String to Verify
Compose the string like the following format:

Format for string to sign
<X-CLIENT-KEY> +|+ <X-TIMESTAMP>

Step 3: Verify the Signature
Use SHA-256 with RSA-2048 encryption to verify the signature. You will need to use the Public Key (which is paired with the private key used by the sender) to decrypt and verify that the signature in the X-SIGNATURE header matches the string you composed in Step 2.

Step 4: Consume the Request
If the verification is successful (the signature matches), proceed with processing the request. If the verification fails, reject the request.


Step 1: Get the Digital Signature
Retrieve the digital signature from the HTTP header under the key X-SIGNATURE.

Example
X-SIGNATURE:iSkd8HPpdeeQSnq5lSRM46l8w/C4ZhNq7ordOv2dfDC0A0rGWxqz+9j864gcuVhu0tgTHJUuV9k5wsluig/sJ4W5Yy1EZPzbpeeUwFxSK0

Step 2: Compose the String to Verify
Compose the string like the following format:

Format for string to sign
<HTTP METHOD> + ":" + <RELATIVE PATH URL> + ":" + <B2B ACCESS TOKEN> + ":" + LowerCase(HexEncode(SHA-256(Minify(<HTTP BODY>)))) + ":" + <X-TIMESTAMP>
Example
POST:/v1.0/emoney/account-inquiry.htm:DlHTC8U5urS6VDsWkNMv3ealeldgjR8H5CvYYfD8n5WxOmo1In6EkfhALRzW94HO8q+KIvG9HZfpThRHGnbQfL8Ok5tCIRFWIkGV8nJkjj087HEjnVXZIWWF2SQFY6lJX2/I54hG1MNDKeSqwXwy5ZhbU38r6X4vSbaUFyAP/dCRMAJO/ewv3O8pdWNKjKTUzmCamR+em2w5A+LZsxDh7nhl8gGezQkF02V6izIJLRbT2NbnGRqbNH2pFRPOKi5nx9elpd8mHORMQ/sqKH8Gf/MGoOiWkXoTbDgAQoJdp7E2y8LWOYwLzJ7lcqhw1sJucgy0FKhgKdYwumx7jzIfUQ==:e9295c3253c05560273ff305d9eea6abf77fff65229bf90b1781383c09c29d98:2022-11-30T09:45:35+07:00

Step 3: Generate the Expected Signature
Generate the signature from the string you composed in Step 2 by applying HMAC_SHA512 hashing using the shared Secret Key provided by DANA. Then, encode the result in Base64.

Step 4: Compare and Consume
Compare the signature you generated in Step 3 with the signature you received in the X-SIGNATURE header (from Step 1).

  • If both values are exactly the same, the request is authentic. You may consume the message.
  • If the values do not match, reject the request.

Support

Need help? contact our Merchant Support Team or join our Discord server
ask AIAI Assistant
Need help with our documentation?
Start from our frequently asked questions or feel free to ask anything else.

AI generated responses may contain mistakes.