Signature Generation

B2B Access Token Specification

B2B Access Token API header consists of the following fields:

Field NameField TypeMandatoryField Description
Content-typeStringMMedia type of the resource, i.e. application/json
X-TIMESTAMPStringMClient’s current local time in ISO-8601 format
X-SIGNATUREStringMCreated using asymmetric signature SHA256withRSA algorithm
X-CLIENT-KEYStringMClient ID
Content-type: application/json
X-TIMESTAMP: 2023-01-01T00:00:00+07:00
X-SIGNATURE: da1fa417c72d6b91c257e01e54fac824
X-CLIENT-KEY: 962489e9-de5d-4eb7-92a4-b07d44d64bf4

Asymmetric Signature SHA256withRSA

Based on the specification above, merchant should use asymmetric signature SHA256withRSA for Access Token API.

Merchant should use this formula to create X-SIGNATURE for Access Token API:
Client ID + “|” + Timestamp encrypted with merchant’s private key by using SHA256withRSA algorithm

SHA256withRSA algorithm reference
8afe58a2b2955453854b9f65d070a10ef3def877a813f8d8e427d58028398b5ea78f9fc35672a0e3d8a592ff0fc9e53bcb7f1aa478603be714aef91f52ce418430faf722e7ef1a7c87337d45c474503cb9fa70ab4371860954b3649be511737e4c1d23e10ea932c8ebab8f98468c836b899396c8c94d4f5a1a32d1141620638332310e71d752722e7a05c1b4bc4c9e5efeae26528ceba78f55c877bb3904859c9370bcc485ac3c80231a0e2b4219408958dbd3da0c815c5a847e449018e361f616bca325c3e935f79eadc6e48fd8ec04b577c2610a88da0dea580514b9394227039c0010ccbe39b3dd8461e0aa0cdb934c93b275a25b52a128d5dfd93d5341b5

For a better understanding, please refer to this sample scenario for generating signature using the formula above on B2B Access Token API:

No.Steps
1Given merchant has private key

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCVZu2WHd4z5tbe
fkAWPjbB10Lgvu1CpsuIIVtO/wrrvKeD2LArmYSf5QxeJGG8HYlVYVp8I8/EVqay
JUbcyOd4aMLQFiCambDipecCfI7ecJ0K4+2ZneWOEq9JM91ZnGtwuLVdr1X/4/Nv
yGuNvmLAyfpJkU14yZliAUqJJ656jpM+WfY+hOpcLOzUe2wzx5RV7wYCyMl7/d1i
X33afJc6kbbUaA27yjlPdY6m0+DoZ0NNaRNZS7jzfJFtVXLTg/PgvwMNlMO/5Zyw
BWIOfWsD+MHUC6P9QYrHai8ZwEf9r+GivlNsAFs4NTpw9MdPngrexJm29k1Xh4UM
HV//jB1/AgMBAAECggEADcXGyitns/4oOauGyeYjUxw+eIxxP88zfRGiIralMZUb
Fi7wEpzc2oaZbMZK0jYg1mOanU4J1a4tQMfp7+l/WRzDNL6Nc+MOKN6lXJfR7dSQ
zZO0cBBbvIyhZwymb5/ZUbNdWM0UjvnbE6d0rsTpwp77+TMxYpynDJ9U2S70ySxe
fGi7x4rK02/8xmj1fY/Ls+uoYhF4IbGJIkFvrlAdWyFvv6sCGBYxl5sPuitgQxPv
Yc7dS7HE+6nZ+wWgoIXjC4CfxHBa9u3dfu3XAnPY3xpnVsbxCAH9OOIrZPY0C/Pq
gj+EElCBChUzDiedV3XipKUweDA+64sNm5NjqlqU8QKBgQDFf5a9vHVf9r2CTOgm
z5wTrK7aTwKwCNC4zpZUxDR8k7AV2gTelabpPWqUMZyRMUPs2hyBvhEWVNKxx3qs
7BAVpmcttuS5/dLNVdhNPUC2IgZqf3jWH2aS3lkci8DATQCphrEXZ3jrNaIRtrSC
kflE+yY8YP8b7ObktgvHz39JMQKBgQDBqCsMmOsQAveIQk5FGAMxsFU9G7OIBFHo
xpwkKUCjoqGxM+YQqDvcVeXNd/HdLnmR05//eoONemuDyYy8XRoud4tpaRKU/FK7
06WdljztB5rn2+cdUbmcU0fZiRQk+WuXsopZn3GUNvA/fQOW9qs7B5Rm5W71FeGk
ZgsvlAUlrwKBgQCUgFFaLWCcXa01UpqkxCp5aLi5EfvVXWuD6mKDLlzA51PZums6
6o/shO+kqoEtczu91mrk64NxpSof3vxRFdcqUEr4xrLJXx+oocnYmhwUVxU38s1r
Q4UfHe0nV7YBYmUDE3IJRRZY1aUdaKHmI9iok6e2csCfwMwEYRYOkekFoQKBgCyy
Oa1gpfA+Hw+N7i64ShRv1FyURi2Agb8uB9+4vbiG0rbpeZIioh5KnQ19P4+DKH/l
zinTBwXiWWpDXH4lJuPOp5ierbFBQ38ibDkg8dLrTG9zK7ZypFpWRmEI6GNYReLv
TEs/J6HDxFOC8Q8ow4COUUwmbCOY90lQXAiRK1b1AoGAScK1db9X5Ct+JtnjYyzi
GYLwyPhHCQIVmEDfuvbMs74woQsrBm3dBB3b2vf9pqcSZB4WAbTQ3wCdxCJKg6MN
6eXBO1M1lcIpZjCDyiXXi7PozNmkasRDUyDFwxlnyDLdRHL3FD+dh6do32FwGLBQ
u256RIyMB13qIuqrc91Z0hM=
-----END PRIVATE KEY-----
2Given merchant wants to create a request with header:
Content-type: application/json
X-TIMESTAMP: 2023-07-31T07:10:00+07:00
X-CLIENT-KEY: G1234325-SNAP
3X-SIGNATURE value for encryption will be:
G1234325-SNAP|2023-07-31T07:10:00+07:00

