<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Emmanuel Mwendwa]]></title><description><![CDATA[Emmanuel Mwendwa]]></description><link>https://blog.mwendwa.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 14 May 2026 23:15:14 GMT</lastBuildDate><atom:link href="https://blog.mwendwa.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Solving Dynamic Scheduling for Frappoint]]></title><description><![CDATA[Scheduling appointments in businesses can quickly become complex. Different services take different amounts of time, multiple providers offering the same service may have varying availability, and managing overlapping bookings can be a nightmare.
Whi...]]></description><link>https://blog.mwendwa.dev/solving-dynamic-scheduling-for-frappoint</link><guid isPermaLink="true">https://blog.mwendwa.dev/solving-dynamic-scheduling-for-frappoint</guid><category><![CDATA[frappoint]]></category><category><![CDATA[appointment booking]]></category><category><![CDATA[appointment booking software]]></category><dc:creator><![CDATA[Coiled Coder]]></dc:creator><pubDate>Mon, 09 Feb 2026 05:27:14 GMT</pubDate><content:encoded><![CDATA[<p>Scheduling appointments in businesses can quickly become complex. Different services take <em>different amounts of time,</em> <em>multiple providers</em> offering the same service may have varying <strong><em>availability</em></strong>, and managing <strong><em>overlapping bookings</em></strong> can be a nightmare.</p>
<p>While building <strong>Frappoint</strong>, this was the hardest challenge I had to overcome. Instead of defining static duration’s for every available service and provider, I needed scheduling to be “<em>alive</em>” to <strong><em>adapt</em></strong> whenever new services, providers, or resources were added. I wanted the system to <strong>evolve</strong> with changes instead of freezing or breaking down.</p>
<h2 id="heading-the-problem">The Problem</h2>
<ul>
<li><p>Services have different duration’s ( e.g., haircut (30m) vs. hair treatment (60m)).</p>
</li>
<li><p>Providers have <strong>individual schedules</strong> and varying services they offer.</p>
</li>
<li><p>Logical Resources to be used when offering the service (e.g., clippers, massage tables).</p>
</li>
<li><p>Avoiding the possibility of double-booking is critical.</p>
</li>
<li><p>Reducing manual scheduling to reduce manual errors and overhead</p>
</li>
</ul>
<p>Traditional scheduling approaches (static tables and manual blocks) weren't flexible enough. I needed a system that could <strong>dynamically calculate availability</strong> in real-time.</p>
<h2 id="heading-introducing-slots">Introducing Slots</h2>
<p>The concept that helped me crack this problem was simple but powerful: <strong>slots</strong>.</p>
<p>Think of them as <em>dynamic time units</em> that combine:</p>
<ol>
<li><strong>Service Durations</strong> - Every service has a duration,  which for me I went with a uniformity of minutes</li>
<li><strong>Provider Allocation</strong> - Each provider has a timeline (e.g.,  Shift 9 AM - 5 PM) and a set of services they can perform.</li>
<li><strong>Service Unit / Resources</strong> - Logical shared resource for performing the service (Clippers for haircut and such)</li>
</ol>
<p>Combining these three we get a <strong>slot</strong>, a bookable time unit.</p>
<p><em>It defines when the service can be performed, who can perform the it and what resources are required.</em> </p>
<p>These slots are then split into <em>chunks</em> of (10, 15, 30 mins depending on your setup) that can be <strong>combined into a single booked unit</strong> for a client. This approach ensures:</p>
<ul>
<li>Providers are never double-booked.</li>
<li>Resources are allocated efficiently.</li>
<li>Availability automatically adapts as services or providers are added or removed.</li>
</ul>
<h2 id="heading-how-it-works-in-practice">How It Works in Practice</h2>
<p>Imagine a haircut service (30 minutes) offered by Jane and John:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Provider</td><td>Service</td><td>Duration</td><td>Available Slots</td></tr>
</thead>
<tbody>
<tr>
<td>Jane</td><td>Haircut</td><td>30 min</td><td>9:00, 9:30, 10:00...</td></tr>
<tr>
<td>John</td><td>Haircut</td><td>30 min</td><td>10:00, 10:30, 11:00...</td></tr>
</tbody>
</table>
</div><p><em>Jane and John's slots are calculated dynamically</em>, so if Jane is already booked at <strong>9:30</strong> that slot disappears from the list of available bookings. </p>
<h2 id="heading-lessons-learned">Lessons Learned</h2>
<p>Working on this feature taught me to:</p>
<ul>
<li><strong>Think in units of time, not just appointments.</strong> Breaking schedules into slots to make everything more flexible.</li>
<li><strong>Separate concerns.</strong> Services, providers, and resources each have their own logic. </li>
</ul>
]]></content:encoded></item><item><title><![CDATA[💯 A Simple Process for Getting Daraja API Credentials]]></title><description><![CDATA[So you’re building an app or system that needs to talk to M-Pesa — nice! Safaricom’s Daraja API is your gateway to sending, receiving and checking M-Pesa transactions. But before your app can say hello to M-Pesa, you need something important: API cre...]]></description><link>https://blog.mwendwa.dev/a-simple-process-for-getting-daraja-api-credentials</link><guid isPermaLink="true">https://blog.mwendwa.dev/a-simple-process-for-getting-daraja-api-credentials</guid><category><![CDATA[lipa na mpesa]]></category><category><![CDATA[daraja-api]]></category><category><![CDATA[MPesa]]></category><dc:creator><![CDATA[Coiled Coder]]></dc:creator><pubDate>Fri, 30 May 2025 06:28:14 GMT</pubDate><content:encoded><![CDATA[<p>So you’re building an app or system that needs to talk to M-Pesa — nice! <a target="_blank" href="https://developer.safaricom.co.ke/">Safaricom’s Daraja API</a> is your gateway to sending, receiving and checking M-Pesa transactions. But before your app can say hello to M-Pesa, you need something important: <strong>API credentials.</strong></p>
<p>So let’s investigate and see what they are, how they are used and what they represent ☕️.</p>
<h2 id="heading-what-are-api-credentials-and-why-are-they-important">What are API Credentials and Why are they Important❓️</h2>
<p>Think of it like this:</p>
<blockquote>
<p>When you log in to a website e.g., <a target="_blank" href="https://hashnode.com/onboard?loginWithEmail=true">Hashnode</a>, you use your email and password.</p>
<p>When your <strong>app logs in to Safaricom, it uses the Consumer Key(email) and Consumer Secret(password).</strong></p>
</blockquote>
<p>These are used as security mechanisms to authenticate (<em>identify your app</em>) and authorize (<em>prove that it has permission</em>) to access the Safaricom M-Pesa services on your behalf.</p>
<p>In the case of <strong>Daraja API (M-Pesa),</strong> the API credentials usually include:</p>
<ul>
<li><p>Consumer Key (username/email)</p>
</li>
<li><p>Consumer Secret (password)</p>
</li>
</ul>
<p>They are used to:</p>
<ul>
<li><p><strong>Authenticate your app</strong> — so safaricom knows who’s calling their services</p>
</li>
<li><p><strong>Get access tokens</strong> — which are temporary “passes/tickets” that let your app make secure requests</p>
</li>
<li><p><strong>Protect the system</strong> — only authorized apps can trigger requests e.g., STK Push.</p>
</li>
</ul>
<p>🧪 <strong>In Sanbox (Testing):</strong></p>
<p>They help you test M-Pesa operations without using real money. It’s safe for developers to experiment and build.</p>
<p>💵 <strong>In Production (Live):</strong></p>
<p>They allow real money transactions. Since money is involved they are tightly controlled and require approval before use.</p>
<p>📝 <strong>Important</strong></p>
<ul>
<li><p>Keep them secret (never share or expose them publicly).</p>
</li>
<li><p>Store them securely (in .env variables or secret managers).</p>
</li>
<li><p>They are <strong>per app</strong> — generate separate credentials for each shortcode/application.</p>
</li>
</ul>
<h2 id="heading-how-do-we-get-these-credentials">🔍️ How do we Get These Credentials</h2>
<h3 id="heading-1-sign-up-for-a-safaricom-developer-account">1️⃣ Sign up for a Safaricom Developer Account</h3>
<p>Whether you’re testing or going live, everything starts here:</p>
<ol>
<li><p>Head over to <a target="_blank" href="https://developer.safaricom.co.ke">https://developer.safaricom.co.ke</a></p>
</li>
<li><p>Click <strong>Sign Up</strong> (or <strong>Login</strong> if you already have an account)</p>
</li>
<li><p>Fill in your details — KYC (Know Your Customer) process</p>
</li>
<li><p>Once you’re in, you’re now officiall a Safaricom developer 🎊</p>
</li>
</ol>
<h3 id="heading-2-get-sandbox-credentials">2️⃣ Get Sandbox Credentials</h3>
<p>This is the staging area, here you get to play around, test your code/app, break stuff (safely), and make sure everything works before going live.</p>
<ol>
<li><p>In the developer portal, go to <strong>My Apps</strong></p>
</li>
<li><p>Click <strong>Create a new app</strong></p>
</li>
<li><p>Give your app a name e.g., My App :)</p>
</li>
<li><p>Create App</p>
</li>
</ol>
<p>A new application is created and you’ll see the <strong>Consumer Key</strong> and <strong>Consumer Secret</strong> in the app.</p>
<p>Use these credentials to move around funds, don’t worry any money you spend on sandbox will be reimbursed.</p>
<h3 id="heading-3-apply-for-production-credentials">3️⃣ Apply for Production Credentials</h3>
<p>Now you’re confident in your integration (or no callback requests from sandbox is now getting on your nerves 😠), it’s time to go live and make real transactions.</p>
<p>🖐🏿 Hold your horses, confirm if you have these:</p>
<ol>
<li><p>A registered Company</p>
</li>
<li><p>Registered Shortcode (Paybill or Till Number)</p>
</li>
<li><p>Access to <a target="_blank" href="https://org.ke.m-pesa.com/">M-Pesa Org Portal</a> (will be sent to your after registering shortcode)</p>
</li>
</ol>
<p>🟩 Confirmed the above, here’s what you need to do:</p>
<ol>
<li><p>In the developer portal click the <strong>Go Live</strong> tab</p>
</li>
<li><p>You’ll be asked to provide a few things:</p>
<ul>
<li><p>Organization Short Code</p>
</li>
<li><p>Organization name</p>
</li>
<li><p>M-Pesa Username</p>
</li>
</ul>
</li>
<li><p>Safaricom will review your app manually — this can take a few hours to a few days.</p>
</li>
</ol>
<p>If everything checks out, you’ll be issued <strong>Prod-App</strong> which will contain live credentials — 🤝🏾 welcome to the big leagues.</p>
<p>Two emails will be shared with you i.e., one containing <strong>Passkey</strong> and some information on your live application, the other containing <strong>live/prod api urls.</strong></p>
<h2 id="heading-one-more-thing-security-credentials">☝🏿One More Thing — ( Security Credentials)</h2>
<p>For some APIs (i.e., B2C), you’ll also need to generate a <strong>Security Credential</strong> to encrypt sensitive data, which is generated from <strong>Initiator Password.</strong></p>
<p>Don’t worry I got you — <a target="_blank" href="https://hashnode.com/post/cmaxzv2i0001g09lb2x4k3z9x">How to Get Initiator Name and Password</a></p>
<h2 id="heading-final-thoughts">💭 Final Thoughts</h2>
<ul>
<li><p>Use sandbox to test everything first — it’s a lifesaver.</p>
</li>
<li><p>Keep your credentials secret — don’t commit them to GitHub!</p>
</li>
<li><p>Set up a public server or tunnel (ngrok) for your callbacks during testing.</p>
</li>
<li><p>Read the docs.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[🔐How to Get Your Daraja API Initiator Password]]></title><description><![CDATA[If you're integrating Safaricom M-Pesa's Daraja API for (B2C, B2B, Transaction Status, Reversals) you'll need an Initiator Password.
For many of you like me, getting this password feels like unlocking a secret level in a game. It's one of those secur...]]></description><link>https://blog.mwendwa.dev/how-to-get-your-daraja-api-initiator-password</link><guid isPermaLink="true">https://blog.mwendwa.dev/how-to-get-your-daraja-api-initiator-password</guid><category><![CDATA[daraja]]></category><category><![CDATA[daraja-api]]></category><category><![CDATA[MPesa]]></category><dc:creator><![CDATA[Coiled Coder]]></dc:creator><pubDate>Wed, 21 May 2025 13:44:13 GMT</pubDate><content:encoded><![CDATA[<p>If you're integrating <strong>Safaricom M-Pesa's Daraja API</strong> for (<strong>B2C, B2B, Transaction Status,</strong> <strong>Reversals</strong>) you'll need an <strong>Initiator Password.</strong></p>
<p>For many of you like me, getting this password feels like unlocking a secret level in a game. It's one of those security layers provided by Safaricom that isn't handed to you by default, and the steps to get it aren't always clearly documented.</p>
<p>Let's walk through how to understand what it is, who manages it, and how to get it -- all from the <strong>M-Pesa Org Portal</strong>.</p>
<h2 id="heading-prerequisites">📘Prerequisites</h2>
<p>Before we begin, ensure you have the following:</p>
<p>* A registered <strong>Paybill/Till</strong> with M-Pesa</p>
<p>* Access to the <strong>M-Pesa Business Portal</strong> <a target="_blank" href="https://org.ke.m-pesa.com/">https://org.ke.m-pesa.com/</a></p>
<h2 id="heading-what-is-the-initiator-password">🔑 What is the Initiator Password?</h2>
<hr />
<p>\&gt; The <strong>Initiator Password</strong> is a <strong>sensitive credential</strong> used in M-Pesa APIs that perform transactions, such as transferring funds to customers or other businesses.</p>
<p>It is not the same as your <strong>consumer secret</strong> (used in standard Daraja authentication) nor is it the web portal password for logging in.</p>
<p>The Initiator Password is: * Tied to a specific <strong>Initiator Name</strong> (a type of user/operator on your shortcode) * Used in API requests as the <code>SecurityCredential</code> parameter * That is after being encrypted using Safaricom's <strong>public security certificate</strong></p>
<h2 id="heading-who-is-the-api-operator-initiator">👤Who Is the API Operator / Initiator?</h2>
<p>Good question. To understand this first we need to understand <strong>user roles</strong> in the M-Pesa Business Org Portal.</p>
<p>We'll have a look at the 3 main operators: * Business Administrator * Business Manager * Business Web Operator (API Operator)</p>
<h4 id="heading-1-business-administrator">🤵🏿 1. Business Administrator</h4>
<p>This is the person/user who signed up for the short code. Safaricom creates this user when the shortcode is first registered.</p>
<p>The primary role of this user is to manage other users(operators) within the organization. * Creating and managing all other users * Assigning roles and permissions * Resetting passwords and unlocking accounts</p>
<p>\&gt; They are essentially the gatekeepers of the entire M-Pesa org account.</p>
<h4 id="heading-2-business-manager">📊 2. Business Manager</h4>
<p>This is the user who: * Approves transactions * Monitors balances * Accesses statements.</p>
<p>\&gt; He'll play a crucial part later don't forget about him.</p>
<h4 id="heading-3-business-web-operator-api-operator-initiator">🌐 3. Business Web Operator (API Operator / Initiator)</h4>
<p>This is the user we are more interested in today. They are responsible for API integrations and once created, they become known as: <strong>the Initiator</strong> 👻</p>
<ul>
<li><p>Provides a layer of authentication</p>
</li>
<li><p>Can initiate API transactions (B2C, B2B, Reversal, etc.)</p>
</li>
<li><p>Cannot log in to the web portal (API-only access)</p>
</li>
</ul>
<blockquote>
<p>This Initiator Name + Password combo is what the Daraja API expects for secure operations.</p>
</blockquote>
<h2 id="heading-how-to-get-the-initiator-password">🛠️ How to Get the Initiator Password.</h2>
<ol>
<li><p>Ask the Business Administrator 🤵🏿 to Log In They should go to the <a target="_blank" href="https://org.ke.m-pesa.com/">M-Pesa Org Portal</a> and log in with their credentials.</p>
</li>
<li><p>Create two Operators (Business Manager 📊, Web Operator🌐)</p>
</li>
</ol>
<ul>
<li><p>Go to Operator Management</p>
</li>
<li><p>Create a new user with the role: Business Manager</p>
</li>
<li><p>Assign them appropriate roles: <strong>Add them later</strong></p>
</li>
<li><p>Repeat the process but role is: Business Web Operator</p>
</li>
<li><p>Assign them appropriate roles: <strong>Add them later</strong></p>
</li>
</ul>
<blockquote>
<p>The Business Manager and Web Operator roles cannot belong to a single user.</p>
<p>Something interesting to note here is the <strong>Set Password</strong> section of the Web Operator is greyed out and the operator is in a <strong>Pending State</strong>. Weird right 🙃</p>
</blockquote>
<ol start="3">
<li>To activate the Web API Operator</li>
</ol>
<ul>
<li><p>Log in as the Business Manager</p>
</li>
<li><p>Access the Operators tab</p>
</li>
<li><p>Select the Web Operator</p>
</li>
<li><p>Set the password for the Operator</p>
</li>
</ul>
<blockquote>
<p>The set password is now a green hue (enabled) The Business Manager is primarily responsible for setting the initiator password. Note: the password should be limited to specific special characters (<strong>#, &amp;, %, $</strong>) other characters are not accepted as special 😏 including <strong>@</strong></p>
</blockquote>
<hr />
<h3 id="heading-now-we-have-the-initiator-password-what-next">Now we have the Initiator Password. What next 🤷🏿</h3>
<hr />
<h2 id="heading-encrypting-the-initiator-password">🔒 Encrypting the Initiator Password</h2>
<p>Step 1: Using the <a target="_blank" href="https://developer.safaricom.co.ke/TestCredentials">Daraja Developer Portal Test Credentials</a>:</p>
<ul>
<li><p>Select environment (Production) for live credentials</p>
</li>
<li><p>Enter your <strong>Initiator Password</strong></p>
</li>
<li><p>Click <strong>Generate</strong></p>
</li>
<li><p>Easy peesy now you have your <strong>Security Credential</strong></p>
</li>
</ul>
<p>Step: 2: Using Code Download the public certificate (available on the <a target="_blank" href="https://developer.safaricom.co.ke/Documentation">Daraja Developer Portal</a>) to encrypt the password.</p>
<p>Follow the provided guide on the <a target="_blank" href="https://developer.safaricom.co.ke/Documentation">Daraja Developer Portal</a> to figure out how to encrypt it.</p>
<h2 id="heading-final-notes">✅ Final Notes</h2>
<ul>
<li><p>Always <strong>encrypt</strong> the Initiator Password before using it in a transaction request</p>
</li>
<li><p>Never hardcode the raw password in your source code</p>
</li>
<li><p>If the password is lost, the Admin must reset it via the Org Portal</p>
</li>
</ul>
<h2 id="heading-still-confused">🙋🏿 Still Confused?</h2>
<p>If you're unsure whether you're using the right initiator Name, or if your password keeps giving <code>"The Initiator information is invalid"</code> errors -- double-check:</p>
<ul>
<li><p>The user role and permissions</p>
</li>
<li><p>The shortcode being used</p>
</li>
<li><p>The encryption process</p>
</li>
</ul>
<p>You can also contact Safaricom M-Pesa Business Support via: <a target="_blank" href="mailto:m-pesabusiness@safaricom.co.ke">m-pesabusiness@safaricom.co.ke</a></p>
<p>Or Safaricom API Team via: <a target="_blank" href="mailto:apisupport@safaricom.co.ke">apisupport@safaricom.co.ke</a></p>
<h2 id="heading-references">References:</h2>
<p>[1]: <a target="_blank" href="https://developer.safaricom.co.ke/APIs/BusinessToCustomer">Daraja API portal B2C</a><br />[2]: <a target="_blank" href="https://www.safaricom.co.ke/main-mpesa/for-your-business/business-channels#:~:text=A%20Business%20Web%20Operator%20who,checks%20balances%2C%20and%20access%20statements.">M-Pesa Business Channels and Portals</a><br />[3]: <a target="_blank" href="https://pay.m-pesaforbusiness.co.ke/">M-Pesa Business</a></p>
]]></content:encoded></item></channel></rss>