Safaricom.Daraja 0.2.0

dotnet add package Safaricom.Daraja --version 0.2.0
                    
NuGet\Install-Package Safaricom.Daraja -Version 0.2.0
                    
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.
<PackageReference Include="Safaricom.Daraja" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Safaricom.Daraja" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Safaricom.Daraja" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Safaricom.Daraja --version 0.2.0
                    
#r "nuget: Safaricom.Daraja, 0.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Safaricom.Daraja@0.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Safaricom.Daraja&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Safaricom.Daraja&version=0.2.0
                    
Install as a Cake Tool

Safaricom.Daraja

NuGet NuGet Downloads Build Status License: MIT .NET Sponsor via Pesapal

An idiomatic .NET SDK for Safaricom's Daraja API, with first-class Sandbox/Production environment switching and one shared OAuth session across every product area.

Authored by Modi97 / Jose Modi.

Status: early preview (v0.2.0), published to NuGet.org. All four packages below are implemented and tested, including live verification against the real Daraja Sandbox — see Verified against the live Sandbox.


Coverage

Area Status
OAuth (client credentials)
M-Pesa Express (STK Push + Query)
Customer to Business (C2B register + simulate)
Business to Customer (B2C, incl. B2Pochi)
Business to Business (B2B, incl. Tax Remittance)
Transaction Reversal
Transaction Status Query
Account Balance
M-Pesa Ratiba (standing orders)
Lipa na Bonga ✅ (raw JSON — undocumented product, see note below)
Pull Transactions API
Dynamic QR Code
Bill Manager (opt-in, invoicing, cancellation)
ASP.NET Core DI + webhook mapping
CLI tool (dotnet-safaricom-daraja)
IoT SIM-portal / IMSI (Safaricom.Daraja.IoT) ✅ (raw JSON — undocumented product, see note below)

Installation

dotnet add package Safaricom.Daraja
dotnet add package Safaricom.Daraja.AspNetCore   # optional: DI + webhook mapping
dotnet add package Safaricom.Daraja.IoT          # optional: SIM-portal / IMSI (separate product, see below)
dotnet tool install --global dotnet-safaricom-daraja   # optional: CLI setup wizard

Quickstart

using Safaricom.Daraja;
using Safaricom.Daraja.Models;

var client = new DarajaClient(new DarajaConfig
{
    Environment = DarajaEnvironment.Sandbox, // or DarajaEnvironment.Production
    ConsumerKey = "YOUR_CONSUMER_KEY",
    ConsumerSecret = "YOUR_CONSUMER_SECRET",
});

// Or via environment variables: DARAJA_CONSUMER_KEY, DARAJA_CONSUMER_SECRET, DARAJA_ENVIRONMENT
// var client = new DarajaClient(new DarajaConfig());

Every service is a property on DarajaClient, sharing one cached OAuth token underneath:

STK Push (Lipa na M-Pesa Online)

var push = await client.StkPush.PushAsync(new StkPushRequest
{
    ShortCode = "174379",
    Passkey = "YOUR_LIPA_NA_MPESA_PASSKEY",
    TransactionType = StkTransactionType.CustomerPayBillOnline,
    Amount = 1,
    PhoneNumber = "254712345678",
    CallBackURL = "https://example.com/mpesa/stk-callback",
    AccountReference = "INV-0001",
    TransactionDesc = "Order payment",
});

var status = await client.StkPush.QueryAsync(new StkPushQueryRequest
{
    ShortCode = "174379",
    Passkey = "YOUR_LIPA_NA_MPESA_PASSKEY",
    CheckoutRequestId = push.CheckoutRequestId!,
});

C2B

await client.C2B.RegisterUrlAsync(new C2BRegisterUrlRequest
{
    ShortCode = "600000",
    ResponseType = nameof(C2BResponseType.Completed),
    // Daraja rejects ValidationURL/ConfirmationURL values containing the word "mpesa" with a
    // 400 ("Bad Request - Invalid ValidationURL - URL has the word MPESA") - confirmed live
    // against the Sandbox. Avoid it in these two URLs specifically.
    ConfirmationURL = "https://example.com/payments/c2b/confirmation",
    ValidationURL = "https://example.com/payments/c2b/validation",
});

// Sandbox only: simulate a customer paying in
await client.C2B.SimulateAsync(new C2BSimulateRequest
{
    ShortCode = "600000",
    CommandID = nameof(C2BCommandId.CustomerPayBillOnline),
    Amount = "100",
    Msisdn = "254712345678",
    BillRefNumber = "INV-0001",
});

