Bill Manager
Bill Manager sends invoices by SMS, chases them with reminders, and pushes payments back to you for reconciliation so customers get an e-receipt.
Opt in first
Section titled “Opt in first”$response = Daraja::billManager()->optIn( email: 'billing@example.com', officialContact: '0710000000', sendReminders: true,);
$response->appKey; // AG_2376487236_126732989KJOpt-in whitelists your short code; nothing else works until it succeeds. Update
the details later with updateOptIn().
Reminders, when enabled, go out 7 days before the due date, 3 days before, and on the day.
Single invoice
Section titled “Single invoice”Daraja::billManager()->invoice( externalReference: 'INV-100', billedFullName: 'John Doe', billedPhoneNumber: '0712345678', billedPeriod: 'August 2026', invoiceName: 'Water', dueDate: '2026-09-15', accountReference: 'ACC-1', amount: 800, items: [ ['itemName' => 'Water', 'amount' => 700], ['itemName' => 'Standing charge', 'amount' => 100], ],);externalReference is your own identifier and must be unique — it is how you
and Bill Manager refer to the same invoice.
Bulk invoicing
Section titled “Bulk invoicing”Up to 1000 invoices per call. The package rejects an empty batch or an oversized one before sending.
Daraja::billManager()->bulkInvoice( $invoices->map(fn ($i) => [ 'externalReference' => $i->reference, 'billedFullName' => $i->customer_name, 'billedPhoneNumber' => $i->phone, 'billedPeriod' => $i->period, 'invoiceName' => $i->description, 'dueDate' => $i->due_at->toDateString(), 'accountReference' => $i->account, 'amount' => $i->total, ])->all(),);Reconciliation
Section titled “Reconciliation”Bill Manager pushes each payment to your callback URL and retries up to five times. Acknowledge it so the customer receives their e-receipt:
Daraja::billManager()->acknowledge( paymentDate: '2026-10-01', paidAmount: 800, accountReference: 'ACC-1', transactionId: 'PJB53MYR1N', phoneNumber: '0710000000', fullName: 'John Doe', invoiceName: 'Water', externalReference: 'INV-100',);Cancelling
Section titled “Cancelling”Daraja::billManager()->cancelInvoice('INV-100');Daraja::billManager()->cancelInvoices(['INV-101', 'INV-102']);A partially or fully paid invoice cannot be cancelled — Safaricom answers
rescode 409.
Responses
Section titled “Responses”Bill Manager uses its own envelope rather than Daraja’s:
$response->successful(); // rescode === "200"$response->code; // "200"$response->message; // "Success"$response->statusMessage; // "Invoice sent successfully"$response->errors;