Nhà cung cấp VNPAY QR MMS
Nhà cung cấp VNPAY QR MMS (Multi-Merchant System) cho phép thanh toán bằng mã QR động. Khách hàng quét mã QR bằng bất kỳ ứng dụng ngân hàng nào của Việt Nam để hoàn tất thanh toán.
Tổng quan
| Thuộc tính | Giá trị |
|---|---|
| Khóa Nhà cung cấp | VNPAY_QR_MMS |
| Phương thức Thanh toán | 100_QR_CODE |
| Quyết toán | T+1 |
| Tiêu chuẩn QR | VietQR / EMVCo |
Tính năng
- Mã QR động - Mã QR duy nhất cho mỗi giao dịch
- Hỗ trợ đa ngân hàng - Hoạt động với hơn 40 ngân hàng Việt Nam
- IPN thời gian thực - Thông báo thanh toán tức thì
- Đối soát tự động - Báo cáo quyết toán hàng ngày
Cấu hình
VNPAY QR MMS sử dụng phân giải thông tin xác thực động qua mẫu credentialGetter. Khóa bí mật được lấy tại thời điểm chạy, cho phép các merchant khác nhau có thông tin xác thực khác nhau.
Cấu hình Ứng dụng
typescript
import { MQPayComponent, MQPayBindingKeys, IMQPayOptions } from '@nx-3rd/mq-pay';
class MyApplication extends BaseApplication {
preConfigure() {
this.bind<IMQPayOptions>({ key: MQPayBindingKeys.MQ_PAY_CLIENT_OPTIONS })
.toValue({
// Credential getter cho khóa bí mật động theo merchant
credentialGetter: async ({ provider, action, types, context }) => {
// Lấy thông tin xác thực từ kho lưu trữ an toàn (cơ sở dữ liệu, vault, v.v.)
return fetchCredentialsFromSecureStorage({ provider, action, types, context });
},
vnpayQrMMS: {
enable: true,
isDefault: true,
enableController: true,
// Bắt buộc: VNPAY App ID
appId: 'your-app-id',
// Bắt buộc: Mã merchant chính
masterMerchantCode: 'your-merchant-code',
// Cờ môi trường
isProduction: process.env.NODE_ENV === 'production',
// Tùy chọn: Trình xử lý thông báo tùy chỉnh
onPaymentNotification: async (ipnData) => {
console.log('QR Payment received:', ipnData);
},
},
});
this.component(MQPayComponent);
}
}Tùy chọn Cấu hình
| Tùy chọn | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
enable | boolean | Có | Bật nhà cung cấp này |
isDefault | boolean | Có | Sử dụng làm nhà cung cấp mặc định |
enableController | boolean | Có | Tự động đăng ký điểm cuối IPN |
appId | string | Có | VNPAY App ID từ đăng ký merchant |
masterMerchantCode | string | Có | Mã merchant VNPAY |
isProduction | boolean | Có | true cho môi trường production |
onPaymentNotification | function | Không | Callback xử lý IPN tùy chỉnh |
Ánh xạ Thông tin Xác thực
Khóa bí mật được lấy động qua credentialGetter:
| Khóa Bí mật | Hành động | Loại |
|---|---|---|
createQr.request | CREATE_PAYMENT | REQUEST |
createQr.response | CREATE_PAYMENT | RESPONSE |
createQr.ipn | VERIFY_IPN | IPN |
checkTransaction.request | CHECK_TRANSACTION | REQUEST |
checkTransaction.response | CHECK_TRANSACTION | RESPONSE |
refund.request | REFUND | REQUEST |
refund.response | REFUND | RESPONSE |
Luồng Thanh toán
Sử dụng API
Tạo Thanh toán QR
typescript
const response = await paymentService.checkout({
source: {
type: 'Order',
id: 'order-uuid-123',
uid: 'ORD-2024-001',
},
payment: {
provider: 'VNPAY_QR_MMS',
method: '100_QR_CODE',
total: 150000,
currency: 'VND',
},
expiration: {
mode: 'duration',
milliseconds: 300000, // 5 phút
},
});
// Phản hồi
{
transaction: {
id: 'txn-uuid',
number: 'TXN001',
status: '100_NEW',
total: '150000.0000',
},
attempt: {
id: 'att-uuid',
code: 'ATT001',
status: '204_SENT',
provider: 'VNPAY_QR_MMS',
method: '100_QR_CODE',
},
payment: {
qrCode: '00020101021238570010A00000072701...',
qrUrl: 'https://api.vnpay.vn/qrpay/...',
qrDataUrl: 'data:image/png;base64,...',
expiresAt: '2024-01-15T10:35:00Z',
},
}Truy vấn Trạng thái Thanh toán
typescript
const status = await paymentService.queryStatus({
attemptId: 'att-uuid',
});
// Phản hồi
{
attempt: {
id: 'att-uuid',
status: '302_SUCCESS',
paidAt: '2024-01-15T10:32:15Z',
},
providerData: {
bankCode: 'VCB',
bankTransactionNo: '20240115123456',
customerName: 'NGUYEN VAN A',
},
}IPN (Thông báo Thanh toán Tức thì)
Điểm cuối IPN
Khi enableController: true, MQ-Pay tự động đăng ký:
POST /api/mq-pay/vnpay/qr-mms/ipnCấu trúc Dữ liệu IPN
typescript
interface VNPayQrIPNData {
vnp_TxnRef: string; // Mã attempt của bạn (ATT001)
vnp_TransactionNo: string; // Số giao dịch VNPAY
vnp_Amount: number; // Số tiền bằng VND (nhân 100)
vnp_ResponseCode: string; // '00' = thành công
vnp_BankCode: string; // VCB, TCB, MB, v.v.
vnp_PayDate: string; // YYYYMMDDHHmmss
vnp_SecureHash: string; // Chữ ký HMAC-SHA512
}Mã Phản hồi
| Mã | Mô tả | Hành động |
|---|---|---|
00 | Thành công | Thanh toán hoàn tất |
07 | Giao dịch đáng ngờ | Liên hệ VNPAY |
11 | Hết thời gian | QR hết hạn |
24 | Đã hủy | Khách hàng đã hủy |
51 | Không đủ tiền | Vấn đề của khách hàng |
75 | Ngân hàng bảo trì | Thử lại sau |