Skip to content

FSD-02, Bill Payment and Products, RichatPay

Purpose and scope

RichatPay is one integration that fronts several billers and products behind one contract. The customer opens a tile in the wallet, walks a few screens, gets back an amount or a price, and pays it, the same way for a school-fee bill, an R-Pay merchant, an insurance policy, a gift card, an international top-up, or a TOD pass. Which biller or product runs is decided by the tile, never by a separate integration, so adding a biller or a product is a data change and not a re-integration. The customer and Comviva see only RichatPay, never the partner behind it.

There is never a tax or a fee added on top, the amount the customer confirms is the amount debited. The wallet debit is the wallet's own leg in every flow. The integration posts one settlement leg of its own (one collection account to one biller or insurer settlement account) only for the invoice billers and for Assurance. R-Pay, the Shopping vouchers, the international recharge and TOD post no settlement leg. The four product flows that deliver a partner-fulfilled item (Assurance, Shopping, international recharge, TOD) reverse the wallet as one leg if the item fails to deliver after the debit. So the only postings Comviva must back are a single settlement leg and its one-to-one reversal, addressed by account role and idempotent on the caller reference.

International recharge here is top-up of a line in another country, and it is one of the product flows. National airtime is a separate service on its own contract, the two are not the same contract. The Shopping vouchers have no native Mobiquity voucher service to map to today, so they carry a precise ask to Comviva for a named voucher purchase service, while the invoice billers, R-Pay and Assurance ride the signed bill-pay contract.

Customer flows

RichatPay is one integration that fronts several billers and products. The customer opens a tile in the Bills and products area of the wallet, the tile decides the flow, and from there the customer walks a few screens, gets back an amount or a price, and pays it. There is never a tax or a fee line added on top, the amount the customer confirms is the amount debited. Each flow below is given screen by screen (what the customer enters, what comes back), with its endpoint, its payload, and a sequence diagram.

The grouping model, standalone billers plus folders

BMCI delivers each invoice biller as a standalone biller, each with its own biller code and its own settlement account. No biller is delivered as part of a shared group. For each biller BMCI also tells Comviva which folder it belongs in, and provides an icon for it. Comviva builds the folders in its catalogue interface (Sante, Transport et Logistique, Etablissements scolaires, Humanitaire, Electricite, and the rest), orders them, drops the standalone billers into the named folders, and shows each biller with the provided icon. The customer opens a folder, picks a biller inside it, and pays by reference. The folders live on Comviva's side, the billers behind them are a flat standalone set.

The products (R-Pay, Assurance, the Shopping vouchers, TOD, and the international Recharge) are not folder-grouped. Each is its own tile and runs its own flow, described below.

The folder-to-biller mapping BMCI hands Comviva (the folder name, then the standalone billers BMCI assigns to it), each biller carrying its own icon.

  • Etablissements scolaires (school fees): El Maarif, Enasser, El Menhel, Boulough El Maram.
  • Transport et Logistique: MTS, Master Voyages, HA Voyages, ARKAS, CMA CGM.
  • Divertissement: BeIN Sport, TOD.
  • Humanitaire: Ithar.
  • Sante: Hopital Cheikh Zayed.
  • Electricite: seeded at cutover from the live catalogue (none confirmed in the reference data, to confirm).

Flow 1, standalone invoice biller

The customer opens the biller tile, types the bill reference, the bill is consulted, and pays. The biller is its own tile, so there is no folder and no biller picker. The customer taps the tile and lands straight on the reference screen.

Endpoint /richattAPI/facturier/standalone/{facturierId}, the path variable is the biller id directly.

Screens.

  1. Reference de la facture. The customer types the bill reference printed on the bill (no biller picker, the tile is the biller). When the biller allows partial payment, an amount field is shown pre-filled with the total instead.
  2. The bill is consulted. The summary comes back showing the amount due and the customer name on the bill.
  3. The customer confirms, enters the PIN. The wallet is debited and the bill is paid to the biller. The receipt shows the transaction reference and the paid amount.

Consult. Request, then response (the biller is fixed by the tile).

{ "billerCode": "0016", "reference": "516707", "phoneNumber": "+222 32 88 01 87", "language": "fr" }
{ "reference": "516707", "amount": 12000, "customer": "Mariem Mint Ahmed", "partnerName": "CMA CGM", "partialPayment": false }

