SDK Java 11+ zero-dependency cho MONA Pay, cổng thanh toán và API ngân hàng của The MONA Group. SDK dùng java.net.http.HttpClient, tự login/cache token và login lại đúng một lần khi HTTP 401.
export MONAPAY_CLIENT_ID="client-id"
export MONAPAY_CLIENT_SECRET="client-secret"
export MONAPAY_BASE_URL="https://api.monapay.vn"MonaPay client = MonaPay.fromEnv();
Object profile = client.me();
Object qr = client.qr().generate(qrBody);
Object sandbox = client.sandbox().createTransaction(MonaPay.object("virtual_account_number", "MONA123", "amount", 10000, "description", "AI test"));
System.out.println(profile);MonaPay.fromEnv() ưu tiên client credentials, cache token tới gần hạn và tự lấy lại khi gặp HTTP 401. Username/password chỉ là fallback tương thích cũ, không dùng cho AI agent vì sẽ gãy khi bật 2FA.
Sau khi package được publish:
<dependency>
<groupId>com.themona</groupId>
<artifactId>monapay</artifactId>
<version>0.4.0</version>
</dependency>MonaPay client = MonaPay.builder(
System.getenv("MONA_USERNAME"),
System.getenv("MONA_PASSWORD")
).clientSecret(System.getenv("MONA_CLIENT_SECRET")).build();
Object profile = client.me();
Object hooks = client.webhooks().list();Body JSON dùng Map<String,Object>; helper MonaPay.object(...) giúp viết ngắn. Các resource: keys, paymentProfile, checkouts, bankAccounts, va (đăng ký + hai bước OTP), qr, transactions, webhooks, webhookLogs, sandbox, emailConfigs, emailLogs, emailSuppressions. POST/PUT/DELETE tự có X-Client-Secret khi đã cấu hình; secret vừa generate sẽ được giữ trong client nếu trước đó chưa có.
Object checkout = client.checkouts().create(MonaPay.object("amount", 250000, "order_code", "DH10234", "return_url", "https://shop.vn/payment/return"));
String url = (String) ((Map<?, ?>) checkout).get("checkout_url");
response.sendRedirect(url);
if ("CHECKOUT_PAID".equals(eventType))
fulfillOnce(eventData.get("order_code"));SDK tự sinh Idempotency-Key cho create và cancel; truyền đối số key khi anh chị cần dùng key riêng. Nguồn sự thật để giao hàng là webhook CHECKOUT_PAID hoặc kết quả get, không phải redirect trình duyệt.
for (Object transaction : client.transactions().iterate(
"MONA000001",
new MonaPay.TransactionOptions().limit(100).sinceId("FT26240001234")
)) {
// Xử lý transaction; lưu transaction_code để chống trùng.
}sinceId là checkpoint phía SDK: iterator dừng trước item có id hoặc transaction_code trùng mốc. API hiện chưa nhận query since_id, nên SDK không gửi tham số này.
Webhook phải được xác thực trên đúng raw bytes:
WebhookVerifier.Result result = WebhookVerifier.verifyWebhook(rawBody, timestamp, signature, secret);
if (!result.isOk()) { /* trả HTTP 401 */ }Ví dụ Spring Boot: examples/SpringBootWebhookController.java.
Self-test không dùng JUnit hay Maven dependency:
rm -rf build && mkdir build
javac --release 11 -d build $(find src/main/java src/test/java -name '*.java')
java -cp build com.themona.monapay.SelfTestDocs: https://monapay.vn/docs · Hotline 1900 636 648 · info@themona.global. MONA Pay miễn phí hoàn toàn.
Zero-dependency Java 11+ SDK for MONA Pay. It covers token caching and one 401 refresh, virtual accounts and both OTP steps, VietQR, client-side sinceId transaction iteration, webhook configuration/logs/retry, and constant-time HMAC verification. The Spring Boot source is an integration example and is not part of the dependency-free SDK build.
MIT © The MONA Group.