Sandbox live

Quickstart

Integrate an education-provider enrolment wizard with StudentPay.

This guide covers the two flows used by Academy Australia–style pages:

  1. Pay Now — full course fee by card (Pinch Capture.js → create checkout)
  2. Payment plan — create checkout → hosted DDA → confirm enrolment

Choose your path

Step Pay Now (card) Payment plan (direct debit)
1. Create checkout payment_type: upfront_payment + card_payment.token payment_type: interest_free_payment_plan
2. Collect bank authority Not used Open / embed direct_debit.setup_url
3. Finish enrolment In your UI: accept the education provider Terms & Conditions, then treat card_payment.success on create as payment complete. Do not call StudentPay confirm (that API requires a DDA). After DDA authorised: POST …/confirm with declarations + dda_id
4. Done when Card charged; Opportunity created with Paid Upfront / Payment Processing; no DDA and no Payment Plan Agreement Opportunity Payment Plan Signed + Payment Plan Agreement PDF

See Authentication and Environments.

0. Confirm sandbox

curl https://sandbox-api.studentpay.com.au/v1/environment

Expect "environment": "sandbox", "pinch_mode": "test", and pinch_publishable_key (publishable by design for Capture.js).

Your API key’s provider_code must match the body (sandbox demos often use SANDBOX_DEMO).

1. Authenticate

Authorization: Bearer <PROVIDER_API_KEY>
Content-Type: application/json

Path A — Pay Now (full card payment)

A1. Tokenise the card in the browser

Never POST raw card numbers to StudentPay.

const capture = new Pinch.Capture({
  publishableKey: pinchPublishableKey // from GET /v1/environment
});

const result = await capture.createToken({
  sourceType: "credit-card",
  cardNumber: "4242424242424242",
  expiryMonth: "11",
  expiryYear: "2027",
  cvc: "123",
  cardHolderName: "Jamie Nguyen"
});

const token = result.token;

Load Capture.js from https://cdn.getpinch.com.au/capturejs/pinch.capture.v2.js.

Sandbox test cards

Any future expiry + any CVC:

Card number Type
4242424242424242 Visa (AU)
4000000360000006 Visa (AU)
378282246310005 AMEX (AU)
5105105105105100 Mastercard

Do not use placeholder numbers such as 1234123412341234.

A2. Create checkout with the token

POST /v1/provider-checkouts
Idempotency-Key: AA-ENROLMENT-67890
{
  "provider": {
    "provider_code": "SANDBOX_DEMO",
    "provider_order_id": "AA-ENROLMENT-67890",
    "provider_account_id": "001XXXXXXXXXXXX"
  },
  "student": {
    "first_name": "Jamie",
    "last_name": "Nguyen",
    "email": "jamie.nguyen@example.com"
  },
  "course": {
    "course_name": "Advanced Full Stack Developer Accelerator"
  },
  "pricing": {
    "course_price": 4995,
    "amount_to_finance": 4995,
    "upfront_payment": 4995
  },
  "plan": {
    "payment_type": "upfront_payment",
    "payment_frequency": "Upfront",
    "number_of_instalments": 1,
    "instalment_amount": 4995,
    "first_payment_date": "2026-08-18"
  },
  "card_payment": {
    "token": "pt_test_xxxxxxxx",
    "amount_to_charge_now": 4995,
    "payment_purpose": "card"
  }
}

plan.* remains required. pricing.amount_to_finance must be > 0 — for full Pay Now, send the course fee.

Schemas: Create a provider checkout.

A3. Finish enrolment in your UI (not StudentPay confirm)

Accept the education provider Terms & Conditions in your checkout UI.

Treat card_payment.success === true on create as payment complete. Do not call confirm — it requires checkout.dda_id, and Pay Now does not create a DDA or Payment Plan Agreement.

Done when: Checkout Status Payment Processing, Authorisation Status Paid Upfront, zero Direct Debit Authorisations, zero Payment Plan Agreements.


Path B — Payment plan (direct debit)

B1. Create checkout

POST /v1/provider-checkouts
Idempotency-Key: ONFIT-ENROLMENT-12345
{
  "provider": {
    "provider_code": "SANDBOX_DEMO",
    "provider_order_id": "ONFIT-ENROLMENT-12345",
    "provider_account_id": "001XXXXXXXXXXXX"
  },
  "student": {
    "first_name": "Alex",
    "last_name": "Student",
    "email": "alex.student@example.com"
  },
  "course": {
    "course_name": "Certificate IV in Fitness"
  },
  "pricing": {
    "course_price": 2990,
    "amount_to_finance": 2490
  },
  "plan": {
    "payment_type": "interest_free_payment_plan",
    "payment_frequency": "Fortnightly",
    "number_of_instalments": 20,
    "instalment_amount": 124.5,
    "first_payment_date": "2026-08-18"
  }
}

Use direct_debit.setup_url for bank authority (hosted /api/dd-setup). Prefer Idempotency-Key — see Idempotency.

B2. Confirm enrolment

After DDA authorisation and student declarations:

POST /v1/provider-checkouts/{checkoutId}/confirm

Compatible legacy route (same body): POST /api/provider-checkout-confirm.

{
  "provider": {
    "provider_code": "SANDBOX_DEMO",
    "provider_order_id": "ONFIT-ENROLMENT-12345"
  },
  "checkout": {
    "checkout_id": "SANDBOX_DEMO_…",
    "checkout_token": "eyJ…",
    "opportunity_id": "006…",
    "dda_id": "a0…"
  },
  "payment": {
    "payment_method": "studentpay_payment_plan",
    "first_payment_date": "2026-08-18",
    "deposit_confirmed": true
  },
  "declarations": {
    "payment_plan_accepted": true,
    "information_confirmed": true,
    "privacy_consent_accepted": true
  }
}

dda_id and all three declaration booleans are required. Confirm creates the Payment Plan Agreement PDF and moves the Opportunity to Payment Plan Signed.

Always include {checkoutId} in the v1 path (or use the legacy URL). A bare /v1/provider-checkouts/confirm returns 405.

Retrieve status

GET /v1/provider-checkouts/{checkoutId}

Next