B2C / B2B / Reversal / Transaction Status / Account Balance

These all require a SecurityCredential — the Initiator password RSA-encrypted with Safaricom's public certificate:

using Safaricom.Daraja.Security;

// Download YOUR environment's certificate from the Daraja portal (Sandbox and
// Production certificates differ) — see the security note below.
var securityCredential = SecurityCredentialEncryptor.EncryptFromCertificateFile(
    "certs/production-cert.cer",
    "YourInitiatorPassword");

await client.B2C.SendAsync(new B2CRequest
{
    InitiatorName = "apiuser",
    SecurityCredential = securityCredential,
    CommandID = nameof(B2CCommandId.BusinessPayment),
    Amount = "500",
    PartyA = "600000",
    PartyB = "254712345678",
    Remarks = "Refund",
    QueueTimeOutURL = "https://example.com/mpesa/b2c/timeout",
    ResultURL = "https://example.com/mpesa/b2c/result",
});

// Tax Remittance is the same B2B endpoint under the hood:
await client.B2B.PayTaxesAsync(
    initiator: "apiuser",
    securityCredential: securityCredential,
    businessShortCode: "600000",
    kraShortCode: "YOUR_KRA_SHORTCODE_FROM_DARAJA_PORTAL",
    paymentRegistrationNumber: "PRN123456",
    amount: 1000,
    remarks: "VAT remittance",
    queueTimeOutUrl: "https://example.com/mpesa/b2b/timeout",
    resultUrl: "https://example.com/mpesa/b2b/result");

The Result (success/failure, amounts, transaction IDs) for all of the above arrives asynchronously as a callback posted to your ResultURL — model it with Safaricom.Daraja.Models.DarajaResultCallback when you build the receiving endpoint.

M-Pesa Ratiba (standing orders)

await client.Ratiba.CreateAsync(new RatibaCreateRequest
{
    StandingOrderName = "Monthly subscription",
    BusinessShortCode = "174379",
    TransactionType = "Standing Order Customer Pay Bill",
    Amount = "500",
    PartyA = "254712345678",
    ReceiverPartyIdentifierType = ((int)RatibaReceiverType.Paybill).ToString(),
    CallBackURL = "https://example.com/mpesa/ratiba-callback",
    AccountReference = "SUB-001",
    TransactionDesc = "Monthly subscription",
    Frequency = ((int)RatibaFrequency.Monthly).ToString(),
    StartDate = "2026-10-01",
    EndDate = "2027-10-01",
});

Dynamic QR Code

var qr = await client.QrCode.GenerateAsync(new QrCodeRequest
{
    MerchantName = "Example Store",
    ReferenceNo = "INV-0001",
    Amount = 500,
    TransactionCode = QrTransactionCode.PayBill,
    CreditPartyIdentifier = "174379",
});

System.IO.File.WriteAllBytes("qr.png", qr.ToPngBytes());

Bill Manager

await client.BillManager.OptInAsync(new BillManagerOptInRequest
{
    ShortCode = "174379",
    Email = "billing@example.com",
    OfficialContact = "254712345678",
    SendReminders = 1,
    CallbackUrl = "https://example.com/mpesa/billmanager/reconciliation",
});

await client.BillManager.SendSingleInvoiceAsync(new BillManagerInvoice
{
    ExternalReference = "INV-0002",
    BilledFullName = "Jane Doe",
    BilledPhoneNumber = "254712345678",
    BilledPeriod = "2026-09-01",
    InvoiceName = "September rent",
    DueDate = "2026-09-30",
    AccountReference = "RENT-0002",
    Amount = 15000,
    InvoiceItems = new() { new BillManagerInvoiceItem { ItemName = "Rent", Amount = 15000 } },
});

ASP.NET Core: DI + webhook mapping

using Safaricom.Daraja;
using Safaricom.Daraja.AspNetCore;
using Safaricom.Daraja.Models;

var builder = WebApplication.CreateBuilder(args);

// From appsettings.json section "Daraja" (ConsumerKey, ConsumerSecret, Environment, BaseAddress),
// or from DARAJA_* environment variables:
builder.Services.AddDaraja(builder.Configuration);

var app = builder.Build();

// STK Push callback
app.MapStkCallback("/mpesa/stk-callback", async (callback, ctx) =>
{
    if (callback.IsSuccess)
    {
        var receipt = callback.GetMetadataValue("MpesaReceiptNumber");
        // await orders.MarkPaidAsync(callback.CheckoutRequestId, receipt);
    }
});

