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 key
  • X-Nonce — unique per request (UUID)
  • X-Timestamp — Unix epoch seconds
  • X-Signature — lowercase hex HMAC
  • X-Merchant-ID — your business profile ID
  • X-Tenant-ID — tenant from onboarding

Signature construction

  1. Build a canonical body: sort JSON fields by key ascending, join as key=value&key=value, omit nulls.
  2. Compute bodySha256Hex = hex(SHA256(canonicalBody)).
  3. Build the base string (literal newlines between parts):
Base string
apiKey
nonce
timestampEpochSeconds
POST
/payment/api/payins
bodySha256Hex

Then 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&currency=NGN&customerEmail=jane@example.com&customerName=Jane Doe&gateway=PALMPAY&narration=Test payment&notifyUrl=https://merchant.example/webhook&redirectUrl=https://merchant.example/return&reference=ref-123

Server 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.