Payment Webhook Events
Receive notifications for payment transactions.
Available Events
| Event | Trigger |
|---|
payment.succeeded | Payment successfully processed |
payment.failed | Payment attempt failed |
payment.refunded | Payment refunded |
payment.partially_refunded | Partial refund issued |
payment.succeeded
Triggered when payment is successfully processed.
Payload
{
"id": "evt_abc123",
"type": "payment.succeeded",
"created": "2024-01-20T14:30:00Z",
"data": {
"id": "pay_xyz789",
"orderId": "ord_123",
"customerId": "cust_456",
"amount": 81.56,
"currency": "USD",
"method": "card",
"last4": "4242",
"brand": "visa",
"receiptUrl": "https://receipts.tiquo.co/pay_xyz789",
"stripePaymentIntentId": "pi_abc123",
"processedAt": "2024-01-20T14:30:00Z"
}
}
Data Fields
Payment method: card, cash, apple_pay, google_pay
Card brand: visa, mastercard, amex
Example Handler
case 'payment.succeeded':
const payment = event.data;
// Update accounting system
await accounting.recordRevenue({
amount: payment.amount,
orderId: payment.orderId,
paymentId: payment.id,
date: payment.processedAt
});
// Send receipt
await email.send(payment.customerEmail, {
template: 'receipt',
receiptUrl: payment.receiptUrl
});
break;
payment.failed
Triggered when payment attempt fails.
Payload
{
"id": "evt_def456",
"type": "payment.failed",
"created": "2024-01-20T14:35:00Z",
"data": {
"id": "pay_failed789",
"orderId": "ord_123",
"customerId": "cust_456",
"amount": 81.56,
"currency": "USD",
"method": "card",
"last4": "1234",
"failureCode": "card_declined",
"failureMessage": "Your card was declined",
"attemptedAt": "2024-01-20T14:35:00Z"
}
}
Failure Codes
| Code | Description |
|---|
card_declined | Card declined by issuer |
insufficient_funds | Not enough funds |
expired_card | Card has expired |
incorrect_cvc | Wrong CVC entered |
processing_error | Processing error |
authentication_required | 3DS required |
Example Handler
case 'payment.failed':
const failedPayment = event.data;
// Notify customer
await email.send(failedPayment.customerEmail, {
template: 'payment_failed',
reason: failedPayment.failureMessage,
updatePaymentUrl: `https://app.example.com/orders/${failedPayment.orderId}/payment`
});
// Alert staff
await slack.send(`Payment failed for order ${failedPayment.orderId}: ${failedPayment.failureCode}`);
break;
payment.refunded
Triggered when payment is refunded.
Payload
{
"id": "evt_ghi789",
"type": "payment.refunded",
"created": "2024-01-22T10:00:00Z",
"data": {
"id": "ref_abc123",
"paymentId": "pay_xyz789",
"orderId": "ord_123",
"customerId": "cust_456",
"amount": 81.56,
"currency": "USD",
"reason": "Order cancelled",
"refundedBy": "staff_123",
"refundedAt": "2024-01-22T10:00:00Z"
}
}
Example Handler
case 'payment.refunded':
const refund = event.data;
// Update accounting
await accounting.recordRefund({
amount: refund.amount,
originalPaymentId: refund.paymentId,
reason: refund.reason
});
// Notify customer
await email.send(refund.customerEmail, {
template: 'refund_processed',
amount: refund.amount,
reason: refund.reason
});
break;
payment.partially_refunded
Triggered for partial refunds.
Payload
{
"id": "evt_jkl012",
"type": "payment.partially_refunded",
"created": "2024-01-22T11:00:00Z",
"data": {
"id": "ref_partial123",
"paymentId": "pay_xyz789",
"orderId": "ord_123",
"originalAmount": 81.56,
"refundAmount": 25.00,
"remainingAmount": 56.56,
"currency": "USD",
"reason": "Service not provided",
"refundedAt": "2024-01-22T11:00:00Z"
}
}
Use Cases
Accounting Integration
Sync with accounting software:
app.post('/webhooks/tiquo', async (req, res) => {
res.status(200).send('OK');
const event = req.body;
switch (event.type) {
case 'payment.succeeded':
await quickbooks.createInvoice(event.data);
break;
case 'payment.refunded':
await quickbooks.createCreditMemo(event.data);
break;
}
});
Revenue Tracking
Track revenue metrics:
case 'payment.succeeded':
analytics.track('Payment Received', {
amount: payment.amount,
method: payment.method,
customerId: payment.customerId
});
// Update daily revenue
await redis.incrby(`revenue:${today}`, payment.amount);
break;
Failed Payment Recovery
Recover failed payments:
case 'payment.failed':
// Add to retry queue
await queue.add('retry_payment', {
orderId: payment.orderId,
customerId: payment.customerId,
attempts: 1
}, { delay: 24 * 60 * 60 * 1000 }); // Retry in 24 hours
break;