Download the PHP package blinkpay-nz/blink-debit-api-client-php without Composer

On this page you can find all versions of the php package blinkpay-nz/blink-debit-api-client-php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package blink-debit-api-client-php

BlinkPay

Blink Payments API Client for PHP

CI Packagist Security Rating Vulnerabilities Snyk security

Table of Contents

  1. Introduction
  2. Contributing
  3. Building and Testing Locally
  4. Minimum Requirements
  5. Adding the Dependency
  6. Quick Start
  7. Configuration
  8. Client Creation
  9. Request ID, Correlation ID and Idempotency Key
  10. Error Handling
  11. Full Examples
  12. Polling and Settlement Behaviour
  13. Individual API Call Examples
  14. Webhooks
  15. PSR Interoperability
  16. Security
  17. Dependencies

Introduction

This SDK allows merchants with PHP-based backends to integrate with Blink PayNow (for one-off payments) and Blink AutoPay (for recurring payments).

It covers every operation in the Blink Debit API: bank metadata, quick payments, single and enduring consents, fixed recurring payments, payments, refunds, transaction reporting and webhook subscriptions, plus a verifier for signed webhook deliveries, request-body builders, status constants and blocking await helpers for background jobs.

The SDK is framework-agnostic. The same client runs unchanged in plain PHP, Laravel, Symfony, CakePHP and e-commerce platform modules (WooCommerce, PrestaShop, Magento): the core has no runtime dependencies and reaches its environment through two small interfaces, with PSR adapters and framework glue included.

⚠️ Security Warning

This SDK is for SERVER-SIDE use only.

Your OAuth2 client credentials (client_id and client_secret) must never reach a browser, a mobile app or client-side code. Your frontend should call your backend, which then uses this SDK to communicate with BlinkPay.

Contributing

We welcome contributions from the community. Your pull request will be reviewed by our team.

This project is licensed under the MIT License.

Building and Testing Locally

Prerequisites

Install and test

From the repository root:

The suite needs no network or sandbox credentials: HTTP is replaced by an in-memory transport (one test drives the real cURL transport at a closed loopback port to cover the failure path) and sleeps are stubbed, so the retry and polling tests run instantly. The PSR adapters are covered with in-memory PSR-6/PSR-16 doubles and nyholm/psr7. The APCu cache tests run wherever the extension is enabled for the CLI (apc.enable_cli=1) and are skipped elsewhere.

The Laravel, Symfony and CakePHP glue is tested against the real frameworks from test-frameworks/, a separate Composer project (PHP 8.2+) that boots each container, resolves the client and checks that the sandbox flag and token cache are wired as documented. It also runs PHPStan over the glue with the frameworks installed, which the main analysis cannot do:

CI runs both suites on every pull request and on every push to master.

Minimum Requirements

Optional, for the integrations:

Adding the dependency

Quick Start

Append the BlinkPay environment variables to your .env (or export them):

Create and use the client:

Configuration

Configuration precedence

  1. As provided directly to the client constructor
  2. Framework configuration (config/blinkpay.php, blink_debit: YAML, or the BlinkPay key in CakePHP), which reads environment variables
  3. Default values (sandbox = true, timeout 30 seconds)

Environment variables

