Developer

🔍 Kiểm tra OneQR - Xem chi tiết QR

✧ Mở bằng AI

Sao chép tài liệu, mở AI rồi dán vào cuộc trò chuyện.

ChatGPTClaudePerplexityGrok
≡ Xem Markdown

📱 Tổng quan

Để kiểm tra chi tiết một mã QR đã tạo, bạn gọi API Retrieve QR Transaction của OneQR. API này trả về đầy đủ thông tin giao dịch và trạng thái thanh toán.


🔌 Endpoint

GET http://api.pay2s.vn/api/{bank_code}/v1/qr/transactions/{transactionId}
Tham số Ví dụ Mô tả
{bank_code} vcb Mã ngân hàng (vcb = Vietcombank, acb = ACB Bank, ...)
{transactionId} 0e907bd2-74d0-4c49-96ba-e64660736a2a Mã truy vấn (từ response tạo QR)

📤 Request

Headers

{
  "Authorization": "Bearer <token>"
}

Lưu ý: <token> là Bearer token được cấp từ Pay2S

✅ Ví dụ Request (cURL)

curl --location 'http://api.pay2s.vn/api/vcb/v1/qr/transactions/0e907bd2-74d0-4c49-96ba-e64660736a2a' \
  --header 'Authorization: Bearer YOUR_BEARER_TOKEN'

📥 Response

✅ Thành công (200 OK)

{
  "success": true,
  "message": "QR transaction retrieved successfully",
  "data": {
    "transactionId": "da58fde344a1e0c9280207e1143c6f40",
    "merchantId": "DEMO_MERCHANT",
    "terminalId": "DEMO_TERMINAL",
    "orderId": "DEMO17916599748852455",
    "amount": 100000,
    "description": "THANHTOANDEMO",
    "exoDate": null,
    "qrData": "https://developer.example.com/payment/?qr=da58fde344a1e0c9280207e1143c6f40",
    "status": "processing",
    "traceNumber": "DEMOQR50269d422b61",
    "bankCode": "978485",
    "responseCode": "00",
    "requestId": "P2S-1780908087998-3hlh5c4og",
    "vcbResponse": {
      "code": "00",
      "nodeIn": "0.0.0.0",
      "message": "Succeed",
      "nodeOut": "10.1.60.185",
      "subCode": "00",
      "checksum": "8DB582799A700B17FA56C2558CC8CCB1",
      "operation": "InitInvoice",
      "ccPayLoad": "https://developer.example.com/payment/?qr=da58fde344a1e0c9280207e1143c6f40",
      "requestId": "P2S-1780908087999-3hlh5c4og",
      "paymentRef": "DEMOQR50269d422b61",
      "serverTime": "15:42:07 09/06/2026",
      "subMessage": "Succeed",
      "paymentName": "CUA HANG DEMO"
    },
    "auditData": {
      "channel": "P2S",
      "channelId": "0.0.0.0",
      "channelTime": "2825600815142",
      "channelUser": "adi-payment",
      "channelUserBranch": "01"
    },
    "createdAt": "2026-10-10T19:19:34.931Z"
  }
}

Giải thích Response

Trường Mô tả
success Trạng thái: true = Lấy thông tin thành công
transactionId Mã giao dịch duy nhất
orderId ID đơn hàng
amount Số tiền (VND)
status Trạng thái: processing (chờ), paid (thanh toán), cancelled (hủy)
qrData Chuỗi QR mã (EMV-QR format)
traceNumber Mã định danh QR
vcbResponse Chi tiết response từ ngân hàng
createdAt Thời gian tạo QR
paymentRef Mã tham chiếu thanh toán

💻 Code mẫu - Kiểm tra QR

<?php
$bearerToken = "YOUR_BEARER_TOKEN";
$transactionId = "0e907bd2-74d0-4c49-96ba-e64660736a2a";
$url = "http://api.pay2s.vn/api/vcb/v1/qr/transactions/" . $transactionId;

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer " . $bearerToken
]);

