PHP code example of blinkpay-nz / blink-debit-api-client-php

1. Go to this page and download the library: Download blinkpay-nz/blink-debit-api-client-php library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

blinkpay-nz / blink-debit-api-client-php example snippets




linkPay\BlinkDebit\BlinkDebitApiException;
use BlinkPay\BlinkDebit\BlinkDebitClient;
use BlinkPay\BlinkDebit\Pcr;
use BlinkPay\BlinkDebit\Uuid;

// Reads BLINKPAY_CLIENT_ID, BLINKPAY_CLIENT_SECRET, BLINKPAY_SANDBOX and BLINKPAY_TIMEOUT.
// An unset or blank BLINKPAY_SANDBOX means sandbox; production must be opted into with "false".
$client = BlinkDebitClient::fromEnvironment();

$idempotencyKey = Uuid::v4();   // persist this against the order so a retry reuses it

try {
    $response = $client->createGatewayQuickPayment(
        '0.01',                                                       // NZD total as a decimal string
        'https://www.blinkpay.co.nz/sample-merchant-return-page',     // must be whitelisted for your merchant
        Pcr::build('particulars', 'code', 'reference'),               // what the customer sees on their statement
        $idempotencyKey
    );

    $redirectUri = $response['redirect_uri'];       // Redirect the consumer to this URL
    $quickPaymentId = $response['quick_payment_id'];

    // From a queue job or CLI script, wait for the money to move (see Polling and Settlement Behaviour).
    $quickPayment = $client->awaitSuccessfulQuickPayment($quickPaymentId, 300);
} catch (BlinkDebitApiException $e) {
    error_log('BlinkPay error: ' . $e->getMessage());   // safe to log: never contains credentials
}

use BlinkPay\BlinkDebit\BlinkDebitClient;

// From the environment variables above:
$client = BlinkDebitClient::fromEnvironment($tokenCache = null, $transport = null);

// Or explicitly:
$client = new BlinkDebitClient(
    $clientId,
    $clientSecret,
    $sandbox = true,
    $tokenCache = null,     // TokenCacheInterface; default ApcuTokenCache when available, else InMemoryTokenCache
    $transport = null       // HttpTransportInterface; default CurlTransport
);
$client->setRequestTimeout(30);

use BlinkPay\BlinkDebit\BlinkDebitClient;

class CheckoutController extends Controller
{
    public function __construct(private BlinkDebitClient $blink)
    {
    }
}

// config/app_local.php
'BlinkPay' => [
    'clientId' => env('BLINKPAY_CLIENT_ID', ''),
    'clientSecret' => env('BLINKPAY_CLIENT_SECRET', ''),
    'sandbox' => env('BLINKPAY_SANDBOX'),   // parsed by the plugin; unset or blank means sandbox
    // 'cacheConfig' => 'default',   // prefer a Redis, Memcached or APCu engine over FileEngine
    // 'timeout' => 30,
],

// src/Application.php, in bootstrap()
$this->addPlugin(\BlinkPay\BlinkDebit\CakePHP\BlinkDebitPlugin::class);

use BlinkPay\BlinkDebit\RequestOptions;

$options = RequestOptions::create()
    ->withRequestId($uuid)                     // overrides the interaction ID Blink Debit would generate
    ->withCorrelationId($uuid)                 // your own UUID for log correlation
    ->withCustomerIp($request->ip())           // when the customer is logged in with you
    ->withCustomerUserAgent($request->userAgent());

$client->getQuickPayment($quickPaymentId, $options);

use BlinkPay\BlinkDebit\BlinkDebitApiException;
use BlinkPay\BlinkDebit\Exception\ConflictException;
use BlinkPay\BlinkDebit\Exception\RateLimitExceededException;

