<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Sospeter Mong'are</title>
    <description>The latest articles on Forem by Sospeter Mong'are (@msnmongare).</description>
    <link>https://forem.com/msnmongare</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F117091%2F89122cee-2645-481e-b979-f96819dc9d1b.jpeg</url>
      <title>Forem: Sospeter Mong'are</title>
      <link>https://forem.com/msnmongare</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/msnmongare"/>
    <language>en</language>
    <item>
      <title>The Stages of AI in Software Engineering - And Where We Are Today</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Wed, 15 Apr 2026 11:36:28 +0000</pubDate>
      <link>https://forem.com/msnmongare/the-stages-of-ai-in-software-engineering-and-where-we-are-today-1odf</link>
      <guid>https://forem.com/msnmongare/the-stages-of-ai-in-software-engineering-and-where-we-are-today-1odf</guid>
      <description>&lt;p&gt;Software engineering hasn’t just evolved. It has accelerated.&lt;/p&gt;

&lt;p&gt;In the last couple of years, the way we build software has changed more than most people realize. Many developers are still operating in older patterns, while the ground beneath them has already shifted.&lt;/p&gt;

&lt;p&gt;To understand where we are going, it helps to break things down into stages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stage 1: Ask AI
&lt;/h2&gt;

&lt;p&gt;This is where it started for most people.&lt;/p&gt;

&lt;p&gt;AI was used like a smarter search engine. You would:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;paste an error&lt;/li&gt;
&lt;li&gt;ask for a function&lt;/li&gt;
&lt;li&gt;get a quick fix&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing about your workflow really changed.&lt;/p&gt;

&lt;p&gt;You were still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;thinking through the problem&lt;/li&gt;
&lt;li&gt;designing the solution&lt;/li&gt;
&lt;li&gt;writing most of the code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI was just helping with syntax and speed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stage 2: AI in Your Editor
&lt;/h2&gt;

&lt;p&gt;Then AI moved closer.&lt;/p&gt;

&lt;p&gt;Instead of switching tabs, it started living inside your editor. It could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;autocomplete your thoughts&lt;/li&gt;
&lt;li&gt;suggest full functions&lt;/li&gt;
&lt;li&gt;understand your code context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This felt powerful. And it was.&lt;/p&gt;

&lt;p&gt;But the control didn’t change.&lt;/p&gt;

&lt;p&gt;You were still driving.&lt;br&gt;
AI was just helping you move faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stage 3: Describe the Problem
&lt;/h2&gt;

&lt;p&gt;This is where the real shift began.&lt;/p&gt;

&lt;p&gt;Instead of asking:&lt;br&gt;
“How do I build this?”&lt;/p&gt;

&lt;p&gt;You started asking:&lt;br&gt;
“Here’s what I want. Build it.”&lt;/p&gt;

&lt;p&gt;The focus moved away from code and into clarity.&lt;/p&gt;

&lt;p&gt;You describe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the feature&lt;/li&gt;
&lt;li&gt;the behavior&lt;/li&gt;
&lt;li&gt;the expected outcome&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI handles the implementation.&lt;/p&gt;

&lt;p&gt;At this stage, your value is no longer how fast you can type.&lt;br&gt;
It’s how clearly you can think.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stage 4: Manage AI Agents (Where We Are Now)
&lt;/h2&gt;

&lt;p&gt;We are no longer just working with a single AI.&lt;/p&gt;

&lt;p&gt;We are starting to work with multiple agents at once.&lt;/p&gt;

&lt;p&gt;Instead of writing code line by line, you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;assign tasks&lt;/li&gt;
&lt;li&gt;run workflows in parallel&lt;/li&gt;
&lt;li&gt;review outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One agent can build a feature.&lt;br&gt;
Another writes tests.&lt;br&gt;
Another refactors existing code.&lt;/p&gt;

&lt;p&gt;This no longer feels like coding.&lt;/p&gt;

&lt;p&gt;It feels like managing a team.&lt;/p&gt;

&lt;p&gt;And that changes everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stage 5: Autonomous AI Systems (What’s Next)
&lt;/h2&gt;

&lt;p&gt;The next step is already taking shape.&lt;/p&gt;

&lt;p&gt;Agents won’t just work in parallel.&lt;br&gt;
They will work together.&lt;/p&gt;

&lt;p&gt;A single request could trigger a full pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;build&lt;/li&gt;
&lt;li&gt;test&lt;/li&gt;
&lt;li&gt;validate&lt;/li&gt;
&lt;li&gt;deploy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With little to no human interruption.&lt;/p&gt;

&lt;p&gt;Your role becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;defining requirements&lt;/li&gt;
&lt;li&gt;setting boundaries&lt;/li&gt;
&lt;li&gt;reviewing final outcomes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You are no longer in the loop at every step.&lt;br&gt;
You step in when it matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stage 6: Self-Evolving Systems (The Future)
&lt;/h2&gt;

&lt;p&gt;This is where things get even more interesting.&lt;/p&gt;

&lt;p&gt;Software will not just run.&lt;br&gt;
It will improve itself.&lt;/p&gt;

&lt;p&gt;Systems will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;learn from user behavior&lt;/li&gt;
&lt;li&gt;adjust features automatically&lt;/li&gt;
&lt;li&gt;optimize performance continuously&lt;/li&gt;
&lt;li&gt;refine their own logic over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Software becomes something closer to a living system.&lt;/p&gt;

&lt;p&gt;Not static. Not finished. Always adapting.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Means for Engineers
&lt;/h2&gt;

&lt;p&gt;The role of a software engineer is not disappearing.&lt;br&gt;
But it is changing.&lt;/p&gt;

&lt;p&gt;Less focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;writing every line of code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;defining problems clearly&lt;/li&gt;
&lt;li&gt;making architectural decisions&lt;/li&gt;
&lt;li&gt;validating outcomes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The bottleneck is no longer coding speed.&lt;/p&gt;

&lt;p&gt;It is thinking.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Shift
&lt;/h2&gt;

&lt;p&gt;AI didn’t remove the need for engineers.&lt;/p&gt;

&lt;p&gt;It exposed something deeper:&lt;/p&gt;

&lt;p&gt;If you cannot clearly explain what you want to build,&lt;br&gt;
AI will build the wrong thing faster.&lt;/p&gt;

&lt;p&gt;But if you can think clearly,&lt;br&gt;
AI becomes a multiplier.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;The best engineers in this new world will not be the fastest coders.&lt;/p&gt;

&lt;p&gt;They will be the clearest thinkers.&lt;/p&gt;

&lt;p&gt;Because in the end, AI executes.&lt;/p&gt;

&lt;p&gt;Humans decide what is worth building.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>beginners</category>
      <category>coding</category>
    </item>
    <item>
      <title>Understanding SOLID Principles in Object-Oriented Programming</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Mon, 13 Apr 2026 14:08:02 +0000</pubDate>
      <link>https://forem.com/msnmongare/understanding-solid-principles-in-object-oriented-programming-1l4g</link>
      <guid>https://forem.com/msnmongare/understanding-solid-principles-in-object-oriented-programming-1l4g</guid>
      <description>&lt;p&gt;When building software, especially in object-oriented languages like Java, writing code that works is only part of the job. The real challenge is writing code that is easy to maintain, extend, and scale over time. This is where SOLID principles come in.&lt;/p&gt;

&lt;p&gt;SOLID is not about how many classes you should have. Instead, it is a set of five design principles that guide how you structure and organize your classes for better software quality.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is SOLID?
&lt;/h2&gt;

&lt;p&gt;SOLID is an acronym representing five key principles of object-oriented design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single Responsibility Principle&lt;/li&gt;
&lt;li&gt;Open/Closed Principle&lt;/li&gt;
&lt;li&gt;Liskov Substitution Principle&lt;/li&gt;
&lt;li&gt;Interface Segregation Principle&lt;/li&gt;
&lt;li&gt;Dependency Inversion Principle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These principles help developers reduce complexity, improve readability, and make systems easier to modify without breaking existing functionality.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Single Responsibility Principle (SRP)
&lt;/h2&gt;

&lt;p&gt;A class should have only one reason to change, meaning it should handle only one responsibility.&lt;/p&gt;

&lt;p&gt;For example, a class that manages user data should not also handle logging or database connections. Separating responsibilities ensures that changes in one area do not affect unrelated parts of the system.&lt;/p&gt;

&lt;p&gt;This makes your code easier to debug and maintain.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Open/Closed Principle (OCP)
&lt;/h2&gt;

&lt;p&gt;Software entities such as classes should be open for extension but closed for modification.&lt;/p&gt;

&lt;p&gt;This means you should be able to add new functionality without changing existing code. Instead of modifying a class directly, you extend it or use abstractions.&lt;/p&gt;

&lt;p&gt;This reduces the risk of introducing bugs into already tested code.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Liskov Substitution Principle (LSP)
&lt;/h2&gt;

&lt;p&gt;Objects of a subclass should be able to replace objects of the parent class without affecting the correctness of the program.&lt;/p&gt;

&lt;p&gt;In simple terms, if a class inherits from another, it should behave in a way that does not break expectations. If replacing a parent class with a child class causes errors, then the design violates this principle.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Interface Segregation Principle (ISP)
&lt;/h2&gt;

&lt;p&gt;Clients should not be forced to depend on interfaces they do not use.&lt;/p&gt;

&lt;p&gt;Instead of creating large, general-purpose interfaces, it is better to create smaller, more specific ones. This ensures that classes only implement what they actually need.&lt;/p&gt;

&lt;p&gt;This leads to cleaner and more focused code.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Dependency Inversion Principle (DIP)
&lt;/h2&gt;

&lt;p&gt;High-level modules should not depend on low-level modules. Both should depend on abstractions.&lt;/p&gt;

&lt;p&gt;This means you should rely on interfaces or abstract classes rather than concrete implementations. It reduces tight coupling between components and makes your system more flexible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SOLID Matters
&lt;/h2&gt;

