Reference
SDK reference
Harbour Connect for PHP: the client, the services and the models.
Harbour Connect is the official PHP SDK: zero runtime dependencies, framework agnostic, integer kobo everywhere, typed exceptions carrying Harbour's own plain-language messages. It talks to the Harbour API and never to a provider, and it never sees provider keys.
Install
composer require nordaxiz/harbour-connect
PHP 8.1 or newer, with ext-curl and ext-json, and no runtime Composer dependencies. The
package is on Packagist; it is MIT licensed and the
source is on GitHub.
The SDK is below 1.0.0, so pin it. Composer treats ^0.1 as "patches only" — it allows
0.1.* but not 0.2.0 — which is what you want while the API settles:
composer require nordaxiz/harbour-connect:^0.1
Commit your composer.lock, so every deploy installs the version you tested against. See
Versioning before moving to a new minor version.
The client
PHP
<?php
use Nordaxiz\HarbourConnect\Harbour;
use Nordaxiz\HarbourConnect\HarbourClient;
// shared client for the static facade
Harbour::configure((string) getenv('HARBOUR_SECRET_KEY')); // api.harbour.africa
Harbour::configure((string) getenv('HARBOUR_SECRET_KEY'), $apiBase); // somewhere else
// or an instance: dependency injection, tests, one client per business
$harbour = new HarbourClient((string) getenv('HARBOUR_SECRET_KEY'), null, [
'webhook_secret' => (string) getenv('HARBOUR_WEBHOOK_SECRET'), // for $harbour->webhooks()
'timeout' => 30, // seconds, default 30
'connect_timeout' => 10, // seconds, default 10
'max_retries' => 2, // 0 to 2, default 2
'webhook_tolerance' => 300, // seconds either side, default 300
'transport' => $fake, // any Http\Transport, for tests
]);
$harbour = Harbour::tenant('hb_sk_live_…'); // the same thing, one line
$harbour->mode(); // "live" | "test"
$harbour->isTestMode();
$harbour->apiBase();
Harbour::VERSION; // sent as User-Agent: harbour-connect-php/<version>
Unknown options throw InvalidArgumentException, so a typo never passes silently. Keys are masked in
debug output and exception messages, kept out of var_dump, print_r, json_encode
and serialize, and marked #[\SensitiveParameter].
Services
PHP
<?php
// charges
Harbour::charge($amountKobo, $customer, $options = []); // → Checkout
Harbour::verify($harbourReference); // → Checkout
Harbour::charges()->findByMerchantReference('order-1043'); // → ?Checkout
$harbour->charge()->amount(…)->customer(…)->create(); // fluent builder
// refunds
Harbour::refund($reference, $amountKobo = null, $reason, $options = []); // → Refund
Harbour::refunds()->retrieve('ref_…');
// payment links
Harbour::links()->create($amountKobo, $description, $options = []);
Harbour::links()->retrieve('lnk_…');
// the ledger
Harbour::transactions()->list($filters = []); // → Page
Harbour::transactions()->all($filters = []); // → iterable, pages lazily
Harbour::transactions()->retrieve('HB-88413'); // → Transaction
// webhooks
Harbour::webhooks('whsec_…')->handle($request, $handler);
$harbour->webhooks()->handle($request, $handler); // uses the client's webhook_secret
Guides for each: charges, refunds, payment links, the ledger, webhooks.
Models
Every object gives you typed camelCase properties and the raw API fields, so a field added to the API tomorrow is readable today without upgrading:
PHP
<?php
$checkout->reference; // camelCase, typed
$checkout['checkout_url']; // the raw API field
$checkout->checkout_url; // the same
$checkout->toArray(); // everything, as it came back
$checkout->isPaid();
$page->hasMore();
$page->nextPage();
$page->autoPagingIterator();
Laravel
The service provider is auto-discovered. Add the keys to .env:
# .env
HARBOUR_SECRET_KEY=hb_sk_test_…
HARBOUR_WEBHOOK_SECRET=whsec_…
# HARBOUR_API_BASE=http://localhost/harbour-api
PHP
<?php
use Nordaxiz\HarbourConnect\HarbourClient;
use Nordaxiz\HarbourConnect\Webhook\WebhookHandler;
final class CheckoutController
{
public function __construct(private HarbourClient $harbour) {} // resolved by the container
public function store(Request $request, WebhookHandler $webhooks) { /* … */ }
}
Publish the config with php artisan vendor:publish --tag=harbour-config if you want it in the
repository. Exclude your webhook route from CSRF, and read the raw body. Laravel is a suggestion, not a dependency:
the SDK works the same in Symfony, Slim, WordPress or plain PHP.
Versioning
- Semantic versioning. Until 1.0.0, minor versions may contain breaking changes,
each one listed in the package's
CHANGELOG.md. Pin with^0.1and widen the constraint by hand, on purpose, after reading the changelog. - Releases are tagged
vX.Y.Zon GitHub and appear on Packagist automatically.composer outdated nordaxiz/harbour-connectshows what is available. - The version is
Harbour::VERSIONand travels asUser-Agent: harbour-connect-php/<version>, which is what support will ask for. - The API is versioned separately: every call goes to
/v1, whichever SDK version you run. Upgrading the package does not move you to a different API version. - Classes and methods marked
@internalare not covered by the promise. - Report a vulnerability privately: see
SECURITY.mdin the package.
Other languages
PHP is the first official SDK. The others below are coming soon; until then, every one of them can call the API directly, which is all an SDK does underneath.
- PHP Available
- Node.js Coming soon
- Python Coming soon
- Java Coming soon
- Go Coming soon
- .NET Coming soon