BLINKPAY_SANDBOX is parsed by Env::bool() in every entry point (fromEnvironment(), the Laravel provider, the CakePHP plugin): unset and blank mean sandbox, true/false/yes/no/on/off/1/0 are accepted, and anything else throws rather than silently picking an environment. Native casts get this wrong (getenv() returns false when unset and Laravel's env() returns '' for a blank value, both of which (bool) turns into production), so prefer the helper over your own parsing.

Token caching

Access tokens last about an hour and are refreshed five minutes early. The client keeps them in a TokenCacheInterface:

Cache keys are scoped by environment and client ID, so a shared cache can never serve a sandbox token to a production client or one merchant's token to another. The SDK ships no file-backed cache of its own, which would write bearer tokens to disk; where the cache is the framework's, keeping tokens off disk is the store choice above. Concurrent workers that miss an empty cache each fetch a token; every token is valid and the retry on 429 absorbs the burst, so no cross-process lock is taken.

Client creation

Plain PHP

Laravel (recommended for Laravel apps)

The service provider is auto-discovered. Set the environment variables shown above and, optionally, publish the config:

Then type-hint the client wherever you need it:

Tokens are persisted in the default cache store, or the one named by BLINKPAY_CACHE_STORE; set it to redis, memcached or apc rather than file. To use your own HTTP stack or token store, bind HttpTransportInterface or TokenCacheInterface in a provider of your own; the package provider picks those bindings up.

Symfony 6.1+

Register BlinkPay\BlinkDebit\Symfony\BlinkDebitBundle in config/bundles.php, then:

Leave sandbox out to stay in sandbox. Symfony's %env(bool:BLINKPAY_SANDBOX)% processor turns an unset or blank variable into false, which would mean production, so drive it from the environment only through a defaulted parameter (the test-frameworks/ suite checks that unset and blank resolve to sandbox with exactly this spelling):

The client is autowirable by type-hint and available for direct container access as blink_debit.client. On Symfony versions before 6.1, wire the same services by hand:

CakePHP 4.2+ and 5.x

The plugin registers the client in the DI container for constructor and action injection. Register HttpTransportInterface or TokenCacheInterface in your application's services() to override the transport or token store.

Request ID, Correlation ID and Idempotency Key

Every request carries a request-id and an x-correlation-id. The SDK generates both as UUIDs when you supply none, and keeps them (and the idempotency key) the same across its own retries of one logical request, so a retried call shows up in BlinkPay's logs as one interaction. Every request also carries User-Agent: blink-debit-api-client-php/<version> php/<php version>, so support can tell SDK traffic apart.

To supply your own IDs, or the customer-context headers the API defines, pass a trailing RequestOptions:

Every value is validated when set: IDs must be UUIDs, the IP must be IPv4 or IPv6, and the User-Agent may not contain control characters. A value that fails validation raises BlinkDebitApiException before anything is sent, so an untrusted browser value can never inject a second header into the authenticated request. Customer IP and User-Agent are sent only on the customer-facing operations the API defines them for (quick payments, consents, payments, refunds); reporting and administrative calls carry the tracing headers alone.

Idempotency keys. The API accepts an optional idempotency-key on consent, payment and refund creation and replays a retried request with the same key and payload for 24 hours instead of creating twice. This SDK makes the key required on every consent and payment create call (createQuickPayment, createSingleConsent, createEnduringConsent, createPayment, createFixedRecurringPayment and their typed helpers) and optional but recommended on the refund helpers. That is the SDK's choice, not the API's: a checkout that can be retried by the browser, a queue or a network blip should never be able to debit twice. Use a fresh UUID for each distinct operation, persist it with the order, and reuse it only when retrying that same request. Subscriptions take no key; list existing subscriptions before retrying a failed create by hand.

Generate keys with Uuid::v4(), or your framework's helper (Str::uuid() in Laravel, Uuid::v4() in Symfony, Text::uuid() in CakePHP); they are interchangeable.

Error Handling

Every failure throws BlinkDebitApiException or a subclass in BlinkPay\BlinkDebit\Exception, so you can catch broadly or by kind:

Exception When
Exception\UnauthorisedException 401 after one token refresh, or the token endpoint rejected the credentials (400/401/403)
Exception\ForbiddenException 403: missing scope, or another merchant's resource
Exception\ResourceNotFoundException 404
Exception\ConflictException 409, including the idempotency conflicts below
Exception\RateLimitExceededException 429 after retries
Exception\ServerErrorException 5xx after retries
Exception\TransportException No HTTP response at all (DNS, TCP, TLS, timeout), after retries where safe
Exception\ConsentRejectedException, ConsentTimeoutException, PaymentRejectedException, PaymentTimeoutException Thrown by the await helpers; see Polling and Settlement Behaviour
BlinkDebitApiException (base) Any other status (400, 422, …) and local validation failures (status 0)

Retries

Error codes you will meet

The code in the error body (also getErrorCode()) distinguishes cases that share an HTTP status:

Status Code Meaning What to do
400 BP283 Enduring consent expiry_timestamp falls on the same NZ date as from_timestamp Move the expiry to a later date
400 PCR field over 12 characters or with disallowed characters Values are never truncated by the API; use Pcr::build() to catch this locally
409 BP702 Idempotency key reused with a different payload Use a fresh key for a different request
409 BP703 / BP708 Idempotency key reused while the first request is still in flight Poll the named payment; do not resubmit
409 BP710 Idempotency key already bound to a terminal payment Rejected: resubmit with a fresh key. AcceptedSettlementCompleted: do not
409 BP712 A concurrent request on the same consent claimed the bank submission; no payment ID returned Read the consent's payments before retrying
409 BP713 Keyless enduring payment matched consent, amount and PCR within the same minute Supply an idempotency key
409 BP715 Card refund raced with settlement Retryable; try again
422 BP053 Card refund of a payment that is authorised but not yet charged Wait for the charge to settle
422 BP039 full_refund requested after a partial_refund exists Use partial_refund for the remainder

Transactions paging accepts page 1–10000 and size 1–1000.

Full Examples

Quick payment (one-off payment), using Gateway flow

A quick payment is a one-off payment that combines the API calls needed for both the consent and the payment.

Single consent followed by one-off payment, using Gateway flow

Polling and Settlement Behaviour

Payment settlement

Payment settlement is asynchronous. Payments transition through these states (constants on Enum\PaymentStatus):

For a bank (A2A) payment, AcceptedSettlementCompleted means the payer's bank has sent the money, and the payment carries accepted_reason = source_bank_payment_sent. For a card payment made through the gateway, it means the card network accepted the charge (accepted_reason = card_network_accepted); the funds arrive through card settlement, and the payment's amount may carry surcharge and total_charge (the amount the customer actually paid, inclusive of surcharge) when surcharging is enabled for your account. Store accepted_reason with the order: it decides which refund type applies later. Constants are on Enum\AcceptedReason.

Await helpers

Four helpers poll once a second for up to $maxWaitSeconds attempts and turn the outcome into typed exceptions, mirroring the Java and Node SDKs. The budget counts polls rather than elapsed time: a poll that times out or is retried adds its own duration, so lower setRequestTimeout() when the total wait matters. They block, so call them from a queue job, a scheduled command or a CLI script rather than a web request:

Helper Returns when Throws On timeout
awaitSuccessfulQuickPayment($id, $seconds) The quick payment's payment is AcceptedSettlementCompleted ConsentRejectedException, ConsentTimeoutException (gateway timeout), PaymentRejectedException Not yet authorised: revokes the quick payment, throws ConsentTimeoutException. Authorised but unsettled: throws PaymentTimeoutException, revokes nothing
awaitAuthorisedSingleConsent($id, $seconds) Consent is Authorised (or Consumed) ConsentRejectedException, ConsentTimeoutException Throws ConsentTimeoutException; nothing to revoke, no money moves on an unpaid single consent
awaitAuthorisedEnduringConsent($id, $seconds) Consent is Authorised (or Consumed) ConsentRejectedException, ConsentTimeoutException Revokes the consent (it grants ongoing access), throws ConsentTimeoutException
awaitSuccessfulPayment($id, $seconds) Payment is AcceptedSettlementCompleted PaymentRejectedException Throws PaymentTimeoutException; the payment may still settle, keep polling or use the webhook

A failed revoke is attached as the exception's getPrevious(). If the revoke is refused with 409 because the customer authorised in the moment after the last poll, the quick payment is re-read and reported as settled or as PaymentTimeoutException, never as abandoned. A poll that fails with a transport, 5xx or 429 error leaves the outcome unknown, so it is absorbed and the next poll reads the authoritative status; a 404 or other client error propagates at once. PaymentTimeoutException is not a failure: never release goods on it, and never treat it as a rejection.

To poll on your own schedule instead, compare statuses with the constants rather than literals, so a typo cannot silently mis-classify a payment:

Quick payments

The first getQuickPayment() call after the consumer authorises initiates the debit. Treat an error on that call as "outcome not yet known" and retry; the payment's own status is the authority. A quick payment that is never retrieved is never debited and is eventually rejected.

Revoking abandoned consents

Individual API Call Examples

Amounts are NZD decimal strings with one or two decimals, such as '12.50'. Statement text is built with Pcr::build($particulars, $code, $reference), in the API's own field order, which validates against the banks' 12-character rules and passes values through unchanged; Pcr::sanitise() is the opt-in lossy alternative for free text. Request bodies are built with the classes in BlinkPay\BlinkDebit\Request (Flow, QuickPaymentRequest, SingleConsentRequest, EnduringConsentRequest, FixedRecurringPaymentRequest, Amount), which return the API's snake_case arrays, so you can also hand-build or adjust a body exactly as the API reference defines it. Banks, periods, identifier types, flow types and statuses have constants in BlinkPay\BlinkDebit\Enum.

Bank Metadata

Supplies the supported banks and supported flows on your account.

Quick Payments

Gateway Flow

Gateway Flow - Redirect Flow Hint

Gateway Flow - Decoupled Flow Hint

Redirect Flow

Redirect Flow - Native App

The redirect URI may be a deep or universal link. Setting redirect_to_app (the third argument of Flow::redirect() and of Flow::gateway()) makes the bank return code and state to the app, which must pass them on to https://debit.blinkpay.co.nz/bank/1.0/return?state={state}&code={code}&redirect=false, together with any error parameters, to complete the consent.

Decoupled Flow

No redirect_uri is returned; the bank pushes the authorisation to the customer's app and notifies your callback URL.

Retrieval

Revocation

Single/One-Off Consents

A single consent takes the same body as a quick payment, built with SingleConsentRequest::build() and the same Flow helpers.

Gateway Flow

Gateway Flow - Redirect Flow Hint

Gateway Flow - Decoupled Flow Hint

Redirect Flow

Suitable for most consents.

Decoupled Flow

This flow type allows better support for mobile by allowing the supply of a mobile number or previous consent ID to identify the customer with their bank.

The customer will receive the consent request directly to their online banking app. This flow does not send the user through a web redirect flow.

Retrieval

Get the consent including its status.

Revocation

Blink AutoPay - Enduring/Recurring Consents

Request an ongoing authorisation from the customer to debit their account on a recurring basis.

Note that such an authorisation can be revoked by the customer in their mobile banking app.

EnduringConsentRequest::build($flow, $fromTimestamp, $period, $maximumAmountPeriod, $expiryTimestamp = null, $maximumAmountPayment = null, $hashedCustomerIdentifier = null) takes any Flow; omit the expiry for an indefinite consent, and note it must not fall on the same NZ date as the start (400 BP283).

Gateway Flow

Gateway Flow - Redirect Flow Hint

Gateway Flow - Decoupled Flow Hint

Redirect Flow

Decoupled Flow

Retrieval

Revocation

Blink AutoPay - Fixed Recurring Payments

Let Blink run a payment schedule against an authorised enduring consent. Only one active schedule is allowed per consent (a duplicate returns 409), the start date must be today or later in NZ time, and the amount must fit within the consent's caps.

Creation

Retrieval

Cancellation

Cancels the schedule and prevents future executions. The underlying enduring consent stays in place.

Payments

The completion of a payment requires a consent to be in the Authorised status.

Single/One-Off

Enduring/Recurring

If you already have an approved consent, you can run a Payment against that consent at the frequency as authorised in the consent.

Raw payload

A 409 with code BP712 carries no payment ID: a concurrent request on the same consent won the bank submission, so read the consent's payments before retrying.

Retrieval

Refunds

How the payment settled decides the refund type, so store the settled payment's accepted_reason (Enum\AcceptedReason) at payment time. The API accepts an optional idempotency key on refunds and replays a retried request with the same key instead of refunding twice; the helpers take it as an optional argument, and money-moving refunds should always send one. Without a key, the SDK does not retry a refund on a 5xx or transport failure, since the first attempt may have gone through.

Account Number Refund

For a bank-settled (A2A) payment. Moves no money: poll getRefund() until it carries account_number, show that to the merchant for a manual transfer, and never persist the account number into your own storage.

Full Refund

A money-transfer refund of the whole payment. The API defines this for any payment; today it is processed for card-settled payments, where BlinkPay chooses between cancelling an unsettled charge and refunding a settled one (see the card payments guide in the merchant portal). Not allowed once a partial refund exists (422 BP039), and use a partial refund instead when a surcharge was applied.

Partial Refund

A money-transfer refund of part of the payment; several may be made up to the payment total. Today processed for card-settled payments. Always use this when a surcharge was applied.

Retrieval

A created money-moving refund is not necessarily processed: check status (Enum\RefundStatus: processing, completed, failed) and surface detail.consent_redirect to the merchant when their bank requires them to authorise the refund.

Transactions

For reconciliation. Results are newest first; page is 1–10000 and size is 1–1000 (default 100).

Subscriptions

Register an HTTPS callback for fixed recurring payment lifecycle events. The signing secret is returned exactly once, on creation; store it immediately. Sandbox and production have separate subscriptions and secrets. Event types are validated locally against the EVENT_* constants.

Scopes

Features are gated by the scopes granted to your client. After the first token fetch, getGrantedScopes() returns them, hasScopes(...) checks any set of SCOPE_* constants, and hasRefundScopes() is a shortcut for the refund pair. All return null before the grant is known; resolve that by calling getAccessToken() once rather than assuming the feature is available.

Webhooks

BlinkPay POSTs a JSON event to your subscription's callback URL, signed with the X-Signature header (t={unix_timestamp},v1={hmac_sha256_hex} over {timestamp}.{raw_body}). Verify every delivery against the raw request body before acting on it:

PSR Interoperability

PSR-4 is the autoloading standard: a namespace prefix maps to a directory, and every class lives in the file named after it, so BlinkPay\BlinkDebit\Psr\Psr18Transport is src/Psr/Psr18Transport.php. Composer generates the autoloader from the autoload.psr-4 entry in composer.json; a single require 'vendor/autoload.php' makes every class available on first use. Because classes load lazily, the framework adapters can live in this package without their frameworks being installed: nothing touches them until you reference them.

PSR-18 is the HTTP client standard: one interface, ClientInterface::sendRequest(), that takes a PSR-7 request and returns a PSR-7 response. Coding to it lets an application choose Guzzle, Symfony HttpClient or any other implementation without the library caring. PSR-18 deliberately says nothing about building requests, so the companion PSR-17 factories are needed to create the request and its body stream. This library keeps its own tiny HttpTransportInterface so the zero-dependency cURL path stays possible, and bridges to PSR-18 with Psr18Transport:

Timeouts are not part of PSR-18, so configure them on the underlying client. A bespoke HttpTransportInterface should throw Exception\TransportException when no response was received, and may return response headers (keyed by lower-case name) so the client can honour Retry-After.

Token caches follow the same pattern. PSR-16 (simple cache: get/set/delete with a TTL) is implemented by Laravel's cache repository and CakePHP's cache engines, and PSR-6 (cache pools of items) is the native contract of Symfony Cache. Psr16TokenCache and Psr6TokenCache wrap either kind:

The PSR interface packages are not runtime dependencies of this library; they arrive with the framework or HTTP client you already use.

Security

If you believe you have found a security issue, contact [email protected] rather than opening a public issue.

Dependencies

Runtime: none beyond PHP with ext-curl and ext-json. ext-apcu is used for the default token cache when present.

Optional (installed by the application, never by this package):

Development: PHPUnit, PHPStan, the PSR interface packages and nyholm/psr7. The test-frameworks/ project additionally installs Laravel (via orchestra/testbench), Symfony and CakePHP.


All versions of blink-debit-api-client-php with dependencies

PHP Build Version
Package Version
Requires php Version ^7.4 || ^8.0
ext-curl Version *
ext-json Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package blinkpay-nz/blink-debit-api-client-php contains the following files

Loading the files please wait ...