&lt;p&gt;Applying SOLID principles leads to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better code organization&lt;/li&gt;
&lt;li&gt;Easier testing and debugging&lt;/li&gt;
&lt;li&gt;Improved scalability&lt;/li&gt;
&lt;li&gt;Reduced risk when making changes&lt;/li&gt;
&lt;li&gt;More reusable components&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;SOLID principles do not tell you how many classes to create. Instead, they guide how those classes should behave and interact with each other.&lt;/p&gt;

&lt;p&gt;By applying these principles consistently, you move from writing code that simply works to building systems that are robust, maintainable, and ready to grow with changing requirements.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>python</category>
    </item>
    <item>
      <title>Understanding AI Agents: Autonomous vs Semi-Autonomous Systems</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Wed, 08 Apr 2026 12:21:22 +0000</pubDate>
      <link>https://forem.com/msnmongare/understanding-ai-agents-autonomous-vs-semi-autonomous-systems-4n3</link>
      <guid>https://forem.com/msnmongare/understanding-ai-agents-autonomous-vs-semi-autonomous-systems-4n3</guid>
      <description>&lt;p&gt;As Artificial Intelligence continues to evolve, the concept of an "agent" has become central to how intelligent systems are designed and deployed. From chatbots and virtual assistants to automated financial systems and robotics, agents are the building blocks behind many modern applications. To fully understand how these systems operate, it is important to start with a clear definition of what an AI agent is, and then explore the difference between autonomous and semi-autonomous agents.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is an AI Agent
&lt;/h2&gt;

&lt;p&gt;An AI agent is a software system or program that is designed to perceive its environment, make decisions, and take actions in order to achieve a specific goal.&lt;/p&gt;

&lt;p&gt;At its core, an agent has three main components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Perception&lt;/strong&gt;: The ability to gather information from its environment. This could be user input, API responses, sensor data, or database queries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decision-making&lt;/strong&gt;: The logic or intelligence that allows the agent to analyze information and determine what action to take.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action&lt;/strong&gt;: The execution of tasks, such as sending a message, updating a database, calling an API, or triggering another process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple example is a chatbot. It receives a message from a user, processes the input, decides on a response, and sends a reply. More advanced agents can handle complex workflows, learn from data, and adapt over time.&lt;/p&gt;

&lt;p&gt;Agents can also be goal-driven, meaning they are designed not just to respond to inputs, but to actively pursue objectives. For instance, an agent might be tasked with increasing sales conversions, monitoring system health, or automating customer engagement.&lt;/p&gt;




&lt;h2&gt;
  
  
  Autonomous AI Agents
&lt;/h2&gt;

&lt;p&gt;Autonomous AI agents are systems that operate independently with minimal or no human intervention. Once they are given a goal or set of objectives, they can plan, make decisions, and execute actions on their own.&lt;/p&gt;

&lt;h3&gt;
  
  
  Characteristics of Autonomous Agents
&lt;/h3&gt;

&lt;p&gt;Autonomous agents are defined by a high level of independence. They can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make decisions without human approval&lt;/li&gt;
&lt;li&gt;Adapt to changing environments&lt;/li&gt;
&lt;li&gt;Continuously operate without supervision&lt;/li&gt;
&lt;li&gt;Optimize their actions based on feedback and data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These agents often rely on advanced techniques such as machine learning, reinforcement learning, and real-time data processing to improve their performance over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples of Autonomous Agents
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Automated trading systems that analyze markets and execute trades instantly&lt;/li&gt;
&lt;li&gt;Self-driving vehicles that navigate roads and respond to traffic conditions&lt;/li&gt;
&lt;li&gt;Network monitoring systems that detect and respond to threats without human input&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;High efficiency and speed&lt;/li&gt;
&lt;li&gt;Ability to operate at scale&lt;/li&gt;
&lt;li&gt;Reduced need for human labor in repetitive tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Challenges
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Higher risk due to lack of human oversight&lt;/li&gt;
&lt;li&gt;Difficulty in handling unexpected or ambiguous situations&lt;/li&gt;
&lt;li&gt;Ethical and accountability concerns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of these challenges, fully autonomous systems are often deployed in controlled environments or where the risks are manageable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Semi-Autonomous AI Agents
&lt;/h2&gt;

&lt;p&gt;Semi-autonomous AI agents operate with a combination of machine intelligence and human involvement. They can perform many tasks independently, but they require human input, validation, or approval at key stages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Characteristics of Semi-Autonomous Agents
&lt;/h3&gt;

&lt;p&gt;These agents are designed to assist rather than fully replace human decision-making. They typically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide recommendations or suggestions&lt;/li&gt;
&lt;li&gt;Execute tasks up to a certain point&lt;/li&gt;
&lt;li&gt;Require human confirmation for critical actions&lt;/li&gt;
&lt;li&gt;Work collaboratively with users&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Examples of Semi-Autonomous Agents
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Code assistants that suggest implementations while developers decide what to use&lt;/li&gt;
&lt;li&gt;Customer support systems that draft replies for human agents to review&lt;/li&gt;
&lt;li&gt;Financial systems that flag suspicious transactions for manual verification&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Lower risk due to human oversight&lt;/li&gt;
&lt;li&gt;Better handling of complex or sensitive scenarios&lt;/li&gt;
&lt;li&gt;Increased trust and accountability&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Challenges
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Slower than fully autonomous systems due to human involvement&lt;/li&gt;
&lt;li&gt;Requires well-designed interaction between human and machine&lt;/li&gt;
&lt;li&gt;May not scale as easily in high-demand environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Semi-autonomous systems are widely used in real-world applications because they strike a balance between efficiency and control.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Differences Between Autonomous and Semi-Autonomous Agents
&lt;/h2&gt;

&lt;p&gt;The distinction between these two types of agents lies primarily in control, decision-making, and risk management.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Autonomous Agents&lt;/th&gt;
&lt;th&gt;Semi-Autonomous Agents&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Human involvement&lt;/td&gt;
&lt;td&gt;Minimal or none&lt;/td&gt;
&lt;td&gt;Required at key points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decision-making&lt;/td&gt;
&lt;td&gt;Fully independent&lt;/td&gt;
&lt;td&gt;Shared with humans&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Risk level&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use cases&lt;/td&gt;
&lt;td&gt;Automation at scale&lt;/td&gt;
&lt;td&gt;Human-assisted workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  When to Use Each Type
&lt;/h2&gt;

&lt;p&gt;Choosing between autonomous and semi-autonomous agents depends on the context in which the system will operate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Autonomous Agents When:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tasks are repetitive and well-defined&lt;/li&gt;
&lt;li&gt;Decisions are based on clear data patterns&lt;/li&gt;
&lt;li&gt;Speed and scalability are critical&lt;/li&gt;
&lt;li&gt;The risk of errors is low or manageable&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Semi-Autonomous Agents When:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Decisions require human judgment or context&lt;/li&gt;
&lt;li&gt;The system operates in sensitive domains such as finance or healthcare&lt;/li&gt;
&lt;li&gt;Accountability and trust are important&lt;/li&gt;
&lt;li&gt;Errors could have significant consequences&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Practical Perspective for Developers
&lt;/h2&gt;

&lt;p&gt;For developers building systems such as APIs, backend services, or automation platforms, understanding this distinction is crucial.&lt;/p&gt;

&lt;p&gt;Autonomous agents are ideal for background processes such as data synchronization, automated notifications, or system monitoring. These tasks benefit from speed and do not usually require human validation.&lt;/p&gt;

&lt;p&gt;Semi-autonomous agents are better suited for user-facing features such as messaging platforms, financial transactions, or content generation tools. In these cases, allowing a human to review or approve actions helps prevent costly mistakes.&lt;/p&gt;

&lt;p&gt;For example, in a WhatsApp API platform, an autonomous agent might automatically send scheduled messages or respond to frequently asked questions. A semi-autonomous agent, on the other hand, might generate message drafts that a user reviews before sending to customers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;AI agents are powerful tools that enable systems to act intelligently and achieve goals with minimal manual effort. The distinction between autonomous and semi-autonomous agents lies in how much control is given to the system versus the human.&lt;/p&gt;

&lt;p&gt;Autonomous agents focus on independence, efficiency, and scalability, while semi-autonomous agents emphasize collaboration, oversight, and safety. Understanding when and how to use each type is essential for building reliable, effective, and responsible AI-driven systems.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Testing M-PESA STK Push Callbacks Locally Without Exposing Your Server</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Wed, 18 Mar 2026 13:02:35 +0000</pubDate>
      <link>https://forem.com/msnmongare/testing-m-pesa-stk-push-callbacks-locally-without-exposing-your-server-pdo</link>
      <guid>https://forem.com/msnmongare/testing-m-pesa-stk-push-callbacks-locally-without-exposing-your-server-pdo</guid>
      <description>&lt;p&gt;If you've ever built an M-PESA STK Push integration, you've probably hit this wall: M-PESA needs a publicly accessible callback URL to send payment confirmations, but your app is running on localhost. How do you test this without deploying every single time?&lt;/p&gt;

&lt;p&gt;In this guide I'll show you a simple approach using webhook.site and a small Node.js poller script that automatically forwards M-PESA callbacks to your local machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  What We're Building
&lt;/h2&gt;

&lt;p&gt;When a user completes an STK Push payment, M-PESA sends a POST request to your callback URL with the payment result. Normally that URL has to be publicly accessible. Since localhost isn't public, we'll use webhook.site as a middleman - it catches the callback from M-PESA, and our poller script picks it up and forwards it to our local app automatically.&lt;/p&gt;

&lt;p&gt;The flow looks like this:&lt;/p&gt;

&lt;p&gt;M-PESA → webhook.site → our poller script → localhost&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Node.js installed on your machine&lt;/li&gt;
&lt;li&gt;Your Laravel app running locally&lt;/li&gt;
&lt;li&gt;An M-PESA Daraja API account (sandbox or production)&lt;/li&gt;
&lt;li&gt;Basic understanding of how STK Push works&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1 - Get a webhook.site URL
&lt;/h2&gt;

&lt;p&gt;Go to webhook.site and you'll immediately get a unique URL that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://webhook.site/f5d500b7-1196-42ef-8ecd-c906e49f7df36
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The part after the last slash is your token. Copy it - you'll need it shortly. Keep this tab open so you can see incoming requests.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2 - Store the Callback URL in Your .env
&lt;/h2&gt;

