OneKhusa.SDK
2026.3.3
dotnet add package OneKhusa.SDK --version 2026.3.3
NuGet\Install-Package OneKhusa.SDK -Version 2026.3.3
<PackageReference Include="OneKhusa.SDK" Version="2026.3.3" />
<PackageVersion Include="OneKhusa.SDK" Version="2026.3.3" />
<PackageReference Include="OneKhusa.SDK" />
paket add OneKhusa.SDK --version 2026.3.3
#r "nuget: OneKhusa.SDK, 2026.3.3"
#:package OneKhusa.SDK@2026.3.3
#addin nuget:?package=OneKhusa.SDK&version=2026.3.3
#tool nuget:?package=OneKhusa.SDK&version=2026.3.3
OneKhusa.SDK
C# SDK for integrating with the OneKhusa Payment Gateway.
The OneKhusa SDK simplifies integration with the OneKhusa platform in .NET applications. It provides strongly-typed models, built-in authentication and token management, request validation, and helper methods for collections, disbursements, bill payments, merchant operations, reports, and more.
Features
- Unified API integration with OneKhusa REST services
- Automatic authentication and access-token caching
- Sandbox and production environment support (
OneKhusaOptions.IsSandbox) - Strongly-typed request and response models
- Built-in FluentValidation on SDK requests
- Idempotency-key support on mutating operations (auto-generated when omitted)
- Manual client instantiation or Microsoft.Extensions.DependencyInjection
- XML documentation in NuGet for IntelliSense
Supported .NET versions: net9.0, net10.0
Installation
Install via NuGet Package Manager:
Install-Package OneKhusa.SDK
Or via .NET CLI:
dotnet add package OneKhusa.SDK
Configuration
Configure the client with your OneKhusa credentials and merchant context:
using OneKhusa.SDK.Models.Configurations;
var options = new OneKhusaOptions
{
ApiKey = "your_api_key", // min 30 characters
ApiSecret = "your_api_secret", // min 40 characters
MerchantAccountNumber = 12345678, // 8-digit merchant account
OrganisationId = "ORG123456789", // 12-character organisation ID
IsSandbox = true, // false for production
ApiVersion = "v1", // v1–v4
BaseUrlOverride = null // optional, e.g. https://dev.api.onekhusa.com/sandbox/v1
};
// BaseUrl is derived automatically when BaseUrlOverride is null:
// Sandbox → https://api.onekhusa.com/sandbox/{ApiVersion}
// Live → https://api.onekhusa.com/live/{ApiVersion}
Options are validated when the client is constructed. Invalid credentials or formats throw before any API call is made.
Quick Start
using Microsoft.Extensions.Logging;
using OneKhusa.SDK;
using OneKhusa.SDK.Models.Configurations;
using OneKhusa.SDK.Models.Transactions.SingleDisbursements.BankOrWallet;
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole().SetMinimumLevel(LogLevel.Debug);
});
var client = new OneKhusaClient(new OneKhusaOptions
{
ApiKey = "your_api_key",
ApiSecret = "your_api_secret",
MerchantAccountNumber = 12345678,
OrganisationId = "ORG123456789"
}, loggerFactory);
var response = await client.Transactions.SingleDisbursements.CreatePayoutAsync(new CreatePayoutRequest
{
MerchantAccountNumber = 12345678,
TransactionAmount = 50000.00m,
BeneficiaryName = "JOE DOE",
BeneficiaryAccountNumber = "3333888800",
ConnectorId = 221300,
SourceReferenceNumber = "REF123456",
TransactionDescription = "Meeting Allowance",
CapturedBy = "joe.doe@example.com"
});
if (response.IsSuccess)
{
var payout = response.Data!;
// payout.TransactionReferenceNumber, payout.ResponseCode, etc.
}
else
{
var error = response.Error!;
// error.ErrorCode, error.ErrorMessage
}
All service methods return OneKhusaResponse<T> with IsSuccess, StatusCode, Data, and Error.
Dependency Injection
Register the client in ASP.NET Core or any IServiceCollection-based host:
using OneKhusa.SDK.Extensions;
using OneKhusa.SDK.Models.Configurations;
builder.Services.AddOneKhusaClient(options =>
{
options.ApiKey = builder.Configuration["OneKhusa:ApiKey"]!;
options.ApiSecret = builder.Configuration["OneKhusa:ApiSecret"]!;
options.MerchantAccountNumber = int.Parse(builder.Configuration["OneKhusa:MerchantAccountNumber"]!);
options.OrganisationId = builder.Configuration["OneKhusa:OrganisationId"]!;
options.IsSandbox = true;
});
// Inject IOneKhusaClient anywhere in your app
public class PaymentService(IOneKhusaClient client) { /* ... */ }
Client structure
Every feature is accessed from IOneKhusaClient (implemented by OneKhusaClient):
IOneKhusaClient
├── Transactions
│ ├── SingleDisbursements → bank/wallet payouts, FI transfers, organisation transfers
│ ├── Collections → request-to-pay, collect payment, checkout
│ ├── BatchDisbursements → bulk payouts (file/JSON upload, workflow, transfer)
│ └── BillPayments → utility and service bill payments
├── Merchants
│ ├── Accounts → merchant account lookup
│ ├── Fees → fee calculation and listing
│ ├── Limits → transaction limits
│ ├── Webhooks → webhook signature verification
│ ├── Analytics → connector and transaction metrics
│ ├── Categories → merchant categories
│ └── Classifications → merchant classifications
├── StaticMaintenance
│ ├── Connectors → payment connectors (banks, wallets, etc.)
│ ├── Currencies → supported currencies
│ └── Countries → supported countries
├── Reports
│ ├── ProofOfPayments → single/batch payout receipts
│ └── Files → batch disbursement file download
└── FakeData → sandbox mock collection/disbursement helpers
├── Collections
└── Disbursements
Transactions
Single disbursements
Entry point: client.Transactions.SingleDisbursements
Single disbursements cover three variants:
| Variant | Entry | Use case |
|---|---|---|
| Bank / wallet | CreatePayoutAsync, ReviewPayoutAsync, ApprovePayoutAsync, RejectPayoutAsync |
External bank or mobile wallet payout |
| Financial institution | TransferToFinancialInstutionAsync |
EFT to a financial institution |
| Organisation | OrganisationTransfers.* |
Merchant-to-merchant transfer (intra / inter) |
Shared history: GetPayoutAsync, GetPayoutsAsync.
Bank / wallet payout
Models: OneKhusa.SDK.Models.Transactions.SingleDisbursements.BankOrWallet (create) and OneKhusa.SDK.Models.Transactions.SingleDisbursements.Shared (review, approve, reject, get)
await client.Transactions.SingleDisbursements.CreatePayoutAsync(request, idempotencyKey: "optional-key");
await client.Transactions.SingleDisbursements.ApprovePayoutAsync(approveRequest);
await client.Transactions.SingleDisbursements.GetPayoutAsync(getPayoutRequest);
Financial institution transfer
Models: OneKhusa.SDK.Models.Transactions.SingleDisbursements.FinancialInstitutionTransfers
await client.Transactions.SingleDisbursements.TransferToFinancialInstutionAsync(fiRequest);
Organisation transfers
Organisation transfers move funds between OneKhusa merchant accounts — within the same organisation (intra) or to a registered merchant in another organisation (inter).
Entry point: client.Transactions.SingleDisbursements.OrganisationTransfers
Models: OneKhusa.SDK.Models.Transactions.SingleDisbursements.OrganisationTransfers (create) and OneKhusa.SDK.Models.Transactions.SingleDisbursements.Shared (review, approve, reject, get)
Intra-organisation transfer
Optionally list merchant accounts in the same organisation to pick a beneficiary (intra only), then create the transfer:
using OneKhusa.SDK.Models.Transactions.SingleDisbursements.Shared;
using OneKhusa.SDK.Models.Transactions.SingleDisbursements.OrganisationTransfers;
var merchants = await client.Transactions.SingleDisbursements.OrganisationTransfers
.GetOrganisationMerchantsAsync(new GetOrganisationMerchantsRequest
{
MerchantAccountNumber = 12345678,
OrganisationId = "ORG123456789"
});
var transfer = await client.Transactions.SingleDisbursements.OrganisationTransfers
.CreateIntraOrganisationTransferAsync(new CreateOrganisationTransferRequest
{
MerchantAccountNumber = 12345678,
TransactionAmount = 50000.00m,
TransactionDescription = "Branch float top-up",
BeneficiaryName = "Branch Operations",
BeneficiaryAccountNumber = "52333819",
SourceReferenceNumber = "BRFLT001",
CapturedBy = "user@example.com"
});
SourceReferenceNumber is optional in the SDK (empty is valid). Prefer sending a 5–12 character alphanumeric value. Some sandbox environments return E999 when the field is empty instead of generating a reference.
On a successful create (S100), use TransactionReferenceNumber for later lookup. CollectionTransactionReferenceNumber may be empty, and BeneficiaryMerchantAccountNumber may be 0 — the beneficiary you submitted is still on the request as BeneficiaryAccountNumber.
Inter-organisation transfer
Use the same CreateOrganisationTransferRequest type; call CreateInterOrganisationTransferAsync instead:
var interTransfer = await client.Transactions.SingleDisbursements.OrganisationTransfers
.CreateInterOrganisationTransferAsync(new CreateOrganisationTransferRequest
{
MerchantAccountNumber = 12345678,
TransactionAmount = 50000.00m,
TransactionDescription = "Settlement payment",
BeneficiaryName = "Partner Merchant",
BeneficiaryAccountNumber = "87654321",
SourceReferenceNumber = "STLMT001",
CapturedBy = "user@example.com"
});
Approval workflow
Depending on your merchant approval level:
| Level | Behaviour on submit |
|---|---|
| 1 | Executes immediately (review/approve APIs are still available; they are typically unused at this level) |
| 2 | Pending until approved |
| 3+ | Pending until reviewed, then approved |
Use ReviewIntraOrganisationTransferAsync / ReviewInterOrganisationTransferAsync, ApproveIntraOrganisationTransferAsync / ApproveInterOrganisationTransferAsync, and RejectIntraOrganisationTransferAsync / RejectInterOrganisationTransferAsync for workflow actions. Workflow request types are reused from shared single-disbursement models (ReviewPayoutRequest, ApprovePayoutRequest, RejectPayoutRequest).
var approved = await client.Transactions.SingleDisbursements.OrganisationTransfers
.ApproveIntraOrganisationTransferAsync(new ApprovePayoutRequest
{
MerchantAccountNumber = 12345678,
TransactionReferenceNumber = "260703A1B2C3",
ActionedBy = "approver@example.com"
});
Transaction history
Prefer GetPayoutAsync with the create response's TransactionReferenceNumber. GetPayoutsRequest has no TransactionCode filter; do not send empty SearchBy / SearchText (that can return 500 / E999).
using OneKhusa.SDK.Models.Constants.Shared;
using OneKhusa.SDK.Models.Transactions.SingleDisbursements.Shared;
var single = await client.Transactions.SingleDisbursements.GetPayoutAsync(new GetPayoutRequest
{
MerchantAccountNumber = 12345678,
TransactionReferenceNumber = transfer.Data!.TransactionReferenceNumber
});
var list = await client.Transactions.SingleDisbursements.GetPayoutsAsync(new GetPayoutsRequest
{
MerchantAccountNumber = 12345678,
TransactionDate = DateTime.UtcNow.Date,
PageNumber = 1,
NumberOfReturnedRows = 10,
SearchBy = SearchFields.TransactionReferenceNumber,
SearchText = transfer.Data.TransactionReferenceNumber
});
History rows expose a display TransactionType (for example Transfer Between Organisations for inter). API create routes use codes TWO (intra) and TBO (inter); those codes are not a filter on GetPayoutsRequest.
Collections
Entry point: client.Transactions.Collections
Models: OneKhusa.SDK.Models.Transactions.Collections
| Method | Description |
|---|---|
CreateRequestToPayAsync |
Initiate a request-to-pay |
CreateCollectPaymentRequestAsync |
Create a collect-payment request |
InitiateRequestToPayCheckoutAsync |
Initiate request-to-pay checkout flow |
GetPaymentAsync |
Get a single collection payment |
GetPaymentsAsync |
List collection payments |
using OneKhusa.SDK.Models.Transactions.Collections;
var rtp = await client.Transactions.Collections.CreateRequestToPayAsync(new RequestToPayRequest
{
MerchantAccountNumber = 12345678,
TransactionAmount = 10000.00m,
TransactionDescription = "Invoice payment",
ReferenceNumber = "INV001",
CapturedBy = "user@example.com"
});
Batch disbursements
Entry point: client.Transactions.BatchDisbursements
Models: OneKhusa.SDK.Models.Transactions.BatchDisbursements
| Method | Description |
|---|---|
UploadFileAsync |
Upload CSV or Excel batch file |
UploadJsonAsync |
Upload JSON batch payload |
GetBatchAsync / GetBatchesAsync |
Retrieve batch(es) |
GetBatchTransactionAsync / GetBatchTransactionsAsync |
Retrieve batch transaction(s) |
ReviewBatchAsync / ApproveBatchAsync / RejectBatchAsync / CancelBatchAsync |
Batch workflow |
TransferFundsAsync |
Execute batch fund transfer |
DownloadBatchErrorsAsync |
Download batch error file |
using OneKhusa.SDK.Models.Transactions.BatchDisbursements;
var upload = await client.Transactions.BatchDisbursements.UploadJsonAsync(new UploadBatchJsonRequest
{
// batch header + transactions
});
Bill payments
Entry point: client.Transactions.BillPayments
Models: OneKhusa.SDK.Models.Transactions.BillPayments
| Method | Description |
|---|---|
PayBillAsync |
Pay a utility or service bill (water, electricity, airtime, etc.) |
using OneKhusa.SDK.Models.Transactions.BillPayments;
var bill = await client.Transactions.BillPayments.PayBillAsync(new PayBillPaymentRequest
{
MerchantAccountNumber = 12345678,
ServiceAccountNumber = "1234567890",
ServiceCode = "101",
SourceReferenceNumber = "BILL001",
TransactionAmount = 5000.00m,
BillDescription = "Electricity bill March 2026",
CapturedBy = "user@example.com"
});
Merchants
Entry point: client.Merchants
| Service | Methods | Description |
|---|---|---|
Accounts |
GetAccountAsync, GetAccountsAsync |
Merchant account details |
Fees |
CalculateFeesAsync, GetFeesAsync |
Transaction fee calculation and listing |
Limits |
GetLimitsAsync |
Transaction limits |
Webhooks |
VerifyWebhookAsync |
Verify incoming webhook signatures |
Analytics |
GetConnectorSummaryByCountAsync, GetConnectorSummaryBySumAsync, GetTransactionMetricsAsync |
Connector and transaction analytics |
Categories |
GetCategoriesAsync |
Merchant categories |
Classifications |
GetClassificationsAsync |
Merchant classifications |
using OneKhusa.SDK.Models.Merchants.MerchantAccounts;
var account = await client.Merchants.Accounts.GetAccountAsync(new GetMerchantRequest
{
MerchantAccountNumber = 12345678
});
Static maintenance
Entry point: client.StaticMaintenance
Reference data for connectors, currencies, and countries:
| Service | Methods |
|---|---|
Connectors |
GetConnectorAsync, GetConnectorsSummaryAsync |
Currencies |
GetCurrenciesAsync |
Countries |
GetCountriesAsync |
Use connector IDs from Connectors when building bank/wallet payout requests (CreatePayoutRequest.ConnectorId).
Reports
Entry point: client.Reports
| Service | Methods | Description |
|---|---|---|
ProofOfPayments |
GetSinglePayoutTransactionReceiptAsync, GetBatchPayoutTransactionReceiptAsync, GetBatchPayoutSummaryReceiptAsync |
Proof-of-payment receipts |
Files |
DownloadBatchDisbursementFileAsync |
Download batch disbursement file (Excel/CSV) |
Fake data (sandbox testing)
Entry point: client.FakeData
Sandbox-only helpers for simulating collection and disbursement flows during integration testing:
| Service | Methods |
|---|---|
Collections |
MockAcceptRequestToPayAsync, MockPaymentAsync |
Disbursements |
GenerateFakeTransactionsAsync |
Documentation
Full documentation and integration guides:
https://docs.onekhusa.com/sdk/get-started/introduction
Support
For technical support, integration assistance, or account-related queries, please contact the OneKhusa support team through your official onboarding channel.
License
This package is distributed under the applicable OneKhusa licensing terms.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. 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. |
-
net10.0
- FluentValidation (>= 12.1.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.9)
- Refit (>= 13.1.0)
-
net9.0
- FluentValidation (>= 12.1.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.9)
- Refit (>= 13.1.0)
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 |
|---|---|---|
| 2026.3.3 | 113 | 9/11/2026 |
| 2026.1.5.4 | 196 | 5/6/2026 |
| 2026.1.5.3 | 123 | 4/12/2026 |
| 2026.1.5.2 | 174 | 3/10/2026 |
| 2026.1.5.1 | 137 | 2/27/2026 |
| 2026.1.5 | 125 | 2/26/2026 |