$response = curl_exec($ch);
$result = json_decode($response, true);

if ($result['success'] === true) {
    $txn = $result['data'];
    
    echo "Order ID: " . $txn['orderId'] . "\n";
    echo "Amount: " . $txn['amount'] . " VND\n";
    echo "Status: " . $txn['status'] . "\n";
    echo "Description: " . $txn['description'] . "\n";
    echo "Created: " . $txn['createdAt'] . "\n";
    
    // Kiểm tra thanh toán
    if ($txn['status'] === 'paid') {
        echo "✅ Thanh toán thành công!\n";
        echo "Payment Ref: " . $txn['paymentRef'] . "\n";
    } else if ($txn['status'] === 'processing') {
        echo "⏳ Chờ thanh toán...\n";
    } else if ($txn['status'] === 'cancelled') {
        echo "❌ QR đã bị hủy\n";
    }
} else {
    echo "Error: " . $result['message'];
}

curl_close($ch);
?>
const axios = require('axios');

const bearerToken = "YOUR_BEARER_TOKEN";
const transactionId = "0e907bd2-74d0-4c49-96ba-e64660736a2a";

const url = `http://api.pay2s.vn/api/vcb/v1/qr/transactions/${transactionId}`;

axios.get(url, {
  headers: {
    "Authorization": `Bearer ${bearerToken}`
  }
})
  .then(response => {
    if (response.data.success === true) {
      const txn = response.data.data;
      
      console.log(`Order ID: ${txn.orderId}`);
      console.log(`Amount: ${txn.amount} VND`);
      console.log(`Status: ${txn.status}`);
      console.log(`Description: ${txn.description}`);
      console.log(`Created: ${txn.createdAt}`);
      
      // Check payment status
      if (txn.status === 'paid') {
        console.log("✅ Payment successful!");
        console.log(`Payment Ref: ${txn.paymentRef}`);
      } else if (txn.status === 'processing') {
        console.log("⏳ Waiting for payment...");
      } else if (txn.status === 'cancelled') {
        console.log("❌ QR was cancelled");
      }
    } else {
      console.error("Error:", response.data.message);
    }
  })
  .catch(err => console.error(err));
import requests

bearer_token = "YOUR_BEARER_TOKEN"
transaction_id = "0e907bd2-74d0-4c49-96ba-e64660736a2a"

url = f"http://api.pay2s.vn/api/vcb/v1/qr/transactions/{transaction_id}"

headers = {
    "Authorization": f"Bearer {bearer_token}"
}

response = requests.get(url, headers=headers)
result = response.json()

if result['success'] == True:
    txn = result['data']
    
    print(f"Order ID: {txn['orderId']}")
    print(f"Amount: {txn['amount']} VND")
    print(f"Status: {txn['status']}")
    print(f"Description: {txn['description']}")
    print(f"Created: {txn['createdAt']}")
    
    # Check payment status
    if txn['status'] == 'paid':
        print("✅ Payment successful!")
        print(f"Payment Ref: {txn['paymentRef']}")
    elif txn['status'] == 'processing':
        print("⏳ Waiting for payment...")
    elif txn['status'] == 'cancelled':
        print("❌ QR was cancelled")
else:
    print("Error:", result['message'])
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class RetrieveQRClient {
    
    public static void main(String[] args) throws Exception {
        String bearerToken = "YOUR_BEARER_TOKEN";
        String transactionId = "0e907bd2-74d0-4c49-96ba-e64660736a2a";
        
        String url = "http://api.pay2s.vn/api/vcb/v1/qr/transactions/" + transactionId;
        
        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Authorization", "Bearer " + bearerToken);
        
        int responseCode = conn.getResponseCode();
        System.out.println("Response Code: " + responseCode);
        
        if (responseCode == 200) {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String inputLine;
            StringBuilder response = new StringBuilder();
            
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
            
            // Parse and display JSON response
            System.out.println("Response: " + response.toString());
            
            // Note: For production, use a JSON library like Gson or Jackson
        }
    }
}

