Skip to main content

NON SNAP

Symmetric

HMAC-SHA256 algorithm using to generate the signature. This signature is typically used to ensure the integrity and authenticity of the data being sent.

Data Preparation

NoDataDescriptionExample
1BodyMinify and Hash the request body with SHA-256
{
    "amount": 1000,
    "trxNo": "0194e94b-e2e3-7dd3-815e-bef454211e52",
    "duration": 10000,
    "successCallbackUrl": "String",
    "cancelCallbackUrl": "String",
    "customer": {
        "id": "0194e94b-e2e3-7dd3-815e-c082e94aad18",
        "phoneNumber": "6282323232332"
    }
}
2ClientIdClientID provided by PGshop_01
3RequestIdUnique String reference identifier generated by merchant0194e94b-e2e3-7dd3-815e-ce4b07522fd7
4UrlURL on each api (exclude the base domain) and must be exists “/”/payment
5TimestampTransaction date time, in format YYYY-MM-DDTHH:mm:ss+07:00. Time must be in GMT+7 (Jakarta time)2025-02-09T13:00:52.195+07:00

Compose String to Sign

Base64Encoded(SHA-256(<Body>)):<ClientId>:<RequestId>:<Url>:<Timestamp>
Example
ckv17xKxGwsyZpR56NAS5GRPFCVHCmxSJFwHyWNG5mM=:shop_01:0194e94b-e2e3-7dd3-815e-ce4b07522fd7:/payment:2025-02-09T13:00:52.195+07:00

Calculate stringToSign using HMAC-SHA256 base64 with Secret Key given from Cash In.

Example Result
15+wYJy0EFEuSaAmWXW4U7VxWbCSWxBO4XQn09fVAq1VkohB6d6Sw1/tpyWMJYOU+sdQTnFf7+oPiFlwtZy/yg==

For example detail implementation check this code.

Example in Java

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.OffsetDateTime;
import java.util.Base64;

public class PaymentRequestExample {

// Data class to hold payment request information
static class PaymentData {
String body; // JSON payload
String clientId; // Client identifier
String requestId; // Unique request ID
String url; // API endpoint
OffsetDateTime timestamp; // Timestamp of the request

// Constructor to initialize the data
public PaymentData(String body, String clientId, String requestId, String url, OffsetDateTime timestamp) {
this.body = body;
this.clientId = clientId;
this.requestId = requestId;
this.url = url;
this.timestamp = timestamp;
}
}

public static void main(String[] args) {
try {
// Sample payment request data
String payloadBody = "{\"amount\":1000,\"trxNo\":\"0194e94b-e2e3-7dd3-815e-bef454211e52\",\"duration\":10000,\"successCallbackUrl\":\"string\",\"cancelCallbackUrl\":\"string\",\"customer\":{\"id\":\"0194e94b-e2e3-7dd3-815e-c082e94aad18\",\"phoneNumber\":\"6282323232332\"}}";
String clientId = "shop_01";
String requestId = "0194e94b-e2e3-7dd3-815e-ce4b07522fd7";
String url = "/payment";
OffsetDateTime timestamp = OffsetDateTime.parse("2025-02-09T13:00:52.195+07:00");

// Create PaymentData object
PaymentData data = new PaymentData(payloadBody, clientId, requestId, url, timestamp);

// Secret key for HMAC-SHA256
String secretKey = "fgEe|Oc<EmsyZA^";

// Generate the signature
String signature = generateSignature(data, secretKey);

// Output the generated signature
System.out.println("Generated Signature: " + signature);
} catch (Exception e) {
e.printStackTrace();
}
}

// Method to generate the signature
public static String generateSignature(PaymentData data, String secretKey) throws Exception {
// Step 1: Create the string to sign
String stringToSign = createStringToSign(data);

// Step 2: Initialize HMAC-SHA256 with the secret key
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
mac.init(secretKeySpec);

// Step 3: Generate the HMAC bytes
byte[] hmacBytes = mac.doFinal(stringToSign.getBytes());

// Step 4: Encode the HMAC bytes to Base64
return Base64.getEncoder().encodeToString(hmacBytes);
}

// Method to create the string to sign
private static String createStringToSign(PaymentData data) throws NoSuchAlgorithmException {
// Step 1: Calculate SHA-256 hash of the body and encode it to Base64
String bodyHash = calculateSha256Base64(data.body);

// Step 2: Combine the body hash, clientId, requestId, url, and timestamp
return bodyHash + ":" + data.clientId + ":" + data.requestId + ":" + data.url + ":" + data.timestamp;
}

// Method to calculate SHA-256 hash and encode it to Base64
private static String calculateSha256Base64(String payload) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256"); // Get SHA-256 instance
byte[] hashBytes = digest.digest(payload.getBytes()); // Calculate hash
return Base64.getEncoder().encodeToString(hashBytes); // Encode to Base64
}
}
Example in PHP
<?php 

// Prepare data

$payloadBody = '{"amount":1000,"trxNo":"0194e94b-e2e3-7dd3-815e-bef454211e52","duration":10000,"successCallbackUrl":"String","cancelCallbackUrl":"String","customer":{"id":"0194e94b-e2e3-7dd3-815e-c082e94aad18","phoneNumber":"6282323232332"}}';

$clientId = 'shop_01';

$requestId = '0194e94b-e2e3-7dd3-815e-ce4b07522fd7';

$url = '/payment';

$timestamp = '2025-02-09T13:00:52.195+07:00';


// Secret Key

$secretKey = 'fgEe|Oc<EmsyZA^';


// function for calculate SHA-256 and encode to Base64

function calculateSha256Base64($payload) {

    $hashBytes = hash('sha256', $payload, true); // calculate SHA-256

    return base64_encode($hashBytes); // Encode to Base64

}


// function for generate string to sign

function generateStringToSign($body, $clientId, $requestId, $url, $timestamp) {

    $bodyHash = calculateSha256Base64($body); // Hitung hash body

    return $bodyHash . ":" . $clientId . ":" . $requestId . ":" . $url . ":" . $timestamp;

}


// function generate Signature

function generateSignature($stringToSign, $secretKey) {

    $hmacHash = hash_hmac('sha256', $stringToSign, $secretKey, true); // Hitung HMAC-SHA256

    return base64_encode($hmacHash); // Encode ke Base64

}


// Step 1: Generate string to sign

$stringToSign = generateStringToSign($payloadBody, $clientId, $requestId, $url, $timestamp);


// Step 2: Generate signature

$signature = generateSignature($stringToSign, $secretKey);


// show result signature

echo "Generated Signature: " . $signature;

?>