Danh sách OneQR - Xem QR đã tạo

Nội dung Markdown đầy đủ của trang tài liệu.

# 📋 Danh sách OneQR - Xem QR đã tạo

## 📱 Tổng quan

Để lấy danh sách các mã QR đã tạo, bạn gọi API **List QR Code** của OneQR. API này hỗ trợ phân trang để xem các QR được tạo trong quá khứ.

---

## 🔌 Endpoint

```
GET http://api.pay2s.vn/api/{bank_code}/v1/qr/list
```

| Tham số | Ví dụ | Mô tả |
|--------|-------|-------|
| `{bank_code}` | `vcb` | Mã ngân hàng (vcb = Vietcombank, acb = ACB Bank, ...) |

---

## 📤 Request

### Headers

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

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

### Query Parameters

| Tham số | Loại | Bắt buộc | Mô tả |
|--------|------|---------|-------|
| `limit` | Number | - | Số lượng bản ghi trả về (default: 20, max: 100) |
| `offset` | Number | - | Vị trí bắt đầu (dùng cho phân trang, default: 0) |

### ✅ Ví dụ Request (cURL)

```bash
curl --location 'http://api.pay2s.vn/api/vcb/v1/qr/list?limit=20&offset=0' \
  --header 'Authorization: Bearer YOUR_BEARER_TOKEN'
```

---

## 📥 Response

### ✅ Thành công (200 OK)

```json
{
  "success": true,
  "message": "QR list retrieved successfully",
  "data": [
    {
      "transactionId": "da58fde344a1e0c9280207e1143c6f40",
      "merchantId": "DEMO_MERCHANT",
      "terminalId": "DEMO_TERMINAL",
      "orderId": "DEMO17916599748852455",
      "amount": 100000,
      "status": "processing",
      "createdAt": "2026-10-10T19:19:34.931Z"
    }
  ],
  "total": 8,
  "limit": 20,
  "offset": 0
}
```

### Giải thích Response

| Trường | Mô tả |
|--------|-------|
| `success` | Trạng thái: `true` = Lấy danh sách thành công |
| `message` | Mô tả: `QR list retrieved successfully` |
| `data` | Mảng danh sách QR codes |
| `transactionId` | Mã giao dịch duy nhất |
| `orderId` | ID đơn hàng |
| `amount` | Số tiền (VND) |
| `status` | Trạng thái: `processing`, `cancelled`, `completed` |
| `traceNumber` | Mã định danh QR |
| `createdAt` | Thời gian tạo QR |


---

## 💻 Code mẫu - Lấy danh sách QR

::: code-group

```php [PHP]
<?php
$bearerToken = "YOUR_BEARER_TOKEN";
$limit = 20;
$offset = 0;
$url = "http://api.pay2s.vn/api/vcb/v1/qr/list?limit=" . $limit . "&offset=" . $offset;

$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) {
    $qrList = $result['data'];
    echo "Found " . count($qrList) . " QR codes\n";
    
    foreach ($qrList as $qr) {
        echo "Order: " . $qr['orderId'] . 
             " | Amount: " . $qr['amount'] . 
             " | Status: " . $qr['status'] . "\n";
    }
    
    $pagination = $result['pagination'];
    echo "Total: " . $pagination['total'] . " QR codes\n";
} else {
    echo "Error: " . $result['message'];
}

curl_close($ch);
?>
```

```javascript [Node.js]
const axios = require('axios');

const bearerToken = "YOUR_BEARER_TOKEN";
const limit = 20;
const offset = 0;

const url = `http://api.pay2s.vn/api/vcb/v1/qr/list?limit=${limit}&offset=${offset}`;

axios.get(url, {
  headers: {
    "Authorization": `Bearer ${bearerToken}`
  }
})
  .then(response => {
    if (response.data.success === true) {
      const qrList = response.data.data;
      console.log(`Found ${qrList.length} QR codes`);
      
      qrList.forEach(qr => {
        console.log(`Order: ${qr.orderId} | Amount: ${qr.amount} | Status: ${qr.status}`);
      });
      
      const pagination = response.data.pagination;
      console.log(`Total: ${pagination.total} QR codes`);
    } else {
      console.error("Error:", response.data.message);
    }
  })
  .catch(err => console.error(err));
