safaricom/mpesa
Laravel package for Safaricom M-Pesa integration, simplifying STK Push, C2B, B2C, transaction status, and callback handling. Configure credentials, initiate payments, and reconcile responses with clean, expressive PHP APIs built for Laravel applications.
composer require safaricom/mpesa
1.0.8 release allows parsing of .env parameters. Check the README and src/ to see exactly how that works: whether the SDK loads .env itself, reads existing environment variables, accepts a path, and how it handles precedence. Prefer Laravel config in application code, but use the new feature only if it fits your setup.src/, any examples, and composer.json. The package history is old—previous release was 2019—so verify abandoned/old dependencies and test against your PHP version before rollout.MPESA_ENV=sandbox
MPESA_CONSUMER_KEY=
MPESA_CONSUMER_SECRET=
MPESA_SHORTCODE=
MPESA_PASSKEY=
MPESA_CALLBACK_URL=https://example.test/api/mpesa/callback
MerchantRequestID and CheckoutRequestID, then expose a public callback route that logs and updates the attempt.use Safaricom\Mpesa\Mpesa;
$mpesa = new Mpesa();
$timestamp = date('YmdHis');
$password = base64_encode($shortcode . $passkey . $timestamp);
// Follow the SDK README for exact argument order.
$response = $mpesa->STKPush(
$shortcode,
$password,
$timestamp,
'CustomerPayBillOnline',
$amount,
$phone,
$shortcode,
$phone,
$callbackUrl,
$accountReference,
$description
);
MpesaService or MpesaGateway. Controllers and jobs should not call the SDK directly. This gives you one place to normalize arguments, log requests, handle environment switching, and later replace the SDK..env parsing in 1.0.8 as a convenience for bootstrapping or local setup, not as your application configuration strategy. Resolve MPESA_* values through Laravel config(), pass explicit values into your gateway, and keep the SDK isolated from config-cache behavior.MerchantRequestID, CheckoutRequestID, raw request, raw response, status, and callback payload. Day-to-day reconciliation depends on these IDs.CheckoutRequestID/MerchantRequestID, queue heavier work, and return HTTP 200 quickly..env parsing if you rely on it: missing keys, empty values, quoted values, and changes after config:cache. Use the real sandbox for a smoke test, but do not make CI depend on M-Pesa availability.PaymentInitiated, PaymentSucceeded, and PaymentFailed so order, invoice, and notification logic stays decoupled from M-Pesa response codes.1.0.8 adds .env parsing, but the release history is sparse and the package was previously dormant. Test on PHP 8.x, check Composer conflicts, pin the version, and isolate it behind your own adapter so you can fork or replace it..env parsing is a likely source of surprises. Confirm whether the SDK reads .env directly, uses getenv(), or relies on Laravel already having loaded env values. In production, config:cache means env() outside config files can return null; do not let SDK-side env parsing bypass Laravel’s config cache..env itself, verify path resolution and precedence. It should not override real production environment variables, read from an unexpected working directory, or break when .env is absent in deployments that inject env vars another way.base64(shortcode + passkey + timestamp), with timestamp in YmdHis format and matching the request. Do not reuse a stale timestamp/password.2547XXXXXXXX without +, spaces, or a leading zero.CheckoutRequestID against your database, and confirm final state with a status query when needed.0 success, 1032 cancelled by user, and 1037 timeout/no response; map these into your own statuses..env parsing behavior, do not edit vendor/. Wrap it, subclass it if safe, or fork it with a small patch and document the fork.How can I help you explore Laravel packages today?