Partner webhooks
A partner endpoint receives the events of all of the partner’s stores, so the platform needs one receiver, not one
per store. Manage endpoints with the Partner API (partner.webhooks:manage):
curl -X POST "https://api.nexafone.so/api/v1/partner/webhook-endpoints" \ -H "Authorization: Bearer $NEXAFON_PARTNER_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://platform.example/hooks/nexafon", "events": ["order.created", "order.paid", "message.received"]}'Each event carries the store it comes from:
{ "id": "7c6b5a49-3827-4165-9483-a2b1c0d9e8f7", "type": "order.paid", "createdAt": "2026-09-21T14:13:18Z", "workspaceId": "bbbbbbbb-0000-0000-0000-000000000000", "partner": { "storeExternalRef": "shop-1" }, "data": { "order": { "number": 1042, "status": "paid", "totalCents": 2800 } }}Deliveries are signed, retried and logged exactly like a workspace’s: see signatures,
retries and the event catalog. The helpers’ verifyWebhook handles
both kinds.
// One endpoint receives every store's events; partner.storeExternalRef names the store.export function onDelivery(headers: Record<string, string>, rawBody: Buffer) { const event = verifyWebhook(headers, rawBody, process.env.NEXAFON_PARTNER_WEBHOOK_SECRET ?? '') if (event.type === 'order.paid') { console.log('paid order in', event.partner?.storeExternalRef, event.id) } return event}Stores can still have their own endpoints too; an event goes to both.