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.
| Key | Prefix | Where it runs | Can it move money? |
|---|---|---|---|
| Secret | sk_live_… | Your server only | Yes — full access |
| Publishable | pk_live_… | Browser and mobile apps | No — tokenisation only |
| Restricted | rk_live_… | Servers, per-service | Only what you granted |
| OAuth token | oat_… | Platforms acting for merchants | Scoped by the merchant |
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.
# 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"
<?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',
]);
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.
| Scope | Grants |
|---|---|
charges:read | Retrieve and list charges |
charges:write | Create, capture and refund charges |
customers:read | Retrieve and list customers and payment methods |
customers:write | Create, update and delete customers |
subscriptions:write | Manage recurring billing |
payouts:read | Read settlements and balance |
disputes:write | Submit evidence and accept liability |
webhooks:write | Manage 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/authorizewith yourclient_id, requestedscopeand astatevalue you generate. - They approve the scopes on a Bear Merchant screen. Nothing sensitive passes through your servers.
- We redirect back to your
redirect_uriwith a short-livedcode. - Exchange the code for an access token and refresh token at
/oauth/token.
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
}
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.
Practical hardening
- Load keys from environment variables or a secrets manager. Never commit them, and add
.envto.gitignorebefore 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.