Skip to main content
Tell PayGrid where to deliver signed notifications. You can set URLs per payment or once as merchant defaults.

What to configure

FieldConfigure?Notes
webhook_urlYes (for server-to-server status updates)Delivers lifecycle events; this is what most integrations need
callback_urlNo (optional)One-shot terminal notification with a simpler payload; skip unless you have a dedicated use case
Neither field is required by the API, but without webhook_url you will not receive payment status events. Without callback_url, nothing breaks — callback delivery is simply skipped.

URL resolution

SourceApplies to
webhook_url / callback_url on POST /api/v1/paymentsThat payment (overrides merchant defaults)
Dashboard → Settings → WebhooksMerchant default webhook_url / callback_url (used when omitted on the request)
Priority: per-payment value → merchant default → no delivery.
In production, URLs must be https:// and publicly reachable — private/internal hosts are rejected, and URLs longer than 2048 characters are invalid. Deliveries to an invalid URL are dead-lettered and not retried. Non-production environments may allow http:// and localhost for local testing.

Configure on payment create

Only webhook_url is shown below — that is enough for a standard integration. Omit callback_url unless you need the optional terminal callback.
curl -X POST "https://meet.briq.tz/api/v1/payments" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "amount": 5000,
    "currency": "TZS",
    "type": "mobile",
    "phone": "255712345678",
    "customer": {"firstname": "John", "lastname": "Doe", "email": "[email protected]"},
    "reference": "ORDER_123",
    "webhook_url": "https://api.example.com/paygrid/webhooks"
  }'
Optional: add callback_url if you want a separate one-shot terminal notification in addition to webhooks.

Merchant default URLs

Set a default webhook_url in the dashboard under Settings → Webhooks instead of sending it on every payment. You can also send a signed test event from there. Set webhook_url before creating payouts — payout create does not accept URL fields; the dashboard default is captured at payout creation time. callback_url is optional for payouts as well. For payments, use the dashboard default or pass webhook_url on POST /api/v1/payments — the per-payment value always wins.

Testing

Dashboard test webhook

Send a signed webhook.test event to your configured webhook_url. Save your webhook_url first in the dashboard under Settings → Webhooks.
POST /api/v1/portal/settings/webhooks/test
Authorization: Bearer <session_or_access_token>
The dashboard uses JWT auth (/portal/v1/settings/webhooks/test with your access_token from login works the same way). This endpoint is not available with your API key — use a dashboard session or portal token. Use this to confirm your endpoint is reachable and signature verification works before going live. The test event uses event: "webhook.test" — see Payload reference.

Local development

Expose a local server with a tunnel, then set the HTTPS URL as your webhook_url:
ngrok http 3000
# Use the https URL, e.g. https://abc123.ngrok.io/paygrid/webhooks
Update your webhook_url in the dashboard under Settings → Webhooks. See Webhook setup.

Trigger a real payment event

After creating a test payment, call the refresh endpoint to poll upstream status and trigger webhooks if the status changed:
curl -X POST "https://meet.briq.tz/api/v1/payments/PAYMENT_ID/refresh" \
  -H "Authorization: Bearer YOUR_API_KEY"
Before testing signatures, make sure you have your webhook signing key. Next step: Verify signatures