Guides
Authentication
Payment APIs use HMAC-SHA256 with a nonce and timestamp to prevent tampering and replay attacks.
Required headers
X-API-KEY— public API keyX-Nonce— unique per request (UUID)X-Timestamp— Unix epoch secondsX-Signature— lowercase hex HMACX-Merchant-ID— your business profile IDX-Tenant-ID— tenant from onboarding
Signature construction
- Build a canonical body: sort JSON fields by key ascending, join as
key=value&key=value, omit nulls. - Compute
bodySha256Hex = hex(SHA256(canonicalBody)). - Build the base string (literal newlines between parts):
Base string
apiKey
nonce
timestampEpochSeconds
POST
/payment/api/payins
bodySha256HexThen signature = hex(HMAC_SHA256(secretKey, baseString)). The requestPath must include the context path (e.g. /payment/api/payins).
Canonical body example
Sorted fields
amount=1000¤cy=NGN&customerEmail=jane@example.com&customerName=Jane Doe&gateway=PALMPAY&narration=Test payment¬ifyUrl=https://merchant.example/webhook&redirectUrl=https://merchant.example/return&reference=ref-123Server checks
- API key matches a known merchant
- Timestamp within ±300 seconds of server time
- Nonce not reused within the TTL window (default 600s)
- Signature matches the recomputed value
Failures return 401 Unauthorized.
Best practices
- Keep secretKey server-side only
- Synchronize clocks with NTP
- Never reuse nonces
- Sign the exact payload you send
Continue with Create a payin.