```

```python [Python]
import requests

bearer_token = "YOUR_BEARER_TOKEN"
limit = 20
offset = 0

url = f"http://api.pay2s.vn/api/vcb/v1/qr/list?limit={limit}&offset={offset}"

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

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

if result['success'] == True:
    qr_list = result['data']
    print(f"Found {len(qr_list)} QR codes")
    
    for qr in qr_list:
        print(f"Order: {qr['orderId']} | Amount: {qr['amount']} | Status: {qr['status']}")
    
    pagination = result['pagination']
    print(f"Total: {pagination['total']} QR codes")
else:
    print("Error:", result['message'])
```

```java [Java]
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ListQRClient {
    
    public static void main(String[] args) throws Exception {
        String bearerToken = "YOUR_BEARER_TOKEN";
        int limit = 20;
        int offset = 0;
        
        String url = "http://api.pay2s.vn/api/vcb/v1/qr/list?limit=" + limit + "&offset=" + offset;
        
        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 JSON response
            System.out.println("Response: " + response.toString());
        }
    }
}
```

:::

---

## ⚡ Best Practices

1. **Pagination**: Sử dụng `limit` và `offset` để lấy dữ liệu từng trang
2. **Limit cách hợp lý**: Không nên lấy quá nhiều bản ghi (max: 100)
3. **Cache kết quả**: Lưu danh sách QR vào cache để tránh request quá nhiều
4. **Filter by status**: Lọc QR theo status (`processing`, `cancelled`, `paid`)
5. **Sort by date**: Sắp xếp theo `createdAt` để xem QR mới nhất trước
6. **Track total**: Lưu `total` từ pagination để biết có bao nhiêu QR
7. **Error handling**: Kiểm tra `success` trước xử lý `data`
8. **Timeout**: Đặt timeout hợp lý (30-60 giây)
9. **Retry logic**: Nếu request fail, retry sau 2-3 giây
10. **Logging**: Log danh sách QR được lấy để audit

---

## 📌 Phân trang - Pagination

Để lấy dữ liệu theo trang, sử dụng `limit` và `offset`:

```javascript
// Trang 1: offset = 0, limit = 20
const page1 = `/qr/list?limit=20&offset=0`;

// Trang 2: offset = 20, limit = 20
const page2 = `/qr/list?limit=20&offset=20`;

// Trang 3: offset = 40, limit = 20
const page3 = `/qr/list?limit=20&offset=40`;
```

**Công thức**: `offset = (page - 1) * limit`

---

## 🔍 Filter QR theo Status

```bash
# Lấy danh sách QR đang xử lý
curl 'http://api.pay2s.vn/api/vcb/v1/qr/list?limit=20&offset=0' \
  -H 'Authorization: Bearer TOKEN'

# Sau đó filter trong code:
# status = 'processing' (chờ thanh toán)
# status = 'paid' (đã thanh toán)
# status = 'cancelled' (đã hủy)
```

---

> **Tiếp theo**: Xem [Tạo OneQR](/oneqr/khoi-tao-oneqr) để tạo QR mới hoặc [Hủy OneQR](/oneqr/huy-oneqr) để hủy QR hoặc [Kiểm tra OneQR](/oneqr/kiem-tra-oneqr) để xem chi tiết


## 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 · Danh sách

<div class="doc-api-actions" data-doc-api-actions><a class="try-button" data-doc-playground href="/playground/?api=oneqr-list">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.

`GET /api/{bank_code}/v1/qr/list`

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

```json
{
  "bank_code": "vcb"
}
```

HTTP 200. Response:

```json
{
  "success": true,
  "message": "QR list retrieved successfully",
  "data": [
    {
      "transactionId": "da58fde344a1e0c9280207e1143c6f40",
      "merchantId": "DEMO_MERCHANT",
      "terminalId": "DEMO_TERMINAL",
      "orderId": "DEMO17916599748852455",
      "amount": 100000,
      "status": "processing",
      "createdAt": "2026-10-10T19:19:34.931Z"
    }
  ],
  "total": 8,
  "limit": 20,
  "offset": 0
}
```