callCash() / Webhooks
One webhook. From every gateway, already checked.
Each gateway tells you about a payment in its own format. You get one event, already checked, whichever gateway the money went through.
Netcash
TransactionAccepted=true Reference=CC1042 Amount=185.00 RequestTrace=7f3c…Yoco
{ "type": "payment.succeeded", "payload": { "amount": 18500 } }Ozow
{ "Status": "Complete", "Amount": "185.00", "Hash": "…" }Peach
{ "result": { "code": "000.000.000" }, "amount": "185.00" }
{
type: "payment.paid",
reference: "order_1042",
amount: 185.00,
method: "instant_eft",
gateway: "netcash",
verified: true
}verified: true means we checked the payment with the gateway ourselves before telling you. Some gateways, Netcash among them, send notifications with no signature, so we never take one on its word.
Gateways, in the order we’re connecting them
- Netcashfirst
- Yocofirst
- Peach Paymentsnext
- Ozownext
- iKhokhanext
- PayFastnext
- Paystacknext
- Yours isn’t here? Tell us
Webhooks on your laptop.
Gateways can’t reach localhost, so testing payments usually means deploying first. callcash listen forwards test events to your machine, and shows you the retries when your handler falls over.
Planned, not built yet. This is what it will print.
$ npx callcash listen --forward localhost:3000/api/hooks
Ready. Test events from Netcash and Yoco now reach this laptop.
14:05:02 payment.paid R185.00 netcash → 200 41ms
14:05:40 payment.pending R60.00 netcash → 200 37ms
14:05:58 payment.paid R1 120.00 yoco → 500 12ms
14:05:59 payment.paid R1 120.00 yoco → 200 39ms retried
14:06:12 payment.paid R60.00 netcash → 200 35ms
Delivered until your handler accepts it.
Today callCash runs inside your own server. If your handler throws, we answer the gateway 500, so Yoco or Netcash sends it again on its own schedule, and the event keeps the same id. Anything still owed is picked up by cash.events.deliver() from a cron. When the hosted service ships, its retry window goes on this page before it handles a single payment.
- 1stnow500your handler threw
- 2ndgateway retries500still throwing
- 3rdgateway retries200delivered, same event id