try {
    $payment = $client->createSingleConsentPayment($consentId, $idempotencyKey);
} catch (ConflictException $e) {
    $e->getErrorCode();      // e.g. "BP712": read the consent's payments before retrying
} catch (RateLimitExceededException $e) {
    // already retried three times; back off and retry later with the same idempotency key
} catch (BlinkDebitApiException $e) {
    $e->getStatusCode();     // HTTP status, or 0 for transport and local validation failures
    $e->getResponseBody();   // decoded error body, when one was returned
    $e->getErrorCode();      // the BPxxx code from that body, or null
    $e->getMessage();        // safe to log: never contains credentials, tokens or request bodies
}

use BlinkPay\BlinkDebit\Enum\ConsentStatus;
use BlinkPay\BlinkDebit\Enum\PaymentStatus;

$response = $client->createGatewayQuickPayment(
    '0.01',
    'https://www.blinkpay.co.nz/sample-merchant-return-page',
    Pcr::build('particulars', 'code', 'reference'),
    $idempotencyKey,
    hash('sha256', $customerId)     // optional; omit when no per-customer value exists
);
$redirectUri = $response['redirect_uri'];       // Redirect the consumer to this URL
$quickPaymentId = $response['quick_payment_id'];

// After the consumer returns: confirm server-side, never from query parameters.
$quickPayment = $client->getQuickPayment($quickPaymentId);
$consentStatus = $quickPayment['consent']['status'];                       // ConsentStatus::CONSUMED, ::REJECTED, ...
$paymentStatus = $quickPayment['consent']['payments'][0]['status'] ?? null; // PaymentStatus::* once a payment exists

// Or, from a background job, block until settled (throws on rejection or timeout):
$quickPayment = $client->awaitSuccessfulQuickPayment($quickPaymentId, 300);

$consent = $client->createGatewaySingleConsent(
    '0.01',
    'https://www.blinkpay.co.nz/sample-merchant-return-page',
    Pcr::build('particulars'),
    $idempotencyKey
);
$redirectUri = $consent['redirect_uri'];        // Redirect the consumer to this URL

// After the consumer returns, from a job: wait for authorisation, debit, wait for settlement.
$client->awaitAuthorisedSingleConsent($consent['consent_id'], 300);
$payment = $client->createSingleConsentPayment($consent['consent_id'], $paymentIdempotencyKey);
$settled = $client->awaitSuccessfulPayment($payment['payment_id'], 300);

use BlinkPay\BlinkDebit\Enum\PaymentStatus;

$payment = $client->getPayment($paymentId);
if ($payment['status'] === PaymentStatus::ACCEPTED_SETTLEMENT_COMPLETED) { /* fulfil */ }

use BlinkPay\BlinkDebit\Enum\Bank;
use BlinkPay\BlinkDebit\Enum\IdentifierType;
use BlinkPay\BlinkDebit\Enum\Period;
use BlinkPay\BlinkDebit\Enum\RetryStrategy;
use BlinkPay\BlinkDebit\Pcr;
use BlinkPay\BlinkDebit\Request\EnduringConsentRequest;
use BlinkPay\BlinkDebit\Request\FixedRecurringPaymentRequest;
use BlinkPay\BlinkDebit\Request\Flow;
use BlinkPay\BlinkDebit\Request\QuickPaymentRequest;
use BlinkPay\BlinkDebit\Request\SingleConsentRequest;

$bankMetadataList = $client->getMeta();

$response = $client->createGatewayQuickPayment($total, $redirectUri, Pcr::build($particulars, $code, $reference), $idempotencyKey);

$response = $client->createQuickPayment(
    QuickPaymentRequest::build(Flow::gateway($redirectUri, Flow::redirectHint(Bank::BNZ)), $total, Pcr::build($particulars, $code, $reference)),
    $idempotencyKey
);

$response = $client->createQuickPayment(
    QuickPaymentRequest::build(
        Flow::gateway($redirectUri, Flow::decoupledHint(Bank::PNZ, IdentifierType::MOBILE_NUMBER, $mobileNumber)),
        $total,
        Pcr::build($particulars, $code, $reference)
    ),
    $idempotencyKey
);

$response = $client->createQuickPayment(
    QuickPaymentRequest::build(Flow::redirect(Bank::ANZ, $redirectUri), $total, Pcr::build($particulars, $code, $reference)),
    $idempotencyKey
);

