Appearance
Mô phỏng thanh toán đơn demo
Tự động kiểm thử Create đơn demo → mô phỏng thanh toán → nhận IPN. Dùng ngay Secret Key của tài khoản demo làm Bearer token; không cần token mới hoặc ký HMAC request.
Request
http
POST https://payment.pay2s.vn/v1/gateway/api/simulate-payment
Authorization: Bearer YOUR_DEMO_SECRET_KEY
Content-Type: application/jsonjson
{
"orderId": "ORDER_123",
"resendIpn": false
}orderId: mã đã gửi lúc create, không phải mã PAY2SJSC; bắt buộc là chuỗi.resendIpn: boolean tùy chọn, mặc địnhfalse. Đặttrueđể chủ động gửi lại IPN của đơn demo đã thanh toán.- Không cần gửi
accessKey,partnerCode,requestId,requestTypehaysignature. Không gửi Secret Key trong URL/body, không Base64 hay HMAC khóa. - Số tiền lấy từ đơn đã lưu; không truyền
amountđể thay đổi số tiền.
Điều kiện
Create vẫn dùng API hiện tại. Response create phải có environment: "demo": tài khoản là demo và tất cả ngân hàng được chọn đều là demo. Server kiểm tra tài khoản, ngân hàng nhận và cờ demo đã lưu của đơn; không tin cờ môi trường do client tự gửi.
Đơn phải thuộc phạm vi Secret Key, có ipnUrl và đang pending hoặc đã thanh toán demo trước đó. Đơn production, đơn đã hủy và orderId trùng nhiều đơn bị từ chối. Secret Key cửa hàng demo chỉ truy cập đơn cửa hàng đó; Secret Key tài khoản truy cập đơn không gắn cửa hàng, cùng phạm vi create.
Không chuyển tiền thật. API giữ nguyên dữ liệu/yêu cầu hóa đơn từ create, không tự thêm yêu cầu xuất hóa đơn. Luồng hóa đơn demo phụ thuộc cấu hình sandbox.
Postman
Import collection và Environment mẫu. Điền secretKey, orderId rồi chọn:
- Simulate Payment: mô phỏng thanh toán, không ép gửi lại IPN nếu đã thanh toán.
- Resend Demo IPN: cùng endpoint, với
resendIpn: trueđể test lại callback/trigger.
Cả hai đọc Secret Key từ Environment, đặt header Authorization và tạo body. Không có script ký HMAC cho hai request này. Create, Cancel và API HĐĐT vẫn giữ cách xác thực riêng.
Response
json
{
"status": true,
"message": "Đã ghi nhận giao dịch demo và khớp đơn thành công.",
"data": {
"partnerCode": "YOUR_PARTNER_CODE",
"orderId": "ORDER_123",
"invoiceNumber": "PAY2SJSC...",
"environment": "demo",
"orderStatus": "completed",
"transactionNumber": "DEMO-...",
"alreadyPaid": false,
"ipnRequeued": false,
"ipnStatus": "queued"
}
}alreadyPaid: true nghĩa là đơn đã thanh toán trước đó; không có giao dịch mới. ipnRequeued: true nghĩa là request này đã đặt lại hàng chờ IPN. ipnStatus có thể là queued, sending, sent, retrying, failed tại thời điểm trả kết quả.
Gửi và gửi lại IPN
Worker gửi POST tới ipnUrl của đơn. IPN vẫn có chữ ký m2signature như thanh toán thật; chỉ request giả lập được đơn giản hóa. Kiểm tra theo chữ ký IPN, phản hồi HTTP 200 và {"success":true} khi xử lý xong.
IPN gửi bất đồng bộ; response mô phỏng thành công không đảm bảo callback đã tới. Bộ test cần đợi IPN với thời gian chờ phù hợp. Đối chiếu bằng orderId; IPN hiện dùng requestId là ID nội bộ, requestTrace là requestId từ create.
- Gọi lại thông thường: không tạo giao dịch mới, không ép gửi lại IPN.
resendIpn: true: nếu đơn đã thanh toán và IPN đã gửi/đang retry/hết lượt retry, đưa lại vào hàng chờ.- IPN đang chờ hoặc đang gửi: giữ lượt hiện có, không tạo lượt song song.
- Đơn pending: thanh toán mô phỏng và gửi IPN lần đầu.
Mỗi lần gọi resendIpn: true sau khi lượt trước hoàn tất có thể tạo callback mới. Không dùng cờ này cho retry thanh toán thông thường. Callback giữ mã đơn/giao dịch nhưng thời gian và chữ ký có thể khác; phía nhận phải tránh cộng tiền/kích hoạt dịch vụ trùng.
Mã lỗi
| HTTP | Ý nghĩa |
|---|---|
| 400 | JSON, orderId hoặc kiểu resendIpn không hợp lệ |
| 401 | Thiếu/sai Secret Key |
| 403 | Tài khoản hoặc đơn production |
| 404 | Không có đơn trong phạm vi khóa |
| 409 | Đơn đã hủy, ngân hàng demo không hợp lệ, thiếu ipnUrl hoặc mã đơn bị trùng |
| 500 | Lỗi xử lý; có thể thử lại cùng orderId |
Không tìm thấy đơn thì báo lỗi; không tạo giao dịch độc lập thay thế.
