SHA256
1
0
Fork 0
forked from nestict/whmcsmpesa
WHMCS payment gateway module for M-Pesa (Safaricom Daraja STK Push). Initiates Lipa Na M-Pesa prompts directly from the invoice page, polls for payment confirmation in real-time, and verifies completion securely via callback — no customer-entered transaction codes required.
  • PHP 99.9%
  • HTML 0.1%
Find a file
nestict b2b13c7b63 Update README.md
Signed-off-by: nestict <nestict@nestict.net>
2026-04-17 10:43:58 +00:00
gateways Upload files to "gateways/mpesa" 2026-04-17 10:20:59 +00:00
LICENSE Initial commit 2026-04-17 10:08:16 +00:00
README.md Update README.md 2026-04-17 10:43:58 +00:00

Nestict M-Pesa WHMCS Gateway (STK Push)

WHMCS M-Pesa Daraja License Made by Nestict

A secure, zero-friction WHMCS payment gateway module that integrates Safaricom's Lipa Na M-Pesa (STK Push) directly into your invoice checkout flow — no manual transaction code entry, no portal URL pre-registration.

Built and maintained by Nestict


How It Works

The module follows a clean two-step payment flow:

Customer enters phone number
        ↓
STK Push sent via Daraja API
        ↓
Real-time polling begins (auto-checks payment status)
        ↓
   ┌────────────────────┐
   │  Paid?             │
   │  Yes → Invoice     │
   │        confirmed   │
   │  No  → "Complete   │
   │        Payment"    │
   │        button      │
   └────────────────────┘
        ↓ (on button click)
Check tblmpesarequests for Completed record
        ↓
   ┌────────────────────┐
   │  Found?            │
   │  Yes → Redirect to │
   │        invoice     │
   │  No  → "Try Again" │
   │        to re-send  │
   │        STK Push    │
   └────────────────────┘

No customer-entered transaction codes are ever accepted. Payment confirmation is sourced exclusively from the Daraja callback handler writing to tblmpesarequests.


Features

  • STK Push — triggers M-Pesa payment prompt directly on the customer's phone
  • Real-time polling — auto-detects payment completion without page refreshes
  • Secure callback verification — only server-written records are trusted; no user input accepted
  • No Daraja portal URL pre-registration — callback URL is passed per request, so manual paybill services remain unaffected
  • Graceful retry flow — on timeout or failure, a single "Complete Payment" button appears; invoice paid-status is checked before re-sending STK Push
  • WHMCS-native integration — works within the standard WHMCS gateway module framework

Requirements

Requirement Details
WHMCS v7.x or later (v8.x recommended)
PHP 7.4 or later
Safaricom Daraja Account developer.safaricom.co.ke
M-Pesa Paybill / Till Active Lipa Na M-Pesa shortcode
HTTPS Required — Daraja callbacks need a valid SSL endpoint

Installation

  1. Download or clone this repository.

  2. Copy the module file to your WHMCS installation:

    /modules/gateways/nestictmpesa.php
    
  3. Copy the callback file (if included separately):

    /modules/gateways/callback/nestictmpesa.php
    
  4. Log in to WHMCS AdminSetupPaymentsPayment Gateways.

  5. Activate the Nestict M-Pesa (STK Push) gateway.

  6. Enter your Daraja credentials in the gateway settings:

    • Consumer Key
    • Consumer Secret
    • Business Shortcode (Paybill or Till)
    • Passkey (Lipa Na M-Pesa Online)
    • Environment (sandbox or live)
  7. Save and test with a sandbox phone number.


Configuration

Setting Description
Consumer Key From your Daraja app
Consumer Secret From your Daraja app
Business Shortcode Your M-Pesa Paybill or Till number
Passkey Lipa Na M-Pesa Online passkey
Environment sandbox for testing, live for production
Account Reference Usually your company name or invoice number (auto-filled)

The callback URL is constructed automatically per request and does not need to be registered in the Daraja portal. This keeps manual paybill collections fully intact.


Database

The module uses a custom table tblmpesarequests to track STK Push requests and callback results.

CREATE TABLE IF NOT EXISTS `tblmpesarequests` (
  `id`              INT(11)      NOT NULL AUTO_INCREMENT,
  `invoice_id`      INT(11)      NOT NULL,
  `phone`           VARCHAR(20)  NOT NULL,
  `checkout_request_id` VARCHAR(100) NOT NULL,
  `status`          VARCHAR(20)  DEFAULT 'Pending',
  `mpesa_receipt`   VARCHAR(50)  DEFAULT NULL,
  `amount`          DECIMAL(10,2) DEFAULT NULL,
  `created_at`      DATETIME     DEFAULT CURRENT_TIMESTAMP,
  `updated_at`      DATETIME     DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `invoice_id` (`invoice_id`),
  KEY `checkout_request_id` (`checkout_request_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

The table is created automatically on first module activation if it does not exist.


Security

  • No user-supplied transaction codes are accepted at any point in the flow.
  • All payment confirmations come exclusively from the Daraja server-to-server callback.
  • The "Complete Payment" button only reads from tblmpesarequests — it does not accept any input.
  • "Try Again" validates that the invoice is still unpaid before re-triggering STK Push, preventing double payments.
  • Callback endpoint should be protected with IP whitelisting for Safaricom's callback IPs in production.

Payment Flow Detail

Step 1 — Initiate STK Push

  • Customer enters their M-Pesa registered phone number on the invoice page.
  • The module calls the Daraja STK Push API.
  • Real-time polling begins — the page auto-checks for payment confirmation.

Step 2 — Confirmation or Retry

  • If the customer pays: polling detects the Completed record and redirects to the confirmed invoice.
  • If the prompt times out or is cancelled: a "Complete Payment" button appears.
    • Clicking it queries tblmpesarequests for a Completed record on the current invoice.
    • Found → invoice is marked paid and the customer is redirected.
    • Not found → a "Try Again" option is shown to re-initiate the STK Push.

Sandbox Testing

  1. Set Environment to sandbox in gateway settings.
  2. Use Safaricom test credentials from developer.safaricom.co.ke.
  3. Use the sandbox test phone number: 254708374149 (PIN: 1234).
  4. Inspect tblmpesarequests to verify callback records are being written.

Troubleshooting

Issue Likely Cause Fix
STK Push not received Wrong shortcode / passkey Verify Daraja credentials
Callback not firing HTTP (not HTTPS) endpoint Ensure valid SSL certificate
Pending stuck forever Callback URL unreachable Check firewall / server accessibility
Double payment concern Re-sending without paid check Module checks invoice status before retry

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you'd like to change.

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature
  3. Commit changes: git commit -m 'Add your feature'
  4. Push: git push origin feature/your-feature
  5. Open a Pull Request

License

MIT License — see LICENSE for details.


Support

For commercial support, custom integrations, or enterprise deployments:

Nesticthttps://www.nestict.com/


Built with care for the East African developer community.