Step-by-step plan for your M-Pesa integration

Work through these steps in order. Each one affects the next, so settle the route and the flows before you build the checkout. For product details, see the M-Pesa payment gateway page.

  1. 1. Decide your connection route

    The API (H2H) lets your own backend create payment requests and control the checkout screens. The Hosted Payment Page sends the customer to a payment page that the gateway hosts, which reduces the amount you build yourself. These are two ways into the same gateway, not separate products. H2H is not white-label.

  2. 2. Confirm which flows you need

    A pay-in is when your customer pays you. A payout is when your business pays a customer, and it is available where confirmed for your account. A merchant settlement is when collected funds are sent to you. Plan each flow on its own, with its own records and its own checks.

  3. 3. Plan the checkout

    Decide where the customer enters their phone number, what they see while the payment is in progress, and what happens if they close the page. In Safaricom's Daraja documentation, M-PESA Express (Lipa na M-PESA Online) is the prompt-style request a business starts on the customer's phone. The market often calls it 'STK Push'. PayBill and Till are separate transaction types.

  4. 4. Define your order states

    Give every order a clear status, such as pending, paid, failed or needs review. Only move an order to paid when your server has confirmed the transaction status. Store a unique reference for each payment so you can match it later.

  5. 5. Build your postback handler

    Set up a server endpoint that receives transaction status from the gateway, verifies it and updates the matching order. Make it safe to run twice for the same transaction, because a status can arrive more than once.

  6. 6. Test failure cases, not only success

    Test what happens when a customer cancels the prompt, enters the wrong PIN, lets the request time out or closes the browser. Each case should leave the order in a correct, visible state for your team.

  7. 7. Plan settlement reconciliation

    Merchant settlements are sent on the same day (T+0). This describes when settlement is sent, not when funds are credited to your account. Match each settlement to the paid orders it covers, and investigate any gap before it builds up.

  8. 8. Prepare for go-live

    Keep API credentials on your server only and limit who on your team can see them. Decide who handles payment queries from customers. When you are ready, start your application and our team will confirm the setup for your account.

How postbacks confirm an M-Pesa payment

A postback is a server-to-server message that sends transaction status to you, the merchant. Your server receives it, checks it and updates the order. It is not a customer notification service, so any email or SMS to the customer is your own system's job.

The handler below shows the logic in plain terms. Field names and verification steps are placeholders. Use the names and methods in the integration documentation provided for your account.

Illustrative flow: postback handler (conceptual)
// Illustrative flow: conceptual only, not the actual API

on POST /payments/postback:
  payload = read_request_body()

  if not verify_source(payload):
    return 401            // reject unverified requests

  order = find_order(payload.merchant_reference)
  if order is null:
    log_for_review(payload)
    return 200

  if order.status is final:
    return 200            // duplicate postback, already handled

  if payload.status == "success" and payload.amount_kes == order.amount_kes:
    mark_paid(order)
    release_goods(order)
  else if payload.status == "failed":
    mark_failed(order)
  else:
    keep_pending(order)   // wait for a final status

  return 200

Illustrative flow. This is pseudo-code to explain the logic, not a working integration. Field names, status values and the verification method are placeholders. Follow the documentation supplied for your account.

Note three habits in this flow. It rejects anything it cannot verify, it checks the amount in KES against the order, and it ignores repeats once an order is final.

Decisions to make before you build

Key decisions for accepting M-Pesa on a website
DecisionOptionsWhat to consider
Connection routeAPI (H2H) or Hosted Payment PageAPI gives more control over screens but needs more development. The Hosted Payment Page means less to build. Both use the same gateway.
Money flowsPay-ins only, or pay-ins plus payoutsPayouts are available where confirmed for your account. Keep pay-ins, payouts and settlements in separate records.
Source of payment statusPostback to your serverOnly mark orders as paid after a verified postback. Do not rely on the browser redirect.
Order statesPending, paid, failed, needs reviewEvery order should end in a clear state, including when the customer leaves mid-payment.
Customer messagesYour own email or SMS systemPostbacks go to the merchant, not the customer. Decide what you send and when.
ReconciliationDaily matching of settlements to ordersMerchant settlements are sent on the same day (T+0). Check for unmatched payments and missing orders.
Team accessWho can see credentials and payment dataLimit access to the people who need it and keep credentials off the front end.

Pricing is set per merchant. See pricing or talk to sales for a quote based on your setup.

Why the redirect is not proof of payment

Use the return page to show a 'checking your payment' message and read the order status from your own database. If the status is still pending, tell the customer you will confirm shortly rather than showing success.

Frequently asked questions

What is the difference between the API (H2H) and the Hosted Payment Page?

With the API (H2H), your backend creates payment requests and you control the checkout screens. With the Hosted Payment Page, the customer completes payment on a page hosted by the gateway. Both are routes into the same gateway, and H2H is not white-label.

Can I mark an order as paid when the customer returns to my site?

No. The redirect only shows that the customer's browser came back. Mark an order as paid only after your server has received and verified the transaction status in a postback.

Will the postback notify my customer?

No. Postbacks send transaction status to you, the merchant. If you want to email or text the customer, send that from your own system after your server confirms the payment.

When are merchant settlements sent?

Merchant settlements are sent on the same day (T+0). This refers to when settlement is sent, not when funds are credited to your account. Reconcile each settlement against your paid orders.

Which payment methods can I accept in Kenya?

In Kenya, the gateway supports M-Pesa. It covers M-Pesa pay-ins, plus payouts where confirmed for your account. Ask our team if you have questions about your specific setup.

Is STK Push the same as M-PESA Express?

In Safaricom's Daraja documentation, M-PESA Express (Lipa na M-PESA Online) is the prompt-style payment request started by a business. 'STK Push' is the market term commonly used for it. PayBill and Till are separate transaction types.

Can I use this with a Shopify store?

When checked on 5 November 2026, Kenya was not on Shopify's official Shopify Payments country list. We do not promise any app, plugin or automatic install for Shopify. Ask our team to discuss your store.

How much does it cost?

Pricing is custom. Talk to sales for a quote based on your business and setup.

Accepting M-Pesa on a website: next step