Transaction Signature
This page to learn how to generate signature for every transaction endpoint
Last updated
This page to learn how to generate signature for every transaction endpoint
Last updated
GET
/game-top-up
Webview
GET
/public/api/ppob/v1/product/{productID}
Open API
GET
/public/api/ppob/v1/product?limit=10&page=1&search=&orderBy=&merchantId={merchantId}
Open API
POST
/public/api/ppob/v1/order
Open API
POST
/public/api/ppob/v1/product/validate
Open API
GET
/public/api/ppob/v1/order/detail
Open API
Before a partner create a signature transaction, make sure the partner has received a token from , eg
eyJzaWduYXR1cmUiOiIwZGEwYmQ1MWU0MjI2Mzc4YWZhMTliYTM5MDRlZjg5NzQxNWY4ODgzZWI0YjI5ZDM5NzM4YTllZjE2OWIxYzc3IiwidG9rZW5QcG9iVXNlclJlc3BvbnNlIjp7InVzZXJJZCI6InJhaHlhbi1jbGllbnQiLCJleHBpcmVkVHMiOjE3MDk3MjE3NzM5NDksInJvbGVzIjpbInBwb2IuZ2FtZV90b3B1cF9pbl9nYW1lIl19fQ%3D%3D
Decode that`s token using URLDecoder / decodeURIComponent, example result :
eyJzaWduYXR1cmUiOiIwZGEwYmQ1MWU0MjI2Mzc4YWZhMTliYTM5MDRlZjg5NzQxNWY4ODgzZWI0YjI5ZDM5NzM4YTllZjE2OWIxYzc3IiwidG9rZW5QcG9iVXNlclJlc3BvbnNlIjp7InVzZXJJZCI6InJhaHlhbi1jbGllbnQiLCJleHBpcmVkVHMiOjE3MDk3MjE3NzM5NDksInJvbGVzIjpbInBwb2IuZ2FtZV90b3B1cF9pbl9nYW1lIl19fQ==
Visit , then decode that`s token
{"signature":"9c3a68e2e9d0593beeab9466c09c8bd546b49aea1807735a1b125b8b9e1e2c29","tokenPpobUserResponse":{"userId":"Xersia01","expiredTs":1709817873986,"roles":["ppob.game_topup_in_game"]}}
Partner will see a signature hash, use this value to next step
<result_signature> = HMAC_SHA256(ClientId + ClientKeyPattern + ClientKey + ClientKeyPattern + pathurl + ClientKeyPattern + <signature>, minify(<request_body>) )
// <result_signature> = 808cac29deaf1efc7f99e1f8aaefdccfbe9e135756ada8b3ab906124a6be19d0
// Passing <result_signature> value to X-SIGNATURE header
import (
"crypto"
"crypto/hmac"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/hex"
"fmt"
)
func main() {
minifyJsonBody := "{\"type\":\"ORDER_PRODUCT\",\"body\":{\"merchantId\":\"M_YDXabcd1\",\"denomId\":1,\"denomCode\":\"ML185\",\"validationUserResponse\":{\"username\":123456,\"validation_token\":\"VT17084167245Y1f1\"}}}"
clientId := "Xersia01"
clientKey := "jH45gXeSW3T8eCCoZQ5{I@iH99D]q9dQ_{{sl@|{xxAvDq?A~92Zw?<(0Mnz8Ygw"
clientKeyPattern := "||/cd"
// this is relative path of endpoint do you want to access
pathUrl := "/public/api/ppob/v1/order"
sampleSignatureFromToken := "9c3a68e2e9d0593beeab9466c09c8bd546b49aea1807735a1b125b8b9e1e2c29"
key := []byte(clientId + clientKeyPattern + clientKey + pathUrl + clientKeyPattern + sampleSignatureFromToken)
h := hmac.New(sha256.New, key)
h.Write([]byte(minifyJsonBody))
signatureTransaction := hex.EncodeToString(h.Sum(nil))
fmt.Println("signatureTrx =", signatureTransaction)
// Output is = a1774d303e66a4655ec65c1f30ddb53964a79482e0574290509f6451a171e617
}
// Hashing method
private String hmacSHA256(String salt, String minifyJsonBody) {
try {
javax.crypto.Mac hmac256SHAInstance = javax.crypto.Mac.getInstance("HmacSHA256");
javax.crypto.spec.SecretKeySpec secret_key = new javax.crypto.spec.SecretKeySpec(salt.getBytes(java.nio.charset.StandardCharsets.UTF_8), "HmacSHA256");
hmac256SHAInstance.init(secret_key);
return org.apache.commons.codec.binary.Hex.encodeHexString(hmac256SHAInstance.doFinal(minifyJsonBody.getBytes(java.nio.charset.StandardCharsets.UTF_8)));
} catch (Exception exception) {
System.out.println("Oops something went wrong.");
return null;
}
}
public void sampleTransactionSignaturePost() {
//body should be minified
String minifyJsonBody = "{\"type\":\"ORDER_PRODUCT\",\"body\":{\"merchantId\":\"M_YDXabcd1\",\"denomId\":1,\"denomCode\":\"ML185\",\"validationUserResponse\":{\"username\":123456,\"validation_token\":\"VT17084167245Y1f1\"}}}";
String clientId = "Xersia01";
String clientKey = "jH45gXeSW3T8eCCoZQ5{I@iH99D]q9dQ_{{sl@|{xxAvDq?A~92Zw?<(0Mnz8Ygw";
String clientKeyPattern = "||/cd";
// this is relative path of endpoint do you want to access
String pathUrl = "/public/api/ppob/v1/order";
String sampleSignatureFromToken = "9c3a68e2e9d0593beeab9466c09c8bd546b49aea1807735a1b125b8b9e1e2c29";
String signature = hmacSHA256(clientId + clientKeyPattern + clientKey + pathUrl + clientKeyPattern + sampleSignatureFromToken, minifyJsonBody);
System.out.println("Transaction signature = " + signature);
// Output = a1774d303e66a4655ec65c1f30ddb53964a79482e0574290509f6451a171e617
}
eyJzaWduYXR1cmUiOiI5YzNhNjhlMmU5ZDA1OTNiZWVhYjk0NjZjMDljOGJkNTQ2YjQ5YWVhMTgwNzczNWExYjEyNWI4YjllMWUyYzI5IiwidG9rZW5QcG9iVXNlclJlc3BvbnNlIjp7InVzZXJJZCI6IlhlcnNpYTAxIiwiZXhwaXJlZFRzIjoxNzA5ODE3ODczOTg2LCJyb2xlcyI6WyJwcG9iLmdhbWVfdG9wdXBfaW5fZ2FtZSJdfX0%3D
Decode that`s token using URLDecoder / decodeURIComponent, example result :
eyJzaWduYXR1cmUiOiI5YzNhNjhlMmU5ZDA1OTNiZWVhYjk0NjZjMDljOGJkNTQ2YjQ5YWVhMTgwNzczNWExYjEyNWI4YjllMWUyYzI5IiwidG9rZW5QcG9iVXNlclJlc3BvbnNlIjp7InVzZXJJZCI6IlhlcnNpYTAxIiwiZXhwaXJlZFRzIjoxNzA5ODE3ODczOTg2LCJyb2xlcyI6WyJwcG9iLmdhbWVfdG9wdXBfaW5fZ2FtZSJdfX0=
{"signature":"9c3a68e2e9d0593beeab9466c09c8bd546b49aea1807735a1b125b8b9e1e2c29","tokenPpobUserResponse":{"userId":"Xersia01","expiredTs":1709817873986,"roles":["ppob.game_topup_in_game"]}}
Partner will see a signature hash, use this value to next step
<result_signature> = HMAC_SHA256(ClientId + ClientKeyPattern + ClientKey + ClientKeyPattern + pathurl + ClientKeyPattern + <signature>, "") )
// Passing <result_signature> value to X-SIGNATURE header
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
privateKey := "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCI4yKrJ0b7L54UDW5raqctBu21aWdPh+tqHgmHRiiAg3wnhvDzTJJMk9UCa7IKMt95X6zoQHC/Dj3pBgP2DwLj7O3ldE1umSR7N89d+xbPk6X2mmjtdTS2/G6rBUNMh9LiZ9oFdSup7CFJmimM5m17PY7Cr+PtOZ2VThmnqET4OfO/TuOlXmNJd8bnuHdy3VNFZCEUSBV01ItADWEyt8UVHRNFdl9zoBNCKJN/F8DhsEOINDt8ekWd7+J2uz6vJqwBV3jYw41ZMMSmSJUncoH9pd1A7plf+Xd6TZFQE2Gs8RMo6buIjxSUeRMI93LFYbdUPeftk3WMTi8DVGFPCCyPAgMBAAECggEAXxHA5jWlKpbrpumdIqUz7iW9uhy2T5oKeezamUS0pGytMZaaiZ9IjD6v1bqOMF8creMw5yy6ITb28HvpDF9olnvazV102bcqixk7v/2+3fOhdB/Rd/nK3rt68PP6xZAfena+CMRTyvPgOooDCYSPzOP33mbiWcOGGkffsX1ASVSRP8gcrHW9n607/0E4xaTsFCPKlGeoi9kKzcUmOMbqg7r/DAufeFu7RrM5kVkOBI2rSOPc4KcirbecHoVOL5/5m/769kBwdVyjLGUxbpOjJlMX/ud54Qfp4i4Fj+oWsxraNg4TxKNrAMvthR66hLGJ0gEMJZmT4x6g2jOi+wxDoQKBgQDNQ1+bOykUNV+UpfFPCg1P0E8trb8D49pDTwDgLn1n8SdukdvamHIepzpPwzVwSISTxMdMm9n+QDvbNm61eprzsRG4S2E2vQu2FFq0izpZAKAp6bzagljJ1TrGiNx5WdYs5NG4tTuP/VZivQBaARJsnZUheJt1f1HZ/Gg5ex8tiwKBgQCquRNSScDOAHuo85HLHkqAztNPXpqLPGw9JkGCIWxnBkbYEaal3DgJVZRAEEe8zXqy8ZKm0JXSN2CByJTRFG34omKlGSo8kfJ6tcnNsOlAWjHT5+bYwfIO491cnn7uGYwq2yQU/P8QY58+p9JK8I/py+dC69BUHsoj4z0SnrUljQKBgQCmmf2amB0SevO2Si4fMhB17KSndbNpa+H26cPTMci1ueWAeEDTHxLZUHAi11Wjaii5a2k8A++ezvIGThrzj6z/CIRSalRgQnaj9cddbPgRz1EwU7fmPw/j2f8Xr3QLxt/wllSmr+rFRyF7iN4lL2ON5yVpAmRjrNB5tsW9ifJXWwKBgCWvCIbHZNmT3bfjW7EcFJHuFVKVrUNCqRmuUhNpUUZEamrTKpe9zlixHTIu5cbVDFpnXFmZ/RgTxSegoMit28BgB6otrdcE2CMh8VOH01SzFACUVa5O0SFcRsZk7ducpAXprUM8vQhfFQ19ebu08e9HZNqutqN60F+vjxGHGrEZAoGAYFXY4qzMOLPIbJztbL6mnVB2Ntg8+8Jvz0YGe4s2ye2ol7vNZ4d0DE7P4Z66EPTJovpmvpjw5XT1RuK4CrNXvoJ4oxBdm3yF9BhobDxO5L5pWaWThxzNH8W61JwisUwDl5IbRRjwPovt5NXHZ/E/fUQ96jjt4NGftOcceD/ggKA="
dataJson := "{\"requestId\":\"{ed3f6763-b1bd-40e3-aecb-ddaa2c3a9775\",\"requestTime\"1863147517949:,\"type\":\"TYPE_GENERATE_TOKEN\",\"body\":{\"merchantId\":\"M_YDXabcd1\",\"webview\":true,\"additionalInfo\":\"\"}}"
signatureToken := generateSignatureToken(privateKey, dataJson)
fmt.Println("signatureToken =", signatureToken)
minifyJsonBody := ""
clientId := "Xersia01"
clientKey := "jH45gXeSW3T8eCCoZQ5{I@iH99D]q9dQ_{{sl@|{xxAvDq?A~92Zw?<(0Mnz8Ygw"
clientKeyPattern := "||/cd"
clientId = "Xersia01"
clientKey = "jH45gXeSW3T8eCCoZQ5{I@iH99D]q9dQ_{{sl@|{xxAvDq?A~92Zw?<(0Mnz8Ygw"
clientKeyPattern = "||/cd"
// this is relative path of endpoint do you want to access
pathUrl := "/game-top-up?token=eyJzaWduYXR1cmUiOiIwZGEwYmQ1MWU0MjI2Mzc4YWZhMTliYTM5MDRlZjg5NzQxNWY4ODgzZWI0YjI5ZDM5NzM4YTllZjE2OWIxYzc3IiwidG9rZW5QcG9iVXNlclJlc3BvbnNlIjp7InVzZXJJZCI6InJhaHlhbi1jbGllbnQiLCJleHBpcmVkVHMiOjE3MDk3MjE3NzM5NDksInJvbGVzIjpbInBwb2IuZ2FtZV90b3B1cF9pbl9nYW1lIl19fQ==&merchantId=M_YDXabcd1"
sampleSignatureFromToken := "9c3a68e2e9d0593beeab9466c09c8bd546b49aea1807735a1b125b8b9e1e2c29"
key := []byte(clientId + clientKeyPattern + clientKey + pathUrl + clientKeyPattern + sampleSignatureFromToken)
h := hmac.New(sha256.New, key)
h.Write([]byte(minifyJsonBody))
signatureTransaction := hex.EncodeToString(h.Sum(nil))
fmt.Println("signatureTrx =", signatureTransaction)
// Output is = eb4c884430ea87b73ba05927affb1a72b2a07e56874a624aff752281ff39c502
}
// Hashing method
private String hmacSHA256(String salt, String minifyJsonBody) {
try {
javax.crypto.Mac hmac256SHAInstance = javax.crypto.Mac.getInstance("HmacSHA256");
javax.crypto.spec.SecretKeySpec secret_key = new javax.crypto.spec.SecretKeySpec(salt.getBytes(java.nio.charset.StandardCharsets.UTF_8), "HmacSHA256");
hmac256SHAInstance.init(secret_key);
return org.apache.commons.codec.binary.Hex.encodeHexString(hmac256SHAInstance.doFinal(minifyJsonBody.getBytes(java.nio.charset.StandardCharsets.UTF_8)));
} catch (Exception exception) {
System.out.println("Oops something went wrong.");
return null;
}
}
public void sampleSignatureGet() {
//ENDPOINT GET : leave as empty string
String minifyJsonBody = "";
String clientId = "Xersia01";
String clientKey = "jH45gXeSW3T8eCCoZQ5{I@iH99D]q9dQ_{{sl@|{xxAvDq?A~92Zw?<(0Mnz8Ygw";
String clientKeyPattern = "||/cd";
String sampleSignatureFromToken = "9c3a68e2e9d0593beeab9466c09c8bd546b49aea1807735a1b125b8b9e1e2c29";
String pathUrl = "/game-top-up?token=eyJzaWduYXR1cmUiOiIwZGEwYmQ1MWU0MjI2Mzc4YWZhMTliYTM5MDRlZjg5NzQxNWY4ODgzZWI0YjI5ZDM5NzM4YTllZjE2OWIxYzc3IiwidG9rZW5QcG9iVXNlclJlc3BvbnNlIjp7InVzZXJJZCI6InJhaHlhbi1jbGllbnQiLCJleHBpcmVkVHMiOjE3MDk3MjE3NzM5NDksInJvbGVzIjpbInBwb2IuZ2FtZV90b3B1cF9pbl9nYW1lIl19fQ==&merchantId=M_YDXabcd1";
String signature = hmacSHA256(clientId + clientKeyPattern + clientKey + pathUrl + clientKeyPattern + sampleSignatureFromToken, minifyJsonBody);
System.out.println("Transaction signature = " + signature);
// Output = eb4c884430ea87b73ba05927affb1a72b2a07e56874a624aff752281ff39c502
}
Before a partner create a signature transaction, make sure the partner has received a token from , eg
Visit , then decode that`s token