Developers

Authentication

Every request is authenticated with an API key. Keys are scoped, environment-specific and rotatable without downtime — so a mistake is recoverable rather than a breach.

Key types

Your dashboard issues four kinds of credential. Which one you use depends on where the code runs — the rule is simply that anything a browser can read must not be able to move money.

KeyPrefixWhere it runsCan it move money?
Secretsk_live_…Your server onlyYes — full access
Publishablepk_live_…Browser and mobile appsNo — tokenisation only
Restrictedrk_live_…Servers, per-serviceOnly what you granted
OAuth tokenoat_…Platforms acting for merchantsScoped by the merchant
A secret key in front-end code is a full account compromise, not a bug. If one has ever been committed to a repository, embedded in a mobile binary or pasted into a support ticket, roll it — assume it is public.

Making an authenticated request

Authentication uses HTTP Basic. Send the key as the username with an empty password — most HTTP clients will encode this for you. A bearer token header is also accepted if that suits your stack better.

auth.sh bash
# HTTP Basic — key as username, blank password (note the trailing colon)
curl https://api.bearmerchant.com/v1/charges \
  -u sk_live_51H8xQ2pLmNv:

# Bearer header — identical result
curl https://api.bearmerchant.com/v1/charges \
  -H "Authorization: Bearer sk_live_51H8xQ2pLmNv"
charge.php php
<?php
use BearMerchant\Client;

// Read the key from the environment — never hard-code it
$bm = new Client(getenv('BM_SECRET_KEY'));

$charge = $bm->charges->create([
    'amount'         => 4280,
    'currency'       => 'usd',
    'payment_method' => 'pm_1KdY7x',
]);
Keys are environment-bound. A sk_test_ key against the production host returns 401, and vice versa — so a misconfigured deploy fails loudly instead of quietly charging real cards.

Restricted keys and scopes

Most services do not need full account access. A reporting job needs to read charges; it has no business issuing refunds. Restricted keys let you grant exactly the permissions a service needs, so a leak from one system does not expose everything.

ScopeGrants
charges:readRetrieve and list charges
charges:writeCreate, capture and refund charges
customers:readRetrieve and list customers and payment methods
customers:writeCreate, update and delete customers
subscriptions:writeManage recurring billing
payouts:readRead settlements and balance
disputes:writeSubmit evidence and accept liability
webhooks:writeManage endpoint registrations
  • Grant the narrowest scope that lets the service do its job.
  • Issue one key per service, not one key shared across your estate — a shared key cannot be rotated without coordinating every consumer.
  • Name keys after the service that holds them, so an audit log entry tells you where a call came from.

OAuth for platforms

If you are a marketplace or SaaS platform acting on behalf of merchants, OAuth lets each merchant grant you access to their own account without ever handing over their secret key. They can revoke you at any time from their dashboard.

Authorisation flow

  • Redirect the merchant to /oauth/authorize with your client_id, requested scope and a state value you generate.
  • They approve the scopes on a Bear Merchant screen. Nothing sensitive passes through your servers.
  • We redirect back to your redirect_uri with a short-lived code.
  • Exchange the code for an access token and refresh token at /oauth/token.
oauth-exchange.sh bash
curl https://api.bearmerchant.com/oauth/token \
  -d grant_type=authorization_code \
  -d code=ac_9Fq2LmTdXk \
  -d client_id=ca_platform_7Yh2 \
  -d client_secret=cs_live_…

# Response
{
  "access_token": "oat_1PkX9a2eZvKY",
  "refresh_token": "ort_8Hn3QpLm",
  "merchant_id": "acct_4Km9Xt",
  "scope": "charges:write customers:read",
  "expires_in": 3600
}
Always verify that the state you receive back matches the one you sent. Skipping that check leaves the flow open to CSRF, where an attacker connects their own account to your user's session.

Rotating keys safely

Rotation should be routine, not an emergency procedure. Keys support an overlap window so you can roll one without a deploy freeze or a moment of downtime.

  • Create the replacement key in the dashboard. Both keys are now live.
  • Deploy the new key to your services and confirm traffic has moved — the dashboard shows last-used time per key.
  • Revoke the old key once its last-used timestamp stops advancing.

If a key has leaked

  • Revoke it immediately — revocation takes effect in under a second, globally. Do not wait for a maintenance window.
  • Check the API logs for calls from unfamiliar IPs during the exposure period.
  • Rotate any webhook signing secrets that were stored alongside it.
  • Tell us at support@bearmerchant.com so we can help review the account for unauthorised activity.
We scan public code hosts for leaked Bear Merchant keys. If one of yours turns up we revoke it and email you — but treat that as a safety net, not your first line of defence.

Practical hardening

  • Load keys from environment variables or a secrets manager. Never commit them, and add .env to .gitignore before the first commit, not after.
  • Restrict production keys to your egress IP ranges in the dashboard — a stolen key is then useless from anywhere else.
  • Log the key id (rk_live_51H8…, truncated) with each outbound call, never the full key.
  • Use separate keys per environment and per service, so revoking one never means an outage everywhere.
  • Enforce TLS 1.2 or higher in your HTTP client. We reject anything older.