Core Concepts
Authentication & signing
Every merchant-API request is authenticated with HMAC-SHA256 — no shared session, no cookies, just an API key and a secret. There is no bearer token to attach; instead, each request is individually signed using your secret as the HMAC key.
Required headers
Every request carries the following. Idempotency-Key is required on state-changing methods only — see Idempotency.
Authorization: ProsoftPay-HMAC-SHA256 KeyId=<api_key_prefix>, Signature=<hex>
X-ProsoftPay-Timestamp: <unix_epoch_seconds>
X-ProsoftPay-Nonce: <uuid_v4>
Idempotency-Key: <uuid_v4> (required on POST/PUT/PATCH/DELETE)
Content-Type: application/jsonCanonical string to sign
Build the canonical string from five newline-joined fields, in this exact order:
<HTTP_METHOD>
<PATH>
<X-ProsoftPay-Timestamp>
<X-ProsoftPay-Nonce>
<SHA256(request_body_bytes)>Then: signature = HMAC_SHA256(api_secret, canonical_string).hex() — lowercase hex. Send it as Authorization: ProsoftPay-HMAC-SHA256 KeyId=<key_id>, Signature=<signature>.
Timestamp & nonce replay protection
X-ProsoftPay-Timestamp is unix epoch seconds and must fall within a 5-minute window of server time. X-ProsoftPay-Nonce is a UUIDv4 that must not repeat within that same 5-minute window — reusing one is treated as a replay attempt, not a retry (use a fresh Idempotency-Key and a fresh nonce for a genuine retry).
Rejections
| Condition | Status |
|---|---|
| Timestamp older than 5 minutes | 401 |
| Signature mismatch | 401 |
| Nonce reused within 5 minutes | 401 |
| API key inactive | 403 |
The admin dashboard API is authenticated differently — Auth0 OIDC, with a bearer JWT — and is not covered here; this page is specifically about the merchant/institution API.