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",
    "transactionFee": 2.5,
    "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"
}
Trigger a payment. The customer receives a PIN prompt on their phone within seconds.
A transaction fee is deducted from your service wallet when the request is accepted. Verify your balance before calling this endpoint.

Key notes

  • Phone numbers are accepted in 07XXXXXXXX, 01XXXXXXXX, +254XXXXXXXXX, or 254XXXXXXXXX format and normalised internally.
  • accountReference must be 12 characters or fewer — it appears on the customer’s M-Pesa statement.
  • transactionDesc must be 13 characters or fewer — it appears on the customer’s PIN prompt.
  • Save the returned transactionId — use it to poll status or match incoming webhooks.
  • PENDING means the STK prompt was sent. The final result arrives via your callbackUrl.
  • transactionFee in the response shows the service wallet amount deducted for this request. It is 0 when no pricing rule is configured.

Using a credential profile (credential_id)

The optional credential_id field lets you route the STK Push through your own M-Pesa Daraja credentials (BYOC — Bring Your Own Credentials) instead of the platform default. When credential_id is provided:
  • Daraja OAuth and the STK Push initiation use that profile’s consumerKey, consumerSecret, passkey, and shortcode.
  • With a channel (channelId) — the channel type determines the transaction type (PAYBILLCustomerPayBillOnline, TILLCustomerBuyGoodsOnline). The channel’s shortcode is used as PartyB.
  • Without a channel — the credential profile’s transactionType (set when creating the profile) determines the transaction type. The profile’s shortcode is used as PartyB. Falls back to the platform DARAJA_TRANSACTION_TYPE setting if the profile has no transactionType set.
Credential profiles are managed from the merchant dashboard under Settings → Credential Profiles. Create a MERCHANT_BYOC profile and copy its UUID to use here.

Response fields

FieldTypeDescription
transactionIdstringUUID of the created transaction
typestringAlways "STK"
statusstringAlways "PENDING" on initiation
amountnumberPayment amount in KES
currencystringAlways "KES"
phonestringNormalised phone number (254XXXXXXXXX)
accountReferencestringReference shown on customer’s M-Pesa statement
transactionDescstringDescription shown on customer’s PIN prompt
transactionFeenumberService wallet fee charged for this request. 0 if no fee applies.
providerRequestIdstring | nullSafaricom MerchantRequestID
providerCheckoutIdstring | nullSafaricom CheckoutRequestID
resultCodestring | nullProvider result code ("0" = accepted)
resultDescriptionstring | nullProvider result message
createdAtstringISO 8601 timestamp
updatedAtstringISO 8601 timestamp

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. Check details.retryAfterSeconds 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.

credential_id
string<uuid> | null

Optional. Use a specific MERCHANT_BYOC credential profile for this request. When provided, Daraja OAuth and STK initiation use that profile's credentials (consumerKey, consumerSecret, passkey, shortcode).

Transaction type (commandId) resolution when credential_id is set:

  • Channel present → channel type drives it (PAYBILL = CustomerPayBillOnline, TILL = CustomerBuyGoodsOnline)
  • No channel → profile's transactionType is used when set; falls back to platform default

PartyB resolution when no channel is configured: the credential profile's shortcode is used instead of the platform default shortcode.

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"