$response = $client->createQuickPayment(
    QuickPaymentRequest::build(Flow::redirect(Bank::ANZ, 'myapp://blink/return', true), $total, Pcr::build($particulars, $code, $reference)),
    $idempotencyKey
);

$response = $client->createQuickPayment(
    QuickPaymentRequest::build(
        Flow::decoupled(Bank::PNZ, IdentifierType::CONSENT_ID, $previousConsentId, $callbackUrl),
        $total,
        Pcr::build($particulars, $code, $reference)
    ),
    $idempotencyKey
);

$quickPayment = $client->getQuickPayment($quickPaymentId);

$client->revokeQuickPayment($quickPaymentId);

$consent = $client->createGatewaySingleConsent($total, $redirectUri, Pcr::build($particulars, $code, $reference), $idempotencyKey);

$consent = $client->createSingleConsent(
    SingleConsentRequest::build(Flow::gateway($redirectUri, Flow::redirectHint(Bank::PNZ)), $total, Pcr::build($particulars, $code, $reference)),
    $idempotencyKey
);

$consent = $client->createSingleConsent(
    SingleConsentRequest::build(
        Flow::gateway($redirectUri, Flow::decoupledHint($bank, $identifierType, $identifierValue)),
        $total,
        Pcr::build($particulars, $code, $reference)
    ),
    $idempotencyKey
);

$consent = $client->createSingleConsent(
    SingleConsentRequest::build(Flow::redirect($bank, $redirectUri), $total, Pcr::build($particulars, $code, $reference)),
    $idempotencyKey
);

$consent = $client->createSingleConsent(
    SingleConsentRequest::build(
        Flow::decoupled($bank, $identifierType, $identifierValue, $callbackUrl),
        $total,
        Pcr::build($particulars, $code, $reference)
    ),
    $idempotencyKey
);

$consent = $client->getSingleConsent($consentId);

$client->revokeSingleConsent($consentId);

$consent = $client->createEnduringConsent(
    EnduringConsentRequest::build(
        Flow::gateway($redirectUri),
        '2026-10-01T00:00:00+13:00',   // from_timestamp
        Period::MONTHLY,               // daily, weekly, fortnightly, monthly, annual
        $totalPerPeriod,
        '2027-10-01T00:00:00+13:00',   // expiry_timestamp, or null for indefinite
        $totalPerPayment               // optional per-payment cap
    ),
    $idempotencyKey
);

$flow = Flow::gateway($redirectUri, Flow::redirectHint(Bank::PNZ));
$consent = $client->createEnduringConsent(EnduringConsentRequest::build($flow, $startDate, $period, $totalPerPeriod), $idempotencyKey);

$flow = Flow::gateway($redirectUri, Flow::decoupledHint($bank, $identifierType, $identifierValue));
$consent = $client->createEnduringConsent(EnduringConsentRequest::build($flow, $startDate, $period, $totalPerPeriod), $idempotencyKey);

$flow = Flow::redirect($bank, $redirectUri);
$consent = $client->createEnduringConsent(EnduringConsentRequest::build($flow, $startDate, $period, $totalPerPeriod), $idempotencyKey);

$flow = Flow::decoupled($bank, $identifierType, $identifierValue, $callbackUrl);
$consent = $client->createEnduringConsent(EnduringConsentRequest::build($flow, $startDate, $period, $totalPerPeriod), $idempotencyKey);

$consent = $client->getEnduringConsent($consentId);

$client->revokeEnduringConsent($consentId);

$schedule = $client->createFixedRecurringPayment(
    FixedRecurringPaymentRequest::build(
        $consentId,
        $total,
        Pcr::build($particulars, $code, $reference),
        '2026-11-01',              // optional start_date; defaults to today or the consent's start
        RetryStrategy::SAME_DAY    // optional: none (default) or same_day
    ),
    $idempotencyKey
);
$fixedRecurringPaymentId = $schedule['fixed_recurring_payment_id'];

$schedule = $client->getFixedRecurringPayment($fixedRecurringPaymentId);   // status, next_payment_date, ...