// C2B: Validation (accept/reject) and Confirmation (informational, already settled)
app.MapC2BValidation("/mpesa/c2b/validation", async (callback, ctx) =>
{
    var known = await accounts.ExistsAsync(callback.BillRefNumber);
    return known ? C2BValidationResponse.Accept() : C2BValidationResponse.Reject("Unknown account");
});

app.MapC2BConfirmation("/mpesa/c2b/confirmation", async (callback, ctx) =>
{
    // await ledger.RecordAsync(callback);
});

// Shared Result envelope for B2C / B2B / Reversal / Transaction Status / Account Balance —
// map the same handler at both ResultURL and QueueTimeOutURL.
app.MapResultCallback("/mpesa/b2c/result", async (result, ctx) =>
{
    if (result.IsSuccess)
    {
        var transactionId = result.TransactionId;
        // ...
    }
});

// Bill Manager reconciliation (posted to the callback URL you gave OptInAsync)
app.MapBillManagerReconciliation("/mpesa/billmanager/reconciliation", async (payload, ctx) =>
{
    // await invoices.MarkPaidAsync(payload.ExternalReference, payload.PaidAmount);
});

app.Run();

Each Map* helper disables antiforgery on that route (these are server-to-server callbacks, not browser form posts) and returns the acknowledgement Daraja expects automatically — your handler only needs to react to the payload.

The same processing logic is available for MVC controllers via DarajaWebhookHandler (e.g. DarajaWebhookHandler.ProcessResultCallbackAsync(Request, onResult) from a controller action) if you'd rather not use Minimal API routing.


CLI tool

dotnet tool install --global dotnet-safaricom-daraja
# Interactive setup wizard: configure credentials, pick a host style, scaffold sample code
safaricom-daraja init

# Non-interactive
safaricom-daraja init --consumer-key YOUR_KEY --consumer-secret YOUR_SECRET \
  --environment Sandbox --shortcode 174379 --passkey YOUR_PASSKEY --framework minimal -y

# Verify your credentials work against Daraja
safaricom-daraja token

# Raise an STK Push, then check its outcome
safaricom-daraja stk --shortcode 174379 --passkey YOUR_PASSKEY --phone 254712345678 \
  --amount 1 --callback-url https://example.com/mpesa/stk-callback
safaricom-daraja stk --shortcode 174379 --passkey YOUR_PASSKEY --query ws_CO_...

# C2B: register callback URLs, or (Sandbox only) simulate an incoming payment
safaricom-daraja c2b --shortcode 600000 --confirmation-url https://example.com/payments/c2b/confirmation \
  --validation-url https://example.com/payments/c2b/validation
safaricom-daraja c2b --simulate --shortcode 600000 --phone 254712345678 --amount 100 --bill-ref INV-0001

# B2C / B2B / Reversal / Transaction Status / Account Balance all need a SecurityCredential
safaricom-daraja b2c --initiator apiuser --shortcode 600000 --phone 254712345678 --amount 500 \
  --remarks Refund --result-url https://example.com/mpesa/b2c/result --timeout-url https://example.com/mpesa/b2c/timeout \
  --cert path/to/cert.cer --initiator-password YourInitiatorPassword

# Dynamic QR Code
safaricom-daraja qr --merchant-name "Example Store" --reference-no INV-0001 --amount 500 --cpi 174379 --output qr.png

# M-Pesa Ratiba standing order
safaricom-daraja ratiba --name "Monthly subscription" --shortcode 174379 --phone 254712345678 --amount 500 \
  --callback-url https://example.com/mpesa/ratiba-callback --account-reference SUB-001 \
  --start-date 2026-10-01 --end-date 2027-10-01

# Bill Manager
safaricom-daraja bill-manager --optin --shortcode 174379 --email billing@example.com \
  --contact 254712345678 --callback-url https://example.com/mpesa/billmanager/reconciliation

# Offline cryptography self-check (SecurityCredential RSA round-trip, STK password format)
safaricom-daraja test

Every core Daraja service area (STK Push/Query, C2B, B2C, B2B + Tax Remittance, Reversal, Transaction Status, Account Balance, Ratiba, Lipa na Bonga, Pull API, Dynamic QR, Bill Manager) has a CLI command — run safaricom-daraja --help for the full flag reference for each. (The Safaricom.Daraja.IoT module isn't wired into the CLI — it's a separate package with a different auth model.)

