> Chọn đúng SDK MONA Pay, khởi tạo bằng client_id và client_secret, tạo checkout, tra giao dịch, kiểm webhook HMAC và thử bằng sandbox.

Nguồn: https://monapay.vn/docs/sdk · Cập nhật: 2026-09-18

[Lấy API key miễn phí](https://my.monapay.vn/auth?mode=register)

Dùng ngay

- [Dùng ngay, không cần lập trình](https://monapay.vn/docs/dung-ngay)
- [Quán ăn, quán trà sữa](https://monapay.vn/docs/dung-ngay/quan-an-tra-sua)
- [Tiệm tóc, spa](https://monapay.vn/docs/dung-ngay/tiem-toc-spa)
- [Bán hàng online](https://monapay.vn/docs/dung-ngay/ban-hang-online)
- [Lớp học, trung tâm](https://monapay.vn/docs/dung-ngay/lop-hoc)

Bắt đầu

- [Tổng quan](https://monapay.vn/docs)
- [Bắt đầu nhanh (5 phút)](https://monapay.vn/docs/bat-dau-nhanh)
- [Khái niệm: VA, VietQR, webhook](https://monapay.vn/docs/khai-niem)

Theo stack

- [Site tĩnh Astro/Hugo + serverless](https://monapay.vn/docs/stack/astro-static-serverless)
- [Django / FastAPI](https://monapay.vn/docs/stack/django-fastapi)
- [Express / NestJS](https://monapay.vn/docs/stack/express-nestjs)
- [Flutter / React Native](https://monapay.vn/docs/stack/flutter-react-native)
- [Go / Spring Boot / .NET](https://monapay.vn/docs/stack/go-java-dotnet)
- [Google Sheets tự ghi tiền vào (Google Apps Scrip](https://monapay.vn/docs/stack/google-apps-script)
- [Laravel nhận VietQR, package PHP](https://monapay.vn/docs/stack/laravel)
- [Build bằng AI builder (Lovable/Bolt/v0/Replit)](https://monapay.vn/docs/stack/lovable-bolt-v0-replit)
- [n8n](https://monapay.vn/docs/stack/n8n)
- [Next.js (App Router, Vercel) nhận chuyển khoản t](https://monapay.vn/docs/stack/nextjs)
- [Supabase Edge Function nhận webhook, cập nhật bả](https://monapay.vn/docs/stack/supabase)
- [WordPress tự viết form, không WooCommerce](https://monapay.vn/docs/stack/wordpress-khong-woo)

Công thức cho agent

- [AI agent bán dịch vụ tự thu tiền rồi mới trả kết](https://monapay.vn/docs/cong-thuc/ai-agent-tu-thu-tien)
- [Bán khoá học, ebook, file số](https://monapay.vn/docs/cong-thuc/ban-khoa-hoc-file-so)
- [App đặt lịch thu cọc](https://monapay.vn/docs/cong-thuc/booking-thu-coc)
- [Bot Telegram/Zalo bán hàng](https://monapay.vn/docs/cong-thuc/bot-telegram-zalo-ban-hang)
- [Cá nhân, hộ kinh doanh chưa có công ty](https://monapay.vn/docs/cong-thuc/ca-nhan-chua-co-cong-ty)
- [Khách chuyển thiếu, thừa, sai nội dung](https://monapay.vn/docs/cong-thuc/khop-don-thieu-thua-sai-noi-dung)
- [App có ví](https://monapay.vn/docs/cong-thuc/nap-vi-cong-credit)
- [Nền tảng nhiều shop, mỗi shop nhận tiền vào tài](https://monapay.vn/docs/cong-thuc/platform-nhieu-shop)
- [SaaS gói tháng thu bằng chuyển khoản](https://monapay.vn/docs/cong-thuc/saas-thu-phi-thang)
- [Landing tĩnh trên Vercel/Netlify, không backend](https://monapay.vn/docs/cong-thuc/site-tinh-khong-backend)
- [Stripe không mở cho Việt Nam](https://monapay.vn/docs/cong-thuc/stripe-khong-ho-tro-viet-nam-dev)
- [Test webhook ở máy mình](https://monapay.vn/docs/cong-thuc/test-local-ngrok-sandbox)
- [Nhận tiền xong tự xuất hoá đơn điện tử và gửi em](https://monapay.vn/docs/cong-thuc/thu-tien-xong-xuat-hoa-don-gui-email)
- [Web bán hàng](https://monapay.vn/docs/cong-thuc/web-ban-hang-tu-xac-nhan-don)

Webhooks

- [Tích hợp webhook](https://monapay.vn/docs/webhooks/tich-hop-webhook)
- [Định dạng payload](https://monapay.vn/docs/webhooks/dinh-dang-payload)
- [Bảo mật: HMAC + chống replay](https://monapay.vn/docs/webhooks/bao-mat)
- [Gửi lại và xử lý lỗi](https://monapay.vn/docs/webhooks/gui-lai-va-xu-ly-loi)
- [Đối soát giao dịch](https://monapay.vn/docs/webhooks/doi-soat)

API v1

- [Xác thực](https://monapay.vn/docs/api/xac-thuc)
- [API keys](https://monapay.vn/docs/api/api-keys)
- [Sandbox: thử không tốn tiền](https://monapay.vn/docs/api/sandbox)
- [Tài khoản ảo (VA)](https://monapay.vn/docs/api/tai-khoan-ao-va)
- [QR thanh toán](https://monapay.vn/docs/api/qr-thanh-toan)
- [Trang thanh toán](https://monapay.vn/docs/api/trang-thanh-toan)
- [Giao dịch](https://monapay.vn/docs/api/giao-dich)
- [Cấu hình webhook qua API](https://monapay.vn/docs/api/webhook-configs)
- [Gói và hoá đơn (billing)](https://monapay.vn/docs/api/goi-va-hoa-don)

Cho lập trình viên

- [MCP server](https://monapay.vn/docs/mcp)
- [SDK](https://monapay.vn/docs/sdk)
- [Mã nguồn GitHub](https://monapay.vn/docs/github)

Kênh thông báo

- [Telegram](https://monapay.vn/docs/telegram)
- [Zalo](https://monapay.vn/docs/zalo)
- [Email](https://monapay.vn/docs/email)

Tham chiếu

- [API reference tương tác](https://monapay.vn/docs/api-reference)
- [Địa chỉ IP](https://monapay.vn/docs/dia-chi-ip)
- [Dành cho AI agent](https://monapay.vn/docs/ai-agent)

[MONA Pay](https://monapay.vn/)[Tài liệu](https://monapay.vn/docs)SDK MONA Pay: Node.js, Python, PHP, Go và các ngôn ngữ khác

# SDK MONA Pay: Node.js, Python, PHP, Go và các ngôn ngữ khác

Cập nhật 05/09/2026[Bản Markdown](https://monapay.vn/docs/sdk.md)[llms.txt](https://monapay.vn/llms.txt)[openapi.json](https://monapay.vn/openapi.json)

## Video hướng dẫn

SDK Node.js MONA Pay: cài từ npm, tạo VA, tạo QR, nhận webhook trong 10 phút · [Xem trên YouTube](https://www.youtube.com/watch?v=F1_uOyTneZ8)

**Xem transcript video (8 phần)**

### SDK cho Node TypeScript

Bạn có một dự án Node.js hoặc TypeScript và muốn thu tiền chuyển khoản mà không tự viết từng lệnh HTTP. Trong mười phút, mình sẽ cài SDK chính thức, khởi tạo client bằng biến môi trường, tạo link thu tiền, đi qua luồng tạo tài khoản ảo, tạo VietQR và xác thực webhook. SDK có tên @monapay/node, không có dependency và dùng fetch có sẵn của Node mười tám trở lên.

### Cài và tạo client

Cài gói bằng npm install @monapay/node. Sau đó đặt MONAPAY_CLIENT_ID và MONAPAY_CLIENT_SECRET lấy từ API Keys trên my.monapay.vn. Trong code, import MonaPay rồi gọi MonaPay.fromEnv(). Lệnh đầu tiên tự lấy OAuth token; các lệnh sau dùng lại token tới gần hạn. SDK làm mới sớm sáu mươi giây và thử lại đúng một lần khi gặp HTTP bốn trăm lẻ một. Secret phải nằm trong biến môi trường, không commit lên git.

### Tạo link thu tiền

Để tạo link thu tiền, gọi mona.checkouts.create với amount, order_code và return_url. Kết quả trả checkout_url; bạn chuyển hướng khách tới đó hoặc gửi link qua tin nhắn. Theo tài liệu API, mỗi đơn nên có mã riêng, request tạo checkout cần khóa chống tạo trùng, và đơn chỉ được xác nhận sau sự kiện CHECKOUT_PAID đã kiểm chữ ký hoặc sau khi đọc lại checkout thấy status là paid.

### Tạo VA qua hai OTP

Luồng tạo tài khoản ảo có bốn bước và hai OTP. Gọi registerVirtualAccount với loại khách hàng, số tài khoản, số điện thoại, đầu số VA, nội dung định danh và user_agreement. Lấy registration.acb_request.id để gọi verifyVirtualAccount bằng OTP người dùng nhập. Sau đó gọi registerNotification với ID của VA, nhận OTP lần hai và gọi verifyNotification. Bỏ hai bước thông báo thì VA tồn tại nhưng webhook giao dịch sẽ không chạy.

### Tạo VietQR động

Khi đã có thông tin ACB, dùng mona.qr.generate. Các trường chính gồm ownerNumber, ownerType, merchantId, terminalId, orderId, virtualAccountPrefix, beneficiaryName, amount và description. Các giá trị merchant và terminal đúng được xem trong dashboard tại mục Tạo QR. SDK trả dữ liệu trực tiếp trong response, nên đọc qr.qr_data_url. Đây là payload VietQR để đưa vào thư viện vẽ QR, không phải URL ảnh. Lưu ID và số VA đầy đủ để hủy hoặc đối chiếu khi cần.

### Kiểm chữ ký webhook

Phần dễ sai nhất là webhook. Route phải nhận raw body trước khi middleware phân tích JSON. Truyền đúng bytes cùng headers và MONA_WEBHOOK_SECRET vào verifyWebhook. Chỉ xử lý khi result.ok là true, rồi lưu transaction_code bằng unique constraint để một giao dịch gửi lại không cập nhật đơn hai lần. Sự kiện checkout dùng checkout_id, không dùng id. Ví dụ Express hoàn chỉnh và ví dụ Next.js App Router đều có trong README.

### Chạy thử bằng sandbox

Trước khi nối ngân hàng, bạn có thể thử cả luồng bằng sandbox. Tạo checkout với sandbox: true, sau đó gọi mona.sandbox.transaction bằng số VA của checkout, đúng số tiền và mã đơn. Đọc lại checkout để thấy trạng thái paid. Sandbox vẫn phát webhook và chạy bộ khớp checkout nhưng không chuyển tiền. Ca thiếu tiền phải giữ status là pending; chỉ giao hàng khi đã nhận đủ và xác minh thành công.

### Sửa lỗi và xem tài liệu

Nếu import lỗi, kiểm tra dự án đang dùng Node từ phiên bản mười tám và đúng tên gói có scope là @monapay/node. Nếu API lỗi, MonaPayError có status và body để log. Các method trả trực tiếp trường data của response. Nếu chữ ký sai, đừng stringify lại object đã parse; hãy lấy nguyên raw body. README, danh sách method và ví dụ nằm trên npm, còn đặc tả endpoint ở monapay.vn/docs. Đăng ký tại my.monapay.vn hoặc gọi một chín không không, sáu ba sáu, sáu bốn tám.

SDK Python MONA Pay: pip install, tạo link thu tiền, kiểm chữ ký webhook · [Xem trên YouTube](https://www.youtube.com/watch?v=T2vcKsoPYv4)

**Xem transcript video (8 phần)**

### SDK cho Python backend

Bạn có dự án Flask, FastAPI hoặc Django và muốn tạo link chuyển khoản, nhận kết quả thanh toán mà không tự ghép từng request. Trong video này, mình cài SDK Python chính thức, tạo client, tạo checkout, chạy sandbox và kiểm chữ ký webhook. Tên gói trên PyPI là monapay. SDK chạy từ Python ba chấm tám, dùng đồng bộ và chỉ dựa vào thư viện chuẩn.

### Cài gói từ PyPI

Cài gói bằng pip install monapay. Tạo API key tại my.monapay.vn rồi đặt MONAPAY_CLIENT_ID và MONAPAY_CLIENT_SECRET trong môi trường chạy ứng dụng. Import MonaPay từ monapay và gọi MonaPay.from_env(). Client tự lấy OAuth token, lưu tới gần hạn, làm mới sớm sáu mươi giây và thử lại đúng một lần khi gặp HTTP bốn trăm lẻ một. Không ghi client secret trực tiếp trong repository.

### Tạo client từ môi trường

Python SDK đặt tên nhóm theo kiểu snake case: bank_accounts, webhook_logs, email_configs, email_logs và payment_profile. Các method trả trực tiếp trường data của response, nên không cần bóc thêm lớp success, message, data trong code sử dụng. Khi cần truyền thông tin tường minh, khởi tạo MonaPay với client_id và client_secret. Lỗi API là ApiError, có status và body để ghi log và tìm trường sai. Alias paymentProfile cũng có sẵn nếu bạn muốn giữ cách gọi giống SDK Node.

### Tạo link thu tiền

Tạo link thu tiền bằng mona.checkouts.create. Body cần amount, order_code và return_url; kết quả cho checkout_url để chuyển hướng hoặc gửi khách. Mỗi phiên mặc định hết hạn sau chín trăm giây theo tài liệu API. Hệ thống chỉ đánh dấu paid khi tổng tiền nhận lớn hơn hoặc bằng số tiền checkout. Vì vậy, ứng dụng không được xác nhận đơn chỉ vì khách quay về return_url.

### Thử checkout sandbox

Muốn kiểm luồng mà chưa nối ngân hàng, tạo checkout với sandbox=True. Lấy checkout["bank"]["account_number"], số tiền và mã đơn để gọi mona.sandbox.transaction. Sau đó đọc lại checkout bằng mona.checkouts.get. Trạng thái đủ tiền sẽ là paid; thiếu tiền vẫn là pending. Sandbox phát webhook như luồng thật nhưng không chuyển tiền, rất phù hợp để thử mapping đơn và chống xử lý trùng trước khi bật production.

### Xác thực webhook

Để xác thực webhook, import verify_webhook. Truyền raw_body, headers và MONA_WEBHOOK_SECRET; raw body phải là bytes nguyên bản từ request. Các framework phải giữ body trước mọi middleware phân tích JSON. Nếu result.ok không đúng, trả HTTP bốn trăm lẻ một với result.reason. Nếu hợp lệ, đọc payload và lưu transaction_code bằng unique key trước khi đổi trạng thái đơn. Không parse JSON rồi encode lại, vì chỉ một khác biệt byte cũng làm chữ ký không khớp.

### Chặn lỗi xử lý đơn

Với sự kiện CHECKOUT_PAID, trường định danh phiên là checkout_id, không phải id. Sau khi kiểm chữ ký, lấy checkout từ API, so order_code, số tiền và trạng thái paid rồi mới giao hàng. Flask, FastAPI và Django đều có ví dụ trong thư mục examples. Nếu cần đọc nhiều giao dịch, dùng iterator và vẫn chống trùng bằng transaction_code. Nhớ dùng tên Python from_env, không dùng fromEnv của Node. Đây là lỗi đặt tên thường gặp khi chuyển ví dụ giữa hai SDK.

### Sửa lỗi và xem docs

Nếu pip cài nhầm gói, đối chiếu trang PyPI có tên đúng monapay và phiên bản Python từ ba chấm tám. Nếu nhận HTTP bốn trăm lẻ hai, đọc ApiError.body để sửa trường hoặc kiểu dữ liệu. Nếu webhook luôn sai, kiểm raw bytes, secret và headers trước. README cùng code mẫu nằm trên PyPI; bản này cũng chỉ rõ lệnh chạy bộ test bằng pytest. Đặc tả checkout ở monapay.vn/docs/api/trang-thanh-toan. Bạn đăng ký tại my.monapay.vn hoặc gọi một chín không không, sáu ba sáu, sáu bốn tám.

MONA Pay có SDK cho 10 hệ sinh thái. Node.js và Python đã có trên npm, PyPI; Go cài trực tiếp bằng module đã gắn tag. Các SDK còn lại có source và tag trên GitHub nhưng chưa có trên registry tương ứng.

Nếu bạn đang bắt đầu một web JavaScript hoặc TypeScript, dùng Node.js. Flask, FastAPI hoặc Django dùng Python. Dự án đã chạy ngôn ngữ nào thì chọn SDK của ngôn ngữ đó để giữ secret ở backend.

## Bảng package và trạng thái phát hành

| Ngôn ngữ | Package hoặc module | Lệnh cài | Trạng thái trong repo |
| --- | --- | --- | --- |
| Node.js / TypeScript | `@monapay/node` 0.5.1 | `npm install @monapay/node` | Đã publish trên npm |
| Python | `monapay` 0.5.1 | `pip install monapay` | Đã publish trên PyPI |
| Go | `github.com/themonagroup/monapay-go` 0.4.0 | `go get github.com/themonagroup/monapay-go@v0.4.0` | Đã có repo và tag công khai |
| PHP | `monapay/php-sdk` 0.4.0 | Sau khi lên Packagist: `composer require monapay/php-sdk` | Trên GitHub, chưa lên registry |
| Java | `com.themona:monapay` 0.4.0 | Thêm dependency Maven ghi trong README sau khi lên Central | Trên GitHub, chưa lên registry |
| .NET | `MonaPay` 0.4.0 | Sau khi lên NuGet: `dotnet add package MonaPay --version 0.4.0` | Trên GitHub, chưa lên registry |
| Ruby | gem `monapay` 0.4.0 | Sau khi lên RubyGems: `gem "monapay", "~> 0.4"` | Trên GitHub, chưa lên registry |
| Dart / Flutter | package `monapay` 0.4.0 | Dùng source từ repo hiện tại | Trên GitHub, chưa lên registry |
| Rust | crate `monapay` 0.4.0 | Dùng source từ repo hiện tại | Trên GitHub, chưa lên registry |
| Elixir | Hex package `monapay` 0.4.0 | Dùng source từ repo hiện tại | Trên GitHub, chưa lên registry |

Không chạy lệnh cài từ registry cho 7 dòng ghi “chưa lên registry”. Mở [GitHub The MONA Group](https://github.com/themonagroup), chọn repo `monapay-<ngôn-ngữ>`, rồi làm theo README và tag trong repo. Trang [Mã nguồn MONA Pay trên GitHub](https://monapay.vn/docs/github) có danh sách link đầy đủ.

## Cách xác thực chung

Base URL production là:

```
https://api.monapay.vn
```

Vào dashboard [my.monapay.vn](https://my.monapay.vn), mở **API Keys**, tạo một key riêng cho ứng dụng và lưu hai giá trị sau vào secret store của backend:

```
export MONAPAY_BASE_URL="https://api.monapay.vn"
export MONAPAY_CLIENT_ID="client_id"
export MONAPAY_CLIENT_SECRET="client_secret"
export MONAPAY_WEBHOOK_SECRET="secret-hmac-rieng"
```

SDK đổi `client_id` và `client_secret` thành Bearer token qua `POST /api/v1/oauth/token`, cache token tới gần hạn và lấy lại một lần khi gặp HTTP 401. Các SDK tự gắn `X-Client-Secret` cho lệnh ghi POST, PUT và DELETE.

`MONAPAY_CLIENT_SECRET` dùng để ứng dụng gọi MONA Pay. `MONAPAY_WEBHOOK_SECRET` dùng để kiểm chữ ký dữ liệu MONA Pay gửi về. Hãy dùng hai chuỗi khác nhau và không đưa chúng xuống trình duyệt.

## Node.js: khởi tạo client

Node.js SDK cần Node 18 trở lên vì dùng `fetch` có sẵn:

```
import { MonaPay, verifyWebhook } from '@monapay/node';

const mona = new MonaPay({
  baseUrl: 'https://api.monapay.vn',
  clientId: process.env.MONAPAY_CLIENT_ID,
  clientSecret: process.env.MONAPAY_CLIENT_SECRET,
});
```

Nếu đã đặt đủ biến môi trường, có thể viết gọn:

```
const mona = MonaPay.fromEnv();
```

### 1. Tạo checkout

```
const checkout = await mona.checkouts.create({
  amount: 250000,
  order_code: 'DH10234',
  return_url: 'https://shop.vn/payment/return',
});

console.log(checkout.checkout_url);
```

Đưa `checkout_url` cho khách hoặc chuyển hướng trình duyệt sang đó. Chỉ giao hàng khi webhook `CHECKOUT_PAID` đã qua bước kiểm chữ ký và khớp đơn, số tiền; redirect của trình duyệt không đủ để xác nhận thanh toán.

### 2. Tra giao dịch theo tài khoản ảo

```
const page = await mona.transactions.list({
  virtualAccountNumber: 'MONA0000010234',
  page: 1,
  limit: 20,
});

for (const tx of page.data ?? []) {
  console.log(tx.transaction_code, tx.amount, tx.description);
}
```

`transaction_code` không đổi qua các lần gửi lại. Lưu trường này bằng unique constraint để một giao dịch chỉ cập nhật đơn một lần.

### 3. Kiểm chữ ký webhook HMAC

```
const rawBody = new Uint8Array(await request.arrayBuffer());
const result = verifyWebhook({
  rawBody,
  headers: request.headers,
  secret: process.env.MONAPAY_WEBHOOK_SECRET,
});

if (!result.ok) {
  return new Response(result.reason, { status: 401 });
}

await saveOnce(result.payload.transaction_code, result.payload);
return Response.json({ ok: true });
```

Phải truyền đúng raw body nhận từ mạng. Nếu parse JSON rồi stringify lại, byte có thể đổi và chữ ký sẽ sai. Verifier kiểm HMAC-SHA256, so sánh constant-time và mặc định từ chối timestamp lệch quá 300 giây.

## Python: khởi tạo client

Python SDK đồng bộ và chỉ dùng thư viện chuẩn:

```
import os
from monapay import MonaPay, verify_webhook

mona = MonaPay(
    base_url="https://api.monapay.vn",
    client_id=os.environ["MONAPAY_CLIENT_ID"],
    client_secret=os.environ["MONAPAY_CLIENT_SECRET"],
)
```

Khi đã đặt biến môi trường, dùng `MonaPay.from_env()`.

### 1. Tạo checkout

```
checkout = mona.checkouts.create({
    "amount": 250000,
    "order_code": "DH10234",
    "return_url": "https://shop.vn/payment/return",
})

print(checkout["checkout_url"])
```

Webhook `CHECKOUT_PAID` dùng trường `checkout_id`. Sau khi kiểm chữ ký, gọi `mona.checkouts.get(event["checkout_id"])` để đối chiếu trạng thái server-side trước khi giao hàng.

### 2. Tra giao dịch theo tài khoản ảo

```
page = mona.transactions.list(
    "MONA0000010234",
    page=1,
    limit=20,
)

for tx in page.get("data", []):
    print(tx["transaction_code"], tx["amount"], tx["description"])
```

Muốn đọc hết nhiều trang, dùng `mona.iter_transactions("MONA0000010234", limit=100)`.

### 3. Kiểm chữ ký webhook HMAC

```
raw_body = request.get_data(cache=True)
result = verify_webhook(
    raw_body,
    request.headers,
    os.environ["MONAPAY_WEBHOOK_SECRET"],
)

if not result.ok:
    return {"reason": result.reason}, 401

save_once(result.payload["transaction_code"], result.payload)
return {"ok": True}, 200
```

`raw_body` phải là `bytes`. SDK kiểm hai header `X-Mona-Timestamp`, `X-Mona-Signature` và cửa sổ 300 giây trước khi parse JSON.

## Thử luồng thanh toán bằng sandbox

Sandbox tạo giao dịch giả, bắn webhook và khớp checkout như luồng thật nhưng không chuyển tiền, không tính hạn mức. Tài khoản chưa nối ngân hàng vẫn dùng được.

**Node.js**

```
const checkout = await mona.checkouts.create({
  amount: 10000,
  order_code: 'DH-SBX-01',
  return_url: 'https://shop.vn/payment/return',
  sandbox: true,
});

await mona.sandbox.transaction({
  virtual_account_number: checkout.bank.account_number,
  amount: checkout.amount,
  description: checkout.order_code,
});

console.log((await mona.checkouts.get(checkout.id)).status); // "paid"
```

**Python**

```
checkout = mona.checkouts.create({
    "amount": 10000,
    "order_code": "DH-SBX-01",
    "return_url": "https://shop.vn/payment/return",
}, sandbox=True)

mona.sandbox.transaction(
    virtual_account_number=checkout["bank"]["account_number"],
    amount=checkout["amount"],
    description=checkout["order_code"],
)

print(mona.checkouts.get(checkout["id"])["status"])  # "paid"
```

Chạy sandbox trước với đủ tiền, thiếu tiền, chữ ký sai và `transaction_code` lặp. Khi lên production, giữ endpoint webhook public qua HTTPS, trả HTTP 200, 201 hoặc 202 trong 10 giây rồi xử lý phần nặng ở hàng đợi.

Đọc thêm: [Sandbox](https://monapay.vn/docs/api/sandbox) · [Bảo mật webhook](https://monapay.vn/docs/webhooks/bao-mat) · [API reference](https://monapay.vn/docs/api-reference)

Trong trang này

- Video hướng dẫn
- Bảng package và trạng thái phát hành
- Cách xác thực chung
- Node.js: khởi tạo client
- Python: khởi tạo client
- Thử luồng thanh toán bằng sandbox
