Sandbox live

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.authorised
  • direct_debit.failed
  • direct_debit.setup_completed
  • payment_plan.activated
  • payment.failed
  • payment.confirmed
  • plan.in_arrears
  • plan.cancelled