SpicePay

API authentication

API keys, environments, and security practices.

All API requests are authenticated with an API key in the api-key header:

curl https://api.spicepay.net/payments \
  -H "api-key: prd_****************" \
  -H "Content-Type: application/json"

Key types

Prefix Type Use
prd_ Secret Server-side only — full API access
pk_prd_ Publishable Browser-side only (hosted checkout) — safe to expose

There is no separate test key. The same key creates both test and real payments; the payment itself says which it is — see Environments below.

Secret keys grant full API access to your merchant account. Never ship them in client code, mobile apps, or public repositories. The publishable key is what the hosted checkout uses, always together with a payment's short-lived client_secret.

Managing keys

Create, label, and revoke secret keys in the Control Center. Keys are shown once at creation — store them in your secret manager.

  • Create separate keys per service/integration, so one compromise or one revocation doesn't take everything down.
  • Revocation is immediate.
  • Set an expiry on keys used by short-lived integrations.

Your publishable key lives on the merchant account and is visible in the dashboard at any time.

Environments

The environment is a property of the payment, not of your key or your account. Send test_mode when you create one:

{ "amount": 1000, "currency": "USD", "test_mode": true }
  • true — runs against your processor's sandbox and is recorded as a test, so it stays out of your live transaction list and analytics.
  • false — runs live.
  • omitted — the processor's own setting decides.

Nothing else changes: same key, same base URL, same code. Going live means no longer sending the flag — usually one environment variable in your own app.

test_mode is read when the payment is created. confirm and update can be called from the browser with a client secret, so honouring it there would let a buyer move a live payment into the sandbox and "succeed" it.

Processors need sandbox credentials

For a test payment to reach a sandbox, the processor has to have credentials for one. Some providers issue a separate set (a different key pair, a different developer app); others use one set for both and flag the request.

Store them in the Control Center under Processors → your processor → Sandbox credentials. Both sets live side by side and both stay active — each payment picks the one matching its own test_mode, so you never switch the processor over.

A processor with no sandbox credentials stored is called with the live ones. The payment is recorded as a test and stays out of your reporting, but the money moves. Add sandbox credentials for every processor that offers them before you rely on test mode, and use your provider's test cards so a stray real charge is impossible.

Check test_mode in your webhook handler

A test payment reaches succeeded exactly like a real one. Anything irreversible — shipping, provisioning, a receipt — should be gated on it:

if (event.content.object.test_mode) return; // don't fulfil a test

Idempotency

Mutating endpoints are idempotent via resource IDs rather than a separate header: pass your own payment_id when creating a payment (or refund_id when creating a refund) and retries of the same request return the original result instead of creating a duplicate.

Webhook authenticity

Inbound API calls use the api-key header; outbound webhooks are HMAC-signed so you can verify they came from SpicePay — see Webhooks.