Webhooks
Receive real-time notifications when order status changes. Signed JSON payloads, easy verification.
A webhook is an HTTP callback — when an order status changes, we send a POST request to your URL with the event data. You don't need to poll; you get instant notifications.
Setup
Via Reseller Panel
Open Settings → Webhook, enter your URL (https:// or http://), save. The secret is generated automatically and shown in the same section — keep it safe. Buttons in the same panel let you rotate the secret (old one stops working immediately) and send a test event.
Public API v2
Full API control: GET/PUT /api/v2/account/webhook (URL + enabled), POST /api/v2/account/webhook/secret/regenerate, POST /api/v2/account/webhook/test, GET /api/v2/account/webhook/deliveries. Authenticate with X-API-Key or Authorization: Bearer.
api.fzr.cards/public/docsEvents
The webhook fires several event types for every order on the account. No extra subscription needed — once URL is set, all events are sent.
| Event | When triggered |
|---|---|
| order.created | order.created — order is created (any type, including API-created and panel-created) |
| order.status_changed | order.status_changed — order status transitioned (processing → completed/failed/refunded/…) |
| manual_service.chat.* | manual_service.chat.message — new supplier message in a manual-service chat; manual_service.chat.waiting_reply — supplier is waiting for the customer's reply |
Payload Format
docs.webhooks.payloadDesc
docs.webhooks.payloadFields
{
"event": "order.status_changed",
"event_id": "8f3a2c9e-1b4d-4f7a-9e2c-5b6a8c1d2e3f",
"timestamp": "2026-03-14T12:34:56.789Z",
"data": {
"order_id": "ord-1001",
"type": "giftcard",
"status": "completed",
"previous_status": "processing"
}
}docs.webhooks.completedPayloadNote
Manual-service chat message example
{
"event": "manual_service.chat.message",
"event_id": "1d2c3b4a-5e6f-7a8b-9c0d-e1f2a3b4c5d6",
"timestamp": "2026-03-14T12:34:56.789Z",
"data": {
"order_id": "ord-1002",
"type": "manual",
"message_preview": "Hi! Could you confirm the recipient handle?",
"message_created_at": "2026-03-14T12:34:55Z"
}
}Signature Verification
docs.webhooks.signatureDesc
The signature proves the request came from FazerCards. Without verification, an attacker could forge webhooks. Always verify before processing.
Node.js example
const crypto = require('crypto');
function verifyWebhookSignature(rawBody, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature, 'utf8'),
Buffer.from(expected, 'utf8')
);
}
// Usage (Express)
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-webhook-signature'];
if (!verifyWebhookSignature(req.body.toString(), sig, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const payload = JSON.parse(req.body.toString());
// Process payload...
res.status(200).send('OK');
});Python example
import hmac
import hashlib
def verify_webhook_signature(raw_body: bytes, signature: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(),
raw_body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
# Usage (Flask)
@app.route('/webhook', methods=['POST'])
def webhook():
raw_body = request.get_data()
sig = request.headers.get('X-Webhook-Signature', '')
if not verify_webhook_signature(raw_body, sig, os.environ['WEBHOOK_SECRET']):
return 'Invalid signature', 401
payload = request.get_json()
# Process payload...
return 'OK', 200Regenerate Secret
Via panel Settings or via POST /api/v2/account/webhook/secret/regenerate. The old secret stops working immediately — update it in your receiver.
Retry Policy
Up to 3 retries with exponential backoff (1 minute, 5 minutes, 30 minutes) for non-2xx responses or 10s timeout. After 50 consecutive failures the webhook is auto-disabled — re-enable it in settings after fixing the receiver.
Security
- Always verify the signature
- Use HTTPS in production
- Store the secret securely
- Respond quickly (200 within seconds); do heavy work asynchronously