Pay. Request, then response.

{ "billerCode": "0016", "reference": "516707", "amount": 12000, "phoneNumber": "+222 32 88 01 87", "externalReferenceId": "1000041", "paymentDate": "2026-06-20T16:30:33Z" }
{ "status": "success", "reference": "PP-2026-0041", "amount": 12000, "customer": "Mariem Mint Ahmed" }
sequenceDiagram
  participant Customer
  participant Wallet as Wallet (Mobiquity)
  participant BMCI as BMCI (integration)
  participant RPay as RichatPay (aggregator)
  Customer->>Wallet: tap biller tile, type Reference (516707)
  Wallet->>BMCI: consult bill (bill-details)
  BMCI->>RPay: consult invoice
  RPay-->>BMCI: amount 12000, customer
  BMCI-->>Wallet: amount, customer
  Wallet-->>Customer: summary (no fee line), confirm + PIN
  Wallet->>Wallet: debit customer (wallet's own leg)
  Wallet->>BMCI: debit confirmed
  BMCI->>RPay: pay invoice
  RPay-->>BMCI: paid, biller credited
  BMCI->>BMCI: settlement, collection acct to biller acct (one leg)
  BMCI-->>Wallet: paid
  Wallet-->>Customer: receipt (reference, amount)

Flow 2, R-Pay

The single dedicated R-Pay tile. The customer enters a reference, R-Pay resolves the merchant behind it, the customer pays. There is no folder and no biller picker, and R-Pay carries no settlement leg.

Endpoint /richattAPI/rpay, no path variable (there is nothing to choose).

Screens.

  1. Reference. The customer types the R-Pay reference or identifier. R-Pay resolves the merchant behind it.
  2. The reference is consulted. The summary comes back with the amount, the merchant name, and whether partial payment is allowed.
  3. The customer confirms, enters the PIN. The wallet is debited and the payment is made to R-Pay. The receipt shows the transaction reference and the paid amount.

Consult. Request (partner fixed at 0), then response (the merchant name is resolved by R-Pay).

{ "billerCode": "0", "reference": "749661", "phoneNumber": "+222 32 88 01 87", "language": "fr" }
{ "reference": "749661", "amount": 2500, "customer": "Ahmed Salem", "partnerName": "Boutique Centrale", "partialPayment": false }

Pay. Request, then response.

{ "billerCode": "0", "reference": "749661", "amount": 2500, "phoneNumber": "+222 32 88 01 87", "externalReferenceId": "1000051", "paymentDate": "2026-06-20T16:30:33Z" }
{ "status": "success", "reference": "PP-2026-0051", "amount": 2500 }
sequenceDiagram
  participant Customer
  participant Wallet as Wallet (Mobiquity)
  participant BMCI as BMCI (integration)
  participant RPay as RichatPay (aggregator)
  Customer->>Wallet: tap R-Pay tile, type Reference (749661)
  Wallet->>BMCI: consult (bill-details, partner 0)
  BMCI->>RPay: consult, resolve merchant
  RPay-->>BMCI: amount 2500, merchant Boutique Centrale
  BMCI-->>Wallet: amount, merchant
  Wallet-->>Customer: summary (no fee line), confirm + PIN
  Wallet->>Wallet: debit customer (wallet's own leg)
  Wallet->>BMCI: debit confirmed
  BMCI->>RPay: pay
  RPay-->>BMCI: paid
  BMCI-->>Wallet: paid (no settlement leg)
  Wallet-->>Customer: receipt (reference, amount)

Flow 3, Assurance

The customer browses to an insurance policy, enters the vehicle registration, gets a priced quote for that vehicle, and pays. The policy is delivered by the insurer.

Endpoint /richattAPI/product/ASSURANCE, the path variable is the category reference ASSURANCE.

Screens.

  1. Choisissez un type. The customer picks the type, then the insurer or brand (for example Medina Assurance).
  2. Choisissez un produit. The customer picks the policy (for example the 3, 6 or 12 month civil-liability RC policy).
  3. Numero d'immatriculation. The customer enters the vehicle registration number (for example 2605AZ00).
  4. Product details. The quote comes back priced for that vehicle (for example Assurance RC 12 mois, 3101 MRU).
  5. The customer confirms, enters the PIN. The wallet is debited, the purchase is completed with the insurer using a reservation taken before the debit. On success the receipt shows the policy reference. On failure the wallet debit is reversed.

Quote. Request (the vehicle registration is the input), then response.

{ "productCode": "MEDINA_RC_12", "phoneNumber": "+222 32 88 01 87", "registrationNumber": "2605AZ00" }
{ "productCode": "MEDINA_RC_12", "label": "Assurance RC 12 mois", "description": "Responsabilite civile auto, 12 mois", "price": 3101 }

Pay. Request, then success response (the policy reference).

{ "productCode": "MEDINA_RC_12", "amount": 3101, "phoneNumber": "+222 32 88 01 87", "registrationNumber": "2605AZ00", "externalReferenceId": "1000071", "paymentDate": "2026-06-20T16:30:33Z" }
{ "status": "success", "reference": "PP-2026-0071", "policy": "MED-RC12-2605AZ00" }
sequenceDiagram
  participant Customer
  participant Wallet as Wallet (Mobiquity)
  participant BMCI as BMCI (integration)
  participant RPay as RichatPay (aggregator)
  Customer->>Wallet: pick type, brand (Choisissez un type), policy (Choisissez un produit)
  Customer->>Wallet: enter registration (2605AZ00)
  Wallet->>BMCI: quote for vehicle
  BMCI->>RPay: get product details for registration
  RPay-->>BMCI: price 3101
  BMCI-->>Wallet: price 3101
  Wallet-->>Customer: summary (no fee line), confirm + PIN
  BMCI->>RPay: reserve purchase (pre-debit)
  RPay-->>BMCI: payment id
  Wallet->>Wallet: debit customer (wallet's own leg)
  Wallet->>BMCI: debit confirmed
  BMCI->>RPay: confirm purchase (payment id)
  alt succeeds
    RPay-->>BMCI: policy
    BMCI->>BMCI: settlement, collection acct to insurer acct (one leg)
    BMCI-->>Wallet: policy reference
    Wallet-->>Customer: receipt with policy reference
  else fails
    RPay-->>BMCI: failed
    BMCI->>BMCI: reversal, collection acct to customer acct (one leg)
    Wallet-->>Customer: purchase did not complete, wallet refunded
  end

Flow 4, Shopping vouchers

The customer picks a brand, picks a denomination, and pays the fixed catalogue price. The voucher is delivered by the partner.

Endpoint /richattAPI/product/SHOPPING, the path variable is the category reference SHOPPING.

Screens.

  1. Que souhaitez-vous faire? (only when the customer already bought vouchers in the last 30 days). The customer picks Effectuer un achat to buy, or Historique vouchers to see past vouchers. When there is no prior voucher, this screen is skipped and the flow starts at the brand.
  2. Choisissez un type. The customer picks the brand (for example Amazon, Noon, Shein, Talabat).
  3. Choisissez un pays. The customer picks the country for the brand.
  4. Choisissez un produit. The customer picks the denomination, shown with its price (for example a gift card priced 17746.82 MRU).
  5. Product details. The price is shown from the catalogue, no extra input.
  6. The customer confirms, enters the PIN. The wallet is debited, the purchase is completed with the partner using a reservation taken before the debit. On success the receipt shows the voucher code. On failure the wallet debit is reversed.

Quote. Request, then response (fixed catalogue price, no registration).

{ "productCode": "AMAZON_UAE_1500", "phoneNumber": "+222 32 88 01 87" }
{ "productCode": "AMAZON_UAE_1500", "label": "Amazon UAE 1500", "description": "Carte cadeau Amazon", "price": 17746.82 }

Pay. Request, then success response (the voucher code).

{ "productCode": "AMAZON_UAE_1500", "amount": 17746.82, "phoneNumber": "+222 32 88 01 87", "externalReferenceId": "1000081", "paymentDate": "2026-06-20T16:30:33Z" }
{ "status": "success", "reference": "PP-2026-0081", "voucher": "AMZ-7H3K-9QX2-1500" }
sequenceDiagram
  participant Customer
  participant Wallet as Wallet (Mobiquity)
  participant BMCI as BMCI (integration)
  participant RPay as RichatPay (aggregator)
  Customer->>Wallet: pick brand (Choisissez un type), country (Choisissez un pays), denomination (Choisissez un produit)
  Wallet->>BMCI: quote
  BMCI->>RPay: get product details
  RPay-->>BMCI: price 17746.82
  BMCI-->>Wallet: price 17746.82
  Wallet-->>Customer: summary (no fee line), confirm + PIN
  BMCI->>RPay: reserve purchase (pre-debit)
  RPay-->>BMCI: payment id
  Wallet->>Wallet: debit customer (wallet's own leg)
  Wallet->>BMCI: debit confirmed
  BMCI->>RPay: confirm purchase (payment id)
  alt succeeds
    RPay-->>BMCI: voucher code
    BMCI-->>Wallet: voucher code (no settlement leg)
    Wallet-->>Customer: receipt with voucher code
  else fails
    RPay-->>BMCI: failed
    BMCI->>BMCI: reversal, collection acct to customer acct (one leg)
    Wallet-->>Customer: purchase did not complete, wallet refunded
  end

Flow 5, international recharge

The customer picks a country, picks an operator product, enters the line to top up in another country, and pays. The top-up is delivered by the partner. This is international airtime, distinct from national recharge, which is a separate service on its own contract.

Endpoint /richattAPI/product/RECHARGE, the path variable is the category reference RECHARGE.

Screens.

  1. Choisissez un pays. The customer picks the country (for example Morocco, Tunisia, UAE, Spain, Saudi Arabia).
  2. Choisissez un type. The customer picks the operator (for example Maroc Telecom, Orange, Ooredoo, DU, Etisalat).
  3. Choisissez un produit. The customer picks the operator product or bundle.
  4. Numero de telephone a recharger. The customer enters the line to top up in international format (the screen shows the country's example, for example +212...).
  5. Product details. The price is shown from the catalogue.
  6. The customer confirms, enters the PIN. The wallet is debited, the top-up is completed with the partner using a reservation taken before the debit. On success the receipt shows the transaction reference. On failure the wallet debit is reversed.

Quote. Request, then response.

{ "productCode": "MAROC_TELECOM_2GB", "phoneNumber": "+222 32 88 01 87" }
{ "productCode": "MAROC_TELECOM_2GB", "label": "Maroc Telecom 2GB", "description": "Recharge data 2GB", "price": 94 }

Pay. Request (the line to recharge is carried as the top-up target), then success response.

{ "productCode": "MAROC_TELECOM_2GB", "amount": 94, "phoneNumber": "+212625833296", "externalReferenceId": "1000091", "paymentDate": "2026-06-20T16:30:33Z" }
{ "status": "success", "reference": "PP-2026-0091" }
sequenceDiagram
  participant Customer
  participant Wallet as Wallet (Mobiquity)
  participant BMCI as BMCI (integration)
  participant RPay as RichatPay (aggregator)
  Customer->>Wallet: pick country (Choisissez un pays), operator (Choisissez un type), product (Choisissez un produit)
  Customer->>Wallet: enter line to recharge (+212625833296)
  Wallet->>BMCI: quote
  BMCI->>RPay: get product details
  RPay-->>BMCI: price 94
  BMCI-->>Wallet: price 94
  Wallet-->>Customer: summary (no fee line), confirm + PIN
  BMCI->>RPay: reserve purchase (pre-debit)
  RPay-->>BMCI: payment id
  Wallet->>Wallet: debit customer (wallet's own leg)
  Wallet->>BMCI: debit confirmed
  BMCI->>RPay: confirm purchase (payment id, line to recharge)
  alt succeeds
    RPay-->>BMCI: topped up
    BMCI-->>Wallet: done (no settlement leg)
    Wallet-->>Customer: receipt (reference)
  else fails
    RPay-->>BMCI: failed
    BMCI->>BMCI: reversal, collection acct to customer acct (one leg)
    Wallet-->>Customer: top-up did not complete, wallet refunded
  end

Flow 6, TOD

The customer picks a TOD type, enters a Mauritanian line on its own input (not the international recharge input), and pays.

Endpoint /richattAPI/product/TOD, the path variable is the category reference TOD.

Screens.

  1. Choisissez un type. The customer picks the TOD type (for example Passe et Abonnement). There is no country picker.
  2. Choisissez un produit. The customer picks the product.
  3. Numero de telephone a recharger. The customer enters a Mauritanian line on 8 digits (no country code, the system adds +222 before sending).
  4. Product details. The price is shown from the catalogue.
  5. The customer confirms, enters the PIN. The wallet is debited and the purchase is completed with the partner. On success the receipt shows the transaction reference. On failure the wallet debit is reversed.

Quote. Request, then response.

{ "productCode": "TOD_PASS_1M", "phoneNumber": "+222 32 88 01 87" }
{ "productCode": "TOD_PASS_1M", "label": "TOD Passe 1 mois", "description": "Passe et abonnement", "price": 389 }

Pay. Request (the Mauritanian line, normalised to +222), then success response.

{ "productCode": "TOD_PASS_1M", "amount": 389, "phoneNumber": "+22247000125", "externalReferenceId": "1000101", "paymentDate": "2026-06-20T16:30:33Z" }
{ "status": "success", "reference": "PP-2026-0101" }
sequenceDiagram
  participant Customer
  participant Wallet as Wallet (Mobiquity)
  participant BMCI as BMCI (integration)
  participant RPay as RichatPay (aggregator)
  Customer->>Wallet: pick type (Choisissez un type), product (Choisissez un produit)
  Customer->>Wallet: enter Mauritanian line (8 digits)
  Wallet->>BMCI: quote
  BMCI->>RPay: get product details
  RPay-->>BMCI: price 389
  BMCI-->>Wallet: price 389
  Wallet-->>Customer: summary (no fee line), confirm + PIN
  BMCI->>RPay: reserve purchase (pre-debit)
  RPay-->>BMCI: payment id
  Wallet->>Wallet: debit customer (wallet's own leg)
  Wallet->>BMCI: debit confirmed
  BMCI->>RPay: confirm purchase (payment id)
  alt succeeds
    RPay-->>BMCI: done
    BMCI-->>Wallet: done (no settlement leg)
    Wallet-->>Customer: receipt (reference)
  else fails
    RPay-->>BMCI: failed
    BMCI->>BMCI: reversal, collection acct to customer acct (one leg)
    Wallet-->>Customer: did not complete, wallet refunded
  end

Across all flows

The invoice billers and R-Pay read an amount due from a live bill consulted by reference. Assurance reads a priced quote returned for the registered vehicle. Shopping, international recharge and TOD read a fixed price from the catalogue. None of them adds a tax or a fee, the amount confirmed is the amount debited. The wallet debit is the wallet's own leg in every flow. The integration posts one settlement leg of its own only for the invoice billers and for Assurance (one collection account to one biller or insurer settlement account), and R-Pay, Shopping, international recharge and TOD post no settlement leg. Assurance, Shopping, international recharge and TOD deliver a partner-fulfilled item (a policy, a voucher, a top-up) that can fail after the debit, so those four carry a one-to-one reversal on a failed fulfilment, the invoice billers and R-Pay do not.

Reserve before debit, two-step billers. Some invoice billers (and every product flow) need the payment reserved at the aggregator before the wallet debit and confirmed after, while the rest pay directly with no reserve. This is a reserve at the aggregator, not a wallet reserve, and it changes neither the screens the customer walks nor the two calls Comviva makes (consult, then pay). When a reserve is placed but the debit fails, the reservation is released or left to expire and the confirm never fires.

Error handling, the clean outcomes. Success, the bill or product is paid and the receipt is returned. Not found, a consult that returns zero or negative stops with a no-bill message and does not debit. Already paid, detected at consult and surfaced as an already-paid outcome with no retry. Refused or in doubt after the debit, reconciled by external reference, never blindly retried, and the duplicate external reference is rejected as a duplicate (the idempotency guard). Product fulfilment fails after the debit (Assurance, Shopping, recharge, TOD), the wallet debit is returned to the customer as one reversal leg (collection account back to the customer account). The aggregator pushes nothing, so the final status is obtained by pull, the status-by-reference lookup, and a reconciled-after-the-fact result is reflected on the receipt against the same reference.

Notifications and receipt. The receipt shows the payment reference, the biller or product and the reference paid, and the one amount (price equals debited equals settled, no fee line). The payment reference is the same value carried as the external reference on the pay, the settlement posting reference, and the key the status reconciliation searches by, so the customer-visible reference and the reconciliation key are one and the same. On a successful product purchase the receipt carries the voucher code or the policy reference. The aggregator pushes nothing and sends the customer no message, so Comviva owns the receipt on screen and any push or SMS, per the program notification rule. On a failed product fulfilment, after the reversal, the customer is told the purchase did not complete and the wallet was refunded.