Two calls.Offline payments live.
Issue a vault, sync payments, listen for events. Your ledger stays in charge.

Issue an allowance
Your backend asks PayVault to sign an allowance for a user's device key, after you lock the funds in your ledger.
Sync payments
Devices upload signed, chained payments when they have signal. You get accepted, duplicate and fork results back.
Listen to events
Webhooks tell your ledger when to settle, recover or revoke.
Two calls toget going
Request shapes are shown for orientation. See the docs for the current reference.
POST /api/v1/allowances
Authorization: Bearer pv_<prefix>_<secret>
Content-Type: application/json
{
"devicePublicKey": "02c4f1...e9",
"country": "NG",
"funded": 500000,
"credit": 0,
"externalRef": "cust_8123_vault_1",
"ttlHours": 72
}
// 201 Created
{
"id": "9f2c1e5b7a3d4c08b6e1a2d3f4c5b6a7",
"cert": "AQEAn8sc63...",
"issuerKid": 3,
"currency": "NGN",
"expiresAt": "2026-10-02T09:30:00.000Z"
}POST /api/v1/payments/sync
Authorization: Bearer pv_<prefix>_<secret>
Content-Type: application/json
{
"bundles": ["AQMBAQEAn8sc...", "AQMBAQEAn8sc..."]
}
// 200 OK
{
"results": [
{ "id": "5d0e...c1", "status": "settled", "amount": 250000, "currency": "NGN" },
{ "id": "77ab...09", "status": "flagged" }
]
}{
"id": 1042,
"type": "fraud.detected",
"createdAt": "2026-10-02T11:04:12.000Z",
"data": {
"allowanceId": "9f2c...",
"cases": [{ "kind": "fork", "seq": 3, "paymentIds": ["5d0e...c1", "77ab...09"], "loss": 0 }]
}
}SDKs
- Web SDKAvailable
- Android (Kotlin)Planned
- iOS (Swift)Planned
- USSD / SIMPlanned
Builtfor integrators
- Idempotent payment sync, so retries are safe
- Signed webhooks with replay protection
- Sandbox with test money and the same API
- Amounts as integers in minor units
