Authentication
Every request must include four headers:
| Header | Value |
|---|---|
Authorization | Bearer pk_… (your publishable key) |
X-Timestamp | Current Unix time in seconds |
X-Signature | HMAC-SHA256 of the signing string (hex) |
Content-Type | application/json |
Signing string
Build the string, then HMAC-SHA256 it with your secret key (sk_…):
- When the request has a reference, amount and currency:
code
merchant_code|reference_no|amount|currency|timestamp - Otherwise (e.g. Get Session):
code
merchant_code|timestamp
amount is formatted to two decimals (e.g. 3.00).
Node.js
js
import crypto from 'node:crypto'
const secret = process.env.SYOK2PAY_SECRET // sk_...
const timestamp = Math.floor(Date.now() / 1000).toString()
const amount = (3).toFixed(2)
const signingString = `M00001|ORD-20260428-001|${amount}|MYR|${timestamp}`
const signature = crypto.createHmac('sha256', secret).update(signingString).digest('hex')
// headers: Authorization: `Bearer ${pk}`, 'X-Timestamp': timestamp, 'X-Signature': signature
PHP
php
<?php
$secret = getenv('SYOK2PAY_SECRET'); // sk_...
$timestamp = (string) time();
$amount = number_format(3, 2, '.', ''); // "3.00"
$signingString = "M00001|ORD-20260428-001|{$amount}|MYR|{$timestamp}";
$signature = hash_hmac('sha256', $signingString, $secret);
// Send Authorization: Bearer pk_..., X-Timestamp, X-Signature
Requests with an invalid signature return 401 Invalid signature.