Skip to main content

Testing

There is no separate sandbox environment to point at. Your account is the sandbox until go-live is approved, on the production base URL with your normal API key. That means the code you test with is the code you ship: no host swap, no key swap, nothing left to get wrong on launch day.

Card payments are tested differently

Cards have a real sandbox on UAT, with test cards that move no money, and none on production: every card payment on production charges a real card. See Testing Card Payments.

What is restricted before approval​

While your project's go-live status is anything other than APPROVED:

RestrictionDetail
RecipientsCollections and payouts only reach counterparties on your Test Recipients whitelist
Whitelist sizeUp to 3 phone numbers, plus a separate list of test bank accounts
Daily capTZS 100,000 per day, counted separately for collections and disbursements

Everything else behaves exactly as it will in production: real channels, real webhooks, real fees, real money. These are small live transactions, not simulations, so use your own numbers and expect to be charged.

Registering test recipients​

Add them in the dashboard under Settings → Test Recipients, or over the API:

curl https://core-prod.malipopay.co.tz/api/v1/project/test-numbers \
-H "apiToken: YOUR_API_KEY" \
-H "Authorization: Bearer YOUR_DASHBOARD_TOKEN"

That returns { numbers, count, max }, where max is 3. To add a phone recipient, POST the same path:

{ "type": "PHONE", "msisdn": "255712345678", "label": "My test line" }

msisdn accepts 0744..., 255744... or +255744... and is normalised for you. Bank recipients go on the same endpoint with type: "BANK" plus bankCode, bankName and accountNumber. PUT /api/v1/project/test-numbers/{id} edits one and DELETE on the same path removes it.

These routes need a dashboard session in addition to the API key and are owner-only, so in practice the dashboard is the easier route. Adding a fourth recipient, or one that is already listed, returns HTTP 409.

A payment to a number that is not on the whitelist is rejected with HTTP 400 and a message naming the project. It is not a silent failure, and it is not a channel problem.

Checking your current limits​

curl https://core-prod.malipopay.co.tz/api/v1/payment/limits \
-H "apiToken: YOUR_API_KEY"

This returns the limit actually being enforced for each direction along with today's usage, which is the fastest way to tell whether you are hitting a cap or a genuine failure.

What to test before going live​

  • One successful collection on each channel you intend to use, checked at your webhook rather than only at the API response.
  • One failed collection (let the USSD prompt time out) so you exercise the payment.failed path.
  • One disbursement all the way through: create, approve from your whitelisted IP, and confirm payout.confirmed arrives.
  • A replayed webhook, to confirm your handler is idempotent.
  • A repeated collection with the same reference, to confirm you get the existing payment back rather than a second charge.