Developers
REST API
GuidesErrorsLogin
Get API Keys
API Navigation
  • Overview
  • Quick start
  • Authentication
  • Collect a payment
  • Payment status
  • Refunds
  • Testing
  • Production
  • Security
API reference
  • Create API keys POST
  • List API keys GET
  • Get API key GET
  • Delete API key DEL
  • Collect with MTN POST
  • MTN payment status GET
  • Collect with Airtel POST
    Create and pay
  • Create order POST
  • Order fee POST
  • Pay order with card POST
  • Pay order with bank POST
  • Status and verify
  • Order status POST
  • Verify order POST
  • Cards and tokens
  • Save card POST
  • Tokenize charge GET
  • Refunds
  • Refund order POST
  • Lists and stats
  • List orders GET
  • Get order GET
  • List banks GET
  • Order stats GET
  • List transactions GET
  • Get transaction GET
  • Transaction statuses GET
Errors and limits
  1. Docs
  2. Guides
  3. Collect a payment

Collect a payment

A complete guide to collecting payments through MTN Mobile Money, Airtel Money, and Multi-channel Card/Bank Checkout via TransactPay.

Overview & Channel Selection

The API includes MTN MoMo, Airtel Money, and TransactPay order routes. The default server configuration targets MTN environment mtnrwanda and Airtel country RW with currency RWF. Live market, card brands, and provider activation still need client confirmation.

Preferred collect route
Documented samples use POST/payment/mtn-momo-pay with Authorization: Bearer <token>. A separate gateway API-key route (/payment/gateway-momo-pay) exists for server-to-server calls — keep x-api-secret on your server only.
Payment ChannelTarget AudienceAuthorizationSupported CurrenciesSettlement & Customer UX
MTN MoMo (API Key)Automated backend servers, POS, cron jobsx-api-key & x-api-secret3-letter code. Example uses RWF.Prompts customer with USSD on handset; poll status until completed.
MTN MoMo (Session)Single-page web apps, mobile apps with loginAuthorization: Bearer <token>3-letter code. Example uses RWF.Authenticated merchant session; prompts customer phone via USSD.
Airtel MoneyAirtel subscribers in the configured country. Default config is RW.Authorization: Bearer <token>3-letter code. Example uses RWF.Direct mobile collection; synchronous debit payload returned from Airtel.
Card & Bank (TransactPay)Card and bank order routes. Live brands are unconfirmed.Authorization: Bearer <token>Currency sent on the order. Example uses RWF.Two-step order workflow: Create order, then charge card or bank transfer.

Channel 1: MTN MoMo via Merchant Bearer token

POST/payment/mtn-momo-pay authenticates with Authorization: Bearer <merchant_jwt_token>. The JSON field is phoneNumber, not phone.

phoneNumber is the paying customer's MTN MSISDN (USSD prompt). The customer does not need a Ziba Pay account. If that MSISDN already belongs to a Ziba user it is linked on the order. The API returns 400 if it is the merchant's own phone number.

Upon submitting the request, MTN dispatches an interactive USSD prompt to the subscriber's handset. Extract the transactionReferenceId and poll the status endpoint until terminal confirmation.

cURL — Collect via MTN (Bearer)
curl -X POST "https://payment-service-mh2d.onrender.com/api/payment/mtn-momo-pay" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <merchant_token>" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "phoneNumber": "+250788000000",
    "amount": 1000,
    "currency": "RWF"
  }'

Channel 1b: Gateway API keys (server-to-server)

Gateway section only: POST/payment/gateway-momo-pay authenticates with x-api-key and x-api-secret. Prefer /payment/mtn-momo-pay for published samples unless your integration is pure server-to-server with gateway keys.

cURL — Collect via gateway keys
curl -X POST "https://payment-service-mh2d.onrender.com/api/payment/gateway-momo-pay" \
  -H "Content-Type: application/json" \
  -H "x-api-key: your_gateway_api_key" \
  -H "x-api-secret: your_gateway_api_secret" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "phoneNumber": "+250788000000",
    "amount": 1000,
    "currency": "RWF"
  }'

