Webhooks
Receive signed order.completed events on your server. This is the only supported way to fulfill orders programmatically.
Setup
- Open Developer in your dashboard.
- Add your HTTPS endpoint URL.
- Save the signing secret when shown — it is only displayed once.
- Use "Send test" to confirm your server receives events.
- Implement signature verification before fulfilling orders.
Event: order.completed
Sent when a buyer's payment succeeds. Flint retries up to 3 times if your endpoint does not return a 2xx response.
Headers
Flint-Signature— HMAC signature (verify before trusting)Flint-Event—order.completedFlint-Delivery-Id— unique event idFlint-Webhook-Test—trueon test deliveries from the dashboard
Payload
order.completed
{
"id": "evt_...",
"type": "order.completed",
"created_at": "2026-06-30T12:00:00.000Z",
"data": {
"order": {
"id": "order-uuid",
"product_id": "product-uuid",
"amount": 1000,
"currency": "usd",
"status": "completed",
"customer_email": "[email protected]",
"payment_method": "crypto",
"product_name": "My product",
"platform_fee_cents": 50,
"seller_net_cents": 950,
"payment_reference_id": "...",
"completed_at": "2026-06-30T12:00:00.000Z"
}
}
}Verify signatures
Signature format: t=timestamp,v1=hex_hmac. Compute HMAC-SHA256 of {timestamp}.{raw_body} using your signing secret.
Node.js
import crypto from "crypto";
function verifyFlintWebhook(rawBody, signatureHeader, secret) {
const parts = Object.fromEntries(
signatureHeader.split(",").map((p) => p.split("="))
);
const expected = crypto
.createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
return expected === parts.v1;
}Do not use success_url for fulfillment
The buyer redirect is for UX only. Always deliver products from verified webhook events.