Building an E-Commerce Checkout for Tanzania: M-Pesa, Tigo Pesa, and Airtel Money
A Tanzanian e-commerce checkout collects items in a cart, presents an order summary with a TZS total, asks for the customer's mobile money phone number, sends a payment request to an aggregator (or directly to Vodacom, Tigo, or Airtel), waits for the customer to confirm on their phone, receives a callback with the result, and updates the order status. The key differences from a card-based checkout: the payment is asynchronous (you wait for a callback instead of getting an instant response), you need a "waiting for confirmation" state in your UI, and you must handle timeouts and retries. Use an aggregator like Selcom or Azampay to support all three rails through one API.
Why a Mobile Money Checkout Is Not a Card Checkout
If you have built a checkout with Stripe or PayPal, you are used to synchronous payments: the customer enters their card details, you send the request, and you get a success or failure response within seconds. The customer never leaves your page.
Mobile money does not work this way. The flow involves the customer's phone:
- The customer enters their phone number on your checkout page.
- Your server sends a payment request to the mobile money provider.
- The provider pushes a prompt to the customer's phone.
- The customer picks up their phone, reads the prompt, and enters their PIN.
- The provider processes the payment and sends a callback to your server.
Steps 3 through 5 happen outside your application. You have no control over how long the customer takes to check their phone. They might be in the other room. They might need to find their phone. They might be in an area with poor network coverage. The typical wait is 10 to 60 seconds, but it can be longer.
Your checkout must handle this waiting period. You cannot show a blank page or a spinning wheel for 60 seconds without explanation. You need a clear "waiting for confirmation" state that tells the customer what is happening and what they need to do.
The Full Checkout Architecture
Here is the end-to-end architecture for a Tanzanian e-commerce checkout:
Frontend
- Cart page: Standard cart with items, quantities, and a TZS total. Nothing special here.
- Checkout page: Order summary, delivery details (if applicable), and a phone number input. Detect the provider from the number prefix and show the relevant logo (Vodacom, Tigo, or Airtel).
- Waiting page: After the customer clicks "Pay," show a clear message: "A payment prompt has been sent to your phone. Please enter your PIN to confirm." Include a visual indicator (pulsing animation, countdown, or progress bar). Poll your backend for the transaction status every 2 to 3 seconds.
- Confirmation page: On success, show the order details, a transaction reference, and next steps. On failure, show the reason and a retry option.
Backend
- Order creation endpoint: Creates an order in your database with status "pending_payment." Returns an order ID.
- Payment initiation endpoint: Sends the payment request to the aggregator (or telco API). Associates the payment with the order. Returns a transaction reference to the frontend.
- Callback endpoint: Receives the payment result from the aggregator. Updates the order status. Triggers post-payment actions (send confirmation, update inventory, notify fulfillment).
- Status check endpoint: Returns the current order/payment status for frontend polling.
Database
- Orders table: Order ID, customer details, items, total (TZS), status, timestamps.
- Transactions table: Transaction ID, order ID, phone number, amount, provider, status, aggregator reference, raw callback payload, timestamps.
Order States and Edge Cases
A mobile money e-commerce order has more states than a card-based order. Here are the states you need to handle:
- Cart: Items added, no order created yet.
- Pending payment: Order created, payment not yet initiated.
- Awaiting confirmation: Payment request sent to the telco. Waiting for the customer to confirm on their phone.
- Payment received: Callback received, payment successful. Order is confirmed.
- Payment failed: Callback received, payment declined (insufficient funds, wrong PIN, etc.).
- Payment timed out: Customer did not respond within the timeout window (typically 60 to 90 seconds).
- Fulfilled: Order shipped or delivered.
Edge cases to handle:
- Customer closes the browser. The payment request is already sent. If the customer confirms on their phone, the callback still arrives. Your system should process it correctly even if the customer is not watching the checkout page. Send a confirmation SMS or email.
- Duplicate callbacks. The aggregator may send the same callback twice. Your handler must be idempotent: processing the same callback twice should not create duplicate orders or charge the customer twice.
- Partial timeout. The payment request times out, but the customer confirmed just before the timeout. The callback may arrive slightly late. Do not mark the order as failed if a success callback arrives shortly after the timeout.
- Customer retries. If the first attempt fails or times out, the customer should be able to retry without creating a new order. Your system should allow re-initiating payment for an existing order.
Handling Multiple Providers in One Checkout
Your checkout must work with M-Pesa, Tigo Pesa, and Airtel Money. Here is how to handle the multi-provider aspect:
If using an aggregator: The aggregator handles provider routing. You send the phone number and amount. The aggregator detects whether it is a Vodacom, Tigo, or Airtel number and routes the request accordingly. You receive a normalized callback regardless of provider. This is the simplest path.
If using direct integration: You need to detect the provider from the phone number prefix and route the request to the correct API. Maintain separate configuration (credentials, endpoints) for each provider. Normalize the callback data from all three into a common format before processing.
Phone number prefix detection for Tanzania:
- Vodacom: 074x, 075x, 076x
- Tigo: 065x, 067x, 071x
- Airtel: 068x, 069x, 078x
Note: number portability could make prefix detection unreliable in the future. If a customer says they are on Airtel but their number prefix suggests Vodacom, trust the customer. Some checkouts add a provider selector (three buttons with provider logos) in addition to the phone number field, as a fallback.
Whichever approach you take, show the customer which provider was detected. Seeing the Vodacom, Tigo, or Airtel logo next to their phone number builds confidence that the checkout supports their wallet.
Inventory Management and Payment Timing
The async nature of mobile money payments creates an inventory problem that card-based checkouts rarely face: what do you do with the inventory during the 10 to 60 seconds between initiating payment and receiving confirmation?
Two approaches:
Optimistic: Reserve inventory on payment initiation. When the customer clicks "Pay," temporarily reserve the items. If payment succeeds, confirm the reservation. If it fails or times out, release the items. This prevents selling the same item to two customers simultaneously but ties up inventory during the confirmation window.
Pessimistic: Reserve inventory on payment confirmation. Do not reserve anything until the callback confirms payment. This means two customers could pay for the same last-in-stock item. The second one gets a refund and an apology. This is simpler to build but creates a worse customer experience.
For most Tanzanian e-commerce stores, the optimistic approach works better. The confirmation window is short (under 90 seconds), and the risk of two customers buying the same item in that window is low unless you sell high-demand, limited-stock products.
Either way, set a timeout on the reservation. If the payment does not confirm within 90 seconds, release the inventory and mark the order as timed out. Allow the customer to retry.
Building the Skills to Build This
A Tanzanian e-commerce checkout combines two skill sets: full-stack web development (building the store, cart, and checkout UI) and mobile money integration (handling payments, callbacks, and transaction management).
McTaba teaches both:
- M-Pesa Integration for Developers (KES 9,999 / ~TZS 200,000): The payment-specific skills. Request-callback architecture, webhook handling, checkout flow, error management. Uses Daraja for the sandbox, but the architecture applies to any Tanzanian aggregator.
- Full-Stack Software + AI Engineering (KES 120,000 / ~TZS 2,400,000): The full-stack skills. React for the frontend (cart, checkout, order pages), Node.js for the backend (APIs, order management, callback handling), databases (storing orders and transactions), authentication, and deployment.
- Deployment: Going Live (KES 4,999 / ~TZS 100,000): Getting your store from localhost to a live, production URL. Domain setup, SSL, hosting, and keeping it running.
The M-Pesa Integration course is the starting point if you already have full-stack skills. The Full-Stack course is the starting point if you are building those skills from scratch. Both together give you everything you need to build a production e-commerce store for the Tanzanian market.
Key Takeaways
- ✓A Tanzanian e-commerce checkout is fundamentally async. Unlike card payments that resolve in seconds, mobile money payments wait for the customer to confirm on their phone. Your checkout must handle this waiting period gracefully.
- ✓Support all three rails from launch. A checkout that only accepts one provider loses transactions from the other two. Use an aggregator to cover M-Pesa, Tigo Pesa, and Airtel Money through one API.
- ✓The order lifecycle has more states than a card-based system: cart, pending payment, awaiting confirmation, payment received, payment failed, payment timed out. Design your database and UI for all of them.
- ✓McTaba teaches the full checkout architecture in the M-Pesa Integration course (KES 9,999 / ~TZS 200,000) and the full-stack skills to build the store in the Full-Stack course (KES 120,000 / ~TZS 2,400,000).
Frequently Asked Questions
- Can I use Stripe or PayPal for e-commerce in Tanzania?
- Stripe and PayPal support card payments but not mobile money. In Tanzania, the majority of digital payments happen through mobile money, not cards. An e-commerce store that only supports Stripe or PayPal will miss most of its potential customers. You need mobile money support (M-Pesa, Tigo Pesa, Airtel Money) as the primary payment method, with card payments as an optional extra for the small percentage of customers who use Visa or Mastercard.
- How do I handle refunds with mobile money?
- Mobile money refunds are sent as B2C (business to customer) disbursements. You use the B2C API of your aggregator or telco to send money back to the customer's phone number. This is a separate API call from the original payment. Build a refund workflow in your admin panel that tracks the refund status independently from the order status.
- What if the customer enters the wrong phone number?
- If the number is valid but belongs to someone else, that person receives the payment prompt. They will likely decline it (they did not initiate a purchase). The payment fails, and your customer can retry with the correct number. To reduce this risk, validate the phone number format before submitting and ask the customer to double-check their number.
Ready to build real-world apps?
Join the McTaba Labs full-stack marathon (4 months full-time · 6 months part-time). Learn M-Pesa, USSD, and WhatsApp engineering while shipping 8 production apps.
Apply to the McTaba Marathon