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
| No | Data | Description | Example |
|---|---|---|---|
| 1 | Body | Minify 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"
}
} |
| 2 | ClientId | ClientID provided by PG | shop_01 |
| 3 | RequestId | Unique String reference identifier generated by merchant | 0194e94b-e2e3-7dd3-815e-ce4b07522fd7 |
| 4 | Url | URL on each api (exclude the base domain) and must be exists “/” | /payment |
| 5 | Timestamp | Transaction 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;
?>