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
<?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
<?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
<?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.