Skip to main content

M-Pesa setup

To accept M-Pesa payments, you need a Safaricom Daraja account with an active paybill or till number. HelaMesh uses the STK push (Lipa Na M-Pesa Online) flow โ€” the customer enters their Safaricom number, receives a prompt on their phone, and enters their PIN.

HelaMesh does not hold M-Pesa credentials

Your Daraja credentials (consumer key, consumer secret, passkey) are encrypted at rest using AES-256-GCM. HelaMesh uses them only to initiate STK push requests and validate callbacks on your behalf. We never initiate unsolicited transactions.

What you need from Safaricom Darajaโ€‹

  1. Go to developer.safaricom.co.ke and create an account.
  2. Create an app and get your Consumer Key and Consumer Secret.
  3. Under Lipa Na M-Pesa Online, get your Passkey and Shortcode (paybill number).

For sandbox testing, Safaricom provides shared test credentials โ€” see the sandbox docs.


Go to Settings โ†’ M-Pesa in the HelaMesh dashboard, click Connect M-Pesa, and fill in:

  • Consumer Key
  • Consumer Secret
  • Shortcode (paybill number)
  • Passkey
  • Environment (sandbox or live)

HelaMesh validates the credentials against Daraja before saving. If validation fails, the credentials are rejected.


Option 2 โ€” Connect via APIโ€‹

Useful for platforms that programmatically onboard merchants.

curl -X POST https://api.helamesh.com/v1/merchant/clients/CLIENT_ID/mpesa/connect \
-H "x-api-key: hm_live_..." \
-H "content-type: application/json" \
-d '{
"consumerKey": "YOUR_CONSUMER_KEY",
"consumerSecret": "YOUR_CONSUMER_SECRET",
"shortcode": "174379",
"passkey": "YOUR_PASSKEY",
"environment": "sandbox"
}'
200 OK
{
"ok": true,
"shortcode": "174379",
"environment": "sandbox"
}

Body fieldsโ€‹

FieldTypeNotes
consumerKeystringFrom Safaricom Daraja app
consumerSecretstringFrom Safaricom Daraja app
shortcodestringYour paybill or till number
passkeystringFrom the Lipa Na M-Pesa Online section in Daraja
environmentstring"sandbox" or "live"
Match environments

Use "environment": "sandbox" with an hm_test_* API key, and "environment": "live" with an hm_live_* key. Mismatching will cause STK push failures.


How STK push works at checkoutโ€‹

When a customer selects M-Pesa on the checkout page:

  1. HelaMesh calls the Daraja STK push API with your credentials
  2. Safaricom sends a push notification to the customer's phone
  3. The payment link moves to PROCESSING state
  4. Customer enters their PIN โ†’ Safaricom sends a callback to HelaMesh
  5. HelaMesh confirms the payment โ†’ link moves to CONFIRMED
  6. Your payment_link.confirmed webhook fires

The callback URL is registered per-request by HelaMesh โ€” you don't need to configure it in Daraja.


Initiating STK push via APIโ€‹

If you're building a custom checkout (not using the hosted page or embed), you can trigger the STK push directly:

curl -X POST https://api.helamesh.com/v1/merchant/payment-links/LINK_ID/pay/mpesa \
-H "x-api-key: hm_test_..." \
-H "content-type: application/json" \
-d '{
"phoneNumber": "254712345678"
}'
200 OK
{
"ok": true,
"checkoutRequestId": "ws_CO_03062026123456789"
}

Poll GET /v1/payment-links/LINK_ID or listen for the payment_link.confirmed webhook to know when the customer completes payment.

Phone number format

Always use the 254XXXXXXXXX format โ€” 12 digits, starting with the Kenya country code. No +, no leading 0.


Sandbox testingโ€‹

In sandbox mode, you can use the Test STK push button on any payment link's detail page in the dashboard. Enter a test phone number and HelaMesh will send a real Daraja sandbox STK request.

Safaricom's sandbox uses shared test credentials and simulates the PIN entry flow. Callbacks are real โ€” the payment link will move to CONFIRMED and your webhook will fire.

See Sandbox for the full test flow.