IdealBoxPay

Documentation

Take your first payment.

Everything below is the real contract: the routes, the statuses, the failure codes, and the rules a correct integration follows.

The simulator is a provider

Not a mock. It implements the full adapter contract, is chosen by the same routing rules as anything else, and signs its callbacks with an HMAC over the raw body that we then verify like any other.

Scripted outcomes

The last three digits of the amount decide what happens. Deterministic, so a test suite can assert on it, and available to you in exactly the same way it is available to our own CI.

Amount ends inWhat happens
000Succeeds normally.
001Declines with INSUFFICIENT_FUNDS — retryable.
002The customer cancels at the prompt.
003Nobody answers; the payment reaches EXPIRED, not FAILED.
004The provider is unavailable, so the router looks elsewhere.
005Succeeds after about thirty seconds — the case your timeout handling is wrong about.
006The callback never arrives, and the reconciler has to resolve it.
# The last three digits of the amount script the outcome in test mode.
# …001 declines for insufficient funds:
curl https://api.idealbox.org/v1/payment_intents \
  -H "Authorization: Bearer ib_sk_test_4f2a9c1e8b7d6053" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "500001",
    "currency": "XAF",
    "country": "CM",
    "methodType": "MOBILE_MONEY",
    "providerParams": { "phoneNumber": "+237699000000" }
  }'

Resetting the sandbox

Developers → Overview has a reset. It clears your test events, deliveries, request logs, customers and — most usefully — your idempotency keys, then seeds a couple of sample customers back in.

Callbacks and the reconciler

Provider callbacks get lost, arrive twice and arrive out of order. A polling reconciler independently asks what happened, and both paths end in the same code, so they cannot disagree.