OI Payments Docs

Authentication

How applications authenticate with an API key + secret, how credentials rotate and revoke, and how admin sessions differ.

The service has two parallel authentication mechanisms. As an integrating app you use the API key + secret. Operators using the dashboard use an admin session (covered in the admin guide).

App API key + secret

Every app-facing request carries two headers:

X-Api-Key: oi_test_xxx
X-Api-Secret: your-secret
  • X-Api-Key is a deterministic lookup handle. The service stores only its SHA-256 digest, so the key resolves a credential row without the raw value being recoverable.
  • X-Api-Secret is verified against a bcrypt hash after the key resolves. Both must be valid.

The resolved credential determines the app and the mode (TEST/LIVE). The mode is never read from the request body — a oi_test_… key always operates on test data.

Send credentials only over HTTPS and only from your backend. Never embed the secret in a browser, mobile app, or anything a customer can inspect.

A credential is one of many

An app can hold more than one credential per mode. That is what makes rotation and revocation non-disruptive: each credential is an independent row that can expire or be revoked without touching the others.

Credential statusBehaviour
ACTIVE, no expiryAuthenticates normally.
ACTIVE, with expiresAtStill authenticates until the grace deadline passes (rotated-out key).
REVOKEDRejected immediately.

Rotation (zero-downtime)

When a credential is rotated, a new one is issued immediately and the old one is stamped with an expiresAt (a grace window, 24h by default). Both keys work during the window, so you can roll your deployment over with no downtime:

  1. Operator rotates the credential; you receive the new key + secret (shown once).
  2. Deploy the new key alongside the old — both authenticate.
  3. Once all traffic uses the new key, let the old one expire (or have it revoked).

Revocation

Revoking a credential takes effect immediately — the next request with it is rejected with UNAUTHORIZED. Use this if a secret may be compromised; issue a replacement by rotating first if you need continuity.

Admin sessions (for reference)

Operators authenticate the dashboard with email + password and receive a bearer token:

Authorization: Bearer <session-token>

Sensitive operations (rotating credentials, overriding the gateway, managing users) additionally require a recent re-authentication — the operator re-enters their password, and the action is written to the append-only audit log. A stale session returns REAUTH_REQUIRED. App integrations never deal with this; see the admin guide for details.

Authentication failures

errorCodeMeaning
UNAUTHORIZEDMissing/invalid key or secret, or a revoked/expired credential.
FORBIDDENAuthenticated, but not permitted (admin RBAC).
SESSION_EXPIREDAdmin session no longer valid.
REAUTH_REQUIREDAdmin must re-authenticate before a sensitive action.

All failures use the standard response envelope.

On this page