This page is the direct-mode reference: it documents the Daraja API contract for ISPs that bring their own Paybill or Till. Most ISPs operate on centralized mode instead, where FyberPay’s shared Paybill (
4026145) collects on their behalf and no Daraja credentials are needed. See M-Pesa Integration → Centralized vs Direct for which mode applies to you.Supported Payment Flows
Environment Endpoints
- Sandbox
- Production
Base URL:
https://sandbox.safaricom.co.keAuthentication: OAuth Token Flow
All Daraja API calls require a Bearer token obtained via OAuth 2.0 client credentials.1
Obtain credentials from Daraja portal
Register your app at developer.safaricom.co.ke and get your Consumer Key and Consumer Secret.
2
Request an access token
FyberPay sends a GET request with Basic auth (base64-encoded
ConsumerKey:ConsumerSecret):3
Token caching
FyberPay caches tokens in Redis for 290 seconds (~5 minutes). Tokens from Safaricom are valid for 3600 seconds (1 hour), but FyberPay refreshes early to avoid edge cases with clock drift. Each set of credentials (per-org or platform-level) gets its own cache key.
STK Push (Lipa Na M-Pesa Online)
STK Push sends a payment prompt directly to the subscriber’s phone. The subscriber enters their M-Pesa PIN to authorize the payment.Request Format
The Password field is computed as
Base64(BusinessShortCode + Passkey + Timestamp). The Timestamp format is YYYYMMDDHHmmss in East Africa Time (UTC+3). FyberPay computes this automatically.M-Pesa requires whole number amounts. FyberPay applies
Math.ceil() to round up fractional amounts before sending.Phone Number Normalization
FyberPay normalizes Kenyan phone numbers to the254XXXXXXXXX format (no plus sign). The following inputs are all accepted:
STK Push Response
CheckoutRequestID to correlate with the callback.
STK Push Callback
Safaricom sends the result to yourCallBackURL:
- Successful Payment
- Failed/Cancelled
MpesaReceiptNumber, Amount, and PhoneNumber from the CallbackMetadata.Item array.
STK Query (Status Check)
If no callback arrives, FyberPay can poll the transaction status:ResultCode to internal payment statuses:
C2B (Customer to Business)
C2B handles payments where the subscriber initiates the transaction from their M-Pesa menu by sending money to the ISP’s paybill number.URL Registration
FyberPay registers validation and confirmation URLs with Safaricom:C2B Callback Payload
TransID as the receipt number, TransAmount as the payment amount, MSISDN as the phone number, and BillRefNumber as the account/invoice reference.
Bill Manager API
Bill Manager handles automated invoice delivery, SMS reminders, and payment reconciliation. It operates at the platform level (not per-org) using dedicated credentials.One-Time Setup: Opt-In
Register your paybill with Safaricom Bill Manager:app_key that confirms successful registration.
Sending Invoices
- Single Invoice
- Bulk Invoices
Endpoint:
POST /v1/billmanager-invoice/single-invoicingSends an invoice to a single subscriber. The subscriber receives an SMS with the amount, due date, and payment instructions.Cancelling Invoices
200 for successful cancellation or 409 if the invoice was already cancelled (both treated as success by FyberPay).
Payment Reconciliation
After processing a Bill Manager payment, FyberPay sends an acknowledgment back to Safaricom. This triggers an e-receipt SMS to the subscriber:Webhook Security
FyberPay validates incoming M-Pesa callbacks using IP allowlisting. Configure theDARAJA_ALLOWED_IPS environment variable with Safaricom’s callback IPs (comma-separated). If no allowlist is configured, all IPs are accepted (suitable for sandbox testing only).
Error Codes Reference
Common M-Pesa STK Push error codes:Retry Behavior and Circuit Breaker
All Daraja API calls are wrapped in a circuit breaker (daraja circuit). If Safaricom’s API is consistently failing, the circuit opens and FyberPay stops sending requests for a cooldown period. This prevents cascade failures and protects against Safaricom downtime.
For STK callbacks that fail to arrive:
- FyberPay queries the transaction status using the STK Query endpoint
- If the query also fails, the payment remains in
PENDINGstatus - A background job retries pending payment status checks periodically
Per-Org vs Platform Credentials
FyberPay supports two credential models:
Per-org credentials take priority. If an organization has no M-Pesa credentials configured, FyberPay falls back to platform-level credentials.