Skip to main content
POST
/
payments
/
stk
curl --request POST \
  --url https://api.palpluss.com/v1/payments/stk \
  --header 'Authorization: Basic <encoded-value>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "amount": 1000,
  "phone": "0712345678",
  "accountReference": "INV-2024-001",
  "transactionDesc": "Payment for invoice #2024-001",
  "callbackUrl": "https://yourserver.com/webhooks/mpesa"
}
'
{
  "success": true,
  "data": {
    "transactionId": "fa98a577-95ea-4a8f-8467-1fbe74f5d6f4",
    "tenantId": "b6fbe75f-ce87-4d44-b318-6cfdb8b7de4d",
    "channelId": null,
    "type": "STK",
    "status": "PENDING",
    "amount": 1000,
    "currency": "KES",
    "phone": "254712345678",
    "accountReference": "INV-2024-001",
    "transactionDesc": "Payment for invoice #2024-001",
    "providerRequestId": "29115-34620561-1",
    "providerCheckoutId": "ws_CO_191220191020363925",
    "resultCode": "0",
    "resultDescription": "Success. Request accepted for processing",
    "createdAt": "2026-03-01T08:00:00.000Z",
    "updatedAt": "2026-03-01T08:00:00.000Z"
  },
  "requestId": "c1b2a3d4-0000-0000-0000-000000000000"
}
A transaction fee is deducted from your service wallet when the request is accepted. Ensure your balance is sufficient before calling this endpoint.

Key notes

  • Phone numbers are accepted in 07XXXXXXXX, +254XXXXXXXXX, or 254XXXXXXXXX format and normalised internally.
  • accountReference must be 12 characters or fewer. It appears in the customer’s M-Pesa statement.
  • transactionDesc must be 13 characters or fewer. It appears on the customer’s PIN prompt.
  • The returned transactionId is the permanent identifier — use it to poll status or match incoming webhooks.
  • A PENDING response means the STK prompt was sent successfully. The final result arrives via your callbackUrl.

STK abuse protection

If your API key initiates too many STK Pushes with a low success rate in a short window, further requests return 429 STK_TEMP_BANNED. The ban lasts 1 hour. See the details.retryAfterSeconds field for the exact wait time.

Authorizations

Authorization
string
header
required

Use your API key as the username. Leave the password field empty.

Authorization: Basic <base64(apikey:)>

You can also pass the raw API key:

Authorization: Basic <apikey>

Body

application/json
amount
number<decimal>
required

Amount to charge in KES.

Required range: x >= 1
Example:

1000

phone
string
required

Customer phone number. Accepted formats: 0712345678, 254712345678, +254712345678. Normalised to 254XXXXXXXXX internally.

Example:

"0712345678"

accountReference
string
required

Your reference — invoice number, order ID, etc.

Maximum string length: 12
Example:

"INV-2024-001"

transactionDesc
string
required

Short description shown on the customer's PIN prompt.

Maximum string length: 13
Example:

"Payment"

callbackUrl
string<uri>
required

HTTPS URL where PalPluss will POST the transaction result after the customer confirms or cancels payment.

Example:

"https://yourserver.com/webhooks/mpesa"

channelId
string<uuid> | null

Optional. Route the STK Push through a specific payment channel (shortcode). If omitted, the default channel is used.

credentialId
string<uuid> | null

Optional. Use a specific M-Pesa credential profile.

Response

STK Push accepted. Transaction is in PENDING state.

success
boolean
required
Example:

true

data
object
required

Response payload. Shape varies by endpoint.

requestId
string<uuid>
required

Unique identifier for this API request. Include in support tickets.

Example:

"c1b2a3d4-e5f6-7890-abcd-ef1234567890"