After the payment
Refunds
Refunds are requests. Someone with authority approves them.
A refund in Harbour is a request, not an instruction. It waits in the business's approval queue until an Owner approves it in the dashboard or the app. That is deliberate: refunds move real money out of a real bank account, and an API key should not be able to do that on its own.
Request a refund
PHP
<?php
use Nordaxiz\HarbourConnect\Harbour;
// partial: two metres short on a twelve-yard order
$refund = Harbour::refund('HB-88402', 25_000_00, 'Two metres short on delivery');
// or the whole payment
$refund = Harbour::refund('HB-88402', null, 'Customer cancelled before dispatch');
$refund->id; // "ref_…"
$refund->status; // "requested"
A reason is required, and it is not paperwork: the Owner reads it in the queue before deciding. Write the sentence you would say out loud.
The approval queue
- Finance users and API keys can request. Owners approve or decline.
- An Owner requesting from the dashboard approves in the same step, so a one-person business is not stuck.
- Staff cannot see refunds at all.
- Every request, approval and decline is in the audit log with who and when.
Following the status
React to the events rather than polling:
PHP
<?php
use Nordaxiz\HarbourConnect\Webhook\Event;
match ($event->type) {
Event::REFUND_COMPLETED => $order->creditBack($event->refund()->amountKobo),
Event::REFUND_DECLINED => $support->reopen($event->refund()->id, 'Refund declined'),
Event::REFUND_FAILED => $support->reopen($event->refund()->id, 'Provider refused the refund'),
default => null,
};
Or read the current state when you need it on a screen:
PHP
<?php
$refund = Harbour::refunds()->retrieve('ref_…');
$refund->status; // requested | approved | processing | completed | failed | declined
$refund->amountKobo;
$refund->reason;
Only completed means the money has left. approved and processing mean the
provider has it in hand; a provider can still fail a refund afterwards.