Skip to main content

Payment Flow

A complete walkthrough of how a payment moves through the Cashless system.

Overview​

Step by step​

1. Create a bill​

Your server sends a POST request to create a bill with the amount and a reference (your order ID).

const bill = await api.issue(
new cashless.BillParams('0712345678', 15000, 'ORDER-042')
);

The response includes:

  • id -- Unique bill UUID for tracking
  • webPayUrl -- URL to the hosted payment page
  • status -- Initially NOT_PAID

2. Customer pays​

If you included a mobile number: The customer receives a USSD push on their phone. They see the merchant name and amount, and enter their mobile money PIN to confirm.

If no mobile number: Redirect the customer to webPayUrl. On the payment page, they enter their mobile number, triggering the USSD push.

3. Confirm payment​

Once the customer confirms, the bill status changes to FULLY_PAID. Detect this via:

  • Polling -- Call GET /api/v3/bills/\{id\} every few seconds
  • Webhooks -- Receive a POST to your configured webhook URL

4. Fulfill the order​

When status is FULLY_PAID, the payment is complete. Update your order status and deliver the goods or service.

Status transitions​

NOT_PAID ──────────────────► FULLY_PAID
│ ▲
│ │
└──► PARTIALLY_PAID ─────────┘
  • NOT_PAID -- No payment received
  • PARTIALLY_PAID -- Customer paid less than the full amount (rare, may happen with partial mobile money balances)
  • FULLY_PAID -- Full payment received

Mobile number formats​

The API accepts Tanzanian mobile numbers in national format:

FormatExampleValid
National0712345678Yes
With country code255712345678Yes
International+255712345678Yes

Supported mobile money providers​

  • M-Pesa (Vodacom)
  • Tigo Pesa (Tigo)
  • Airtel Money (Airtel)