Skip to content
HomeAbout MeMy WorkServicesBlogContact
Back to Blog
M-PesaMarch 30, 202612 min read

M-Pesa Paybill Has Two Accounts Inside It — And Nobody Tells You

When I was building the payment integration for PropFlow, a property management platform that collects rent via M-Pesa, I ran into a problem that had nothing to do with code. I needed tenants to pay rent in (C2B) and landlords to receive disbursements out (B2C) from the same shortcode. Sounds simple. It wasn’t.

The thing that tripped me up, and I’m convinced trips up every developer building a collection-and-disbursement platform in Kenya, is that a single M-Pesa Paybill shortcode actually has two separate accounts inside it. And the way money flows between them determines whether your B2C disbursements work or fail silently.

Here’s everything I wish someone had told me before I spent days trying to figure out why my disbursements weren’t going through.


The Two Accounts Inside Every Paybill

When Safaricom sets up a Paybill shortcode, it comes with two internal accounts:

Here’s the problem with the traditional setup: these two accounts are separate. In a standard Paybill, C2B payments land in the Working Account but B2C pulls from the Utility Account. If your Utility Account has zero balance, your B2C API calls will fail even if your Working Account has millions sitting in it. You have to manually move funds from Working to Utility via the G2 portal before you can disburse.

This is what caught me off guard. My C2B collections were flowing in perfectly, but every B2C call was failing because the Utility Account was empty. The dashboard showed money in the Working Account, but that’s not where B2C looks.


The Old Way: How B2C Float Used to Work

Before the Business One Account product existed, if you wanted to do both C2B (collect payments) and B2C (send money out), you typically needed two separate shortcodes:

  • A Paybill shortcode for C2B collections
  • A Bulk Payment shortcode for B2C disbursements

And funding the Bulk Payment shortcode was painful. You had to purchase float by depositing money into trust accounts at KCB or NCBA via cash, cheque, EFT, or RTGS. Cheque deposits could take up to three days to clear.

So the flow looked like this:

You deposit money at KCB/NCBA (cash, cheque, EFT, RTGS) ↓ Bank credits Safaricom’s M-Pesa holding account ↓ Funds appear in your B2C Working Account ↓ You manually move funds to Utility Account (via G2 portal) ↓ Now you can finally call the B2C API to send money out

Six steps before a single shilling leaves your system. And if you ran out of float on a Friday afternoon, you were stuck until Monday.

The alternative was using the B2B API to transfer funds from your Paybill’s C2B shortcode to your Bulk Payment’s B2C shortcode. But this required having a Merchant Payment Portal, and the B2B API itself needs separate whitelisting on your shortcode (which is a whole other headache — I wrote about that here).


The Better Way: M-Pesa Business One Account

This is the product that changed everything for me, and it’s what I’d recommend to any developer building a platform that needs to both collect and disburse funds.

The M-Pesa Business One Account lets you use a single Paybill shortcode for both C2B and B2C. But the real game-changer is how it handles float:

C2B funds land directly in the Utility Account.

This is the key difference. In the old setup, C2B payments land in the Working Account and you have to manually move them to Utility before you can disburse. With Business One Account, C2B payments skip the Working Account entirely and go straight into the Utility Account. That means the moment a tenant pays rent to your Paybill, those funds are sitting in the same account that B2C disbursements are sent from. No manual transfers. No waiting.

The simplified flow:

Tenant pays rent via M-Pesa (C2B) to your Paybill ↓ Funds land directly in the Utility Account ↓ You call B2C API to disburse to landlord’s M-Pesa (B2C debits from Utility Account — funds are already there)

Three steps. That’s it.

For PropFlow, this was exactly what I needed. Tenants pay rent in, PropFlow processes the payment and matches it to the correct unit and lease, then the landlord gets paid out. One shortcode handles both directions.


How to Get Business One Account

There are three scenarios depending on your current setup:

For support during the process, contact:

  • Phone: 0722 002 222 (M-Pesa Business team)
  • Email: M-Pesabusiness@safaricom.co.ke
  • Email: Lipanampesa@safaricom.co.ke
  • M-Pesa G2 Portal: org.ke.m-pesa.com
  • Safaricom Retail Shop: Walk in to any branch

