Documentation Index
Fetch the complete documentation index at: https://docs.toffeepay.com/llms.txt
Use this file to discover all available pages before exploring further.
ToffeePay uses webhooks to notify your backend when important events occur, such as successful payments, completed refunds or successful wallet deposits. All webhooks are signed using Standard Webhooks.
Webhook Structure
All ToffeePay webhooks follow a consistent structure:
{
"type": "session.created",
"timestamp": "2023-06-01T12:05:00Z",
"data": {
// Event-specific data
}
}
Fields:
type: Event type (e.g., session.created, payment.succeeded, deposit.succeeded)
timestamp: ISO 8601 timestamp when the event occurred
data: Event-specific payload containing the relevant entity data
Webhook Events
Payment Events
| Event | Description |
|---|
session.created | A payment session was created |
session.paid | A session was successfully paid |
session.failed | A payment attempt related to a session failed |
session.expired | A session expired without payment |
session.cancelled | A session was cancelled |
payment.created | A payment was created |
payment.succeeded | A payment was successfully processed |
payment.failed | A payment attempt failed |
payment.authorized | A payment was authorized for later capture |
payment.cancelled | A payment was cancelled |
refund.created | A refund was created |
refund.succeeded | A refund was processed successfully |
refund.failed | A refund attempt failed |
Wallet Events
| Event | Description |
|---|
deposit.succeeded | A wallet deposit completed successfully |
deposit.failed | A wallet deposit failed |
Webhook Signature Verification
All webhooks are signed using Standard Webhooks. Each request includes these headers:
| Header | Description |
|---|
webhook-id | Unique message identifier for idempotency |
webhook-timestamp | Unix timestamp of the event |
webhook-signature | Signature in format v1,{base64-encoded-signature} |
Verification
Use the official Standard Webhooks libraries to verify webhook signatures:
import { Webhook } from "standardwebhooks";
const wh = new Webhook(process.env.WEBHOOK_SECRET);
function handleWebhook(req: Request) {
const payload = wh.verify(req.body, req.headers);
switch (payload.type) {
case 'session.paid':
handleSessionPaid(payload.data);
break;
case 'payment.succeeded':
handlePaymentSuccess(payload.data);
break;
case 'refund.succeeded':
handleRefundSuccess(payload.data);
break;
case 'deposit.succeeded':
handleDepositSuccess(payload.data);
break;
}
}
Idempotency
Webhooks may be delivered more than once. Use the webhook-id header to deduplicate:
const webhookId = req.headers['webhook-id'];
if (await isProcessed(webhookId)) {
return; // Skip duplicate
}
// ... verify and process
await markProcessed(webhookId);
Webhook Configuration
You can configure and manage your webhook settings:
- Webhook URL: The endpoint where ToffeePay will send webhooks
- Webhook Secret: Used to sign webhook payloads (can be rotated)
- Event Selection: Choose which events to receive (payments, refunds, deposits, or all)
Best Practices
- Always verify signatures: Never process webhooks without signature verification
- Handle duplicate events: While rare, webhooks may be sent multiple times — use the
webhook-id header for idempotency
- Respond quickly: Return a 200 status code within 10 seconds to acknowledge receipt
- Retry logic: ToffeePay will retry failed webhooks, but implement your own retry logic for critical operations
- Log webhook events: Keep audit logs of all webhook events for debugging and compliance
- Use HTTPS: Always use HTTPS endpoints for webhook URLs
Troubleshooting
Common Issues
- Signature verification fails: Check that you’re using the correct webhook secret and following the verification steps exactly
- Timeout errors: Ensure your webhook endpoint responds within 10 seconds
- Missing webhooks: Check your webhook URL configuration and ensure your endpoint is accessible
Testing Webhooks
Use tools like ngrok for local development to expose your local webhook endpoint to ToffeePay: