Signature Generation
Overview
To ensure message integrity, non-repudiation, and protection against request tampering, all transaction requests exchanged between the Switch and Participating Banks must be digitally signed using HMAC-SHA256.
This mechanism is mandatory for all financial transaction endpoints (Balance Enquiry, Debit Transfer, and Reversal).
The signing process is standardized across all participating institutions to ensure uniform implementation, interoperability, and auditability.
Step-by-Step Signing Process (Switch Side)
Step 1 — Prepare Request Body
Ensure:
- JSON is valid
- UTF-8 encoded
- No formatting changes after signing
Example:
{
"requestId": "REQ-20260123-000003",
"stan": "000301",
"processingCode": "310000"
}
Step 2 — Generate Timestamp
2026-01-23T11:00:00Z
Step 3 — Generate Nonce
Random unique string:
b7f23c9d82a14f0e
Step 4 — Hash Request Body
Apply SHA-256:
SHA256(body)
Example output:
9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab
Step 5 — Build Canonical String
POST # HTTP Method
/api/v1/transactions/transfer # Request Path
2026-01-23T11:00:00Z # ISO 8601 Timestamp
b7f23c9d82a14f0e # Nonce
9c56cc51b374c3ba18927790d351c96c47c02190ecf1e430635ab # Hash Request Body
Step 6 — Generate HMAC Signature
Formula:
HMAC_SHA256(secret_key, canonical_string)
Step 7 — Base64 Encode Signature
Result:
mJ7Qz8sYp4Kp9aU0MZ7xQhQ3B8L9T0C5RrWm9FJ2H3Y=
Step 8 — Attach Headers
Authorization: Bearer eyJhbGciOi...
X-Timestamp: 2026-01-23T11:00:00Z
X-Nonce: b7f23c9d82a14f0e
X-Signature: mJ7Qz8sYp4Kp9aU0MZ7xQhQ3B8L9T0C5RrWm9FJ2H3Y=
Content-Type: application/json
Accept: application/json
| Header Name | Type | Mandatory | Description |
|---|---|---|---|
| Authorization | String | Yes | Bearer token in the format Bearer `access_token` |
| X-Signature | String | Yes | Cryptographic request signature |
| X-Timestamp | String | Yes | UTC ISO-8601 timestamp |
| X-Nonce | String | Yes | Unique random value per request |
| Content-Type | String | Yes | Must be application/json |
| Accept | String | Yes | Must be application/json |
Server-Side Verification Process (Bank )
Step 1 — Extract headers
- X-Timestamp
- X-Nonce
- X-Signature (Base64)
Step 2 — Validate timestamp
Reject if:
| current_time - timestamp | > 5 minutes
Step 3 — Validate nonce
Reject if nonce already exists (replay protection).
Step 4 — Rebuild canonical string
Using received:
- Method
- Path
- Timestamp
- Nonce
- Body Hash
POST
/api/v1/transactions/transfer
2026-01-23T11:00:00Z
b7f23c9d82a14f0e
9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab
Step 5 — Recompute HMAC
Using stored secret key.
Formula:
HMAC_SHA256(secret_key, canonical_string)
Step 6 — Decode Signature (Base64)
Extract the signature header:
client_signature_base64 = X-Signature
Decode it:
client_raw_signature = Base64Decode(client_signature_base64)
Step 7 — Compare signatures
If mismatch → reject
Validation Error Codes
| Code | Meaning |
|---|---|
| 91 | Invalid signature |
| 92 | Timestamp expired |
| 93 | Duplicate nonce |
| 94 | Missing signature |
| 95 | Malformed signature |