Essentials
Webhooks
Real-time notifications for checkout payment events
How It Works
When you create a checkout with a webhookUrl, we send HTTP POST requests to your endpoint when payments are processed.
Important: Your webhook endpoint must be publicly accessible and respond with HTTP 200 status.
Webhook Types
Checkout Events
checkout.paid- Exact payment amount receivedcheckout.overpaid- More than required amount paidcheckout.underpaid- Less than required amount paid
Webhook Payload
All webhooks include the same payload structure:
200
{
"type": "checkout.paid",
"data": {
"checkoutId": "ch_xyz123",
"amount": 29.99,
"currency": "USD",
"status": "completed",
"metadata": {
"orderId": "order_12345",
"customerEmail": "customer@example.com"
},
"timestamp": "2024-01-15T10:30:00Z"
}
}
Implementation Example
Here's how to handle webhooks in your application:
POST
// Webhook endpoint
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
const webhook = req.body;
switch (webhook.type) {
case 'checkout.paid':
// Handle exact payment
console.log('Payment completed:', webhook.data.checkoutId);
// Update your database, send confirmation email, etc.
break;
case 'checkout.overpaid':
// Handle overpayment
console.log('Overpayment detected:', webhook.data.checkoutId);
// Maybe issue refund or store credit
break;
case 'checkout.underpaid':
// Handle underpayment
console.log('Underpayment detected:', webhook.data.checkoutId);
// Maybe send reminder or cancel order
break;
}
// Always respond with 200
res.status(200).send('OK');
});
Security
Always verify webhook authenticity:
Security Note: Verify the webhook signature to ensure requests are from Zyrapay. Check the source IP and validate the payload structure.