&lt;p&gt;Instead of hardcoding the webhook.site URL in your code, store it in your .env file so you can swap it out easily without touching any code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;MPESA_CALLBACK_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://webhook.site/f5d500b7-1196-42ef-8ecd-c906e49f7df36&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On production you simply leave this variable out and it falls back to your real callback URL automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 - Update Your ProcessController
&lt;/h2&gt;

&lt;p&gt;In your M-PESA ProcessController where you build the STK Push request, find the CallBackURL line and update it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s2"&gt;"CallBackURL"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'MPESA_CALLBACK_URL'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ipn.MPesa'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this does is simple. If MPESA_CALLBACK_URL is set in your .env it uses that. If it's not set, it falls back to your real route. This means locally it points to webhook.site, and on production it uses your actual callback route - no code changes needed when you deploy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 - Create the Poller Script
&lt;/h2&gt;

&lt;p&gt;This is the magic piece. Create a file called forwarder.js anywhere on your machine - I put mine in the project root. Paste this in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;WEBHOOK_TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;f5d500b7-1196-42ef-8ecd-c906e49f7df36&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// your token here&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LOCAL_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:8000/ipn/mpesa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;POLL_INTERVAL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// check every 5 seconds&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lastSeenId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;poll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://webhook.site/token/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;WEBHOOK_TOKEN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/requests?sorting=newest&amp;amp;per_page=1`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;latest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;lastSeenId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// already processed this one&lt;/span&gt;

        &lt;span class="nx"&gt;lastSeenId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;New callback received! Forwarding to local app...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;forward&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LOCAL_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Done. Local app responded with status:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;poll&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;POLL_INTERVAL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Watching webhook.site for incoming callbacks...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the WEBHOOK_TOKEN value with your own token from Step 1. The LOCAL_URL should match whatever route your app uses for the M-PESA IPN.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5 - Run Everything
&lt;/h2&gt;

&lt;p&gt;You'll need two terminals open.&lt;/p&gt;

&lt;p&gt;Terminal 1 - start your Laravel app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Terminal 2 - start the poller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node forwarder.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see this message in Terminal 2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Watching webhook.site for incoming callbacks...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 6 - Trigger a Test Payment
&lt;/h2&gt;

&lt;p&gt;Go through your app's deposit flow and trigger an STK Push. Enter your phone number and hit pay. You'll get the prompt on your phone.&lt;/p&gt;

&lt;p&gt;Once you complete the payment, here's what happens automatically:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;M-PESA sends the callback to webhook.site&lt;/li&gt;
&lt;li&gt;Your poller picks it up within 5 seconds&lt;/li&gt;
&lt;li&gt;It forwards the full payload to your local app&lt;/li&gt;
&lt;li&gt;Your local app processes it and updates the database&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You'll see something like this in Terminal 2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;New&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;callback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;received!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Forwarding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;app...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"Body"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"stkCallback"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"ResultCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"CheckoutRequestID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"ws_CO_xxxxx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Done.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;app&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;responded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;status:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And your database gets updated just like it would in production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Not Just Use ngrok?
&lt;/h2&gt;

&lt;p&gt;Ngrok is the most common answer to this problem and it works well. However if you're running a licensed script, adding a new public URL can trigger a second domain detection and invalidate your license. The webhook.site approach avoids this completely since your app never gets a new public URL - only the callback endpoint changes temporarily, and only in your local .env.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cleaning Up After Testing
&lt;/h2&gt;

&lt;p&gt;When you're done testing, remove MPESA_CALLBACK_URL from your .env or comment it out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# MPESA_CALLBACK_URL=https://webhook.site/f5d500b7-1196-42ef-8ecd-c906e49f7df36
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your app will fall back to the real route automatically. Stop the forwarder.js script and you're done. Nothing was changed in your codebase, nothing gets pushed to production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;The whole setup takes about 5 minutes and gives you a proper local testing loop for M-PESA callbacks without ngrok, without deploying, and without touching your production environment. The poller script is lightweight, requires no dependencies beyond Node.js, and you can reuse the same approach for any other payment gateway callback - just change the LOCAL_URL to point to the right IPN route.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>ai</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Run Multiple PHP Versions on Windows and Switch Easily</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Sun, 15 Mar 2026 12:45:08 +0000</pubDate>
      <link>https://forem.com/msnmongare/how-to-run-multiple-php-versions-on-windows-and-switch-easily-a7k</link>
      <guid>https://forem.com/msnmongare/how-to-run-multiple-php-versions-on-windows-and-switch-easily-a7k</guid>
      <description>&lt;p&gt;When working on modern PHP projects like those built with &lt;strong&gt;Laravel&lt;/strong&gt;, you will eventually run into version conflicts.&lt;/p&gt;

&lt;p&gt;One project may require &lt;strong&gt;PHP 8.3&lt;/strong&gt;, while another older project may still run on &lt;strong&gt;PHP 8.1 or 8.2&lt;/strong&gt;. If your system only has one PHP version installed, you will constantly run into errors like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Composer detected issues in your platform:
Your Composer dependencies require a PHP version "&amp;gt;= 8.3.0".
You are running 8.2.12.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of reinstalling PHP every time you switch projects, the better solution is to install &lt;strong&gt;multiple PHP versions&lt;/strong&gt; and switch between them instantly.&lt;/p&gt;

&lt;p&gt;One of the easiest ways to achieve this on Windows is by using &lt;strong&gt;Scoop&lt;/strong&gt;, a lightweight package manager designed for developers.&lt;/p&gt;

&lt;p&gt;Below is a simple and clean setup.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Install Scoop
&lt;/h2&gt;

&lt;p&gt;Open &lt;strong&gt;PowerShell&lt;/strong&gt; and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Set-ExecutionPolicy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;RemoteSigned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Scope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CurrentUser&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;irm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;get.scoop.sh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scoop installs tools into your user directory and avoids the common permission problems that occur with traditional installers.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Add the Versions Bucket
&lt;/h2&gt;

&lt;p&gt;Scoop organizes packages using "buckets". To install multiple PHP versions, you need the versions bucket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;versions&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This bucket contains packages like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;php81&lt;/li&gt;
&lt;li&gt;php82&lt;/li&gt;
&lt;li&gt;php83&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Install Multiple PHP Versions
&lt;/h2&gt;

&lt;p&gt;You can now install any PHP version you need.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;php82&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;php83&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check installed packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point both PHP versions exist on your system, but only one will be active at a time.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Switch Between PHP Versions
&lt;/h2&gt;

&lt;p&gt;To switch to &lt;strong&gt;PHP 8.3&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;php83&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To switch to &lt;strong&gt;PHP 8.2&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;php82&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the active version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-v&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This instantly updates your terminal environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Running Your Laravel Project
&lt;/h2&gt;

&lt;p&gt;Once the correct version is active, you can start your project normally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the project requires PHP 8.3, switching to php83 will resolve the platform check error.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Approach Is Powerful
&lt;/h2&gt;

&lt;p&gt;Modern development environments rarely use a single runtime version.&lt;/p&gt;

&lt;p&gt;You may have projects such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Legacy project running PHP 8.1&lt;/li&gt;
&lt;li&gt;Production system using PHP 8.2&lt;/li&gt;
&lt;li&gt;New &lt;strong&gt;Laravel 11&lt;/strong&gt; applications requiring PHP 8.3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using Scoop allows you to move between these environments instantly without reinstalling anything.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus: Install Other Developer Tools
&lt;/h2&gt;

&lt;p&gt;Scoop can also install common development tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;composer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodejs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a clean development environment that is easy to maintain and update.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Managing multiple PHP versions used to be complicated on Windows. With &lt;strong&gt;Scoop&lt;/strong&gt;, the process becomes simple and developer friendly.&lt;/p&gt;

&lt;p&gt;Instead of fighting your environment, you can focus on building applications and switching versions only when necessary.&lt;/p&gt;

&lt;p&gt;For backend developers working with frameworks like &lt;strong&gt;Laravel&lt;/strong&gt;, this setup saves time and prevents version related errors during development.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>M-PESA DARAJA API - C2B Integration Guide</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Fri, 13 Mar 2026 09:42:47 +0000</pubDate>
      <link>https://forem.com/msnmongare/m-pesa-daraja-api-c2b-integration-guide-djn</link>
      <guid>https://forem.com/msnmongare/m-pesa-daraja-api-c2b-integration-guide-djn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you are building a web or mobile app that needs to receive payments from M-PESA customers in Kenya, the Safaricom Daraja API is the tool you need. This guide will walk you through everything from scratch  no prior API experience required.&lt;/p&gt;

&lt;p&gt;By the end of this guide, you will understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What the C2B API is and how it works&lt;/li&gt;
&lt;li&gt;How to set up and test it in the sandbox using Postman&lt;/li&gt;
&lt;li&gt;What ValidationURL and ConfirmationURL do&lt;/li&gt;
&lt;li&gt;How to take your integration live&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What is C2B?
&lt;/h2&gt;

&lt;p&gt;C2B stands for &lt;strong&gt;Customer to Business&lt;/strong&gt;. It refers to the flow of money from an individual customer to your business. When a customer pays your Paybill or Till number via M-PESA, that is a C2B transaction.&lt;/p&gt;

&lt;p&gt;The C2B API allows your application to receive real-time notifications every time a payment comes in, so you can automate things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Marking an order as paid&lt;/li&gt;
&lt;li&gt;Sending a payment receipt to the customer&lt;/li&gt;
&lt;li&gt;Updating your accounting system automatically&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What is Daraja?
&lt;/h2&gt;

&lt;p&gt;Daraja (which means "bridge" in Swahili) is Safaricom's developer portal that gives you access to the M-PESA API. It provides a &lt;strong&gt;sandbox&lt;/strong&gt; (testing) environment where you can simulate payments without using real money, and a &lt;strong&gt;production&lt;/strong&gt; environment for real transactions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Portal URL:&lt;/strong&gt; &lt;a href="https://developer.safaricom.co.ke" rel="noopener noreferrer"&gt;https://developer.safaricom.co.ke&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  PART ONE: SANDBOX TESTING
&lt;/h2&gt;

