Webhooks
StudentPay → provider outbound webhooks only.
This page does not document inbound GoCardless webhooks.
Configuration
Outbound delivery is optional. It runs only when StudentPay has configured a destination URL and signing secret for your environment. It is not enabled automatically.
Until then, GET /v1/environment may show readiness.webhook_destinations_configured: false. Create, GET, and confirm still succeed. Poll GET for setup complete and agreement ids.
Ask StudentPay to configure sandbox first.
Implemented
Only these events are emitted by the NZ API.
| Event | When | Replay |
|---|---|---|
checkout.created |
New provider checkout created | Not sent on idempotent create replay |
checkout.confirmed |
Enrolment confirmed | Not sent when already_confirmed |
agreement.generated |
Agreement PDF stored during that confirm | Only if pdf_generated is true; not sent on confirm replay |
No direct_debit.*, payment, or arrears events are implemented.
Envelope
{
"event_id": "evt_…",
"event": "checkout.created",
"created_at": "2026-08-13T01:40:00.000Z",
"request_id": "req_…",
"environment": "sandbox",
"data": {}
}
Treat event_id as idempotent. The API retries in-request up to 3 times (0 / 250 / 750 ms) with the same event_id and signed body.
Signature
| Header | Purpose |
|---|---|
X-StudentPay-Event |
Event name |
X-StudentPay-Event-Id |
evt_… |
X-StudentPay-Timestamp |
Unix seconds used in the signature |
X-StudentPay-Signature |
t=<timestamp>,v1=<hmac_sha256_hex> |
X-StudentPay-Delivery-Attempt |
1-based attempt |
X-StudentPay-Delivery-Max-Attempts |
Default 3 |
X-Request-Id |
Correlated API request id when available |
Canonical string: timestamp, then ., then the raw JSON body. HMAC-SHA256 with the configured webhook secret.
checkout.created data
{
"provider_code": "SANDBOX_DEMO",
"provider_order_id": "DEMO-ENROLMENT-1001",
"checkout_id": "SANDBOX_DEMO-1720000000000-AB12CD34",
"opportunity_id": "006XXXXXXXXXXXX",
"dda_id": "a0XXXXXXXXXXXXX",
"contact_id": "003XXXXXXXXXXXX"
}
checkout.confirmed data
{
"provider_code": "SANDBOX_DEMO",
"provider_order_id": "DEMO-ENROLMENT-1001",
"checkout_id": "SANDBOX_DEMO-1720000000000-AB12CD34",
"opportunity_id": "006XXXXXXXXXXXX",
"dda_id": "a0XXXXXXXXXXXXX",
"status": "Confirmed",
"payment_plan_agreement_id": "a0JXXXXXXXXXXXX"
}
agreement.generated data
{
"provider_code": "SANDBOX_DEMO",
"provider_order_id": "DEMO-ENROLMENT-1001",
"checkout_id": "SANDBOX_DEMO-1720000000000-AB12CD34",
"opportunity_id": "006XXXXXXXXXXXX",
"payment_plan_agreement_id": "a0JXXXXXXXXXXXX",
"payment_plan_agreement_number": "PPA-000001",
"pdf_content_document_id": "069XXXXXXXXXXXX",
"agreement_version": "2026-08-02"
}
Not implemented
Do not build handlers for these. They are not emitted.
direct_debit.authoriseddirect_debit.faileddirect_debit.setup_completedpayment_plan.activatedpayment.failedpayment.confirmedplan.in_arrearsplan.cancelled