ConceptsEnvironments

Environments

Soxara has two environments — test and live — accessible through the same base URL. Which environment your request lands in is determined by the prefix on your API key, not the URL.

Base URL:  https://api.soxara.com
Test key:  sxm_test_<random>     → test mode (sandbox rails)
Live key:  sxm_live_<random>     → live mode (real money)

This mirrors Stripe’s model. There’s no sandbox.api.soxara.com — you swap one character in your key and you’re in the other environment.

What changes between environments

Test modeLive mode
Card / MoMo / wallet paymentsSettle via simulate — no card network, no MoMo, no real wallet touchedReal settlement through the real rail
MandatesActivate immediately, no customer approval stepRequires a real card-save or wallet-PIN approval
WebhooksSent to your test endpoint; payload carries "environment": "test" inside data.paymentSent to your live endpoint; "environment": "live"
Webhook signaturesVerified against your test endpoint’s own signing secretVerified against your live endpoint’s own signing secret
Rate limitsShared with live — not more permissiveSame budgets

What stays the same

  • Endpoint URLs (/v1/api/payment-links, /v1/api/webhook-endpoints, etc.)
  • Request/response shapes
  • Error codes and the envelope
  • Webhook event names and payloads (down to field names)
  • Idempotency semantics

So you build once, test against sxm_test_* keys, and ship to production by swapping in your sxm_live_* keys. No code changes, no URL changes, no library swap.

How requests are routed

When the gateway receives a request:

  1. It reads the Authorization: Bearer sxm_(live|test)_... header.
  2. The prefix tells it which environment your request runs in. The gateway stamps X-Soxara-Env: live or X-Soxara-Env: test on the upstream request.
  3. Downstream services (payments, MoMo, wallet, etc.) read that header and pick the right provider credentials per request — card live vs test credentials, MTN production vs sandbox, etc.
  4. Every transaction row stored in our database carries the env. Test data and live data never mix in reports or webhooks.

Picking the right key to test with

A test merchant account in Soxara can mint both test and live keys. Use them like this:

Use caseKey
Local developmentsxm_test_*
CI / integration testssxm_test_* (with X-Idempotency-Key randomized per test run)
Staging environment that hits real customers’ real cardssxm_live_* (but with a low spending ceiling — talk to support to scope it down)
Productionsxm_live_*

Forcing an outcome in test mode

There’s no matrix of magic test card numbers or test phone numbers. Instead, settle a test payment link directly with simulate and pick the outcome yourself:

curl -X POST "$SOXARA_BASE/v1/api/payment-links/{id}/simulate" \
  -H "Authorization: Bearer $SOXARA_TEST_KEY" \
  -d '{"method": "momo", "outcome": "failed"}'

See Test with the sandbox for the full rundown, including mandates, sub-merchants, and card/fleet-card redemption in test mode.

Don’t mix environments

A sxm_test_* key’s payments fire your test endpoint’s webhooks, signed with that endpoint’s own secret — not your live endpoint’s. Register a separate webhook endpoint per environment and keep the two secrets in distinct env vars (SOXARA_TEST_WEBHOOK_SECRET, SOXARA_LIVE_WEBHOOK_SECRET); verifying a test delivery against your live secret (or vice versa) will fail.