&lt;p&gt;Before using real money, Daraja gives you a sandbox environment to safely test your integration. This is where you should always start.&lt;/p&gt;




&lt;h2&gt;
  
  
  STEP 1 - Create a Daraja Account &amp;amp; App
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Set up your developer profile&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://developer.safaricom.co.ke" rel="noopener noreferrer"&gt;https://developer.safaricom.co.ke&lt;/a&gt; and click &lt;strong&gt;Sign Up&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Fill in your details and verify your email address&lt;/li&gt;
&lt;li&gt;Once logged in, click &lt;strong&gt;"My Apps"&lt;/strong&gt; in the top navigation menu&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;"Create Sandbox App"&lt;/strong&gt; - give it any name (e.g. "MyShopC2B")&lt;/li&gt;
&lt;li&gt;Under the products section, check &lt;strong&gt;"M-Pesa Sandbox"&lt;/strong&gt; to enable sandbox APIs&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;"Create App"&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your app will now appear in the "My Apps" section. Click on it and you will see two important values:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consumer Key&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Acts like your app's username for the API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consumer Secret&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Acts like your app's password for the API&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;💾 &lt;strong&gt;Save These!&lt;/strong&gt; Copy your Consumer Key and Consumer Secret somewhere safe. You will need them for every API call.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  STEP 2 - Get an Access Token
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Authenticate before making any API call&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every single API request to Daraja requires an access token. Think of it like a &lt;strong&gt;temporary password&lt;/strong&gt; that proves your identity. It expires after 1 hour and you need to generate a new one.&lt;/p&gt;