init detects whether you're in an ASP.NET Core Minimal API, MVC, or plain console project and scaffolds a working STK Push example (endpoint/controller + callback handler) plus an appsettings.json "Daraja" section, wired for AddDaraja(builder.Configuration).


Environment switching

var config = new DarajaConfig
{
    Environment = DarajaEnvironment.Sandbox, // default — fails safe against real money
    // Environment = DarajaEnvironment.Production,
    ConsumerKey = "...",
    ConsumerSecret = "...",
};

DarajaConfig also reads DARAJA_CONSUMER_KEY, DARAJA_CONSUMER_SECRET, DARAJA_ENVIRONMENT (Sandbox/Production), and DARAJA_BASE_ADDRESS from environment variables as a fallback, so credentials never need to be hardcoded.

C2B.SimulateAsync throws if called against Production — Safaricom doesn't expose a simulate endpoint there, since live payments arrive through real M-Pesa traffic.


Security note: the SecurityCredential certificate

B2C, B2B, Reversal, and Account Balance all require a SecurityCredential: your Initiator password, RSA-encrypted with a Safaricom-issued public certificate. This SDK does not bundle either certificate. Third-party copies circulating in various open-source repos have in the past turned out to be the wrong certificate (silently producing credentials Daraja rejects) — always download yours directly from the Daraja developer portal (Docs → APIs → Authorization), and note that Sandbox and Production use different certificates.

var securityCredential = SecurityCredentialEncryptor.EncryptFromCertificateFile(
    "path/to/your-downloaded-cert.cer",
    "YourInitiatorPassword");

A known Daraja quirk this SDK handles for you

  • C2B RegisterUrl typo: Daraja's own response ships the field misspelled as OriginatorCoversationID. C2BRegisterUrlResponse.OriginatorConversationId maps to that exact wire spelling so you don't have to think about it.
  • Bill Manager's inconsistent envelope: unlike the rest of Daraja (ResponseCode/ResponseDescription), Bill Manager responses use rescode/resmsg. BillManagerResponse maps both.
  • OAuth expires_in is a string, not a JSON number. DarajaToken parses it defensively.
  • C2B RegisterUrl rejects any callback URL containing the word "mpesa" — confirmed live against the Sandbox: ValidationURL/ConfirmationURL values like https://example.com/mpesa/c2b/validation fail with a 400 (Bad Request - Invalid ValidationURL - URL has the word MPESA). This SDK can't work around it for you since it's an outbound URL you choose — just avoid the word in that specific path; every example in this repo uses /payments/... instead.

Verified against the live Sandbox

The core client, OAuth flow, and STK Push were run against Safaricom's real Sandbox during development (not just unit-tested against mocks) using the samples/Safaricom.Daraja.Sample.Console project:

  • ✅ OAuth token acquisition — real tokens issued and cached correctly, across multiple runs.
  • ✅ STK Push + Query — real CheckoutRequestIDs returned and successfully queried (result codes varied run to run as expected: 4999 "still processing", 1037 "user cannot be reached" — both are Daraja telling you nobody entered a PIN on the Sandbox test number, not SDK errors).
  • ✅ C2B Simulate — accepted successfully.
  • ⚠️ C2B RegisterUrl — the request shape is confirmed correct (Daraja validated and rejected the URL content specifically, proving the payload parsed correctly), but registration then hit a 500 Service is currently unreachable on retry. Shortcode 174379 is Safaricom's shared public Sandbox test shortcode used by every Daraja developer worldwide, so this looks like registration contention on that shortcode rather than an SDK issue — try your own dedicated Sandbox shortcode if you hit the same thing.
  • ⚠️ Dynamic QR Code — consistently returned an HTTP 503 with an infrastructure-level "Application is not available" HTML page (not a Daraja JSON error), suggesting that specific Sandbox microservice was down during testing rather than a request-shape problem. Untested beyond that.

Safaricom.Daraja.IoT: SIM-portal & IMSI

This is a separate Safaricom product from core Daraja — it shares the same Sandbox/Production hosts, but a different auth/header scheme, and it isn't part of Safaricom's public Daraja documentation. It's bundled here because it shipped in the same source Postman collection this whole SDK was built from.

using Safaricom.Daraja.IoT;
using Safaricom.Daraja.IoT.Models;

var iot = new IoTClient(new IoTConfig
{
    ApiKey = "YOUR_X_API_KEY",
    Msisdn = "254712345678", // your operating system's identifying MSISDN
    // Either supply a pre-acquired token directly...
    AccessToken = "YOUR_BEARER_TOKEN",
    // ...or let the SDK fetch/cache one via /oauth/v1/generate, same as core Daraja
    // (unconfirmed whether this product accepts that flow for your app registration - try it):
    // ConsumerKey = "...", ConsumerSecret = "...",
});