$client->cancelFixedRecurringPayment($fixedRecurringPaymentId);

$payment = $client->createSingleConsentPayment($consentId, $idempotencyKey);

$payment = $client->createEnduringConsentPayment($consentId, $total, Pcr::build($particulars, $code, $reference), $idempotencyKey);

$payment = $client->createPayment(['consent_id' => $consentId], $idempotencyKey);

$payment = $client->getPayment($paymentId);
$settled = $client->awaitSuccessfulPayment($paymentId, 300);   // from a job; see Await helpers

$refund = $client->createAccountNumberRefund($paymentId, $idempotencyKey);

$refund = $client->createFullRefund($paymentId, Pcr::build($particulars, $code, $reference), $idempotencyKey);

$refund = $client->createPartialRefund($paymentId, Pcr::build($particulars, $code, $reference), $total, $idempotencyKey);

$refund = $client->getRefund($refundId);

$transactions = $client->getTransactions('2026-09-01T00:00:00+12:00', '2026-09-01T23:59:59+12:00', [
    'bank' => Bank::BNZ,
    'payment_status' => PaymentStatus::ACCEPTED_SETTLEMENT_COMPLETED,
    // 'consent_status' => ..., 'card_network' => ..., 'merchant_id' => ..., 'page' => 1, 'size' => 500,
]);

$totals = $client->getTransactionTotals('2026-09-01', '2026-09-07');   // NZ dates; successful payments only

$subscription = $client->createSubscription('https://shop.example/blinkpay/webhook', [
    BlinkDebitClient::EVENT_FIXED_RECURRING_PAYMENT_COMPLETED,
    BlinkDebitClient::EVENT_FIXED_RECURRING_PAYMENT_FAILED,
    BlinkDebitClient::EVENT_FIXED_RECURRING_PAYMENT_CANCELLED,
]);
$secret = $subscription['secret'];            // whsec_…, shown only now

$subscriptions = $client->getSubscriptions();
$client->deleteSubscription($subscriptionId);

use BlinkPay\BlinkDebit\WebhookSignature;

$rawBody = file_get_contents('php://input');
if (!WebhookSignature::verify($rawBody, $_SERVER['HTTP_X_SIGNATURE'] ?? '', $secret)) {
    http_response_code(400);   // 4xx is final: BlinkPay will not retry a delivery you reject
    exit;
}

$event = json_decode($rawBody, true);
// event_type, event_id, timestamp, frp_id, consent_id, and payment_id when one exists

use BlinkPay\BlinkDebit\Psr\Psr18Transport;

// Guzzle 7: the client is PSR-18, HttpFactory implements both PSR-17 factories.
$factory = new GuzzleHttp\Psr7\HttpFactory();
$transport = new Psr18Transport(new GuzzleHttp\Client(['timeout' => 30]), $factory, $factory);

// Symfony HttpClient: Psr18Client implements all three interfaces itself.
$psr18 = new Symfony\Component\HttpClient\Psr18Client();
$transport = new Psr18Transport($psr18, $psr18, $psr18);

$client = new BlinkDebitClient($clientId, $clientSecret, true, $tokenCache, $transport);

use BlinkPay\BlinkDebit\Psr\Psr16TokenCache;
use BlinkPay\BlinkDebit\Psr\Psr6TokenCache;

$tokenCache = new Psr16TokenCache($anyPsr16Cache);     // e.g. Cache::store() in Laravel
$tokenCache = new Psr6TokenCache($anyPsr6CachePool);    // e.g. cache.app in Symfony
shell
export BLINKPAY_CLIENT_ID=<BLINKPAY_CLIENT_ID>
export BLINKPAY_CLIENT_SECRET=<BLINKPAY_CLIENT_SECRET>
export BLINKPAY_SANDBOX=true            # true/false; unset or blank means true
export BLINKPAY_TIMEOUT=30              # seconds, optional
export BLINKPAY_CACHE_STORE=redis       # Laravel only, optional
bash
php artisan vendor:publish --tag=blinkpay-config