What This Means for Developers Building Payment Platforms

If you’re building a SaaS, lending platform, payroll system, or anything that needs to collect money from users and also send money out, the Business One Account should be your default setup. Here’s why:

No more float management headaches. You don’t need to pre-fund a separate B2C account. Customer payments become your disbursement float automatically.

One shortcode to manage. One set of API credentials, one set of callbacks, one statement. Your reconciliation logic is simpler because everything flows through a single shortcode.

Faster disbursements. Instead of waiting for bank float deposits to clear (up to 3 days for cheques), you can disburse immediately from incoming C2B payments.

No B2B API dependency. You don’t need to whitelist and integrate the B2B API just to move money between your own shortcodes. That removes an entire layer of complexity and potential 404.001.03 errors from your architecture.

Use cases that benefit most:

  • Property management (collect rent, pay landlords) — this is what PropFlow does
  • Lending platforms (collect repayments, disburse loans)
  • Payroll systems (collect client payments, disburse salaries)
  • Insurance (collect premiums, settle claims)
  • SACCOs and MFIs (collect deposits, disburse withdrawals)
  • Government and NGOs (collect revenue, disburse project funds)

The Operator Roles You Should Know About

Once your Business One Account is set up, the G2 portal gives you four operator roles:

Business Administrator creates and manages users. This is your admin-level access.

Business Manager can view statements, initiate single and bulk B2C transactions, approve or reject disbursements, and withdraw funds from M-Pesa to the bank. This is the role you want for your finance team or the person who approves payouts.

Business Web Operator can do everything the Business Manager does except approve/reject transactions and withdraw to bank. This is good for your operations team who initiates payments but shouldn’t have final approval.

Business Auditor has read-only access to statements. Perfect for compliance or external auditors.

Adding the Business One Account product doesn’t interfere with any existing operator roles on your shortcode, so your current setup stays intact.


The Architecture I’d Recommend

For any developer building a platform like PropFlow, here’s the architecture that works:

┌─────────────────────────────────────────┐ │ Your Application (Next.js) │ ├──────────────┬──────────────────────────┤ │ Collection │ Disbursement │ │ │ │ │ STK Push │ B2C API │ │ (tenant │ (pay landlord’s │ │ pays rent) │ M-Pesa) │ │ │ │ │ C2B │ B2C to Bank │ │ Callback │ (future: pay │ │ (confirm │ landlord’s bank) │ │ payment) │ │ ├──────────────┴──────────────────────────┤ │ Single Paybill — Business One │ │ Account (C2B + B2C enabled) │ │ │ │ Float auto-recycles: │ │ C2B payments → available for B2C │ └─────────────────────────────────────────┘

Your application handles the business logic (matching payments to tenants, calculating disbursements), and the Business One Account handles the money movement in both directions through a single shortcode.


Lessons Learned

First, ask for Business One Account from the start. If you’re applying for a new Paybill and you know you’ll need both collection and disbursement, request it during onboarding. Don’t apply for C2B first and try to add B2C later. It’s easier to get both set up together.

Second, understand the Working Account vs Utility Account distinction. Even with Business One Account, it helps to know that these two accounts exist inside your shortcode. When debugging, check both balances on the G2 portal. If your B2C is failing, the first thing to check is whether the Utility Account has sufficient float.

Third, the G2 portal is your friend. You can view statements, check balances, manage operators, and initiate manual transactions at org.ke.m-pesa.com. Bookmark it. You’ll use it more than the Daraja portal once you’re live.

Fourth, this information is hard to find. The Business One Account product guide is a Safaricom internal document. Most developers don't know it exists. Most tutorials only cover the API integration and assume you've figured out the business account setup. Hopefully this post fills that gap.


Boniface Muchendu

Boniface Muchendu

Full-stack developer based in Nairobi. I build software for African businesses and have integrated M-Pesa’s Daraja API in production across multiple applications, including PropFlow and DukaSale.

Need help with M-Pesa integration?

I’ve been through the pain so you don’t have to.

Get in touch →