Most businesses in Africa juggle three payment channels: mobile money (M-Pesa, MTN MoMo), bank transfers, and cash. Each has its own statement format, reconciliation process, and accounting treatment. ERPNext unifies all three into a single ledger with one reconciliation workflow, one Chart of Accounts, and one set of financial reports.
This article explores ERPNext's payment architecture in depth -- how Payment Entries work, how the Accounts module handles multi-currency transactions, how auto-reconciliation matches payments to invoices, and how the Mode of Payment system lets you plug in any payment channel (including M-Pesa via Coale-Payments) without changing your accounting structure.
Whether you are evaluating ERPNext for the first time or already running it and want to understand the financial engine under the hood, this is the technical walkthrough you need.
The Payment Entry: ERPNext's Universal Payment Object
Every payment in ERPNext -- whether it arrives via M-Pesa, bank transfer, cheque, or cash -- flows through the same DocType: Payment Entry. This is ERPNext's universal payment object. It links a payment to one or more invoices, records the payment method, captures reference numbers, and creates the corresponding General Ledger entries automatically.
A Payment Entry can be created manually, generated from a Sales Invoice with one click ("Make Payment"), or created programmatically by integrations like Coale-Payments. Regardless of how it is created, the downstream accounting is identical: the receivable or payable account is credited/debited, the bank or cash account is updated, and the invoice status changes from "Unpaid" to "Paid" (or "Partly Paid" for partial payments).
This design means adding a new payment channel -- M-Pesa today, MTN MoMo tomorrow, a cryptocurrency gateway next year -- never requires changes to your Chart of Accounts or reporting structure. You simply create a new Mode of Payment, link it to a bank account, and payments flow through the same proven accounting pipeline.
Mode of Payment: Plugging Any Channel into the Ledger
STK (SIM Toolkit) push is the most common integration pattern for retail and point-of-sale environments. When triggered from ERPNext or Coale-POS, the Safaricom Daraja API sends a payment prompt directly to the customer's phone. The customer sees the business name, amount, and confirms with their M-Pesa PIN.
From a technical perspective, STK push uses Safaricom's Lipa Na M-Pesa Online API (also known as the M-Pesa Express API). Coale-Payments handles the OAuth token generation, request formatting, and callback processing. When the payment succeeds, a Payment Entry is created in ERPNext with the M-Pesa transaction ID, the payer's phone number (masked for privacy), and the exact timestamp.
If the payment fails -- because the customer cancelled, entered the wrong PIN, or had insufficient funds -- Coale-Payments logs the failure reason and the Sales Invoice remains unpaid. The cashier can retry the STK push or accept an alternative payment method.
STK push is ideal for retail shops, restaurants, service businesses, and any scenario where the customer is present and paying immediately. It eliminates the friction of customers having to remember and type your paybill number.
Multi-Currency: KES, USD, and Beyond
Customer-to-Business (C2B) payments happen when customers initiate the payment from their own M-Pesa menu. They select "Lipa Na M-Pesa," enter your paybill number or till number, provide an account reference (such as an invoice number or customer code), and send the money.
With Coale-Payments, your ERPNext instance registers a C2B callback URL with Safaricom. Every time a customer pays to your business number, Safaricom sends a real-time notification to your system. Coale-Payments receives this notification and performs automatic matching: it looks up the account reference in ERPNext's Sales Invoice list, finds the matching unpaid invoice, and creates a Payment Entry.
This is particularly powerful for businesses that send invoices by email or WhatsApp. The invoice includes your paybill number and the invoice number as the account reference. The customer pays when convenient, and the payment is recorded in ERPNext within seconds -- no bookkeeper required.
For cases where the account reference does not match any invoice -- perhaps the customer typed it incorrectly -- Coale-Payments creates an unallocated Payment Entry tagged for manual review. This ensures no payment is ever lost, even when matching fails.
The Accounts Module: Double-Entry Done Right
Business-to-Customer (B2C) payments go in the other direction: your business sends money to M-Pesa users. This is used for supplier payments, employee salary disbursements, customer refunds, and petty cash distributions.
In ERPNext, when you submit a Payment Entry for a supplier or an employee's salary, Coale-Payments can trigger a B2C disbursement through the Safaricom API. The recipient receives the money directly in their M-Pesa wallet. The transaction ID from Safaricom is recorded against the Payment Entry for audit purposes.
B2C disbursements require a higher level of Safaricom API access and additional KYC verification for your business. This is because you are moving money out of your account. Coale-Payments supports the full B2C workflow including balance checks, transaction limits, and queue management for bulk disbursements (such as monthly payroll).
For payroll specifically, ERPNext's Payroll Entry generates salary slips for all employees. Coale-Payments can process these as bulk B2C transactions, sending each employee's net salary to their registered M-Pesa number. The entire payroll disbursement for a 50-person company can be completed in under a minute.
Auto-Reconciliation: From Bank Statement to Balanced Books
Reconciliation is where M-Pesa integration delivers its biggest time savings. In a manual workflow, an accountant downloads the M-Pesa statement from the Safaricom portal, exports it to Excel, and manually matches each transaction to an invoice in ERPNext. For a business processing 100+ M-Pesa transactions daily, this takes hours.
Coale-Payments eliminates this entirely. Every incoming payment is matched in real time using a multi-step matching algorithm. First, it checks the account reference against Sales Invoice numbers. If no match is found, it checks against Sales Order numbers, Customer IDs, and phone numbers. If a definitive match is found, the payment is allocated automatically. If multiple potential matches exist, the payment is flagged for manual review with suggested matches.
The system also handles partial payments and overpayments correctly. If a customer pays KES 8,000 against a KES 10,000 invoice, ERPNext records the partial payment and the invoice shows KES 2,000 outstanding. If a customer overpays, the excess is recorded as a credit balance on their customer account.
At the end of each day, your accountant reviews only the unmatched payments -- typically fewer than 5% of total transactions. The rest have been reconciled automatically, with full audit trails showing the M-Pesa transaction ID, timestamp, and matching logic used.
Party-Level Accounting: Customer and Supplier Ledgers
Payment integrations demand rigorous security. Coale-Payments implements several layers of protection to keep your financial data safe.
API credentials are encrypted at rest in your ERPNext instance. The Safaricom consumer key, consumer secret, and passkey are stored using ERPNext's built-in encryption, not as plain text. They are only decrypted in memory during API calls.
Callback validation ensures that payment notifications actually come from Safaricom. Each callback is verified against Safaricom's IP whitelist and the request signature is validated before any payment is recorded.
Transaction logging creates a complete audit trail. Every API call, callback, matching decision, and Payment Entry creation is logged with timestamps. This satisfies both internal audit requirements and KRA compliance obligations.
PCI DSS considerations do not apply to M-Pesa integrations in the same way as card payments, since no card data is involved. However, protecting customer phone numbers and transaction amounts is still essential under Kenya's Data Protection Act (2019). Coale-Payments masks phone numbers in user-facing screens and restricts access to payment logs through ERPNext's role-based permission system.
Reports: Aged Receivables, Cash Flow, and Trial Balance
Getting started with Coale-Payments requires three things: a Safaricom Daraja API account, an ERPNext instance, and the Coale-Payments app installed on that instance.
First, register on the Safaricom Daraja portal (developer.safaricom.co.ke) and create an application. You will receive a consumer key and consumer secret. For production access, you need to go through Safaricom's Go Live process, which involves providing your business registration documents, KRA PIN certificate, and a test report showing successful API calls in the sandbox environment.
Second, install Coale-Payments on your ERPNext instance using the Frappe bench. Navigate to the M-Pesa Settings page, enter your Daraja API credentials, and configure your paybill or till number. The setup wizard walks you through callback URL registration and sandbox testing.
Third, configure your payment modes in ERPNext's Mode of Payment settings. Create an "M-Pesa" mode of payment linked to your M-Pesa bank account in the Chart of Accounts. This ensures all M-Pesa transactions are correctly reflected in your financial statements.
Frequently Asked Questions
Does the integration work with both Paybill and Till numbers?
Yes. Coale-Payments supports both Paybill (with account numbers) and Buy Goods Till numbers. You can configure multiple business numbers on a single ERPNext instance if your business operates under different M-Pesa accounts for different branches or entities.
What happens if my server goes down during a payment?
Safaricom's callback system includes retry logic. If your server is unreachable when a payment is completed, Safaricom will retry the callback multiple times. Coale-Payments also includes a reconciliation tool that pulls the latest transactions from the Daraja API and matches any payments that were missed during downtime.
Can I use this integration with Coale-POS for retail?
Absolutely. Coale-POS has built-in M-Pesa payment support through Coale-Payments. The cashier selects M-Pesa as the payment method, and the STK push is triggered automatically. The POS closing entry reflects M-Pesa totals alongside cash and card payments.
ERPNext + Coale-Payments: The Complete Stack
Stop wasting hours on manual payment reconciliation. Coale-Payments connects your ERPNext instance to M-Pesa in minutes and handles the entire payment lifecycle -- from STK push to ledger entry -- automatically.
Whether you are processing 10 or 10,000 M-Pesa transactions per day, the integration scales with your business. Contact us for a demo or get started with a free trial.