WooCommerce has no native M-Pesa, and that is the whole problem
WooCommerce ships with support for direct bank transfer, cheque, cash on delivery and PayPal. None of those describe how most Kenyan shoppers actually pay for things online. M-Pesa has to arrive through a third-party gateway, which means the quality of your checkout depends entirely on which route you pick.
That decision matters more than it looks. A payment method is not just a way for money to arrive. It is the signal that tells WooCommerce an order is real, which in turn releases stock, sends the processing email, triggers your fulfilment integration and makes your reports true. If the payment lands somewhere WooCommerce cannot see, none of that happens.
The three ways Kenyan stores do it today
The first is manual: put a paybill or till number on the checkout page, ask the buyer to send the money and paste the confirmation code into the order notes. It costs nothing to set up and it works, right up to the point where someone in your team is matching M-Pesa SMS messages against orders at eleven at night, trying to work out which of two customers sent 2,400 shillings.
The second is a hosted gateway or aggregator plugin. The buyer is sent to a page that triggers the payment, and a callback tells your store the outcome. This is the shape you want. The variation between providers is in the parts you cannot see from the marketing page: whether the callback is signed, whether a retry can charge twice, whether refunds work at all.
The third is a direct integration against Safaricom Daraja, which some larger merchants build themselves. It gives you the most control and it is also a real engineering project: credential rotation, callback endpoints that must stay reachable, timeout and reversal handling, and a reconciliation job you now own. It is a reasonable choice if you have a payments engineer. It is a bad first choice if you do not.
What properly integrated actually means
Four things separate a payment integration you can trust from one that will quietly cost you money. They are worth checking before you install anything, whichever provider you choose.
Orders are marked paid by a server-to-server callback, not by the buyer arriving back on your site. Anyone can type your order-received URL. Only a signed webhook proves a payment happened. Any integration that flips an order to Processing on the return redirect alone is a way to get free goods.
The callback is signed and replay-protected. That means a shared-secret signature you verify over the raw request body, a timestamp so an old delivery can be rejected, and a unique event id so a retried delivery cannot mark the same order paid twice. Retries are normal and expected; double fulfilment is not.
Repeat requests cannot double-charge. A shopper double-clicking Pay, or a network timeout followed by a retry, must not create two payments. This is what idempotency keys are for: the second request with the same key replays the first response instead of taking money again.
Refunds exist in the admin. If refunding means emailing support or sending money back manually from your own phone, you do not have a payment integration, you have a payment notification.
Setting it up with E-Sarif Checkout
The E-Sarif WooCommerce plugin follows the second pattern above. You install it, activate it under WooCommerce, Settings, Payments, and paste two keys: a secret key that stays on your server and a publishable key that is safe in the browser. Sessions are created server-side, so your secret key never appears in the page a shopper loads.
Two settings deserve real thought rather than a default. The first is the payment methods you offer, since the plugin can present M-Pesa, stablecoins in USDT or USDC, or both. The second is the settlement currency, which decides what you actually receive: a USDT balance, or shillings paid back out over M-Pesa. It defaults to USDT, which is not what you want if you were expecting shillings.
Then register the webhook URL the plugin shows you in your merchant portal, and place a test order using test keys. A test payment confirms after a few seconds without a real prompt going to anyone, so you can watch the order move to Processing before real money is involved.
Five mistakes that cost stores their first live weekend
Skipping the webhook registration. The plugin will happily create sessions and take payments, and your orders will sit in Pending forever, because nothing is telling WooCommerce they were paid.
A security plugin or CDN rule blocking the callback. This is the single most common failure, and it is invisible: the payment succeeds, the delivery is refused at your edge, and you find out from a customer. Confirm one webhook arrives before you announce the new method.
Leaving the settlement currency on its default. Check it deliberately, and check it before your first busy day rather than during it.
Never testing a cancelled payment. You need to know what a shopper sees when they change their mind at the prompt, because a confusing failure state turns a recoverable sale into a support ticket.
Assuming renewals will charge themselves. M-Pesa and stablecoin payments both require the buyer to approve the payment, so there is no stored instrument to charge later. If you sell subscriptions, plan on reminder emails with a payment link, and keep a card gateway alongside for customers who want unattended renewals.
Should you offer stablecoins as well?
If every customer you have is in Kenya and pays in shillings, M-Pesa alone is a complete answer and adding a second method is noise on your checkout page.
It becomes worth it when part of your revenue comes from outside the country. Diaspora and overseas buyers routinely hit cross-border card declines and conversion fees, and a card payment can be reversed weeks after you have shipped. A settled stablecoin transfer cannot. Because both methods sit on the same checkout page and resolve to the same paid order in WooCommerce, offering the second one costs you nothing operationally.