Postman — Hosted Payments
REPLACE EXAMPLE CREDENTIALS
Replace all placeholder values in the pre-request scripts:
'your-api-key'→ Your actual API Key from the merchant portal'your-api-secret'→ Your actual API Secret from the merchant portal- Replace
1000in the URL with your actual Merchant ID
How Signatures Work in Postman
Postman's built-in CryptoJS library handles all cryptographic operations. The pre-request scripts below calculate the correct signature and set the required headers automatically before each request.
POST signature: Base64(HMAC-SHA256(timestamp\nPOST\npath\nBase64(SHA256(body)), apiSecret))
GET signature (no query string): Base64(HMAC-SHA256(timestamp\nGET\npath, apiSecret))
GET signature (with query string): Base64(HMAC-SHA256(timestamp\nGET\npath\nBase64(SHA256(queryString)), apiSecret))
Create Order
1. Configure the Request
Method: POSTURL: https://api.paystablecoin.global/api/v1/merchants/1000/orders
Replace 1000 with your Merchant ID.
2. Set the Request Body
In Postman, go to Body → select raw → choose JSON, then paste:
{
"merchantOrderId": "ORDER_{{$timestamp}}",
"orderAmount": {
"value": "99.99",
"currency": "USD"
},
"expiresAt": "2026-12-31T23:59:59Z",
"returnUrl": "https://yoursite.com/payment/success",
"callbackUrl": "https://yoursite.com/webhook/payment"
}TIP
is a Postman built-in variable that inserts the current Unix timestamp, ensuring a unique merchantOrderId on every send.
3. Add the Pre-request Script
Go to the Pre-request Script tab and paste the following:
// ── Configuration ──────────────────────────────────────────────────
const apiKey = 'your-api-key';
const secretKey = 'your-api-secret';
// ── Timestamp ──────────────────────────────────────────────────────
const timestamp = Date.now().toString();
// ── Request details ────────────────────────────────────────────────
const method = pm.request.method; // "POST"
const urlObj = new URL(pm.request.url.toString());
const path = urlObj.pathname; // e.g. /api/v1/merchants/1000/orders
// ── Body: replace Postman variables, then minify ───────────────────
let body = pm.request.body.raw;
body = body.replace(/\{\{\$timestamp\}\}/g, timestamp);
body = JSON.stringify(JSON.parse(body)); // minify
pm.request.body.raw = body; // update the actual request body
// ── Body hash: SHA256 → Base64 ─────────────────────────────────────
const bodyHash = CryptoJS.SHA256(body).toString(CryptoJS.enc.Base64);
// ── Build signature string ─────────────────────────────────────────
const stringToSign = [timestamp, method, path, bodyHash].join('\n');
console.log('=== Hosted Payments — Create Order ===');
console.log('Timestamp:', timestamp);
console.log('Method:', method);
console.log('Path:', path);
console.log('Body Hash (Base64):', bodyHash);
console.log('String to Sign:', stringToSign.replace(/\n/g, ' | '));
// ── HMAC-SHA256 → Base64 ───────────────────────────────────────────
const signature = CryptoJS.enc.Base64.stringify(
CryptoJS.HmacSHA256(stringToSign, secretKey)
);
console.log('Signature:', signature);
// ── Set headers ────────────────────────────────────────────────────
pm.request.headers.upsert({ key: 'Content-Type', value: 'application/json' });
pm.request.headers.upsert({ key: 'X-Api-Key', value: apiKey });
pm.request.headers.upsert({ key: 'X-Timestamp', value: timestamp });
pm.request.headers.upsert({ key: 'X-Signature', value: signature });4. Send and Verify
Click Send. A successful response looks like:
{
"code": "00000",
"message": "Success",
"data": {
"orderId": "ord_8fcb2a2e5b",
"merchantOrderId": "ORDER_1738112345000",
"status": "INIT",
"checkoutUrl": "https://checkout.paystablecoin.global/ord_8fcb2a2e5b"
}
}Redirect the customer to checkoutUrl to complete payment.
Query Order
1. Configure the Request
Method: GETURL: https://api.paystablecoin.global/api/v1/merchants/1000/orders/ORDER_1738112345000
Replace 1000 with your Merchant ID and ORDER_1738112345000 with the order ID to query.
2. No Body Required
Leave the Body tab empty (select none).
3. Add the Pre-request Script
// ── Configuration ──────────────────────────────────────────────────
const apiKey = 'your-api-key';
const secretKey = 'your-api-secret';
// ── Timestamp ──────────────────────────────────────────────────────
const timestamp = Date.now().toString();
// ── Request details ────────────────────────────────────────────────
const method = pm.request.method; // "GET"
const urlObj = new URL(pm.request.url.toString());
const path = urlObj.pathname;
// ── Build signature string (no body, no query string) ──────────────
const stringToSign = [timestamp, method, path].join('\n');
console.log('=== Hosted Payments — Query Order ===');
console.log('Timestamp:', timestamp);
console.log('Method:', method);
console.log('Path:', path);
console.log('String to Sign:', stringToSign.replace(/\n/g, ' | '));
// ── HMAC-SHA256 → Base64 ───────────────────────────────────────────
const signature = CryptoJS.enc.Base64.stringify(
CryptoJS.HmacSHA256(stringToSign, secretKey)
);
console.log('Signature:', signature);
// ── Set headers ────────────────────────────────────────────────────
pm.request.headers.upsert({ key: 'X-Api-Key', value: apiKey });
pm.request.headers.upsert({ key: 'X-Timestamp', value: timestamp });
pm.request.headers.upsert({ key: 'X-Signature', value: signature });Query Refund (GET with Query String)
For refund queries, the query string is hashed as the fourth component of the signature.
1. Configure the Request
Method: GETURL: https://api.paystablecoin.global/api/v1/merchants/1000/refunds
Add a Query Param: key refundOrderId, value REF_20260128120001.
2. Add the Pre-request Script
// ── Configuration ──────────────────────────────────────────────────
const apiKey = 'your-api-key';
const secretKey = 'your-api-secret';
// ── Timestamp ──────────────────────────────────────────────────────
const timestamp = Date.now().toString();
// ── Request details ────────────────────────────────────────────────
const method = pm.request.method; // "GET"
const urlObj = new URL(pm.request.url.toString());
const path = urlObj.pathname;
const qs = urlObj.search.replace(/^\?/, ''); // e.g. "refundOrderId=REF_..."
// ── Query string hash: SHA256 → Base64 ────────────────────────────
const qsHash = CryptoJS.SHA256(qs).toString(CryptoJS.enc.Base64);
// ── Build signature string ─────────────────────────────────────────
const stringToSign = [timestamp, method, path, qsHash].join('\n');
console.log('=== Hosted Payments — Query Refund ===');
console.log('Query String:', qs);
console.log('QS Hash (Base64):', qsHash);
console.log('String to Sign:', stringToSign.replace(/\n/g, ' | '));
// ── HMAC-SHA256 → Base64 ───────────────────────────────────────────
const signature = CryptoJS.enc.Base64.stringify(
CryptoJS.HmacSHA256(stringToSign, secretKey)
);
// ── Set headers ────────────────────────────────────────────────────
pm.request.headers.upsert({ key: 'X-Api-Key', value: apiKey });
pm.request.headers.upsert({ key: 'X-Timestamp', value: timestamp });
pm.request.headers.upsert({ key: 'X-Signature', value: signature });Troubleshooting
| Error | Likely Cause | Fix |
|---|---|---|
Invalid signature | Wrong key or body mismatch | Verify apiKey/secretKey; check the Console log for the body hash |
Invalid or expired timestamp | Clock out of sync | Sync your system time; timestamp must be within ±5 minutes |
Missing required field | Incomplete request body | Check all required fields are present |
Invalid parameter: merchantId | Wrong Merchant ID in URL | Verify the Merchant ID matches your credentials |
Related Documentation
- Hosted Payments Integration Guide — Step-by-step integration walkthrough
- API Reference — Full endpoint and field specification
- Signature Algorithm — Signature calculation details