Start here

Keys and modes

Which key goes where, what test mode really means, and how to keep secrets out of trouble.

Harbour issues its own credentials. They are not your provider's keys, and they never travel to a provider: Harbour holds the provider keys, encrypted, and uses them on the business's behalf.

The three credentials

CredentialLooks likeLivesCan do
Secret key hb_sk_live_…
hb_sk_test_…
Your server, in an environment variable Everything a Finance user can: create charges, verify, request refunds, create links, read the ledger. It can never approve a refund.
Public key hb_pk_live_…
hb_pk_test_…
A browser, in your page Start a checkout with harbour.js, and nothing else. Restrict it to your own domains on the same screen.
Endpoint secret whsec_… Your server, beside the secret key Prove a webhook delivery really came from Harbour. One per endpoint.
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;
use Nordaxiz\HarbourConnect\HarbourClient;

// one key for the whole process (most apps)
Harbour::configure((string) getenv('HARBOUR_SECRET_KEY'));

// or a client per key, for dependency injection, tests and multi-tenant apps
$harbour = new HarbourClient((string) getenv('HARBOUR_SECRET_KEY'), null, [
    'webhook_secret' => (string) getenv('HARBOUR_WEBHOOK_SECRET'),
]);

$harbour->isTestMode();   // true for hb_sk_test_…
$harbour->mode();         // "test" or "live"

Test and live

Mode runs the whole way through, and the two never touch:

  • A test Harbour key only ever reaches the business's test provider keys, and a live key only live ones.
  • The ledger, the feed and every list are filtered by the mode of the key that asks. A test key sees test payments only.
  • Webhook endpoints have a mode too, and their own signing secret, so test deliveries never hit your live endpoint.
  • Every object and every event carries "mode", so you can assert on it.

Creating and revoking keys

Keys are made in the dashboard under Settings → Developers, by an Owner. The secret is shown once, at creation: Harbour stores only a hash of it, so a lost key is replaced, never recovered.

  • Revoking is immediate: anything still using that key starts getting 401 unauthorized.
  • Rotating is two steps with no downtime: create the new key, deploy it, then revoke the old one.
  • Creating a live key needs a confirmed email address on the account. Test keys do not.

Rules that are not negotiable

  • Secret keys are server only. Never in a browser, a mobile app, a public repository or a client-side log. PHP cannot tell where a key ends up; that part is yours.
  • One key per environment. Staging and production get their own, so revoking one never takes the other down.
  • Never log a whole key. The SDK masks keys in exceptions and debug output, keeps them out of var_dump, print_r, json_encode and serialize, and refuses to be serialised at all.
  • Never send a secret key from a browser, even over HTTPS, even "just for a test". Use the public key.

If a key does leak: revoke it in Settings → Developers, create a replacement, and check Settings → Security for what that key did. Every key action is in the audit log.