.NET SDK for the MONA Pay API: create checkout links and VietQR codes, manage virtual accounts, webhooks and email notifications, and verify signed webhooks.
Targets netstandard2.0 and net8.0. No runtime dependencies; HTTP goes through HttpClient.
NuGet package (once published):
dotnet add package MonaPay --version 0.4.0using System.Collections.Generic;
using MonaPay;
using var client = MonaPayClient.FromEnvironment();
object? checkout = await client.Checkouts.CreateAsync(MonaPayClient.Object(
"amount", 250000,
"order_code", "DH10234",
"return_url", "https://shop.example/payment/return"));
string url = (string)((IDictionary<string, object?>)checkout!)["checkout_url"]!;// From environment variables (see Configuration)
using var client = MonaPayClient.FromEnvironment();
// Or explicitly
using var client = new MonaPayClient(new MonaPayOptions
{
ClientId = Environment.GetEnvironmentVariable("MONAPAY_CLIENT_ID")!,
ClientSecret = Environment.GetEnvironmentVariable("MONAPAY_CLIENT_SECRET"),
// BaseUrl and HttpClient are optional
});
object? profile = await client.MeAsync();- Client credentials (
ClientId+ClientSecret) are the recommended login.Username/Passwordis a legacy fallback and does not work for accounts with 2FA enabled. - The Bearer token is cached until 60 seconds before
expires_in. A request that fails with HTTP 401 triggers a new login and is retried once. X-Client-Secretis sent on non-GET requests when a client secret is set.- Request bodies are
IDictionary<string, object?>;MonaPayClient.Object(k1, v1, k2, v2, ...)builds one inline. - Methods return the
datafield of the response. Errors are thrown asMonaPayExceptionwithStatusCodeandBody. - Every async method accepts an optional
CancellationToken.
| Property | Methods |
|---|---|
Keys |
GenerateAsync, ListAsync, DestroyAsync, RevealAsync, RotateAsync |
BankAccounts |
ListAsync |
VA |
RegisterAsync, VerifyAsync, RegisterNotificationAsync, VerifyNotificationAsync, ListAsync |
PaymentProfile |
GetAsync, SetAsync, RotateReturnSecretAsync, RevealReturnSecretAsync |
Checkouts |
CreateAsync, GetAsync, ListAsync, CancelAsync |
QR |
GenerateAsync, CancelAsync |
Transactions |
ListAsync, Iterate, RetryAsync |
Sandbox |
CreateTransactionAsync |
Webhooks |
ListAsync, CreateAsync, UpdateAsync, RemoveAsync, TestAsync |
WebhookLogs |
ListAsync, StatsAsync |
EmailConfigs |
ListAsync, CreateAsync, GetAsync, UpdateAsync, RemoveAsync, VerifyAsync, ResendVerificationAsync, TestAsync |
EmailLogs |
ListAsync, StatsAsync |
EmailSuppressions |
ListAsync, RemoveAsync |
CreateAsync and CancelAsync send an Idempotency-Key header generated by the SDK; pass idempotencyKey to set your own. Fulfil orders from the CHECKOUT_PAID webhook or from GetAsync, not from the browser redirect.
object? tx = await client.Sandbox.CreateTransactionAsync(MonaPayClient.Object(
"virtual_account_number", "MONA123",
"amount", 10000,
"description", "Sandbox test"));TransactionIterator iterator = client.Transactions.Iterate(
"MONA000001",
new TransactionOptions { Limit = 100, SinceId = "FT26240001234" });
while (await iterator.MoveNextAsync())
{
object? transaction = iterator.Current;
// Use transaction_code as the idempotency key when storing.
}SinceId is handled by the SDK: the iterator stops before the item whose id or transaction_code matches. It is not sent to the API.
Verify the raw request bytes. VerifyWebhook takes the X-Mona-Timestamp and X-Mona-Signature header values and an optional tolerance in seconds (default 300).
WebhookResult result = Webhook.VerifyWebhook(rawBody, timestamp, signature, secret);
if (!result.Ok)
{
// respond with HTTP 401
}
object? payload = result.Payload;An ASP.NET Core minimal API handler is in examples/AspNetCore/Program.cs.
MonaPayClient.FromEnvironment() reads:
| Variable | Purpose |
|---|---|
MONAPAY_CLIENT_ID, MONAPAY_CLIENT_SECRET |
API key credentials (recommended) |
MONAPAY_USERNAME, MONAPAY_PASSWORD |
Legacy password login; does not work for accounts with 2FA enabled |
MONAPAY_BASE_URL |
API base URL, defaults to https://api.monapay.vn |
The ASP.NET Core example reads MONA_WEBHOOK_SECRET from configuration.
Documentation: https://monapay.vn/docs
dotnet build MonaPay.csproj
dotnet run --project tests/SelfCheck/SelfCheck.csproj
dotnet build examples/AspNetCore/Example.csprojMIT
MONA Pay is part of MONA Cloud by The MONA Group.