{"id":25148906,"url":"https://github.com/gabrieldwight/mpesa-sdk-net","last_synced_at":"2025-04-28T14:48:12.560Z","repository":{"id":65959704,"uuid":"321465978","full_name":"gabrieldwight/Mpesa-Sdk-Net","owner":"gabrieldwight","description":"This is a M-Pesa SDK to allow you to integrate Safaricom M-Pesa API in net framework, .NetCore, NET5, NET6 and Net Standard projects.","archived":false,"fork":false,"pushed_at":"2025-02-08T14:43:31.000Z","size":5387,"stargazers_count":18,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-14T12:54:13.874Z","etag":null,"topics":["csharp","daraja","dotnet","mobile-money-payment","mpesa-apis","mpesa-sdk","netcore","netstandard","payment-integration","xamarin","xamarin-forms"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gabrieldwight.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-12-14T20:34:07.000Z","updated_at":"2025-02-08T14:35:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"ff60f1df-bf62-4032-8c9f-625add426521","html_url":"https://github.com/gabrieldwight/Mpesa-Sdk-Net","commit_stats":{"total_commits":104,"total_committers":1,"mean_commits":104.0,"dds":0.0,"last_synced_commit":"6e977dca8ca9d2a90b0a7eaaa3892f4b5ac0682c"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieldwight%2FMpesa-Sdk-Net","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieldwight%2FMpesa-Sdk-Net/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieldwight%2FMpesa-Sdk-Net/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieldwight%2FMpesa-Sdk-Net/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gabrieldwight","download_url":"https://codeload.github.com/gabrieldwight/Mpesa-Sdk-Net/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251333935,"owners_count":21572921,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","daraja","dotnet","mobile-money-payment","mpesa-apis","mpesa-sdk","netcore","netstandard","payment-integration","xamarin","xamarin-forms"],"created_at":"2025-02-08T21:17:35.282Z","updated_at":"2025-04-28T14:48:12.524Z","avatar_url":"https://github.com/gabrieldwight.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mpesa-Sdk-Net\nThis is an M-Pesa SDK that allows you to integrate Safaricom's M-Pesa API in Net Framework, NetCore, NET5, and Net Standard projects. \n[![Build status](https://gabrieldwight.visualstudio.com/MpesaSdk/_apis/build/status/MpesaSdk-CI)](https://gabrieldwight.visualstudio.com/MpesaSdk/_build/latest?definitionId=6)\n[![NuGet version (MpesaSdk)](https://img.shields.io/nuget/v/MpesaSdk.svg?style=flat-square)](https://www.nuget.org/packages/MpesaSdk/)\n \nA .NET Standard M-PESA API Helper Library for .NET Developers.\n- [End User License](https://github.com/gabrieldwight/Mpesa-Sdk-Net/blob/master/LICENSE)\n- [NuGet Package](https://www.nuget.org/packages/MpesaSdk/)\n- [Mpesa Daraja Portal](https://developer.safaricom.co.ke/)\n- [Pull Transaction API](https://documenter.getpostman.com/view/1724456/SVtTy8sd#intro)\n\n## Required API Products Need To be enabled by api support to your mpesa applications\n- Pull Transaction API\n- Dynamic Mpesa QR\n- Mpesa Ratiba\n\n## Supported Platforms\n\n|   *Platform*   | .Net 6.0 | .Net 5.0 | .NET Core | .NET Framework | Mono | Xamarin.iOS | Xamarin.Android | Xamarin.Mac |     UWP    |\n|:--------------:|---------:|---------:|:---------:|:--------------:|:----:|:-----------:|:---------------:|:-----------:|:----------:|\n| *Min. Version* |    6     |    5     |    2.0    |      4.6.1     |  5.4 |    10.14    |       8.0       |     3.8     | 10.0.16299 |\n\n## Installation\n- PackageManager: ```PM\u003e Install-Package MpesaSdk```\n- DotNetCLI: ```\u003e dotnet add package MpesaSdk```\n\n## Setting yourself up for successful Mpesa integration\nBefore proceeding, kindly acquaint yourself with Mpesa Apis by going through the Docs in Safaricom's developer portal or Daraja if you like.\n\n1.  Obtain consumerKey, consumerSecret and Passkey (for Lipa Na Mpesa Online APIs) from daraja portal.\n\n2.  Ensure your project is running on the minimum supported versions of .Net \n\n3.  MpesaSdk is dependency injection (DI) friendly and can be readily injected into your classes. You can read more on DI in Asp.Net core [**here**](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-5.0). If you can't use DI you can always manually create a new instance of MpesaClient and pass in an httpClient instance in its constructor. eg.\n\n```c#\n// When Dependency Injection is not possible...\n\n//create httpclient instance\nvar httpClient = new HttpClient();\n\nhttpClient.BaseAddress = MpesaRequestEndPoint.SandboxBaseAddress; //Use MpesaRequestEndPoint.LiveBaseAddress in production\n\t\n//create Mpesa API client instance\nvar mpesaClient = new MpesaClient(httpClient); //make sure to pass httpclient intance as an argument\n\t\n```\nI would recommend creating MpesaClient using Dependency Injection. [Optional] You can use any IOC container or Microsoft DI container in your legacy projects.\n```c#\n// Adding Dependency Injection into legacy projects\n\npublic static IServiceProvider ServiceProvider;\n\n\n// To be used in the main application startup method\nvoid Application_Start(object sender, EventArgs e)\n{\n  var hostBuilder = new HostBuilder();\n  hostBuilder.ConfigureServices(ConfigureServices);\n  var host = hostBuilder.Build();\n\n  ServiceProvider = host.Services;\n}\n\nvoid ConfigureServices(IServiceCollection services)\n{\n   services.AddHttpClient\u003cIMpesaClient, MpesaClient\u003e(options =\u003e options.BaseAddress = MpesaRequestEndPoint.SandboxBaseAddress);\n   //inject services here\n}\n\t\n```\n\n## Registering MpesaClient \u0026 Set the BaseAddress -Dependency Injection Method in ASPNETCORE\n* Install MpesaSdk Project via Nuget Package Manager Console or Nuget Package Manager GUI.\n\n## For ASPNETCORE projects\n* In **Startup.cs** add the namespace...\n\n```c#    \nusing MpesaSdk;\n```\n\n* Inside ConfigureServices method add the following\n\n```c#\nservices.Configure\u003cMpesaApiConfiguration\u003e(options =\u003e\n            {\n                Configuration.GetSection(\"MpesaApiConfiguration\").Bind(options);\n            });\nservices.AddHttpClient\u003cIMpesaClient, MpesaClient\u003e(options =\u003e options.BaseAddress = MpesaRequestEndPoint.SandboxBaseAddress);\n```\n\n## OR using MpesaSDK Extension\n```c#    \nusing MpesaSdk.Extensions;\n```\n\n* Inside ConfigureServices method add the following\n\n```c#\nservices.Configure\u003cMpesaApiConfiguration\u003e(options =\u003e\n            {\n                Configuration.GetSection(\"MpesaApiConfiguration\").Bind(options);\n            });\nservices.AddMpesaService(Enums.Environment.Sandbox);\n```\n\n\nUse ```MpesaRequestEndPoint.LiveBaseAddress``` as base address/base url in production. You can do an environment check using the IHostingEnvironment property in asp.net core.\n\n* Once the MpesaClient is registered, you can pass it and use it in your classes to make API calls to Mpesa Server as follows;\n```c#\nusing MpesaSdk; //Add MpesaSdk namespace\npublic class PaymentsController\n{\n\tprivate readonly IMpesaClient _mpesaClient;\n\tpublic PaymentsController(IMpesaCleint mpesaClient)\n\t{\n\t\t_mpesaClient = mpesaClient;\n\t}\n\t....\n\t//code omitted for brevity\n}\n```\n\n## Requesting for the Accesstoken\nMpesa APIs require authorization to use the APIs. The accesstoken (auth token) has to be used with each api call. The accesstoken expire after an hour so it is recommended that you use a caching strategy to refresh the token after every hour or less depending on how  much traffic your site has.\n\n* To get an accesstoken, invoke the ``` _mpesaClient.GetAuthTokenAsync(*args); ``` method. You have to await the Async call. use Non-Async method call provided if you cannot leverage async.\n\n```c# \n//Async Method\nvar accesstoken = await _mpesaClient.GetAuthTokenAsync(ConsumerKey, ConsumerSecret);\n\n```\n\nNote that you have to pass in a consusmerKey, ConsumerSecret provided by Mpesa.\n\n\n## C2B Register Urls Request\n```c#\nvar RegisterC2BUrlObject = new CustomerToBusinessRegisterUrl\n(\n  ShortCode: \"ShortCode\",\n  ResponseType: \"ResponseType\",\n  ConfirmationURL: \"ConfirmationURL\",\n  ValidationURL: \"ValidationURL\"\n);\n\nvar c2bRegisterUrlrequest = await _mpesaClient.RegisterC2BUrlAsync(RegisterC2BUrlObject, accesstoken);\n```\n\n## C2B Payment Request (For Sandbox Environment Only)\n```c#\n//C2B Object\nVar CustomerToBusinessSimulateObject = new CustomerToBusinessSimulate\n(\n  ShortCode: \"ShortCode\",\n  CommandID: \"CommandID\",\n  Amount: \"Amount\",\n  Msisdn: \"Msisdn\",\n  BillRefNumber: \"BillRefNumber\"\n);\n\nvar c2brequest = await _mpesaClient.MakeC2BPaymentAsync(CustomerToBusinessSimulateObject, accesstoken);\n```\n\n## LipaNaMpesaOnline/MpesaExpress (STK Push) Payment Request\n\n```c#\n// initialize object with data\nvar MpesaExpressObject = new LipaNaMpesaOnline\n(\n    businessShortCode: \"BusinessShortCode\",\n    timeStamp: \"TimeStamp\",\n    transactionType: \"TransactionType\",\n    amount: \"Amount\",\n    partyA: \"PartyA\",\n    partyB: \"PartyB\",\n    phoneNumber: \"PhoneNumber\",\n    callBackUrl: \"CallBackUrl\",\n    accountReference: \"AccountReference\",\n    transactionDescription: \"TransactionDescription\",\n    passkey: \"PassKey\"\n);\n\n//Make payment request \nvar paymentrequest = await _mpesaClient.MakeLipaNaMpesaOnlinePaymentAsync(MpesaExpressObject, accesstoken));\n\n```\n\n## LipaNaMpesaOnline/MpesaExpress Transaction Query Request\n```c#\nvar QueryLipaNaMpesaTransactionObject = new LipaNaMpesaQuery\n(\n\t businessShortCode: \"LipaNaMpesaOnlineShortCode\",\n\t checkoutRequestId: \"CheckoutRequestID\",\n\t passKey: \"passKey\",\n\t timestamp: \"Timestamp\"\n);\n\nvar stkpushquery = await _mpesaClient.QueryLipaNaMpesaTransactionAsync(QueryLipaNaMpesaTransactionObject, accesstoken);\n```\n\n## B2C Payment Request\n```c#\n//B2C Object\nvar BusinessToCustomerObject = new BusinessToCustomer\n(\n    InitiatorName: \"InitiatorName\", // Test data for initiator like safaricom.x or api_xxx\n    SecurityCredential: \"SecurityCredential\", // Password credential used in mpesa portal (Use MpesaSdk.Extensions.MpesaCredentials)\n    CommandID: \"CommandID\", // Please use the correct command -usage depends on what is enabled for your shortcode. More info \n    Amount: \"Amount\",\n    PartyA: \"PartyA\", // Test for Party A 603047\n    PartyB: \"PartyB\", // Receipient Phone Number (07XXXX123) \n    Remarks: \"Remarks\",\n    QueueTimeOutURL: \"QueueTimeOutURL\", // URL to send the B2C timeout results\n    ResultURL: \"ResultURL\" // URL to send the B2C callback results\n    Occasion: \"Occasion\"\n);\n\nvar b2crequest = await _mpesaClient.MakeB2CPaymentAsync(BusinessToCustomerObject, accesstoken);\n\n```\n\n## B2B Payment Request\n\n```c#\nvar BusinessToBusinessObject = new BusinessToBusinessDto\n( \n  InitiatorName: \"InitiatorName\", // Test data for initiator like safaricom.x or api_xxx\n  SecurityCredential: \"SecurityCredential\", // Password credential used in mpesa portal (Use MpesaSdk.Extensions.MpesaCredentials)\n  CommandID: \"CommandID\", // Please use the correct command -usage depends on what is enabled for your shortcode. More info\n  SenderIdentifierType: \"SenderIdentifierType\", // Test for paybill identifiertype 4\n  RecieverIdentifierType: \"RecieverIdentifierType\", // Test for paybill identifiertype 4. Read on receiver identifier types from daraja\n  Amount: \"Amount\",\n  PartyA: \"PartyA\", // Test for Party A 603047\n  PartyB: \"PartyB\", // Test for Party B 600000\n  AccountReference: \"AccountReference\"\n  Remarks: \"Remarks\",\n  QueueTimeOutURL: \"QueueTimeOutURL\", // URL to send the B2B timeout results\n  ResultURL: \"ResultURL\" // URL to send the B2B callback results\n);\n\nvar b2brequest = await _mpesaClient.MakeB2BPaymentAsync(BusinessToBusinessObject, accesstoken);\n\n```\n\n## Transaction Status Request\n```c#\nvar TransactionStatusObject = new MpesaTransactionStatus\n(  \n  Initiator: \"Initiator\", // Test data for initiator like safaricom.x or api_xxx\n  SecurityCredential: \"SecurityCredential\", // Password credential used in mpesa portal (Use MpesaSdk.Extensions.MpesaCredentials)\n  CommandID: \"CommandID\", // Command set to \"TransactionStatusQuery\"\n  TransactionID: \"TransactionID\", // TransactionID from the Mpesa reference that is tied to the short code that performed either a B2C, C2B or B2B\n  PartyA: \"PartyA\", // Test for Party A 603047 OR 07XXXX123. Organization/MSISDN receiving the transaction\n  IdentifierType: \"IdentifierType\"\n  Remarks: \"Remarks\",\n  QueueTimeOutURL: \"QueueTimeOutURL\", // URL to send the TransactionStatus timeout results\n  ResultURL: \"ResultURL\", // URL to send the TransactionStatus callback results\n  Occassion: \"Occasion\"\n);\n\nvar transactionrequest = await _mpesaClient.QueryMpesaTransactionStatusAsync(TransactionStatusObject, accesstoken);\n```\n## Pull Transaction Register Url Request\n```C#\nvar pullTransactionRegisterObject = new PullTransactionRegisterUrl\n(\n  ShortCode: \"ShortCode\",\n  RequestType: \"RequestType\",\n  NominatedNumber: \"NominatedNumber\",\n  CallBackURL: \"CallBackUrl\"\n);\n\nvar pullTransactionRegisterRequest = await _mpesaClient.RegisterPullTransactionAsync(pullTransactionRegisterObject, accesstoken);\n```\n\n## Pull Transaction Query Request\n```C#\nvar pullTransactionQueryObject = new PullTransactionQuery\n(\n  ShortCode: \"ShortCode\",\n  StartDate: \"StartDate\",\n  EndDate: \"EndDate\",\n  OffSetValue: \"OffSetValue\"\n);\n\nvar pullTransactionRequest = await _mpesaClient.QueryPullTransactionAsync(pullTransactionQueryObject, accesstoken);\n```\n\n## Account Balance Query Request\n```c#\nvar AccountBalanceObject = new AccountBalance\n(\t\n  Initiator: \"Initiator\", // Test data for initiator like safaricom.x or api_xxx\n  SecurityCredential: \"SecurityCredential\", // Password credential used in mpesa portal (Use MpesaSdk.Extensions.MpesaCredentials)\n  CommandID: \"CommandID\", // Command set to \"AccountBalance\"\n  PartyA: \"PartyA\", // Test for Party A 603047. Organization/MSISDN receiving the transaction\n  IdentifierType: \"IdentifierType\"\n  Remarks: \"Remarks\",\n  QueueTimeOutURL: \"QueueTimeOutURL\", // URL to send the AccountBalance timeout results\n  ResultURL: \"ResultURL\", // URL to send the AccountBalance callback results\n);\n\nvar accountbalancerequest = await _mpesaClient.QueryAccountBalanceAsync(AccountBalanceObject, accesstoken); //async method\n\n```\n\n## Transaction Reversal Request. Must be done using the short code that receives a credit amount\n```c#\nvar TransactionReversalObject = new Reversal\n(\n  Initiator: \"Initiator\", // Test data for initiator like safaricom.x or api_xxx\n  SecurityCredential: \"SecurityCredential\", // Password credential used in mpesa portal (Use MpesaSdk.Extensions.MpesaCredentials)\n  CommandID: \"CommandID\", // Command set to \"TransactionReversal\"\n  TransactionID: \"TransactionID\", // TransactionID from the Mpesa reference that is tied to the short code that performed either a C2B or B2B.\n  ReceiverParty: \"ReceiverParty\", // Test for Party A 603047. Organization/MSISDN receiving the transaction\n  RecieverIdentifierType: \"RecieverIdentifierType\",\n  Remarks: \"Remarks\",\n  QueueTimeOutURL: \"QueueTimeOutURL\", // URL to send the TransactionReversal timeout results\n  ResultURL: \"ResultURL\", // URL to send the TransactionReversal callback results\n  Occasion: \"Occasion\"\n);\n\nvar reversalrequest = await _mpesaClient.ReverseMpesaTransactionAsync(TransactionReversalObject, accesstoken);\n\n```\n\n## Getting Security Credential for B2B, B2C, Reversal, Transaction Status and Account Balance APIs\nThe Security Credential helper class is in MpesaSdk.Extensions namespace.\n\nThis class helps you generate the required credential to be used to authorize the above mentioned APIs.\n\n```c#\nusing MpesaSdk.Extensions; // add this to your class or namespace\n\n//get path to Mpesa public certificate. There are different certs for development and for production, ensure to use the correct one)\n#if DEBUG\n  string certificate = @\"..\\sandbox.cer\";\n#else\n  string certificate = @\"..\\prod.cer\";\n#endif\n \n //generate security credential as follows... Initiator password from daraja\n\nvar SecutityCredential = Credentials.EncryptPassword(certificate, \"Initiator Password\");\n\n```\n\n## Dynamic Mpesa QR Request\n```c#\nDynamicMpesaQR dynamicMpesaQR = new DynamicMpesaQR(qrVersion: \"01\",\n                qrFormat: 1, // 1, 2, 3 or 4\n                qrType: \"D\", // D or S\n                merchantName: dynamicQR.MerchantName,\n                refNo: dynamicQR.Reference,\n                amount: dynamicQR.Amount,\n                trxCode: \"PB\", // BG, WA, PB, SM or SB\n                cpi: dynamicQR.CPI);\n\t\t\nDynamicMpesaQRResponse dynamicMpesaQRResponse = await _mpesaClient.GenerateDynamicMpesaQRAsync(dynamicMpesaQR, accessToken);\n```\n\n## Error handling\nMpesaClient Throws ```MpesaApiException``` whenever A 200 status code is not returned. It is your role as the developer to catch\nthe exception and continue processing in your aplication. Snippet below shows how you can catch the MpesaApiException.\n\n```c#\nusing MpesaSdk.Exceptions; // add this to you class or namespace\n\n\ntry\n{\t\n\treturn await _mpesaClient.MakeLipaNaMpesaOnlinePaymentAsync(MpesaPayment, accesstoken);\n}\ncatch (MpesaApiException e)\n{\n\t_logger.LogError(ex, ex.Message);\n}\n\t\t\t\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrieldwight%2Fmpesa-sdk-net","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgabrieldwight%2Fmpesa-sdk-net","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrieldwight%2Fmpesa-sdk-net/lists"}