Transaction Signature

This page to learn how to generate signature for every transaction endpoint

Relative Path

TYPEPATHDESCRIPTION

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

Step 1

Before a partner create a signature transaction, make sure the partner has received a token from Authentication token, eg

eyJzaWduYXR1cmUiOiIwZGEwYmQ1MWU0MjI2Mzc4YWZhMTliYTM5MDRlZjg5NzQxNWY4ODgzZWI0YjI5ZDM5NzM4YTllZjE2OWIxYzc3IiwidG9rZW5QcG9iVXNlclJlc3BvbnNlIjp7InVzZXJJZCI6InJhaHlhbi1jbGllbnQiLCJleHBpcmVkVHMiOjE3MDk3MjE3NzM5NDksInJvbGVzIjpbInBwb2IuZ2FtZV90b3B1cF9pbl9nYW1lIl19fQ%3D%3D

Step 2

Decode that`s token using URLDecoder / decodeURIComponent, example result :

eyJzaWduYXR1cmUiOiIwZGEwYmQ1MWU0MjI2Mzc4YWZhMTliYTM5MDRlZjg5NzQxNWY4ODgzZWI0YjI5ZDM5NzM4YTllZjE2OWIxYzc3IiwidG9rZW5QcG9iVXNlclJlc3BvbnNlIjp7InVzZXJJZCI6InJhaHlhbi1jbGllbnQiLCJleHBpcmVkVHMiOjE3MDk3MjE3NzM5NDksInJvbGVzIjpbInBwb2IuZ2FtZV90b3B1cF9pbl9nYW1lIl19fQ==

Step 3

Visit base64decode.org, 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

Step 4

<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

Example Code (Golang)

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
}

Example Code (Java)

    // 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
    }

Last updated