Channel 2: MTN MoMo via JavaScript session

If your frontend already maintains a merchant login session, call POST/payment/mtn-momo-pay with Authorization: Bearer <merchant_jwt_token>.

JavaScript — Collect via MTN Session
const response = await fetch("https://payment-service-mh2d.onrender.com/api/payment/mtn-momo-pay", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${merchantToken}`,
    "Idempotency-Key": crypto.randomUUID()
  },
  body: JSON.stringify({
    phoneNumber: "+250788000000",
    amount: 1000,
    currency: "RWF"
  })
});

const data = await response.json();
console.log("Track status with reference:", data.transactionReferenceId);

Channel 3: Airtel Money

For Airtel, use POST/payment/airtel-momo-pay with a merchant bearer token. Country and currency are taken from server configuration. The example configuration uses Airtel UAT, country RW, and currency RWF, so live Airtel is not confirmed.

The HTTP 200 response returns the raw JSON payload produced directly by Airtel's upstream OpenAPI gateway without a Ziba Pay wrapper envelope.

cURL — Collect via Airtel Money
curl -X POST "https://payment-service-mh2d.onrender.com/api/payment/airtel-momo-pay" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <merchant_token>" \
  -d '{
    "amount": 1500,
    "number": "788000000",
    "reference": "order-1042"
  }'

Channel 4: Card & Bank Checkout (TransactPay)

Card and bank payment routes use the TransactPay integration. Before creating orders, ensure your merchant account KYC status is VERIFIED.

TransactPay collections follow a structured 2-step workflow:

  • Step 1: Call POST/payment/zibapay/order/create with order.amount, order.currency, order.description, and redirectUrl to register the order reference.
  • Step 2 (Card): Call POST/payment/zibapay/card/:reference with card.cardnumber, card.expirymonth, card.expiryyear, card.cvv, country, and paymentoption.
  • Step 2 (Bank Transfer): Call POST/payment/zibapay/bank/:reference with BankTransfer.bankcode, country, and paymentoption.
  • Step 3: Poll POST/payment/zibapay/order/status/:reference or POST/payment/zibapay/order/verify/:reference to verify final payment outcome.
Card Data Security (PCI DSS)
Always submit card details directly from your secure backend servers. Never log raw card numbers (PANs) or CVVs in application log files or persistent databases.

Idempotency & Duplicate Prevention

Network drops and client timeouts can occur during mobile money collections. To prevent charging a customer twice when retrying a request, always provide a unique Idempotency-Key header (UUID v4) or an idempotencyKey parameter in the JSON request body.

If Ziba Pay receives a collection request with an Idempotency-Key that has already been processed within the last 24 hours, it returns the cached HTTP 200 response without initiating a second debit on the telecom network.

Payment Channels

4 available options
Server-to-ServerOption 1

MTN (API key)

Best for backend server-to-server integrations. Use your merchant API key and secret to initiate collections directly.
Explore MTN (API key)API Reference
Merchant SessionOption 2

MTN (Session)

Best for browser or frontend applications. Uses a merchant JWT session token in the Authorization Bearer header.
Explore MTN (Session)API Reference
Direct MoMoOption 3

Airtel

Direct mobile money collection for Airtel subscribers (configured country RW / currency RWF) using phone number, amount, and reference.
Explore Airtel MoneyAPI Reference
Hosted CheckoutOption 4

Card / Bank

TransactPay multi-channel checkout. Requires merchant KYC status VERIFIED. Create an order, then charge via card or bank.
Explore Create OrderAPI Reference
Polling (no webhooks)Status Polling Model

Merchant outbound webhooks are not implemented. Poll the payment status endpoint with your transactionReferenceId until COMPLETED or FAILED.

1. Polling IntervalPoll every 3 to 5 seconds after initiating payment.
2. Exponential BackoffIncrease to 5s, 10s, 20s if still pending after 30s.
3. Timeout HandlingMark expired after 180s and prompt user to re-initiate.

Related

Payment statusCollect with MTNCollect with AirtelCreate order
Was this page helpful?

Let us know how we can make our API documentation better.

PreviousAuthentication
NextPayment status