Search by

nyumbani / daraja

geekaburu

A small Laravel client for Safaricom's Daraja API: STK push, C2B and Pull transactions, with the payloads, events and middleware to receive them.

Package info

github.com/nyumbani-tech-solutions/daraja

Homepage

Language:Blade

pkg:composer/nyumbani/daraja

Statistics

Installs: 21

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.1 2026-10-21 19:46 UTC

This package is auto-updated.

Last update: 2026-10-21 19:52:49 UTC


README

A small Laravel client for Safaricom's Daraja API: STK push, C2B URL registration and Pull transactions, plus the payload parsers, middleware, and response helpers to receive them. It requires only Laravel.

Short code

Set the environment, sandbox or production, in your .env (it defaults to production):

DARAJA_ENVIRONMENT=sandbox

To use another environment for one client, call live() or sandbox(): Daraja::for($shortCode)->sandbox().

Build a ShortCode wherever your credentials live (env, config or a database row):

use Nyumbani\Daraja\ShortCode;

$shortCode = new ShortCode(
    value: '174379',
    consumerKey: '...',
    consumerSecret: '...',
    passKey: '...',
    tillNumber: null,                  // set for Buy Goods
);

Calls

use Nyumbani\Daraja\Daraja;

$daraja = Daraja::for($shortCode);

$daraja->stkPush('0712345678', 100, 'INV-1', 'Order payment', $callbackUrl);
$daraja->registerC2BUrls($validationUrl, $confirmationUrl);
$daraja->registerPullUrl('0712345678', $callbackUrl);
$daraja->pullTransactions();           // last 48 hours, or pass from and to

Each call returns Laravel's HTTP client response, so use successful(), failed() and json(). Daraja can answer 200 with a failure code, so also check ResponseCode (0 for an STK push, 1000 for the Pull calls).

Receiving payments

Validation, confirmation, Pull and STK push callbacks are your app's routes, so it decides which paybill a request belongs to, how to read the payload and what to do with it. The package only guards them:

use App\Http\Controllers\ConfirmationController;
use Illuminate\Support\Facades\Route;
use Nyumbani\Daraja\Http\Middleware\EnsureRequestIsFromSafaricom;

Route::post('hooks/{paybill}/confirm', [ConfirmationController::class, 'store'])
    ->middleware(EnsureRequestIsFromSafaricom::class);

EnsureRequestIsFromSafaricom checks daraja.allowed_ips (skipped in daraja.skip_ip_check_in environments) and answers other addresses with C2B00016.

stkPush() needs the callbackUrl Safaricom posts the result to. daraja_phone() normalises a Kenyan number to the 254XXXXXXXXX format Daraja expects.