Sandbox MONA Pay: thử giao dịch và checkout không tốn tiền

Video hướng dẫn

Sandbox MONA Pay: thử giao dịch và checkout không tốn tiền · Xem trên YouTube
Xem transcript video (9 phần)

Thử trọn luồng an toàn

Đưa code thanh toán lên thật rồi mới thử ca thiếu tiền hoặc webhook gửi lại là quá rủi ro. Sandbox cho anh chị chạy trọn luồng mà không chuyển tiền thật. Trong video này, mình tạo giao dịch giả, nhận thông báo, thử checkout đủ tiền, thiếu tiền và gửi trùng mã. Chưa nối ngân hàng, anh chị vẫn làm được với tài khoản ảo bắt đầu bằng SBX.

Tạo giao dịch sandbox

Endpoint là POST /api/v1/sandbox/transactions, cần Bearer và X-Client-Secret. Body tối thiểu có amount, số nguyên lớn hơn không, tối đa một tỷ đồng, cùng description dài từ một đến hai trăm năm mươi lăm ký tự. Nếu không truyền tài khoản, hệ thống tự tạo hoặc dùng lại VA sandbox SBX. Response còn trả mã giao dịch, số VA, số tài khoản và số tiền; is_sandbox bằng true.

Chọn VA và mã thử

Muốn thử trên một VA đã có, truyền virtual_account_number. Muốn chỉ định tài khoản thật đã nối, dùng account_number; chỉ cần một trong hai. transaction_code là tùy chọn, dài tối đa một trăm ký tự. Tự đặt mã như SANDBOX-DH10234-01 rất hữu ích để kiểm chống trùng. Nếu bỏ trống, hệ thống sinh mã bắt đầu bằng SANDBOX.

Đi qua kênh thật

Giao dịch sandbox đi qua cùng bộ xử lý như giao dịch thật, nên webhook, Telegram, email và logic khớp checkout đều nhận được. Trong bảng nội bộ, vẫn dùng transaction_code làm khóa chống trùng và dùng is_sandbox để phân biệt môi trường thử. Không viết một nhánh xử lý hoàn toàn khác, vì mục tiêu của sandbox là kiểm đúng code mà anh chị sẽ chạy khi có tiền thật.

Đưa localhost ra HTTPS

Nếu endpoint webhook đang ở máy cá nhân, MONA Pay không gọi trực tiếp được localhost. Tạo URL HTTPS công khai bằng lệnh cloudflared tunnel --url http://localhost:4400, rồi dán URL được cấp vào webhook_url. Nếu chưa có URL công khai, trong lúc thử checkout anh chị có thể gọi GET /api/v1/checkouts/{checkout_id} mỗi vài giây để đọc trạng thái.

Tạo checkout sandbox

Để thử trang thanh toán, thêm sandbox bằng true vào body POST /api/v1/checkouts, đồng thời gửi Idempotency-Key. Response trả checkout_url, dữ liệu QR và VA SBX; trang thanh toán có dải “PHIÊN THỬ, không chuyển tiền thật”. Lấy data.bank.account_number hoặc VA trong response rồi tạo giao dịch sandbox vào đúng số đó. Khi tổng tiền đủ, phiên thành paid và phát CHECKOUT_PAID.

Chạy ba ca kiểm thử

Ca đầu là đủ tiền: checkout hai trăm năm mươi nghìn, giao dịch sandbox đúng hai trăm năm mươi nghìn, chờ CHECKOUT_PAID và bảo đảm đơn chỉ xử lý một lần. Ca hai là thiếu tiền: bắn hai trăm nghìn, status phải giữ pending và có partial_amount. Ca ba gửi lại cùng transaction_code; tổng tiền không được cộng thêm và trạng thái không được xử lý lần nữa.

Biết giới hạn sandbox

Sandbox không gửi hay nhận tiền thật và giao dịch thử không tính vào hạn mức gói. VA SBX, QR và checkout thử không đưa cho khách thanh toán. Kết quả sandbox kiểm luồng dịch vụ cùng code của anh chị, nhưng không thay lần thử cuối bằng một khoản chuyển thật sau khi nối ngân hàng. Nếu trùng mã mà số tiền cộng dồn, hãy kiểm khóa UNIQUE và cách xử lý transaction_code.

Mở docs và thử ngay

Lệnh tạo giao dịch, checkout thử và ba kịch bản kiểm tra nằm tại monapay.vn/docs/api/sandbox. Anh chị đăng ký tại my.monapay.vn, lấy khóa API rồi chạy đầy đủ cả ba ca sandbox trước khi nối ngân hàng thật. Nếu webhook, email hoặc trạng thái checkout chưa đổi như mong đợi, gọi tổng đài một chín không không, sáu ba sáu, sáu bốn tám để đội MONA hỗ trợ đối chiếu luồng.

Sandbox cho anh chị chạy trọn luồng xác nhận thanh toán mà không chuyển tiền thật. Gọi POST /api/v1/sandbox/transactions, MONA Pay ghi một giao dịch giả rồi phát qua webhook, Telegram, email và bộ khớp hosted checkout giống luồng thật.

