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
}
```