Skip to content

🎯 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}vcbMã 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ạiBắt buộcMô tả
orderIdStringID đơn hàng trong hệ thống của bạn
amountNumberSố tiền (VND) - ví dụ: 18000, 500000
merchantNameStringTên cửa hàng/thương nhân
merchantIdStringMã thương nhân do ngân hàng cấp
terminalIdStringID thiết bị/terminal
descriptionStringNội dung thanh toán
templateString-Kiểu template hiển thị (ví dụ: frame)
maskAccountBoolean-Ẩn số tài khoản (default: false)
frameIdNumber-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": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA1IAAARMCAYAAACTXaJiAAAACXBIWXMAAAsTAAALEwEAmpwYAAAgAElEQVR4nO...",
        "qrImageUrl": "http://103.249.116.110:3004/qr/qr_1780908088557_doghrplgu",
        "template": "frame",
        "decodedQrCode": "00020101021238630010A000000727013300069704360119QRPP2S26159194HHKZE0208QRIBFTTA5204732153037045405100005802VN5920CT CP TM DAU TU GAJA6011HO CHI MINH62350708591998060819THANH TOAN DON HANG63047130",
        "deeplink": "acbone://FUTE/external/transactions/v1/qrcode?timeStamp=1780908088558&qrCode=00020101021238630010A000000727013300069704360119QRPP2S26159194HHKZE0208QRIBFTTA5204732153037045405100005802VN5920CT%20CP%20TM%20DAU%20TU%20GAJA6011HO%20CHI%20MINH62350708591998060819THANH%20TOAN%20DON%20HANG63047130&signature=hQ5jWVmYrAAPpxyl%2F5X0dXLN9oZjot5JLAxIjcZNy2WisM0iVHiNyoqaVl6n%2F3TJgX9kgzbjRsTDxD2cFXTVU7pHlpCGDwWawZ4LHm1ZHnFw6yeneAySvoVsIDyUzxAgJZlW5%2B2ML4lVi4lJqZQOZviFz0fyFbtbbUNowg9MAkunqcJTKe%2FshRbEQ8%2BYXDHLm6BsysRN2mIhIlaaspL8BW1hvbJp0vzCmHHGe40PdE5QTk2YX56ug3fa3dgV5q7nHnxnql6FRkEpufnpTFiWO5KIUy70zviajLYbiIQoE0LL%2B%2Bs5kjaESWoVeixJ%2BGexD7ikmGU3YIWUXXlUYKdHbQ%3D%3D&redirectUrl=pay2s.vn",
        "signature": "hQ5jWVmYrAAPpxyl/5X0dXLN9oZjot5JLAxIjcZNy2WisM0iVHiNyoqaVl6n/3TJgX9kgzbjRsTDxD2cFXTVU7pHlpCGDwWawZ4LHm1ZHnFw6yeneAySvoVsIDyUzxAgJZlW5+2ML4lVi4lJqZQOZviFz0fyFbtbbUNowg9MAkunqcJTKe/shRbEQ8+YXDHLm6BsysRN2mIhIlaaspL8BW1hvbJp0vzCmHHGe40PdE5QTk2YX56ug3fa3dgV5q7nHnxnql6FRkEpufnpTFiWO5KIUy70zviajLYbiIQoE0LL++s5kjaESWoVeixJ+GexD7ikmGU3YIWUXXlUYKdHbQ==",
        "timeStamp": "1780908088558",
        "orderId": "123456",
        "amount": 10000,
        "status": "processing",
        "traceNumber": "QRPP2S26159194HHKZE",
        "qrData": "00020101021238630010A000000727013300069704360119QRPP2S26159194HHKZE0208QRIBFTTA5204732153037045405100005802VN5920CT CP TM DAU TU GAJA6011HO CHI MINH62350708591998060819THANH TOAN DON HANG63047130",
        "transactionId": "0e907bd2-74d0-4c49-96ba-e64660736a2a",
        "requestID": "P2S-1780908087998-3hlh5c4og"
    }
}
TrườngMô tả
codeMã lỗi: 00 = Thành công
descMô tả: Succeed = Thành công
qrDataURLChuỗi QR mã (EMV-QR format) - dùng để sinh hình ảnh QR
traceNumberMã định danh duy nhất của QR được tạo ra
transactionIdMã kiểm tra trạng thái QR

💻 Code mẫu - Tạo QR cho từng đơn hàng

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
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
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 để nhận thông báo thanh toán tự động