MoniWave
Sandbox open

The payments API for Central Africa

Collect and send Mobile Money payments in Cameroon, integrated directly with the operators. Start in the sandbox today: self-service signup, nothing to sign, no fees.

2
Operators, integrated directly
XAF
Central African CFA franc
FR / EN
Every screen, both languages
6
Deterministic test numbers
col_3f9c1e2a7b4d5 000 XAF
Completed
Operator
MTN Mobile Money
Customer
237 690 000 001
Fee
100 XAF
Net to you
4 900 XAF
Event history
  1. Accepted — request recorded14:02:11
  2. Submitted to the operator14:02:12
  3. Completed — confirmed by poll14:02:19
Webhook delivered
POST /your-endpoint
MoniWave-Signature: t=1755…,v1=9f3c…

{ "event": "collection.completed",
  "id": "evt_8c2f…", "amount": 5000 }
Rails
MTN Mobile Moneyin sandboxOrange MoneynextDirect integrations — no aggregator in between.
Where we are

What is true today, and what is not

We would rather you find the limits here than after a day of integration work.

French and English
Every screen a merchant or a customer sees exists in both languages. French is the reference, not a translation added later.
Direct integration
MTN Mobile Money, then Orange Money — with no aggregator sitting between you and the operator.
Deterministic sandbox
Test numbers that always produce the same outcome: success, decline, insufficient funds, expiry.
Published contract
A versioned, documented /v1 API whose error codes do not change without a new version.
Integration

Three steps to your first payment

Nothing to sign to begin: the test key is created with your account.

  1. 1

    Create your account

    Self-service signup. Your workspace and your first sk_test_ key exist immediately, with no step that waits on us.

  2. 2

    Call the API

    One request to collect: the amount, the currency and the customer's number. An idempotency key makes the call safe to replay without charging twice.

  3. 3

    Get the outcome

    A signed webhook tells you, and the status stays available to poll at any time — the notification is never the only source of truth.

curl -X POST https://api-sandbox.moni-wave.com/v1/collections \
  -H "Authorization: Bearer sk_test_…" \
  -H "Idempotency-Key: 3f9c1e2a-7b4d-4a1f-9c8e-2d6b5a0f3e11" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000,
    "currency": "XAF",
    "msisdn": "237690000001",
    "description": "Commande #1042"
  }'
Collecting 5,000 XAF from an MTN customer, in the sandbox.
Capabilities

What you can build

One API for money coming in, money going out, and everything needed to account for both.

Collections

Charge a customer's mobile wallet, confirmed on their own phone.

Payouts

Send money to a mobile wallet, one at a time or in bulk.

Refunds

Refund all or part of a collection, without calling anyone.

Hosted checkout

A link to send a customer when you do not have their number.

Webhooks

Signed notifications, retried, and replayable from the dashboard.

Dashboard

Transactions, balances, keys, team and the webhook delivery log.

See all capabilities
Ways in

Four ways to connect

From a raw HTTP call to a plugin you install — the same API underneath, so moving between them changes nothing about how money is handled.

01

REST API

Versioned /v1 endpoints, OpenAPI described, no SDK required. If you can make an HTTP request you can take a payment.

Available
02

Hosted checkout

Create a session, send the customer a link. They pick their operator and enter their number on a page we host, so you never touch it.

Available
03

Server SDKs

Node and PHP libraries generated from the same OpenAPI description as the docs, so they cannot drift from the contract.

In progress
04

E-commerce plugins

A WooCommerce plugin first, so a shop can take Mobile Money without anyone writing code.

Planned
Transaction lifecycle

A status you can actually trust

Most integration pain comes from a gateway that says “success” when it means “we sent it”. Here the status is folded from an immutable event stream, and the three terminal states absorb: nothing ever leaves them.

Acceptedrecorded, not yet sentSubmittedwith the operatorCompletedconfirmed by a status pollFaileddeclined, or no fundsExpiredcustomer never answeredterminal

An operator callback is recorded as a claim, never as truth — only a status poll makes an outcome final. That is why a missing webhook can never leave you guessing, and why a late duplicate callback cannot reopen a transaction you have already settled.

Sandbox

Six numbers, six outcomes, every time

The sandbox is deterministic rather than random: each test number always produces the same result, so a failing test means your code changed, not that the fake operator felt different today.

Test numberAlways produces
237 690 000 001Succeeds on the first status poll
237 690 000 002Stays pending ~10 s, then succeeds — exercises your poll loop
237 690 000 003Fails: the payer declined the prompt
237 690 000 004Fails: insufficient funds
237 690 000 005Stays pending forever — exercises expiry
237 690 000 006Rejected at submission: not a registered subscriber

These numbers are part of the published sandbox contract. Merchants script against them, so changing one would be a breaking change and is treated as such. Any other number behaves like the first row.

Get a test key
Guarantees

Built for developers

The guarantees that matter when money is involved, written into the contract rather than promised.

Idempotency is required

Every request that moves money carries a key; replaying it returns the original response.

Signed webhooks

Per-merchant HMAC-SHA256 signatures, with a reference implementation to verify them.

Status is confirmed, not claimed

An operator callback is evidence; only a status poll makes an outcome final.

A versioned contract

Error codes are stable; changing one would require a new version.

Get a test key
How the money is kept

Built like a ledger, not like a form

