KeyTD.Manat 0.2.2

dotnet add package KeyTD.Manat --version 0.2.2
                    
NuGet\Install-Package KeyTD.Manat -Version 0.2.2
                    
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="KeyTD.Manat" Version="0.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="KeyTD.Manat" Version="0.2.2" />
                    
Directory.Packages.props
<PackageReference Include="KeyTD.Manat" />
                    
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 KeyTD.Manat --version 0.2.2
                    
#r "nuget: KeyTD.Manat, 0.2.2"
                    
#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 KeyTD.Manat@0.2.2
                    
#: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=KeyTD.Manat&version=0.2.2
                    
Install as a Cake Addin
#tool nuget:?package=KeyTD.Manat&version=0.2.2
                    
Install as a Cake Tool

Manat for .NET

One API for Azerbaijani online payment providers: Kapital Bank, Azericard, Payriff, Epoint, GoldenPay and Yığım. netstandard2.0, so it runs on .NET Framework 4.6.1+ as well as .NET 6, 8, 10…; no package dependencies.

dotnet add package KeyTD.Manat
using KeyTD.Manat;
using KeyTD.Manat.Providers;

var pay = new ManatClient(new KapitalBankProvider(new KapitalBankOptions
{
    Username = config["KB_USER"]!,
    Password = config["KB_PASSWORD"]!,
}));

var result = await pay.CreatePaymentAsync(new CreatePaymentRequest
{
    OrderId = "A-1001",
    Amount = Money.Azn("25.50"),   // 2550 qəpik; floats are never accepted
    ReturnUrl = "https://shop.az/payment/return",
});

// Send the customer on: a redirect, or (Azericard) an auto-submitted form.
if (result.Next.Type == NextAction.ActionType.Redirect)
{
    return Redirect(result.Next.Url!);
}

Store result.PaymentId with the order. It is what GetStatusAsync, RefundAsync, CaptureAsync and CancelAsync take.

Providers

new KapitalBankProvider(new KapitalBankOptions { Username = user, Password = password, Environment = ProviderEnvironment.Test });
new AzericardProvider(new AzericardOptions
{
    Terminal = terminal, PrivateKey = System.IO.File.ReadAllText("merchant.pem"), GatewayPublicKey = System.IO.File.ReadAllText("gateway.pem"),
    MerchantName = "My Shop", MerchantUrl = "https://shop.az", Environment = ProviderEnvironment.Test,
});
new PayriffProvider(new PayriffOptions { SecretKey = secretKey });
new EpointProvider(new EpointOptions { PublicKey = publicKey, PrivateKey = privateKey });
new GoldenPayProvider(new GoldenPayOptions { AuthKey = authKey, MerchantName = merchantName, Environment = ProviderEnvironment.Test });
new YigimProvider(new YigimOptions { Merchant = merchant, ApiKey = apiKey, Biller = biller, Environment = ProviderEnvironment.Test });
Provider CreatePayment VerifyCallback GetStatus Refund Capture Cancel
Kapital Bank ✓ ✓ ✓ ✓ ✓ ✓
Azericard ✓ (form POST) ✓ ✓ ✓ ✓ ✓
Payriff ✓ ✓ ✓ ✓ ✓ —
Epoint ✓ ✓ ✓ ✓ — —
GoldenPay ✓ ✓ ✓ ✓ — —
Yığım ✓ ✓ ✓ ✓ ✓ ✓

pay.Supports(Capability.Capture) tells you at runtime; an unsupported call throws unsupported_operation.

Callbacks

Pass what your handler received. Signed callbacks are verified in constant time; unsigned redirects and webhooks are never trusted: the adapter re-reads the payment from the provider's API. Epoint's browser redirect is unsigned and rejected with invalid_signature; call GetStatusAsync there.

using var reader = new StreamReader(Request.Body);
var evt = await pay.VerifyCallbackAsync(new IncomingCallback(Request.Method)
    .WithQuery(Request.Query)                 // ASP.NET Core's IQueryCollection works as is
    .WithBody(await reader.ReadToEndAsync()));

if (evt.Status == PaymentStatus.Paid)
{
    // fulfil order evt.PaymentId; for Azericard store evt.ProviderRef for refunds
}

Refunds, capture, cancel

await pay.RefundAsync(new RefundRequest { PaymentId = id });                                 // full refund
await pay.RefundAsync(new RefundRequest { PaymentId = id, Amount = Money.Azn("10.00") });    // partial
await pay.CaptureAsync(new PaymentAction { PaymentId = id });                                // after Intent = Intent.Authorize
await pay.RefundAsync(new RefundRequest { PaymentId = id, ProviderRef = providerRef });      // Azericard needs the callback's ProviderRef

Errors

Everything throws ManatException. error.Code is one of InvalidRequest, InvalidSignature, ProviderError, NetworkError, UnsupportedOperation (error.Code.ToValue() gives the spec's "provider_error"); for provider errors ProviderCode and ProviderMessage hold what the provider said and Raw its whole reply.

HTTP

Every options class takes HttpClient (pass one from IHttpClientFactory) and Timeout (default 30 seconds). Without a client a shared one is used, with redirects off. On .NET Framework, enable TLS 1.2 (ServicePointManager.SecurityProtocol) if your version does not default to it. All methods are async and take a CancellationToken.

Tests

The adapters run the same JSON test vectors as every other language (spec/vectors). Without a local .NET SDK:

docker run --rm -v "$PWD":/repo -w /repo/dotnet mcr.microsoft.com/dotnet/sdk:10.0 dotnet test tests/KeyTD.Manat.Tests -f net10.0
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 was computed.  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 was computed.  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

    • No dependencies.

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
0.2.2 42 10/27/2026
0.2.1 46 10/27/2026
0.2.0 48 10/27/2026
0.1.0 47 10/27/2026