Identity & access
Authentication
Vouchify separates machine credentials, interactive identity, public widget keys, and callback credentials so each trust boundary stays explicit.
Choose the credential by actor
Merchant API token
Use for durable backend integrations that call explicitly enabled business endpoints.
- Explicit scopes
- Merchant-bound
- Rotatable
Interactive JWT
Use for signed-in merchant actions, sensitive operations, and API-token management.
- OTP or OAuth identity
- Refresh lifecycle
- User context
Public widget key
Use only for the separate widget checkout/read contract guarded by x-public-key.
- Not a bearer token
- Not interchangeable
Merchant API tokens
Version 1 tokens are owned by a merchant owner and permanently bound to that merchant. The credential looks like this:
Authorization: Bearer vou_<43-character-base64url-secret>.v1| Format | vou_ + 43 base64url characters + .v1 |
|---|---|
| Entropy | 32 cryptographically random bytes (256 bits) |
| Storage | SHA-256 of the complete token; plaintext is never persisted |
| Owner | Active user with role MERCHANT who still owns the bound active merchant |
| Capacity | Five records per merchant; expired and revoked records continue to occupy slots |
| Expiry | 90 days by default; custom expiry ≥24 hours away; null means never expires |
How a request is processed
- 01Parse
Read the bearer header. A credential beginning with
vou_must match the strict versioned token format. - 02Resolve
Hash the complete credential with SHA-256 and find its record through the unique hash index.
- 03Revalidate
Reject malformed, unknown, revoked, expired, or unsupported credentials; then load the owner and merchant.
- 04Enforce
Attach live identity and auth metadata, enforce the route scope, then continue through existing role and permission guards.
request.auth = {
type: 'api-token',
apiTokenId: string,
merchantId: string,
scopes: ApiTokenScope[],
generation: number
};Interactive JWTs
JWTs represent a signed-in user, not a long-lived integration. They remain required for token management, authentication, account security, payment mutations, ownership operations, KYB mutations, and other sensitive routes.
Bypasses API-token scope metadata, but still passes normal JWT, role, merchant, and permission checks.
Must satisfy an explicit route scope in addition to every live identity and permission constraint.
An API token presented to a management route is rejected. Use the email + OTP token console to establish a temporary JWT session for administration.
Other authentication contracts
Widget API
Uses x-public-key with WidgetApiKeyGuard. Widget checkout and reads do not accept merchant bearer tokens.
Callbacks
pawaPay and Apple Wallet callbacks keep callback authentication. Withdrawal verification links use dedicated link credentials.