DocsGet started

Authentication

Every request must include four headers:

HeaderValue
AuthorizationBearer pk_… (your publishable key)
X-TimestampCurrent Unix time in seconds
X-SignatureHMAC-SHA256 of the signing string (hex)
Content-Typeapplication/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.