wallet.top_up
Sent when a top-up is confirmed and the money is added to the workspace wallet.
Sent when a top-up is confirmed and the money is added to the workspace wallet.
wallet.top_up is sent once a top-up is confirmed and the wallet has been credited. Calls that were refused for a low balance can be placed again from this point.
Subscribe by adding wallet.top_up to the events of a webhook created with POST /v1/webhooks.
The body is flat JSON. The event name is in the X-Sautikit-Event-Kind header, not in the body.
{
"workspace_id": "01900000-0000-7000-8000-000000000002",
"topup_id": "01900000-0000-7000-8000-000000000005",
"ledger_id": "01900000-0000-7000-8000-000000000006",
"provider": "mpesa",
"provider_ref": "SJK4XXXXXX",
"amount_minor": 100000,
"currency": "KES",
"balance_after": 104800
}| Field | Type | Description |
|---|---|---|
workspace_id | string (UUID) | The workspace that was topped up. |
ledger_id | string (UUID) | The wallet statement entry for this credit. |
amount_minor | integer | Amount added, in minor units (KES cents). 100000 is KES 1,000.00. |
currency | string | Wallet currency, for example KES. |
balance_after | integer | Wallet balance after the credit, in minor units. |
topup_id | string (UUID) | The top-up. Present on M-Pesa and card top-ups. |
provider | string | mpesa or paystack. Present on M-Pesa and card top-ups. |
provider_ref | string | The payment provider's reference. Present on M-Pesa and card top-ups. |
reference | string | Present instead of the three fields above when the credit did not come through a payment provider. |
| Header | Description |
|---|---|
X-Sautikit-Event-Kind | wallet.top_up. Route on this. |
X-Sautikit-Event-Id | UUID of the event. Deduplicate on this. |
X-Sautikit-Delivery-Id | UUID of this delivery. |
X-Sautikit-Attempt | Attempt number, starting at 1. |
X-Sautikit-Timestamp | Unix time (seconds) when the delivery was signed. |
X-Sautikit-Signature | t=<timestamp>,v1=<hex HMAC-SHA256>. See Verify webhook signatures. |
X-Sautikit-Event-Id header.// verifyWebhook is the function from the "Verify webhook signatures" guide.
import { verifyWebhook } from "./verify-webhook.js";
export async function POST(req) {
const body = await req.text();
try {
verifyWebhook(body, req.headers.get("x-sautikit-signature") ?? "", process.env.WEBHOOK_SECRET);
} catch {
return new Response("Forbidden", { status: 403 });
}
if (req.headers.get("x-sautikit-event-kind") === "wallet.top_up") {
const { amount_minor, currency, balance_after } = JSON.parse(body);
console.log(`Top-up: ${currency} ${amount_minor / 100}, balance now ${balance_after / 100}`);
// clear low-balance alerts, resume paused work
}
return new Response("OK", { status: 200 });
}wallet.low_balance to know when to top up.