The parts that decide whether money is correct are not features bolted on later — they are the shape of the system.

Double-entry ledger

Every movement is a set of postings that sum to zero. A balance is derived, never edited, so it cannot silently disagree with its history.

Event-sourced history

The audit log is the source of truth rather than a copy of it. Status is folded from the events, so the record and the reality cannot diverge.

Signed webhooks

HMAC-SHA256 with a per-merchant secret and a timestamp, so you can verify a notification really came from us and is not a replay.

Hashed API keys

Keys are stored as SHA-256 digests and shown in plaintext exactly once, at creation. We cannot recover yours, which is the point.

Private data plane

The database has no public endpoint and is reachable only over a private link from the application, never from the internet.

Regional hosting

Runs in Azure South Africa North, the closest region to the CEMAC market with three availability zones.

We do not claim certifications we have not been through. PCI DSS is not relevant while no card data is touched, and any certification we do obtain will be named here with its scope rather than shown as a badge.

Settlement

Where the money sits, and when it moves

Collections do not vanish into an opaque pool: each one posts to your balance the moment it is confirmed, and you can see the posting.

  1. 01

    A collection completes

    The moment a status poll confirms it, the ledger posts the gross amount, the fee and the net — atomically with the terminal event, so the two can never disagree.

  2. 02

    Your balance updates

    Available funds move in real time and are visible in the dashboard and over the API. A payout is checked against them before submission.

  3. 03

    You pay out

    Send to any mobile wallet, singly or in bulk. A payout never leaves against a balance that is not there.

Architecture

Direct rails, not an aggregator of aggregators

Most of what is sold locally is a layer over other people’s integrations. That is a legitimate way to launch quickly, and it changes what you can be told when something goes wrong.

AspectThrough an aggregatorMoniWave
Hops to the operatorTwo or more, each able to time out or transform an error.One. We hold the operator contract and the connector.
What “success” meansOften “the upstream accepted it”, which is not the same as the customer paying.Confirmed by a status poll against the operator, never by a callback alone.
Dispute evidenceWhatever the middle layer chose to keep, requested by email.Every provider exchange is logged and attached to the transaction.
Error codesRe-mapped, and liable to change without a version.Contractual and stable — changing one requires a new API version.
FeesTwo margins stacked: the operator’s and the aggregator’s.One. There is nobody else in the chain to pay.
Coverage

Cameroon first, CEMAC next

One monetary zone, one currency, six countries. The rails are the same in each, which is what makes expansion a connector rather than a rebuild.

Countries

  • CameroonLaunch market
  • GabonPlanned
  • Republic of the CongoPlanned
  • ChadPlanned
  • Central African RepublicPlanned
  • Equatorial GuineaPlanned

All six share the Central African CFA franc (XAF), so a merchant integrating once does not re-integrate per country.

What is done, what is next

  1. Public sandbox

    Done

    Self-service signup, a test key in one call, deterministic outcomes.

  2. Merchant dashboard

    Done

    Transactions, balances, API keys, team and the webhook delivery log, in both languages.

  3. SDKs and plugins

    In progress

    Node and PHP first, then a WooCommerce plugin.

  4. Licensing

    Next

    The regulatory step that has to precede real money. Not ours to schedule, so no date is promised here.

  5. MTN Mobile Money, live

    Next

    The same API, the same webhooks — you swap the base URL and the key.

  6. Orange Money, live

    Next

    The second operator on the same connector interface.

Pricing

Pricing

You pay only for successful payments. A failure or an expiry costs nothing.

0 XAFfor everything in the sandbox, indefinitely

The rate card is being finalised: the figures below will be published before real payments open. We would rather show an empty cell than a number nobody has agreed to yet.

See the rate card
Use cases

Who it is for

The API is the same for everyone; these are the shapes it is being designed against.

  • Online retailOnline retail: collect at checkout, refund without calling anyone.
  • Software and subscriptionsSoftware and subscriptions: repeat collections and automatic reconciliation.
  • MarketplacesMarketplaces: collect on one side, pay sellers on the other.
  • Gaming and bettingGaming and betting: high volumes, fast payouts, a status you can trust.
Questions

Common questions

Including the ones a landing page usually avoids.

Can I take real payments today?

Not yet. The sandbox is open and behaves exactly as production will; real payments follow our licensing and operator agreements.

How do we go live?

Swap the base URL and the key. Nothing else changes: same requests, same responses, same webhooks.

Which operators are covered?

MTN Mobile Money first, Orange Money next, by direct integration rather than through an aggregator.

How do I get help?

Write to us — we answer in French and English, and the technical documentation is public.

What does it cost to test?

Nothing, with no time limit. The sandbox is free because it is how you decide whether to integrate at all, and a trial that expires mid-evaluation helps nobody.

What happens if a webhook never arrives?

Nothing is lost. Delivery is retried eight times with growing delays, every attempt is logged and redeliverable by hand, and the status stays available to poll — so a webhook is never your only way to know.

Do you handle card payments?

No. Mobile Money is the payment method that matters in this market, and doing one rail properly is worth more than doing several partially.

Who is behind MoniWave?

Awumba, building for the CEMAC market. Write to us and you will get a person who works on it, not a ticket queue.

Start in the sandbox

Create an account, take a test key, and run your first simulated collection within minutes.

No card, no contract, no sales call. Signing up creates a workspace and a test key.