Partners

Webhooks

Niftipay pushes partner-relevant events to the webhook URL configured on the integration. Each delivery is a signed POST.

Verifying a webhook

Every delivery carries two headers you must check before trusting the body:

Header Meaning
x-signature v1=<hex hmac-sha256(secret, "${x-timestamp}.${raw body}")>
x-timestamp Unix seconds at send time
x-webhook-id The id of the destination webhook

Recompute hmac-sha256(secret, "<x-timestamp>.<raw request body>") and compare it to the v1= value in x-signature. Reject mismatches, and reject timestamps that fall outside a small clock-skew window. Always return 2xx quickly and process asynchronously — a slow handler is retried as if it failed.

Event shape

{
  "event_id": "evt_3f9a...",
  "event_type": "payment.confirmed",
  "created_at": "2024-01-01T00:00:00.000Z",
  "partner_id": "client_abc123",
  "data": {
    "partner_customer_id": "pc_1",
    "order_id": "1001",
    "status": "paid"
  }
}

event_id is unique per delivery; use it to dedupe. The data field carries only identifiers and status — never raw documents or PII. Re-read detail through the API where scopes still apply.

The events Niftipay can emit today:

  • customer.updated
  • verification.pending
  • verification.approved
  • verification.rejected
  • agreement.accepted
  • document.reviewed
  • capability.updated
  • payment.confirmed
  • payment.expired

Retries

Failed deliveries are retried up to six times with exponential backoff: 1m, 5m, 25m, 2h, 10h, 24h. A 2xx response ends delivery; a non-retryable 4xx is dead-lettered; a 5xx or network timeout is retried on the schedule above. Use event_id to dedupe across retries.

Webhooks are delivered only for the customers this partner onboarded, and only to destinations it supplied. A partner never receives another partner’s events.