*same value as X-CLIENT-KEY + “|” + X-TIMESTAMP
4By using merchant’s private key to encrypt the value with SHA256withRSA algorithm, merchant will generate
iv5YorKVVFOFS59l0HChDvPe+HeoE/jY5CfVgCg5i16nj5/DVnKg49ilkv8PyeU7y38apHhgO+cUrvkfUs5BhDD69yLn7xp8hzN9RcR0UDy5+nCrQ3GGCVSzZJvlEXN+TB0j4Q6pMsjrq4+YRoyDa4mTlsjJTU9aGjLRFBYgY4MyMQ5x11JyLnoFwbS8TJ5e/q4mUozrp49VyHe7OQSFnJNwvMSFrDyAIxoOK0IZQIlY29PaDIFcWoR+RJAY42H2FryjJcPpNfeercbkj9jsBLV3wmEKiNoN6lgFFLk5QicDnAAQzL45s92EYeCqDNuTTJOydaJbUqEo1d/ZPVNBtQ==
5Final result of merchant's header will be:
Content-type: application/json
X-TIMESTAMP: 2023-07-31T07:10:00+07:00
X-CLIENT-KEY: G1234325-SNAP
X-SIGNATURE: <SIGNATURE SAMPLE RESULT>

Transactional API Specification

Transactional API header consists of the following fields:

Field NameField TypeMandatoryField Description
Content-typeStringMMedia type of the resource, i.e. application/json
X-TIMESTAMPStringMClient’s current local time in ISO-8601 format
X-SIGNATUREStringMCreated using symmetric signature HMAC_SHA512 algorithm
AuthorizationStringMRepresents access_token of a request, received from Access Token API response
Authorization-CustomerStringCUser Access Token which GoPay will be sharing once linking is complete.

(Required only for GoPay Tokenization)
X-PARTNER-IDStringMMerchant’s partner ID
X-EXTERNAL-IDStringMMerchant’s unique ID per transaction request
CHANNEL-IDStringMMandatory field from Bank Indonesia that can take any value with correct format 5 digits numeric string
X-DEVICE-IDStringMDevice identification on which the API services are currently being accessed by the end user (customer).

Sample:
Web Application:
Mozilla / 5.0(Windows NT 10.0; Win64; x64)AppleWebKit / 537.36(KHTML, like Gecko)Chrome / 75.0.3770.100 Safari / 537.36 OPR / 62.0.3331.99

