Skip to content

Sandbox testing ​

Everything you need to run end-to-end integration tests against the sandbox before going live.

What the sandbox is ​

Every merchant starts in environment=sandbox. The sandbox has the exact same API contract as production — same endpoints, same auth, same response schemas — with three differences you need to know about:

  1. Transactions are capped at 1 USD per call (error RMT-9003 above that).
  2. The real telco switch is not contacted by default. Our platform fires a simulated callback locally (Successful status, references prefixed SIMULATED- and SIM-) so you can validate your integration without burning real money.
  3. Compliance screening (OFAC, PEP, internal blacklist) still runs identically — use realistic non-flagged names in your test payloads or you will see CMP-1001 (block) / CMP-1002 (hold).

Sandbox transactions are tagged environment=sandbox across all internal tables and never mix with production flows.

Test MSISDNs ​

In sandbox mock mode, any MSISDN with a valid operator prefix will complete successfully. The following numbers are convenient defaults you can use directly:

OperatorMSISDN
Vodacom M-Pesa243810000001
Orange243850000001
Airtel243990000001
Afrimoney243900000001

Any other number that respects the operator prefix rules below will also work.

Prefix rules per operator (RDC) ​

OperatorAccepted prefixesFormats accepted
Vodacom M-Pesa (mpesa)81, 82, 83, 869 digits (81xxxxxxx), 10 digits (081xxxxxxx), 12 digits (24381xxxxxxx)
Orange (orange)80, 84, 85, 89idem
Airtel (airtel)97, 98, 99idem
Afrimoney (afrimoney)90, 91idem

A number with an invalid prefix returns 400 RMT-1007 immediately, before any wallet reservation or DB write.

What a sandbox mock transaction looks like ​

Request:

bash
curl -X POST https://staging.remittance.gofreshpay.com/api/v1/remittance/inbound \
  -H 'Authorization: Basic <base64(merchant_code:merchant_secret)>' \
  -H 'X-Skip-Name-Check: true' \
  -H 'Content-Type: application/json' \
  -d '{
    "amount": 1,
    "currency": "USD",
    "customer_number": "243810000001",
    "reference": "YOUR-REF-001",
    "operator": "mpesa",
    "sender_first_name": "...", "sender_last_name": "...",
    ... (full KYC payload — see /api/inbound)
  }'

Immediate response (HTTP 202):

json
{
  "status": "accepted",
  "data": {
    "transaction_id": "IMT-IN-20261007-XXXXXX-XXXX",
    "reference": "YOUR-REF-001",
    ...
  }
}

A few hundred milliseconds later, a simulated callback is posted to your configured callback URL (HMAC-signed just like a real one) with:

json
{
  "status": "Successful",
  "transaction_reference": "IMT-IN-20261007-XXXXXX-XXXX",
  "switch_reference": "SIMULATED-dfd8ac4f7c6949bb",
  "telco_reference": "SIM-246bcc0fa8ca",
  "status_description": "Sandbox mock"
}

The SIMULATED- and SIM- prefixes are how you can tell a mock callback apart from a real one.

Important subtleties ​

The M-Pesa pre-validation step calls the real Vodacom switch ​

Even in sandbox mock mode, the pre-validation step for M-Pesa transactions hits the real Vodacom switch to confirm the subscriber name on the MSISDN you provide. This means:

  • If you declare expected_receiver_name in your payload, it must match the real subscriber on that MSISDN or you get a name-mismatch error.
  • Easiest workaround for testing: send the header X-Skip-Name-Check: true. This skips the aggregator KYC name check that normally cross-references the real subscriber name.

Compliance screening runs identically to production ​

Names like "John Doe", "Jane Smith", "Pierre Dubois" are commonly on sanctions / PEP watchlists and will be blocked (CMP-1001) or held (CMP-1002). Use realistic non-flagged names for your sandbox tests. If you need to test the compliance-hold path, use a name you expect to match (see Compliance & KYC).

The 1 USD cap is enforced early ​

If you send amount > 1, you get 403 RMT-9003 before any wallet reservation or DB insert — no side effect, your wallet balance is untouched. To test larger amounts you must go through the Go Live process.

Topping up your sandbox wallet ​

Sandbox wallets start empty. Before you can send /inbound, your relevant wallet (per currency + operator) must have credit. We grant a symbolic top-up on request — email remittance-support@mokoafrika.com with your merchant_code and the wallet(s) you need (currency + operator).

Advanced: real-switch dry run before Go Live ​

Some partners want to validate end-to-end against the real DRC telco switches before Go Live — real HTTP calls, real callbacks, real subscriber credit. This is possible on request:

  • We flip your test_mode from 1 (mock) to 0 (real switch) while keeping you in environment=sandbox.
  • You keep the 1 USD cap, but each transaction now actually credits the MSISDN you target.
  • Requires your sandbox wallet to be pre-funded with real float (contact support).

This is useful for last-mile validation (latency, real error codes from the telco, real subscriber names) before the full Go Live promotion.

Going live ​

When your sandbox integration is validated, request Go Live from the merchant dashboard. Backoffice approves within 24h, your production wallets are provisioned empty, and your subsequent /inbound calls hit the real switch with no cap. See Register & log in → Going live for the detailed flow.

Documentation is versioned alongside the API. Confidential — for integration partners.