After the payment

The ledger

Read your payments back: filters, cursors and settlement.

The ledger is every payment, refund and dispute across every provider the business has connected, in one shape. It is the thing most integrations read from after the first week: reconciliation, exports, a payments screen inside your own product.

List transactions

PHP
SDK language
  • PHP
  • Node.jsComing soon
  • PythonComing soon
  • JavaComing soon
  • GoComing soon
  • .NETComing soon
Any language can call the API today
<?php

use Nordaxiz\HarbourConnect\Harbour;

$page = Harbour::transactions()->list([
    'status'   => 'succeeded',            // succeeded | pending | failed | refunded | disputed
    'provider' => 'paystack',
    'channel'  => 'card',                 // card | bank_transfer | ussd | qr | mobile_money
    'from'     => '2026-09-01',           // a string or any DateTimeInterface
    'to'       => new DateTimeImmutable('2026-09-13'),
    'customer' => 'tunde@example.ng',
    'limit'    => 100,                    // 1 to 100, default 25
]);

foreach ($page as $transaction) {         // this page only
    echo $transaction->reference, ' ', $transaction->amountKobo, PHP_EOL;
}

Dates are the business's local days (Africa/Lagos), so "from 1 September" means from midnight in Lagos, not UTC. Every filter is optional; with none you get the newest payments, newest first.

Paging through everything

Lists are cursor paginated, never offset: a payment landing while you page will not shift rows under you.

PHP
SDK language
  • PHP
  • Node.jsComing soon
  • PythonComing soon
  • JavaComing soon
  • GoComing soon
  • .NETComing soon
Any language can call the API today
<?php

// every page, fetched lazily as you walk
foreach ($page->autoPagingIterator() as $transaction) {
    $export->write($transaction);
}

// the same, from the start, in one call
foreach (Harbour::transactions()->all(['status' => 'settled']) as $transaction) {
    $export->write($transaction);
}

// or drive it yourself
$page->nextCursor;   // "eyJvIjoi…" or null
$page->hasMore();    // bool
$next = $page->nextPage();

One transaction

PHP
SDK language
  • PHP
  • Node.jsComing soon
  • PythonComing soon
  • JavaComing soon
  • GoComing soon
  • .NETComing soon
Any language can call the API today
<?php

$transaction = Harbour::transactions()->retrieve('HB-88413');   // or 'txn_…'

$transaction->reference;           // "HB-88413"
$transaction->merchantReference;   // "order-1043"
$transaction->amountKobo;          // 1200000
$transaction->feeKobo;             // 18000  (the provider's fee; Harbour adds nothing)
$transaction->netKobo;             // 1182000
$transaction->status;              // "succeeded"
$transaction->provider;            // "paystack"
$transaction->channel;             // "card"
$transaction->customer->email;     // "funke@example.ng"
$transaction->occurredAt;          // DateTimeImmutable
$transaction->settlementId;        // "stl_…" once it is in a payout, else null

Every model also exposes the raw API fields, so a field added tomorrow is readable today: $transaction['net_kobo'], $transaction->net_kobo and $transaction->toArray() all work.

Settlement

A payment is succeeded when the customer paid, and settled once it is part of a payout that reached the bank. settlementId ties the two together, and the dashboard's settlement calendar shows what is forecast, what landed and what landed short. Harbour never moves that money: the provider pays the business's own bank account on the provider's own schedule.

If you reconcile against bank statements, match on the settlement, not on individual payments: providers pay in batches, net of their fees.