Khởi tạo OneQR - Tạo QR động
Nội dung Markdown đầy đủ của trang tài liệu.
# 🎯 Khởi tạo OneQR - Tạo QR động
## 📱 Tổng quan
Để tạo một mã QR động cho giao dịch, bạn gọi API **Create QR Code** của OneQR. Mỗi lần gọi sẽ sinh ra **1 QR mới** với các thông tin giao dịch cụ thể.
---
## 🔌 Endpoint
```
POST http://api.pay2s.vn/api/{bank_code}/v1/qr/create
```
| Tham số | Ví dụ | Mô tả |
|--------|-------|-------|
| `{bank_code}` | `vcb` | Mã ngân hàng (vcb = Vietcombank, acb = ACB Bank, ...) |
---
## 📤 Request
### Headers
```json
{
"Content-Type": "application/json",
"Authorization": "Bearer <token>"
}
```
> **Lưu ý**: `<token>` là Bearer token được cấp từ Pay2S
### Body Parameters (JSON)
| Tham số | Loại | Bắt buộc | Mô tả |
|--------|------|---------|-------|
| `orderId` | String | ✓ | ID đơn hàng trong hệ thống của bạn |
| `amount` | Number | ✓ | Số tiền (VND) - ví dụ: 18000, 500000 |
| `merchantName` | String | ✓ | Tên cửa hàng/thương nhân |
| `merchantId` | String | ✓ | Mã thương nhân do ngân hàng cấp |
| `terminalId` | String | ✓ | ID thiết bị/terminal |
| `description` | String | ✓ | Nội dung thanh toán |
| `template` | String | - | Kiểu template hiển thị (ví dụ: `frame`) |
| `maskAccount` | Boolean | - | Ẩn số tài khoản (default: false) |
| `frameId` | Number | - | ID khung hình để hiển thị QR |
### ✅ Ví dụ Request (cURL)
```bash
curl --location 'http://api.pay2s.vn/api/vcb/v1/qr/create' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_BEARER_TOKEN' \
--data '{
"orderId": "123456",
"amount": 10000,
"merchantName": "CONG TY CO PHAN FUTE",
"merchantId": "091000000900000",
"terminalId": "60000000",
"description": "THANH TOAN DON HANG",
"template": "frame",
"maskAccount": true,
"frameId": 1
}'
```
---
## 📥 Response
### ✅ Thành công (200 OK)
```json
{
"code": "00",
"desc": "Succeed",
"data": {
"qrDataURL": "<QRDATAURL_OMITTED>",
"qrImageUrl": "<QRIMAGEURL_OMITTED>",
"template": "frame",
"decodedQrCode": "https://developer.example.com/payment/?qr=da58fde344a1e0c9280207e1143c6f40",
"deeplink": "https://developer.example.com/payment/?qr=da58fde344a1e0c9280207e1143c6f40",
"signature": "<SIGNATURE>",
"timeStamp": "1791659974931",
"orderId": "DEMO17916599748852455",
"amount": 100000,
"status": "processing",
"traceNumber": "DEMOQR50269d422b61",
"qrData": "https://developer.example.com/payment/?qr=da58fde344a1e0c9280207e1143c6f40",
"transactionId": "da58fde344a1e0c9280207e1143c6f40",
"requestID": "DEMO-6e40f8301889"
}
}
```
| Trường | Mô tả |
|--------|-------|
| `code` | Mã lỗi: `00` = Thành công |
| `desc` | Mô tả: `Succeed` = Thành công |
| `qrDataURL` | Chuỗi QR mã (EMV-QR format) - dùng để sinh hình ảnh QR |
| `traceNumber` | Mã định danh duy nhất của QR được tạo ra |
| `transactionId` | Mã kiểm tra trạng thái QR |
---
## 💻 Code mẫu - Tạo QR cho từng đơn hàng
::: code-group
```php [PHP]
<?php
$bearerToken = "YOUR_BEARER_TOKEN";
$url = "http://api.pay2s.vn/api/vcb/v1/qr/create";
$data = [
'orderId' => "123456",
'amount' => 10000,
'merchantName' => "CONG TY CO PHAN FUTE",
'merchantId' => "091000000900000",
'terminalId' => "60000000",
'description' => "THANH TOAN DON HANG",
'template' => "frame",
'maskAccount' => true,
'frameId' => 1
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . $bearerToken,
"Content-Type: application/json"
]);
$response = curl_exec($ch);
$result = json_decode($response, true);
if ($result['code'] === '00') {
$qrData = $result['data'];
echo "QR Code: " . $qrData;
} else {
echo "Error: " . $result['desc'];
}
curl_close($ch);
?>
```
```javascript [Node.js]
const axios = require('axios');
const bearerToken = "YOUR_BEARER_TOKEN";
const payload = {
orderId: "123456",
amount: 10000,
merchantName: "CONG TY CO PHAN FUTE",
merchantId: "091000000900000",
terminalId: "60000000",
description: "THANH TOAN DON HANG",
template: "frame",
maskAccount: true,
frameId: 1
};
axios.post("http://api.pay2s.vn/api/vcb/v1/qr/create", payload, {
headers: {
"Authorization": `Bearer ${bearerToken}`,
"Content-Type": "application/json"
}
})
.then(response => {
if (response.data.code === '00') {
console.log("QR Code:", response.data.data);
} else {
console.error("Error:", response.data.desc);
}
})
.catch(err => console.error(err));
```
```python [Python]
import requests
import json
bearer_token = "YOUR_BEARER_TOKEN"
payload = {
'orderId': "123456",
'amount': 10000,
'merchantName': "CONG TY CO PHAN FUTE",
'merchantId': "091000000900000",
'terminalId': "60000000",
'description': "THANH TOAN DON HANG",
'template': "frame",
'maskAccount': True,
'frameId': 1
}
headers = {
"Authorization": f"Bearer {bearer_token}",
"Content-Type": "application/json"
}
response = requests.post("http://api.pay2s.vn/api/vcb/v1/qr/create",
data=json.dumps(payload),
headers=headers)
result = response.json()
if result['code'] == '00':
print("QR Code:", result['data'])
else:
print("Error:", result['desc'])
```
:::
---
## ⚡ Best Practices
1. **Validate input**: Kiểm tra `amount > 0` trước khi request
2. **Error handling**: Kiểm tra `code` trước xử lý `data`
3. **Lưu QR data**: Lưu chuỗi QR vào database để regenerate ảnh nếu cần
4. **Timeout QR**: Đặt QR có hiệu lực 15-30 phút
5. **MaskAccount**: Sử dụng `maskAccount: true` để bảo mật thông tin
6. **Template**: Chọn `template: "frame"` để hiển thị với UI frame
7. **TerminalId**: Đảm bảo terminalId hợp lệ từ ngân hàng
8. **Retry logic**: Nếu request fail, retry sau 2-3 giây
9. **Database record**: Lưu `orderId`, `amount`, `qr_status` để tracking
10. **Rate limit**: Giới hạn số lượng request tạo QR mỗi phút
---
## 📌 Luồng tạo QR
```
1. Khách order → 2. Hệ thống tạo QR → 3. Hiển thị ảnh QR + frame →
4. Khách scan QR → 5. Chọn ngân hàng → 6. Xác nhận →
7. Thanh toán → 8. Webhook notify → 9. Cập nhật status = paid
```
---
> **Tiếp theo**: Xem [Webhook](/webhook/tai-lieu-ky-thuat.html) để nhận thông báo thanh toán tự động
## Request và response đối chiếu ngày 11/10/2026
Các mẫu dưới đây giữ cấu trúc trường và kiểu dữ liệu. Khóa, chữ ký, URL phiên đã được thay bằng placeholder; danh sách chỉ giữ tối đa hai phần tử và dữ liệu ảnh/PDF/XML dài được rút gọn. Không sao chép placeholder để gọi API thật.
### OneQR · Tạo QR động
<div class="doc-api-actions" data-doc-api-actions><a class="try-button" data-doc-playground href="/playground/?api=oneqr-create">Thử API trong Playground ↗</a><a class="try-button experience-button" data-doc-experience hidden>Trải nghiệm ↗</a></div>
**Mô phỏng; chưa xác minh với API nhà cung cấp.** Giữ mô phỏng theo cấu hình demo. Chưa có API OneQR thật để xác minh lại hợp đồng nhà cung cấp.
`POST /api/{bank_code}/v1/qr/create`
Body:
```json
{
"orderId": "DEMO17916599748852455",
"amount": 100000,
"merchantName": "CUA HANG DEMO",
"merchantId": "DEMO_MERCHANT",
"terminalId": "DEMO_TERMINAL",
"description": "THANHTOANDEMO",
"template": "frame",
"maskAccount": false,
"frameId": 1
}
```
HTTP 200. Response:
```json
{
"code": "00",
"desc": "Succeed",
"data": {
"qrDataURL": "<QRDATAURL_OMITTED>",
"qrImageUrl": "<QRIMAGEURL_OMITTED>",
"template": "frame",
"decodedQrCode": "https://developer.example.com/payment/?qr=da58fde344a1e0c9280207e1143c6f40",
"deeplink": "https://developer.example.com/payment/?qr=da58fde344a1e0c9280207e1143c6f40",
"signature": "<SIGNATURE>",
"timeStamp": "1791659974931",
"orderId": "DEMO17916599748852455",
"amount": 100000,
"status": "processing",
"traceNumber": "DEMOQR50269d422b61",
"qrData": "https://developer.example.com/payment/?qr=da58fde344a1e0c9280207e1143c6f40",
"transactionId": "da58fde344a1e0c9280207e1143c6f40",
"requestID": "DEMO-6e40f8301889"
}
}
```