var result = await iot.Messaging.SendSingleMessageAsync(new SendSingleMessageRequest
{
    Msisdn = "254712345678",
    Message = "Your SIM has been activated.",
    VpnGroup = "your-vpn-group",
    Username = "your-portal-username",
});

Console.WriteLine(result.Json); // raw response - see note below

Why raw JSON, not typed models? Every response in this module comes back as DarajaRawResult.Json rather than a typed C# object. Unlike core Daraja, this product has no public documentation this SDK could verify response shapes against — presenting a guessed typed model here would risk silently misleading you about field names that don't actually exist. Request bodies, by contrast, are fully typed: they're taken directly from the reference Postman collection's request payloads, which are unambiguous.

What's confirmed vs. not: the endpoints, HTTP methods, and request bodies below are taken directly from the reference collection. The exact semantics of the X-MessageID header (pass via IoTCallOptions.MessageId) are not — it resembles a conversation-continuation token in the source collection, but this SDK cannot confirm whether it's required, generated, or echoed back from a prior response. Leave it unset unless your integration has been told otherwise.

Client Covers
iot.Messaging Search/filter/get-all messages, send a single message, delete a message or thread
iot.SimOperations List SIMs, lifecycle status, customer info, activation (+ trends), rename asset, location info, suspend/unsuspend
iot.Imsi CheckATI v1, and "SWAP CheckATI" (v2)

Lipa na Bonga: response shape is unconfirmed

Lipa na Bonga isn't part of Safaricom's public Daraja catalog, so unlike every other area in this SDK, its response schema hasn't been cross-checked against official documentation. LipaNaBongaClient returns the raw response body (DarajaRawResult.Json) rather than a typed model with guessed field names. If you've confirmed the real shape against your own sandbox, contributions adding a typed model are welcome.

Live-tested finding: safaricom-daraja bonga --calculate --points 100 against the real Sandbox with a standard app registration returned 404 Not Found on /v1/lipa/na/bonga/calculator-points. The request shape matches the reference collection exactly, so this looks like the product needing separate account enablement rather than a bug in this SDK — but if you get it working, we'd like to know what's different about your setup.


Examples & Samples

  • examples/ — four self-contained, copy-pasteable demos: console-script, aspnetcore-minimal-api, aspnetcore-mvc, worker-service. Each references the published NuGet packages directly — see examples/README.md.
  • samples/Safaricom.Daraja.Sample.Console — part of the main solution (uses a local ProjectReference); this is the project used for the live Sandbox verification above.

Roadmap

  • Cross-check Safaricom.Daraja.IoT (SIM-portal/IMSI) and the less common core areas (Ratiba, Bill Manager, Lipa na Bonga, Pull API) against real Sandbox credentials — only OAuth, STK Push/Query, and C2B Simulate have been run against the live Sandbox so far.
  • Add a NuGet package icon.

Sponsorship

If this SDK helps you in your projects or commercial integrations, consider supporting ongoing open-source maintenance and development:

Sponsor via Pesapal

👉 Click here to Support via Pesapal Open Source Sponsorship


License

MIT © Jose Modi / Modi97

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Safaricom.Daraja:

Package Downloads
Safaricom.Daraja.IoT

.NET client for Safaricom's IoT SIM-portal (SIM messaging and subscriber/SIM operations) and IMSI CheckATI APIs. A distinct product from core Daraja with its own auth/header scheme and no public documentation - responses are returned as raw JSON since this SDK cannot verify a typed response shape against official docs.

Safaricom.Daraja.AspNetCore

ASP.NET Core integration for the Safaricom Daraja API. Dependency injection extensions, Minimal API webhook endpoint mapping (STK Push, C2B, B2C/B2B/Reversal/Transaction Status/Account Balance result callbacks, Bill Manager reconciliation), and MVC webhook processing helpers.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.0 41 9/17/2026
0.1.0 48 9/17/2026

0.2.0: Version alignment with the CLI's expanded command coverage - no functional changes to the core client since 0.1.0. 0.1.0: Initial preview release of the core Daraja client (OAuth, STK Push, C2B, B2C, B2B, Reversal, Transaction Status, Account Balance, Ratiba, Lipa na Bonga, Pull API, Dynamic QR, Bill Manager, Tax Remittance).