Webhooks
Webhooks allow Cashless to notify your server when a bill's payment status changes, eliminating the need to poll the API.
Setup
Contact Cashless support to configure a webhook URL for your merchant account. Your endpoint should:
- Accept
POSTrequests with a JSON body - Return a
200status code to acknowledge receipt - Process the payment update (e.g., mark order as paid)
Webhook payload
When a bill is paid, Cashless sends a POST request to your webhook URL:
{
"bill": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"mobile": "0712345678",
"amount": 5000.0,
"status": "FULLY_PAID",
"reference": "ORDER-001"
}
}
Example handler
// Express.js webhook handler
app.post('/webhooks/cashless', (req, res) => {
const { bill } = req.body;
if (bill.status === 'FULLY_PAID') {
// Update your order status
markOrderAsPaid(bill.reference);
}
res.sendStatus(200);
});
Best practices
- Always verify: After receiving a webhook, call GET /bills/{id} to verify the payment status independently. Do not trust the webhook payload alone.
- Idempotency: Your handler may receive duplicate webhooks. Ensure processing the same bill twice is safe.
- Respond quickly: Return
200within a few seconds. Do heavy processing asynchronously. - Fallback: Use polling as a fallback in case webhooks fail to deliver.
Webhook + polling pattern
For maximum reliability, combine webhooks with polling:
// 1. Create bill and start background polling
const bill = await api.issue(params);
startPolling(bill.id);
// 2. Also handle webhooks for faster notification
app.post('/webhooks/cashless', async (req, res) => {
const { bill } = req.body;
// Verify via API
const verified = await api.get(bill.id);
if (verified.status.name === 'FULLY_PAID') {
stopPolling(bill.id);
markOrderAsPaid(bill.reference);
}
res.sendStatus(200);
});