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
| Credential | Looks like | Lives | Can 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
<?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_encodeandserialize, 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.