Skip to main content
Use this endpoint to send an M-Pesa STK push (Lipa na M-Pesa Express) prompt directly to a customer’s phone. When you call this endpoint, the customer receives a payment dialog on their device and approves the charge with their M-Pesa PIN. No redirect or frontend action is required. This endpoint requires your secret key and is intended for server-to-server calls only. If you need to trigger M-Pesa from a client-side context, use the collect payment endpoint with your public_key instead. Method: POST
URL: https://app.kulmipay.com/api/v1/payment/collection/stk-push/

Authentication

Authorization: Bearer <secret_key>

Request

phone_number
string
required
Customer’s M-Pesa phone number in 254XXXXXXXXX format. The number must be a registered Safaricom line with an active M-Pesa account.
amount
number
required
Amount to charge in KES. Minimum is KES 10, maximum is KES 150,000. Decimal values are rounded up to the nearest whole shilling before the STK push is sent.
api_ref
string
Your reference for this transaction, up to 140 characters. Stored on the invoice and returned in webhook events. Defaults to "MPesa Express" if omitted.
wallet_id
string
Alias ID of a specific KES wallet to receive the funds. If omitted, funds go to your default KES settlement wallet.
mobile_tarrif
string
default:"BUSINESS-PAYS"
Who bears the M-Pesa processing fee. BUSINESS-PAYS deducts the fee from your settlement; CUSTOMER-PAYS adds the fee on top of amount before sending the prompt. If your account has a default tariff set in Payment Settings, that value is used when this field is omitted.

Response

The response contains the payment session created for this request, including the invoice and customer details.
id
string
Payment session UUID.
invoice
object
Invoice created for this STK push.
customer
object
Customer record associated with this session.
created_at
string
ISO 8601 timestamp when the session was created.

Code examples

curl --request POST \
  --url https://app.kulmipay.com/api/v1/payment/collection/stk-push/ \
  --header 'Authorization: Bearer YOUR_SECRET_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "phone_number": "254712345678",
    "amount": 1500,
    "api_ref": "order_20240416_001",
    "mobile_tarrif": "BUSINESS-PAYS"
  }'

Example response

{
  "id": "a3f7c819-4e2b-4d1a-9c3f-2b8e1d7a6f05",
  "invoice": {
    "id": "GQ7KZ2XPNM",
    "state": "PENDING",
    "value": "1500.00",
    "currency": "KES",
    "provider": "M-PESA",
    "api_ref": "order_20240416_001",
    "created_at": "2024-04-16T08:23:11.042Z"
  },
  "customer": {
    "customer_id": "CUST_XJ82KP",
    "phone_number": "254712345678",
    "provider": "M-PESA",
    "created_at": "2024-04-16T08:23:11.012Z"
  },
  "customer_comment": null,
  "refundable": false,
  "created_at": "2024-04-16T08:23:11.055Z",
  "updated_at": "2024-04-16T08:23:11.055Z"
}
The STK push prompt expires after 60 seconds if the customer does not respond. Poll the payment status endpoint with the returned invoice.id to detect the final state, or subscribe to webhook events to receive a push notification when the payment completes.