Salami Gateway provides a unified payments API that integrates with multiple payment providers across Africa and beyond. The module uses a driver-based architecture allowing you to switch providers without changing your integration code.
https://your-domain.com/api/pay
All API endpoints (except callbacks and transaction validation) require authentication via Laravel Sanctum bearer tokens.
Authorization: Bearer {your-api-token}
| Driver | Type Identifier | Capabilities |
|---|---|---|
| M-Pesa Express (STK Push) | MpesaKeExpress |
Request Payment, Callback, Transaction Status, Reversal, Balance Check |
| M-Pesa C2B | MpesaKeC2B |
Callback, Validation, URL Registration, Simulation, SMS Extract, Balance Check, Reversal, Transaction Status |
| M-Pesa B2C | MpesaKeB2C |
Send Money, Reversal, Callback, Transaction Status, Balance Check |
| M-Pesa B2B | MpesaKeB2B |
Send Money, Reversal, Transaction Status, Balance Check, Callback |
| Driver | Type Identifier | Capabilities |
|---|---|---|
| STK Push | CoopKeExpress |
Request Payment, Callback |
| Send to M-Pesa | CoopKeB2M |
Send Money, Callback, Transaction Status |
| Internal Transfer | CoopKeIFT |
Send Money, Callback, Transaction Status |
| PesaLink (Bank) | CoopKePesaLink |
Send Money, Callback, Transaction Status |
| PesaLink (Phone) | CoopKePesaLinkPhone |
Send Money, Callback, Transaction Status |
| Account Balance | CoopKeAccountBalance |
Balance Check |
| Mini Statement | CoopKeMiniStatement |
Fetch Transactions |
| Account Validation | CoopKeAccountValidation |
Validate |
| Exchange Rate | CoopKeExchangeRate |
(custom method) |
| Driver | Type Identifier | Capabilities |
|---|---|---|
| M-Pesa STK Push | EquityKeExpress |
Request Payment, Callback |
| Equitel STK Push | EquityKeEquitelExpress |
Request Payment, Callback |
| Internal Transfer | EquityKeIFT |
Send Money, Callback, Transaction Status |
| Send to Mobile | EquityKeB2M |
Send Money, Callback, Transaction Status |
| RTGS | EquityKeRTGS |
Send Money, Callback, Transaction Status |
| SWIFT | EquityKeSWIFT |
Send Money, Callback, Transaction Status |
| PesaLink (Bank) | EquityKePesaLink |
Send Money, Callback, Transaction Status |
| PesaLink (Phone) | EquityKePesaLinkPhone |
Send Money, Callback, Transaction Status |
| Account Balance | EquityKeAccountBalance |
Balance Check |
| Mini Statement | EquityKeMiniStatement |
Fetch Transactions |
| Airtime | EquityKeAirtime |
Send Airtime |
| Driver | Type Identifier | Capabilities |
|---|---|---|
| USSD Push | AirtelKeExpress |
Request Payment, Callback |
| Disbursement (B2C) | AirtelKeB2C |
Send Money, Callback, Transaction Status |
| Account Balance | AirtelKeAccountBalance |
Balance Check |
| Provider | Type Identifier | Region | Capabilities |
|---|---|---|---|
| M-Pesa Personal | MpesaKePersonal |
Kenya | SMS Extract |
| M-Pesa Tanzania | MpesaTz |
Tanzania | SMS Extract |
| M-Pesa Congo | MpesaCongo |
Congo | SMS Extract |
| Airtel Ghana | AirtelGh |
Ghana | SMS Extract |
| MTN Ghana | MtnGh |
Ghana | SMS Extract |
| MTN Rwanda | MtnRwa |
Rwanda | SMS Extract |
| MTN Uganda | MtnUg |
Uganda | SMS Extract |
| PayPal IPN | PaypalIPN |
Global | Callback |
| Pesalink Kenya | PesalinkKe |
Kenya | SMS Extract |
| Tigo Tanzania | TigoTz |
Tanzania | SMS Extract |
| Kopokopo | Kopokopo |
Kenya | Callback |
| Log (Debug) | Log |
N/A | All operations (logged only) |
For detailed SDK usage and code examples, see the SDK Reference.
A Payment App is the central configuration entity. Each Payment App binds a specific provider driver to a set of credentials. You can have multiple Payment Apps for the same provider (e.g., separate M-Pesa Express apps for different paybills).
Key properties:
| Field | Type | Description |
|---|---|---|
id |
integer | Unique identifier, used in all API endpoint paths |
name |
string | Human-readable name for the app |
type |
string | Driver identifier (e.g., MpesaKeExpress) |
is_live |
boolean | true for production, false for sandbox |
dedicated |
boolean | Whether this is a dedicated or shared app |
parent_app_id |
integer/null | Parent app ID for shared configurations |
Each provider has a corresponding driver class that implements one or more capability interfaces:
| Capability | Description |
|---|---|
RequestsPayment |
Initiates a payment request (e.g., STK Push) |
SendsMoney |
Sends money to a recipient (B2C/B2B) |
SendsAirtime |
Sends airtime to a phone number |
HandlesCallback |
Processes IPN/callback notifications from the provider |
ValidatesTransactions |
Validates incoming transactions (e.g., C2B validation) |
RegistersUrls |
Registers callback/validation URLs with the provider |
SimulatesTransactions |
Simulates transactions in sandbox mode |
FetchesTransactions |
Fetches transaction records from the provider |
FetchesTransactionStatus |
Checks the status of a specific transaction |
ChecksBalance |
Checks account balance at the provider |
ReversesTransactions |
Reverses a completed transaction |
ExtractsTransactionsFromSms |
Parses transaction details from SMS messages |
Each Payment App has an is_live flag:
is_live: false): Requests are routed to the provider's sandbox/test environment. Use test credentials and test phone numbers.is_live: true): Requests go to the live provider environment. Real money is moved.For M-Pesa, sandbox mode uses Safaricom's sandbox APIs at https://sandbox.safaricom.co.ke, while production uses https://api.safaricom.co.ke.
Every payment operation that moves or attempts to move money creates a Transaction record.
| Field | Type | Description |
|---|---|---|
id |
integer | Unique transaction ID in Salami |
payer_account |
string | Account/phone of the payer |
payer_name |
string | Name of the payer |
payee_account |
string | Account/phone of the payee |
payee_name |
string | Name of the payee |
reference |
string | Payment reference or account number |
transaction_id |
string | Provider's transaction ID (e.g., M-Pesa receipt number) |
amount |
decimal | Transaction amount |
currency |
string | Three-letter ISO currency code (default: KES) |
transaction_time |
datetime | When the transaction occurred |
narration |
string | Transaction description/narration |
status |
string | Transaction status (see below) |
transaction_type |
string | PAYMENT_IN, PAYMENT_OUT, or PAYMENT_NEUTRAL |
transaction_sub_type |
string | Provider-specific sub-type |
payment_provider |
string | Provider driver that processed this transaction |
app_id |
integer | Associated Payment App ID |
raw_details |
object | Full raw response from the provider |
created_at |
datetime | Record creation timestamp |
| Status | Value | Description |
|---|---|---|
| Attempted | STATUS_ATTEMPTED |
Payment request initiated but not yet completed |
| Completed | STATUS_COMPLETED |
Payment successfully processed |
| Failed | STATUS_FAILED |
Payment failed |
| Cancelled | STATUS_CANCELLED |
Payment was cancelled |
| Declined | STATUS_DECLINED |
Payment was declined by provider or user |
| Type | Value | Description |
|---|---|---|
| Payment In | PAYMENT_IN |
Money received (e.g., C2B, STK Push) |
| Payment Out | PAYMENT_OUT |
Money sent (e.g., B2C) |
| Neutral | PAYMENT_NEUTRAL |
No money movement (e.g., balance check, reversal) |
All API responses follow this structure:
{
"data": { },
"status": "success",
"message": "Operation completed successfully"
}
Error responses:
{
"data": null,
"status": "error",
"message": "Description of what went wrong"
}
| Code | Description |
|---|---|
200 |
Success |
201 |
Resource created |
401 |
Unauthenticated -- missing or invalid bearer token |
403 |
Forbidden -- you do not own this Payment App |
404 |
Payment App or Transaction not found |
422 |
Validation error -- check the request body |
500 |
Server error or provider error |
API requests are subject to the application's default rate limiting configuration. Provider-specific rate limits (e.g., Safaricom's M-Pesa API limits) are enforced by the upstream provider.