paylod
Quickstart

Get started

Quickstart

.md

Your first M-Pesa STK Push in five minutes — create an application, add your Daraja credentials, mint a key, and collect a payment.

You need a Safaricom Daraja account (the sandbox is free and instant) and about five minutes. One npm install, and nothing to deploy — no callback server, no tunnel.

1. Create an application

In the paylod dashboard, create an application — one per till or paybill. Give it a name; you can add both a Sandbox and a Production environment to the same application.

2. Add your Daraja credentials

On the application's Credentials tab, paste the four values Daraja gives you:

FieldWhere it comes from
Consumer keyDaraja portal → your app
Consumer secretDaraja portal → your app
ShortcodeYour till / paybill number (174379 in sandbox)
PasskeyDaraja portal → Lipa na M-Pesa Online

They are encrypted at rest and write-only — no API, tool, or dashboard screen ever reads them back.

3. Paste the callback URL into Daraja

paylod shows you a hosted callback URL on the application's Endpoints & Webhooks tab. Copy it into the Daraja portal as your Lipa na M-Pesa Online callback URL.

That is the entire "host a public HTTPS endpoint" problem, solved. You never write callback-handling code.

4. Mint an API key

On the API Keys tab, create a key. Keys are environment-scoped:

  • mp_test_… → Sandbox
  • mp_live_… → Production

The key is shown once. It identifies which application and environment a request runs against, so you never send a shortcode or a Daraja credential over the wire.

The key is a server-side secret. Never ship it in a browser, a mobile app, or anything a payer can open.

5. Install the SDK

Install
npm install @paylod/node

Put the key in your environment. The client picks it up on its own:

.env
PAYLOD_API_KEY=mp_test_YOUR_API_KEY

6. Send your first STK Push

collect.ts
import { Paylod } from "@paylod/node";

const paylod = new Paylod(process.env.PAYLOD_API_KEY!);

const outcome = await paylod.collectAndWait({
  amount: 10,
  phone: "0712345678",
  accountReference: "INV-2041",
  description: "Order #2041",
});

if (outcome.paid) {
  console.log("Paid:", outcome.receipt);   // "UG1F3A1U7J"
} else {
  console.log(outcome.message);            // already decoded, safe to show a customer
}

That is the whole integration. One argument to the constructor, one call.

collectAndWait() sends the STK Push, then polls until the payment settles. The customer's phone rings, they enter their PIN, and you get an answer back. No callback server, no OAuth token to refresh, no result-code table to write.

The answer is a PaymentOutcome: a message you can show a customer, already decoded, and a retryable flag that tells you whether charging again is safe. A wrong PIN is a business outcome, not a crash, so it comes back as data rather than a thrown error.

Phone numbers are normalised for you, so 0712345678, +254712345678 and 254712345678 all work.

A timeout throws PaylodTimeoutError rather than reporting status: "failed". An unanswered prompt is not a failed payment: the customer may still be typing their PIN. Leave the order open. See Handle the result.

You do not need a webhook for this to work. Polling is a first-class path, and collectAndWait() does it for you. Add a signed webhook when you want your server told about payments it is not actively waiting on.

Not on Node?

The SDK is a wrapper over a plain HTTP API — every language can call it directly:

The same call, over HTTP
curl -X POST https://paylod.dev/functions/v1/collect \
  -H "Authorization: Bearer mp_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order_2041" \
  -d '{ "amount": 10, "phone": "254712345678" }'
Response · 202 Accepted
{
  "paymentId": "e69e5c00-8a01-44ed-b003-48e2e86a7c9e",
  "status": "pending",
  "checkoutRequestId": "ws_CO_010720261905029287161380"
}

Then poll GET /functions/v1/status/{paymentId} until it settles. Going this route means doing yourself what the SDK does for you: the polling loop, the idempotency key, and decoding the result code. The full surface is in the API reference.

Next

  • Every method, option and error class: Node SDK.
  • Prefer the terminal? The CLI sends the same STK Push in one command.
  • Prefer push over poll? Handle the result covers signed webhooks.
  • Exercise the failure paths first: Test in sandbox.
  • Ready for real money? Go live.