Manage Webhooks
webhooks.list.subtitle
Last Updated: March 8, 2026
Overview
Webhooks allow Pause POS merchants to receive real-time notifications when events happen in their POS system. Merchants can configure custom HTTP endpoints to receive JSON payloads.
Order Completed
When a POS order is synced
Order Refunded
When an order is refunded or credit note created
Stock Low
When product stock drops below minimum threshold
Shift Closed
When a cash drawer shift is closed
API Integration
Available Functions
All webhook functions are already exported from `lib/api.ts` and ready to use:
// Fetch all webhooks for current tenant
fetchWebhooks(): Promise<ApiWebhook[]>
// Get single webhook details
fetchWebhookById(id: number): Promise<ApiWebhook>
// Create new webhook (returns secret)
createWebhook(data: CreateWebhookInput): Promise<ApiWebhook & { secret: string }>
// Update webhook (events, headers, name)
updateWebhook(id: number, data: Partial<CreateWebhookInput>): Promise<ApiWebhook>
// Delete webhook
deleteWebhook(id: number): Promise<void>
// Rotate signing secret
rotateWebhookSecret(id: number): Promise<ApiWebhook & { secret: string }>
// Fetch delivery attempts log
fetchWebhookDeliveries(id: number, limit?: number): Promise<ApiWebhookDelivery[]>
// Manually retry a failed delivery
redeliverWebhook(webhookId: number, deliveryId: number): Promise<void>TypeScript Types
interface ApiWebhook {
id: number;
tenant_id: string;
name: string;
url: string;
events: string; // JSON array: ["order.completed","stock.low"]
secret?: string; // Only shown on creation
headers?: string; // Custom headers as JSON
is_active: boolean;
created_at: string;
updated_at: string;
}
interface ApiWebhookDelivery {
id: number;
tenant_id: string;
webhook_id: number;
event_type: string;
payload: string; // JSON payload sent
response_status: number; // HTTP status code
response_body: string; // Response from endpoint
attempt_count: number;
next_retry_at: string | null;
status: 'pending' | 'delivered' | 'failed' | 'retrying';
created_at: string;
updated_at: string;
}
interface CreateWebhookInput {
name: string;
url: string;
events: string[]; // Array of event types
headers?: Record<string, string>;
}Example Webhook Payload
This is an example of what your webhook endpoint will receive:
{
"id": "delivery-uuid",
"event": "order.completed",
"tenant_id": "tenant-uuid",
"created_at": "2026-03-08T10:30:00Z",
"data": {
"order_id": 123,
"invoice_number": "TAXINV-2026-000001",
"total_amount": 150.00,
"items_count": 3
}
}Implementation Guide
Secret Handling
The webhook secret is shown only once after creation. You should:
- Store the secret securely on your backend
- Use it to verify webhook signatures via HMAC-SHA256
- Rotate the secret periodically for security
- Never expose the secret in client-side code
Webhook URL Requirements
- Must use HTTPS (encrypted connection required)
- Must return HTTP 2xx status to confirm delivery
- Should respond within 30 seconds
- Timeouts or errors trigger automatic retries
Automatic Retry Logic
Failed deliveries are automatically retried on this schedule:
Attempt 1: Immediate failure
Attempt 2: 1 minute later
Attempt 3: 5 minutes later
Attempt 4: 30 minutes later
Max attempts: 4 (then marked as failed)Testing Your Webhooks
Recommended: webhook.site
Use webhook.site for free testing and debugging:
- Visit webhook.site
- Copy your unique URL
- Paste it in your webhook configuration
- Trigger an event (e.g., complete an order)
- See the request in real-time
// Example webhook endpoint (Node.js)
import crypto from 'crypto';
app.post('/webhooks/pause', (req, res) => {
const signature = req.headers['x-pause-signature'];
const payload = JSON.stringify(req.body);
// Verify signature
const hash = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(payload)
.digest('hex');
if (hash !== signature) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process webhook
const { event, data } = req.body;
switch (event) {
case 'order.completed':
// Handle order completion
break;
case 'stock.low':
// Handle low stock alert
break;
}
// Return 200 OK to confirm delivery
res.json({ success: true });
});Best Practices
✅ Always verify signatures
Validate the X-Pause-Signature header using HMAC-SHA256 to ensure the webhook came from Pause POS.
✅ Respond quickly
Your webhook endpoint should respond within 30 seconds. Queue long-running tasks asynchronously.
✅ Handle duplicates
Webhooks may be delivered multiple times. Use idempotency keys (event ID) to prevent duplicate processing.
✅ Use HTTPS only
All webhook URLs must use HTTPS to protect sensitive business data in transit.