Webhooks
Receive real-time notifications when events happen in a store.
Setup
- Go to Store Settings > Notifications > Webhooks or use the API.
- Provide an HTTPS endpoint URL.
- Select the events you want to receive.
- Copy the webhook secret for signature verification.
const webhook = await tanqory.webhooks.create(storeId, {
url: 'https://example.com/webhooks/tanqory',
events: ['order.created', 'order.fulfilled', 'product.updated'],
})
// Save webhook.secret securely
Event Payload
{
"id": "evt_abc123",
"event": "order.created",
"storeId": "store_xyz",
"createdAt": "2026-04-09T10:00:00Z",
"data": {
"id": "ord_abc123",
"orderNumber": 1042,
"total": { "amount": 39900, "currency": "THB" }
}
}
Event Types
| Category | Events |
|---|---|
| Orders | order.created, order.updated, order.cancelled, order.fulfilled, order.refunded |
| Products | product.created, product.updated, product.deleted |
| Customers | customer.created, customer.updated, customer.deleted |
| Inventory | inventory.updated, inventory.low_stock |
| Checkout | checkout.created, checkout.completed, checkout.abandoned |
| Themes | theme.published, theme.updated |
| App | app.installed, app.uninstalled |
Signature Verification
Every webhook request includes an x-tanqory-signature header. Always verify it before processing.
import { verifyWebhookSignature } from '@tanqory/sdk'
app.post('/webhooks/tanqory', express.raw({ type: 'application/json' }), (req, res) => {
const isValid = verifyWebhookSignature(
req.body, // Raw body (Buffer or string)
req.headers['x-tanqory-signature'], // Signature header
process.env.TANQORY_WEBHOOK_SECRET, // Secret from dashboard
)
if (!isValid) return res.status(401).send('Invalid signature')
const event = JSON.parse(req.body)
// Process event...
res.status(200).send('OK')
})
The signature is an HMAC-SHA256 hex digest of the raw request body using your webhook secret.
Retry Policy
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 24 hours |
A delivery is considered failed if your endpoint returns a non-2xx status code or times out (30s). After 5 failed attempts, the webhook is marked as failing. Fix the issue and re-enable from the dashboard.
Best Practices
- Always return
200quickly; process events asynchronously. - Use the
idfield to deduplicate events (retries send the sameid). - Verify signatures on every request.
- Use
express.raw()or equivalent to get the raw body for signature verification.