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)