Skip to main content
Sandbox is where you build. It runs the same code as production, but on its own servers and database, with simulated mobile money and bank rails and real crypto testnets. Nothing you do here moves real money. Your keys keep the two apart: a sk_test_ key only works in sandbox and a sk_live_ key only works in production, so you can’t send a test payout to a real customer by accident.

Funding a balance

Payouts and conversions spend from your balance, and a new sandbox account starts at zero. Use this endpoint to add test money to your sandbox balance so you have something to send. It’s sandbox only: no real money is involved, and it doesn’t exist in production.
The money lands instantly in that currency’s balance. It works for fiat currencies (NGN, GHS, KES, USD and so on); for crypto, send testnet funds to your deposit address instead (see Stellar testnet). Reusing an externalReference replays the original top-up, so use a new one each time. Prefer clicking? Add test funds on the dashboard’s Home and Balances pages does the same thing.

Deterministic outcomes

Real rails fail in real ways: a wallet rejects, a bank times out, a customer never approves the prompt. Sandbox lets you trigger each one on purpose.

Payouts: the amount’s cents choose the outcome

So 150.00 completes, 150.07 goes pending and then fails, the same code path your production integration will hit.

Collections: the amount’s cents choose the outcome

Validation: the account number’s suffix chooses the outcome

Simulated inflows

Money arriving has no natural trigger in sandbox, so there are endpoints for it:
  • POST /v1/simulations/virtual-account-deposit: a customer transferred into a virtual account (choose completed or failed).
  • POST /v1/simulations/checkout-deposit: a payer completed a bank-transfer checkout session.
  • Crypto deposits: send real testnet tokens to the address, or use the checkout page’s dev tools locally.
GET /v1/simulations returns this whole table as JSON, so your test suite can read the rules rather than hardcode them.

Stellar testnet

Sandbox runs on the real Stellar testnet. USDC is Circle’s testnet USDC, issuer GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5; XLM is testnet lumens. A testnet wallet to test with. Create a keypair with any Stellar wallet or SDK and fund it with 10,000 XLM from Friendbot:
For USDC, add a trustline to the asset above, then take testnet USDC from Circle’s faucet or swap testnet XLM for it on the Stellar testnet exchange (a path payment). Money in. Create a deposit address:
The response has an address and a tag. Send to the address with the tag as a memo ID. The memo is how the deposit is matched to your workspace, and a payment without it is held for manual review instead of being credited. Deposits credit within seconds of the ledger closing, net of the deposit fee, and send account.credited. Use "currency": "XLM" for lumens. Money out. A payout to any Stellar address:
Use xlm_stellar for XLM, and add "tag" when the destination needs a memo, as exchanges do. A USDC destination must hold a USDC trustline. Payouts complete within about a minute. Ramps. An order converts and delivers in one call, for example GHS from mobile money straight to USDC in a Stellar wallet:

What sandbox won’t tell you

Sandbox proves your integration: envelopes, idempotency, webhook handling, state machines. It doesn’t prove a specific rail’s behaviour on a Tuesday afternoon in Accra: real settlement times, real operator downtime, real limits. Treat the estimatedSettlement values in capabilities as the honest production guide.

Moving to production

You can create a sk_live_ key and use the production API from day one, changing nothing but the key and base URL. The one thing gated is sending payouts with real money: production access is enabled per organization. Email api-support@chippercash.com with your organization name and use case. If you create GHS virtual accounts, set your organization representative in production first. Sandbox fills one in from your owner’s name, but production doesn’t, and without one it returns 422.