Mobile Application:
Android: android-20013adf6cdd8123f
iOS: 72635bdfd223yvjm7246nsdj34hd4559393kjh42
Content-type:application/json
X-TIMESTAMP:2020-01-01T00:00:00+07:00
X-SIGNATURE: da1fa417c72d6b91c257e01e54fac824
Authorization: Bearer gp9HjjEj813Y9JGoqwOeOPWbnt4CupvIJbU1Mmu4a11MNDZ7Sg5u9a
Authorization-Customer: Bearer gp9HjjEj813Y9JGoqwOeOPWbnt4CupvIJbU1Mmu4a11MNDZ7Sg5u9a
X-PARTNER-ID: BMRI
X-DEVICE-ID: 0987ADCASA
X-EXTERNAL-ID:12345678901234567890
CHANNEL-ID:12345

📘

X-EXTERNAL-ID behavior

Currently we have 2 usage for X-EXTERNAL-ID:

Usage #1: For account linking related endpoint (ie. get-auth, binding, unbinding),

  • If merchant sends the same request with same X-EXTERNAL-ID, then Midtrans will return an error conflict (the duration is 24 hour after the first request)

Usage #2: For payment related endpoint (ie. direct debit, auth payment, etc)

  • If merchant sends the same request with same X-EXTERNAL-ID and the previous response is success, then GoPay will return an idempotency response

Things to note as well, in account linking flow, the external-id will need to be unique for each merchants, means different merchant can use the same X-EXTERNAL-ID to get different response from different request.


Symmetric Signature HMAC_SHA512

Based on the specification above, merchant should use symmetric signature HMAC_SHA512 for Transactional API.

Merchant should use this formula to create X-SIGNATURE for Transactional API:
HTTPMethod +”:“+ EndpointUrl +":"+ AccessToken +":“+ Lowercase(HexEncode(SHA-256(minify(RequestBody))))+ ":“ + TimeStamp encrypted with merchant’s client secret by using HMAC_SHA512 algorithm.

HMAC_SHA512 algorithm reference
1529627511dee28c3daa9a4d89f19540d71dbfaee506380288fd011f2961f88297a387ecdab1da1ac14d518d0df2dd2b3e566ce2200700e0839259c271cc2e27

For a better understanding, please refer to this sample scenario for generating signature using the formula above on Transactional API:

No.Steps
1Given merchant has client secret fdppqbF5wq7vVegyvsV1CROMv646nJ7A
2Given merchant wants to create a request with header for POST https://api.midtrans.com/v1.0/registration-account-binding
Content-type:application/json
X-TIMESTAMP:2020-01-01T00:00:00+07:00
Authorization: Bearer gp9HjjEj813Y9JGoqwOeOPWbnt4CupvIJbU1Mmu4a11MNDZ7Sg5u9a
X-PARTNER-ID: BMRI
X-DEVICE-ID: 0987ADCASA
X-EXTERNAL-ID:12345678901234567890
CHANNEL-ID:12345
3X-SIGNATURE value for encryption will be:
POST:/v1.0/debit/payment-host-to-host:gp9HjjEj813Y9JGoqwOeOPWbnt4CupvIJbU1Mmu4a11MNDZ7Sg5u9a:56fa5f4999ad8014de49d7898c1d1d53472569db8999de3c1b752a0dd181e98c:2020-01-01T00:00:00+07:00

*same value as HTTPMethod +”:“+ EndpointUrl +":"+ AccessToken +":“+ Lowercase(HexEncode(SHA-256(minify(RequestBody))))+ ":“ + TimeStamp
4By using merchant’s client secret to encrypt the value with HMAC_SHA512 algorithm, merchant will generate
FSlidRHe4ow9qppNifGVQNcdv67lBjgCiP0BHylh+IKXo4fs2rHaGsFNUY0N8t0rPlZs4iAHAOCDklnCccwuJw==
5Final result of merchant's header will be:
Content-type:application/json
X-TIMESTAMP:2020-01-01T00:00:00+07:00
Authorization: Bearer gp9HjjEj813Y9JGoqwOeOPWbnt4CupvIJbU1Mmu4a11MNDZ7Sg5u9a
X-PARTNER-ID: BMRI
X-DEVICE-ID: 0987ADCASA
X-EXTERNAL-ID:12345678901234567890
CHANNEL-ID:12345
`X-SIGNATURE: FSlidRHe4ow9qppNifGVQNcdv67lBjgCiP0BHylh+IKXo4fs2rHaGsFNUY0N8t0rPlZs4iAHAOCDklnCccwuJw==