Authentication
QairoPay supports two authentication patterns. Pick the one that matches what you’re building:
- API keys — for first-party integrations: your server, your code, your data. Most customers use this.
- OAuth 2.1 — for third-party platforms acting on behalf of a QairoPay merchant. Required if you’re building a tool that other QairoPay customers will connect.
Webhook payloads use a third pattern — HMAC signature verification — covered in Signing and verification.
API keys
Every API request must include a bearer token in the Authorization header:
Authorization: Bearer qp_sk_live_01HZX...Keys come in two flavors and three roles:
| Prefix | Flavor | Use |
|---|---|---|
qp_sk_sandbox_ | secret, sandbox | Server-side calls against the sandbox environment |
qp_sk_live_ | secret, live | Server-side calls against the live environment |
qp_pk_sandbox_ | publishable, sandbox | Browser-side calls (limited to pass-template reads and tokenization) |
qp_pk_live_ | publishable, live | Browser-side calls in production |
Never put a secret key in browser, mobile, or end-user-distributed code. Use publishable keys client-side and proxy through your server for anything else.
Creating and rotating keys
In the dashboard, Developers → API keys → New key. Pick the environment and role. The plaintext secret is shown exactly once — store it in your secret manager immediately.
Rotation is a first-class operation. To rotate without downtime:
- Create a new key with the same environment and role.
- Roll it out to your fleet.
- In the dashboard, mark the old key Pending revocation. It continues to work for 24 hours.
- Confirm the new key has fully rolled out (check the Key usage chart).
- Revoke the old key.
Keys do not auto-expire. If a key leaks, revoke it immediately and rotate.
Scoping keys
Every key has a scope: read, write, or admin. Most of your fleet should use write scoped keys. Reserve admin keys for human-operated workflows (CLI, migration scripts) that touch tenant configuration. Keys with the wrong scope return 403 insufficient_scope with the required scope in the error body.
OAuth 2.1
If your product is a platform that other QairoPay merchants connect, use OAuth.
The authorization-code flow with PKCE is the only supported grant. Refresh tokens are rotated on every use and short-lived (30 days). Confidential clients receive an additional client secret; public clients (single-page apps) must use PKCE.
sequenceDiagram
autonumber
participant U as User (merchant)
participant P as Your platform
participant Auth as auth.qairopay.com
participant API as api.qairopay.com
P->>P: Generate code_verifier<br/>code_challenge = SHA256(verifier)
P->>U: Redirect to /oauth/authorize<br/>(client_id, redirect_uri, scope,<br/>code_challenge, state)
U->>Auth: Sign in, review scopes
Auth-->>U: Consent screen
U->>Auth: Approve
Auth-->>P: Redirect with code + state
P->>Auth: POST /oauth/token<br/>(code, code_verifier, client_id)
Auth-->>P: { access_token,<br/> refresh_token,<br/> expires_in }
P->>API: API call<br/>Authorization: Bearer access_token
API-->>P: 200 / 401
Note over P,Auth: Later: refresh
P->>Auth: POST /oauth/token<br/>(refresh_token, grant_type=refresh_token)
Auth-->>P: { access_token, NEW refresh_token } Authorization endpoint: https://auth.qairopay.com/oauth/authorizeToken endpoint: https://auth.qairopay.com/oauth/tokenRevocation endpoint: https://auth.qairopay.com/oauth/revokeScopes match the API key roles (read, write, admin) plus product-specific scopes (pass:read, pass:write, card:read, card:write, settlement:read, settlement:write). Always request the minimum scope set you need.
To register an OAuth client, email [email protected] with your redirect URIs and intended scopes. Self-serve OAuth client registration ships in Q3.
Two-factor for admin operations
Operations that change billing, rotate tenant credentials, or wipe sandbox data require a fresh second factor in the same request. You’ll see factor_required in the error response with a one-time challenge URL the dashboard user must complete. SDKs surface this as MFAChallengeRequired and walk the user through it.
Network controls
Production traffic uses TLS 1.3. The platform refuses TLS < 1.2. Optional IP allowlists restrict where requests with a given key can originate — configure them per key in the dashboard.