⚡ Best Practices

  1. Cache transaction ID: Lưu transactionId từ khi tạo QR để kiểm tra sau
  2. Poll status: Gọi API này định kỳ để kiểm tra trạng thái thanh toán
  3. Error handling: Kiểm tra success trước xử lý data
  4. Timeout: Đặt timeout hợp lý (30-60 giây)
  5. Retry logic: Nếu request fail, retry sau 2-3 giây
  6. Check payment status: Luôn kiểm tra status trước cập nhật database
  7. Store response: Lưu toàn bộ response để audit trail
  8. VCB Response: Kiểm tra vcbResponse.code để xác nhận ngân hàng
  9. Avoid repeated calls: Đừng gọi quá nhiều lần trong một vài giây
  10. Logging: Log transactionId và status để debug

🔄 Luồng kiểm tra QR

// 1. Tạo QR → nhận transactionId
// 2. Hiển thị QR cho khách hàng
// 3. Poll API kiểm tra status
const interval = setInterval(() => {
  getQRStatus(transactionId).then(status => {
    if (status === 'completed') {
      clearInterval(interval);
      console.log("✅ Payment completed");
      updateOrderStatus('paid');
    } else if (status === 'cancelled') {
      clearInterval(interval);
      console.log("❌ QR cancelled");
    }
  });
}, 2000); // Kiểm tra mỗi 2 giây

📊 Trạng thái QR

Status Mô tả Hành động
processing Chờ thanh toán Tiếp tục kiểm tra
paid Đã thanh toán Cập nhật order, gửi email
cancelled QR bị hủy Hiển thị lỗi, yêu cầu tạo QR mới
expired QR hết hạn Yêu cầu tạo QR mới

Tiếp theo: Xem Danh sách OneQR để xem tất cả QR hoặc Webhook để nhận thông báo 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 · Truy vấn trạng thái

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.

GET /api/{bank_code}/v1/qr/transactions/{transactionId}

Tham số path/query (không gửi JSON body):

{
  "bank_code": "vcb",
  "transactionId": "LAST_QR"
}

HTTP 200. Response:

{
  "success": true,
  "message": "QR transaction retrieved successfully",
  "data": {
    "transactionId": "da58fde344a1e0c9280207e1143c6f40",
    "merchantId": "DEMO_MERCHANT",
    "terminalId": "DEMO_TERMINAL",
    "orderId": "DEMO17916599748852455",
    "amount": 100000,
    "description": "THANHTOANDEMO",
    "exoDate": null,
    "qrData": "https://developer.example.com/payment/?qr=da58fde344a1e0c9280207e1143c6f40",
    "status": "processing",
    "traceNumber": "DEMOQR50269d422b61",
    "bankCode": "978485",
    "responseCode": "00",
    "requestId": "P2S-1780908087998-3hlh5c4og",
    "vcbResponse": {
      "code": "00",
      "nodeIn": "0.0.0.0",
      "message": "Succeed",
      "nodeOut": "10.1.60.185",
      "subCode": "00",
      "checksum": "8DB582799A700B17FA56C2558CC8CCB1",
      "operation": "InitInvoice",
      "ccPayLoad": "https://developer.example.com/payment/?qr=da58fde344a1e0c9280207e1143c6f40",
      "requestId": "P2S-1780908087999-3hlh5c4og",
      "paymentRef": "DEMOQR50269d422b61",
      "serverTime": "15:42:07 09/06/2026",
      "subMessage": "Succeed",
      "paymentName": "CUA HANG DEMO"
    },
    "auditData": {
      "channel": "P2S",
      "channelId": "0.0.0.0",
      "channelTime": "2825600815142",
      "channelUser": "adi-payment",
      "channelUserBranch": "01"
    },
    "createdAt": "2026-10-10T19:19:34.931Z"
  }
}
Tìm trong 57 trang tài liệu · Esc để đóng