All guides

Payments & M-Pesa

Which tenders settle instantly, how the M-Pesa STK push flow works end to end, configuring credentials, split payments and custom tenders.

10 min readOwnerManagerCashier

The payment methods

MethodWhen it settles
CashImmediately at the till
CardImmediately at the till
VisaImmediately at the till
Debit CardImmediately at the till
Credit NoteImmediately at the till
M-PesaWhen the customer approves the prompt on their phone
Custom tendersImmediately, into the bucket you mapped them to
Which tender to reach foryesnosomething elseHow is the customerpaying?CashSettles at the tillCard, Visa, DebitRecorded here, processed onyour terminalM-PesaWaits for confirmationMore than one method?Use split payment linesMust add up to the totalexactlyVoucher, wallet, houseaccount?Add it as a custom tenderCounts toward itsreconciliation bucketat close

Everything except M-Pesa settles the moment you place the order. Custom tenders settle immediately too, into whichever bucket you mapped them to.

Read this diagram as text
  • How is the customer paying? Cash
  • How is the customer paying? Card, Visa, Debit
  • How is the customer paying? M-Pesa
  • Cash More than one method?
  • Card, Visa, Debit More than one method?
  • M-Pesa More than one method?
  • More than one method? Use split payment lines (yes)
  • Use split payment lines Counts toward its reconciliation bucket at close
  • More than one method? Counts toward its reconciliation bucket at close (no)
  • How is the customer paying? Voucher, wallet, house account? (something else)
  • Voucher, wallet, house account? Counts toward its reconciliation bucket at close

Card tenders are recorded, not processed — Wezo books the sale against the tender you chose while the card terminal handles the money. M-Pesa is different: Wezo actually initiates the request and waits for confirmation.

The M-Pesa flow, step by step

The M-Pesa round trip, including every way it failsnoyesnoretryyesPlace the order asM-PesaBranch has M-Pesaconfigured and enabled?STK push sent to thecustomer's phoneOrder saved, push notstartedYou are told why — takeanother tenderOrder sits as pendingDo not release goods yetCustomer approves onthe handset?Safaricom confirms toWezoAuthenticated callbackDeclined or timed outPayment status: failedOrder marked paidReceipt number stored onthe transactionLoyalty points awarded

Only Safaricom's authenticated confirmation can settle the order. Nothing the cashier does at the till can mark an M-Pesa sale paid.

Read this diagram as text
  • Place the order as M-Pesa Branch has M-Pesa configured and enabled?
  • Branch has M-Pesa configured and enabled? Order saved, push not started (no)
  • Branch has M-Pesa configured and enabled? STK push sent to the customer's phone (yes)
  • STK push sent to the customer's phone Order sits as pending
  • Order sits as pending Customer approves on the handset?
  • Customer approves on the handset? Declined or timed out (no)
  • Declined or timed out Order sits as pending (retry)
  • Customer approves on the handset? Safaricom confirms to Wezo (yes)
  • Safaricom confirms to Wezo Order marked paid
  • Order marked paid Loyalty points awarded

At the till

  1. Make sure the customer's phone number is captured on the order.

    The prompt goes to that number, so a typo means nobody gets a prompt.

  2. Select M-Pesa as the payment method and place the order.

  3. Ask the customer to check their phone and approve.

    The order shows as pending until confirmation arrives. Do not hand over goods on the assumption it worked.

  4. Confirm the order shows as paid.

    Open the order to see its transactions table with receipt number, amount and status.

Only a verified callback can mark an order paid

Nothing at the till can mark an M-Pesa order paid by itself. The order settles only when Safaricom's authenticated confirmation reaches Wezo — which is what stops an unpaid order from being closed out as paid.

When it does not go through

  • The push could not be started: the order is still saved and you are told why on screen. Take another tender or retry.
  • The customer cancels or lets it time out: the order stays unpaid. Ask them to try again or pay another way.
  • Payment failed: the order's payment status is marked failed and the balance stands. Do not release goods.

Configure M-Pesa for a branch

Organization → Branch → Settings → Payments

  1. Open the branch's settings page and find the Payments section.

  2. Add the M-Pesa provider and enter the credentials from your Safaricom Daraja account.

  3. Save. The provider shows as configured.

    Credentials are encrypted before they are stored and are never returned to the browser or written to logs.

  4. Run a test payment against your own phone number.

    This proves the credentials, the callback URL and the whole round trip before a customer is standing in front of you.

Credentials are per branch

Each branch holds its own M-Pesa configuration, so a location with its own till number is not forced to share another's. A branch with no configured provider cannot send a push — the till tells the cashier immediately rather than failing quietly.

Split payments

  1. In the cart summary, click Add under Split Payment.

    The new line is pre-filled with whatever is still outstanding.

  2. Choose the method and adjust the amount.

  3. Add more lines until Remaining to pay reaches zero.

    While a shortfall remains it shows in red and Place Order stays disabled.

  4. Place the order.

The split-payment gatenoyesyesnoAdd tender linesDo the lines cover thetotal?Do they exceed thetotal?Remaining to pay shownin redPlace Order stays disabledReduce a linePlace Order

Checked in the browser and again on the server: too little is a shortfall, too much is rejected rather than recorded as change.

Read this diagram as text
  • Add tender lines Do the lines cover the total?
  • Do the lines cover the total? Remaining to pay shown in red (no)
  • Remaining to pay shown in red Add tender lines
  • Do the lines cover the total? Do they exceed the total? (yes)
  • Do they exceed the total? Reduce a line (yes)
  • Reduce a line Add tender lines
  • Do they exceed the total? Place Order (no)

The tenders must equal the total

Split payments are checked twice — in the browser and again on the server. Too little is rejected as not covering the total; too much is rejected outright rather than being recorded as an overpayment.

Custom tenders

Dashboard → Settings → Custom payment tenders

A custom tender is any manual way you accept money that is not in the built-in list — a gift voucher, a staff account, another mobile wallet. Each one is mapped to a reconciliation bucket so end-of-day counting still balances.

  1. Open Dashboard → Settings and find Custom payment tenders.

  2. Enter a tender name such as Voucher or Airtel Money.

  3. Map it to a reconciliation bucket: cash, card, M-Pesa or other.

    That is the column its takings land in at reconciliation time.

  4. Enable it.

    Only enabled tenders appear in the POS payment list. Disable one to retire it without losing history.

Payment safety rules

  • Totals are recomputed on the server from the catalog; a terminal cannot dictate what is charged.
  • Provider credentials are encrypted at rest and never sent to the browser.
  • Only an authenticated provider callback can settle an M-Pesa order.
  • Refunds require a paid order, the right permission, and are recorded in the audit log.
  • Payment references and receipt numbers are stored per transaction, so any figure can be traced back to a specific payment.