Adding M-Pesa to a WordPress site is not finished when a customer receives an STK prompt. A production payment flow must connect the prompt to the correct order, receive the provider's final result, update the order once, keep a useful audit trail and give staff a safe way to handle delayed or failed payments.
If you are choosing an M-Pesa integration, the common search phrase mpesa payment plugin for WordPress is a useful starting point, but evaluate the whole transaction lifecycle. The gateway screen is the visible part. Reliability depends on credentials, secure callbacks, order-state rules, duplicate protection, hosting and reconciliation.
This guide explains the decisions and tests a Kenyan store or service business should complete before accepting live payments. Provider onboarding and credentials change over time, so confirm the current requirements in the provider portal and the plugin documentation.
Decide what the payment must do
Start with the selling workflow. A WooCommerce store normally needs the gateway to collect the exact order total and update the order after confirmed payment. A consultant may need a fixed booking-fee form. A school or property manager may need a reference field that links payment to a student, tenant or invoice. A digital-download site may need access released only after confirmed payment.
Write down these details before installing anything:
What is being paid for: products, services, deposits, invoices, fees or donations?
Is the amount fixed by the server, calculated from a cart, or entered by the customer?
Which reference must appear in the payment and reconciliation report?
When should stock, email, fulfilment or a download be released?
Can a customer pay partly, retry, or pay an order that is already complete?
Who handles refunds, reversals and unmatched payments?
For a WooCommerce store, the amount should come from the server-side order, not a value sent by the browser that a visitor can edit. For a custom form, validate the amount and reference on the server before initiating payment.
Choose the provider and settlement path
An M-Pesa plugin may connect directly to Safaricom Daraja or through another approved provider or bank integration. The best route depends on where the business wants funds to settle and which merchant relationship it already has.
Mocky Digital's current M-Pesa WordPress plugin supports Safaricom Daraja, Kopo Kopo, KCB Buni and Equity Jenga. According to the live product page checked on 27 September 2026, Daraja is intended for merchants using their own Lipa na M-Pesa paybill or till; Kopo Kopo settles through its merchant account; KCB Buni and Equity Jenga provide bank-linked options. Confirm current onboarding, settlement and transaction charges directly with the selected provider.
Do not choose only from the number of logos on a sales page. Ask:
1. Where does the money settle? 2. Which business account and KYC approval are required? 3. Does the provider support sandbox testing? 4. Which callback or webhook must be publicly reachable? 5. What identifies the payment in provider reports? 6. How are reversals and support cases handled? 7. Which costs come from the plugin, provider and merchant account separately?
Prepare WordPress and WooCommerce first
Payment reliability begins with the hosting environment. WordPress currently recommends PHP 8.3 or greater, MariaDB 10.11 or MySQL 8.0 or greater, and HTTPS. WooCommerce's current recommendations include WordPress 6.9 or greater, PHP 8.3 or greater, MySQL 8.0 or MariaDB 10.6 or greater, HTTPS and a WordPress memory limit of at least 256 MB. Check the current official requirements for the versions you run.
Before adding the gateway:
Update WordPress, WooCommerce, the theme and plugins on a staging copy.
Make a tested backup of files and the database.
Confirm the site uses HTTPS on checkout and callback URLs.
Check WooCommerce > Status for outdated templates, memory problems and failed scheduled actions.
Make sure the site can receive external HTTPS requests without a maintenance page or basic-auth prompt.
Review security or firewall rules that might block provider callbacks.
Confirm WordPress cron or a real server cron runs reliably if the plugin uses scheduled status checks.
Avoid installing a payment plugin for the first time directly on a busy production checkout. A staging test catches theme conflicts and configuration errors, but final provider callbacks may still require a public test environment.
Install and configure the gateway safely
Install the plugin from a trusted source and verify the version. In WordPress, upload the ZIP or use the documented installation route, activate it, then open its payment settings. Enable only the provider you plan to test.
Credentials such as consumer keys, secrets, passkeys and private keys are sensitive. Restrict administrator access, use unique accounts and avoid sending credentials through ordinary chat or email. Do not paste production secrets into screenshots, tickets or staging sites. If a credential is exposed, rotate it in the provider portal.
Copy the callback URL exactly as the plugin displays it. It must use the public HTTPS domain and must not redirect through a login page. If the provider requires callback registration, complete that step in the official portal. Keep sandbox and production credentials clearly separated. A common failure is switching the plugin to live mode while leaving a sandbox shortcode, key or callback registration in place.
For WooCommerce, enable the gateway, set a clear customer-facing title such as "M-Pesa", and decide which shipping, currency or order conditions should allow it. Place a low-value test order before announcing the option.
Understand the STK Push transaction lifecycle
A robust checkout treats payment as an asynchronous process:
1. The customer submits a Kenyan mobile number. 2. The server validates the order, amount and reference. 3. The plugin sends the payment request to the configured provider. 4. The customer receives the STK prompt and enters the M-Pesa PIN on the phone. 5. The provider processes the request and sends a final callback or status result. 6. The plugin matches that result to the saved transaction. 7. The order moves to the appropriate paid state once, and fulfilment begins.
The first API response is not necessarily proof of payment. It may only confirm that the request was accepted for processing. The final provider result and recorded receipt are what should drive the paid order state.
The plugin should handle common outcomes explicitly: customer cancellation, timeout, insufficient funds, invalid number, provider error and a successful payment whose callback arrives late. The customer needs a calm status message and a safe retry path. Staff need enough detail to reconcile the event without seeing secrets.
Prevent duplicate orders and false paid states
Retries are normal on mobile payments. They become dangerous when every button press creates a new order or every callback repeats fulfilment. Look for these controls:
A stable order and transaction reference.
Duplicate-request protection during a short pending window.
Idempotent callback handling, so the same success result can be processed more than once without shipping twice.
A unique provider request or receipt identifier stored with the order.
Server-side amount checks before marking an order paid.
An order note or transaction log showing important status changes.
Never mark the order paid simply because the browser shows a success page. The browser can close, refresh or be manipulated. Payment confirmation belongs on the server, based on the provider result and a matching stored transaction.
Test more than one successful payment
A single happy-path test does not prove the gateway is ready. Run a documented test matrix:
Core tests
Successful payment from checkout to paid order.
Customer cancels the STK prompt.
Prompt expires or the customer does not respond.
Insufficient funds or another provider rejection.
Invalid and differently formatted Kenyan phone numbers.
Double-clicking the pay button or refreshing while pending.
Callback delivered twice.
Callback delayed until after the browser stops polling.
Amount or reference mismatch.
Payment received while the site is under normal caching and firewall rules.
WooCommerce tests
Physical product with shipping.
Virtual or downloadable product.
Coupon and tax calculations.
Out-of-stock product and stock reduction after payment.
Failed payment followed by a successful retry.
Customer and administrator email notifications.
Mobile checkout on a common Android device and network.
Record the order ID, transaction reference, provider request ID, M-Pesa receipt and final order status for each successful test. Then compare the WordPress record with the provider report.
Reconciliation and daily operations
The store team needs a daily answer to three questions: which orders are paid, which provider receipts were received, and which payments do not match an order? Exportable transaction records make that practical.
Define who reviews pending transactions, how long they wait before checking provider status, and what evidence is required before manually changing an order. Manual "mark paid" access should be restricted and logged. Never ask a customer to share an M-Pesa PIN. If support needs proof, request the receipt code and verify it through the business's approved records.
Back up the WordPress database because payment and order records live there. Retain records according to the business's accounting, tax and privacy obligations. Store only the customer data needed for the transaction and support process.
Custom payment forms outside WooCommerce
A business that does not need a product catalogue can use a payment form on a WordPress page. Mocky's plugin provides a shortcode for fixed server-stored amounts and references, which can suit consultations, bookings, invoices and one-off fees.
For example, a payment page can carry a fixed amount and invoice reference while asking the customer for the phone number. The amount must remain controlled by the server. If customers may enter an amount, set sensible minimums and maximums, validate it server-side and describe what the payment covers.
Use a unique business reference rather than a generic label such as "payment". A useful reference helps staff match the provider receipt to the client, invoice or booking without searching by phone number.
Frequently asked questions
Do I need WooCommerce to accept M-Pesa on WordPress?
No. WooCommerce is appropriate for carts, products and orders. A shortcode or custom payment form can handle a service fee, invoice, booking or donation without a full store, provided the plugin supports that workflow.
Can M-Pesa payments settle directly to my business account?
It depends on the provider. Daraja commonly works with the merchant's paybill or till, while bank-linked providers may settle to the corresponding bank account. Confirm the current settlement arrangement and fees before onboarding.
Why does STK Push work in testing but fail on the live site?
Common causes include mixed sandbox and production credentials, an unregistered or blocked callback URL, HTTPS problems, incorrect merchant details, firewall rules and production approval that is not complete. Review provider logs and the plugin transaction log without exposing secrets.
Should an order be marked paid when the STK prompt is sent?
No. Sending the prompt means the payment was initiated. Mark the order paid only after a matching successful provider result is recorded.
What happens if the callback is delayed?
The transaction should remain pending while the plugin waits or checks status safely. A delayed success must still match the original order and should not create duplicate fulfilment. Staff need an exception process for transactions that remain unresolved.
Launch with a payment runbook
A good M-Pesa checkout is more than a button. It is a controlled sequence from order creation to provider confirmation, order update and reconciliation. Choose the settlement route first, prepare WordPress, protect credentials, test failure cases and give staff a clear support process.
Review the current M-Pesa payment plugin for WordPress, compare it with a complete WooCommerce store build, or request setup help for provider onboarding, testing and launch.