&lt;h3&gt;
  
  
  In Postman:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Method:&lt;/strong&gt; &lt;code&gt;GET&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL:&lt;/strong&gt; &lt;code&gt;https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go to the &lt;strong&gt;Authorization&lt;/strong&gt; tab in Postman:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auth Type: &lt;strong&gt;Basic Auth&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Username: paste your &lt;strong&gt;Consumer Key&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Password: paste your &lt;strong&gt;Consumer Secret&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click &lt;strong&gt;Send&lt;/strong&gt;. You should get a response like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"access_token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SGWcJPtNtYNPGm1DqBNqZZZZZZ"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expires_in"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3599"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;📋 &lt;strong&gt;Copy It!&lt;/strong&gt; Copy the &lt;code&gt;access_token&lt;/code&gt; value. You will paste it in the Authorization header of every request below.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  STEP 3 - Understanding Your Callback URLs
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;The heart of how C2B notifications work&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Before registering your URLs, it is important to understand what each one does. When a customer makes a payment, Safaricom contacts your server at two different points in the payment flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📱 Customer Pays  →  🔍 ValidationURL  →  ✅ ConfirmationURL
  (Sends money)      ("Should I allow    ("Payment done,
                          this?")          record it!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ValidationURL - "Should I allow this payment?"
&lt;/h3&gt;

&lt;p&gt;This is called &lt;strong&gt;before&lt;/strong&gt; the payment is processed. Safaricom sends you the payment details and waits for your response. You can accept or reject the payment based on your own business logic - for example, checking if the account number the customer entered actually exists in your system.&lt;/p&gt;

&lt;p&gt;You respond with one of the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Accept&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;payment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"ResultCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"ResultDesc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Accepted"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Reject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;payment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"ResultCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C2B00012"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"ResultDesc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rejected"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Note:&lt;/strong&gt; ValidationURL is &lt;strong&gt;optional&lt;/strong&gt;. If you set &lt;code&gt;ResponseType&lt;/code&gt; to &lt;code&gt;"Completed"&lt;/code&gt; when registering, Safaricom skips validation and auto-accepts all payments. This is recommended for beginners.&lt;br&gt;
Validation URL is the URL that receives the validation request from API upon payment submission. The validation URL is only called if external validation on the registered short code is enabled.&lt;br&gt;
(By default, External Validation is disabled)&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  ConfirmationURL - "Payment went through, save the details"
&lt;/h3&gt;

&lt;p&gt;This is called &lt;strong&gt;after&lt;/strong&gt; the payment has been successfully processed. At this point, you &lt;strong&gt;cannot&lt;/strong&gt; reject the payment - it has already gone through. This is where your app should record the transaction, update a database, send a receipt, or trigger any other business logic.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;ValidationURL&lt;/th&gt;
&lt;th&gt;ConfirmationURL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;When called&lt;/td&gt;
&lt;td&gt;BEFORE payment is processed&lt;/td&gt;
&lt;td&gt;AFTER payment is processed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Purpose&lt;/td&gt;
&lt;td&gt;Accept or reject the payment&lt;/td&gt;
&lt;td&gt;Record and act on the payment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Your response matters?&lt;/td&gt;
&lt;td&gt;YES - can block the payment&lt;/td&gt;
&lt;td&gt;NO - informational only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Required?&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;Yes, always required&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;🏪 &lt;strong&gt;Real-world analogy:&lt;/strong&gt; Think of it like a supermarket checkout. The ValidationURL is the cashier checking if your loyalty card is valid before ringing up. The ConfirmationURL is the receipt printer - it just records that the sale happened.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  STEP 4 - Get a Free Callback URL for Testing
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Use webhook.site to capture callbacks&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Your ValidationURL and ConfirmationURL must be &lt;strong&gt;publicly accessible HTTPS endpoints&lt;/strong&gt;. For sandbox testing, you do not need a real server - you can use a free tool called &lt;strong&gt;webhook.site&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://webhook.site" rel="noopener noreferrer"&gt;https://webhook.site&lt;/a&gt; in your browser&lt;/li&gt;
&lt;li&gt;You will instantly get a unique URL like: &lt;code&gt;https://webhook.site/abc-123-xyz&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Copy that URL - you will use it as both your ValidationURL and ConfirmationURL for testing&lt;/li&gt;
&lt;li&gt;Leave the webhook.site tab open. Callbacks from Safaricom will appear here in real time&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;🚫 &lt;strong&gt;URL Rules:&lt;/strong&gt; Never use words like "MPesa", "M-Pesa", or "Safaricom" in your URLs - the system will block them. Also, localhost URLs will not work. Always use a proper HTTPS URL.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  STEP 5 - Register Your Callback URLs
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Tell Safaricom where to send payment notifications&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now you will call the Register URL API to link your callback URLs to your Paybill shortcode.&lt;/p&gt;

&lt;h3&gt;
  
  
  In Postman:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Method:&lt;/strong&gt; &lt;code&gt;POST&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL:&lt;/strong&gt; &lt;code&gt;https://sandbox.safaricom.co.ke/mpesa/c2b/v1/registerurl&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Headers tab - add these two headers:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Header Key&lt;/th&gt;
&lt;th&gt;Header Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Authorization&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bearer YOUR_ACCESS_TOKEN&lt;/code&gt; (paste the token from Step 2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content-Type&lt;/td&gt;
&lt;td&gt;&lt;code&gt;application/json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Body tab - select "raw" and "JSON", then paste:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ShortCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"600584"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ResponseType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Completed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Either&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Cancelled&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Completed&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ConfirmationURL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://webhook.site/your-unique-url"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ValidationURL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://webhook.site/your-unique-url"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ShortCode&lt;/td&gt;
&lt;td&gt;The sandbox test Paybill number (600584 is the default sandbox shortcode)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ResponseType&lt;/td&gt;
&lt;td&gt;"Completed" means skip validation and auto-accept all payments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ConfirmationURL&lt;/td&gt;
&lt;td&gt;Your webhook.site URL - where Safaricom sends payment confirmations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ValidationURL&lt;/td&gt;
&lt;td&gt;Your webhook.site URL - where Safaricom asks for approval (optional here)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A successful response looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"OriginatorCoversationID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ResponseCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ResponseDescription"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  STEP 6 - Simulate a C2B Payment
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Pretend a customer is paying you&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now for the fun part - you will simulate a customer sending money to your Paybill. Safaricom provides a test phone number you can use.&lt;/p&gt;

&lt;h3&gt;
  
  
  In Postman:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Method:&lt;/strong&gt; &lt;code&gt;POST&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL:&lt;/strong&gt; &lt;code&gt;https://sandbox.safaricom.co.ke/mpesa/c2b/v1/simulate&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use the same Authorization header as before, then paste this JSON body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ShortCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"600584"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"CommandID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CustomerPayBillOnline"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Msisdn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"254708374149"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"BillRefNumber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"INV001"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ShortCode&lt;/td&gt;
&lt;td&gt;Your sandbox Paybill number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CommandID&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;"CustomerPayBillOnline"&lt;/code&gt; for Paybill, or &lt;code&gt;"CustomerBuyGoodsOnline"&lt;/code&gt; for Till&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amount&lt;/td&gt;
&lt;td&gt;The amount the simulated customer is paying (in KES)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Msisdn&lt;/td&gt;
&lt;td&gt;The test customer phone number - always use &lt;code&gt;254708374149&lt;/code&gt; in sandbox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BillRefNumber&lt;/td&gt;
&lt;td&gt;The account reference - e.g. an invoice number or order ID&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  STEP 7 - Check Your Callback
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;See what your app would receive&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After sending the simulation request, go to your webhook.site tab. Within a few seconds, you should see a POST request arrive. This is exactly the payload your real server would receive when a customer pays.&lt;/p&gt;

&lt;p&gt;It will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"TransactionType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Pay Bill"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"TransID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"UCB030CBG1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"TransTime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"20260311161727"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"TransAmount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"BusinessShortCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"600991"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"BillRefNumber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"account001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"InvoiceNumber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"OrgAccountBalance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4635316.60"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"ThirdPartyTransID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"MSISDN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bbff37cea44ac0b2d964ee0dfb8d2df8513dc7ba1b36129a929fc3fbd6dd4af4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"FirstName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TransactionType&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Pay Bill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The type of transaction. Will be "Pay Bill" for Paybill or "Buy Goods" for Till numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TransID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UCB030CBG1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unique M-PESA transaction ID. Use this as your reference to avoid processing the same payment twice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TransTime&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;20260311161727&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Timestamp of the transaction in &lt;code&gt;YYYYMMDDHHmmss&lt;/code&gt; format. This one means 11 March 2026 at 16:17:27&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TransAmount&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1.00&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The amount the customer paid in KES&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BusinessShortCode&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;600991&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your Paybill or Till number that received the payment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BillRefNumber&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;account001&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The account number the customer entered when paying. Use this to identify which customer or order the payment belongs to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;InvoiceNumber&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(empty)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;Optional invoice number. Usually empty for most C2B transactions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OrgAccountBalance&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4635316.60&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your Paybill account balance after this transaction was processed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ThirdPartyTransID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(empty)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;Used in some integrations for a third-party reference. Usually empty&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MSISDN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bbff37c...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The customer's phone number. In sandbox it is returned as a hashed/masked value for privacy.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FirstName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;John&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The first name of the customer as registered on M-PESA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; The three most important fields to save in your database are &lt;code&gt;TransID&lt;/code&gt; (to prevent duplicate processing), &lt;code&gt;BillRefNumber&lt;/code&gt; (to identify the customer/order), and &lt;code&gt;TransAmount&lt;/code&gt; (to confirm the correct amount was paid).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In a real application, you would read this JSON payload and use the &lt;code&gt;TransAmount&lt;/code&gt;, &lt;code&gt;BillRefNumber&lt;/code&gt;, and &lt;code&gt;MSISDN&lt;/code&gt; fields to update your database and send a receipt to the customer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Sandbox Note:&lt;/strong&gt; Sandbox callbacks can sometimes be unreliable. If your webhook.site does not receive anything after 30 seconds, try the simulation again. This is a known sandbox issue.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Full C2B Flow Recap
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;What Happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Get Token&lt;/td&gt;
&lt;td&gt;You authenticate with your Consumer Key &amp;amp; Secret and receive a temporary access token&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Register URLs&lt;/td&gt;
&lt;td&gt;You tell Safaricom where to send payment notifications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Customer Pays&lt;/td&gt;
&lt;td&gt;A real or simulated customer sends money to your Paybill or Till number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Validation&lt;/td&gt;
&lt;td&gt;Safaricom hits your ValidationURL asking "should I accept this?" (optional)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Confirmation&lt;/td&gt;
&lt;td&gt;Safaricom hits your ConfirmationURL with the full payment details&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Your App Acts&lt;/td&gt;
&lt;td&gt;Your server reads the payload and updates the database, sends a receipt, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  PART TWO: GOING LIVE
&lt;/h2&gt;

&lt;p&gt;Once your sandbox integration is working correctly, you are ready to go live and process real M-PESA transactions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites Before Going Live
&lt;/h2&gt;

&lt;p&gt;Make sure you have all of the following before applying for live credentials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A working sandbox integration - all steps above tested and confirmed working&lt;/li&gt;
&lt;li&gt;A registered and verified Paybill or Till Number from Safaricom&lt;/li&gt;
&lt;li&gt;An active Safaricom G2 Business Admin account (used to verify your shortcode)&lt;/li&gt;
&lt;li&gt;A real publicly accessible HTTPS server URL (not localhost, not webhook.site) for your callback URLs&lt;/li&gt;
&lt;li&gt;Company documentation: Certificate of incorporation, KRA PIN, and directors' IDs (for businesses)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;🏢 &lt;strong&gt;Get a Paybill First:&lt;/strong&gt; To get a Paybill number, visit a Safaricom shop with your company registration documents. For a Till number, you can apply via the Safaricom self-onboarding portal. Processing takes 24–72 hours.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 1 - Register on the Safaricom G2 Portal
&lt;/h2&gt;

&lt;p&gt;The G2 portal (&lt;a href="https://org.ke.mpesa.com" rel="noopener noreferrer"&gt;https://org.ke.mpesa.com&lt;/a&gt;) is Safaricom's business management platform. You need an account here so Daraja can verify you own the Paybill or Till number you want to use.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Send an email to &lt;strong&gt;&lt;a href="mailto:M-PESABusiness@safaricom.co.ke"&gt;M-PESABusiness@safaricom.co.ke&lt;/a&gt;&lt;/strong&gt; requesting a Business Admin account&lt;/li&gt;
&lt;li&gt;Attach required documents: company registration certificate, KRA PIN, directors' IDs, and a signed board resolution&lt;/li&gt;
&lt;li&gt;Safaricom will create your G2 account and send login credentials&lt;/li&gt;
&lt;li&gt;Log in, change your password, and create an "assistant role" user - these credentials will be used in the next step&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 2 - Confirm Your Sandbox Integration is Solid
&lt;/h2&gt;

&lt;p&gt;Before applying to go live, make sure all of the following are working in sandbox:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access token generation is working&lt;/li&gt;
&lt;li&gt;URL registration returns a success response&lt;/li&gt;
&lt;li&gt;Simulated payments are triggering callbacks to your server&lt;/li&gt;
&lt;li&gt;Your server is responding with the correct &lt;code&gt;200 OK&lt;/code&gt; responses&lt;/li&gt;
&lt;li&gt;Your database or backend is correctly parsing and saving the callback payload&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 3 - Click "Go Live" on the Daraja Portal
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Log into &lt;a href="https://developer.safaricom.co.ke" rel="noopener noreferrer"&gt;https://developer.safaricom.co.ke&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;"My Apps"&lt;/strong&gt; and open your app&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;"Go Live"&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;"Verification by Shortcode"&lt;/strong&gt; as the method&lt;/li&gt;
&lt;li&gt;Enter your Paybill/Till shortcode and your G2 assistant user credentials&lt;/li&gt;
&lt;li&gt;Select the API products you need (e.g. C2B)&lt;/li&gt;
&lt;li&gt;Upload your &lt;strong&gt;test cases&lt;/strong&gt; - a document showing what you tested and the results&lt;/li&gt;
&lt;li&gt;Submit your request&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;⏱️ &lt;strong&gt;Approval Time:&lt;/strong&gt; Safaricom typically takes 24–72 hours to review and approve your live request. You will receive your production credentials by email once approved.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 4 - Replace Sandbox Credentials with Live Ones
&lt;/h2&gt;

&lt;p&gt;Once approved, update your application to use production values:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What to Change&lt;/th&gt;
&lt;th&gt;Sandbox → Production&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;API Base URL&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;sandbox.safaricom.co.ke&lt;/code&gt; → &lt;code&gt;api.safaricom.co.ke&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consumer Key&lt;/td&gt;
&lt;td&gt;Sandbox key → New live Consumer Key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consumer Secret&lt;/td&gt;
&lt;td&gt;Sandbox secret → New live Consumer Secret&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ShortCode&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;600584&lt;/code&gt; (test) → Your actual Paybill/Till number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Callback URLs&lt;/td&gt;
&lt;td&gt;webhook.site URLs → Your real HTTPS server URLs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Step 5 - Test a Small Live Transaction
&lt;/h2&gt;

&lt;p&gt;After switching to production credentials, do a small test with real money (e.g. KES 1) to confirm everything works end to end:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pay your Paybill from a real M-PESA number&lt;/li&gt;
&lt;li&gt;Confirm your ConfirmationURL receives the callback&lt;/li&gt;
&lt;li&gt;Verify your database is updated correctly&lt;/li&gt;
&lt;li&gt;Check that the customer receives the expected response or receipt&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;📝 &lt;strong&gt;Keep Logs:&lt;/strong&gt; Always log every transaction in the early stages of going live. Implement retry logic in case of failed callbacks - Safaricom may occasionally retry if your server is slow to respond.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Common Mistakes to Avoid
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;❌ Do NOT do this&lt;/th&gt;
&lt;th&gt;✅ Do this instead&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Include "MPesa" or "Safaricom" in your callback URLs&lt;/td&gt;
&lt;td&gt;Use neutral words in your URLs e.g. &lt;code&gt;/payment/confirm&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Use localhost or 127.0.0.1 as your callback URL&lt;/td&gt;
&lt;td&gt;Host your app or use a tunneling tool like Ngrok (sandbox only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Use webhook.site/ngrok URLs in production&lt;/td&gt;
&lt;td&gt;Use a real, stable HTTPS server in production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Apply for all products without knowing what you need&lt;/td&gt;
&lt;td&gt;Plan ahead - decide which APIs you need before going live&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Forget to renew your access token every hour&lt;/td&gt;
&lt;td&gt;Generate a fresh token on each session or add auto-renewal logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Ignore the callback response format&lt;/td&gt;
&lt;td&gt;Always respond with &lt;code&gt;200 OK&lt;/code&gt; and valid &lt;code&gt;ResultCode&lt;/code&gt;/&lt;code&gt;ResultDesc&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Useful Resources
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Daraja Developer Portal&lt;/td&gt;
&lt;td&gt;&lt;a href="https://developer.safaricom.co.ke" rel="noopener noreferrer"&gt;https://developer.safaricom.co.ke&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daraja API Documentation&lt;/td&gt;
&lt;td&gt;&lt;a href="https://developer.safaricom.co.ke/APIs" rel="noopener noreferrer"&gt;https://developer.safaricom.co.ke/APIs&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safaricom G2 Business Portal&lt;/td&gt;
&lt;td&gt;&lt;a href="https://org.ke.mpesa.com" rel="noopener noreferrer"&gt;https://org.ke.mpesa.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test Callback Tool&lt;/td&gt;
&lt;td&gt;&lt;a href="https://webhook.site" rel="noopener noreferrer"&gt;https://webhook.site&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M-PESA Business Email&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:M-PESABusiness@safaricom.co.ke"&gt;M-PESABusiness@safaricom.co.ke&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;If you need payment integrations, You can reach out to me on &lt;a href="mailto:sosmongare@gmail"&gt;email&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy building!&lt;/p&gt;

</description>
      <category>mpesa</category>
      <category>api</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Understanding APIs: Core Knowledge Every Developer Should Have</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Mon, 09 Mar 2026 20:10:20 +0000</pubDate>
      <link>https://forem.com/msnmongare/understanding-apis-core-knowledge-every-developer-should-have-3ghn</link>
      <guid>https://forem.com/msnmongare/understanding-apis-core-knowledge-every-developer-should-have-3ghn</guid>
      <description>&lt;p&gt;Application Programming Interfaces (APIs) are the backbone of modern software. They enable different applications and services to communicate with each other, exchange data, and perform actions across systems. Whether you are working in frontend, backend, or product development, understanding how APIs work is essential.&lt;/p&gt;

&lt;p&gt;Below are the key concepts every developer should understand when learning APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. REST
&lt;/h3&gt;

&lt;p&gt;Most modern APIs follow the REST (Representational State Transfer) architecture. REST defines how resources are structured and accessed over the web. In a REST API, resources such as users, payments, or products are accessed through endpoints.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users
GET /orders/123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;REST helps maintain consistency and makes APIs easier to understand and use.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. HTTP Methods
&lt;/h3&gt;

&lt;p&gt;HTTP methods define the type of action you want to perform on a resource. The most common methods include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GET - Retrieve data from the server&lt;/li&gt;
&lt;li&gt;POST - Create a new resource&lt;/li&gt;
&lt;li&gt;PUT or PATCH - Update an existing resource&lt;/li&gt;
&lt;li&gt;DELETE - Remove a resource&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding when to use each method is fundamental when building or consuming APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Status Codes
&lt;/h3&gt;

&lt;p&gt;Status codes tell you the outcome of an API request. They help developers quickly determine whether a request succeeded or failed.&lt;/p&gt;

&lt;p&gt;Common examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;200 - Request successful&lt;/li&gt;
&lt;li&gt;201 - Resource created successfully&lt;/li&gt;
&lt;li&gt;400 - Bad request&lt;/li&gt;
&lt;li&gt;401 - Unauthorized&lt;/li&gt;
&lt;li&gt;404 - Resource not found&lt;/li&gt;
&lt;li&gt;500 - Server error&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learning how to interpret these codes is crucial for debugging integrations.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. JSON
&lt;/h3&gt;

&lt;p&gt;Most APIs use JSON (JavaScript Object Notation) as the format for exchanging data. JSON is lightweight and easy for both humans and machines to read.&lt;/p&gt;

&lt;p&gt;Example response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"john@example.com"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Developers should be comfortable reading, writing, and validating JSON structures.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Authentication and Authorization
&lt;/h3&gt;

&lt;p&gt;APIs must ensure that only authorized users or systems can access them. Authentication verifies identity, while authorization determines what actions are allowed.&lt;/p&gt;

&lt;p&gt;Common methods include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API Keys&lt;/li&gt;
&lt;li&gt;OAuth 2.0&lt;/li&gt;
&lt;li&gt;JWT (JSON Web Tokens)&lt;/li&gt;
&lt;li&gt;Basic Authentication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many business APIs rely heavily on authentication mechanisms, such as the &lt;strong&gt;Stripe API&lt;/strong&gt;, &lt;strong&gt;Twilio API&lt;/strong&gt;, and &lt;strong&gt;M-Pesa Daraja API&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Headers
&lt;/h3&gt;

&lt;p&gt;HTTP headers provide additional information about the request or response.&lt;/p&gt;

&lt;p&gt;Common headers include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authorization - used to pass authentication tokens&lt;/li&gt;
&lt;li&gt;Content-Type - defines the format of the request body&lt;/li&gt;
&lt;li&gt;Accept - indicates the expected response format&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding headers helps you control how APIs process requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Request and Response Structure
&lt;/h3&gt;

&lt;p&gt;An API request can contain several components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Path parameters&lt;/li&gt;
&lt;li&gt;Query parameters&lt;/li&gt;
&lt;li&gt;Request body&lt;/li&gt;
&lt;li&gt;Headers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /transactions?limit=10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response typically returns structured data along with a status code.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Error Handling
&lt;/h3&gt;

&lt;p&gt;Well-designed APIs return clear error messages when something goes wrong.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"invalid_request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Missing required field"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Understanding error responses helps developers quickly diagnose and fix issues during integration.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Pagination
&lt;/h3&gt;

&lt;p&gt;When APIs return large datasets, they often split results into smaller pages.&lt;/p&gt;

&lt;p&gt;Common parameters include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;limit&lt;/li&gt;
&lt;li&gt;offset&lt;/li&gt;
&lt;li&gt;cursor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /transactions?limit=20&amp;amp;offset=40
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pagination ensures efficient data retrieval without overloading the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Rate Limiting
&lt;/h3&gt;

&lt;p&gt;To protect infrastructure, many APIs limit how many requests a client can make within a given time period.&lt;/p&gt;

&lt;p&gt;If the limit is exceeded, the server may return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;429 Too Many Requests
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Developers must design their systems to handle rate limits gracefully.&lt;/p&gt;

&lt;h3&gt;
  
  
  11. Webhooks
&lt;/h3&gt;

&lt;p&gt;Webhooks allow systems to receive real-time notifications when an event occurs, instead of constantly polling an API.&lt;/p&gt;

&lt;p&gt;For example, a payment service may send a webhook when a payment is completed. This pattern is widely used in platforms like the &lt;strong&gt;Stripe API&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  12. API Documentation
&lt;/h3&gt;

&lt;p&gt;Good documentation is essential when working with APIs. Many APIs use tools like &lt;strong&gt;Swagger&lt;/strong&gt;, &lt;strong&gt;Postman&lt;/strong&gt;, or the &lt;strong&gt;OpenAPI Specification&lt;/strong&gt; to clearly describe endpoints, parameters, and responses.&lt;/p&gt;

&lt;p&gt;Being able to read and interpret API documentation is a critical developer skill.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;APIs power the digital world. From payment processing to messaging services and cloud platforms, they enable systems to interact seamlessly.&lt;/p&gt;

&lt;p&gt;For anyone building modern applications, understanding REST, HTTP methods, status codes, JSON, authentication, headers, pagination, rate limits, and webhooks is not optional. It is foundational knowledge that every developer should master. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>beginners</category>
      <category>api</category>
    </item>
    <item>
      <title>What is Vite</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Wed, 18 Feb 2026 09:47:07 +0000</pubDate>
      <link>https://forem.com/msnmongare/what-is-vite-181o</link>
      <guid>https://forem.com/msnmongare/what-is-vite-181o</guid>
      <description>&lt;p&gt;If you just downloaded a React project and saw something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then an error mentioning &lt;strong&gt;vite&lt;/strong&gt;, you might be wondering:&lt;/p&gt;

&lt;p&gt;What exactly is Vite?&lt;/p&gt;

&lt;p&gt;Let us break it down in simple terms.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is Vite?
&lt;/h2&gt;

&lt;p&gt;Vite is a tool that helps you &lt;strong&gt;run and build modern frontend applications&lt;/strong&gt; like React, Vue, or plain JavaScript apps.&lt;/p&gt;

&lt;p&gt;You can think of it as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A development server&lt;/li&gt;
&lt;li&gt;A build tool&lt;/li&gt;
&lt;li&gt;A translator for modern JavaScript&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All combined into one.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Do We Need Vite?
&lt;/h2&gt;

&lt;p&gt;Modern frontend code includes things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSX (used in React)&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;ES Modules&lt;/li&gt;
&lt;li&gt;CSS imports inside JavaScript&lt;/li&gt;
&lt;li&gt;Modern JavaScript features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Browsers do not fully understand all of this directly.&lt;/p&gt;

&lt;p&gt;Vite takes your modern code and converts it into something the browser can understand.&lt;/p&gt;

&lt;p&gt;Without a tool like Vite, your React app would not run properly in the browser.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Does Vite Actually Do?
&lt;/h2&gt;

&lt;p&gt;When you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vite:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Starts a local development server&lt;br&gt;
Usually something like:&lt;br&gt;
&lt;a href="http://localhost:5173" rel="noopener noreferrer"&gt;http://localhost:5173&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Loads your app into the browser&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Watches your files for changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automatically refreshes the browser when you save changes&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This makes development fast and smooth.&lt;/p&gt;




&lt;h2&gt;
  
  
  Simple Analogy
&lt;/h2&gt;

&lt;p&gt;Imagine building a car:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React is the engine components&lt;/li&gt;
&lt;li&gt;Your code is the raw material&lt;/li&gt;
&lt;li&gt;The browser is the driver&lt;/li&gt;
&lt;li&gt;Vite is the factory that assembles everything so the car can run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without the factory, the parts do not become a working car.&lt;/p&gt;




&lt;h2&gt;
  
  
  Is Vite Part of React?
&lt;/h2&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;React is just a JavaScript library for building user interfaces.&lt;/p&gt;

&lt;p&gt;It does not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start a server&lt;/li&gt;
&lt;li&gt;Compile files&lt;/li&gt;
&lt;li&gt;Bundle your code&lt;/li&gt;
&lt;li&gt;Optimize your app for production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vite is what makes your React project actually run during development and prepares it for deployment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Is Vite Popular?
&lt;/h2&gt;

&lt;p&gt;Vite is popular because it is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very fast&lt;/li&gt;
&lt;li&gt;Simple to configure&lt;/li&gt;
&lt;li&gt;Lightweight&lt;/li&gt;
&lt;li&gt;Easy to set up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compared to older tools like Webpack, Vite starts almost instantly and reloads changes much faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Happens If Vite Is Missing?
&lt;/h2&gt;

&lt;p&gt;If you see an error like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'vite' is not recognized as an internal or external command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It usually means:&lt;/p&gt;

&lt;p&gt;You have not installed project dependencies yet.&lt;/p&gt;

&lt;p&gt;The fix is usually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;If you are building modern frontend apps, Vite is the tool that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runs your app locally&lt;/li&gt;
&lt;li&gt;Converts modern code to browser ready code&lt;/li&gt;
&lt;li&gt;Makes development faster&lt;/li&gt;
&lt;li&gt;Prepares your app for production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short:&lt;/p&gt;

&lt;p&gt;Vite is the engine that makes your frontend project come alive.&lt;/p&gt;

</description>
      <category>react</category>
      <category>vite</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The Engineer as a Decision Maker, Not a Developer</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Wed, 11 Feb 2026 08:43:49 +0000</pubDate>
      <link>https://forem.com/msnmongare/the-engineer-as-a-decision-maker-not-a-developer-lid</link>
      <guid>https://forem.com/msnmongare/the-engineer-as-a-decision-maker-not-a-developer-lid</guid>
      <description>&lt;p&gt;For years, the software industry has romanticized the image of the engineer as someone who writes elegant code, masters frameworks, and ships features at lightning speed. But the most valuable engineers today are not defined by how fast they type or how many languages they know.&lt;/p&gt;

&lt;p&gt;They are defined by the quality of their decisions.&lt;/p&gt;

&lt;p&gt;The shift from developer to decision maker is what separates average engineers from high impact engineers. And in a world where AI can generate code in seconds, this shift is no longer optional. It is essential.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Is a Tool. Decisions Create Value.
&lt;/h2&gt;

&lt;p&gt;A junior developer focuses on implementation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How do I build this?&lt;/li&gt;
&lt;li&gt;Which syntax should I use?&lt;/li&gt;
&lt;li&gt;How do I fix this error?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A decision making engineer asks different questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Should we build this at all?&lt;/li&gt;
&lt;li&gt;What problem are we actually solving?&lt;/li&gt;
&lt;li&gt;Is this the simplest solution?&lt;/li&gt;
&lt;li&gt;What are the long term consequences?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference is subtle but powerful.&lt;/p&gt;

&lt;p&gt;Code is the output. Decisions determine whether that output is useful, scalable, secure, and aligned with business goals.&lt;/p&gt;

&lt;p&gt;An engineer who understands tradeoffs between performance and cost, speed and maintainability, abstraction and simplicity becomes far more valuable than someone who only knows how to implement tickets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every Line of Code Is a Liability
&lt;/h2&gt;

&lt;p&gt;Writing code feels productive. But every line added is something that must be maintained, tested, debugged, documented, and eventually refactored.&lt;/p&gt;

&lt;p&gt;A decision driven engineer understands that sometimes the best decision is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reuse instead of rebuild.&lt;/li&gt;
&lt;li&gt;Integrate instead of invent.&lt;/li&gt;
&lt;li&gt;Simplify instead of scale prematurely.&lt;/li&gt;
&lt;li&gt;Delete instead of add.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Strong engineers reduce complexity. They do not increase it just to prove skill.&lt;/p&gt;

&lt;p&gt;They think in systems, not just scripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Choices Are Business Decisions
&lt;/h2&gt;

&lt;p&gt;Choosing a database is not just a technical act. It affects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hosting costs&lt;/li&gt;
&lt;li&gt;Scaling strategy&lt;/li&gt;
&lt;li&gt;Hiring requirements&lt;/li&gt;
&lt;li&gt;Vendor lock in&lt;/li&gt;
&lt;li&gt;Performance under growth&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choosing to microservice too early can slow a startup. Choosing to ignore observability can cost days in downtime. Choosing the wrong payment flow can affect revenue.&lt;/p&gt;

&lt;p&gt;Engineers who understand that architecture impacts money, users, and growth move from being implementers to strategic contributors.&lt;/p&gt;

&lt;p&gt;They stop waiting for instructions. They start shaping direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision Making Requires Context
&lt;/h2&gt;

&lt;p&gt;You cannot make strong engineering decisions without understanding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The product vision&lt;/li&gt;
&lt;li&gt;The customer pain points&lt;/li&gt;
&lt;li&gt;The revenue model&lt;/li&gt;
&lt;li&gt;The team capacity&lt;/li&gt;
&lt;li&gt;The timeline constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why the best engineers attend product meetings, ask business questions, and care about metrics.&lt;/p&gt;

&lt;p&gt;They do not hide behind code.&lt;/p&gt;

&lt;p&gt;They know that a technically perfect solution that misses market timing is a failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Is Raising the Bar
&lt;/h2&gt;

&lt;p&gt;With AI tools generating boilerplate, scaffolding APIs, and even debugging, the value of raw coding skill is decreasing.&lt;/p&gt;

&lt;p&gt;The competitive advantage is now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Problem framing&lt;/li&gt;
&lt;li&gt;Tradeoff analysis&lt;/li&gt;
&lt;li&gt;Risk evaluation&lt;/li&gt;
&lt;li&gt;Architectural thinking&lt;/li&gt;
&lt;li&gt;Clear communication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyone can generate code.&lt;/p&gt;

&lt;p&gt;Not everyone can decide what should be generated.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Task Taker to Owner
&lt;/h2&gt;

&lt;p&gt;A developer waits for a ticket.&lt;/p&gt;

&lt;p&gt;A decision making engineer asks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What outcome are we targeting?&lt;/li&gt;
&lt;li&gt;Is this the highest priority problem?&lt;/li&gt;
&lt;li&gt;Is there a faster way to deliver impact?&lt;/li&gt;
&lt;li&gt;What will break in six months if we do this?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ownership changes everything.&lt;/p&gt;

&lt;p&gt;Instead of “I implemented what I was told,” the mindset becomes, “I am responsible for the result.”&lt;/p&gt;

&lt;p&gt;That shift transforms careers.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Become a Decision Driven Engineer
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Study tradeoffs, not just syntax.&lt;br&gt;
Learn why systems fail. Learn scaling patterns. Learn architectural mistakes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Understand the business model.&lt;br&gt;
If the product makes money from transactions, uptime and performance matter differently than if it makes money from subscriptions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simplify aggressively.&lt;br&gt;
Complexity compounds. Simplicity scales.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Communicate clearly.&lt;br&gt;
The best decisions are useless if you cannot explain them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Think long term.&lt;br&gt;
Ask what this decision looks like at 10x growth.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Future Engineer
&lt;/h2&gt;

&lt;p&gt;The future engineer is not the person who knows the most frameworks.&lt;/p&gt;

&lt;p&gt;It is the person who:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Knows when not to use one.&lt;/li&gt;
&lt;li&gt;Understands impact beyond code.&lt;/li&gt;
&lt;li&gt;Aligns technology with strategy.&lt;/li&gt;
&lt;li&gt;Chooses clarity over cleverness.&lt;/li&gt;
&lt;li&gt;Optimizes for outcomes, not ego.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code is still important. But code is no longer the differentiator.&lt;/p&gt;

&lt;p&gt;Judgment is.&lt;/p&gt;

&lt;p&gt;And the engineers who master decision making will shape products, teams, and industries long after the syntax they once memorized becomes obsolete.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>softwareengineering</category>
      <category>software</category>
      <category>productivity</category>
    </item>
    <item>
      <title>React Hooks Explained (Beginner-Friendly)</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Mon, 09 Feb 2026 05:08:00 +0000</pubDate>
      <link>https://forem.com/msnmongare/react-hooks-explained-beginner-friendly-3ggn</link>
      <guid>https://forem.com/msnmongare/react-hooks-explained-beginner-friendly-3ggn</guid>
      <description>&lt;h2&gt;
  
  
  First: What is a Hook?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;Hook&lt;/strong&gt; is just a &lt;strong&gt;special function React gives you&lt;/strong&gt; to “plug into” React features like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;State&lt;/li&gt;
&lt;li&gt;Lifecycle&lt;/li&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;Performance optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hooks always:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with &lt;code&gt;use&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Are called &lt;strong&gt;inside components only&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Follow predictable rules&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Core Hooks (You should learn these)
&lt;/h2&gt;

&lt;p&gt;These are the hooks you’ll use in &lt;strong&gt;almost every React app&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  1️⃣ &lt;code&gt;useState&lt;/code&gt; — Store changing data
&lt;/h2&gt;

&lt;p&gt;You already know this one 👍&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use it for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Form inputs&lt;/li&gt;
&lt;li&gt;Toggles&lt;/li&gt;
&lt;li&gt;Counters&lt;/li&gt;
&lt;li&gt;Loading states&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mental model:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Component-level variables that cause re-render when changed.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2️⃣ &lt;code&gt;useEffect&lt;/code&gt; — Run side effects
&lt;/h2&gt;

&lt;p&gt;Also familiar now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use it for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API calls&lt;/li&gt;
&lt;li&gt;Subscriptions&lt;/li&gt;
&lt;li&gt;Timers&lt;/li&gt;
&lt;li&gt;Logging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mental model:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Run this after rendering or when something changes.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3️⃣ &lt;code&gt;useContext&lt;/code&gt; — Read global data
&lt;/h2&gt;

&lt;p&gt;Used with React Context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use it for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logged-in user&lt;/li&gt;
&lt;li&gt;Theme&lt;/li&gt;
&lt;li&gt;Language&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mental model:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Read shared data without passing props.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Secondary Hooks (Learn after basics)
&lt;/h2&gt;

&lt;p&gt;These make apps cleaner and faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  4️⃣ &lt;code&gt;useRef&lt;/code&gt; — Store values without re-rendering
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use it for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accessing DOM elements&lt;/li&gt;
&lt;li&gt;Storing values that shouldn’t trigger UI updates&lt;/li&gt;
&lt;li&gt;Timers, counters, previous values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;inputRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mental model:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A box that holds data across renders without re-rendering.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5️⃣ &lt;code&gt;useReducer&lt;/code&gt; — Advanced state logic
&lt;/h2&gt;

&lt;p&gt;Alternative to &lt;code&gt;useState&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;State logic is complex&lt;/li&gt;
&lt;li&gt;Many related state updates exist&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Backend analogy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reducer = controller logic&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6️⃣ &lt;code&gt;useMemo&lt;/code&gt; — Cache expensive calculations
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;heavyCalculation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prevent unnecessary recalculations&lt;/li&gt;
&lt;li&gt;Improve performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mental model:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Only recalculate if inputs change.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7️⃣ &lt;code&gt;useCallback&lt;/code&gt; — Cache functions
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Passing functions to child components&lt;/li&gt;
&lt;li&gt;Preventing unnecessary re-renders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mental model:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Same function instance unless dependencies change.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Advanced / Rare Hooks (Know they exist)
&lt;/h2&gt;

&lt;p&gt;You don’t need these early on, but it’s good to know them.&lt;/p&gt;




&lt;h2&gt;
  
  
  8️⃣ &lt;code&gt;useLayoutEffect&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Like &lt;code&gt;useEffect&lt;/code&gt;, but runs &lt;strong&gt;before browser paint&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Use only when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to measure layout sizes&lt;/li&gt;
&lt;li&gt;You see flickering UI issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚠️ Rarely needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  9️⃣ &lt;code&gt;useImperativeHandle&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Controls what a parent can access from a child component.&lt;/p&gt;

&lt;p&gt;Used with &lt;code&gt;forwardRef&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Advanced use cases only.&lt;/p&gt;




&lt;h2&gt;
  
  
  10️⃣ &lt;code&gt;useId&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Generates unique IDs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Form inputs&lt;/li&gt;
&lt;li&gt;Accessibility (labels)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Custom Hooks (VERY IMPORTANT)
&lt;/h2&gt;

&lt;p&gt;You can create your &lt;strong&gt;own hooks&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useGroups&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setGroups&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;fetchGroups&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setGroups&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use them to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reuse logic&lt;/li&gt;
&lt;li&gt;Keep components clean&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mental model:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Extract reusable logic into a function.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Beginner Learning Order (Recommended)
&lt;/h2&gt;

&lt;p&gt;Here’s the &lt;strong&gt;safe learning path&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;useState&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useEffect&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useContext&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useRef&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useReducer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useMemo&lt;/code&gt; &amp;amp; &lt;code&gt;useCallback&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Custom Hooks&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What You Should NOT Do as a Beginner 🚫
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Don’t memorize all hooks&lt;/li&gt;
&lt;li&gt;Don’t use &lt;code&gt;useMemo&lt;/code&gt; everywhere&lt;/li&gt;
&lt;li&gt;Don’t optimize too early&lt;/li&gt;
&lt;li&gt;Don’t jump to advanced hooks before basics&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Quick Summary Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hook&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Learn When&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;useState&lt;/td&gt;
&lt;td&gt;Local state&lt;/td&gt;
&lt;td&gt;Day 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;useEffect&lt;/td&gt;
&lt;td&gt;Side effects&lt;/td&gt;
&lt;td&gt;Day 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;useContext&lt;/td&gt;
&lt;td&gt;Global state&lt;/td&gt;
&lt;td&gt;Early&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;useRef&lt;/td&gt;
&lt;td&gt;DOM &amp;amp; mutable values&lt;/td&gt;
&lt;td&gt;Early&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;useReducer&lt;/td&gt;
&lt;td&gt;Complex logic&lt;/td&gt;
&lt;td&gt;Intermediate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;useMemo&lt;/td&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Later&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;useCallback&lt;/td&gt;
&lt;td&gt;Stable functions&lt;/td&gt;
&lt;td&gt;Later&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Final Takeaway
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;You don’t need all hooks to build real apps.&lt;br&gt;
You need to &lt;strong&gt;understand a few deeply&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you master:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;useState&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useEffect&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useContext&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can build &lt;strong&gt;most production apps&lt;/strong&gt; comfortably.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The First Big Mistake: Thinking Software Engineering Is Just Coding</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Wed, 04 Feb 2026 10:42:02 +0000</pubDate>
      <link>https://forem.com/msnmongare/the-first-big-mistake-thinking-software-engineering-is-just-coding-490d</link>
      <guid>https://forem.com/msnmongare/the-first-big-mistake-thinking-software-engineering-is-just-coding-490d</guid>
      <description>&lt;p&gt;One of the biggest misconceptions shaping today’s AI panic is the belief that &lt;strong&gt;software engineering equals writing code&lt;/strong&gt;. From that flawed assumption comes an even bigger conclusion: &lt;em&gt;“If AI can write code, then AI will replace software engineers.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This logic sounds convincing-until you understand what software engineering actually is.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coding Is the Output, Not the Job
&lt;/h3&gt;

&lt;p&gt;Writing code is only the &lt;strong&gt;visible output&lt;/strong&gt; of software engineering, not the work itself.&lt;/p&gt;

&lt;p&gt;Software engineering is about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding ambiguous problems&lt;/li&gt;
&lt;li&gt;Translating human needs into technical systems&lt;/li&gt;
&lt;li&gt;Designing architectures that scale&lt;/li&gt;
&lt;li&gt;Making trade-offs between performance, cost, security, and time&lt;/li&gt;
&lt;li&gt;Anticipating failure, misuse, and edge cases&lt;/li&gt;
&lt;li&gt;Maintaining systems long after they are written&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code is simply the medium through which these decisions are expressed.&lt;/p&gt;

&lt;p&gt;If you remove the thinking, the code becomes meaningless.&lt;/p&gt;

&lt;h3&gt;
  
  
  Software Engineering Is Decision-Making Under Constraints
&lt;/h3&gt;

&lt;p&gt;Real-world systems don’t fail because someone didn’t know syntax.&lt;br&gt;
They fail because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requirements were misunderstood&lt;/li&gt;
&lt;li&gt;Assumptions were wrong&lt;/li&gt;
&lt;li&gt;Systems didn’t scale as expected&lt;/li&gt;
&lt;li&gt;Trade-offs weren’t thought through&lt;/li&gt;
&lt;li&gt;Human behavior wasn’t considered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are &lt;strong&gt;engineering problems&lt;/strong&gt;, not typing problems.&lt;/p&gt;

&lt;p&gt;AI can generate code, but it does not &lt;em&gt;own responsibility&lt;/em&gt;. It doesn’t sit in meetings to clarify vague requirements. It doesn’t get paged at 2 a.m. when production is down. It doesn’t weigh business risk against technical purity.&lt;/p&gt;

&lt;p&gt;Engineers do.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI Is Powerful at Code - Weak at Context
&lt;/h3&gt;

&lt;p&gt;AI excels at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pattern matching&lt;/li&gt;
&lt;li&gt;Rewriting existing logic&lt;/li&gt;
&lt;li&gt;Generating boilerplate&lt;/li&gt;
&lt;li&gt;Speeding up repetitive tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But software lives in &lt;strong&gt;context&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business goals change&lt;/li&gt;
&lt;li&gt;Users behave unpredictably&lt;/li&gt;
&lt;li&gt;Legal and compliance rules evolve&lt;/li&gt;
&lt;li&gt;Systems interact with messy, legacy infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Context is not static. It’s political, social, economic, and human. That’s where engineering judgment lives-and where AI struggles the most.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Real Role of a Software Engineer
&lt;/h3&gt;

&lt;p&gt;A software engineer is closer to a &lt;strong&gt;systems thinker&lt;/strong&gt; than a typist.&lt;/p&gt;

&lt;p&gt;They:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ask &lt;em&gt;why&lt;/em&gt; before &lt;em&gt;how&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Challenge requirements that don’t make sense&lt;/li&gt;
&lt;li&gt;Design for failure, not perfection&lt;/li&gt;
&lt;li&gt;Communicate trade-offs to non-technical stakeholders&lt;/li&gt;
&lt;li&gt;Take responsibility for outcomes, not just outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why senior engineers write less code than juniors-but create far more value.&lt;/p&gt;

&lt;h3&gt;
  
  
  What AI Actually Changes
&lt;/h3&gt;

&lt;p&gt;AI doesn’t eliminate software engineers. It &lt;strong&gt;raises the bar&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Just like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compilers didn’t eliminate programmers&lt;/li&gt;
&lt;li&gt;Frameworks didn’t eliminate engineers&lt;/li&gt;
&lt;li&gt;Cloud computing didn’t eliminate infrastructure thinking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI removes low-level friction and exposes who actually understands systems.&lt;/p&gt;

&lt;p&gt;The future belongs to engineers who can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Think clearly&lt;/li&gt;
&lt;li&gt;Reason about systems&lt;/li&gt;
&lt;li&gt;Make sound decisions&lt;/li&gt;
&lt;li&gt;Use AI as a tool, not fear it as a replacement&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The first mistake was reducing software engineering to coding.&lt;br&gt;
The second mistake is assuming automation replaces thinking.&lt;/p&gt;

&lt;p&gt;AI will write more code.&lt;br&gt;
Humans will still decide &lt;strong&gt;what should exist, why it should exist, and whether it should exist at all&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s not going away anytime soon.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>software</category>
    </item>
    <item>
      <title>Passing Props in React (How Components Talk to Each Other)</title>
      <dc:creator>Sospeter Mong'are</dc:creator>
      <pubDate>Wed, 04 Feb 2026 06:50:00 +0000</pubDate>
      <link>https://forem.com/msnmongare/passing-props-in-react-how-components-talk-to-each-other-5654</link>
      <guid>https://forem.com/msnmongare/passing-props-in-react-how-components-talk-to-each-other-5654</guid>
      <description>&lt;h2&gt;
  
  
  Why Passing Props Exists
&lt;/h2&gt;

&lt;p&gt;In React:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Components are &lt;strong&gt;isolated&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;One component cannot access another’s data directly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So how do they communicate?&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Props&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What Are Props?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Props are inputs to a component.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of them like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Function parameters&lt;/li&gt;
&lt;li&gt;API request data&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Simple Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Greeting&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Greeting&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"John"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What’s Happening?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;App&lt;/code&gt; sends data → &lt;code&gt;name="John"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Greeting&lt;/code&gt; receives it → &lt;code&gt;{ name }&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;UI updates based on props&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Backend analogy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Hello &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Props Are Read-Only
&lt;/h2&gt;

&lt;p&gt;❌ This is NOT allowed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mike&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Props are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Immutable&lt;/li&gt;
&lt;li&gt;Owned by the parent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If data must change → it belongs in &lt;strong&gt;state&lt;/strong&gt;, not props.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Beginner Mistake
&lt;/h2&gt;

&lt;p&gt;Trying to store everything in one component.&lt;/p&gt;

&lt;p&gt;Correct mindset:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Components should &lt;strong&gt;receive data&lt;/strong&gt;, not own everything.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Props are how data &lt;strong&gt;flows downward&lt;/strong&gt; in React.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No props → no real app.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>react</category>
    </item>
  </channel>
</rss>
