Mpesa.SDK.AspNetCore 1.0.1

.NET Core 3.1
NuGet\Install-Package Mpesa.SDK.AspNetCore -Version 1.0.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
dotnet add package Mpesa.SDK.AspNetCore --version 1.0.1
<PackageReference Include="Mpesa.SDK.AspNetCore" Version="1.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Mpesa.SDK.AspNetCore --version 1.0.1
#r "nuget: Mpesa.SDK.AspNetCore, 1.0.1"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install Mpesa.SDK.AspNetCore as a Cake Addin
#addin nuget:?package=Mpesa.SDK.AspNetCore&version=1.0.1

// Install Mpesa.SDK.AspNetCore as a Cake Tool
#tool nuget:?package=Mpesa.SDK.AspNetCore&version=1.0.1

Mpesa.SDK.AspNetCore

Mpesa.SDK.AspNetCore is a Library for asp.net core that implements the Daraja API which is documented at Safaricom. It creates a simple interface that can be used to call the M-Pesa API.

ASP.NET Core Usage

Installation

PM> Install-Package Mpesa.SDK.AspNetCore

Usage

Library consists of the following interfaces:

ILipaNaMpesa - StkPush and QueryStatus
IC2B - QueryBalance, QueryTransactionStatus, ReverseTransaction, RegisterUrl, SimulateTransaction
IB2C - QueryBalance, QueryTransactionStatus, ReverseTransaction, SendMoney
IB2B - To come soon

Add configuration to appsettings.json. Only add configuration relevant to the interface you want to use.
{
  "Mpesa": {
    "B2C": {
      "ConsumerKey": "",
      "ConsumerSecret": "",
      "ShortCode": "",
      "Initiator": "",
      "InitiatorPassword": "",
      "IsLive": false,
      "CallbackURL": "https://example.com/webhook"
    },
    "C2B": {
      "ConsumerKey": "",
      "ConsumerSecret": "",
      "ShortCode": "",
      "Initiator": "",
      "InitiatorPassword": "",
      "IsLive": false,
      "CallbackURL": "https://example.com/webhook"
    },
    "LipaNaMpesa": {
      "ConsumerKey": "",
      "ConsumerSecret": "",
      "ShortCode": "",
      "PassKey": "",
      "IsLive": false,
      "CallbackURL": "https://example.com/webhook"
    }
  }
}

The callback has a predefined ending. For Example
Balance Callback ends with /<requestId>/balance the requestId will be randomly generated
and will be present for storage before the callback responds.
The CallbackUrl should always point to a controller.

Add to Startup class
services.AddMpesaSdk(Configuration);
Use dependency injection with the interface you require
public class HomeController : ControllerBase
    {
        private readonly ILipaNaMpesa lnm;
        private readonly IC2B c2b;
        private readonly IB2C b2c;
        private readonly ILogger _logger;

        public HomeController(ILipaNaMpesa lnm, IC2B c2b, IB2C b2c, ILogger<HomeController> logger)
        {
            this.lnm = lnm;
            this.c2b = c2b;
            this.b2c = b2c;
            _logger = logger;
        }

        [HttpGet]
        public async Task<IActionResult> Get()
        {
            // STK Push
            var stk = await lnm.PushStk("254712345678", "10", "My Account");

            // STK Query
            var query = await lnm.QueryStatus("ws_CO_031120201658538238");

            // Check C2B Account Balance. Can also do forn B2C.
            var c2bBalance = await c2b.QueryBalance();

            // Check C2B transaction status. Can also do forn B2C
            var c2bStatus = await c2b.QueryTransactionStatus("OJQERYZFSR", Mpesa.SDK.Account.IdentifierTypeEnum.Organization);

            // Reverse C2B Transaction. Can also do forn B2C
            var reverse = await c2b.RequestReversal("OFRJUI4TAZ", "700");

            // Send Money through B2C
            var sendB2C = await b2c.SendMoney("254712345678", "27.28");

            return Ok("Ok");
        }
    }

The WebhookController

public class WebhookController : ControllerBase
    {
        [HttpPost("{requestId}/balance")]
        public IActionResult QueryBalanceCallback(string requestId, BalanceQueryCallbackResponse response)
        {
            if (response == null)
                return Ok(new { ResultCode = 1, ResultDesc = "Rejecting the transaction" });

            if (response.Success)
                logger.LogInformation("Balance Callback Data: {@Balance}", response.Data);
            else
                logger.LogError("Balance Callback Error: {@Error}", response.Error);

            return Ok(new { ResultCode = "00000000", ResponseDesc = "success" });
        }

        [HttpPost("{requestId}/status")]
        public IActionResult QueryStatusCallback(string requestId, StatusQueryCallbackResponse response)
        {
            if (response == null)
                return Ok(new { ResultCode = 1, ResultDesc = "Rejecting the transaction" });

            if (response.Success)
                logger.LogInformation("Transaction Status Callback Data: {@Data}", response.Data);
            else
                logger.LogError("Transaction Status Callback Error: {@Error}", response.Error);

            return Ok(new { ResultCode = "00000000", ResponseDesc = "success" });
        }

        [HttpPost("{requestId}/reversal")]
        public IActionResult ReverseCallback(string requestId, ReverseCallbackResponse response)
        {
            if (response == null)
                return Ok(new { ResultCode = 1, ResultDesc = "Rejecting the transaction" });

            if (response.Success)
                logger.LogInformation("Reverse Transaction Callback Data: {@Data}", response.Data);
            else
                logger.LogError("Reverse transaction Callback Error: {@Error}", response.Error);

            return Ok(new { ResultCode = "00000000", ResponseDesc = "success" });
        }

        [HttpPost("{requestId}/b2c")]
        public IActionResult B2CCallback(string requestId, B2CCallbackResponse response)
        {
            if (response == null)
                return Ok(new { ResultCode = 1, ResultDesc = "Rejecting the transaction" });

            if (response.Success)
                logger.LogInformation("B2C Callback Data: {@Data}", response.Data);
            else
                logger.LogError("B2C Callback Error: {@Error}", response.Error);

            return Ok(new { ResultCode = "00000000", ResponseDesc = "success" });
        }

        [HttpPost("{requestId}/lnm")]
        public IActionResult LipaNaMpesaCallback(string requestId, LipaNaMpesaCallbackResponse response)
        {
            if (response == null)
                return Ok(new { ResultCode = 1, ResultDesc = "Rejecting the transaction" });

            if (response.Success)
                logger.LogInformation("Lipa Na Mpesa Callback Data: {@Data}", response.Data);
            else
                logger.LogError("Lipa Na Mpesa Callback Error: {@Error}", response.Error);

            return Ok(new { ResultCode = "00000000", ResponseDesc = "success" });
        }

        [HttpPost("c2b/confirmation")]
        public IActionResult C2BPaymentCallback(C2BCallbackResponse response)
        {
            if (response == null)
                return Ok(new { ResultCode = 1, ResultDesc = "Rejecting the transaction" });

            if (response.Success)
                logger.LogInformation("C2B Payment Confirmation: {@Data}", response.Data);

            return Ok(new { ResultCode = 0, ResponseDesc = "success" });
        }
    }
Product Versions
.NET net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows
.NET Core netcoreapp3.1
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.1 340 11/3/2020
1.0.0 250 10/31/2020

Webook support
Secure Webook call by havin random string to each call