{"id":397704,"date":"2026-11-02T09:01:32","date_gmt":"2026-11-02T09:01:32","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/pesapulse-billing\/"},"modified":"2026-11-02T09:00:54","modified_gmt":"2026-11-02T09:00:54","slug":"pesapulse-billing","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/pesapulse-billing\/","author":23586214,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.1.0","stable_tag":"1.1.0","tested":"7.1.4","requires":"6.2","requires_php":"8.0","requires_plugins":null,"header_name":"PesaPulse Billing","header_author":"Jaydee Innovation Hub","header_description":"Recurring subscription billing for M-Pesa (Safaricom Daraja): idempotent C2B and STK Push webhooks, strict account-reference matching, an isolated ledger, automatic grace-period enforcement and access control.","assets_banners_color":"79ae8c","last_updated":"2026-11-02 09:00:54","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/jaytechkenya.com\/pesapulse","header_author_uri":"https:\/\/jaytechkenya.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":109,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.1.0":{"tag":"1.1.0","author":"jmwatee","date":"2026-11-02 09:00:54","revision":3779340}},"upgrade_notice":{"1.1.0":"<p>Reminders (SMS, WhatsApp, webhooks) now come with PesaPulse Pro. Your existing settings are kept and become active as soon as Pro is installed.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3779340,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3779340,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3779340,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3779340,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.1.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3779386,"resolution":"1","location":"assets","locale":"","width":1270,"height":252},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3779386,"resolution":"2","location":"assets","locale":"","width":1255,"height":976},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3779386,"resolution":"3","location":"assets","locale":"","width":1591,"height":950},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3779386,"resolution":"4","location":"assets","locale":"","width":1270,"height":232}},"screenshots":{"1":"Dashboard: active, grace and suspended counts, collections, suspense queue and callback URLs.","2":"Subscriptions list with status, paid-until date and credit.","3":"A subscription's journal and M-Pesa receipts.","4":"Suspense queue: assign a mistyped payment in one click.","5":"The customer page with Pay now (STK Push).","6":"Settings: Daraja credentials, account matching and grace periods."}},"plugin_section":[],"plugin_tags":[15149,37731,3050,32529,4079],"plugin_category":[41,45],"plugin_contributors":[287662],"plugin_business_model":[],"class_list":["post-397704","plugin","type-plugin","status-publish","hentry","plugin_tags-billing","plugin_tags-kenya","plugin_tags-mpesa","plugin_tags-recurring-payments","plugin_tags-subscriptions","plugin_category-communication","plugin_category-ecommerce","plugin_contributors-jmwatee","plugin_committers-jmwatee"],"banners":{"banner":"https:\/\/ps.w.org\/pesapulse-billing\/assets\/banner-772x250.png?rev=3779340","banner_2x":"https:\/\/ps.w.org\/pesapulse-billing\/assets\/banner-1544x500.png?rev=3779340","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/pesapulse-billing\/assets\/icon-128x128.png?rev=3779340","icon_2x":"https:\/\/ps.w.org\/pesapulse-billing\/assets\/icon-256x256.png?rev=3779340","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/pesapulse-billing\/assets\/screenshot-1.png?rev=3779386","caption":"Dashboard: active, grace and suspended counts, collections, suspense queue and callback URLs."},{"src":"https:\/\/ps.w.org\/pesapulse-billing\/assets\/screenshot-2.png?rev=3779386","caption":"Subscriptions list with status, paid-until date and credit."},{"src":"https:\/\/ps.w.org\/pesapulse-billing\/assets\/screenshot-3.png?rev=3779386","caption":"A subscription's journal and M-Pesa receipts."},{"src":"https:\/\/ps.w.org\/pesapulse-billing\/assets\/screenshot-4.png?rev=3779386","caption":"Suspense queue: assign a mistyped payment in one click."}],"raw_content":"<!--section=description-->\n<p>PesaPulse Billing turns WordPress into a billing desk for any business that collects recurring payments through M-Pesa. ISPs, water vendors, gyms, schools, landlords, SaaS and membership sites can all use it.<\/p>\n\n<p>Each customer gets an account number. When they pay to your Paybill or Till with that account number, or tap <strong>Pay now<\/strong> on their account page, Safaricom notifies your site. PesaPulse credits the right customer and extends their subscription without anyone reconciling statements by hand.<\/p>\n\n<h4>What it does<\/h4>\n\n<ul>\n<li><strong>M-Pesa C2B and STK Push.<\/strong> Paybill or Buy Goods (Till), through your own Safaricom Daraja app.<\/li>\n<li><strong>Strict matching.<\/strong> Account numbers carry a check digit that catches every single-digit typo and every swapped pair of digits. A mistyped payment goes to a suspense queue for review instead of being credited to the wrong customer.<\/li>\n<li><strong>Never counted twice.<\/strong> Each M-Pesa receipt is stored under a unique constraint, so repeated or replayed callbacks can't credit a payment twice.<\/li>\n<li><strong>Isolated ledger.<\/strong> Payments, balances and history live in dedicated database tables, not in user or post meta, with an append-only journal for every payment, charge and adjustment.<\/li>\n<li><strong>Prepaid credit.<\/strong> Partial payments accumulate. Overpayments buy several billing cycles.<\/li>\n<li><strong>Grace periods and suspension.<\/strong> A background job moves overdue accounts to grace, then to suspended. Paying restores access instantly.<\/li>\n<li><strong>Access control without database writes.<\/strong> Suspended customers lose the capabilities or URL paths you choose. Nothing is written to their user record.<\/li>\n<li><strong>Know who is overdue.<\/strong> The dashboard and subscription list show who is active, in grace or suspended, with their paid-until date and the amount due.<\/li>\n<li><strong>Customer page.<\/strong> The <code>[pesapulse_account]<\/code> shortcode shows each customer's plan, account number, paid-until date and a Pay now (STK Push) button.<\/li>\n<li><strong>Admin screens<\/strong> for subscriptions, transactions, the suspense queue and the notification log, plus WP-CLI commands for operations and testing.<\/li>\n<\/ul>\n\n<h4>Plans and pricing<\/h4>\n\n<p>PesaPulse Billing is free, with no limits on customers, payments or sites. Everything listed above works without paying anything, and nothing stops working after a trial period.<\/p>\n\n<p>PesaPulse shows you who is overdue. <strong>PesaPulse Pro<\/strong>, a separate paid add-on that is not hosted on WordPress.org, chases them for you:<\/p>\n\n<ul>\n<li>automatic SMS reminders (Africa's Talking) and WhatsApp reminders (Meta WhatsApp Cloud API) before the due date, during grace and on suspension, plus payment receipts<\/li>\n<li>signed outbound webhooks to any SMS gateway, CRM or automation tool<\/li>\n<li>revenue and arrears reports, CSV export and bulk customer import<\/li>\n<\/ul>\n\n<p>Pro is sold per website. Current pricing is on <a href=\"https:\/\/jaytechkenya.com\/pesapulse\">jaytechkenya.com\/pesapulse<\/a>. This plugin contains no Pro code, no locked features and no upgrade prompts outside its own Settings page and Plugins screen. The PesaPulse dashboard also shows a small note linking to two other products by the same author, ElimuSMS (school billing) and RetailPulse (retail and inventory). Click <strong>Hide<\/strong> to remove it for good. It loads nothing from outside your site and tracks nothing.<\/p>\n\n<h4>Your accounts, your money<\/h4>\n\n<p>PesaPulse doesn't process payments itself and never routes money through a third party. You enter your own Safaricom Daraja credentials, which are stored encrypted in your database. Payments go straight from your customers to your Paybill or Till.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin connects to the services below, and only when you have configured them with your own credentials.<\/p>\n\n<h4>Safaricom Daraja API (M-Pesa)<\/h4>\n\n<p>Used to receive M-Pesa payments and to start STK Push payment prompts.<\/p>\n\n<ul>\n<li><strong>When:<\/strong> whenever you test credentials or register callback URLs in the admin, when a customer clicks Pay now, and whenever Safaricom sends payment notifications to your site.<\/li>\n<li><strong>Data sent:<\/strong> your Daraja consumer key and secret (to obtain an access token), your shortcode, your callback URLs, and for STK Push the customer's phone number, the amount and their account reference.<\/li>\n<li><strong>Endpoints:<\/strong> <code>https:\/\/sandbox.safaricom.co.ke<\/code> (sandbox) and <code>https:\/\/api.safaricom.co.ke<\/code> (production).<\/li>\n<li>Provided by Safaricom PLC: <a href=\"https:\/\/developer.safaricom.co.ke\">Daraja developer portal and terms of use<\/a>, <a href=\"https:\/\/www.safaricom.co.ke\/images\/Safaricom-Data-Privacy-Statement-updated.pdf\">Data privacy statement<\/a>.<\/li>\n<\/ul>\n\n<h4>No other services<\/h4>\n\n<p>This plugin makes no other remote requests. It has no tracking and no analytics, and it never contacts Jaydee Innovation Hub.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate the plugin.<\/li>\n<li>Go to <strong>Settings \u2192 Permalinks<\/strong> and choose any option except \"Plain\". M-Pesa callbacks need clean URLs.<\/li>\n<li>Create an app at <a href=\"https:\/\/developer.safaricom.co.ke\">developer.safaricom.co.ke<\/a>. Under <strong>PesaPulse \u2192 Settings<\/strong>, enter its consumer key, consumer secret and passkey, and your Paybill or Till number.<\/li>\n<li>On <strong>PesaPulse \u2192 Dashboard<\/strong>, click <strong>Test Daraja credentials<\/strong>, then <strong>Register C2B URLs<\/strong>. Your site must be reachable over public HTTPS.<\/li>\n<li>Create a page containing <code>[pesapulse_account]<\/code> and enter its URL as the <strong>Renewal page URL<\/strong> in Settings.<\/li>\n<li>Add customers under <strong>PesaPulse \u2192 Subscriptions<\/strong> and give each one their account number.<\/li>\n<li>Recommended: disable WP-Cron's traffic-based trigger (<code>define( 'DISABLE_WP_CRON', true );<\/code>) and run <code>wp cron event run --due-now<\/code> every 5 minutes from a system cron, so expiry is enforced on time.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20need%20a%20safaricom%20daraja%20account%3F\"><h3>Do I need a Safaricom Daraja account?<\/h3><\/dt>\n<dd><p>Yes. PesaPulse uses your own Daraja app and shortcode. Sandbox works for testing.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20a%20till%20%28buy%20goods%29%20number%3F\"><h3>Does it work with a Till (Buy Goods) number?<\/h3><\/dt>\n<dd><p>Yes. Choose <strong>Buy Goods (Till)<\/strong> as the shortcode type and enter your store number for STK Push.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20a%20customer%20types%20the%20wrong%20account%20number%3F\"><h3>What happens if a customer types the wrong account number?<\/h3><\/dt>\n<dd><p>The check digit rejects it. If Safaricom has enabled External Validation on your shortcode, the payment is refused before any money moves. Otherwise it lands in <strong>Transactions \u2192 Suspense<\/strong>, where you assign it to the right account in one click.<\/p><\/dd>\n<dt id=\"can%20the%20same%20payment%20be%20counted%20twice%3F\"><h3>Can the same payment be counted twice?<\/h3><\/dt>\n<dd><p>No. Every M-Pesa receipt code is unique in the database, and every journal entry is unique per transaction. Replayed and concurrent callbacks are ignored.<\/p><\/dd>\n<dt id=\"is%20my%20customers%27%20data%20sent%20anywhere%3F\"><h3>Is my customers' data sent anywhere?<\/h3><\/dt>\n<dd><p>Only to Safaricom, as described under \"External services\" below. PesaPulse has no tracking or analytics, and it doesn't phone home.<\/p><\/dd>\n<dt id=\"does%20the%20free%20plugin%20send%20reminders%3F\"><h3>Does the free plugin send reminders?<\/h3><\/dt>\n<dd><p>No. The free plugin tracks who is due, in grace or suspended, and pauses and restores access automatically. Automatic SMS and WhatsApp reminders are part of PesaPulse Pro (see \"Plans and pricing\").<\/p><\/dd>\n<dt id=\"does%20it%20work%20behind%20cloudflare%20or%20a%20reverse%20proxy%3F\"><h3>Does it work behind Cloudflare or a reverse proxy?<\/h3><\/dt>\n<dd><p>Yes. Set <strong>Trusted client-IP header<\/strong> in Settings so the optional Safaricom IP allowlist sees the real caller.<\/p><\/dd>\n<dt id=\"where%20do%20i%20get%20support%3F\"><h3>Where do I get support?<\/h3><\/dt>\n<dd><p>Free support is on the WordPress.org support forum for this plugin. Pro customers get priority email support.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Dashboard: a small, hideable note linking to ElimuSMS and RetailPulse.<\/li>\n<li>Reminder channels (SMS, WhatsApp and outbound webhooks) moved to the separate PesaPulse Pro add-on. Payments, matching, grace periods and access control remain free.<\/li>\n<li>Extension points for add-ons: <code>pesapulse_settings_fields<\/code>, <code>pesapulse_settings_sections<\/code>, <code>pesapulse_channels<\/code>.<\/li>\n<li>Text domain is now <code>pesapulse-billing<\/code>.<\/li>\n<li>Settings page lists the external accounts you need.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>First release.<\/li>\n<\/ul>","raw_excerpt":"Recurring billing for businesses paid by M-Pesa. Payments match the right customer automatically, and access pauses and restores on time.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/397704","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=397704"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/jmwatee"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=397704"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=397704"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=397704"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=397704"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=397704"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=397704"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}