Skip to content

Rails and countries

The 13 mobile money rails, their identifiers, per-project activation and the Orange Money Côte d’Ivoire OTP code.

A rail is a mobile money operator in a country. Its identifier goes in rail when creating a payment, a payout number or a quote. Every rail collects in XOF.

Rail table

CountryOperatorIdentifier
🇸🇳 SenegalWavesn_wave
🇸🇳 SenegalOrange Moneysn_orange
🇨🇮 Côte d’IvoireWaveci_wave
🇨🇮 Côte d’IvoireOrange Money (customer OTP code)ci_orange
🇨🇮 Côte d’IvoireMTN Mobile Moneyci_mtn
🇨🇮 Côte d’IvoireMoov Moneyci_moov
🇧🇫 Burkina FasoOrange Moneybf_orange
🇧🇫 Burkina FasoWavebf_wave
🇧🇫 Burkina FasoMoov Moneybf_moov
🇹🇬 TogoMoov Moneytg_moov
🇹🇬 TogoTogoceltg_togocell
🇧🇯 BeninMoov Moneybj_moov
🇧🇯 BeninMTN Mobile Moneybj_mtn

Read the list: GET /v1/rails

Public route. With a key, the response also says which rails are activated on the project.

Terminal
curl "$API_URL/v1/rails?lang=en" -H "Authorization: Bearer $API_KEY"
200 · application/json (excerpt)
{
  "currency": "XOF",
  "data": [
    {
      "rail": "sn_wave",
      "country": "SN",
      "country_label": "Senegal",
      "operator": "wave",
      "operator_label": "Wave",
      "label": "Wave",
      "otp_required": false,
      "min_amount": "100",
      "platform_state": "open",
      "enabled_for_project": true,
      "fees": {
        "collection_bps": 200,
        "withdrawal_bps": 200,
        "refund_bps": 200,
        "example_10000": { "amount": "10000", "collection_fee": "200", "withdrawal_fee": "200", "refund_fee": "200" }
      }
    }
  ]
}

The rates in force are in fees: see Fees.

Activate a rail on a project

A project collects on a rail when enabled_for_project is true and platform_state is open. A new project has sn_wave and sn_orange activated. An administrator activates or deactivates the others:

Terminal
curl -X PUT "$API_URL/v1/rails/ci_wave/enabled" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled": true}'

Every change is logged. A payment on a rail not activated returns 503 CHANNEL_UNAVAILABLE.

Common rules

  • Currency: XOF only.
  • Amount: digit string in whole XOF, at least min_amount.
  • customer_phone: mobile number of the rail's country, in local or E.164 format.
  • Each rail has its own balance. See Balances.

Customer step: next_action

Depending on the operator, the customer approves the payment through a redirect, a QR code or an instruction on their phone. The creation response gives the step in next_action. Handling of each type is described in Payments, section "Customer action".

Orange Money Côte d’Ivoire OTP code

On ci_orange, the customer authorises the payment with a one-time code (OTP) generated from their Orange Money account. The code comes with the payment creation.

The customer generates the code

The customer dials #144*82# on their Orange Côte d’Ivoire phone and follows the prompts: Orange Money shows a one-time code.

The order page collects the number and the code

Two fields: customer mobile number and OTP code (4 to 8 digits). Show the procedure (#144*82#) next to the field, with the instruction: "Enter the code immediately after receiving it."

The server creates the payment with customer_otp

Terminal
curl -X POST "$API_URL/v1/payments" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: order-2077" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "2500",
    "currency": "XOF",
    "rail": "ci_orange",
    "merchant_reference": "order-2077",
    "return_url": "https://shop.example/payment/return",
    "customer_phone": "+2250701020304",
    "customer_otp": "123456"
  }'

Single-use code

On your server, send customer_otp for this payment only. Do not store the code or write it to your logs. 221 Pay does not retain it either.