FSD-03, Bill Payment, Direct Billers (Al Ibdaa, AFI / Al Karama)¶
Purpose¶
Pay a direct biller from the wallet. Two institutions are in scope, each a leaf the customer selects in the Bills area then enters a reference at. Al Ibdaa, a microfinance institution, where the customer consults a dossier by reference and pays it. AFI and Al Karama, a finance institution, where the customer repays a loan instalment or funds a savings deposit. Both ride the same Comviva contract, keyed by billerCode, two calls, order/bill-details (consult) then order/billpay (pay). The customer consults a reference at the institution, sees the amount due and the holder name, confirms, the wallet is debited once, and the institution records the payment at its own core. There is never a tax or a fee line added on top, the amount confirmed is the amount debited. The two billers differ only in when the institution is called relative to the debit. Al Ibdaa pays once, after the debit. AFI reserves at the institution before the debit and confirms after, so its summary screens carry a loan-or-deposit operation the institution detects at consultation.
Customer flows¶
Two billers, each a select-then-confirm flow. Each flow below is given screen by screen (what the customer enters, what comes back, using the real on-screen labels), with its endpoint, its payloads, and a sequence diagram. The reserve-before-debit nuance of AFI is invisible to the customer, who sees one consult and one confirm in every case. The same two Comviva calls serve both billers, only the billerCode and the reference shape change.
Flow 1, Al Ibdaa (consult then pay)¶
The customer picks Al Ibdaa, types the reference that identifies the dossier, the dossier is consulted, and pays. One operation, no operation picker. No institution call happens before the wallet is debited, the pay fires once after the debit.
billerCode IBDAA.
Screens.
- Reference. The customer types the contract or client reference at Al Ibdaa (for example
IB-100245). On entry the dossier is consulted. - Detail. The summary comes back showing the holder name, the client code, the client account, and the amount due (for example Mohamed Lemine,
IB-100245, account457120, 3500 MRU). The label on this screen is Detail. If the reference is unknown the flow stops with a check-your-reference message and no debit. - The customer confirms, enters the PIN. The wallet is debited once for the amount due, and the dossier is paid at the Al Ibdaa core. The receipt shows the transaction reference and the paid amount.
Consult. POST /v2/order/bill-details. Request, then response (illustrative, Al Ibdaa dossier).
{ "billerCode": "IBDAA", "reference": "IB-100245", "phoneNumber": "+222 32 88 01 87", "language": "fr" }
{ "reference": "IB-100245", "amount": 3500, "customer": "Mohamed Lemine", "details": "dossier" }
Pay. POST /v2/order/billpay. Request, then response.
{ "billerCode": "IBDAA", "reference": "IB-100245", "amount": 3500, "currency": "929", "phoneNumber": "+222 32 88 01 87", "externalReferenceId": "BILL-2026-0031", "paymentDate": "2026-06-20T16:30:33Z" }
{ "status": "success", "orderId": "ORD-2026-0031", "transactionId": "TXN-2026-0031", "message": "Payment completed" }
sequenceDiagram
participant Customer
participant Wallet as Wallet (Mobiquity)
participant BMCI as BMCI (integration)
participant Inst as Al Ibdaa (opaque)
Note over Customer,Inst: consult then pay (no reserve before debit, no BMCI posting)
Customer->>Wallet: pick Al Ibdaa, type Reference (IB-100245)
Wallet->>BMCI: consult (bill-details)
BMCI->>Inst: consult dossier
Inst-->>BMCI: holder, amount due
BMCI-->>Wallet: amount, holder (Detail screen)
Wallet-->>Customer: summary (no fee line), confirm + PIN
Wallet->>Wallet: debit customer (wallet's own leg)
Wallet->>BMCI: debit confirmed
BMCI->>Inst: pay (after debit)
alt institution responds
Inst-->>BMCI: paid, credit recorded at the institution core
BMCI-->>Wallet: paid
Wallet-->>Customer: receipt (reference, amount)
else pay refused after debit
Inst-->>BMCI: refused
Note over Wallet,BMCI: reverse the wallet debit (net-new at cutover)
Wallet-->>Customer: payment did not complete
else no clear response
Note over BMCI,Inst: no blind retry, reconcile by externalReferenceId
end
Flow 2, AFI / Al Karama (reserve before debit)¶
The customer picks AFI, types the client code, and the institution detects at consultation whether the client has a loan to repay or only a deposit account. The summary screen differs by operation, loan or deposit. The institution reserves the payment before the wallet debit and validates it after. The customer still sees one consult and one confirm. The amount field is pre-filled with the amount due and partial payment is allowed (the customer can pay the exact amount or enter a higher or lower one), so the customer can adjust the figure before confirming.
billerCode AFI.
Screens, loan repayment.
- Reference. The customer types the AFI client code (for example
C-4821). On entry the client is consulted and a loan instalment is found. - Al Karama Finance details. The summary comes back showing the client code, the client account, the holder name, and the amount due, with the line "Vous pouvez payer le montant exact ou saisir un montant supérieur ou inférieur." (for example
C-4821, account019920, NBG, 2600 MRU). The label on this screen is Al Karama Finance details. - Montant à Payer. The amount field is shown pre-filled with the amount due, described Paiement partiel possible. The customer keeps or edits the amount.
- The customer confirms, enters the PIN. The payment is reserved at AFI, then the wallet is debited once, then AFI validates the reserved payment. The receipt shows the transaction reference, the client code, the holder name, and the paid amount.
Screens, savings deposit. Same flow, the customer typed a client code that has no loan instalment, so the institution returns the deposit account instead.
- Reference. The customer types the AFI client code (for example
C-7702). On entry the client is consulted and no loan is found, so the deposit account is returned. - Al Karama Finance details. The summary comes back showing the client code, the deposit account, and the holder name, with the line "Vous n'avez pas de prêts. Cependant, vous pouvez faire des dépôts." There is no amount due for a deposit.
- Montant à Déposer. The customer types the amount to deposit (the field is not pre-filled, there is no amount due).
- The customer confirms, enters the PIN. The deposit is reserved at AFI, then the wallet is debited once, then AFI validates the reserved deposit. The receipt shows the transaction reference, the client code, the holder name, and the deposited amount.
Consult. POST /v2/order/bill-details. Request, then response (loan), then response (deposit). The same call serves both, the institution decides loan or deposit and labels it in details.
{ "billerCode": "AFI", "reference": "C-4821", "phoneNumber": "+222 22 32 88 01", "language": "fr" }
{ "reference": "C-4821", "amount": 2600, "customer": "NBG", "details": "loan" }
{ "reference": "C-7702", "amount": 0, "customer": "Sidi Ahmed", "details": "deposit" }
Pay. POST /v2/order/billpay. Request, then response. For a deposit the customer-entered amount is sent (the consult amount was zero), and the operation is selected by what the institution returned at consultation.
{ "billerCode": "AFI", "reference": "C-4821", "amount": 2600, "currency": "929", "phoneNumber": "+222 22 32 88 01", "externalReferenceId": "BILL-2026-0041", "paymentDate": "2026-06-20T16:30:33Z" }
{ "status": "success", "orderId": "ORD-2026-0041", "transactionId": "TXN-2026-0041", "message": "Payment completed" }
sequenceDiagram
participant Customer
participant Wallet as Wallet (Mobiquity)
participant BMCI as BMCI (integration)
participant Inst as AFI / Al Karama (opaque)
Note over Customer,Inst: consult then reserve (pre-debit) then validate (post-debit), no BMCI posting
Customer->>Wallet: pick AFI, type Reference (client code C-4821)
Wallet->>BMCI: consult (bill-details)
BMCI->>Inst: consult client (loan first, deposit fallback)
Inst-->>BMCI: holder, amount due, operation (loan or deposit)
BMCI-->>Wallet: amount, holder, operation (details screen)
Wallet-->>Customer: summary (no fee line), amount field, confirm + PIN
Wallet->>BMCI: pay (billpay)
Note over BMCI,Inst: reserve before the wallet debit
BMCI->>Inst: reserve payment / deposit (pre-debit)
Inst-->>BMCI: reserved, payment id, initiated
Wallet->>Wallet: debit customer (wallet's own leg)
alt debit confirmed
BMCI->>Inst: validate reserved payment (after debit)
Inst-->>BMCI: confirmed, credit recorded at the institution core
BMCI-->>Wallet: paid
Wallet-->>Customer: receipt (reference, amount)
else reserve placed but debit fails
Note over BMCI,Inst: release or expire the reservation, never validate
else validate fails after debit
Note over Wallet,BMCI: reverse the wallet debit (net-new at cutover)
Wallet-->>Customer: payment did not complete
else no clear response after debit
Note over BMCI,Inst: no blind retry, reconcile by externalReferenceId, reverse if unconfirmed
end
Error handling¶
Clean outcomes, mapped from the institution result into the Mobiquity envelope. Business errors arrive inside a successful HTTP envelope with a result code in the body, inspect the code, do not infer success from the HTTP status alone.
- Success. The institution confirms the payment, the receipt is returned with the transaction reference and the paid amount.
- Reference not found. The institution rejects an unknown client code or contract reference at consultation. Reject before any debit, no wallet movement.
- Payment refused. The institution declines the reserve or the pay. The wallet is not debited (Al Ibdaa), or the reserved payment is released and the debit does not proceed (AFI).
- Insufficient balance. Rejected before any debit, the customer is asked to fund the wallet.
- Debit succeeds then the institution side fails. The wallet was debited but the credit at the institution did not complete. Do not re-debit. Re-drive the pay (for AFI, from the reserved payment), and if it cannot be completed, reconcile and reverse on the wallet side.
- Reserve succeeds then debit fails (AFI). The institution holds a reserved, unconfirmed payment that was never funded. It must be released or left to expire, never validated.
- Timeout or no clear response. Do not blindly retry a pay. Re-check by external reference and reconcile. The
externalReferenceIdis the single idempotency and dedup key, a replay with the same value returns the same result without re-paying. There is no reconciliation job inside the connectors today, so the safety net is the platform ambiguous-order engine plus the status-by-reference lookup.
Notifications and receipt¶
The customer is on a screen at confirmation, so the primary receipt is on screen, and the same content is mirrored into the wallet history. The receipt shows the institution and the customer reference paid (the credited institution and the reference that identifies the customer there), the biller payment reference (prominent, the value the institution returns when it confirms the payment, which is the same value as the reconciliation key and the status-lookup key, so the customer-visible reference, the ledger reference, and the reconciliation key are one value), the amount paid and the total debited (equal, since no fee or tax is added on top, so the figure on the receipt matches the wallet movement exactly), the operation (a loan repayment or a savings deposit for AFI, a dossier payment for Al Ibdaa), the status (succeeded, or pending while an in-doubt payment is reconciled then succeeded once resolved), and the timestamp.
Comviva owns the customer-facing notification driven off the final status it obtains (synchronously on the pay, or by the status-by-reference reconciliation). On a success Comviva decides per the program notification rule whether a push (if enabled) or an SMS fallback is also sent. On a refused or failed payment, and after any wallet reversal, the customer is told on screen that the payment did not complete. The institution sends the customer nothing, so the receipt and any push or SMS are Comviva's, the same as the other bill-pay channels.