Chưa nối ngân hàng vẫn thử được. MONA Pay tự tạo một VA sandbox riêng cho tài khoản, có số bắt đầu bằng SBX…. Nếu anh chị đã có VA thật, có thể truyền số VA đó; giao dịch vẫn mang cờ is_sandbox: true và không đụng tới tiền trong ngân hàng.

POST /api/v1/sandbox/transactions

Request cần Bearer token và X-Client-Secret:

curl -X POST https://api.monapay.vn/api/v1/sandbox/transactions \
  -H "Authorization: Bearer $MONA_TOKEN" \
  -H "X-Client-Secret: $MONA_SECRET" \
  -H 'Content-Type: application/json' \
  -d '{"amount":250000,"description":"Thanh toan DH10234"}'

Không truyền số tài khoản thì MONA Pay tự cấp hoặc dùng lại VA sandbox SBX… của anh chị. Muốn thử trên một VA thật đã nối, truyền thêm virtual_account_number:

{
  "virtual_account_number": "LOCHOA000123456",
  "amount": 250000,
  "description": "Thanh toan DH10234",
  "transaction_code": "SANDBOX-DH10234-01"
}
Trường Kiểu Bắt buộc Ghi chú
virtual_account_number string, tối đa 50 ký tự không Số VA thật hoặc VA SBX…; bỏ trống để MONA Pay tự cấp VA sandbox
account_number string, tối đa 50 ký tự không Tài khoản thật đã nối; chỉ cần một trong hai trường số tài khoản nếu muốn chỉ định nơi nhận
amount integer Số tiền giả, lớn hơn 0 và tối đa 1.000.000.000 VND
description string, 1–255 ký tự Nội dung chuyển khoản giả; nên đặt mã đơn để kiểm logic khớp
transaction_code string, 1–100 ký tự không Mã tự đặt để thử chống trùng; bỏ trống thì MONA Pay sinh mã SANDBOX-…

Response 200:

{
  "success": true,
  "message": "Sandbox transaction accepted",
  "data": {
    "transaction_code": "SANDBOX-DH10234-01",
    "virtual_account_number": "SBX000123456",
    "account_number": "SBX000123456",
    "amount": 250000,
    "is_sandbox": true
  }
}

Giao dịch đi qua cùng bộ xử lý và kênh thông báo như giao dịch thật. Khi đối soát, dùng transaction_code làm khoá chống trùng và nhận biết môi trường thử bằng is_sandbox.

Chạy webhook trên localhost

Webhook cần một URL HTTPS công khai, MONA Pay không thể gọi trực tiếp vào localhost.

cloudflared tunnel --url http://localhost:4400

Dán URL HTTPS do tunnel cấp vào webhook_url; anh chị cũng có thể dùng ngrok. Nếu chưa có URL công khai, hãy hỏi lại GET /api/v1/checkouts/{checkout_id} mỗi vài giây trong lúc thử. Trang Địa chỉ IP chỉ áp dụng khi đưa hệ thống lên production.

Thử hosted checkout

Khi tạo checkout, thêm "sandbox": true vào body. Phiên thử dùng VA SBX…, trả checkout_url, dữ liệu QR hợp lệ để hiển thị và trường sandbox: true; trang thanh toán có dải PHIÊN THỬ, không chuyển tiền thật.

curl -X POST https://api.monapay.vn/api/v1/checkouts \
  -H "Authorization: Bearer $MONA_TOKEN" \
  -H "X-Client-Secret: $MONA_SECRET" \
  -H "Idempotency-Key: sandbox-DH10234" \
  -H 'Content-Type: application/json' \
  -d '{"amount":250000,"order_code":"DH10234","return_url":"https://shop.vn/payment/return","sandbox":true}'

Lấy data.bank.account_number hoặc số VA trong response checkout, rồi gọi /sandbox/transactions với virtual_account_number đó. Khi tổng tiền sandbox đủ amount, phiên chuyển sang paid và phát CHECKOUT_PAID. Chi tiết trường checkout ở Trang thanh toán.

Ba ca nên chạy trước khi lên thật

  1. Đủ tiền: tạo checkout 250.000đ, bắn một giao dịch sandbox 250.000đ. Chờ CHECKOUT_PAID, kiểm chữ ký, trạng thái paid và việc xử lý đơn chỉ chạy một lần.
  2. Thiếu tiền: tạo checkout 250.000đ, bắn 200.000đ. Phiên phải giữ pending và ghi partial_amount; chưa được giao hàng.
  3. Gửi lại cùng mã giao dịch: gửi lại đúng transaction_code. MONA Pay trả 200 giống lần đầu và không cộng dồn, vì vậy paid_amount giữ nguyên. Muốn tự động kiểm ca này, gọi GET /api/v1/checkouts/{checkout_id} trước và sau, rồi so paid_amountpartial_amount.

Giới hạn của sandbox

  • Không có tiền thật được gửi hoặc nhận; đừng quét QR sandbox để chuyển khoản.
  • Giao dịch sandbox không tính vào hạn mức giao dịch của gói.
  • VA SBX…, QR và checkout sandbox chỉ dùng để thử; không đưa cho khách thanh toán thật.
  • Sandbox kiểm luồng MONA Pay và code của anh chị, không thay cho lần kiểm tra cuối bằng một khoản chuyển thật sau khi nối ngân hàng.

Xem thêm định dạng payload webhook, bảo mật webhookđối soát giao dịch.