This guide demonstrates how to create a payment using Gateway Flow with Quick Payments.
Sandbox Environment
This guide uses the sandbox environment. Use the mock bank "PNZ" with username user01 and password password for testing.
Request:
POST /oauth2/token HTTP/1.1
Host: sandbox.debit.blinkpay.co.nz
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
Token Expiry
Access tokens expire after 1 hour. Implement automatic token refresh in your application.
Request:
POST /payments/v1/quick-payments HTTP/1.1
Host: sandbox.debit.blinkpay.co.nz
Authorization: Bearer {access_token}
Content-Type: application/json
{
"flow": {
"detail": {
"type": "gateway",
"redirect_uri": "https://www.yourwebsite.com/payment/complete"
}
},
"amount": {
"currency": "NZD",
"total": "25.00"
},
"pcr": {
"particulars": "Invoice",
"code": "12345",
"reference": "Payment"
}
}
PCR Field Limits
Each PCR field (particulars, code, reference) has a maximum length of 12 characters. Requests with longer values are rejected with a 400 validation error.
Response:
{
"quick_payment_id": "3a3b7f7d-f8e6-4c3e-b2a1-5f9c8d7e6a5b",
"redirect_uri": "https://sandbox.debit.blinkpay.co.nz/gateway/pay?id=3a3b7f7d..."
}
Redirect the customer to the redirect_uri from the response. The customer will:
redirect_uriCustomer returns to your redirect_uri with query parameters:
https://www.yourwebsite.com/payment/complete?cid={consent_id}
| Parameter | Description |
|---|---|
cid | The consent ID, which for a quick payment is also the quick_payment_id |
status | Only on a non-success outcome: cancelled, rejected, timeout, error or pending |
error | Customer-safe text to display alongside status. It can change without notice, so never branch on it |
A return with cid and no status means the outcome was not reported as failed; it is not confirmation. Confirm the outcome with a server-side GET before you act on it. See Return Parameters for the full rules.
Make this call as soon as the customer returns; the gateway normally does this for you, and calling it again is safe. For a bank payment this call completes the payment. If it returns a 4xx or 5xx, retry the GET rather than treating the payment as failed.
Request:
GET /payments/v1/quick-payments/{quick_payment_id} HTTP/1.1
Host: sandbox.debit.blinkpay.co.nz
Authorization: Bearer {access_token}
Response:
{
"quick_payment_id": "3a3b7f7d-f8e6-4c3e-b2a1-5f9c8d7e6a5b",
"consent": {
"consent_id": "9f8e7d6c-5b4a-3c2b-1a09-8f7e6d5c4b3a",
"status": "Authorised",
"creation_timestamp": "2025-12-16T10:00:00+13:00",
"status_updated_timestamp": "2025-12-16T10:05:00+13:00",
"detail": {
"type": "single",
"flow": {
"detail": {
"type": "gateway",
"redirect_uri": "https://www.yourwebsite.com/payment/complete"
}
},
"pcr": {
"particulars": "Invoice",
"code": "12345",
"reference": "Payment"
},
"amount": {
"total": "25.00",
"currency": "NZD"
}
},
"payments": [
{
"payment_id": "9f8e7d6c-5b4a-3c2b-1a09-8f7e6d5c4b3a",
"type": "single",
"status": "AcceptedSettlementInProcess",
"creation_timestamp": "2025-12-16T10:05:00+13:00",
"status_updated_timestamp": "2025-12-16T10:06:00+13:00",
"detail": {
"consent_id": "9f8e7d6c-5b4a-3c2b-1a09-8f7e6d5c4b3a"
},
"refunds": []
}
]
}
}
| Status | Description |
|---|---|
Pending | Payment initiated, awaiting bank processing. |
AcceptedSettlementInProcess | Bank has accepted the payment for processing. Treat as "in flight, not yet confirmed". |
AcceptedSettlementCompleted | The payer's bank has sent funds via BECS. |
Rejected | Payment rejected by bank, or the customer declined the consent. |
If the customer declines the payment, the consent status becomes Rejected and consent.payments contains a single payment record with status: Rejected. This means the most recent record in consent.payments tells you the outcome whether the payment was authorised or declined. The exception is a consent that never reached the bank at all — one that was revoked (Revoked), or that ran out of time before the customer authorised it — where consent.payments remains empty. Check consent.status for those cases rather than relying on the payments array.
Determining settlement: which fields to trust
Use payment.status = AcceptedSettlementCompleted as the only signal that funds have settled.
Do not use consent.status to determine whether a payment has settled. consent.status = Consumed means the consented action is complete, not that the money has moved: a consent whose payment the bank rejected after accepting it is also Consumed, with a Rejected payment. Always read consent.payments[0].status. See the payment lifecycle for details.
AcceptedSettlementCompleted confirms that the payer's bank has sent the funds through BECS. It does not guarantee funds have arrived in your account. Always reconcile with actual bank statements.
| Setting | Value |
|---|---|
| Base URL | https://sandbox.debit.blinkpay.co.nz |
| Mock Bank | PNZ |
| Test Username | user01 |
| Test Password | password |
| Decoupled auto-approve number | +64-259531933 (other numbers never authorise) |
See Sandbox Test Values for how to produce declines, timeouts and revocations.