Payments in BlinkPay progress through a defined lifecycle from initiation through settlement. Understanding these states helps you provide accurate payment tracking and handle edge cases appropriately.
┌─────────┐ ┌─────────────────────────────┐ ┌─────────────────────────────┐
│ Pending │ ──► │ AcceptedSettlementInProcess │ ──► │ AcceptedSettlementCompleted │
└─────────┘ └─────────────────────────────┘ └─────────────────────────────┘
│ │
│ (if declined) │ (if the bank rejects it after accepting)
▼ │
┌──────────┐ │
│ Rejected │ ◄─────────────────┘
└──────────┘
| State | Description |
|---|---|
| Pending | Payment created, awaiting bank response |
| AcceptedSettlementInProcess | Bank accepted, processing via BECS |
| AcceptedSettlementCompleted | Settlement complete, funds transferred |
| Rejected | Bank declined the payment, before or after accepting it. A quick payment whose consent was declined or timed out at the bank also carries one Rejected payment |
Initial state immediately after payment creation
The payment has been created via the BlinkPay API and submitted to the customer's bank for processing.
Typical duration: Seconds to minutes
Next states:
AcceptedSettlementInProcess - Bank accepted and is processingRejected - Bank rejected the paymentWhat's happening:
Merchant actions:
Normal Behaviour
Most payments move from Pending within seconds. If a payment is still Pending after 6 hours, contact support with the consent ID and payment ID—banks occasionally have maintenance windows that can delay processing.
Bank has accepted and is processing the payment
The customer's bank has accepted the payment and initiated the settlement process through the BECS (Bulk Electronic Clearing System).
Typical duration: 1-2 hours (can be longer for late-day payments)
Next states:
AcceptedSettlementCompleted - Payment sent via BECSRejected - Bank rejected the payment at settlement time (rare but possible)What's happening:
Merchant actions:
AcceptedSettlementCompletedSettlement Time
Settlement timing is subject to the transfer times and rules of the BECS (Bulk Electronic Clearing System) and participating banks.
Payment sent to merchant's bank via BECS (Final state)
The customer's bank has successfully sent the payment through BECS Direct Credit. This means the funds have been sent from the customer's bank to your merchant bank account.
What this means:
What this doesn't mean:
Typical timing:
Merchant actions:
For a card payment, AcceptedSettlementCompleted (with accepted_reason: card_network_accepted) means the card network accepted the charge; the BECS detail on this page applies to bank payments.
Avoid Duplicate Charges
On an accepted payment from BlinkPay, do not also take a payment from another payment channel (e.g., credit card) that the customer may have on file. This could result in the customer being charged twice for the same order.
Reconciliation
Use the PCR (Particulars, Code, Reference) fields to match BlinkPay payments with entries in your bank statement. Each field can contain up to 12 characters.
Bank rejected the payment (Final state)
The payment was rejected by the customer's bank and will not be processed.
For quick payments, a payment record with status: Rejected is also created when the consent is declined or times out at the bank. In those cases the consent is Rejected too; check consent.status to tell them apart from a payment the bank rejected after the customer authorised it.
A card quick payment still pending 24 hours after authorisation is cancelled and marked Rejected; the customer's hold is released, though their bank can take a few days to show it.
Common reasons a bank rejects a payment:
The API does not say which of these applied: neither the payment nor the consent has a rejection-reason field.
| Reason | Description |
|---|---|
| Insufficient Funds | Account doesn't have enough balance |
| Account Closed | Customer's account is no longer active |
| Invalid Account | Account number or details incorrect |
| Payment Blocked | Bank fraud detection or customer block |
| Exceeds Limits | Payment exceeds daily/transaction limits |
| Technical Error | Bank system issue |
Merchant actions:
Don't Auto-Retry
Never automatically retry rejected payments. Handle a rejection as you would any failed payment: the customer needs to resolve the underlying issue (add funds, unblock account, etc.) before trying again. A new attempt needs a new idempotency-key: reusing the old key returns the rejected payment. On a single consent you can only try again while the consent is still Authorised (the bank refused the payment outright); if the consent is Consumed, create a new consent.
Time State Action
------ ------------------------------ --------------------------------
0s [Payment Created]
0-30s Pending Bank validates payment
30s AcceptedSettlementInProcess Bank accepts, queues for BECS
2hr AcceptedSettlementCompleted Payment sent via BECS
2-4hr [Funds in merchant account] Merchant bank receives funds
All BlinkPay payments use New Zealand's BECS (Bulk Electronic Clearing System) for Direct Credit transfers.
How BECS works:
Settlement timing:
Important: Settlement vs Receipt
AcceptedSettlementCompleted verifies that the funds have been sent by the payer's bank, not that they've been received by your bank.
While payments rarely fail after this point, there may be limited circumstances where the merchant bank does not accept funds sent to it—for example, if it has reason to suspect fraudulent activity. Always reconcile with your actual bank statements.
Best practice:
AcceptedSettlementCompleted as the only success statusUse
payment.status = AcceptedSettlementCompletedas the only signal that the payment has succeeded and the payer's bank has sent the funds. Do not useconsent.statusto determine this — aConsumedconsent means the consented action is complete (the bank has made its final decision on the payment), not that the payment succeeded.
When the money arrives in your account depends on settlement: the funds reach you once the payment settles. Settlement timing varies based on when the payment is initiated and the participating banks' processing schedules. Payments clear through BECS and settle via SBI365, which runs 365 days a year within a daily operating window (approx. 9am–midnight NZ time). Most payments settle within about 2 hours; a payment initiated outside the operating window completes once it next opens.
Factors affecting settlement:
Retrieve payment status via API:
GET /payments/v1/payments/{payment_id} HTTP/1.1
Host: sandbox.debit.blinkpay.co.nz
Authorization: Bearer {access_token}
Required: poll to a terminal status — don't assume success early
AcceptedSettlementCompleted or Rejected) or your polling window (below) ends — then fall back to your wash-up.Pending or AcceptedSettlementInProcess) as success — these mean the payment is in flight, not complete.payment.status = AcceptedSettlementCompleted — confirmation that the payer's bank has sent the funds. Don't infer this from consent.status; see Determining settlement for which fields to trust.Poll only once you have a reason to look, then poll quickly:
| Situation | What to do |
|---|---|
| The customer is still at their bank (gateway or redirect flow) | Don't poll. Wait for the customer to return to your redirect_uri; on mobile, also check when your app comes back to the foreground |
The customer has returned, or the decoupled callback_url has fired | Read the consent, or the quick payment, straight away. If it isn't terminal yet, poll every second |
| A payment exists | Poll it every second until it is AcceptedSettlementCompleted or Rejected, for a minute or two at most: that is your polling window |
Direct decoupled flow (not through the gateway) with no callback_url | Nothing comes back to you, so poll the consent every 5 seconds until it leaves AwaitingAuthorisation, for the bank's authorisation window |
The bank's authorisation window is roughly 4-10 minutes; read it from redirect_flow.request_timeout or features.decoupled_flow.request_timeout on the metadata endpoint.
Most payments reach a final status within seconds. One that is still Pending or AcceptedSettlementInProcess when your polling window ends is not a failure: stop polling and leave it to the wash-up.
Quick payments: for a bank payment, retrieve the quick payment with GET /payments/v1/quick-payments/{quick_payment_id} as soon as the customer returns; the gateway normally does this for you, and calling it again is safe. That call completes the payment. If it returns a 4xx or 5xx, retry it, and read the outcome from consent.payments[0].status.
A payment made late in the day may not settle until the next morning (see Settlement Speed). Leave such a payment to your wash-up rather than polling for it, and reconcile against your bank statement as the final source of truth.
consent.payments lists the newest payment first, so payments[0] is always the most recent.
Read the consent or payment to learn its state (see Polling). BlinkPay sends two kinds of notification:
| Notification | When | What to do |
|---|---|---|
Decoupled flow callback_url | When the customer authorises, the bank rejects, or the authorisation window times out; it can arrive more than once | It is an unsigned GET carrying only ?cid=. Treat it as a prompt to fetch the consent (or quick payment), never as the outcome |
| Fixed Recurring Payment webhooks | When a scheduled payment completes or fails, or the schedule is cancelled | Signed events; verify the signature before acting |
Revocation: a consent revoked at the customer's bank is not pushed to you: it shows as Revoked on your next GET /payments/v1/enduring-consents/{consent_id}, and POST /payments on a revoked consent returns 422 BP015. If the consent has an active Fixed Recurring Payment, the schedule is cancelled and you receive a fixed-recurring-payment-cancelled webhook.
Store these IDs server-side, against your order, before you send the customer to their bank. The customer may never return to your site, and the return URL carries only cid.
| ID | Where you get it | What you need it for |
|---|---|---|
quick_payment_id | Response to POST /payments/v1/quick-payments; the same value as cid on the return URL | GET /payments/v1/quick-payments/{quick_payment_id}, which completes the payment and reports its outcome |
consent_id | Response to POST /payments/v1/single-consents or /enduring-consents; the same value as cid on the return URL | Creating payments and reading or revoking the consent. For an enduring consent, every payment until it is revoked or expires. It can also identify a returning customer in the decoupled flow (identifier_type: consent_id) |
payment_id | Response to POST /payments/v1/payments, or consent.payments[0].payment_id | GET /payments/v1/payments/{payment_id} and refunds |
refund_id | Response to POST /payments/v1/refunds | GET /payments/v1/refunds/{refund_id} |
The IDs do not change. Keep them as long as you may need to reconcile the payment or refund it.
Send an idempotency-key header (a UUID you generate, new for each distinct payment) on every POST. If a request times out or returns a 5xx, you don't know whether it succeeded, so retry it with the same key: if the first attempt created something, you get it back rather than a duplicate. (Gateway-flow consents are de-duplicated on the request-id header instead, so resend the same request-id.)
If you are still unsure, GET the consent and inspect payments[0] before doing anything else. Never create a new consent until you know the old one has no payment that may still settle, or the customer could be charged twice. After a Rejected payment, use a new key.
Reconcile against your own bank records
We recommend running regular bank reconciliation against your settlement account — confirm every payment you expect has arrived, and that the amount received matches the amount expected. Your own bank account is the source of truth for whether funds were actually received: AcceptedSettlementCompleted confirms the payer's bank sent the funds via BECS, but does not by itself guarantee receipt (see Settlement Guarantees).
Match payments to bank statements using Particulars, Code, and Reference (PCR) fields. Each field supports up to 12 characters.
| Field | Purpose | Example |
|---|---|---|
| Particulars | Primary identifier | INV-123456 |
| Code | Transaction type | SALE |
| Reference | Secondary identifier | CUST-789 |
PCR Best Practices
Real-time polling resolves the vast majority of payments quickly, but some are still reported by the bank as non-terminal (Pending or AcceptedSettlementInProcess) when your polling window ends — for example payments initiated late in the day (outside the SBI operating window) or during a bank maintenance window. If your integration stops polling at that point, those payments can be left in a stale state in your own records even though the bank later resolved them.
To catch these, run a recurring wash-up (a sweep) on a schedule that suits your business — every 12 hours is a sensible default, but anything from a few hours to daily works depending on volume and how quickly you need certainty:
Pending or AcceptedSettlementInProcess and older than your normal polling window (e.g. older than 6 hours, or from a previous day).GET /payments/v1/payments/{payment_id} to pull it to its current status.AcceptedSettlementCompleted or Rejected) and reconcile it against your bank statement.Why a wash-up matters
The wash-up is a safety net for payments that outlive a single polling session — it catches the rare cases where settlement actually completed but the status update was delayed. The vast majority of payments resolve on their own, and if you run thorough bank reconciliation you may well catch these there instead. But not every integration has that in place, so we recommend the wash-up as a simple, programmatic way to make sure no payment is left sitting as "processing" in your system.
Refund a payment once it is AcceptedSettlementCompleted, using POST /payments/v1/refunds. Bank payments take an account_number refund (you pay the customer back yourself); card payments take a full_refund or partial_refund. See Refunds.
Settlement runs 365 days a year, including weekends and public holidays (SBI365), so weekend and holiday payments are no longer held to the next business day. Payments initiated outside the daily SBI operating window (approx. 9am–midnight NZ time) complete once it next opens. Settlement timing remains subject to individual bank processing schedules.