# Tổng quan

VietQR và Open API Banking VietQR cung cấp giải pháp kết nối một lần cho tất cả các ngân hàng, giúp doanh nghiệp quản lý thanh toán dễ dàng và hiệu quả.

Chúng tôi cung cấp đủ các API và Bộ công cụ  phần mềm để thúc đẩy Doanh nghiệp của bạn số hoá kinh doanh :thumbsup:

### API Kết nối đối soát thanh toán với ngân hàng

Dịch vụ VietQR là giải pháp mở, giúp kết nối linh hoạt giữa hệ thống ngân hàng và doanh nghiệp. Với giải pháp này, các doanh nghiệp có thể cho phép khách hàng sử dụng tài khoản ngân hàng hoặc ví điện tử để thanh toán cho các dịch vụ trên nhiều nền tảng như website, ứng dụng di động, thiết bị bán hàng (POS), thanh toán hóa đơn, Web In App VietQR, cũng như các thiết bị bán hàng tự động và hệ thống IOT.

### API Xuất hoá đơn tự động

Bộ API chuẩn giúp bạn xuất hoá đơn tự động cho các giao dịch thanh toán.

### API tạo Tem số mã vạch

Tạo ra Mã số định danh để Kiểm tra xác thực truy suất nguồn gốc sản phẩm, công cụ báo cáo quản trị và tra cứu nguồn gốc.

### Mô tả

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FgdIdfju9XbdgWBlWgBkf%2FProcess%20Map%20Payment%20APIs.png?alt=media&amp;token=77ef763a-aa3a-49f8-83ad-349489fcebb2" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Đối tác cần hoàn tất quá trình đăng ký tài khoản với đầy đủ thông tin nhằm định danh và bảo mật tài khoản. Thông tin tích hợp mặc định sẽ là môi trường Test (Sandbox).
{% endhint %}

**Các bước cơ bản để tích hợp với VietQR:**

## **Chuẩn bị : Mở tài khoản và khởi tại môi trường test**

1 - Mở Tài khoản VietQR và Liên kết TK ngân hàng với ứng dụng VietQR

2 - [Khai báo thông tin kết nối ở trang VietQR.vn](https://vietqr.vn/merchant/request).

## Kết nối dịch vụ trên môi trường test

1. Đối tác triển khai API Get Token ở phía đối tác.
2. Đối tác triển khai API Transaction Sync ở phía đối tác.&#x20;
3. Truyền `username` và `password` được cấp bởi VietQR sau khi khai báo ở bước 4 vào [API Get Token](/vi/api-vietqr-callback/goi-api-get-token).
4. Sử dụng Token ở bước 5 để gọi [API Generate VietQR Code](/vi/api-vietqr-callback/goi-api-generate-vietqr-code) để tạo mã thanh toán.
5. Gọi [API Test Callback](/vi/api-vietqr-callback/goi-api-test-callback) để giả lập thanh toán thành công cho giao dịch vừa tạo ở bước 6.
6. Nghiệm thu và yêu cầu GoLive trên môi trường sản xuất.

## Ký hợp đồng và Golive dịch vụ với Tài khoản thực

Liên hệ với cán bộ kinh doanh hoặc kỹ thuật của chúng tôi để được hỗ trợ và hoàn thiện các thủ tục pháp lý để có thể đưa dịch vụ vào&#x20;

***

### Tích hợp dịch vụ APIs của chúng tôi

<details>

<summary><strong>VietQR Payment APIs</strong></summary>

* Chúng tôi cung cấp một công cụ đơn giản để doanh nghiệp dễ dàng tích hợp dịch vụ thanh toán bằng mã QR vào hệ thống của mình. Với bộ APIs này, bạn có thể tạo mã thanh toán, xử lý các giao dịch, và kiểm tra xem thanh toán đã hoàn tất chưa.
* VietQR Payment API được thiết kế thân thiện, an toàn, và dễ sử dụng, phù hợp cho mọi loại hình doanh nghiệp, dù lớn hay nhỏ.

</details>

<details>

<summary>VietQR Refund API</summary>

* Gói dịch vụ này là một phần bổ sung cho hệ thống thanh toán mã QR hiện có. VietQR Refund API giúp doanh nghiệp dễ dàng xử lý các giao dịch hoàn tiền một cách nhanh chóng và hiệu quả. Khi cần hoàn tiền cho khách hàng, bạn chỉ cần sử dụng API này để thực hiện nhanh chóng và chính xác.
* API này giúp đơn giản hóa quy trình hoàn tiền, giảm thiểu sai sót và nâng cao trải nghiệm khách hàng.

</details>

<details>

<summary>VietQR Payment MQTTs</summary>

Cung cấp một giải pháp thanh toán qua mã QR, sử dụng giao thức truyền thông **MQTTs (Message Queuing Telemetry Transport Secure)** để đảm bảo tính bảo mật và hiệu quả trong việc truyền tải thông tin giao dịch. Đây là một gói dịch vụ hướng đến các doanh nghiệp và tổ chức có nhu cầu tích hợp thanh toán qua mã QR và nhận thông báo biến động số dư theo thời gian thực một cách an toàn.

</details>

<details>

<summary>WordPress Plugin</summary>

Chúng tôi cung cấp Plugin WordPress - VietQR, giúp khách hàng dễ dàng sử dụng dịch vụ thanh toán qua mã QR và đối soát tự động qua mã VietQR chỉ bằng cách cài đặt Plugin và sử dụng ứng dụng App VietQR [(hướng dẫn cài app tại đây)](https://youtu.be/8tFoBjtSFXQ?si=mVzmWmluqgCfbC2F). Sau khi tích hợp Plugin VietQR vào hệ thống WordPress, bạn có thể:

• Tạo mã QR thanh toán cho các sản phẩm trên website của mình.

• Nhận thông báo biến động số dư (BĐSD) và xác nhận giao dịch ngay khi phát sinh, với đầy đủ thông tin chi tiết.

• Hỗ trợ tạo mã QR thanh toán cho tất cả tài khoản ngân hàng đã đăng ký trên ứng dụng VietQR hoặc website VietQR.vn.

• Tự động đối soát và khớp lệnh đơn hàng với ngân hàng MB và BIDV.

• Cung cấp báo cáo doanh số và phân tích giao dịch thông qua hệ thống quản lý thanh toán trên web VietQR.vn hoặc ứng dụng VietQR.

• Chia Sẻ biến động số dư và thông tin khách đặt hàng qua group chat mạng xã hội như Lark, Telegram, Google Chat, Google Sheet, Slark.

</details>

<details>

<summary>VietQR Host to Client</summary>

* Llà công cụ hoàn hảo giúp doanh nghiệp dễ dàng tích hợp các tính năng của VietQR API vào trình duyệt của mình mà không cần viết mã code. Với tiện ích mở rộng này, bạn có thể nhanh chóng tạo mã thanh toán, xử lý giao dịch và quản lý hoàn tiền ngay trên trình duyệt Chrome.
* Thiết kế của tiện ích mở rộng giúp đơn giản hóa quy trình, giảm thiểu sai sót, và nâng cao trải nghiệm người dùng. Đây là giải pháp lý tưởng cho doanh nghiệp muốn sử dụng dịch vụ VietQR một cách nhanh chóng và hiệu quả.

</details>

<details>

<summary>VietQR Host to Host (<em>Đang cập nhật</em>)</summary>

</details>

***

### Các nền tảng của chúng tôi

{% tabs %}
{% tab title="Mobile IOS" %}

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2F2wwW539P3lZ62r327N2i%2F1%5B1%5D.png?alt=media&amp;token=abcc0ccf-ce13-43d2-83d1-a7e72c012b1f" alt="" width="563"><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Mobile Android" %}

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FJ8KYoyRwzt8jN84lW1m3%2F2%5B1%5D.png?alt=media&amp;token=7e6ac5ab-9ec1-4e15-b0b0-72b90db65471" alt="" width="563"><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Website" %}

* Trang chủ: [https://vietqr.com](https://vietqr.com/)
* Trang người dùng: [https://vietqr.vn](https://vietqr.vn/)
* Bạn còn thấy VietQR ở đâu :thumbsup:
  * kiot.vietqr.vn
  * pro.vietqr.vn
  * Vietqrpro.vn
  * Vietqrplus.vn
  * Vietqr.org
  * Myvietqr.vn
  * App : VietQR Kiot
    {% endtab %}
    {% endtabs %}

***

### Các khóa bảo mật

* Access Key: Cấp quyền truy cập để gọi API Get Token.
* Basic Authen: Chuỗi mã hóa do VietQr cung cấp cho đối tác.
* Check Sum: Chuỗi mã hóa MD5 để truy cập một số API.
* Secret Key: Dùng để tạo chữ ký điện tử.

***

### Security

Secret key à một chuỗi ký tự được tạo ra bằng một thuật toán nhất định, dùng để xác thực tính chính xác của dữ liệu trong quá trình truyền tải giữa hai hệ thống. Một số thuật toán đang được sử dụng bao gồm MD5, SHA1, SHA256 và Hmac.

***


# Giới thiệu chung

Giới thiệu chung về QR và mã VietQR, phần mềm VietQR và gói dịch vụ

### Giới thiệu về VietQR

VietQR là giải pháp thanh toán nhanh chóng và an toàn qua mã QR, giúp doanh nghiệp tối ưu hóa quy trình giao dịch, giảm thiểu chi phí vận hành và tăng trải nghiệm khách hàng. Với VietQR, bạn có thể dễ dàng quản lý dòng tiền, nhận thông báo thay đổi số dư, và hỗ trợ khách hàng với tính năng hoàn tiền (refund) linh hoạt ở gói dịch vụ Pro.

### **So sánh gói dịch vụ VietQR Pro và VietQR Plus**

<table data-header-hidden><thead><tr><th valign="top"></th><th></th><th></th></tr></thead><tbody><tr><td valign="top"><strong>Đặc điểm</strong></td><td><strong>VietQR Pro</strong></td><td><strong>VietQR Plus</strong></td></tr><tr><td valign="top">Phí dịch vụ</td><td>0,8% giá trị giao dịch + VAT</td><td>1.600 VNĐ/giao dịch + VAT</td></tr><tr><td valign="top">Giới hạn giá trị tối thiểu</td><td>Không có giới hạn</td><td>Không có giới hạn</td></tr><tr><td valign="top">Phù hợp cho</td><td>Thiết bị điều khiển tự động, đại lý hoặc khách hàng có nhiều giao dịch và đòi hỏi nghiệp vụ có chất lượng dịch vụ cao</td><td>Thương mại điện tử, giao dịch có giá trị lớn</td></tr><tr><td valign="top">Tính năng hoàn tiền (refund)</td><td>Có</td><td>Không</td></tr><tr><td valign="top">Phương thức kết nối</td><td>Chung chuẩn kỹ thuật với Plus</td><td>Chung chuẩn kỹ thuật với Pro</td></tr></tbody></table>

### Cách nhận biết bạn nên chọn sử dụng gói Pro hay Plus

• VietQR Pro: Có thêm tính năng hoàn tiền (refund) . Cước phí tính theo % giá trị giao dịch.

• VietQR Plus: Không có tính năng hoàn tiền, phí được tính theo hình thức 1.600 VNĐ/giao dịch + VAT.

### Cách lựa chọn gói dịch vụ :

• Với thiết bị điều khiển tự động, VietQR khuyến nghị sử dụng gói Pro vì có lợi cho cả đại lý và khách hàng với phí theo tỷ lệ giao dịch và không giới hạn giá trị tối thiểu.

• Gói Plus phù hợp với các doanh nghiệp thương mại điện tử, nơi giao dịch có giá trị lớn.

### Chuyển đổi giữa gói dịch vụ dễ dàng

Cả VietQR Pro và Plus đều sử dụng chung chuẩn kỹ thuật kết nối. Khi khách hàng chuyển đổi giữa hai gói, hệ thống VietQR sẽ tự động thiết lập cơ chế thu phí phù hợp, khách hàng và đối tác không cần thực hiện thêm thao tác nào.


# Liên kết với VietQR

Bước đầu tiên trong quá trình tích hợp dịch vụ VietQR Payment MQTTs

{% hint style="success" %}
Quý khách có thể tham khảo video demo [tại đây](https://doc.vietqr.vn/vietqr-doc#lien-ket-va-quan-ly-tai-khoan).
{% endhint %}

### Đăng ký tài khoản VietQR

{% hint style="info" %}
Nếu quý khách đã có tài khoản VietQR, hẫy đến bước tiếp theo.
{% endhint %}

1. Truy cập trang web [`VietQR.vn`](https://vietqr.vn/register) của chúng tôi để đăng ký tài khoản.
2. Nhập số điện thoại và mật khẩu để tạo một tài khoản mới.
3. Sau khi đăng ký, bạn cần liên kết tài khoản ngân hàng để có thể nhận tiền từ các giao dịch thanh toán qua mã QR.
4. Đăng nhập vào VietQR, nhấn vào nút thêm tài khoản ngân hàng.
5. Chọn ngân hàng MB hoặc BIDV.
6. Nhập các thông tin cần thiết và xác thực để liên kết.

{% hint style="success" %}

* Nếu quý khách chưa có tài khoản tại ngân hàng MB hoặc BIDV, hãy đăng ký ngay  [tại đây](https://omni.bidv.com.vn/static/bidv/share/gioi-thieu-ban-thuong-vo-han.html?data=aH0RHc6MyLk9Cbi5Wa2R2ch1nciRWYr5Wan5nLuZ2LiVlTBRGTS1VbuVVeYZEZo4) để mở tài khoản mới và nhận nhiều ưu đãi hấp dẫn.
* Trong thời gian chờ tài khoản chính thức được kích hoạt, chúng tôi sẽ cung cấp tài khoản ngân hàng thử nghiệm để quý khách có thể tích hợp và trải nghiệm dịch vụ trước.
  {% endhint %}

***

<details>

<summary>Tôi cần làm gì để đăng ký tài khoản VietQR?</summary>

Bạn cần truy cập trang web VietQR.vn, nhập số điện thoại và mật khẩu để tạo tài khoản mới. Sau khi đăng ký thành công, bạn có thể bắt đầu sử dụng các dịch vụ của VietQR.

</details>

<details>

<summary>Tại sao tôi phải liên kết tài khoản ngân hàng với VietQR?</summary>

Việc liên kết tài khoản ngân hàng cho phép bạn nhận tiền từ các giao dịch thanh toán qua mã QR. Tài khoản liên kết sẽ là nơi nhận tiền khi khách hàng thanh toán thông qua mã QR do VietQR cung cấp.

</details>

<details>

<summary>Hiện tại VietQR hỗ trợ liên kết với những ngân hàng nào?</summary>

Hiện tại, VietQR hỗ trợ liên kết với tài khoản ngân hàng tại MB và BIDV. Các ngân hàng khác đang được triển khai và sẽ sớm được hỗ trợ trong thời gian tới.

</details>

<details>

<summary>Tôi chưa có tài khoản tại ngân hàng MB hoặc BIDV, tôi phải làm gì?</summary>

Nếu bạn chưa có tài khoản tại MB hoặc BIDV, bạn có thể đăng ký mở tài khoản mới tại ngân hàng thông qua liên kết trên trang VietQR. Sau khi mở tài khoản, bạn có thể quay lại VietQR để liên kết tài khoản ngân hàng này.

</details>

<details>

<summary>Tôi có thể sử dụng tài khoản ngân hàng thử nghiệm để làm gì?</summary>

Trong thời gian chờ tài khoản chính thức được kích hoạt, VietQR sẽ cung cấp tài khoản ngân hàng thử nghiệm để bạn có thể tích hợp và trải nghiệm các dịch vụ của VietQR trước khi sử dụng tài khoản chính thức.

</details>

<details>

<summary>Liên kết tài khoản ngân hàng có mất phí không?</summary>

Hiện tại, việc liên kết tài khoản ngân hàng với VietQR không mất phí. Ngoài ra, sau khi hoàn thành bước xác thực email, bạn sẽ được tặng key 1 tháng kích hoạt nhận biến động số dư. (\*áp dụng trong khung chương trình khi còn hiệu lực)

</details>


# Mô tả luồng nghiệp API

Mô tả luồng Nghiệp vụ kết nối API VietQR Callback

## Mô tả luồng nghiệp API VietQR

### 1. Các bước để tạo mã thanh toán VietQR:

#### • Bước 1: Lấy Token truy cập

Khách hàng (KH) cần gọi API Get Token của VietQR để thực hiện truy cập và xác thực. Sau khi xác thực thành công, VietQR sẽ trả về một token, đóng vai trò như chìa khóa để truy cập API tạo mã VietQR.

🔗 [Tham khảo API Get Token](https://api.vietqr.vn/vi/api-vietqr/goi-api-get-token)

#### • Bước 2: Tạo mã thanh toán VietQR

Sau khi nhận được token, KH sử dụng token này để gọi API tạo mã thanh toán VietQR.

🔗 [Tham khảo API tạo mã VietQR](https://api.vietqr.vn/vi/api-vietqr/goi-api-generate-vietqr-code)

#### • Bước 3: Giả lập thanh toán trong môi trường Test/Staging/Sandbox

Trong môi trường thử nghiệm, KH không cần quét mã để thanh toán thực tế. Thay vào đó, KH có thể gọi API Test Callback để giả lập giao dịch thanh toán thành công.

🔗 [Tham khảo API Test Callback](https://api.vietqr.vn/vi/api-vietqr/goi-api-test-callback)

📌 Lưu ý: Sau khi hoàn tất thanh toán, KH cần một nơi để nhận thông báo biến động số dư (BĐSD). Do đó, cần thiết lập một hệ thống tiếp nhận thông tin thanh toán.

### 2. Thiết lập nơi tiếp nhận thông tin thanh toán/BĐSD

#### • Bước 1: Cung cấp API Get Token

KH cần triển khai API Get Token của riêng mình để xác thực và cung cấp token cho VietQR. Token này cho phép VietQR truy cập vào hệ thống của KH để gửi dữ liệu thanh toán/BĐSD.

🔗 [Tham khảo API Get Token](https://api.vietqr.vn/vi/api-vietqr/trien-khai-api-get-token)

#### • Bước 2: Tạo API tiếp nhận dữ liệu giao dịch

KH cần triển khai API Transaction Sync để làm nơi tiếp nhận dữ liệu thanh toán/BĐSD từ VietQR.

🔗 [Tham khảo API Transaction Sync](https://api.vietqr.vn/vi/api-vietqr/trien-khai-api-transaction-sync)

## 📌 Tóm lại:

Quy trình bao gồm việc tạo mã thanh toán VietQR, giả lập thanh toán (trong môi trường test), và xây dựng hệ thống tiếp nhận dữ liệu thanh toán/BĐSD để đảm bảo thông tin giao dịch được ghi nhận đầy đủ.

Quét Mã QR để join vào nhóm Zalo hỗ trợ mở để đươc hỗ trợ :&#x20;

{% embed url="<https://zalo.me/g/tachpp720>" %}
Link vào nhóm mở zalo&#x20;
{% endembed %}

{% tabs %}
{% tab title="Mã QR vào nhóm Chat" %}

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FtHtUUSHeEmDUP2tczUlN%2Fimage.png?alt=media&amp;token=23e4e0e4-3036-4d48-a616-5287c756bdb1" alt=""><figcaption><p>Nhóm chat Zalo của VIetQR suport khách</p></figcaption></figure>
{% endtab %}

{% tab title="Second Tab" %}

{% endtab %}
{% endtabs %}


# Khai báo merchant connection

Bạn cần khai báo các thông tin cần thiết để kết nối merchant của mình với VietQR.

Khai báo thông tin kết nối

Đăng nhập đường link để khai báo kết nối tại đây : <https://vietqr.vn/merchant/request>

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2F7ixtn58jg4RN6B3fsTgc%2Fimage.png?alt=media&amp;token=d6e44db5-a214-4dcf-a28c-b7ba0f194398" alt=""><figcaption></figcaption></figure>

hoặc gửi thông tin yêu cầu khởi tạo môi trường test về địa chỉ email : <Sales@vietqr.vn> với các thông tin như sau :thumbsup:

ác thông tin cần thiết để thiết lập kết nối API nhằm tạo môi trường test cho hệ thống. Vui lòng điền đầy đủ các tham số sau:

```
1.	Địa chỉ kết nối (URL/IP + PORT):
•	URL: [Vui lòng điền URL kết nối]
•	IP + PORT: [Nếu không sử dụng URL, vui lòng cung cấp địa chỉ IP và PORT]
2.	URL Path:
```

\[Vui lòng nhập đường dẫn cụ thể của API] 3. Địa chỉ KH (mã khách hàng, không dấu): \[Cung cấp địa chỉ khách hàng/mã KH để tránh trùng lặp] 4. Ngân hàng thụ hưởng: \[Vui lòng chọn ngân hàng từ danh sách hoặc nhập tên ngân hàng thụ hưởng] 5. Thông tin tài khoản MB Bank (nếu có): • Số tài khoản: \[Vui lòng nhập số tài khoản MB Bank] • Tên chủ tài khoản: \[Vui lòng nhập tên chủ tài khoản không dấu] 6. Basic Authentication: • Username: \[Vui lòng nhập tên đăng nhập] • Password: \[Vui lòng nhập mật khẩu] MB 3888831389 Truong Hiep HungMB 3888831389 Truong Hiep Hung

Sau khi điền đầy đủ thông tin, vui lòng gửi lại để chúng tôi có thể tiến hành tạo môi trường test và kiểm tra kết nối.

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FR5SMTIko8S8cdQrY2V80%2Fimage.png?alt=media&amp;token=e7de8941-f30c-4b7b-b3ff-d32cf9ee3a37" alt=""><figcaption></figcaption></figure>

1. Truy cập trang khai báo kết nối [tại đây](https://vietqr.vn/merchant/request).
2. Nhập các thông tin cần khai báo.
3. Nhấn nút `Test Get Token` kiểm tra việc lấy token để đảm bảo kết nối hoạt động đúng cách.
4. Sau khi khai báo hoàn tất, hãy liên hệ đến bộ phận kỹ thuật của chúng tôi.

{% hint style="warning" %}
Lưu ý:&#x20;

* URL hoặc IP + Port cần khai báo là của phía quý khách.
* Hiện chúng tôi đang hỗ trợ liên kết tài khoản ngân hàng MB và BIDV. Danh sách các ngân hàng khác đang được triển khai trong thời gian sắp tới.
  {% endhint %}

***

### Thông báo bộ phận kỹ thuật của VietQR

1. Hãy đảm bảo rằng đội kỹ thuật của chúng tôi đã nhận được thông tin kết nối và hướng dẫn cần thiết để bắt đầu tích hợp. (Khi liên hệ với chúng tôi, hãy gửi lại `Merchant Name` (tên đại lý) đã khai báo).
2. Sau khi tiếp nhận thông tin, chúng tôi sẽ kiểm tra và duyệt kết nối.

{% hint style="success" %}
Sau khi hoàn thành bước này, VietQR sẽ cung cấp lại cho quý khách `username` và `password` để truy cập đến các API của VietQR trên môi trường Test.
{% endhint %}

***

### Các câu hỏi thường gặp

<details>

<summary>Tôi cần khai báo những thông tin gì để kết nối merchant với VietQR?</summary>

Bạn cần khai báo URL hoặc IP + Port mà hệ thống của bạn sẽ sử dụng để kết nối với dịch vụ VietQR. Đảm bảo rằng các thông tin này chính xác và đã được kiểm tra kỹ lưỡng.

</details>

<details>

<summary>Tôi có thể thay đổi thông tin khai báo sau khi đã hoàn tất không?</summary>

Có, bạn có thể thay đổi thông tin khai báo. Tuy nhiên, sau khi thay đổi, bạn cần phải thực hiện lại bước kiểm tra bằng cách nhấn "Test Get Token" để đảm bảo rằng kết nối vẫn hoạt động chính xác.

</details>

<details>

<summary>Nếu tôi gặp lỗi khi thực hiện bước "Test Get Token", tôi nên làm gì?</summary>

Nếu bạn gặp lỗi khi thực hiện "Test Get Token", hãy kiểm tra lại các thông tin khai báo như URL, IP, và Port. Đảm bảo rằng hệ thống của bạn có thể giao tiếp với VietQR. Nếu vấn đề vẫn tiếp diễn, hãy liên hệ với bộ phận kỹ thuật của VietQR để được hỗ trợ.

</details>

<details>

<summary>Tại sao việc Test Get Token lại quan trọng?</summary>

Bước này giúp xác nhận rằng hệ thống của bạn có thể lấy token thành công từ API của VietQR, đồng thời đảm bảo rằng kết nối hoạt động đúng cách trước khi tiến hành các bước tích hợp tiếp theo.

</details>

<details>

<summary>Tôi có thể sử dụng bất kỳ URL hoặc IP + Port nào để khai báo không?</summary>

Không, bạn cần sử dụng URL hoặc IP + Port mà hệ thống của bạn sẽ thực sự sử dụng để kết nối với VietQR. Các thông tin này phải chính xác và phù hợp với môi trường của bạn.

</details>

<details>

<summary>VietQR hỗ trợ những ngân hàng nào cho việc liên kết tài khoản?</summary>

Hiện tại, VietQR hỗ trợ liên kết tài khoản với ngân hàng MB và BIDV. Các ngân hàng khác sẽ được hỗ trợ trong thời gian tới.

</details>

<details>

<summary>Tại sao tôi cần liên hệ với bộ phận kỹ thuật của VietQR sau khi khai báo?</summary>

Liên hệ với bộ phận kỹ thuật của VietQR giúp đảm bảo rằng họ đã nhận được thông tin kết nối của bạn và có thể tiến hành kiểm tra, duyệt kết nối. Đây là bước quan trọng để tiến hành tích hợp dịch vụ.

</details>

<details>

<summary>Khi nào tôi sẽ nhận được username và password để truy cập API của VietQR?</summary>

Sau khi bộ phận kỹ thuật của VietQR kiểm tra và duyệt kết nối của bạn, họ sẽ cung cấp lại username và password để bạn có thể truy cập các API của VietQR trên môi trường Test.

</details>


# Các loại QR thanh toán

Đây là các nội dung thêm vào giúp bạn có cái nhìn rõ hơn về sản phẩm hoặc dịch vụ, bao gồm các ví dụ cụ thể hoặc trường hợp sử dụng.

### Các loại mã VietQR

<table><thead><tr><th width="100.58984375">Loại mã</th><th width="113.453125">Mã QR tĩnh</th><th width="191.015625">Mã QR động</th><th width="452">Mã QR bán động</th></tr></thead><tbody><tr><td>Đặc điểm</td><td>Mã QR tĩnh chứa thông tin cố định của 01 tài khoản thanh toán (tên ngân hàng, số tài khoản, và tên chủ tài khoản).</td><td>Mã QR động được tạo theo từng đơn hàng, chứa sẵn thông tin thanh toán của đơn hàng tương ứng (thông tin tài khoản nhận tiền, số tiền, nội dung chuyển khoản).</td><td>Mã QR bán động chứa các thông tin như mã QR tĩnh, tuy nhiên người bán có thể điền trước số tiền cần thanh toán và nội dung chuyển khoản.</td></tr><tr><td>Phạm vi sử dụng</td><td>Áp dụng cho tất cả các giao dịch nhận thanh toán qua mã QR.</td><td>Áp dụng cho 01 giao dịch thanh toán.</td><td>Áp dụng cho các giao dịch có cùng số tiền thanh toán.</td></tr><tr><td>Tính ứng dụng</td><td>Có thể chia sẻ trực tuyến, in và trưng bày để nhận thanh toán mọi lúc mọi nơi.</td><td>Mã QR sẽ hết hiệu lực sau khi nhận thanh toán đơn hàng thành công. Không dùng để in và trưng bày để nhận thanh toán.</td><td>Có thể chia sẻ trực tuyến. Không khuyến khích in và trưng bày để nhận thanh toán vì giới hạn phạm vi sử dụng.</td></tr><tr><td>Cách thực hiện</td><td>Người dùng quét mã QR, điền số tiền thanh toán và nội dung chuyển khoản, sau đó xác thực giao dịch.</td><td>Người dùng quét mã QR và xác thực giao dịch.</td><td>Người dùng quét mã QR và xác thực giao dịch.</td></tr></tbody></table>


# Cần biết về QRcode

Những điều cần biết về Mã QR

## 1. Mã QR là gì?

Mã QR là một loại mã vạch hai chiều với các ô vuông đen trắng cho phép mã hóa hàng trăm ký tự. Các thiết bị như điện thoại thông minh và máy tính bảng ngày nay có thể nhận diện và quét mã QR rất nhanh chóng – đó là lý do mà QR được viết tắt từ “Quick Response” (Phản hồi nhanh).

## 2. Mã QR được sử dụng như thế nào?

Nhờ sự phổ biến của điện thoại thông minh, mã QR thường được dùng trong các chiến dịch tiếp thị di động. Các nhà tiếp thị sử dụng mã QR để kết nối nội dung kỹ thuật số như trang web, video, tài liệu PDF, album ảnh, hoặc thông tin liên hệ vào các phương tiện in ấn như tờ rơi, áp phích, danh mục sản phẩm và danh thiếp.

## 3. Làm thế nào để tạo mã QR?

Bạn có thể tạo mã QR nhanh chóng qua công cụ Tạo mã QR với ba bước đơn giản: Đầu tiên, chọn chức năng cho mã; sau đó nhập nội dung mà bạn muốn hiển thị, tùy chỉnh mã với màu sắc và logo nếu cần. Cuối cùng, tải mã QR xuống và sẵn sàng in.

## 4. Mã QR có thể tùy chỉnh không?

Có. Nhờ khả năng chịu lỗi cao, mã QR có thể được tùy chỉnh mà không ảnh hưởng đến khả năng quét. Bạn có thể thay đổi màu sắc, thêm logo công ty vào giữa mã, và chỉnh sửa thiết kế của các góc mã. Đảm bảo mã hoạt động bằng cách thử quét trên nhiều thiết bị trước khi sử dụng chính thức.

## 5. Sự khác biệt giữa mã QR tĩnh và động là gì?

Mã QR động cho phép bạn chỉnh sửa nội dung và theo dõi dữ liệu ngay cả sau khi in. Mã này sử dụng URL chuyển tiếp để đưa người dùng đến nội dung đích và có thể cung cấp các số liệu thống kê như số lần quét, vị trí, thời gian truy cập. Trong khi đó, mã tĩnh liên kết trực tiếp với nội dung mà không có khả năng theo dõi.

## 6. Làm thế nào để đo lường số lần quét mã QR?

Bạn có thể theo dõi số lần quét mã QR động thông qua một URL chuyển tiếp được kết nối với máy chủ của nhà cung cấp mã. Tất cả dữ liệu thời gian thực sẽ được lưu vào tài khoản của bạn.

## 7. Cần lưu ý gì trước khi in mã QR?

Nên sử dụng tệp có độ phân giải cao như JPG, PNG, EPS, hoặc SVG. Định dạng vectơ như EPS và SVG đặc biệt phù hợp với kích thước in lớn, không bị mất chất lượng. Đừng quên kiểm tra mã bằng cách quét thực tế trước khi phát hành.

## 8. Những yếu tố nào khác cần chú ý khi in mã QR?

Kích thước mã QR nên phù hợp với lượng thông tin được mã hóa; nếu nhiều thông tin thì mã cần kích thước lớn hơn. Kích thước tối thiểu thường là 2 x 2 cm. Tránh đặt mã trên các bề mặt không bằng phẳng để đảm bảo khả năng quét tốt nhất.

## 9. Cách quét mã QR

Bạn chỉ cần điện thoại hoặc máy tính bảng có cài ứng dụng quét mã QR. Sau khi mở ứng dụng, đưa camera hướng vào mã, nội dung sẽ hiển thị trong vài giây. Lựa chọn ứng dụng dựa trên xếp hạng trên cửa hàng ứng dụng để đảm bảo chất lượng.

## 10. Làm sao để sử dụng mã QR hiệu quả?

Hãy suy nghĩ từ góc nhìn của khán giả và tự hỏi liệu bạn có muốn quét mã không. Tạo nội dung giá trị và thu hút, tối ưu trang đích cho thiết bị di động. Dùng lời kêu gọi hành động đơn giản như “Quét mã này để biết thêm” để khuyến khích người xem.

## 11. Lịch sử mã QR

Từ năm 1994, mã QR đã được phát triển bởi Denso Wave (thuộc Toyota) tại Nhật Bản để đánh dấu các linh kiện, hỗ trợ quá trình logistics trong sản xuất ô tô. Hiện nay, mã QR đã phổ biến tại Nhật Bản và nhiều quốc gia khác, được chuẩn hóa quốc tế. Điểm đặc biệt của mã QR là dù 30% bề mặt bị hỏng hoặc bẩn, mã vẫn có thể quét được.

## 12. Khả năng ứng dụng của mã QR

Mã QR có thể mã hóa URL, trang web, video, hình ảnh, mã giảm giá, biểu mẫu, và nhiều loại nội dung khác. Một số nội dung như sự kiện, kết nối WiFi, hoặc thông tin liên hệ không cần internet để sử dụng. Bạn có thể đặt mã QR trên các trang web, tài liệu in ấn, sản phẩm, và nhiều bề mặt phẳng khác.


# API VIETQR CALLBACK

Mô tả quy trình test tích hợp bộ dịch vụ APIs nhận Biến động số dư qua mã VietQR.

## Hướng dẫn Test Kiểm thử&#x20;

Để cấu hình kết nối API với VietQR, anh/chị vui lòng cung cấp giúp em các thông tin sau : • Tên merchant: (Tên cửa hàng/doanh nghiệp muốn hiển thị)&#x20;

<table><thead><tr><th width="363.94921875">Thông tin đối tác cần cung cấp</th><th>Thông tin ietQR cung cấp</th></tr></thead><tbody><tr><td><p>• URL kết nối: (Địa chỉ API để kết nối) </p><p>• URL Path (Suffix): (Đường dẫn mở rộng nếu có) </p><p>Khoá Key kết nối truyền dữ liệu</p><p>• Username: (Tự đặt theo nhu cầu của KH) </p><p>• Password: (Tự đặt theo nhu cầu của KH)</p></td><td><p>1: Username:</p><p>(VietQR cấp username cho đối tác)</p><p>2 Password:</p><p>(VietQR cấp mật khẩu cho đối tác)</p></td></tr><tr><td>Hoặc mở TK VIETQR và ký TK và tự khai báo trong link liên kết </td><td>LINK ZALO TEST - https://zalo.me/g/wbclso803</td></tr><tr><td>Link Thông tin ký hợp đồng :: <a href="https://docs.google.com/forms/d/e/1FAIpQLSfNywc4SAYleFZ-d7faUvUyzXzNlu0ahHsAd_H43AqO-opsZg/viewform">https://docs.google.com/forms/d/e/1FAIpQLSfNywc4SAYleFZ-d7faUvUyzXzNlu0ahHsAd_H43AqO-opsZg/viewform</a></td><td><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FiB5USq13uwGGXKaQZwbt%2Fimage.png?alt=media&amp;token=65f90b80-7c80-42c9-9b24-8ab915f965b6" alt="" data-size="original"></td></tr></tbody></table>

<https://pro.vietqr.vn/merchant-register>

<https://pro.vietqr.vn/api-service/3a4fb799-7cae-47e4-a56d-59d4944313e3>

## Cấu trúc tài liệu và thực hiện gồm 5 phần :

1. Implement Get Token API
2. Execute Transaction Sync API
3. Call Get Token API
4. Generate VietQR Code API
5. Test Callback

### **Hướng dẫn thực hiện từng bước:**

#### Bước 1: Cấu hình và kết nối API

Khách hàng cần thực hiện theo thứ tự sau:

• Bước 1 → Bước 2 → Bước 3 → Bước 4 → Bước 5

• Sau khi hoàn tất các bước trên, bắt đầu test kết nối

**Quy trình cụ thể:**

&#x20;         ✅ Bắt đầu từ Bước 1 (Triển khai API Get Token)

&#x20;         ✅ Sau đó chuyển sang Bước 2 (API Transaction Sync)

&#x20;         ✅ Tiếp tục với Bước 3 (Call API Get Token)

&#x20;         ✅ Sau đó thực hiện Bước 4 (API Generate VietQR Code)

&#x20;         ✅ Cuối cùng là Bước 5 (Gọi API Test Callback)

#### Bước 2: Kiểm tra dữ liệu

• Kiểm tra lại dữ liệu đã cấu hình tại Bước 1 và Bước 2 để đảm bảo tính chính xác.

• Nếu có lỗi, cần chỉnh sửa trước khi tiếp tục các bước tiếp theo.

🔹 Lưu ý: Sau khi hoàn tất các bước trên, khách hàng có thể tiến hành kiểm thử toàn bộ quy trình để đảm bảo hệ thống hoạt động đúng yêu cầu

**Hướng dẫn sau khi hoàn tất GOLIVE kiểm thử**

✅ Sau khi test thành công, khách hàng sẽ được nghiệm thu và triển khai trên môi trường dịch vụ thực của tài khoản ngân hàng.

📌 Liên hệ bộ phận kinh doanh (Khối khách hàng Doanh nghiệp số) để hỗ trợ triển khai:

| Cán bộ KD         | • Mobile:                               | • Email:                                   |
| ----------------- | --------------------------------------- | ------------------------------------------ |
| 📞 Lê Hương       | <p>0968 383 636</p><p>024 6663 3324</p> | <huong.le@vietqr.vn> <huong.le@bluecom.vn> |
| 📞 Đạo            | 0923 006 234                            | <dao.nguyen@bluecom.vn>                    |
| 📞 Tạ Quang Tuấn  | 0966 266 049                            | <tuan.ta@bluecom.vn>                       |
| 📞 Hoàng Văn Hiển | 0565 606 789                            | <hien.hoang@bluecom.vn>                    |
| 📞 Thịnh Nguyễn   | 0936 381 333                            | <thinh@bluecom.vn>                         |
| 📞 Tuấn Phạm      | 0922 333 636                            | <tuan@bluecom.vn>                          |
| 📞 Hotline        | 0939 603 636                            | <sales@vietqr.vn> <sales@bluecom.vn>       |

🔹 Nếu cần thêm hỗ trợ, vui lòng liên hệ với bộ phận kinh doanh theo thông tin trên.

Mô tả chi tiết về tài liệu API

{% tabs %}
{% tab title="API Get Token" %}
Các bước để nhận biến động số dư từ VietQR

(Áp dụng để đối tác đồng bộ biến động số dư do VietQR trả về)

Bước 1: Cấp quyền truy cập API

• Đối tác cần cấp quyền cho VietQR bằng cách thiết lập quyền truy cập vào API Transaction Sync.

• Cấu hình điểm nhận dữ liệu (Webhook) để VietQR có thể gửi thông tin biến động số dư.

Bước 2: Cấu hình đầu hứng (Webhook)

• Đối tác cung cấp URL endpoint để nhận dữ liệu.

• Đảm bảo endpoint hỗ trợ nhận dữ liệu từ VietQR với phương thức POST.

• Kiểm tra bảo mật, xác thực request từ VietQR.

Bước 3: VietQR gửi dữ liệu biến động số dư

• Khi có giao dịch mới, VietQR sẽ gửi thông tin biến động số dư theo thời gian thực đến webhook của đối tác.

• Dữ liệu bao gồm:

• Số tiền thay đổi

• Số dư mới

• Thời gian giao dịch

• Mã giao dịch

• Các thông tin khác tùy theo cấu hình

Bước 4: Xác nhận và xử lý dữ liệu từ VietQR

• Đối tác nhận request từ VietQR và xác thực dữ liệu.

• Lưu trữ hoặc xử lý thông tin theo nhu cầu (cập nhật vào hệ thống, hiển thị trên ứng dụng, v.v.).

• Trả về response 200 OK để xác nhận đã nhận dữ liệu thành công.

Bước 5: Kiểm tra và giám sát

• Định kỳ kiểm tra logs để đảm bảo không có lỗi kết nối.

• Nếu có lỗi (mất kết nối, dữ liệu sai, v.v.), cần kiểm tra lại cấu hình webhook hoặc liên hệ hỗ trợ từ VietQR.

👉 Lưu ý: VietQR có thể yêu cầu xác thực webhook bằng token hoặc chữ ký số để đảm bảo an toàn khi truyền dữ liệu.
{% endtab %}

{% tab title="API Transaction Sync" %}

{% endtab %}
{% endtabs %}

```
// Some code
```

<table data-view="cards"><thead><tr><th></th></tr></thead><tbody><tr><td></td></tr></tbody></table>


# API Get Token

Đối tác cung cấp API cấp quyền truy cập để VietQR có thể kết nối và đồng bộ dữ liệu với API Transaction Sync (đồng bộ biến động số dư). Để cấp quyền, đối tác cần cấu hình và tạo điểm nhận dữ liệu

### <mark style="color:green;">`2.1 POST`</mark> Get Token <a href="#get-token" id="get-token"></a>

```
https://<your-host>/<your-basepath>/api/token_generate
```

**Headers**

<table><thead><tr><th width="249">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td>Basic Authentication: Base64[<code>username:password</code>]</td></tr></tbody></table>

{% hint style="success" %}
`username` và `password` của API này sẽ do bạn định nghĩa và cung cấp cho VietQR.
{% endhint %}

**Body**

<table><thead><tr><th width="201">Name</th><th width="99">Type</th><th width="101">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>access_token</code></td><td>String</td><td>Yes</td><td>Là Bearer Token do đối tác cung cấp cho VietQR sử dụng để xác thực và callback giao dịch vào API Transaction Sync của đối tác</td></tr><tr><td><code>token_type</code></td><td>String</td><td>Yes</td><td>Là dạng token dạng “Bearer”.</td></tr><tr><td><code>expires_in</code></td><td>Integer</td><td>Yes</td><td>Thời gian (giấy/s) hết hạn của token kể từ thời điểm được tạo</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "access_token": "bearer_token",
    "token_type": "Bearer",
    "expires_in": 300
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### 2.2 - Code cài đặt

Test với Posmant :

curl --location --request POST '<https://uat8.thuythu.vn/mrtao/wp-json/tt-vietqr/api/token_generate>' \ --header 'Authorization: Basic dGFpcGhpbTRrOjYxZTU1ZmU0LTBhNjMtNGU4Zi1hZDgyLTBlNjFiYzk4M\mRlNA=='

{% tabs %}
{% tab title="C#" %}

```csharp
namespace YourNamespace.Controllers
{
    [Route("vqr/api")]
    [ApiController]
    public class TokenController : ControllerBase
    {
        private const string VALID_USERNAME = "customer-vietqrtest-user2468";
        private const string VALID_PASSWORD = "Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09"; // Base64 của username:password
        private const string SECRET_KEY = "your-256-bit-secret"; // Bí mật để ký JWT token

        [HttpPost("token_generate")]
        public IActionResult GenerateToken([FromHeader] string Authorization)
        {
            // Kiểm tra Authorization header
            if (string.IsNullOrEmpty(Authorization) || !Authorization.StartsWith("Basic "))
            {
                return BadRequest("Authorization header is missing or invalid");
            }

            // Giải mã Base64
            var base64Credentials = Authorization.Substring("Basic ".Length).Trim();
            var credentials = Encoding.UTF8.GetString(Convert.FromBase64String(base64Credentials));
            var values = credentials.Split(':', 2);

            if (values.Length != 2)
            {
                return BadRequest("Invalid Authorization header format");
            }

            var username = values[0];
            var password = values[1];

            // Kiểm tra username và password
            if (username == VALID_USERNAME && password == VALID_PASSWORD)
            {
                var token = GenerateJwtToken(username);
                return Ok(new
                {
                    access_token = token,
                    token_type = "Bearer",
                    expires_in = 300 // Thời gian hết hạn token
                });
            }
            else
            {
                return Unauthorized("Invalid credentials");
            }
        }

        // Hàm tạo JWT token
        private string GenerateJwtToken(string username)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(SECRET_KEY);

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(ClaimTypes.Name, username)
                }),
                Expires = DateTime.UtcNow.AddMinutes(5), // Token hết hạn sau 5 phút
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature)
            };

            var token = tokenHandler.CreateToken(tokenDescriptor);
            return tokenHandler.WriteToken(token);
        }
    }
}

// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}

{% tab title="Java" %}

```java
@RestController
@RequestMapping("/vqr/api")
public class TokenController {

    private static final String VALID_USERNAME = "customer-vietqrtest-user2468";
    private static final String VALID_PASSWORD = "Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09"; // Đây là chuỗi base64 từ username:password thật của bạn.

    // API để tạo token
    @PostMapping("/token_generate")
    public ResponseEntity<?> generateToken(@RequestHeader("Authorization") String authHeader) {
        // Kiểm tra xem header có Authorization không
        if (authHeader != null && authHeader.startsWith("Basic ")) {
            // Giải mã Base64 từ Authorization header
            String base64Credentials = authHeader.substring("Basic ".length()).trim();
            String credentials = new String(Base64.getDecoder().decode(base64Credentials), StandardCharsets.UTF_8);

            // Phân tách username và password
            final String[] values = credentials.split(":", 2);
            String username = values[0];
            String password = values[1];

            // Kiểm tra tính hợp lệ của username và password
            if (VALID_USERNAME.equals(username) && VALID_PASSWORD.equals(password)) {
                // Nếu hợp lệ, tạo JWT token
                String token = "your-generated-jwt-token"; // Ở đây bạn cần tạo JWT token thực sự, ví dụ với jjwt.

                return ResponseEntity.ok(new TokenResponse(token, "Bearer", 300));
            } else {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
            }
        } else {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Authorization header is missing or invalid");
        }
    }

    // Class cho response
    public static class TokenResponse {
        private String access_token;
        private String token_type;
        private int expires_in;

        public TokenResponse(String access_token, String token_type, int expires_in) {
            this.access_token = access_token;
            this.token_type = token_type;
            this.expires_in = expires_in;
        }

        // Getters và Setters
        public String getAccess_token() {
            return access_token;
        }

        public void setAccess_token(String access_token) {
            this.access_token = access_token;
        }

        public String getToken_type() {
            return token_type;
        }

        public void setToken_type(String token_type) {
            this.token_type = token_type;
        }

        public int getExpires_in() {
            return expires_in;
        }

        public void setExpires_in(int expires_in) {
            this.expires_in = expires_in;
        }
    }
}

// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}

{% tab title="NodeJS" %}

```javascript
const express = require('express');
const jwt = require('jsonwebtoken');
const bodyParser = require('body-parser');

// Khởi tạo ứng dụng Express
const app = express();
app.use(bodyParser.json());

const VALID_USERNAME = 'customer-vietqrtest-user2468';
const VALID_PASSWORD = 'Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09'; // Base64 của username:password
const SECRET_KEY = 'your-256-bit-secret'; // Secret key để ký JWT

// API để tạo token
app.post('/vqr/api/token_generate', (req, res) => {
    // Kiểm tra Authorization header
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Basic ')) {
        return res.status(400).json({ error: 'Authorization header is missing or invalid' });
    }

    // Giải mã Base64 từ Authorization header
    const base64Credentials = authHeader.split(' ')[1];
    const credentials = Buffer.from(base64Credentials, 'base64').toString('utf-8');
    const [username, password] = credentials.split(':');

    // Kiểm tra username và password
    if (username === VALID_USERNAME && password === VALID_PASSWORD) {
        // Tạo JWT token
        const token = jwt.sign(
            { username }, 
            SECRET_KEY, 
            { algorithm: 'HS512', expiresIn: '5m' } // Token hết hạn sau 5 phút
        );

        // Trả về token
        res.json({
            access_token: token,
            token_type: 'Bearer',
            expires_in: 300 // 300 giây = 5 phút
        });
    } else {
        res.status(401).json({ error: 'Invalid credentials' });
    }
});

// Chạy server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require __DIR__ . '/vendor/autoload.php'; // Autoload từ Composer
use \Firebase\JWT\JWT;

class TokenAPI {
    private $validUsername = 'customer-vietqrtest-user2468';
    private $validPassword = 'Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09'; // Base64 của username:password
    private $secretKey = 'your-256-bit-secret'; // Secret key để ký JWT

    public function generateToken() {
        // Kiểm tra Authorization header
        if (!isset($_SERVER['HTTP_AUTHORIZATION'])) {
            http_response_code(400);
            echo json_encode(["error" => "Authorization header is missing or invalid"]);
            return;
        }

        $authHeader = $_SERVER['HTTP_AUTHORIZATION'];
        if (strpos($authHeader, 'Basic ') !== 0) {
            http_response_code(400);
            echo json_encode(["error" => "Invalid Authorization header"]);
            return;
        }

        // Giải mã Base64 từ Authorization header
        $base64Credentials = substr($authHeader, 6);
        $credentials = base64_decode($base64Credentials);
        list($username, $password) = explode(':', $credentials);

        // Kiểm tra username và password
        if ($username === $this->validUsername && $password === $this->validPassword) {
            $token = $this->createJwtToken($username);
            echo json_encode([
                "access_token" => $token,
                "token_type" => "Bearer",
                "expires_in" => 300
            ]);
        } else {
            http_response_code(401);
            echo json_encode(["error" => "Invalid credentials"]);
        }
    }

    // Hàm tạo JWT token
    private function createJwtToken($username) {
        $issuedAt = time();
        $expirationTime = $issuedAt + 300;  // Token hết hạn sau 300 giây
        $payload = [
            'iss' => 'https://yourdomain.com', // Issuer của token
            'iat' => $issuedAt,
            'exp' => $expirationTime,
            'username' => $username
        ];

        return JWT::encode($payload, $this->secretKey, 'HS512');
    }
}

// Khởi tạo đối tượng và gọi hàm generateToken
$api = new TokenAPI();
$api->generateToken();


// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}

{% tab title="Python" %}

```python
from flask import Flask, request, jsonify
import jwt
import time
import base64

app = Flask(__name__)

# Cấu hình username, password hợp lệ và secret key
VALID_USERNAME = 'customer-vietqrtest-user2468'
VALID_PASSWORD = 'Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09' # Base64 của username:password
SECRET_KEY = 'your-256-bit-secret'  # Secret key để ký JWT

# API để tạo token
@app.route('/vqr/api/token_generate', methods=['POST'])
def generate_token():
    # Kiểm tra Authorization header
    auth_header = request.headers.get('Authorization')
    if not auth_header or not auth_header.startswith('Basic '):
        return jsonify({"error": "Authorization header is missing or invalid"}), 400

    # Giải mã Base64 từ Authorization header
    base64_credentials = auth_header.split(' ')[1]
    credentials = base64.b64decode(base64_credentials).decode('utf-8')
    username, password = credentials.split(':')

    # Kiểm tra username và password
    if username == VALID_USERNAME and password == VALID_PASSWORD:
        # Tạo JWT token
        issued_at = int(time.time())
        expiration_time = issued_at + 300  # Token hết hạn sau 300 giây (5 phút)
        payload = {
            'username': username,
            'iat': issued_at,
            'exp': expiration_time
        }

        token = jwt.encode(payload, SECRET_KEY, algorithm='HS512')

        # Trả về token
        return jsonify({
            "access_token": token,
            "token_type": "Bearer",
            "expires_in": 300
        })
    else:
        return jsonify({"error": "Invalid credentials"}), 401

if __name__ == '__main__':
    app.run(port=5000)

// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}
{% endtabs %}

***

### 2.3 - Các câu hỏi thường gặp chủ đề API Get Token

> <details>
>
> <summary>Làm thế nào để cấp quyền truy cập cho VietQR vào API của chúng tôi?</summary>
>
> Bạn cần tạo một username và password dành riêng cho VietQR để họ có thể truy cập vào API Transaction Sync của bạn. Sau đó, bạn chia sẻ thông tin này với đội ngũ VietQR để họ có thể thực hiện đồng bộ dữ liệu.
>
> </details>
>
> <details>
>
> <summary>Thông tin đăng nhập VietQR sử dụng có bảo mật không?</summary>
>
> VietQR cam kết tuân thủ các quy trình bảo mật nghiêm ngặt. Thông tin đăng nhập mà bạn cung cấp sẽ được mã hóa và chỉ sử dụng cho mục đích đồng bộ dữ liệu theo thỏa thuận giữa hai bên.
>
> </details>
>
> <details>
>
> <summary>Có giới hạn nào về tần suất truy cập mà VietQR có thể thực hiện vào API của tôi?</summary>
>
> Nếu có bất kỳ giới hạn nào về tần suất truy cập hoặc tài nguyên, bạn nên thông báo trước với đội ngũ VietQR để họ có thể điều chỉnh tần suất truy cập phù hợp và tránh quá tải hệ thống.
>
> </details>
>
> <details>
>
> <summary>Tôi có thể giới hạn quyền truy cập của VietQR vào một phần nhất định của API không?</summary>
>
> Có, bạn có thể cấu hình quyền truy cập để VietQR chỉ có thể truy cập vào các endpoint cần thiết cho việc đồng bộ dữ liệu. Điều này giúp đảm bảo an toàn và bảo mật cho hệ thống của bạn.
>
> </details>


# API Transaction Sync

Dùng nhận Callback biến động số dư VietQR trả về cho đối tác

### <mark style="color:green;">`POST`</mark> API Transaction Sync <a href="#api-transaction-sync" id="api-transaction-sync"></a>

```
https://<your-host>/<your-basepath>/bank/api/transaction-sync
```

**Headers**

<table><thead><tr><th width="203">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td><code>Bearer &#x3C;token></code>  Bearer Token VietQR nhận được từ response API Get Token của đối tác trả về.</td></tr></tbody></table>

**Body**

<table data-full-width="false"><thead><tr><th width="203">Name</th><th width="98">Type</th><th width="105">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>bankaccount</code></td><td>String</td><td>Yes</td><td>Tài khoản ngân hàng tạo mã thanh toán.</td></tr><tr><td><code>amount</code></td><td>Long</td><td>Yes</td><td>Số tiền giao dịch.</td></tr><tr><td><code>transType</code></td><td>String</td><td>Yes</td><td>Phân loại giao dịch là ghi nợ/ghi có (giá trị: D/C).</td></tr><tr><td><code>content</code></td><td>String</td><td>Yes</td><td>Nội dung chuyển tiền.</td></tr><tr><td><code>transactionid</code></td><td>String</td><td>Yes</td><td>ID của giao dịch.</td></tr><tr><td><code>transactiontime</code></td><td>Long</td><td>Yes</td><td>Thời gian giao dịch được thực hiện (timestamp (ms))<br>Ví dụ: 1757342061000</td></tr><tr><td><code>referencenumber</code></td><td>String</td><td>Yes</td><td>Mã giao dịch.</td></tr><tr><td><code>orderId</code></td><td>String</td><td>Yes</td><td>Mã đơn hàng</td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng/điểm bán.</td></tr><tr><td><code>subTerminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng phụ/điểm bán phụ.</td></tr><tr><td><code>serviceCode</code></td><td>String</td><td>Optional</td><td>Mã sản phẩm/dịch vụ.</td></tr><tr><td><code>urlLink</code></td><td>String</td><td>Optional</td><td>Link điều hướng sau khi thanh toán thành công.</td></tr><tr><td><code>sign</code></td><td>String</td><td>Optional</td><td>Chữ ký.</td></tr></tbody></table>

Response

{% tabs %}
{% tab title="200 (OK)" %}

```json
{
    "error": false,
    "errorReason": "mã_lỗi_trả_về_từ_đối_tác",
    "toastMessage": "mô_tả_lỗi_trả_về_từ_đối_tác",
    "object": {
        "reftransactionid": "ID_của_giao_dịch"
    }
}
```

{% endtab %}

{% tab title="400 (Error Request)" %}

```json
{
    "error": true,
    "errorReason": "mã_lỗi_trả_về_từ_đối_tác",
    "toastMessage": "mô_tả_lỗi_trả_về_từ_đối_tác",
    "object": null
}
```

{% endtab %}
{% endtabs %}

### 3.2 Code cài đặt

{% tabs %}
{% tab title="C#" %}

```csharp
namespace YourNamespace.Controllers
{
    [Route("bank/api")]
    [ApiController]
    public class TransactionSyncController : ControllerBase
    {
        private const string SECRET_KEY = "your-256-bit-secret"; // Secret key để kiểm tra JWT
        private const string BEARER_PREFIX = "Bearer ";

        // API để xử lý transaction-sync
        [HttpPost("transaction-sync")]
        public IActionResult TransactionSync([FromBody] TransactionCallback transactionCallback)
        {
            // Lấy token từ header Authorization
            string authHeader = Request.Headers["Authorization"];
            if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith(BEARER_PREFIX))
            {
                return StatusCode(401, new ErrorResponse
                {
                    Error = true,
                    ErrorReason = "INVALID_AUTH_HEADER",
                    ToastMessage = "Authorization header is missing or invalid",
                    Object = null
                });
            }

            string token = authHeader.Substring(BEARER_PREFIX.Length).Trim();

            // Xác thực token
            if (!ValidateToken(token))
            {
                return StatusCode(401, new ErrorResponse
                {
                    Error = true,
                    ErrorReason = "INVALID_TOKEN",
                    ToastMessage = "Invalid or expired token",
                    Object = null
                });
            }

            // Xử lý logic của transaction
            try
            {
                // Ví dụ xử lý nghiệp vụ và sinh mã reftransactionid
                string refTransactionId = "GeneratedRefTransactionId"; // Tạo ID của giao dịch
                
                // Trả về response 200 OK với thông tin giao dịch
                return Ok(new SuccessResponse
                {
                    Error = false,
                    ErrorReason = null,
                    ToastMessage = "Transaction processed successfully",
                    Object = new TransactionResponseObject
                    {
                        reftransactionid = refTransactionId
                    }
                });
            }
            catch (Exception ex)
            {
                // Trả về lỗi trong trường hợp có exception
                return StatusCode(400, new ErrorResponse
                {
                    Error = true,
                    ErrorReason = "TRANSACTION_FAILED",
                    ToastMessage = ex.Message,
                    Object = null
                });
            }
        }

        // Phương thức để xác thực token JWT
        private bool ValidateToken(string token)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(SECRET_KEY);

            try
            {
                tokenHandler.ValidateToken(token, new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ClockSkew = TimeSpan.Zero, // Không cho phép độ trễ thời gian
                }, out SecurityToken validatedToken);

                return true;
            }
            catch
            {
                return false;
            }
        }
    }

    // Lớp model cho request body
    public class TransactionCallback
    {
        public string transactionid { get; set; }
        public long transactiontime { get; set; }
        public string referencenumber { get; set; }
        public decimal amount { get; set; }
        public string content { get; set; }
        public string bankaccount { get; set; }
        public string orderId { get; set; }
        public string sign { get; set; }
        public string terminalCode { get; set; }
        public string urlLink { get; set; }
        public string serviceCode { get; set; }
        public string subTerminalCode { get; set; }
    }

    // Lớp model cho success response
    public class SuccessResponse
    {
        public bool Error { get; set; }
        public string ErrorReason { get; set; }
        public string ToastMessage { get; set; }
        public TransactionResponseObject Object { get; set; }
    }

    // Lớp model cho lỗi response
    public class ErrorResponse
    {
        public bool Error { get; set; }
        public string ErrorReason { get; set; }
        public string ToastMessage { get; set; }
        public object Object { get; set; }
    }

    // Lớp model cho object trả về trong success response
    public class TransactionResponseObject
    {
        public string reftransactionid { get; set; }
    }
}

// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}

{% tab title="Java" %}

```java
@RestController
@RequestMapping("/bank/api")
public class TransactionSyncController {

    private static final String SECRET_KEY = "your-256-bit-secret"; // Secret key để kiểm tra JWT
    private static final String BEARER_PREFIX = "Bearer ";

    @PostMapping("/transaction-sync")
    public ResponseEntity<Object> transactionSync(@RequestBody TransactionCallback transactionCallback,
                                                  HttpServletRequest request) {
        // Lấy token từ header Authorization
        String authHeader = request.getHeader("Authorization");
        if (authHeader == null || !authHeader.startsWith(BEARER_PREFIX)) {
            return new ResponseEntity<>(new ErrorResponse(true, "INVALID_AUTH_HEADER", 
                    "Authorization header is missing or invalid", null), HttpStatus.UNAUTHORIZED);
        }

        String token = authHeader.substring(BEARER_PREFIX.length()).trim();

        // Xác thực token
        if (!validateToken(token)) {
            return new ResponseEntity<>(new ErrorResponse(true, "INVALID_TOKEN", 
                    "Invalid or expired token", null), HttpStatus.UNAUTHORIZED);
        }

        try {
            // Xử lý nghiệp vụ, sinh mã refTransactionId (Giả sử tạo một mã ngẫu nhiên)
            String refTransactionId = "GeneratedRefTransactionId"; // Sinh ID của giao dịch

            // Trả về response 200 OK với thông tin giao dịch
            TransactionResponseObject transactionResponse = new TransactionResponseObject(refTransactionId);
            return ResponseEntity.ok(new SuccessResponse(false, null, 
                    "Transaction processed successfully", transactionResponse));
        } catch (Exception ex) {
            // Trả về lỗi trong trường hợp có exception
            return new ResponseEntity<>(new ErrorResponse(true, "TRANSACTION_FAILED", ex.getMessage(), null), HttpStatus.BAD_REQUEST);
        }
    }

    // Phương thức để xác thực token JWT
    private boolean validateToken(String token) {
        // Đây là phương pháp giả sử validate token với SECRET_KEY
        // Bạn có thể tích hợp JWT library như `io.jsonwebtoken` để validate
        try {
            // Giả sử giải mã token với SECRET_KEY
            byte[] secretKeyBytes = SECRET_KEY.getBytes();
            String decodedToken = new String(Base64.getDecoder().decode(token.getBytes()));

            // Kiểm tra token hợp lệ (thực tế nên sử dụng JWT library như jjwt)
            return decodedToken.contains(SECRET_KEY);
        } catch (Exception e) {
            return false;
        }
    }
}

// Lớp model cho request body
class TransactionCallback {
    private String transactionid;
    private long transactiontime;
    private String referencenumber;
    private double amount;
    private String content;
    private String bankaccount;
    private String orderId;
    private String sign;
    private String terminalCode;
    private String urlLink;
    private String serviceCode;
    private String subTerminalCode;

    // Getters and Setters
    // ...
}

// Lớp model cho success response
class SuccessResponse {
    private boolean error;
    private String errorReason;
    private String toastMessage;
    private TransactionResponseObject object;

    public SuccessResponse(boolean error, String errorReason, String toastMessage, TransactionResponseObject object) {
        this.error = error;
        this.errorReason = errorReason;
        this.toastMessage = toastMessage;
        this.object = object;
    }

    // Getters and Setters
    // ...
}

// Lớp model cho lỗi response
class ErrorResponse {
    private boolean error;
    private String errorReason;
    private String toastMessage;
    private Object object;

    public ErrorResponse(boolean error, String errorReason, String toastMessage, Object object) {
        this.error = error;
        this.errorReason = errorReason;
        this.toastMessage = toastMessage;
        this.object = object;
    }

    // Getters and Setters
    // ...
}

// Lớp model cho object trả về trong success response
class TransactionResponseObject {
    private String reftransactionid;

    public TransactionResponseObject(String reftransactionid) {
        this.reftransactionid = reftransactionid;
    }

    // Getters and Setters
    // ...
}

// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}

{% tab title="NodeJS" %}

```javascript
const express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');

const app = express();
const PORT = process.env.PORT || 3000;

const SECRET_KEY = 'your-256-bit-secret'; // Secret key để kiểm tra JWT
const BEARER_PREFIX = 'Bearer ';

app.use(bodyParser.json());

// Model cho request body
class TransactionCallback {
    constructor(transactionid, transactiontime, referencenumber, amount, content, bankaccount, orderId, sign, terminalCode, urlLink, serviceCode, subTerminalCode) {
        this.transactionid = transactionid;
        this.transactiontime = transactiontime;
        this.referencenumber = referencenumber;
        this.amount = amount;
        this.content = content;
        this.bankaccount = bankaccount;
        this.orderId = orderId;
        this.sign = sign;
        this.terminalCode = terminalCode;
        this.urlLink = urlLink;
        this.serviceCode = serviceCode;
        this.subTerminalCode = subTerminalCode;
    }
}

// API để xử lý transaction-sync
app.post('/bank/api/transaction-sync', (req, res) => {
    const authHeader = req.headers['authorization'];
    if (!authHeader || !authHeader.startsWith(BEARER_PREFIX)) {
        return res.status(401).json(new ErrorResponse(true, "INVALID_AUTH_HEADER", "Authorization header is missing or invalid", null));
    }

    const token = authHeader.substring(BEARER_PREFIX.length).trim();

    // Xác thực token
    if (!validateToken(token)) {
        return res.status(401).json(new ErrorResponse(true, "INVALID_TOKEN", "Invalid or expired token", null));
    }

    const transactionCallback = new TransactionCallback(
        req.body.transactionid,
        req.body.transactiontime,
        req.body.referencenumber,
        req.body.amount,
        req.body.content,
        req.body.bankaccount,
        req.body.orderId,
        req.body.sign,
        req.body.terminalCode,
        req.body.urlLink,
        req.body.serviceCode,
        req.body.subTerminalCode
    );

    try {
        // Ví dụ xử lý nghiệp vụ và sinh mã reftransactionid
        const refTransactionId = "GeneratedRefTransactionId"; // Tạo ID của giao dịch

        // Trả về response 200 OK với thông tin giao dịch
        return res.status(200).json(new SuccessResponse(false, null, "Transaction processed successfully", new TransactionResponseObject(refTransactionId)));
    } catch (error) {
        // Trả về lỗi trong trường hợp có exception
        return res.status(400).json(new ErrorResponse(true, "TRANSACTION_FAILED", error.message, null));
    }
});

// Phương thức để xác thực token JWT
const validateToken = (token) => {
    try {
        const decoded = jwt.verify(token, SECRET_KEY);
        return true;
    } catch (error) {
        return false;
    }
};

// Lớp model cho success response
class SuccessResponse {
    constructor(error, errorReason, toastMessage, object) {
        this.error = error;
        this.errorReason = errorReason;
        this.toastMessage = toastMessage;
        this.object = object;
    }
}

// Lớp model cho lỗi response
class ErrorResponse {
    constructor(error, errorReason, toastMessage, object) {
        this.error = error;
        this.errorReason = errorReason;
        this.toastMessage = toastMessage;
        this.object = object;
    }
}

// Lớp model cho object trả về trong success response
class TransactionResponseObject {
    constructor(reftransactionid) {
        this.reftransactionid = reftransactionid;
    }
}

// Khởi động server
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

//sample code mang tính chất tham khảo
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

require 'vendor/autoload.php';

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Factory\AppFactory;
use Firebase\JWT\JWT;
use Firebase\JWT\ExpiredException;

$app = AppFactory::create();

$SECRET_KEY = 'your-256-bit-secret'; // Secret key để kiểm tra JWT

// Model cho request body
class TransactionCallback {
    public $transactionid;
    public $transactiontime;
    public $referencenumber;
    public $amount;
    public $content;
    public $bankaccount;
    public $orderId;
    public $sign;
    public $terminalCode;
    public $urlLink;
    public $serviceCode;
    public $subTerminalCode;

    public function __construct($data) {
        $this->transactionid = $data['transactionid'];
        $this->transactiontime = $data['transactiontime'];
        $this->referencenumber = $data['referencenumber'];
        $this->amount = $data['amount'];
        $this->content = $data['content'];
        $this->bankaccount = $data['bankaccount'];
        $this->orderId = $data['orderId'];
        $this->sign = $data['sign'];
        $this->terminalCode = $data['terminalCode'];
        $this->urlLink = $data['urlLink'];
        $this->serviceCode = $data['serviceCode'];
        $this->subTerminalCode = $data['subTerminalCode'];
    }
}

// Lớp model cho success response
class SuccessResponse {
    public $error;
    public $errorReason;
    public $toastMessage;
    public $object;

    public function __construct($error, $errorReason, $toastMessage, $object) {
        $this->error = $error;
        $this->errorReason = $errorReason;
        $this->toastMessage = $toastMessage;
        $this->object = $object;
    }
}

// Lớp model cho lỗi response
class ErrorResponse {
    public $error;
    public $errorReason;
    public $toastMessage;
    public $object;

    public function __construct($error, $errorReason, $toastMessage, $object) {
        $this->error = $error;
        $this->errorReason = $errorReason;
        $this->toastMessage = $toastMessage;
        $this->object = $object;
    }
}

// Lớp model cho object trả về trong success response
class TransactionResponseObject {
    public $reftransactionid;

    public function __construct($reftransactionid) {
        $this->reftransactionid = $reftransactionid;
    }
}

// API để xử lý transaction-sync
$app->post('/bank/api/transaction-sync', function (ServerRequestInterface $request, ResponseInterface $response) use ($SECRET_KEY) {
    $authHeader = $request->getHeaderLine('Authorization');
    $bearerPrefix = 'Bearer ';

    if (empty($authHeader) || !str_starts_with($authHeader, $bearerPrefix)) {
        return $this->respondWithError($response, new ErrorResponse(true, "INVALID_AUTH_HEADER", "Authorization header is missing or invalid", null), 401);
    }

    $token = substr($authHeader, strlen($bearerPrefix));

    // Xác thực token
    if (!validateToken($token, $SECRET_KEY)) {
        return $this->respondWithError($response, new ErrorResponse(true, "INVALID_TOKEN", "Invalid or expired token", null), 401);
    }

    $data = json_decode($request->getBody(), true);
    $transactionCallback = new TransactionCallback($data);

    try {
        // Ví dụ xử lý nghiệp vụ và sinh mã reftransactionid
        $refTransactionId = "GeneratedRefTransactionId"; // Tạo ID của giao dịch

        // Trả về response 200 OK với thông tin giao dịch
        $successResponse = new SuccessResponse(false, null, "Transaction processed successfully", new TransactionResponseObject($refTransactionId));
        $response->getBody()->write(json_encode($successResponse));
        return $response->withStatus(200)->withHeader('Content-Type', 'application/json');
    } catch (Exception $e) {
        return $this->respondWithError($response, new ErrorResponse(true, "TRANSACTION_FAILED", $e->getMessage(), null), 400);
    }
});

// Phương thức để xác thực token JWT
function validateToken($token, $secretKey) {
    try {
        JWT::decode($token, $secretKey, ['HS256']);
        return true;
    } catch (ExpiredException $e) {
        return false;
    } catch (Exception $e) {
        return false;
    }
}

// Phương thức để trả về lỗi response
function respondWithError($response, $errorResponse, $statusCode) {
    $response->getBody()->write(json_encode($errorResponse));
    return $response->withStatus($statusCode)->withHeader('Content-Type', 'application/json');
}

// Khởi động server
$app->run();

//sample code mang tính chất tham khảo
```

{% endtab %}

{% tab title="Python" %}

```python
from flask import Flask, request, jsonify
import jwt
from jwt.exceptions import ExpiredSignatureError, InvalidTokenError

app = Flask(__name__)

SECRET_KEY = 'your-256-bit-secret'  # Secret key để kiểm tra JWT

# Model cho request body
class TransactionCallback:
    def __init__(self, data):
        self.transactionid = data.get('transactionid')
        self.transactiontime = data.get('transactiontime')
        self.referencenumber = data.get('referencenumber')
        self.amount = data.get('amount')
        self.content = data.get('content')
        self.bankaccount = data.get('bankaccount')
        self.orderId = data.get('orderId')
        self.sign = data.get('sign')
        self.terminalCode = data.get('terminalCode')
        self.urlLink = data.get('urlLink')
        self.serviceCode = data.get('serviceCode')
        self.subTerminalCode = data.get('subTerminalCode')

# Lớp model cho success response
class SuccessResponse:
    def __init__(self, error, errorReason, toastMessage, object):
        self.error = error
        self.errorReason = errorReason
        self.toastMessage = toastMessage
        self.object = object

# Lớp model cho lỗi response
class ErrorResponse:
    def __init__(self, error, errorReason, toastMessage, object):
        self.error = error
        self.errorReason = errorReason
        self.toastMessage = toastMessage
        self.object = object

# Lớp model cho object trả về trong success response
class TransactionResponseObject:
    def __init__(self, reftransactionid):
        self.reftransactionid = reftransactionid

@app.route('/bank/api/transaction-sync', methods=['POST'])
def transaction_sync():
    auth_header = request.headers.get('Authorization')
    bearer_prefix = 'Bearer '

    if not auth_header or not auth_header.startswith(bearer_prefix):
        return jsonify(ErrorResponse(True, "INVALID_AUTH_HEADER", "Authorization header is missing or invalid", None).__dict__), 401

    token = auth_header[len(bearer_prefix):]

    # Xác thực token
    if not validate_token(token):
        return jsonify(ErrorResponse(True, "INVALID_TOKEN", "Invalid or expired token", None).__dict__), 401

    transaction_callback = TransactionCallback(request.json)

    try:
        # Ví dụ xử lý nghiệp vụ và sinh mã reftransactionid
        ref_transaction_id = "GeneratedRefTransactionId"  # Tạo ID của giao dịch

        # Trả về response 200 OK với thông tin giao dịch
        success_response = SuccessResponse(False, None, "Transaction processed successfully", 
                                           TransactionResponseObject(ref_transaction_id))
        return jsonify(success_response.__dict__), 200

    except Exception as e:
        return jsonify(ErrorResponse(True, "TRANSACTION_FAILED", str(e), None).__dict__), 400

# Phương thức để xác thực token JWT
def validate_token(token):
    try:
        jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
        return True
    except (ExpiredSignatureError, InvalidTokenError):
        return False

if __name__ == '__main__':
    app.run(debug=True, port=5000)

//sample code mang tính chất tham khảo
```

{% endtab %}
{% endtabs %}

### 3.3 - Các câu hỏi thường gặp triển khai API Transaction Sync

> <details>
>
> <summary>API Transaction Sync dùng để làm gì?</summary>
>
> API Transaction Sync được sử dụng để đồng bộ dữ liệu giao dịch từ hệ thống của VietQR với hệ thống của khách hàng. Nó giúp đảm bảo rằng thông tin về các giao dịch luôn được cập nhật và nhất quán giữa hai hệ thống.
>
> </details>
>
> <details>
>
> <summary>Cần chuẩn bị những gì trước khi triển khai API Transaction Sync?</summary>
>
> Trước khi triển khai, bạn cần chuẩn bị thông tin xác thực (username và password) mà VietQR cung cấp, cùng với endpoint API mà bạn sẽ tích hợp. Đảm bảo hệ thống của bạn đã sẵn sàng để tiếp nhận và xử lý dữ liệu đồng bộ từ VietQR.
>
> </details>
>
> <details>
>
> <summary>Dữ liệu đồng bộ qua API Transaction Sync bao gồm những gì?</summary>
>
> Dữ liệu được đồng bộ qua API Transaction Sync thường bao gồm các thông tin giao dịch như mã giao dịch, số tiền, trạng thái giao dịch, và thời gian thực hiện. Các thông tin chi tiết sẽ phụ thuộc vào cấu hình của VietQR và yêu cầu cụ thể của hệ thống bạn.
>
> </details>
>
> <details>
>
> <summary>Làm thế nào để xử lý nếu việc đồng bộ thất bại?</summary>
>
> Nếu việc đồng bộ thất bại, API sẽ trả về mã lỗi và thông báo chi tiết. Bạn nên kiểm tra lại dữ liệu được gửi, đảm bảo rằng thông tin xác thực là chính xác và hệ thống của bạn có thể tiếp nhận dữ liệu từ API. Nếu lỗi vẫn tiếp diễn, hãy liên hệ với bộ phận kỹ thuật của VietQR.
>
> </details>


# Gọi API Get Token

Sử dụng thông tin kết nối do VietQR cung cấp để lấy token phục vụ cho việc truy cập API của VietQR

### <mark style="color:green;">`POST-`</mark> Môi trường Dev (Test/Kiểm thử)

```
https://dev.vietqr.org/vqr/api/token_generate
```

### <mark style="color:green;">`POST-`</mark> Môi trường Production (Golive/Vận hành)

```
https://api.vietqr.org/vqr/api/token_generate
```

**Headers**

<table><thead><tr><th width="225">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td>Basic Authentication: Base64[<code>username:password</code>]</td></tr></tbody></table>

**Body**

<table><thead><tr><th width="226">Name</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>access_token</code></td><td>String</td><td>Là Bearer Token do VietQR cung cấp dùng để truy cập các API của VietQR</td></tr><tr><td><code>token_type</code></td><td>String</td><td>Là dạng token dạng “Bearer”.</td></tr><tr><td><code>expires_in</code></td><td>Integer</td><td>Thời gian hết hạn của token. Mặc định là 300 giây.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "access_token": "bearer_token_của_VietQR_cung_cấp",
    "token_type": "Bearer",
    "expires_in": 300
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

**Note:**

Đối với môi trường Sandbox\
Username và Password do VietQR cung cấp khi đăng ký tích hợp và kết nối thành công \
(hình ảnh minh họa)

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2Fifx8asoemYDyaigbQ3gs%2Fimage.png?alt=media&amp;token=6f0966bc-7b09-4ce4-9689-11ce1551e64d" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FS3afjhG7mN08Q2CevI4s%2Fimage.png?alt=media&amp;token=869a5530-ee74-4ceb-9d2a-ca0ce0c8eb52" alt=""><figcaption></figcaption></figure>

### Code tham khảo

{% tabs %}
{% tab title="cURL" %}

```
curl --location --request POST 'https://dev.vietqr.org/vqr/api/token_generate' \
--header 'Authorization: Basic Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09'


Response:
{
    "access_token": "eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGRtbGxkSEZ5ZEdWemRDMTFjMlZ5TWpRMk9BPT0iLCJpYXQiOjE3MjEzNzI2MzQsImV4cCI6MTcyMTM3MjkzNH0.D19qvrpYHUgcGjDCXuXXAv3j6lZr6tfmIB0VzdCzAXMJAElGok04sNLysS6PRLdRb0hSgEX5_9KpLjB-xErn-A",
    "token_type": "Bearer",
    "expires_in": 300
}
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp

<details>

<summary>API Get Token dùng để làm gì?</summary>

API Get Token được sử dụng để cấp quyền truy cập vào các dịch vụ của VietQR bằng cách cung cấp một mã token (`access_token`). Mã token này sẽ được sử dụng trong các yêu cầu API khác để xác thực người dùng.

</details>

<details>

<summary>Làm thế nào để gọi API Get Token?</summary>

Bạn cần gửi một yêu cầu POST đến endpoint của API Get Token với thông tin xác thực (username và password) trong phần header. VietQR sẽ cung cấp thông tin này cho bạn sau khi hoàn tất quá trình đăng ký.

</details>

<details>

<summary>Token có thời gian sử dụng bao lâu?</summary>

Token được cấp bởi API Get Token thường có thời gian sử dụng là 300 giây (5 phút). Sau thời gian này, bạn cần gọi lại API để lấy token mới.

</details>

<details>

<summary>Tôi cần làm gì nếu nhận được thông báo lỗi khi gọi API Get Token?</summary>

Kiểm tra lại các thông tin bạn đã gửi, bao gồm username và password. Đảm bảo rằng các thông tin này đúng và vẫn còn hiệu lực. Nếu vấn đề vẫn tiếp diễn, hãy liên hệ với bộ phận hỗ trợ của VietQR để được giúp đỡ.

</details>

<details>

<summary>Tại sao tôi lại nhận được mã lỗi khi gọi API Get Token?</summary>

Các mã lỗi thường xuất hiện do vấn đề xác thực (sai username hoặc password), yêu cầu không hợp lệ, hoặc lỗi kết nối. Thông báo lỗi sẽ cung cấp chi tiết về nguyên nhân cụ thể, giúp bạn xác định và khắc phục vấn đề.

</details>

<details>

<summary>Tôi có thể sử dụng token trên môi trường nào?</summary>

Token được cấp có thể sử dụng trên các API của VietQR, tùy thuộc vào môi trường mà bạn đang sử dụng (Test hoặc Prod). Đảm bảo rằng bạn đang gọi API trên đúng môi trường tương ứng.

</details>

<details>

<summary>Làm thế nào để bảo mật token sau khi nhận được?</summary>

Token cần được bảo mật như một thông tin nhạy cảm. Không chia sẻ token với bất kỳ ai và lưu trữ nó một cách an toàn. Khi sử dụng token, hãy đảm bảo rằng kết nối của bạn được mã hóa (sử dụng HTTPS) để bảo vệ thông tin khỏi bị lộ.

</details>


# Gọi API Generate VietQR Code

API cho phép đối tác tạo mã QR Code thanh toán để người dùng quét và thực hiện thanh toán trực tiếp

### <mark style="color:green;">`POST-`</mark> Môi trường Dev (Test/Kiểm thử)

```
https://dev.vietqr.org/vqr/api/qr/generate-customer
```

### <mark style="color:green;">`POST-`</mark> Môi trường Production (Golive/Vận hành)

```
https://api.vietqr.org/vqr/api/qr/generate-customer
```

**Headers**

<table><thead><tr><th width="249">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td>Bearer &#x3C;token>  bạn nhận được khi gọi API Get Token của VietQR</td></tr></tbody></table>

**Body**&#x20;

<table data-full-width="false"><thead><tr><th width="215">Name</th><th width="90">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>bankCode</code></td><td>String</td><td>Yes</td><td>Mã ngân hàng của tài khoản. </td></tr><tr><td><code>bankAccount</code></td><td>String</td><td>Yes</td><td>Tài khoản ngân hàng tạo mã thanh toán VietQR.</td></tr><tr><td><code>userBankName</code></td><td>String</td><td>Yes</td><td>Họ tên chủ tài khoản. Không dấu tiếng Việt.</td></tr><tr><td><code>content</code></td><td>String</td><td>Yes</td><td>Nội dung chuyển tiền.<br><mark style="color:red;">T<strong>ối đa 23 ký tự,</strong></mark> tiếng Việt không dấu, không ký tự đặc biệt.</td></tr><tr><td><code>qrType</code></td><td>Integer</td><td>Yes</td><td><p>Tùy loại mã thanh toán cần tạo, nhập giá trị tương ứng:<br>- <mark style="background-color:green;">VietQR động: 0</mark><br>- <mark style="background-color:green;">VietQR tĩnh: 1</mark></p><p>- <mark style="background-color:green;">VietQR bán động: 3</mark> </p></td></tr><tr><td><code>amount</code></td><td>Long</td><td>Optional</td><td>Số tiền cần thanh toán.<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 0 hoặc 3></mark></td></tr><tr><td><code>orderId</code></td><td>String</td><td>Optional</td><td>Mã đơn hàng bên đối tác cần quản lý. “orderId” sẽ được trả về khi hệ thống nhận biến động số dư (có thông tin giao dịch trùng với giao dịch được tạo bằng mã QR).<br><mark style="color:red;"><strong>Tối đa 13 ký tự.</strong></mark><br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 0></mark></td></tr><tr><td><code>transType</code></td><td>String</td><td>Optional</td><td>Phân loại giao dịch là ghi nợ/ghi có (giá trị: D/C). <br>Mặc định là “C”.<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 0></mark></td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng/điểm bán.<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 1 hoặc 3></mark></td></tr><tr><td><code>serviceCode</code></td><td>String</td><td>Optional</td><td>Mã sản phẩm, dịch vụ được thanh toán.<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 3></mark></td></tr><tr><td><code>subTerminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng/điểm bán phụ.</td></tr><tr><td><code>sign</code></td><td>String</td><td>Optional</td><td>Chữ ký. </td></tr><tr><td><mark style="color:red;"><strong><code>urlLink</code></strong></mark></td><td><mark style="color:red;"><strong>String</strong></mark></td><td><mark style="color:red;"><strong>Optional</strong></mark></td><td><mark style="color:red;">Trang chuyển đến sau khi quét mã thanh toán.</mark> </td></tr><tr><td><code>note</code></td><td>String</td><td>Optional</td><td>Ghi chú cho giao dịch.</td></tr><tr><td><code>additionalData</code></td><td>List&#x3C;Object></td><td>Optional</td><td>Các tham số truyền thêm.</td></tr></tbody></table>

**Response**

```json
// Ví dụ kết quả trả về mã QR động
{
    "bankCode": "MB",
    "bankName": "Ngân hàng TMCP Quân đội",
    "bankAccount": "0852240768",
    "userBankName": "HA TRUNG HIEU",
    "amount": "6868",
    "content": "Test VA Account",
    "qrCode": "00020101021238570010A000000727012700069704220113VQRQACYEK56060208QRIBFTTA5303704540468685802VN62300107NPS68690815Test VA Account6304BE01",
    "imgId": "58b7190b-a294-4b14-968f-cd365593893e",
    "existing": 1,
    "transactionId": "",
    "transactionRefId": "MGEzMDIzNjktYThiZi00ZTFhLTlmNGEtZTI0ODBkMjE4Y2Vh",
    "qrLink": "https://pro.vietqr.vn/qr-generated?token=MGEzMDIzNjktYThiZi00ZTFhLTlmNGEtZTI0ODBkMjE4Y2Vh",
    "terminalCode": null,
    "subTerminalCode": "",
    "serviceCode": "",
    "orderId": "TESTVA",
    "additionalData": [],
    "vaAccount": "VQRQACYEK5606" (VA được hỗ trợ cho luồng TF MB và BIDV)
}
```

{% tabs %}
{% tab title="200 - mã QR động" %}

<pre class="language-json"><code class="lang-json"><strong>{
</strong>    "bankCode": "mã_ngân_hàng",
    "bankName": "tên_ngân_hàng",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "userBankName": "tên_chủ_tài_khoản",
    "amount": "số_tiền_cần_thanh_toán",
    "content": "nội_dung_thanh_toán",
    "qrCode": "mã_QR_dạng_string",
    "imgId": "id_ảnh_ngân_hàng",
    "existing": "1: đã_được_tạo_trên_hệ_thống_vietQR_thành_công",
    "transactionId": "id_định_danh_của_QR",
    "transactionRefId": "mã_định_danh_của_QR",
    "qrLink": "mã_QR_dạng_link",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "serviceCode": "mã_sản_phẩm",
    "orderId": "mã_đơn_hàng",
    "additionalData": "thông_tin_thêm",
    "vaAccount": "thông_tin_tài_khoản_ảo_Virtual_Account"
<strong>}
</strong></code></pre>

{% endtab %}

{% tab title="200 - mã QR bán động" %}

```json
{
    "bankCode": "mã_ngân_hàng",
    "bankName": "tên_ngân_hàng",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "userBankName": "tên_chủ_tài_khoản",
    "amount": "số_tiền_cần_thanh_toán",
    "content": "nội_dung_thanh_toán",
    "qrCode": "mã_QR_dạng_string",
    "imgId": "id_ảnh_ngân_hàng",
    "existing": "1: đã_được_tạo_trên_hệ_thống_vietQR_thành_công",
    "transactionId": "id_định_danh_của_QR",
    "transactionRefId": "mã_định_danh_của_QR",
    "qrLink": "mã_QR_dạng_link",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "serviceCode": "mã_sản_phẩm",
    "orderId": "mã_đơn_hàng",
    "additionalData": "thông_tin_thêm",
    "vaAccount": "thông_tin_tài_khoản_ảo_Virtual_Account"
}
```

{% endtab %}

{% tab title="200 - mã QR tĩnh" %}

```json
{
    "bankCode": "mã_ngân_hàng",
    "bankName": "tên_ngân_hàng",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "userBankName": "tên_chủ_tài_khoản",
    "amount": "số_tiền_cần_thanh_toán",
    "content": "nội_dung_thanh_toán",
    "qrCode": "mã_QR_dạng_string",
    "imgId": "id_ảnh_ngân_hàng",
    "existing": "1: đã_được_tạo_trên_hệ_thống_vietQR_thành_công",
    "transactionId": "id_định_danh_của_QR",
    "transactionRefId": "mã_định_danh_của_QR",
    "qrLink": "mã_QR_dạng_link",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "serviceCode": "mã_sản_phẩm",
    "orderId": "mã_đơn_hàng",
    "additionalData": "thông_tin_thêm",
    "vaAccount": "thông_tin_tài_khoản_ảo_Virtual_Account"
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code tham khảo

{% tabs %}
{% tab title="cURL tạo mã QR động" %}

```
curl --location 'https://dev.vietqr.org/vqr/api/qr/generate-customer' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=D4468C26FD481B215DBF12CB9707B0AD' \
--header 'Content-Type: application/json' \
--data '{
    "amount": "số_tiền_cần_thanh_toán",
    "content": "nội_dung_thanh_toán",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "bankCode": "mã_ngân_hàng",
    "userBankName": "tên_chủ_tài_khoản",
    "transType": "C:giao_dịch_đến/D:giao_dịch_đi",
    "orderId": "mã_đơn_hàng",
    "sign": "chữ_ký",
    "serviceCode": "mã_sản_phẩm",
    "qrType": "loại qr: 0",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "note": "ghi_chú_mã_qr",
    "urlLink": "link_mà_trang_qr_link_sẽ_redirect_nếu_mã_qr_được_thanh_toán_thành công",
    "additionalData": "thông_tin_thêm_mã_QR_có_thể_truyền_empty_do_KH_tự_định_nghĩa",
}'
```

{% endtab %}

{% tab title="cURL tạo mã QR bán động" %}

```
curl --location 'https://dev.vietqr.org/vqr/api/qr/generate-customer' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=D4468C26FD481B215DBF12CB9707B0AD' \
--header 'Content-Type: application/json' \
--data '{
    "amount": "số_tiền_của_sản_phẩm",
    "content": "nội_dung_thanh_toán",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "bankCode": "mã_ngân_hàng",
    "userBankName": "tên_chủ_tài_khoản",
    "transType": "C:giao_dịch_đến/D:giao_dịch_đi",
    "qrType": "loại qr: 1",
    "terminalCode": "mã_điểm_bán_đã_đồng_bộ"
    "serviceCode": "mã_sản_phẩm",
    "qrType": 3
}'
```

{% endtab %}

{% tab title="cURL tạo mã QR tĩnh" %}

```
curl --location 'https://dev.vietqr.org/vqr/api/qr/generate-customer' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=A2494C77F9BCB561B15CDFDF6FF2CD1F' \
--header 'Content-Type: application/json' \
--data '{
    "content": "nội_dung_thanh_toán",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "bankCode": "mã_ngân_hàng",
    "userBankName": "tên_chủ_tài_khoản",
    "transType": "C:giao_dịch_đến/D:giao_dịch_đi",
    "qrType": "loại qr: 1",
    "terminalCode": "mã_điểm_bán_đã_đồng_bộ"
}'
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp

<details>

<summary>Khi gọi API Generate VietQR Code, tôi gặp phải mã lỗi trả về là "E34"??!</summary>

Khi gặp phải mã lỗi này, bạn hãy kiểm tra lại 2 trường sau:

* &#x20;`content` :&#x20;
  * Độ dài không được vượt quá 23 ký tự.&#x20;
  * Không chứa ký tự đặc biệt.
  * Ký tự thuộc dạng chữ cái Latin/Tiếng Việt không dấu.
* `orderId` :&#x20;
  * Độ dài không được vượt quá 13 ký tự.&#x20;
  * Không chứa ký tự đặc biệt.
  * Ký tự thuộc dạng chữ cái Latin/Tiếng Việt không dấu.

</details>

<details>

<summary>API Generate VietQR Code dùng để làm gì?</summary>

API Generate VietQR Code được sử dụng để tạo mã QR thanh toán cho các giao dịch. Mã QR này có thể được khách hàng quét để thực hiện thanh toán trực tiếp từ tài khoản ngân hàng.

</details>

<details>

<summary>Tôi cần cung cấp những thông tin gì để tạo mã QR thanh toán?</summary>

Để tạo mã QR thanh toán, bạn cần cung cấp các thông tin như số tiền, mã đơn hàng, thông tin người nhận, và thông tin tài khoản ngân hàng của người nhận. Các thông tin này sẽ được mã hóa vào mã QR. Bạn có thể xem chi tiết các thông tin cần thiết cho từng loại mã QR ở trên.

</details>

<details>

<summary>Làm thế nào để biết mã QR đã được tạo thành công?</summary>

Khi mã QR được tạo thành công, API sẽ trả về hình ảnh mã QR dưới dạng string cùng với các thông tin chi tiết liên quan đến giao dịch. Nếu có lỗi xảy ra, bạn sẽ nhận được thông báo lỗi trong phần phản hồi.

</details>

<details>

<summary>Làm thế nào để xử lý lỗi khi gọi API Generate VietQR Code?</summary>

Nếu bạn gặp lỗi khi gọi API, trước tiên hãy kiểm tra lại các thông tin đầu vào như số tiền, thông tin tài khoản, và mã đơn hàng. Đảm bảo rằng các thông tin này chính xác và hợp lệ. Nếu vấn đề vẫn tiếp diễn, hãy liên hệ với bộ phận hỗ trợ kỹ thuật của VietQR để được giúp đỡ.

</details>

<details>

<summary>Mã QR có thể được quét bằng ứng dụng nào?</summary>

Mã QR được tạo bởi API VietQR có thể được quét bằng bất kỳ ứng dụng ngân hàng nào hỗ trợ chuẩn thanh toán QR tại Việt Nam, hoặc các ứng dụng thanh toán ví điện tử có tính năng quét mã QR.

</details>

<details>

<summary>Tôi có cần mã hóa thông tin trước khi gửi đến API không?</summary>

Không, API VietQR sẽ tự động mã hóa các thông tin cần thiết khi tạo mã QR. Bạn chỉ cần đảm bảo rằng các thông tin gửi đến API là chính xác và đầy đủ.

</details>


# Gọi API Test Callback

API cho phép đối tác giả lập thanh toán đơn hàng trên môi trường Sandbox để kiểm tra kết nối callback từ hệ thống VietQR đến hệ thống của đối tác

{% hint style="danger" %}
**Lưu ý: API này chỉ có thể áp dụng ở môi trường Sandbox (TEST).**
{% endhint %}

{% hint style="success" %}
**Giả Định Giao Dịch:** Trong môi trường thử nghiệm này, API giả định rằng một giao dịch đã được hoàn thành và thanh toán.
{% endhint %}

### <mark style="color:green;">`POST-`</mark> Môi trường Dev (Test/Kiểm thử)

```
https://dev.vietqr.org/vqr/bank/api/test/transaction-callback
```

**Headers**

<table><thead><tr><th width="250">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code>   </td></tr><tr><td>Authorization</td><td>Bearer &#x3C;token>  bạn nhận được khi gọi API Get Token của VietQR<br><mark style="color:red;">Lưu ý: Token bạn nhận được ở môi trường Sandbox</mark></td></tr></tbody></table>

**Body**

<table data-full-width="false"><thead><tr><th width="213">Name</th><th width="92">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>bankAccount</code></td><td>String</td><td>Yes</td><td>Tài khoản ngân hàng tạo mã thanh toán VietQR.</td></tr><tr><td><code>content</code></td><td>String</td><td>Yes</td><td>Nội dung chuyển tiền. <br>Bạn cần truyền đúng nội dung <em><strong>Response</strong></em> API tạo mã QR để đối soát giao dịch thành công</td></tr><tr><td><code>amount</code></td><td>Long</td><td>Yes</td><td>Số tiền.<br>Bạn cần truyền đúng số tiền <em><strong>Response</strong></em> API tạo mã QR để đối soát giao dịch thành công với mã QR động (qrType = 0) hoặc số tiền bất kỳ với loại qr khác</td></tr><tr><td><code>transType</code></td><td>String</td><td>Yes</td><td>Phân loại giao dịch là ghi nợ/ghi có (giá trị: D/C). Mặc định là “C”.</td></tr><tr><td><code>bankCode</code></td><td>String</td><td>Yes</td><td>Mã ngân hàng. <br>VD: "MB" cho ngân hàng MBBank.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "status": "SUCCESS",
    "message": ""
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://dev.vietqr.org/vqr/bank/api/test/transaction-callback' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIxNDUwMzEzLCJleHAiOjE3MjE0NTA2MTN9.u0hK2fZVFvtaZQ3jyVJmMvhyqW8aRFGJIgpL8C71jtXbAPfPhqyJIdGc0Lv-XOY7e1NcjZQWH3FUhc4SXxgqlQ' \
--header 'Cookie: JSESSIONID=5DAD675C6D1BFEB2305B2340FE3BEDEC' \
--data '{
    "bankAccount": "tài_khoản_ngân_hàng_đồng_bộ",
    "content": "nội_dung_test_callback_là_nội_dung_khi_quét_mã_qr_thanh_toán",
    "amount": "số_tiền",
    "bankCode": "mã_ngân_hàng", //VD: "MB" cho ngân hàng MBBank.
    "transType": "C:giao_dịch_đến, D:giao_dịch_đi"
}'
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp

<details>

<summary>API Test Callback dùng để làm gì?</summary>

API Test Callback được sử dụng để kiểm tra khả năng tiếp nhận và xử lý callback từ hệ thống của VietQR đến hệ thống của bạn. Nó giúp xác minh rằng hệ thống của bạn có thể nhận và xử lý thông báo từ VietQR khi có sự kiện xảy ra.

</details>

<details>

<summary>Tại sao cần phải thực hiện Test Callback?</summary>

Thực hiện Test Callback giúp đảm bảo rằng hệ thống của bạn có thể nhận thông báo (callback) một cách chính xác từ VietQR, điều này rất quan trọng trong việc đồng bộ trạng thái giao dịch và phản hồi kịp thời cho khách hàng.

</details>

<details>

<summary>Khi nào nên thực hiện Test Callback?</summary>

Bạn nên thực hiện Test Callback sau khi đã cấu hình xong các endpoint cần thiết trên hệ thống của mình và trước khi triển khai dịch vụ vào môi trường sản xuất. Điều này giúp phát hiện và khắc phục sớm các vấn đề tiềm ẩn.

</details>

<details>

<summary>Làm thế nào để kiểm tra rằng hệ thống của tôi đã nhận đúng callback?</summary>

Bạn có thể theo dõi log hệ thống của mình hoặc kiểm tra các phản hồi từ API Test Callback để xác nhận rằng hệ thống đã nhận đúng callback và xử lý nó theo mong đợi.

</details>

<details>

<summary>Phản hồi của API Test Callback sẽ như thế nào?</summary>

API Test Callback sẽ gửi một yêu cầu HTTP POST đến endpoint của API Transaction Sync mà bạn đã cấu hình, với dữ liệu mô phỏng giao dịch đã được thanh toán thực tế. Hệ thống của bạn cần trả về một phản hồi HTTP 200 OK để xác nhận rằng callback đã được nhận và xử lý thành công.

</details>

<details>

<summary>Sau khi tôi gọi API Test Callback thành công, nhưng vẫn chưa nhận được báo có giao dịch từ API Transaction Sync?</summary>

Hãy truyền đúng 2 trường `content` và `amount` được trả về ở phần response lúc tạo mã ở bước 6.

</details>

<details>

<summary><strong>Nếu callback không được xử lý thành công thì cần làm gì?</strong></summary>

Nếu callback không được xử lý thành công, bạn cần kiểm tra lại cấu hình endpoint, logic xử lý callback trên hệ thống của bạn, và thử lại Test Callback. Kiểm tra log và các thông báo lỗi để xác định nguyên nhân và khắc phục.

</details>

<details>

<summary>Có thể thực hiện Test Callback bao nhiêu lần?</summary>

Bạn có thể thực hiện Test Callback nhiều lần cho đến khi đảm bảo rằng hệ thống của bạn có thể xử lý callback một cách chính xác và ổn định.

</details>

<details>

<summary>Làm thế nào để xác nhận rằng callback đã được xử lý đúng cách?</summary>

Sau khi nhận được callback, hệ thống của bạn cần thực hiện các bước xử lý theo yêu cầu và gửi phản hồi HTTP 200 OK. Kiểm tra log hệ thống để đảm bảo rằng tất cả các bước đã được thực hiện đúng.

</details>


# Retry giao dịch

Hướng dẫn nghiệp vụ Retry trong hệ thống VietQR

Nghiệp vụ Retry là quá trình VietQR sẽ tự động đẩy lại thông tin biến động số dư (BĐSD) bị lỗi trước đó đến phía đối tác. Quá trình này bao gồm hai phần chính:

1\. Giao dịch bị lỗi do timeout hoặc lỗi kết nối giữa hệ thống VietQR và đối tác: VietQR sẽ thực hiện retry, tức là đẩy lại thông tin BĐSD.

2\. Giao dịch nhận được mã lỗi từ API Transaction-sync của đối tác: Nếu mã lỗi thuộc bộ mã lỗi yêu cầu thực hiện retry, VietQR sẽ tiến hành retry lại giao dịch.

### Quy trình Retry của VietQR

• VietQR sẽ thực hiện retry thông tin BĐSD cho đến khi nhận được phản hồi thành công từ phía đối tác hoặc phản hồi với các mã lỗi không yêu cầu retry.

• Số lần retry tối đa là 10 lần. Trong phút đầu tiên, VietQR sẽ retry 5 lần. Từ phút thứ 2 trở đi, hệ thống sẽ retry mỗi phút một lần.

• Khi tích hợp nghiệp vụ retry, đối tác cần kiểm tra kỹ mã giao dịch (referenceNumber) để tránh tình trạng trùng lặp giao dịch. VietQR đảm bảo không ghi nhận giao dịch bị trùng lặp.

### Các bước thực hiện tích hợp nghiệp vụ Retry

1\. VietQR cung cấp một file định dạng để đối tác khai báo bộ mã lỗi.

2\. Đối tác cung cấp thông tin về bộ mã lỗi của mình vào file.

3\. VietQR tiến hành cấu hình tích hợp retry dựa trên bộ mã lỗi của đối tác.

4\. Hai bên thực hiện kiểm thử và nghiệm thu quy trình.

5\. Đối tác tiến hành golive nghiệp vụ retry.

Hướng dẫn này nhằm đảm bảo quá trình retry diễn ra suôn sẻ và tránh những lỗi không mong muốn.


# Đồng bộ thông tin (api để đối tác tạo cửa hàng)

Tạo ra Terminal code để phục vụ cho việc tạo mã QR bán động hoặc QR tĩnh Hỗ trợ đối tác quản lý các giao dịch của cửa đại lý/cửa hàng/điểm bán một cách dễ dàng hơn.

{% tabs %}
{% tab title="Mục đích" %}
Việc đồng bộ thông tin giữa các đơn vị trong mạng lưới phân phối là vô cùng quan trọng. Mục đích chính của việc này bao gồm:

<table data-header-hidden><thead><tr><th width="148"></th><th></th></tr></thead><tbody><tr><td>Tổng Đại Lý</td><td>Quản trị kết nối và theo dõi hiệu quả hoạt động của mạng lưới phân phối.</td></tr><tr><td>Đại Lý</td><td><ul><li>Sử dụng dịch vụ tạo mã VietQR tĩnh cho các cửa hàng/điểm bán trực thuộc.</li><li>Nhận báo cáo doanh số và quản trị giao dịch theo từng mã cửa hàng/điểm bán.</li></ul></td></tr></tbody></table>

Việc đồng bộ thông tin các cửa hàng/điểm bán với Đại Lý là vô cùng cần thiết để đảm bảo các tiện ích trên được vận hành hiệu quả.
{% endtab %}

{% tab title="Quy trình thực hiện" %}
**Đối với Tổng Đại Lý:**

* Đối tác sử dụng [API Sync MID(s)](broken://pages/Qtfq4VAcFRmxjJJEtG8b) để đồng bộ thông tin các đại lý phân phối trực thuộc.

**Đối với Đại Lý:**

* Đối tác sử dụng [API Get MID(s)](broken://pages/ghOhkaCcp4jorSIxpbKv) để lấy thông tin đại lý của mình.
* Đối tác truyền tham số `MID` vào [API Get TID(s)](broken://pages/G51YmPkxAqaE9YkqRFWQ) để lấy danh sách thông tin các điểm bán/cửa hàng đã đồng bộ.
* Đối tác sử dụng[ API Sync TID(s)](broken://pages/t3Z08nJLgFa3gUmjRVcj) để đồng bộ thông tin các điểm bán/cửa hàng trực thuộc.
* Đối tác sử dụng giá trị của `terminalCode` để gọi [API Generate VietQR Code](broken://pages/jiuumbNC6UuMA2B0vUdE) để tạo mã VietQR và đánh dấu giao dịch.
  {% endtab %}
  {% endtabs %}

> Trường hợp Đại Lý không có nhu cầu sử dụng mã VietQR tĩnh và quản trị trên hệ thống VietQR, có thể bỏ qua bước này.
>
> <mark style="color:red;">**Note : API này chỉ sử dụng được trên môi trường Live.**</mark>


# Đồng bộ tổng đại lý

API này dùng để đồng bộ thông tin các đại lý thuộc tổng đại lý.

{% hint style="success" %}
Khách hàng và đối tác không thuộc diện tổng đại lý có thể bỏ qua bước này.
{% endhint %}

<mark style="color:green;">**`POST`**</mark> API Sync MID

```
https://<vietqr-host>/<basepath>/api/mid/synchronize/v1
```

**Headers**

<table><thead><tr><th width="283">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td>Bearer &#x3C;token> Bạn nhận được khi gọi API Get Token của VietQR</td></tr></tbody></table>

**Body**

<table data-full-width="false"><thead><tr><th width="264.3333740234375">Name</th><th width="111">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>merchants</code></td><td>List object</td><td>Yes</td><td>Danh sách đại lý cần đồng bộ.</td></tr><tr><td><code>merchants[].merchantFullName</code></td><td>String</td><td>Yes</td><td>Tên đại lý.</td></tr><tr><td><code>merchants[].merchantName</code></td><td>String</td><td>Yes</td><td>Tên rút gọn đại lý. Không chứa dấu tiếng Việt, không khoảng trắng, không ký tự đặc biệt.</td></tr><tr><td><code>merchants[].merchantAddress</code></td><td>String</td><td>Yes</td><td>Địa chỉ đăng ký kinh doanh.</td></tr><tr><td><code>merchants[].merchantIdentity</code></td><td>String</td><td>Yes</td><td>MST/CCCD/ĐKKD</td></tr><tr><td><code>merchants[].checkSum</code></td><td>String</td><td>Yes</td><td><p>Chuỗi mã hóa MD5 của tổ hợp:</p><p>(<code>password</code>+ <code>merchantName</code>+<code>merchantIdentity</code>)</p></td></tr><tr><td><code>merchants[].contactEmail</code></td><td>String</td><td>Optional</td><td>Địa chỉ email liên hệ của đại lý.</td></tr><tr><td><code>merchants[].contactPhone</code></td><td>String</td><td>Optional</td><td>Số điện thoại liên hệ của đại lý.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "status": "SUCCESS",
    "data": [
        {
            "mid": "ID_đại_lý",
            "merchantName": "tên_rút_gọn_đại_lý"
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://api.vietqr.org/vqr/api/mid/synchronize/v1' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIxMzc1MzUzLCJleHAiOjE3MjEzNzU2NTN9.Wi5BTmJ63f7h_p7rimfaycfGIs4TNBkzVGlCUSkOxzWU-QaYZF3rCNndlgPjO89LpRmU3VliSYcf5iHHNrnC7A' \
--header 'Cookie: JSESSIONID=068E5AFD023BFA9AAFBA841C0BF00B62' \
--data-raw '{
    "merchants": [ // DANH SÁCH CỬA HÀNG CẦN ĐỒNG BỘ
        {
            "merchantFullName": "tên_đầy_đủ_của_đại_lý",
            "merchantName": "tên_viết_tắt",
            "merchantAddress": "địa_chỉ_của_đại_lý",
            "merchantIdentity": "Mã_số_thuế",
            "contactEmail": "Email_liên_hệ",
            "contactPhone": "SĐT_liên_hệ",
            "checkSum": "HASHMD5 128bit của: mật_khẩu_get_token + merchant_name + merchantIdentity"
        }
    ]
}'
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp


# Kiểm tra danh sách đại lý

Dùng để lấy danh sách thông tin các đại lý đã đồng bộ thuộc tổng đại lý.

<mark style="color:green;">**`GET`**</mark> API Get MID

```
https://<vietqr-host>/<basepath>/api/mid/list-mid
```

**Headers**

<table><thead><tr><th width="283">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td>Bearer &#x3C;token> Bạn nhận được khi gọi API Get Token của VietQR</td></tr></tbody></table>

**Request Param**

<table data-full-width="false"><thead><tr><th width="197">Name</th><th width="93">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>page</code></td><td>Integer</td><td>Optional</td><td>Giá trị trang muốn hiển thị (default = 1)</td></tr><tr><td><code>size</code></td><td>Integer</td><td>Optional</td><td>Giá trị số item tối đa hiển thị của page (default = 20)</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "metadata": {
        "page": 1,
        "size": 20,
        "totalPage": 1,
        "totalElement": 1
    },
    "data": [
        {
            "merchantIdentify": "MST/CCCD/ĐKKD",
            "mid": "ID_của_đại_lý",
            "merchantName": "tên_rút_gọn_đại_lý",
            "merchantFullName": "tên_đại_lý",
            "merchantAddress": "địa_chỉ_đại_lý",
            "contactEmail": "email_liên_hệ",
            "contactPhone": "điện_thoại_liên_hệ"
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://api.vietqr.org/vqr/api/mid/list-mid?page=page_cần_chọn&size=số_record_cần_hiển_thị_trong_1_lần&mid=id_của_đại_lý' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIxMzc1MTUyLCJleHAiOjE3MjEzNzU0NTJ9.M-Yfnvm_mZGVteqoZ4aLdN2m_7_c8BwUHnzHm0WPOMW5ayTk49HWLtpl562AdgS_BUBUAS0648BktOaGzy6h8Q' \
--header 'Cookie: JSESSIONID=483ACB24C22E803DCFB52C2D89CCB4B0'
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp


# Đồng bộ điểm bán

Dùng để đồng bộ thông tin các cửa hàng/điểm bán.

<mark style="color:green;">**`POST`**</mark> API Sync TID

```
https://<vietqr-host>/<basepath>/api/tid/synchronize/v1
```

**Headers**

<table><thead><tr><th width="283">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td>Bearer &#x3C;token> Bạn nhận được khi gọi API Get Token của VietQR</td></tr></tbody></table>

**Body**

{% hint style="warning" %}
Đối tác truyền `mid` thì không cần truyền `merchantName`.
{% endhint %}

<table data-full-width="false"><thead><tr><th width="240">Name</th><th width="110">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>terminals</code></td><td>List object</td><td>Yes</td><td>Name of the user</td></tr><tr><td><code>terminal[].mid</code></td><td>String</td><td>Yes</td><td>ID của đại lý.</td></tr><tr><td><code>terminal[].merchantName</code></td><td>String</td><td>Yes</td><td>Tên rút gọn đại lý.</td></tr><tr><td><code>terminal[].terminalCode</code></td><td>String</td><td>Yes</td><td>Mã cửa hàng/điểm bán.</td></tr><tr><td><code>terminal[].terminalName</code></td><td>String</td><td>Yes</td><td>Tên cửa hàng/điểm bán.</td></tr><tr><td><code>terminal[].terminalAddress</code></td><td>String</td><td>Yes</td><td>Địa chỉ cửa hàng/điểm bán.</td></tr><tr><td><code>terminal[].bankCode</code></td><td>String</td><td>Yes</td><td>Mã ngân hàng.</td></tr><tr><td><code>terminal[].bankAccount</code></td><td>String</td><td>Yes</td><td>Số tài khoản ngân hàng.</td></tr><tr><td><code>terminal[].checkSum</code></td><td>String</td><td>Yes</td><td><p>Chuỗi mã hóa MD5 của tổ hợp:</p><p>(<code>password</code> + <code>bankCode</code> + <code>bankAccount</code>)</p></td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "status": "SUCCESS",
    "data": [
        {
            "tid": "ID_điểm_bán",
            "terminalName": "tên_điểm_bán",
            "terminalCode": "mã_điểm_bán",
            "bankAccount": "số_tài_khoản_áp_dụng_cho_điểm_bán",
            "bankCode": "mã_ngân_hàng"
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://api.vietqr.org/vqr/api/tid/synchronize/v1' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIwMDg4MDE3LCJleHAiOjE3MjAwODgwNzZ9.3_jljTg8llYVANJW4MVqW6YsJZbFl10r2AC66NNXCuSDWMyNYd2MlbnStNuyjHIqYDO5E5jD0izl4puPckYSyw' \
--header 'Cookie: JSESSIONID=EB9099326C4526CAA29AD331FFE6B789' \
--data '{
    "terminals": [ //DANH SÁCH CỬA HÀNG CỦA ĐẠI LÝ C ̀N ĐỒNG BỘ
        {
            "mid": "id_của_đại_lý", 
            "merchantName": "tên_viết_tắt_của_đại_lý", 
            "terminalName": "tên_cửa_hàng",
            "terminalCode": "mã_code_của_cửa_hàng",
            "terminalAddress": "địa_chỉ_của_cửa_hàng",
            "bankAccount": "số_tài_khoản_ngân_hàng",
            "bankCode": "mã_code_của_ngân_hàng",
            "checkSum": "HASHMD5 128 bit của: password_khi_get_token + bank_code + bankAccount" 
            
        }
    ]
}'
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp


# Kiểm tra danh sách điểm bán

Dùng để lấy danh sách thông tin các cửa hàng/điểm bán đã đồng bộ.

<mark style="color:green;">**`GET`**</mark> API Get TID

```
https://<vietqr-host>/<basepath>/api/tid/list-tid
```

**Headers**

<table><thead><tr><th width="283">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td>Bearer &#x3C;token> Bạn nhận được khi gọi API Get Token của VietQR</td></tr></tbody></table>

**Request Param**

<table><thead><tr><th width="192">Name</th><th width="89">Type</th><th width="99">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>page</code></td><td>Integer</td><td>Optional</td><td>Giá trị trang muốn hiển thị (default = 1)</td></tr><tr><td><code>size</code></td><td>Integer</td><td>Optional</td><td>Giá trị số item tối đa hiển thị của page (default = 20)</td></tr><tr><td><code>mid</code></td><td>String</td><td>Yes</td><td>ID của đại lý được lấy từ API Get Mid (Kiểm tra danh sách đại lý)</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "metadata": {
        "page": 1,
        "size": 20,
        "totalPage": 1,
        "totalElement": 1
    },
    "data": [
        {
            "bankAccount": "số_tài_khoản_áp_dung_cho_điểm_bán",
            "bankCode": "mã_ngân_hàng",
            "terminalCode": "mã_điểm_bán",
            "terminalName": "tên_điểm_bán",
            "terminalAddress": "địa_chỉ_điểm_bán",
            "tid": "ID_của_điểm_bán"
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://api.vietqr.org/vqr/api/tid/list-tid?page=page_cần_chọn&size=số_record_cần_hiển_thị_trong_1_lần&mid=id_của_đại_lý' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIxMzc0ODQxLCJleHAiOjE3MjEzNzUxNDF9.q2VEtZfITLi-Odvf0PPSyG_BDCzYeTNR3E8KkfUWg9yMOgczZYjcAS7-UyQZe6_TZh874CHcjw6NvGc8Fd8i3g' \
--header 'Cookie: JSESSIONID=EB9099326C4526CAA29AD331FFE6B789' \
--data ''
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp


# MASTER MERCHANT

## 1- API tạo merchant mới :&#x20;

## 2 -  QR ACTIVE ACTIVE  (CHIỀU APP VIETQR)

Đối tác Master merchant được cấp API dạng token đê in ra Mã QR hoặc hiển thị trên Web hoặc app của Merchant Giúp khách hàng có thể quét Mã QR lựa chọn tài khoản Kích hoạt dịch vụ :

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FeLvDAd4i5uz94myA86dQ%2Fimage.png?alt=media&amp;token=a6ca3106-6353-4f96-bbf6-338e2e525ada" alt=""><figcaption></figcaption></figure>

Ví dụ :&#x20;

| Mã Active trên thiết bị                                                                                                                                                                                                                                   | Mã Active trên Website | Mã Active trên App |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | ------------------ |
| <img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FAiCmvXfJbv75dtbRhe7o%2Fimage.png?alt=media&amp;token=be4c616f-3871-40dd-9f4f-a0448c78788b" alt="" data-size="original"> |                        |                    |

## 2 - API ATCITIVE (CHIỀU TỪ ĐẠI LÝ)

Khách hàng mở ứng dụng VietQR, tiến hành cài đặt và thiết lập QRBox tự động (do VietQR tạo và phê duyệt).

Sau đó, hệ thống thực hiện API call đến Master để kiểm tra trạng thái, xác định thành công hoặc thất bại.


# Golive dịch vụ

Hướng dẫn nghiệm thu test và Golive dịch vụ

Sau khi đại lý và khách hàng golive kết nối thành công có thể tiến hành golive dịch vụ!

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FpIO8May7mvLrM6dLp5YM%2Fimage.png?alt=media&amp;token=605c9e3c-6e3e-43a7-a2ad-49840d0d9794" alt=""><figcaption></figcaption></figure>

Chú ý về nhận diện thương hiệu :thumbsup:

oàn bộ Kết nối thanh toán qua Mã VietQR cần có Logo VietQR Để tạo sự thuận lợi cho khách hàng trong quá trình thanh toán.

Có những hướng dẫn cơ bản để người dùng&#x20;


# Nghiệm thu GoLive

Sau khi hoàn thành việc tích hợp và kiểm tra, bạn hãy yêu cầu nghiệm thu và tiến hành đưa dịch vụ vào hoạt động chính thức (GoLive).

{% file src="/files/En5py3ExCQhp66F53GO8" %}

{% hint style="success" %}
Download file trên, xác thực lại các thông tin sẽ được cấu hình GOLive (môi trường PROD).
{% endhint %}

{% hint style="success" %}
Sau khi đã hoan tất xác thực thông tin, hãy gửi lại file copy cho đội kỹ thuật để hoàn tất cấu hình và tiến hành đưa dịch vụ vào hoạt động chính thức (GoLive).
{% endhint %}


# Các Dịch vụ API Khác

cao


# PUSH QR VÀO VIETQR PAYBOX

TÀI LIỆU ĐẨY MÃ QR XUỐNG THIẾT BỊ PAYBOX

1. #### GỌI API Get Token

Mục đích: Dùng để tạo lấy token Dùng để lấy bearer token phục vụ cho việc truy cập API tạo mã thanh toán VietQR.

POST:&#x20;

<https://api.vietqr.org/vqr/api/token_generate>

Header:

<table data-header-hidden><thead><tr><th width="281"></th><th></th></tr></thead><tbody><tr><td>Name</td><td>Value</td></tr><tr><td>Content-Type</td><td>application/json</td></tr><tr><td>Authorization</td><td><p>Basic Authentication: </p><p>Base64[username:password]</p></td></tr></tbody></table>

Liên hệ VietQR : 0922333636 hoặc 0939603636 để được cấp Username, password.

Response Body:

<table data-header-hidden><thead><tr><th width="159"></th><th width="127"></th><th></th></tr></thead><tbody><tr><td>Name</td><td>Type</td><td>Desc</td></tr><tr><td>access_token</td><td>String</td><td>Là Bearer Token được VietQR cung cấp sau khi hoàn thành bước 4. Dùng để truy cập tạo mã thanh toán VietQR.</td></tr><tr><td>token_type</td><td>String</td><td>Là dạng token dạng “Bearer”</td></tr><tr><td>expires_in</td><td>int</td><td>Thời gian hết hạn của token. Mặc định là 300 giây</td></tr></tbody></table>

cURL:

curl --location --request POST '<https://api.vietqr.org/vqr/api/token\\_generate'&#x20>;

\--header 'Authorization: Basic Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09'

Response:

{

&#x20;   "access\_token": "eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGRtbGxkSEZ5ZEdWemRDMTFjMlZ5TWpRMk9BPT0iLCJpYXQiOjE3MjEzNzI2MzQsImV4cCI6MTcyMTM3MjkzNH0.D19qvrpYHUgcGjDCXuXXAv3j6lZr6tfmIB0VzdCzAXMJAElGok04sNLysS6PRLdRb0hSgEX5\_9KpLjB-xErn-A",

&#x20;   "token\_type": "Bearer",

&#x20;   "expires\_in": 300

}

2. #### Gọi API truyền mã QR xuống thiết bị

Mục đích: Dùng truyền mã QR xuống thiết bị để hiển thị

POST:  <https://api.vietqr.org/vqr/api/tid/send-qr>

Request Header:

<table data-header-hidden><thead><tr><th width="237"></th><th></th></tr></thead><tbody><tr><td>Name</td><td>Value</td></tr><tr><td>Content-Type</td><td>application/json</td></tr><tr><td>Authorization</td><td>Bearer Token</td></tr></tbody></table>

Request Body:

<table data-header-hidden><thead><tr><th width="165.00006103515625"></th><th width="114"></th><th></th></tr></thead><tbody><tr><td>Name</td><td>Type</td><td>Desc</td></tr><tr><td>bankAccount</td><td>String</td><td>STK được liên kết với thiết bị paybox</td></tr><tr><td>bankCode</td><td>String</td><td>Mã ngân hàng được liên kết với thiết bị paybox</td></tr><tr><td>amount</td><td>String</td><td>Số tiền</td></tr><tr><td>content</td><td>String</td><td>Nội dung thanh toán</td></tr><tr><td>qrCode</td><td>String</td><td>Mã QR Code cần truyền xuống thiết bị</td></tr><tr><td>terminalCode</td><td>String</td><td>Mã thiết bị (định dạng VVB)</td></tr><tr><td>serialNumber</td><td>String</td><td>Mã thiết bị (định dạng VVB)</td></tr><tr><td>orderId</td><td>String</td><td>Mã đơn hàng</td></tr><tr><td>checkSum</td><td>String</td><td>mã hóa checkSum MD5(password + bankAccount + amount + bankCode)</td></tr></tbody></table>

Response Body:

| Name    | Type   | Desc                                                  |
| ------- | ------ | ----------------------------------------------------- |
| status  | String | <p>“SUCCESS”: Thành công</p><p>“FAILED”: Thất bại</p> |
| message | String | Mã lỗi                                                |

cURL:

curl --location '<https://api.vietqr.org/vqr/api/tid/send-qr>' \\

\--header 'Content-Type: application/json' \\

\--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IllXUnRhVzR0ZG5GeUxXRmpkR2wyWlMxclpYa3RNak15Tmc9PSIsImlhdCI6MTc0NDYwNTE5MCwiZXhwIjoxNzQ0NjA1NDkwfQ.KaHnBRrmE4xQRqvLFoDN5Hlrv0olprlgW-3El-jALV8SmKK1RQuO50-1HLrAOlNfjMnFRxoMjX77Ll\_B3X2F4g' \\

\--header 'Cookie: JSESSIONID=006F5D39156747B38EB4187401E14210' \\

\--data '{

&#x20;   "bankAccount": "037356",

&#x20;   "bankCode": "MB",

&#x20;   "amount": "1000",

&#x20;   "content": "",

&#x20;   "qrCode": "123",

&#x20;   "terminalCode": "VVB407323",

&#x20;   "serialNumber": "ZSV242400203",

&#x20;   "orderId": "1234",

&#x20;   "checkSum": "0a644dad4146ddb232a2d8d619ed3b70"

}'

Response:

{

&#x20;   "status": "SUCCESS",

&#x20;   "message": ""

}

### 2 - HƯỚNG  DẪN CÁC BƯỚC KẾT NỐI

{% tabs %}
{% tab title="API Get Token" %}
curl --location --request POST '<https://api.vietqr.org/vqr/api/token\\_generate>' \\

\--header 'Authorization: Basic Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09' \\

\--header 'Cookie: JSESSIONID=8E0DE1EDE33EC191F611536DB6895898; JSESSIONID=DC4871188D95F26D481CB72C012F8F8D; JSESSIONID=F42DA5E6
{% endtab %}

{% tab title="Second Tab" %}

{% endtab %}
{% endtabs %}

<table data-header-hidden><thead><tr><th></th><th width="378.7333984375"></th><th width="139"></th><th width="180.2666015625"></th></tr></thead><tbody><tr><td>API</td><td>Import</td><td>Truyền dữ liệu</td><td>Response</td></tr><tr><td>API <sub>Get</sub> Token</td><td><p>curl --location --request POST 'https://api.vietqr.org/vqr/api/token_generate' \</p><p>--header 'Authorization: Basic Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09' \</p><p>--header 'Cookie: JSESSIONID=8E0DE1EDE33EC191F611536DB6895898; JSESSIONID=DC4871188D95F26D481CB72C012F8F8D; JSESSIONID=F42DA5E6B21EC2F3788ADE512EB6AEFF'</p></td><td>Truyền thông tin username và password do VietQR cung cấp vào Basic Auth</td><td>Token có thời hạn sử dụng là 300s (5 phút)</td></tr><tr><td>API Generate QR Code</td><td><p>curl --location 'https://api.vietqr.org/vqr/api/qr/generate-customer' \</p><p>--header 'Content-Type: application/json' \</p><p>--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGRtbGxkSEZ5ZEdWemRDMTFjMlZ5TWpRMk9BPT0iLCJpYXQiOjE3NDQ3MTMzMDksImV4cCI6MTc0NDcxMzYwOX0.cY3g8qGdBH20owYDmTfOodL_j2ieg6tcPasdEJslVt-z1dJzg6M2aZ0yuJ2dmh56O0AgHjWsu0Q9O67bmu1pgw' \</p><p>--header 'Cookie: JSESSIONID=57714DA017AF2E5EC3851BB1CE7DCDAB; JSESSIONID=023FE56A409B1D90B6860ED141EBF915; JSESSIONID=DC4871188D95F26D481CB72C012F8F8D; JSESSIONID=C3913C5A8AE870D3E7450FDBE1E36927' \</p><p>--data '{</p><p>    "amount": 99999,</p><p>    "content": "Anh Hieu Dep Trai",</p><p>    "bankAccount": "0852240768",</p><p>    "bankCode": "MB",</p><p>    "userBankName": "HA TRUNG HIEU",</p><p>    "transType": "C",</p><p>    "orderId": "Z153",</p><p>    "qrType": 0</p><p>}</p></td><td><p>Truyền token lấy được ở bước trên vào mục Header</p><p>và sửa thông tin body để tạo mã QR</p></td><td>Thông tin đầy đủ của mã QR động</td></tr><tr><td>API Push QR Pay Box</td><td><p>curl --location 'https://api.vietqr.org/vqr/api/tid/send-qr' \</p><p>--header 'Content-Type: application/json' \</p><p>--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGRtbGxkSEZ5ZEdWemRDMTFjMlZ5TWpRMk9BPT0iLCJpYXQiOjE3NDQ3MTMzMDksImV4cCI6MTc0NDcxMzYwOX0.cY3g8qGdBH20owYDmTfOodL_j2ieg6tcPasdEJslVt-z1dJzg6M2aZ0yuJ2dmh56O0AgHjWsu0Q9O67bmu1pgw' \</p><p>--header 'Cookie: JSESSIONID=006F5D39156747B38EB4187401E14210; JSESSIONID=C3913C5A8AE870D3E7450FDBE1E36927' \</p><p>--data '{</p><p>    "bankAccount": "0852240768",</p><p>    "bankCode": "MB",</p><p>    "amount": 99999,</p><p>    "content": "Anh Hieu Dep Trai",</p><p>    "qrCode": "00020101021138540010A00000072701240006970422011008522407680208QRIBFTTA53037045405999995802VN62350831VQRbc67cc3484 Anh Hieu Dep Trai6304E9A9",</p><p>    "terminalCode": "VVB567340",</p><p>    "serialNumber": "VVB567340",</p><p>    "orderId": "Z153",</p><p>    "checkSum": "8f95bb14f078099ab0001184bae0f59f"</p><p>}'</p></td><td><p>Truyền token lấy được ở bước trên vào mục Header</p><p>và sửa thông tin body để push mã QR về Pay box</p></td><td>Success</td></tr></tbody></table>

Note:&#x20;

qrCode: response API Generate QR Code

checkSum: mã hóa checkSum MD5(password + bankAccount + amount + bankCode)

[https://www.md5hashgenerator.com](https://www.md5hashgenerator.com/) web mã hóa MD5


# Cloud Sound Box Push

API GỬI SỐ TIỀN XUỐNG THIẾT BỊ VOICEBOX ĐỂ PHÁT ÂM THANH

## 1 -  API GỬI SỐ TIỀN XUỐNG THIẾT BỊ VOICEBOX

### 1.1 TỔNG QUAN

Tài liệu mô tả quy trình và cách thức sử dụng API của VietQR để gửi thông tin số tiền thanh toán xuống thiết bị Voicebox.

Tài liệu bao gồm:

* Các thức lấy token xác thực (GET TOKEN)
* Gọi API chính để truyền dữ liệu (thông tin số tiền thanh toán).

### 1.2 - LUỒNG KẾT NỐI

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FNDFDTwh8ThAQYXFIeIw5%2F%7BB80825E1-3882-4B5A-91E0-2AC5D3A32FA7%7D.png?alt=media&amp;token=34fb0173-f777-42ea-bc1b-706598ba5e23" alt=""><figcaption><p>Luồng gửi thông báo đọc âm thanh BĐSD</p></figcaption></figure>

## 2 - MÔ TẢ APIs

### 2.1 GET TOKEN

Mục đích: API này dùng để tạo Bearer Token cần thiết cho việc xác thực các yêu cầu API tiếp theo (API gửi số tiền thanh toán 2.2).

Method: POST:&#x20;

URL: <https://api.vietqr.org/vqr/api/token_generate>

Request Header:

<table data-header-hidden><thead><tr><th width="191.99993896484375"></th><th></th></tr></thead><tbody><tr><td>Name</td><td>Value</td></tr><tr><td>Content-Type</td><td>application/json</td></tr><tr><td>Authorization</td><td><p>Basic Authentication: </p><p>Base64[username:password]</p></td></tr></tbody></table>

Lưu ý: username, password sẽ do VietQR cung cấp:

Response Body:

<table data-header-hidden><thead><tr><th width="176"></th><th width="137"></th><th></th></tr></thead><tbody><tr><td>Name</td><td>Type</td><td>Desc</td></tr><tr><td>access_token</td><td>String</td><td>Là Bearer Token được VietQR cung cấp sau khi hoàn thành bước 4. Dùng để truy cập tạo mã thanh toán VietQR.</td></tr><tr><td>token_type</td><td>String</td><td>Là token dạng “Bearer”</td></tr><tr><td>expires_in</td><td>int</td><td>Thời gian hết hạn của token. Mặc định là 300 giây</td></tr></tbody></table>

{% tabs %}
{% tab title="cURL:" %}
curl --location --request POST '<https://api.vietqr.org/vqr/api/token\\_generate>' \\

\--header 'Authorization: Basic Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09'
{% endtab %}

{% tab title="Response" %}
{

&#x20;   "access\_token": "eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGRtbGxkSEZ5ZEdWemRDMTFjMlZ5TWpRMk9BPT0iLCJpYXQiOjE3MjEzNzI2MzQsImV4cCI6MTcyMTM3MjkzNH0.D19qvrpYHUgcGjDCXuXXAv3j6lZr6tfmIB0VzdCzAXMJAElGok04sNLysS6PRLdRb0hSgEX5\_9KpLjB-xErn-A",

&#x20;   "token\_type": "Bearer",

&#x20;   "expires\_in": 300

}
{% endtab %}
{% endtabs %}

### 2.2 GỬI THÔNG TIN SỐ TIỀN XUỐNG THIẾT BỊ

Mục đích: API này dùng để truyền thông tin số tiền cần thanh toán xuống thiết bị Voicebox để thiết bị đọc thông báo bằng giọng nói.

Method: POST <https://api.vietqr.org/vqr/api/tid/callback/event/payment>

Request Header:   Request Body

<table data-header-hidden><thead><tr><th width="175"></th><th width="118"></th><th></th></tr></thead><tbody><tr><td>Name</td><td>Type</td><td>Desc</td></tr><tr><td>amount</td><td>long</td><td>Số tiền</td></tr><tr><td>language</td><td>String</td><td>Ngôn ngữ (Mặc định: VN)</td></tr><tr><td>currency</td><td>String</td><td>Đơn vị tiền tệ (Mặc định: VND)</td></tr><tr><td>serialNumber</td><td>String</td><td>Mã serial Number của máy</td></tr><tr><td>referenceNumber</td><td>String</td><td>Mã giao dịch duy nhất</td></tr><tr><td>checkSum</td><td>String</td><td>mã hóa checkSum MD5(username + amount + referenceNumber + serialNumber)</td></tr></tbody></table>

Response Body:

| Name    | Type   | Desc                                                  |
| ------- | ------ | ----------------------------------------------------- |
| status  | String | <p>“SUCCESS”: Thành công</p><p>“FAILED”: Thất bại</p> |
| message | String | Mã lỗi                                                |

Thông tin cURL:

```json
curl --location 'https://api.vietqr.org/vqr/api/vnpt-epay/callback' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9' \
--header 'Cookie: JSESSIONID=349BED123B39E6FF3D30630E85E46C85' \
--data '{
    "amount": 8000,
    "language": "VN",
    "currency": "VND",
    "referenceNumber": "FT25132940673006",
    "serialNumber": "BT37878837",
    "checkSum": "cee74d89030f6190afea4da84fb41fe5"
}'
```

Response:

{

&#x20;   "status": "SUCCESS",

&#x20;   "message": ""

}

(Link tài liệu [tại đây](https://docs.google.com/document/d/12Ywi81VAaO8-0iy8dtMm2m1QFXDsbHbiD1jEPWtMPU8/edit?tab=t.0))

\---------------------------------------------------

## HƯỚNG DẪN THỰC HÀNH DÙNG POSHMAN PUSH

### Bước 1 : GET TOKEN

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2F6v8yWSwQQgQ8koUoIGl4%2Fimage.png?alt=media&amp;token=43041e85-7a3d-4088-a267-4bd6be9a206f" alt=""><figcaption><p>Lấy Token</p></figcaption></figure>

### Bước 2 : PUSH ÂM THANH VÀ SỐ TIỀN THÀNH CÔNG XUỐNG THIẾT BỊ :&#x20;

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FQCxU0AIpMXrae52wAi5N%2Fimage.png?alt=media&amp;token=3e5e5908-4804-44ab-a992-ea72b80a4d0a" alt=""><figcaption></figcaption></figure>


# VietQR Refund APIs

Mô tả yêu cầu nghiệp vụ và quy trình tích hợp cho bộ API Services dịch vụ hoàn tiền VietQR.

### Mô tả

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FZZntapbUzT3349NWUrC2%2FProcess%20Map%20Refund%20API.png?alt=media&amp;token=9784a21e-2c52-44c7-8d17-abef2204d3e3" alt=""><figcaption></figcaption></figure>

**Dịch vụ hoàn tiền qua VietQR hoạt động theo các bước sau:**

1. Khách hàng đã tích hợp xong dịch vụ [VietQR Payment APIs](/vi/api-vietqr-callback).
2. Yêu cầu VietQR cấp `secretKey` để dùng dịch vụ hoàn tiền.
3. Gọi [API Check Transaction](/vi/cac-dich-vu-api-khac/vietqr-refund-apis/goi-api-check-transaction) để kiểm tra và khởi tạo giao dịch cần hoàn tiền.
4. Gọi [API Refund](/vi/cac-dich-vu-api-khac/vietqr-refund-apis/goi-api-refund) để thực hiện hoàn tiền.

***

### Quy định về quy trình kết nối

Đối tác cần tuân thủ theo quy trình kết nối dịch vụ để đảm bảo hệ thống vận hành một cách hiệu quả nhất, giảm thiểu rủi ro không mong muốn. (Tham khảo quy trình tích hợp [VietQR Payment API](/vi/api-vietqr-callback))


# Gọi API Check Transaction

Dùng để tra soát thông tin các giao dịch đã thực hiện.

### <mark style="color:green;">`POST`</mark>

```
https://<vietqr-host>/<basepath>/api/transactions/check-order
```

**Headers**

| Name          | Value                                                          |
| ------------- | -------------------------------------------------------------- |
| Content-Type  | `application/json`                                             |
| Authorization | Bearer \<token> Bạn nhận được khi gọi API Get Token của VietQR |

**Body**

<table data-full-width="false"><thead><tr><th width="187">Name</th><th width="92">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>bankAccount</code></td><td>String</td><td>Yes</td><td>Số tài khoản ngân hàng.</td></tr><tr><td><code>type</code></td><td>String</td><td>Yes</td><td>Check by <code>orderId</code>: 0<br>Check by <code>referenceNumber</code>: 1</td></tr><tr><td><code>value</code></td><td>String</td><td>Yes</td><td>Giá trị là<code>orderId</code> nếu <code>type</code> = 0<br>Giá trị là<code>referenceNumber</code> nếu <code>type</code> = 1</td></tr><tr><td><code>checkSum</code></td><td>String</td><td>Yes</td><td><p>Chuỗi mã hóa MD5 của tổ hợp:</p><p>(<code>bankAccount</code> + <code>username</code>)</p></td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
[
    {
        "referenceNumber": "mã_giao_dịch",
        "orderId": "mã_đơn_hàng",
        "amount": số_tiền_giao_dịch,
        "content": "nội_dung_thanh_toán",
        "transType": "giao_dịch_đến_hoặc_đi",
        "status": phân_loại_trạng_thái_giao_dịch_theo_số,
        "type": phân_loại_giao_dịch_theo_số,
        "timeCreated": tem_thời_gian_tạo_mã_QR,
        "timePaid": tem_thời_gian_thanh_toán,
        "terminalCode": "mã_điểm_bán",
        "note": "ghi_chú_giao_dịch",
        "refundCount": số_lần_đã_hoàn_tiền_thuộc_giao_dịch_này,
        "amountRefunded": số_tiền_đã_hoàn_tiền_thuộc_giao_dịch_này
    }
]
```

{% hint style="info" %}
Giá trị trả về của `type`:

* 0: Giao dịch từ mã VietQR động.
* 1: Giao dịch từ mã VietQR tĩnh.
* 2: Giao dịch ngoài hệ thống VietQR.
* 3: Giao dịch từ mã VietQR bán động.
  {% endhint %}

{% hint style="info" %}
Giá trị trả về của `status`:

* 0: Giao dịch chờ thanh toán.
* 1: Giao dịch đã thanh toán.
* 2: Giao dịch hết hạn thanh toán.
  {% endhint %}
  {% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://api.vietqr.org/vqr/api/transactions/check-order' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=F40E5CBDEEB02F82DF40BAD476A6222B' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIxMzc2MzQ2LCJleHAiOjE3MjEzNzY2NDZ9.QfnN8-p79uB8w5rTRmuOBoANrku276Jtzd7osltE9-E1zQfiXo0YlGCiX1cOHe4A0_VRWJPC5s0tymhND2kGnQ' \
--data '{
    "bankAccount": "tài_khoản_ngân_hàng",
    "type": "loại_check_giao_dịch: 0: mã_đơn_hàng, 1: mã_giao_dịch",
    "value": "giá_trị_cần_check",
    "checkSum": "HASH MD5 128 bit của: bankAccount + username"
    }'

```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp

<details>

<summary>API Check Transaction dùng để làm gì?</summary>

API này được sử dụng để kiểm tra trạng thái của một giao dịch cụ thể trước khi thực hiện các thao tác tiếp theo như hoàn tiền.

</details>

<details>

<summary><code>checkSum</code> là gì và tại sao nó quan trọng?</summary>

`checkSum` là một chuỗi mã hóa MD5 128 bit của các giá trị `bankAccount` và `username`, đảm bảo tính toàn vẹn và bảo mật của yêu cầu. Nó giúp xác thực rằng dữ liệu không bị thay đổi trong quá trình truyền.

</details>

<details>

<summary>Nếu API Check Transaction trả về trạng thái "FAILED", điều đó có nghĩa là gì?</summary>

Trạng thái "FAILED" có thể chỉ ra rằng mã giao dịch hoặc mã đơn hàng không hợp lệ, hoặc giao dịch đã bị hủy. Bạn nên kiểm tra lại các thông tin đầu vào hoặc liên hệ với bộ phận hỗ trợ.

</details>

<details>

<summary>Làm thế nào để xử lý các lỗi phổ biến khi sử dụng API Check Transaction?</summary>

* Một số lỗi phổ biến bao gồm:
  * Sai thông tin đầu vào (`bankAccount`, `value`, hoặc `checkSum` không chính xác).
  * Token hết hạn hoặc không hợp lệ.
  * Kết nối không thành công.
* Đảm bảo rằng bạn đã kiểm tra kỹ các thông tin và token trước khi gọi API.

</details>

<details>

<summary>Tôi có thể kiểm tra trạng thái của bất kỳ giao dịch nào bằng API này không?</summary>

Bạn chỉ có thể kiểm tra trạng thái của các giao dịch đã thực hiện qua hệ thống VietQR và phải cung cấp thông tin chính xác tương ứng với mã giao dịch hoặc mã đơn hàng.

</details>


# Gọi API Refund

API Refund cho phép đối tác thực hiện hoàn tiền cho các giao dịch đã được thanh toán qua mã VietQR.

### <mark style="color:green;">`POST`</mark>

```
https://<vietqr-host>/<basepath>/api/transaction/refund
```

**Headers**

<table><thead><tr><th width="214">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td><code>Bearer &#x3C;token></code></td></tr></tbody></table>

**Body**

<table data-full-width="false"><thead><tr><th width="200">Name</th><th width="93">Type</th><th width="101">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>bankAccount</code></td><td>String</td><td>Yes</td><td>TK ngân hàng của đối tác.</td></tr><tr><td><code>referenceNumber</code></td><td>String</td><td>Yes</td><td>Mã giao dịch (GD TT đang cần hoàn tiền).</td></tr><tr><td><code>amount</code></td><td>String</td><td>Yes</td><td>Số tiền cần hoàn tiền cho KH của đối tác.</td></tr><tr><td><code>content</code></td><td>String</td><td>Yes</td><td>Nội dung hoàn tiền.</td></tr><tr><td><code>checkSum</code></td><td>String</td><td>Yes</td><td><p>Chuỗi mã hóa MD5 các tham số: (<strong><code>secretKey</code></strong>+<strong><code>referenceNumber</code></strong>+</p><p><strong><code>amount</code></strong> + <strong><code>bankAccount)</code></strong></p></td></tr><tr><td><code>multiTimes</code></td><td>Boolean</td><td>Optional</td><td><p>Cho phép hoàn tiền nhiều lần.</p><p>Chỉ có thể chọn vào lần hoàn tiền đầu tiên.</p></td></tr><tr><td><code>bankCode</code></td><td>String</td><td>Yes</td><td>Tên viết tắt của ngân hàng.</td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng/điểm bán.</td></tr><tr><td><code>subTerminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng phụ/điểm bán phụ.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "status": "SUCCESS",
    "message": "mã_giao_dịch"
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://api.vietqr.org/vqr/api/transaction/refund' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=F40E5CBDEEB02F82DF40BAD476A6222B' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIxMjk3NjAxLCJleHAiOjE3MjEyOTc5MDF9.SEy2kqjhNup2UVaKhldXZQ1bVJn6o69LxgF9r0yA7zBqJWC5n9PhFUYk3G_oBsmCrAbobMohNHzJRsgqbwsUUA' \
--data '{
    "bankCode": "mã_ngân_hàng",
    "bankAccount": "tài_khoản_ngân_hàng_đồng_bộ",
    "referenceNumber": "mã_giao_dịch_đã_thanh_toán_cần_hoàn_tiền",
    "amount": "số_tiền_được_hoàn",
    "content": "nội_dung_hoàn_tiền",
    "multiTimes": "true: cho_phép_hoàn_tiền_nhiều_lần",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "checkSum": "HASH MD5 128 bit: secret_key_do_vietqr_cung_cấp + referenceNumber + amount + bankAccount"
}'

```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp

<details>

<summary><strong><code>secretKey</code></strong> tôi phải lấy ở đâu?</summary>

Sau khi bạn tích hợp xong dịch vụ thanh toán qua mã VietQR, hãy liên hệ đến bộ phận kỹ thuật của VietQR để được cấp **`secretKey`**.

</details>

<details>

<summary>API Refund hỗ trợ những loại giao dịch nào?</summary>

API Refund chỉ hỗ trợ hoàn tiền cho các giao dịch đã thanh toán qua mã VietQR và còn hiệu lực.

</details>

<details>

<summary>Làm thế nào để kiểm tra trạng thái hoàn tiền?</summary>

Bạn có thể kiểm tra trạng thái của yêu cầu hoàn tiền bằng cách gọi lại API `Check Transaction` với mã giao dịch hoặc mã đơn hàng.

</details>

<details>

<summary>Có giới hạn về số lần hoàn tiền cho một giao dịch không?</summary>

Tùy thuộc vào chính sách của VietQR và cấu hình của bạn, có thể có giới hạn về số lần hoàn tiền cho một giao dịch cụ thể.

</details>


# Chú ý đối với refund

Chú ý về các giao dịch Refund

Lưu ý:&#x20;

Khi hoàn tiền cho khách hàng thanh toán qua Ví điện tử Momo hoặc ZaloPay, cần thông báo rằng tiền hoàn sẽ không được nhận ngay lập tức. Khách hàng sẽ phải chờ ví điện tử xử lý và chuyển lại tiền.&#x20;

Để quá trình nhanh hơn, khách hàng có thể liên hệ trực tiếp với ví điện tử của mình để yêu cầu ghi có nhanh. Đối với các khoản hoàn qua ngân hàng, ngân hàng đã hoàn tất việc chuyển tiền, chỉ còn chờ ví điện tử trả lại cho khách hàng.


# API Host to Device (MQTTs)

Mô tả quy trình tích hợp bộ dịch vụ thanh toán qua mã VietQR sử dụng giao thức MQTT để truyền thông tin giao dịch đến hệ thống khác .

### Mô tả

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FxfgwtvifoL4xBZCNXMVR%2FProcess%20Map.png?alt=media&amp;token=71712063-546f-4bd5-8c33-2a41ad31f635" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FxByQKXVln5wlII7Php3F%2Fimage.png?alt=media&amp;token=b3a186db-9227-4d5e-8a0f-87215b83fc69" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Đối tác cần hoàn tất quá trình đăng ký tài khoản với đầy đủ thông tin nhằm định danh và bảo mật tài khoản. Thông tin tích hợp mặc định sẽ là môi trường Test (Sandbox).
{% endhint %}

**Các bước cơ bản để tích hợp với VietQR:**

1. Liên kết với VietQR.
2. Thiết lập và kết nối với VIetQR MQTTs.
3. Đối tác triển khai trước MQTT nhận Biến Động Số Dư.
4. Đối tác triển khai MQTT yêu cầu tạo mã thanh toán VietQR.
5. Đối tác triển khai MQTT nhận phản hồi thanh toán VietQR.
6. Đối tác triển khai MQTT giả lập thanh toán thành công (Áp dụng bước này đối với môi trường Test).
7. Nghiệm thu và yêu cầu GoLive trên môi trường sản xuất.

***

### Thông số kết nối

| Param          | Type   | Description                                                                         |
| -------------- | ------ | ----------------------------------------------------------------------------------- |
| Broker         | String | Địa chỉ của broker để **publishers** và **subscribers** kết nối                     |
| Username       | String | Tên đăng nhập để xác thực với broker (nếu có).                                      |
| Password       | String | Mật khẩu đăng nhập để xác thực với broker (nếu có).                                 |
| Topic request  | String | Topic để **publishers** gửi yêu cầu.                                                |
| Topic response | String | Topic để **publishers** gửi phản hồi lại cho **subscribers** sau khi xử lý yêu cầu. |

{% hint style="success" %}
**Thông số kết nối sẽ được VietQr cung cấp cho đối tác.**
{% endhint %}

{% hint style="info" %}
**Publishers** : Là các thực thể (thiết bị, ứng dụng) gửi dữ liệu hoặc thông điệp lên một topic cụ thể trên broker. Publishers không cần biết đến các subscribers (người nhận) mà chỉ cần gửi thông điệp lên topic.
{% endhint %}

{% hint style="info" %}
**Subscribers** : Là các thực thể đăng ký nhận thông điệp từ một hoặc nhiều topics trên broker. Khi có một thông điệp mới được gửi lên topic mà họ đã đăng ký, broker sẽ chuyển tiếp thông điệp đó đến subscribers.
{% endhint %}

***


# Thiết lập và kết nối

Hướng dẫn các bước thiết lập và kết nối dịch vụ thanh toán luồng MQTT.

### Bước 1: Cài đặt ứng dụng hỗ trợ MQTT

Bạn cần một ứng dụng hoặc phần mềm hỗ trợ giao thức MQTT để kết nối với hệ thống. Một số ứng dụng phổ biến mà bạn có thể tải về như:

* MQTTBox (cho máy tính)
* MQTT cho thiết bị thanh toán
* MQTT Dashboard (cho điện thoại Android hoặc iOS)

### Bước 2: Nhận thông tin từ VietQR

Sau khi đăng ký sử dụng dịch vụ, bạn sẽ nhận được các thông tin cần thiết từ VietQR, bao gồm:

* Địa chỉ kết nối (Broker): Đây là địa chỉ của hệ thống VietQR mà bạn cần kết nối để thực hiện các giao dịch.
* Tên đăng nhập và mật khẩu: Bạn sẽ dùng thông tin này để đăng nhập vào hệ thống.

{% hint style="success" %}
Nếu bạn chưa có thông tin này, hãy liên hệ với bộ phận hỗ trợ của VietQR.
{% endhint %}

### **Bước 3: Cấu hình kết nối với hệ thống**

Mở ứng dụng MQTT mà bạn đã cài đặt và thực hiện các bước kết nối với hệ thống VietQR bằng cách nhập các thông tin mà VietQR cung cấp như:

* Broker: Địa chỉ máy chủ kết nối VietQR (được cung cấp).
* Username và Password: Thông tin đăng nhập VietQR (được cung cấp).


# MQTT Nhận Biến Động Số Dư

Nhận biến động số dư sau khi thực hiện giao dịch.

### <mark style="color:green;">`MQTT`</mark> Transaction Alerts <a href="#get-token" id="get-token"></a>

```
mqtt://<vietqr-port>/vietqr/bdsd/{terminalCode}
```

**Message**

<table><thead><tr><th width="207">Param</th><th width="131">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>bankAccount</code></td><td>String</td><td>Số tài khoản nhận tiền</td></tr><tr><td><code>amount</code></td><td>Long</td><td>Số tiền nhận</td></tr><tr><td><code>transType</code></td><td>String</td><td>Loại giao dịch</td></tr><tr><td><code>referenceNumber</code></td><td>String</td><td>Mã tham chiếu</td></tr><tr><td><code>orderId</code></td><td>String</td><td>Mã đơn hàng</td></tr><tr><td><code>content</code></td><td>String</td><td>Nội dung chuyển tiền</td></tr><tr><td><code>status</code></td><td>String</td><td>Trạng thái chuyển tiền</td></tr><tr><td><code>timePaid</code></td><td>String</td><td>Thời gian thanh toán</td></tr></tbody></table>

### Code mẫu

{% tabs %}
{% tab title="Message" %}

```
{
  "bankAccount": "9876543210",
  "amount": 25000.0,
  "timePaid": "01/09/2024 14:30:00",
  "transType": "C",
  "referenceNumber": "TXN876543210123",
  "content": "SampleTransaction Payment",
  "status": 1
}
```

{% endtab %}
{% endtabs %}

***


# MQTT Tạo Mã Thanh Toán VietQR

Từ thông tin nhận được, thực hiện tạo mã thanh toán VietQR cho giao dịch.

### <mark style="color:green;">`MQTT`</mark> **Request** Generate VietQR Code <a href="#get-token" id="get-token"></a>

```
mqtt://<vietqr-port>/vietqr/request/{terminalCode}
```

**Message**

<table><thead><tr><th width="209">Param</th><th width="134">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>amount</code></td><td>Long</td><td>Số tiền nhận.</td></tr><tr><td><code>content</code></td><td>String</td><td>Nội dung chuyển tiền.</td></tr><tr><td><code>bankAccount</code></td><td>String</td><td>Số tài khoản nhận tiền.</td></tr><tr><td><code>bankCode</code></td><td>String</td><td>Mã ngân hàng.</td></tr><tr><td><code>userBankName</code></td><td>String</td><td>Tên chủ tài khoản ngân hàng.</td></tr><tr><td><code>transType</code></td><td>String</td><td>Loại giao dịch.</td></tr><tr><td><code>orderId</code></td><td>String</td><td>Mã đơn hàng.</td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Mã điểm bán hoặc mã cửa hàng</td></tr><tr><td><code>serviceCode</code></td><td>String</td><td>Mã sản phẩm.</td></tr><tr><td><code>additionalData</code></td><td>List&#x3C;Object></td><td>Thông tin thêm của đối tác muốn lưu trữ kèm giao dịch.</td></tr></tbody></table>

### Code mẫu

{% tabs %}
{% tab title="Message" %}

```
{
  "amount": 15000,
  "content": "PaymentForOrder",
  "bankAccount": "1234567890",
  "bankCode": "MB",
  "userBankName": "ABC Corporation",
  "transType": "C",
  "orderId": "ORD12345XYZ",
  "terminalCode": "987",
  "serviceCode": "SVC001",
  "additionalData": [
    {
      "info": "AdditionalInfo1"
    }
  ]
}
```

{% endtab %}
{% endtabs %}

***


# MQTT Nhận Mã Thanh Toán VietQR

Gửi phản hồi lại cho MQTT Generate VietQR Code đã tạo và các thông tin liên quan.

### <mark style="color:green;">`MQTT`</mark> **Request** Generate VietQR Code <a href="#get-token" id="get-token"></a>

```
mqtt://<vietqr-port>/vietqr/response/{terminalCode}
```

**Message**

<table><thead><tr><th width="212">Param</th><th width="133">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>bankCode</code></td><td>String</td><td>Mã ngân hàng.</td></tr><tr><td><code>bankName</code></td><td>String</td><td>Tên của ngân hàng</td></tr><tr><td><code>bankAccount</code></td><td>String</td><td>Số tài khoản nhận tiền</td></tr><tr><td><code>userBankName</code></td><td>String</td><td>Tên chủ tài khoản ngân hàng</td></tr><tr><td><code>amount</code></td><td>Long</td><td>Số tiền nhận</td></tr><tr><td><code>content</code></td><td>String</td><td>Nội dung chuyển tiền</td></tr><tr><td><code>qrCode</code></td><td>String</td><td>Mã QR</td></tr><tr><td><code>orderId</code></td><td>String</td><td>Mã đơn hàng</td></tr><tr><td><code>imgId</code></td><td>String</td><td>Hình ảnh qrCode</td></tr><tr><td><code>existing</code></td><td>String</td><td>Có tồn tại trong hệ thống VietQR</td></tr><tr><td><code>transactionId</code></td><td>String</td><td>Id của giao dịch</td></tr><tr><td><code>transactionRefId</code></td><td>String</td><td>Mã tham chiếu giao dịch</td></tr><tr><td><code>qrLink</code></td><td>String</td><td>Đường link hiện qrCode</td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Mã điểm bán hoặc mã cửa hàng</td></tr><tr><td><code>serviceCode</code></td><td>String</td><td>Mã sản phẩm</td></tr><tr><td><code>additionalData</code></td><td>List&#x3C;Object></td><td>Thông tin thêm của đối tác muốn lưu trữ kèm giao dịch</td></tr></tbody></table>

### Code mẫu

{% tabs %}
{% tab title="Message" %}

```
{
  "bankCode": "MB",
  "bankName": "MB Bank",
  "bankAccount": "1234567890",
  "userBankName": "XYZ Ltd",
  "amount": "50000",
  "content": "SampleTransactionDescription",
  "qrCode": "00020101021138540010A00000072701240006970422011012345678900208QRIBFTTA53037045405200005802VN62350831SampleTransactionDescription6304AAB8",
  "imgId": "abcd1234-5678-90ef-ghij-klmn01234567",
  "existing": 1,
  "transactionId": "",
  "transactionRefId": "ABC1234567890XYZ",
  "qrLink": "https://vietqr.vn/test/qr-generated?token=ABC1234567890XYZ",
  "terminalCode": "987",
  "serviceCode": "SVC002",
  "additionalData": [
    {
      "info": "AdditionalInfo1"
    }
  ]
}
```

{% endtab %}
{% endtabs %}

***


# MQTT Giả Lập Thanh Toán

Bước này được áp dụng đối với quá trình kiểm thử trên môi trường TEST. Khách hàng không cần thanh toán thật trong quá trình kiểm thử.

{% hint style="info" %}
Chúng tôi đang bảo trì để cập nhật MQTT này, trong lúc chờ đợi, quý khách hàng và đối tác có thể liên hệ chúng tôi để thao tác bước này nhé.
{% endhint %}


# MQTT Tra Cứu Thông Tin Giao Dịch

Tra cứu thông tin giao dịch

### <mark style="color:green;">`MQTT`</mark> Request Check Transaction <a href="#get-token" id="get-token"></a>

```
mqtt://<vietqr-port>/vietqr/request-status/{terminalCode}
```

**Message**

<table><thead><tr><th width="171">Param</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>bankAccount</code></td><td>String</td><td>Số tài khoản nhận tiền</td></tr><tr><td><code>type</code></td><td>int</td><td>Loại kiểm tra (0: kiểm tra theo OrderId, 1: kiểm tra theo ReferenceNumber).</td></tr><tr><td><code>value</code></td><td>String</td><td>Giá trị cần kiểm tra (OrderId hoặc referenceNumber)</td></tr><tr><td><code>checkSum</code></td><td>String</td><td>Mã kiểm tra bảo mật được tạo từ bankAccount và userBankName.</td></tr></tbody></table>

**Note**&#x20;

{% hint style="success" %}
&#x20;"***checkSum***" sẽ do bên khách hàng cung cấp .

\- Kết hợp bankAccount và userBankName thành một chuỗi duy nhất

\- Mã hóa chuỗi đó bằng thuật toán MD5.

\- Mã MD5 sẽ được sử dụng làm ***checksum***.
{% endhint %}

### Code mẫu

{% tabs %}
{% tab title="Message" %}

```
{
  "bankAccount": "1234567890",
  "type": 0,
  "value": "ORD98765XYZ",
  "checkSum": "abc1234567890def1234567890abcdef"
}
```

{% endtab %}
{% endtabs %}

***


# MQTT Phản Hồi Tra Cứu Thông Tin

Nhận phản hồi sau khi gửi yêu cầu kiểm tra trạng thái giao dịch

### <mark style="color:green;">`MQTT`</mark> Response Check Transaction <a href="#get-token" id="get-token"></a>

```
mqtt://<vietqr-port>/vietqr/response-status/{terminalCode}
```

**Message**

<table><thead><tr><th width="204">Param</th><th width="113">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>referenceNumber</code></td><td>String</td><td>Mã tham chiếu giao dịch</td></tr><tr><td><code>orderId</code></td><td>String</td><td>Mã đơn hàng.</td></tr><tr><td><code>amount</code></td><td>Long</td><td>Số tiền giao dịch</td></tr><tr><td><code>content</code></td><td>String</td><td>Nội dung giao dịch</td></tr><tr><td><code>transType</code></td><td>String</td><td>Số tiền giao dịch</td></tr><tr><td><code>status</code></td><td>int</td><td>Trạng thái giao dịch</td></tr><tr><td><code>type</code></td><td>int</td><td>Loại kiểm tra</td></tr><tr><td><code>timeCreated</code></td><td>Long</td><td>Thời gian tạo giao dịch</td></tr><tr><td><code>timePaid</code></td><td>Long</td><td>Thời gian thanh toán giao dịch</td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Mã điểm bán hoặc mã cửa hàng</td></tr><tr><td><code>note</code></td><td>String</td><td>Ghi chú</td></tr><tr><td><code>refundCount</code></td><td>int</td><td>Số lần hoàn tiền</td></tr><tr><td><code>amountRefunded</code></td><td>int</td><td>Số tiền đã hoàn lại</td></tr></tbody></table>

**Note**&#x20;

{% hint style="info" %}
**status**:

* 0: Giao dịch đang chờ thanh toán
* 1: Giao dịch thành công
* 2: Giao dịch đã hủy
  {% endhint %}

{% hint style="info" %}
**type**:

* 0: Kiểm tra theo Mã đơn hàng
* 1: Kiểm tra theo Mã tham chiếu giao dịch
  {% endhint %}

{% hint style="info" %}
**transType**:

* "C": Giao dịch đến
* "D": Giao dịch đi
  {% endhint %}

### Code mẫu

{% tabs %}
{% tab title="Message" %}

```
{
  "referenceNumber": "TXN123456789012",
  "orderId": "ORD98765XYZ",
  "amount": 25000,
  "content": "SampleProductPurchase",
  "transType": "C",
  "status": 1,
  "type": 0,
  "timeCreated": 1623039658,
  "timePaid": 1623039685,
  "terminalCode": "",
  "note": "",
  "refundCount": 0,
  "amountRefunded": 0
}
```

{% endtab %}
{% endtabs %}

***


# Tài liệu đồng bộ mã điểm bán MQTT

Tài liệu đồng bộ mã điểm bán MQTT

1.Mục Đích

Hướng dẫn tích hợp tính năng tạo và sử dụng mã QR cho các giao dịch qua

VietQR, sử dụng giao thức MQTT để truyền tải thông tin giao dịch nhận thông

báo thay đổi số dư (BDSD) và kiểm tra trạng thái giao dịch.

2\. Giới Thiệu

VietQR cung cấp khả năng tạo mã QR cho các giao dịch thanh toán sử dụng

giao thức MQTT để truyền thông tin mã QR đến hệ thống khác.

VietQR cung cấp dịch vụ nhận thông báo biến động số dư (BĐSD) cho các thiết

bị hỗ trợ kết nối giao thức MQTT (IoT).

3\. Thiết Lập Kết Nối MQTT

3.2. Thông Số Kết Nối

Param Type Description

Broker String

Địa chỉ của broker để

publishers và subscribers kết

nối

Username String Tên đăng nhập để xác thực với

broker (nếu có).

Password String Mật khẩu đăng nhập để xác

thực với broker (nếu có).

Topic request String Topic để publishers gửi yêu

cầu.

Topic response String

Topic để publishers gửi phản

hồi lại cho subscribers sau

khi xử lý yêu cầu.secretKey String Khóa bí mật do VietQR cung

cấp

\- Thông số kết nối sẽ được VietQr cung cấp cho đối tác.

\- Note:

\- Publishers : Là các thực thể (thiết bị, ứng dụng) gửi dữ liệu hoặc thông

điệp lên một topic cụ thể trên broker. Publishers không cần biết đến các

subscribers (người nhận) mà chỉ cần gửi thông điệp lên topic.

\- Subscribers : Là các thực thể đăng ký nhận thông điệp từ một hoặc nhiều

topics trên broker. Khi có một thông điệp mới được gửi lên topic mà họ đã đăng

ký, broker sẽ chuyển tiếp thông điệp đó đến subscribers.

3.2. Các Topic

● Topic yêu đồng bộ điểm bán: /vqr/handle-box

● Topic phản hồi dữ liệu đồng bộ điểm bán: /vqr/handle-

box/response/{macAddr}

● Topic nhận dữ liệu sau khi đồng bộ điểm bán: vietqr/boxId/{boxId}

● Topic yêu cầu Tạo mã Qr: vietqr/request/{terminalCode}

● Topic phản hồi mã Qr: vietqr/response/{terminalCode}

● Topic Thông báo BDSD: vietqr/bdsd/{terminalCode}

● Topic kiểm tra trạng thái giao dịch: vietqr/request-status/#

● Topic phản hồi trạng thái giao dịch:vietqr/response-status/#

● Topic yêu cầu refund: vietqr/refund-request/#

● Topic phản hồi nhận message refund: vietqr/refund-response/#

4\. MQTT VÀ CÁC BƯỚC THỰC HIỆN VIỆC ĐỒNG BỘ

4.1. MQTT yêu cầu đồng bộ thiết bị:

○ Mô tả : Thiết bị sử dụng các thông tin cơ bản như macAddr, IMEI,

serialNumber,… để yêu cầu đồng bộ điểm bán với hệ thống

VietQR. Sau khi gửi yêu cầu động bộ sẽ nhận response ở mục 4.2.

○ MQTT topic: /vqr/handle-box

○ Example request: Chi tiết xem mục 5.6

○ Message:Param Type Required Description

macAddr String Yes Địa chỉ MAC hoặc

IMEI thiết bị

serialNumber String No Số định danh serial của

thiết bị

secretKey String Yes Khóa bí mật do VietQR

cung cấp

checkSum String Yes

Chuỗi mã hóa

checkSum MD5:

macAddr +

“VietQRBoxAccessKey

”

4.2. MQTT phản hồi dữ liệu đồng bộ thiết bị:

○ Mô tả : Sau khi gửi yêu cầu đồng bộ dữ liệu từ mục 4.1 thì dữ liệu

sẽ được trả về bởi topic ở dưới đây.

○ MQTT topic: /vqr/handle-box/response/{macAddr}

○ Example response: Chi tiết xem mục 5.7

○ Message:

Param Type Description

qrCertificate String

QR Certificate dùng để active

và đồng bộ bằng VietQR

(không thay đổi nếu cùng địa

chỉ MAC, IMEI đã được đồng

bộ với hệ thống)

boxId String

boxId dùng để đăng ký nhận

message sau khi đồng bộ TK

ngân hàng thành công với hệ

thống VietQR (không thay đổi

nếu cùng địa chỉ MAC, IMEI

đã được đồng bộ với hệ thống)- Sau khi có kết quả message trả về. Sử dụng giá trị của field

“qrCertificate” để hiển thị trên máy box có màn hình dưới dạng mã QR

để thuận tiện cho việc active bằng app VietQR, đối với các thiết bị không

có màn hình VietQR sẽ hỗ trợ nhập liệu bằng số serinalNumber của máy

hoặc địa chỉ MAC.

\- Giả lập thiết bị: nhập kết quả qrCertificate vào web <https://vi.qr-code->

generator.com/.

\- Đăng ký hoặc đăng nhập TK VietQR bằng cách sử dụng app VietQR:

\+ Android:

<https://play.google.com/store/apps/details?id=com.vietqr.product&>

pcampaignid=web\_share

\+ IOS: <https://apps.apple.com/us/app/vietqr-vn/id6447118484>

\- Liên kết TK ngân hàng với app VietQR để nhận BĐSD (MB, BIDV)

\- Thực hiện quét mã QR và chọn hoặc tạo thông tin doanh nghiệp, cửa

hàng, ngân hàng đã liên kết để nhận biến động số dư và tạo mã QR.

\- Nhấn xác nhận

\- Hệ thống VietQR sẽ gửi thông tin đồng bộ thành công xuống thiết bị

thông qua giao thức MQTT.

\- Khi cần thay đổi thông tin TK ngân hàng, yêu cầu thiết bị có thể reset về

lại nguyên trạng sau khi nhận phản hồi đồng bộ thiết bị (qrCertificate,

boxId,...) thực hiện bước 4.1 và 4.2 một lần.

4.3. MQTT nhận dữ liệu sau khi thực hiện active thiết bị:

○ Mô tả :

\- Sau khi nhận được dữ liệu từ mục 4.2, sử dụng giá trị {boxId} để

đăng ký nhận dữ liệu sau khi thực hiện việc quét mã và nhấn xác

nhận đồng bộ thành công qrCertificate ở mục 4.2.

\- Khi active lại, thiết bị cần xóa các dữ liệu cũ và ghi đè bởi dữ liệu

mới gửi từ hệ thống

○ MQTT topic: vietqr/boxId/{boxId} - không có dấu “/” ở đầu

○ Example response: Chi tiết xem mục 5.8

○ Message:

Param Type DescriptionnotificationType String Loại thông báo active thiết bị

thành công (“N”)

bankAccount String Tài khoản ngân hàng để tạo

mã QR hoặc nhận BĐSD

bankShortName String Ngân hàng khách hàng đã

đăng ký

userBankName String Tên chủ tài khoản ngân hàng

terminalCode String Mã điểm bán/cửa hàng

terminalName String Tên điểm bán/cửa hàng

qrCode String mã QR tĩnh dùng để thanh

toán và nhận BĐSD

bankCode String Mã ngân hàng sử dụng để tạo

mã VietQR.(Ví dụ: MB)

imgBank String Mã định danh hình ảnh của

ngân hàng

homePage String Trang chủ vietqr

4.4. MQTT tạo mã QR động - QR có gán số tiền và nội dung thanh

toán (bỏ qua đối với thiết bị voice box):

○ Mô tả : Từ thông tin nhận được, thực hiện tạo mã QR cho giao

dịch. Mã QR bao gồm các thông tin như số tài khoản, số tiền, nội

dung thanh toán, số tài khoản người nhận , mã ngân hàng , tên chủ

tài khoản , loại giao dịch, mã đơn hàng, mã điểm bán(mã cửa

hàng), mã sản phẩm.

○ MQTT: mqtt://api.vietqr.org/vietqr/request/{terminalCode}○ Message:

Param Type Description

amount Long Số tiền nhận

content String Nội dung chuyển tiền

bankAccount String Số tài khoản nhận tiền

bankCode String Mã ngân hàng .(Ví dụ: MB)

userBankName String Tên chủ tài khoản ngân hàng

transType String Loại giao dịch

orderId String Mã đơn hàng

terminalCode String Mã điểm bán hoặc mã cửa

hàng

serviceCode String Mã sản phẩm

additionalData List\<Object> Thông tin thêm của đối tác

muốn lưu trữ kèm giao dịch

4.5. MQTT phản hồi yêu cầu tạo mã VietQR động (bỏ qua đối với

thiết bị voice box):

○ Mô tả: Gửi phản hồi lại cho với mã QR đã tạo và các thông tin liên

quan.○ MQTT: mqtt:api.vietqr.org/vietqr/response/{terminalCode}

○ Message:Param bankCode bankName bankAccount userBankName amount content qrCode orderId imgId existing transactionId transactionRefId qrLink Type String String String String Long String String String String String String String String Description

Mã ngân hàng .(Ví du; MB)

Tên của ngân hàng

Số tài khoản nhận tiền

Tên chủ tài khoản ngân hàng

Số tiền nhận

Nội dung chuyển tiền

Mã QR

Mã đơn hàng

Hình ảnh qrCode

Có tồn tại trong hệ thống

VietQR

Id của giao dịch

Mã tham chiếu giao dịch

Đường link hiện qrCodeterminalCode String Mã điểm bán hoặc mã cửa

hàng

serviceCode String Mã sản phẩm

additionalData List\<Object> Thông tin thêm của đối tác

muốn lưu trữ kèm giao dịch

4.6. MQTT nhận BĐSD đối với các thiết bị đã được đồng bộ và active

thành công (Sau khi hoàn thành các bước 4.1, 4.2, 4.3):

○ Mô tả: Sau khi thực hiện việc đồng bộ thiết bị và active thiết bị

thành công, khi có giao dịch tới ứng với thiết bị, VietQR sẽ gửi

thông báo thanh toán thành công đến thiết bị, {terminalCode} được

lấy và sử dụng từ response trả về mục 4.3.

○ MQTT: /vietqr/bdsd/{terminalCode}

○ Example response: Chi tiết xem mục 5.9

○ Message:Param Type Description

bankAccount String Số tài khoản nhận tiền

amount Long Số tiền thanh toán thành công

transType String

Loại giao dịch:

\+ “C”: Giao dịch nhận tiền (+)

\+ “D”: Giao dịch trừ tiền (-)

referenceNumber String Mã giao dịch của hệ thống ngân hàng

trả về

orderId String

Mã đơn hàng ứng với giao dịch được

tạo (empty đối với việc thanh toán

không qua mã QR động)

content String Nội dung chuyển tiền khách hàng

nhận được

status String

Trạng thái chuyển tiền:

\+ 0: Chờ TT

\+ 1: Thành công (Giá trị khi nhận

BĐSD)

\+ 2: Đã hủy

timePaid String Thời gian thanh toán (dd/MM/yyyy

HH:mm:ss), múi giờ: UTC+7

4.7. MQTT YÊU CẦU KIỂM TRA TRẠNG THÁI GIAO DỊCH yêu cầu

kiểm tra trạng thái giao dịch (bỏ qua đối với các thiết bị voicebox và không

sử dụng việc tạo mã QR động)

○ Mô tả: Sau khi giao dịch không nhận được biến động số dư

○ MQTT: mqtt://api.vietqr.org/vietqr/request-status/{terminalCode}

○ Message:Param Type Description

bankAccount String Số tài khoản nhận tiền

type int

Loại kiểm tra (0: kiểm tra theo

OrderId, 1: kiểm tra theo

ReferenceNumber).

value String Giá trị cần kiểm tra (OrderId

hoặc referenceNumber)

checkSum String

Mã kiểm tra bảo mật được tạo

từ bankAccount và

userBankName.

\* Note :

"*checkSum*" sẽ do bên khách hàng cung cấp .

\- Kết hợp bankAccount và userBankName thành một chuỗi duy nhất

\- Mã hóa chuỗi đó bằng thuật toán MD5.

\- Mã MD5 sẽ được sử dụng làm *checksum*.

4.8. MQTT PHẢN HỒI TRẠNG THÁI GIAO DỊCH

○ Mô tả: Nhận phản hồi sau khi gửi yêu cầu kiểm tra trạng thái giao

dịch

○ MQTT: mqtt://api.vietqr.org/vietqr/response-

status/{terminalCode}

○ Message:Param referenceNumber orderId amount content transType status type timeCreated timePaid terminalCode note refundCount amountRefunded Note :

Type String String Long String String int int Long Long String String int int Description

Mã tham chiếu giao dịch

Mã đơn hàng.

Số tiền giao dịch

Nội dung giao dịch

Số tiền giao dịch

Trạng thái giao dịch

Loại kiểm tra

Thời gian tạo giao dịch

Thời gian thanh toán giao dịch

Mã điểm bán hoặc mã cửa

hàng

Ghi chú

Số lần hoàn tiền

Số tiền đã hoàn lạistatus:

● 0: Giao dịch đang chờ thanh toán

● 1: Giao dịch thành công

● 2: Giao dịch đã hủy

type:

● 0: Kiểm tra theo Mã đơn hàng

● 1: Kiểm tra theo Mã tham chiếu giao dịch

transType:

● "C": Giao dịch đến

● "D": Giao dịch đi

5\. Mẫu Dữ Liệu

5.1. Mẫu Yêu Cầu Tạo QR (4.4)

{ "amount":20000,

"content":"Dondathangsanpham",

"bankAccount":"0373568944",

"bankCode":"MB",

"userBankName":"CONG TY CO PHAN SAB",

"transType":"C",

"orderId":"5035Linh30",

"terminalCode":"123",

"serviceCode":"A95",

"additionalData":\[

{

"additionalData1":"01"

}

]

}

5.2. Mẫu Phản Hồi Tạo QR (4.5)

{ "bankCode":"MB","bankName":"Ngân hàng TMCP Quân đội",

"bankAccount":"0373568944",

"userBankName":"CONG TY CO PHAN SAB",

"amount":"20000",

"content":"VQRb89d683eec Dondathangsanpham",

"qrCode":"00020101021138540010A00000072701240006970422011003

735689440208QRIBFTTA53037045405200005802VN62350831VQRb89d683

eec Dondathangsanpham6304AAB8",

"imgId":"58b7190b-a294-4b14-968f-cd365593893e",

"existing":1,

"transactionId":"",

"transactionRefId":"ZDkzZmE4MzItZGIzZi00ZjJhLTk5MWYtNGZjZD

c3NGZkMTA2",

"qrLink":"<https://vietqr.vn/test/qr->

generated?token=ZDkzZmE4MzItZGIzZi00ZjJhLTk5MWYtNGZjZDc3NGZk

MTA2",

"terminalCode":"123",

"serviceCode":"A95",

"additionalData":\[

{

"additionalData1":"01"

}

]

}

5.3. Mẫu Thông Báo Biến Động Số Dư (4.6)

{

"bankAccount": "2220170973333",

"amount": 30000.0,

"timePaid": "07/08/2024 09:44:56",

"transType": "C",

"referenceNumber": "FT2439724066684",

"content": "VQR49e47786a6 Dondathangkhac",

"status": 1

}5.4. Mẫu Yêu Cầu Kiểm Tra Trạng Thái Giao Dịch (4.7)

{

"bankAccount": "0373568944",

"type": 0,

"value": "5035Linh31",

"checkSum": "257088447838a11a08bd809198e32119"

5.5. Mẫu Phản Hồi Yêu Cầu Kiểm Tra Trạng Thái Giao Dịch (4.8)

}

{

"referenceNumber": "FT24397240666820",

"orderId": "5035Linh31",

"amount": 20000,

"content": "VQR2aacfc2a85 Dondathangsanpham",

"transType": "C",

"status": 1,

"type": 0,

"timeCreated": 1723039658,

"timePaid": 1723039685,

"terminalCode": "",

"note": "",

"refundCount": 0,

"amountRefunded": 0

}

5.6. Mẫu yêu cầu đồng bộ thiết bị với hệ thống VietQR (4.1)

{

"macAddr": "862225071268411",

"checkSum": "fb0611a286aa0306f81b0e0646ae3177",

"secretKey": "secretKey",

"serialNumber": "ZSV12433565"

}

5.7. Mẫu phản hồi dữ liệu đồng bộ thiết bị (4.2)

{"qrCertificate": "CERT-VVB-

VlZCNDI4MDc4ODYyMjI1MDcxMjY4NDExVmlldFFSQm94QWNjZXNzS2V5",

"boxId": "VlZCNDI4MDc4VmlldFFSQm94QWNjZXNzS2V5"

}

5.8. Mẫu nhận dữ liệu sau khi thực hiện active thiết bị (4.3)

{

"notificationType": "N16",

"bankAccount": "0373568944",

"bankShortName": "MBBank",

"userBankName": "Nguyen Phuong Nhai Linh",

"terminalCode": "VVB409068",

"terminalName": "VietQR Pro Linhsii",

"qrCode":

"00020101021138540010A0000007270124000697042201100373568944020

8QRIBFTTA530370454005802VN62170813SQR3jlciLK2zv6304AE8A",

"bankCode": "MB",

"imgBank": ""

,

"homePage": "vietqr.vn|vietqr.com"

}

5.9. Mẫu phản hồi dữ liệu nhận BĐSD (4.6)

{

"bankAccount": "0373568944",

"amount": 5000.0,

"timePaid": "24/10/2024 22:45:25",

"transType": "C",

"referenceNumber": "FT24299111068025",

"orderId": ""

,

"content": "SQR3jlciLK2zv Ma giao dich Trace688146

Trace 688146",

"status": 1

}


# Các bước đồng bộ MQTT

Các bước đồng bộ MQTT

Bước 1: Đồng bộ thiết bị với tài khoản VietQR -> Đăng kí 2 topic : Topic đăng kí : /vqr/handle-box\
Topic nhận phản hồi : /vqr/handle-box/response/11.78.36.89.21

Bước 2: Sau khi message được phản hồi về topic : /vqr/handle-box/response/11.78.36.89.21 - Ta sử dụng giá trị của filed "boxId" để đăng kí nhận phản hồi từ topic mới : vietqr/boxId/{boxId} để nhận các thông tin từ đồng bộ điểm bán

```
    - Ví dụ: "boxId":"VlZCNDA5MDY4VmlldFFSQm94QWNjZXNzS2V5" Thì topic tương ứng là: vietqr/boxId/VlZCNDA5MDY4VmlldFFSQm94QWNjZXNzS2V5.
```

Bước 3: Sử dụng giá trị của "qrCertificate" được phản hồi từ topic /vqr/handle-box/response/11.78.36.89.21 để quét mã QR từ app VietQR với mục đích đồng bộ điểm bán

Bước 4: Sau khi đồng bộ điểm bán từ app VietQR thì sẽ nhận được phản hồi từ topic vietqr/boxId/{boxId} mà ta đã đăng kí từ bước 2


# Host To Client

Bộ API này giúp cho đối tác có thể kết nối trực tiếp thiết bị thanh toán của mình với hệ thống VietQR

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2F6SZI1nxWerNJMhH3VKA6%2FHTC%20-%20VN.png?alt=media&amp;token=2d5c1a36-76bd-44ca-a411-2fd362b4ec09" alt=""><figcaption></figcaption></figure>

### Mô tả

{% hint style="info" %}
Đối tác cần hoàn tất quá trình đăng ký tài khoản với đầy đủ thông tin nhằm định danh và bảo mật tài khoản. Thông tin tích hợp mặc định sẽ là môi trường Test (Sandbox).
{% endhint %}

**Các bước cơ bản để tích hợp với VietQR:**

1. Gọi API Get Token.
2. Gọi API Ecommerce Sync.
3. Đối tác triển khai web socket Bank Account Sync.
4. Đối tác triển khai web socket Transaction Sync.
5. Thực hiện đồng bộ tài khoản ngân hàng nhanh chóng.
6. Sử dụng Token được trả về ở bước 2 để gọi [API Generate VietQR Code](/vi/api-vietqr-callback/goi-api-generate-vietqr-code) để tạo mã thanh toán.

***

### Môi trường tích hợp và Domain

<table><thead><tr><th width="135">Môi trường</th><th width="197">Domain</th><th>Mô tả</th><th data-hidden></th></tr></thead><tbody><tr><td>Test</td><td><a href="https://dev.vietqr.org">https://dev.vietqr.org</a></td><td>Sử dụng trong quá trình tích hợp kiểm thử.</td><td></td></tr><tr><td>Production</td><td><a href="https://api.vietqr.org">https://api.vietqr.org</a></td><td>Sử dụng để triển khai cho người dùng cuối.</td><td></td></tr></tbody></table>

***

### Cấu hình HTTP Request

<table><thead><tr><th width="183">Key</th><th>Value</th><th data-hidden></th></tr></thead><tbody><tr><td>Content-Type</td><td>application/json; charset=UTF-8</td><td></td></tr><tr><td>Method</td><td>POST</td><td></td></tr></tbody></table>

1. #### API GET TOKEN

* URL: <https://api.vietqr.org/vqr/api/peripheral/ecommerce/token_generate>
* Method: POST
* Xác thực: Basic Authentication
* Thông tin Basic Authentication: Liên hệ VietQR.
* Mô tả:&#x20;
* API get token sử dụng để lấy bearer token, token này sử dụng cho active-ecommerce
* Request Header:

| Field          | Type   | Description                   |
| -------------- | ------ | ----------------------------- |
| Authentication | String | HashBase64: username:password |

* Example: HashBase64: “nhatlinh:37256497631” => bmhhdGxpbmg6MzcyNTY0OTc2MzE=
* Response Body:

| Field         | Type   | Description                                                   |
| ------------- | ------ | ------------------------------------------------------------- |
| access\_token | String | token sử dụng gọi api active-ecommerce và tạo mã VietQR |
| token\_type   | String | Loại token (Mặc định là ‘Bearer’)                         |
| expires\_in   | int    | Thời gian token hết hạn (Mặc định là 300 giây)          |

* Response Example:&#x20;

{

&#x20;   "access\_token": "eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdFltd3RkWE5sY2pBMSIsImlhdCI6MTcyNDQ3MTY3OX0.axvTVS5lFEZcjE3nWqDoJDw2plzRjTK86Q34LqsXvDkTvcJfBmfDWrkAfQiimMWGqYX4s0PaHAgYmpfJH3WDtQ",

&#x20;   "token\_type": "Bearer",

&#x20;   "expires\_in": 0

}

* curl:

curl --location --request POST '<https://api.vietqr.org/vqr/api/peripheral/ecommerce/token\\_generate>' \\

\--header 'Authorization: Basic bmhhdGxpbmg6MzcyNTY0OTc2MzE=' \\

\--header 'Cookie: JSESSIONID=A2FF65B2A88D8E3C984D4602847027B9'

2. #### API ĐỒNG BỘ ECOMMERCE

* URL: [https://api.vietqr.org/vqr/api/ecommerce](https://api.vietqr.org/vqr/api/peripheral/ecommerce/token_generate)
* Method: POST
* Xác thực: Bearer Token từ API Get TOKEN
* Mô tả:&#x20;
* API đồng bộ 1 website mới sử dụng ecommerce-wordpress
* Request Body:

<table data-header-hidden><thead><tr><th width="182"></th><th></th><th></th></tr></thead><tbody><tr><td>Field</td><td>Type</td><td>Description</td></tr><tr><td>ecommerceSite</td><td>String</td><td>Địa chỉ url của hệ thống ecommerce</td></tr><tr><td>checkSum</td><td>String</td><td><p>Chuỗi mã hóa checkSum MD5: </p><p>password sử dụng api get_token + “:” + ecommerceSite + “VietQRAccesskey”</p></td></tr><tr><td>webhook</td><td>String</td><td>Webhook trả vể khi có thông báo BĐSD</td></tr><tr><td>codcode</td><td>String</td><td>Đánh dấu phân biệt khác hàng</td></tr></tbody></table>

* curl:

curl --location '<https://api.vietqr.org/vqr/api/ecommerce>' \\

\--header 'Content-Type: application/json' \\

\--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGFHVm9aUzExYzJWeU1qUXhNVFE9IiwiaWF0IjoxNzI5MDE0NDYzfQ.YddtvhDTaIGwUVfdGEvFMdBR5udOqtrepSCqrEQ9f9Jrkkk7YOw22BhvaoYnIs0dphOs0qOtA0J2i0K2ne8u0w' \\

\--data '{

&#x20;   "ecommerceSite": "<https://www.google2.com>",

&#x20;   "checkSum": "824dd80a89481085da810860e675bcf0",

&#x20;   "webhook": "",

&#x20;   "code": "3587923"

}'

* Example Request Body:

{

&#x20;   "ecommerceSite": "<https://www.google.com>",

&#x20;   "checkSum": "8a3439ca64d2394713e946f9f3677bb1"&#x20;

//HashMD5: 37256497631:[https://www.google.comVietQRAccesskey](https://www.google.comvietqraccesskey)

&#x20;   "webhook": "<https://www.google.com>",

&#x20;   "code": "3587923"

}

* Response Body:

| Field                     | Type   | Description                                                             |
| ------------------------- | ------ | ----------------------------------------------------------------------- |
| webhook                   | String | Webhook nhận BĐSD                                                      |
| clientId                  | String | clientId để đăng kí wss nhận BĐSD                                    |
| certificate               | String | Mã QR dạng chuỗi hiển thị trong hệ thống ecommerce để đồng bộ |
| token                     | Object | Object chứa các thông tin token để sử dụng api tạo mã VietQR     |
| \[token].\[access\_token] | String | Token dùng để tạo mã VietQR                                         |
| \[token].\[token\_type]   | String | Loại token (Mặc định “Bearer”)                                       |
| \[token].\[expires\_in]   | int    | Thời gian hết hạn của token (Mặc định là 300s)                   |

* Example Response Body:

{

&#x20;   "webhook": "",

&#x20;   "clientId": "ZTk2NjVmMTgtM2I3MC00YTUwLTkxZTItM2ZiMjAwOGNiMTM2VmlldFFSQm94QWNjZXNzS2V5", // clientId để nhận wss

&#x20;   "certificate": "MER-ECM-MER37695058",

// certificate hiển thị dưới dạng mã QR cho người dùng muốn đồng bộ TK ngân hàng vào trang có thể quét

&#x20;   "token": {

&#x20;   "access\_token": "eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdFltd3RkWE5sY2pBMSIsImlhdCI6MTcyNDQ3MTY3OX0.axvTVS5lFEZcjE3nWqDoJDw2plzRjTK86Q34LqsXvDkTvcJfBmfDWrkAfQiimMWGqYX4s0PaHAgYmpfJH3WDtQ",

&#x20;   "token\_type": "Bearer",

&#x20;   "expires\_in": 0

},

&#x20;          "code": "3587923"

}

3. #### ĐỒNG BỘ NGÂN HÀNG VỚI HỆ THỐNG VIETQR

* Liên kết TK ngân hàng (MB, BIDV) với hệ thống VietQR
* Hiển thị mã certificate dưới dạng QR

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXfyj9LCUaEOxCaF_OWntRT7dtrrHs9F3EHU2J8e34d-OBbGjc9IMhKiF9XGc9SJpQ4qsx6Yhfybqil_j_Lg8VnxjZ4tFKFh_bboIST_aK843xPx7mIPaKpKO0Y3m6eijpGC1oM2TAgZHEinio_8DRV2_qvD?key=bp4CxudbRmRcF7cYKNLONw)

* Sử dụng app VietQR để quét mã

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXdcTNGU7qvklnli-hw5ZzBKxoEDrAlcmdYZE8sNAXNVF01dSmL6dmHV4VfK6wVCsjtlchSYqUnbm89PJy8q0_pnV2PmLF6D0ixwBH1aaJ7IwJbD5pdqfuyU5pilhAN56PC_FDiWAg70HYCW0eyQ-gUfqM9u?key=bp4CxudbRmRcF7cYKNLONw)

* Điền đầy đủ các thông tin cần thiết để đồng bộ với hệ thống<br>

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXddK9pAGeXY3VZQykaSFL4NNSaoOaXUuXQpfMaaPzIpVbYXw9Jc3PMWBHDeVSvuUWh9iw_AnhRhaR2mo0CcSxpHbYW0SJyA6AwDuE5_NtUyECRZa3tpIyWXx8gWSpHUZyhR9FFuskHKt-bEbPeL3FAwso9i?key=bp4CxudbRmRcF7cYKNLONw)

* Chọn TK ngân hàng muốn đồng bộ để tạo mã QR thanh toán và nhận biến động số dư khi mã QR được thanh toán thành công
* Kiểm tra lại thông tin và nhấn xác nhận

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXe8WYCetHHNAbElF6dlX6xDuhNi8WOAXBoeg1Hgz9axxK4b7-h1KHfoblXX_h2GntAcxlEXR_blRXCvRl408IeKmGaMGRZzXethsD1OEBRZJZbUOwkThbkSANMeO7cZj8hQhiQtoiCS4Q1ft9CXxvLi7XTo?key=bp4CxudbRmRcF7cYKNLONw)

<br>

* Thông tin tài khoản ngân hàng sẽ được gửi thông qua websocket hoặc webhook để khách hàng có thể sử dụng thông tin tạo mã QR

1. #### API TẠO MÃ VIETQR

* URL: [https://api.vietqr.org/vqr/api/](https://api.vietqr.org/vqr/api/peripheral/ecommerce/token_generate)qr/generate-customer
* Method: POST
* Xác thực: Bearer Token từ API ĐỒNG BỘ ECOMMERCE
* Mô tả:&#x20;
* * API tạo mã VietQR&#x20;
* Request Body:<br>

| Field           | Type        | Description                                                                                                                                                           |
| --------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| bankCode        | String      | Mã ngân hàng của tài khoản đã đồng bộ                                                                                                                              |
| bankAccount     | String      | Tài khoản ngân hàng tạo mã thanh toán VietQR đã được đồng bộ                                                                                                      |
| userBankName    | String      | Họ tên chủ tài khoản. Không dấu tiếng Việt.                                                                                                                           |
| content         | String      | <p>Nội dung chuyển tiền.</p><p>Tối đa 19 ký tự, tiếng Việt không dấu, không ký tự đặc biệt</p>                                                                        |
| qrType          | int         | <p>Tùy loại mã thanh toán cần tạo, nhập giá trị tương ứng:</p><ul><li>VietQR tĩnh: 1</li><li>VietQR bán động: 3</li><li>VietQR động: 0</li></ul>                      |
| amount          | String/Long | Số tiền cần thanh toán                                                                                                                                                |
| orderId         | String      | Mã ID giao dịch bên đối tác cần quản lý. “orderId” sẽ được trả về khi hệ thống nhận biến động số dư (có thông tin giao dịch trùng với giao dịch được tạo bằng mã QR). |
| transType       | String      | <p>Phân loại giao dịch là ghi nợ/ghi có (giá trị: D/C). </p><p>Mặc định là “C”</p>                                                                                    |
| terminalCode    | String      | Mã cửa hàng/điểm bán                                                                                                                                                  |
| subTerminalCode | String      | Mã con cửa hàng / điểm bán                                                                                                                                            |
| serviceCode     | String      | Mã sản phẩm                                                                                                                                                           |
| note            | String      | Ghi chú giao dịch                                                                                                                                                     |
| urlLink         | String      | Trang chuyển hướng sau khi thanh toán sử dụng qrLink để hiển thị mã QR                                                                                                |
| sign            | String      | Chữ ký của giao dịch                                                                                                                                                  |
| reconciliation  | boolean     | Mặc định là “true”, có đối soát hay không, nếu “false” giao dịch sẽ chỉ tạo ra mã QR                                                                                  |

* curl:

curl --location '<https://api.vietqr.org/vqr/api/qr/generate-customer>' \\

\--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=A2FF65B2A88D8E3C984D4602847027B9' \\

\--header 'Content-Type: application/json' \\

\--data '{

&#x20;   "bankAccount": "0373568944",

&#x20;   "bankCode": "MB",

&#x20;   "amount": 5000,

&#x20;   "transType": "C",

&#x20;   "userBankName": "Nguyen Phuong Nhat Linh",

&#x20;   "orderId": "LINHSII191",

&#x20;   "content": "NhatLinh CK",

&#x20;   "qrType": 0,

&#x20;   "terminalCode": "CUAHANGLINH",

&#x20;   "subTerminalCode": ""

}'

* Example Request Body:

{

&#x20;   "bankAccount": "5580245198",

&#x20;   "bankCode": "MB",

&#x20;   "amount": 5000,

&#x20;   "transType": "C",

&#x20;   "userBankName": "Nguyen Phuong Nhat Linh",

&#x20;   "orderId": "LINHSII1521",

&#x20;   "content": "NhatLinh",

&#x20;   "qrType": 0,

&#x20;   "terminalCode": "",

&#x20;   "subTerminalCode": "",

&#x20;   "serviceCode": "",

&#x20;   "note": "",

&#x20;   "urlLink": "<https://www.google.com>",

&#x20;   "sign": "",

&#x20;   "reconciliation": true

}

* Response Body:

<table data-header-hidden><thead><tr><th></th><th width="142"></th><th></th></tr></thead><tbody><tr><td>Field</td><td>Type</td><td>Description</td></tr><tr><td>bankCode</td><td>String</td><td>Mã ngân hàng của tài khoản đã đồng bộ</td></tr><tr><td>bankName</td><td>String</td><td>Tên ngân hàng của tài khoản đã đồng bộ</td></tr><tr><td>bankAccount</td><td>String</td><td>Tài khoản ngân hàng tạo mã thanh toán VietQR đã được đồng bộ</td></tr><tr><td>userBankName</td><td>String</td><td>Họ tên chủ tài khoản</td></tr><tr><td>amount</td><td>String</td><td>Số tiền cần thanh toán</td></tr><tr><td>content</td><td>String </td><td>Nội dung chuyển tiền.</td></tr><tr><td>qrCode</td><td>int</td><td>Mã QR Code dạng String</td></tr><tr><td>imgId</td><td>String</td><td>Mã định danh của hình ảnh ngân hàng</td></tr><tr><td>existing</td><td>int</td><td>0: Được đối soát, 1: Không được đối soát</td></tr><tr><td>transactionId</td><td>String</td><td>Mã định danh của QR</td></tr><tr><td>transactionRefId</td><td>String</td><td>Mã định danh của QR</td></tr><tr><td>qrLink</td><td>String</td><td>Mã qr dạng link</td></tr><tr><td>terminalCode</td><td>String</td><td>Mã cửa hàng / mã điểm bán</td></tr><tr><td>subTerminalCode</td><td>String</td><td>Mã con cửa hàng / mã con điểm bán</td></tr><tr><td>serviceCode</td><td>String</td><td>Mã sản phẩm</td></tr><tr><td>orderId</td><td>String</td><td>Mã đơn hàng</td></tr><tr><td>additionalData</td><td>List&#x3C;Object></td><td>Thông tin thêm</td></tr></tbody></table>

* Example Response Body:

{

&#x20;   "bankCode": "MB",

&#x20;   "bankName": "Ngân hàng TMCP Quân đội",

&#x20;   "bankAccount": "0373568944",

&#x20;   "userBankName": "NGUYEN PHUONG NHAT LINH",

&#x20;   "amount": "5000",

&#x20;   "content": "NhatLinh",

&#x20;   "qrCode": "00020101021238570010A000000727012700069704220113VQRQ00035mj8e0208QRIBFTTA5303704540450005802VN62230107NPS68690808NhatLinh63049C62",

&#x20;   "imgId": "58b7190b-a294-4b14-968f-cd365593893e",

&#x20;   "existing": 0,

&#x20;   "transactionId": "",

&#x20;   "transactionRefId": "MDE2NzBmODgtZTg3Yi00YTY1LWFjZTMtMTE1M2E3ODYyZDNi",

&#x20;   "qrLink": "<https://vietqr.vn/qr-generated?token=MDE2NzBmODgtZTg3Yi00YTY1LWFjZTMtMTE1M2E3ODYyZDNi>",

&#x20;   "terminalCode": "",

&#x20;   "subTerminalCode": "",

&#x20;   "serviceCode": "",

&#x20;   "orderId": "LINHSII1521",

&#x20;   "additionalData": \[]

}

2. #### WEBSOCKET VÀ WEBHOOK NHẬN BĐSD

* Websocket: ws\://api.vietqr.org/vqr/socket?clientId={clientId}
* Mô tả:&#x20;
* Web Socket dùng để nhận BĐSD khi có giao dịch tới

| Field            | Type   | Description                                                     |
| ---------------- | ------ | --------------------------------------------------------------- |
| notificationType | String | Mã của notificationType ‘N05’: Mã code nhận biết BĐSD tới |
| transactionid    | String | Mã định danh của giao dịch                                  |
| referencenumber  | String | Mã giao dịch                                                  |
| amount           | String | Số tiền giao dịch                                            |
| content          | String | Nội dung chuyển tiền của giao dịch                         |
| bankaccount      | String | TK ngân hàng                                                   |
| transType        | String | <p>C: Giao dịch đến</p><p>D: Giao dịch đi</p>                |
| orderId          | String | Mã đơn hàng của giao dịch                                   |
| terminalCode     | String | Mã cửa hàng của giao dịch                                  |
| serviceCode      | String | Mã sản phẩm của giao dịch                                  |
| subTerminalCode  | String | Mã điểm bán của giao dịch                                  |

Example Response WSS:

{

&#x20;   "notificationType": "N05",

&#x20;   "transactionid": "d6cbc2cb-6d02-45bb-97a3-b641b1a799f0",

&#x20;   "referencenumber": "FT2401335256512",

&#x20;   "amount": "5000",

&#x20;   "content": "nhatLinhCK",

&#x20;   "bankaccount": "0373568944",

&#x20;   "transType": "C",

&#x20;   "orderId": "LINH048952",

&#x20;   "terminalCode": "",

&#x20;   "serviceCode": "",

&#x20;   "subTerminalCode": ""

}

3. #### WEBSOCKET VÀ WEBHOOK THÊM TK NGÂN HÀNG THÀNH CÔNG

Websocket: ws\://api.vietqr.org/vqr/socket?clientId={clientId}

Mô tả:&#x20;

* Web Socket dùng để nhận thông tin khi đồng bộ thành công<br>

| Field            | Type   | Description                                                              |
| ---------------- | ------ | ------------------------------------------------------------------------ |
| notificationType | String | Mã của notificationType ‘N22’: Mã code nhận biết active thành công |
| bankAccount      | String | Số TK ngân hàng đã được kết nối                                    |
| bankCode         | String | Mã code của ngân hàng                                                 |
| userBankName     | String | Tên TK đã đồng bộ                                                     |
| ecommerceSite    | String | Website được đồng bộ                                                  |

<br>

4. #### API KIỂM TRA TRẠNG THÁI GIAO DỊCH

* URL: [https://api.vietqr.org/vqr/api/](https://api.vietqr.org/vqr/api/peripheral/ecommerce/token_generate)ecommerce-transactions/check-order
* Method: POST
* Xác thực: Bearer Token từ API ĐỒNG BỘ ECOMMERCE
* Mô tả:&#x20;
* * API kiểm tra trạng thái của giao dịch ecommerce
* Request Body:

| Field       | Type   | Description                                                                                                                                      |
| ----------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| bankAccount | String | TK ngân hàng đồng bộ với ecommerce                                                                                                           |
| bankCode    | String | Mã code ngân hàng đồng bộ                                                                                                                    |
| type        | String | 0: check theo orderId (truyền 0)                                                                                                                |
| value       | String | Mã orderId cần kiểm tra trạng thái                                                                                                          |
| checkSum    | String | <p>HashMD5 từ: bankAccount + username<br>Ví dụ: 0373568944customer-ecommerce-wordpress-user241328<br>Ra: c9c3239d4e9ff3888ad6186d02342870</p> |

* curl:<br>

curl --location '<http://api.vietqr.org/vqr/api/ecommerce-transactions/check-order>' \\

\--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD' \\

\--header 'Content-Type: application/json' \\

\--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGRtbGxkSEZ5ZEdWemRDMTFjMlZ5TWpRMk9BPT0iLCJpYXQiOjE3MjQ5NTYyOTd9.\_ojK4a-AkB27CvASRIBkXMi0FzzUZ7G4XBSvH47ipsJhqoZzoZaNZqMcz7WXb\_1f1z4S8U4odUuo5CvMiBQF4A' \\

\--data '{

&#x20;   "bankAccount": "0373568944",

&#x20;   "bankCode": "MB",

&#x20;   "type": "0",

&#x20;   "value": "LINHSII139",

&#x20;   "checkSum": "fdcb8bfa5f1590c08c0d8af6bde8ac81"

&#x20;   }'

* Example Request Body:

{

&#x20;   "bankAccount": "0373568944",

&#x20;   "bankCode": "MB",

&#x20;   "type": "0",

&#x20;   "value": "LINHSII139",

&#x20;   "checkSum": "c9c3239d4e9ff3888ad6186d02342870"

&#x20;   }

* Response Body: LIST JSON

<br>

| Field           | Type   | Description                                                              |
| --------------- | ------ | ------------------------------------------------------------------------ |
| referenceNumber | String | Mã giao dịch nếu đã thanh toán thành công                          |
| orderId         | String | Mã đơn hàng của giao dịch                                            |
| amount          | int    | Số tiền giao dịch                                                     |
| content         | String | Nội dung giao dịch                                                     |
| transType       | String | C: Giao dịch đến, D: Giao dịch đi                                     |
| status          | int    | <p>0: Chờ thanh toán</p><p>1: Thành công</p><p>2: Đã hủy</p>        |
| type            | int    | <p>0: QR giao dịch</p><p>1: QR cửa hàng</p><p>2: Giao dịch khác</p> |
| timeCreated     | int    | Thời gian tạo mã QR                                                   |
| timePaid        | int    | Thời gian thanh toán                                                   |
| terminalCode    | String | Mã cửa hàng                                                           |
| note            | String | Ghi chú cho giao dịch                                                  |
| refundCount     | int    | Số lần đã hoàn tiền                                                 |
| amountRefund    | int    | Số tiền đã hoàn tiền                                                |

* Example Response Body:

\[

&#x20;   {

&#x20;       "referenceNumber": "",

&#x20;       "orderId": "LINHSII139",

&#x20;       "amount": 5000,

&#x20;       "content": "VQR02dffc8bed NhatLinh",

&#x20;       "transType": "C",

&#x20;       "status": 0,

&#x20;       "type": 0,

&#x20;       "timeCreated": 1724946637,

&#x20;       "timePaid": 0,

&#x20;       "terminalCode": "",

&#x20;       "note": "",

&#x20;       "refundCount": 0,

&#x20;       "amountRefunded": 0

&#x20;   }

]


# Gọi API Get Token

API get token sử dụng để lấy bearer token, token này sử dụng cho kích hoạt cho ecommerce

### <mark style="color:green;">`POST`</mark>

```
https://<vietqr-host>/<basepath>/api/token_generate
```

**Headers**

<table><thead><tr><th width="225">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td>Basic Authentication: Base64[<code>username:password</code>]</td></tr></tbody></table>

**Body**

<table><thead><tr><th width="226">Name</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>access_token</code></td><td>String</td><td>Là Bearer Token được VietQR cung cấp để truy cập các API VietQR.</td></tr><tr><td><code>token_type</code></td><td>String</td><td>Là dạng token dạng “Bearer”.</td></tr><tr><td><code>expires_in</code></td><td>String</td><td>Thời gian hết hạn của token. Mặc định là 300 giây.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "access_token": "bearer_token_của_đối_tác",
    "token_type": "Bearer",
    "expires_in": 300
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location --request POST 'https://dev.vietqr.org/vqr/api/token_generate' \
--header 'Authorization: Basic Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09'


Response:
{
    "access_token": "eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGRtbGxkSEZ5ZEdWemRDMTFjMlZ5TWpRMk9BPT0iLCJpYXQiOjE3MjEzNzI2MzQsImV4cCI6MTcyMTM3MjkzNH0.D19qvrpYHUgcGjDCXuXXAv3j6lZr6tfmIB0VzdCzAXMJAElGok04sNLysS6PRLdRb0hSgEX5_9KpLjB-xErn-A",
    "token_type": "Bearer",
    "expires_in": 300
}
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp

<details>

<summary>API Get Token dùng để làm gì?</summary>

API Get Token được sử dụng để cấp quyền truy cập vào các dịch vụ của VietQR bằng cách cung cấp một mã token (`access_token`). Mã token này sẽ được sử dụng trong các yêu cầu API khác để xác thực người dùng.

</details>

<details>

<summary>Làm thế nào để gọi API Get Token?</summary>

Bạn cần gửi một yêu cầu POST đến endpoint của API Get Token với thông tin xác thực (username và password) trong phần header. VietQR sẽ cung cấp thông tin này cho bạn sau khi hoàn tất quá trình đăng ký.

</details>

<details>

<summary>Token có thời gian sử dụng bao lâu?</summary>

Token được cấp bởi API Get Token thường có thời gian sử dụng là 300 giây (5 phút). Sau thời gian này, bạn cần gọi lại API để lấy token mới.

</details>

<details>

<summary>Tôi cần làm gì nếu nhận được thông báo lỗi khi gọi API Get Token?</summary>

Kiểm tra lại các thông tin bạn đã gửi, bao gồm username và password. Đảm bảo rằng các thông tin này đúng và vẫn còn hiệu lực. Nếu vấn đề vẫn tiếp diễn, hãy liên hệ với bộ phận hỗ trợ của VietQR để được giúp đỡ.

</details>

<details>

<summary>Tại sao tôi lại nhận được mã lỗi khi gọi API Get Token?</summary>

Các mã lỗi thường xuất hiện do vấn đề xác thực (sai username hoặc password), yêu cầu không hợp lệ, hoặc lỗi kết nối. Thông báo lỗi sẽ cung cấp chi tiết về nguyên nhân cụ thể, giúp bạn xác định và khắc phục vấn đề.

</details>

<details>

<summary>Tôi có thể sử dụng token trên môi trường nào?</summary>

Token được cấp có thể sử dụng trên các API của VietQR, tùy thuộc vào môi trường mà bạn đang sử dụng (Test hoặc Prod). Đảm bảo rằng bạn đang gọi API trên đúng môi trường tương ứng.

</details>

<details>

<summary>Làm thế nào để bảo mật token sau khi nhận được?</summary>

Token cần được bảo mật như một thông tin nhạy cảm. Không chia sẻ token với bất kỳ ai và lưu trữ nó một cách an toàn. Khi sử dụng token, hãy đảm bảo rằng kết nối của bạn được mã hóa (sử dụng HTTPS) để bảo vệ thông tin khỏi bị lộ.

</details>


# API Ecommerce Sync

API đồng bộ website mới sử dụng ecommerce-wordpress

### <mark style="color:green;">`POST`</mark>

```
https://<vietqr-host>/<basepath>/api/ecommerce
```

**Request Headers**

<table><thead><tr><th width="225">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td>Basic Authentication: Base64[<code>username:password</code>]</td></tr></tbody></table>

**Request Body**

<table><thead><tr><th width="185">Field</th><th width="84">Type</th><th>Description</th></tr></thead><tbody><tr><td>ecommerceSite</td><td>String</td><td>Địa chỉ url của hệ thống ecommerce</td></tr><tr><td>checkSum</td><td>String</td><td><p>Chuỗi mã hóa checkSum MD5:</p><p><code>password</code> + <code>:</code> + <code>ecommerceSite</code> + <code>VietQRAccesskey</code></p></td></tr><tr><td>webhook</td><td>String</td><td>Webhook trả vể khi có thông báo BĐSD</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "webhook": "",
  "clientId": "ZTk2NjVmMTgtM2I3MC00YTUwLTkxZTItM2ZiMjAwOGNiMTM2VmlldFFSQm94QWNjZXNzS2V5",
  // clientId để nhận wss
  "certificate": "MER-ECM-MER37695058",
  // certificate hiển thị dưới dạng mã QR cho người dùng muốn đồng bộ  
  // tài khoản ngân hàng vào trang có thể quét
  "token": {
    "access_token": "eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdFltd3RkWE5sY2pBMSIsImlhdCI6MTcyNDQ3MTY3OX0.axvTVS5lFEZcjE3nWqDoJDw2plzRjTK86Q34LqsXvDkTvcJfBmfDWrkAfQiimMWGqYX4s0PaHAgYmpfJH3WDtQ",
    "token_type": "Bearer",
    "expires_in": 0
  }
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="Request body" %}

```json
{
  "ecommerceSite": "https://www.google.com",
  "checkSum": "8a3439ca64d2394713e946f9f3677bb1",
  //HashMD5: 37256497631:https://www.google.comVietQRAccesskey
  "webhook": "https://www.google.com"
}
```

{% endtab %}
{% endtabs %}


# WS: Sync Bank Account

Web Socket dùng để nhận thông tin khi đồng bộ thành công

### <mark style="color:green;">`WS`</mark> Sync Bank Account <a href="#get-token" id="get-token"></a>

```
ws://api.vietqr.org/vqr/socket?clientId={clientId}
```

<table><thead><tr><th width="182">Field</th><th width="103">Type</th><th>Description</th></tr></thead><tbody><tr><td>notificationType</td><td>String</td><td>Mã của notificationType ‘N22’: Mã code nhận biết active thành công</td></tr><tr><td>bankAccount</td><td>String</td><td>Số TK ngân hàng đã được kết nối</td></tr><tr><td>bankCode</td><td>String</td><td>Mã code của ngân hàng</td></tr><tr><td>userBankName</td><td>String</td><td>Tên TK đã đồng bộ</td></tr><tr><td>ecommerceSite</td><td>String</td><td>Website được đồng bộ</td></tr></tbody></table>


# WS: Transaction Sync

Web Socket dùng để nhận biến động số dư khi có giao dịch tới.

### <mark style="color:green;">`WS`</mark> Sync Bank Account <a href="#get-token" id="get-token"></a>

```
ws://api.vietqr.org/vqr/socket?clientId={clientId}
```

<table><thead><tr><th width="176">Field</th><th width="84">Type</th><th>Description</th></tr></thead><tbody><tr><td>notificationType</td><td>String</td><td>Mã của notificationType ‘N05’: Mã code nhận biết BĐSD tới</td></tr><tr><td>transactionid</td><td>String</td><td>Mã định danh của giao dịch</td></tr><tr><td>referencenumber</td><td>String</td><td>Mã giao dịch</td></tr><tr><td>amount</td><td>String</td><td>Số tiền giao dịch</td></tr><tr><td>content</td><td>String</td><td>Nội dung chuyển tiền của giao dịch</td></tr><tr><td>bankaccount</td><td>String</td><td>TK ngân hàng</td></tr><tr><td>transType</td><td>String</td><td><p>C: Giao dịch đến</p><p>D: Giao dịch đi</p></td></tr><tr><td>orderId</td><td>String</td><td>Mã đơn hàng của giao dịch</td></tr><tr><td>terminalCode</td><td>String</td><td>Mã cửa hàng của giao dịch</td></tr><tr><td>serviceCode</td><td>String</td><td>Mã sản phẩm của giao dịch</td></tr><tr><td>subTerminalCode</td><td>String</td><td>Mã điểm bán của giao dịch</td></tr></tbody></table>


# Đồng bộ tài khoản ngân hàng

Bước đồng bộ này để chọn tài khoản ngân hàng cần sủ dụng dịch vụ.

### Hiển thị mã QR kích hoạt dịch vụ được trả về ở *Bước 2: Đồng bộ Ecommerce*.

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FDTtvoHtmh81GllsW50kh%2Funnamed.png?alt=media&amp;token=bc378e26-1c9c-47b8-8676-a2e2f526bfae" alt=""><figcaption></figcaption></figure>

### Sử dụng ứng dụng VietQR trên điện thoại để quét mã QR hiển thị ở trang trên.

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FEG4Yb472wuOXt3k2XQQs%2Fimage.png?alt=media&amp;token=29c42247-975d-4dc3-879f-6d3310c27075" alt=""><figcaption></figcaption></figure>

* Điền thông tin tài khoản ngân hàng cần liên kết.
* Sau khi nhập xong, nhấn Xác nhận để hoàn tất liên kết.

{% hint style="success" %}
Thông tin tài khoản ngân hàng sẽ được gửi thông qua websocket để khách hàng có thể sử dụng thông tin tạo mã QR.
{% endhint %}


# Gọi API Generate VietQR Code

Dịch vụ cho phép đối tác tạo mã QR Code thanh toán để người dùng quét và thực hiện thanh toán trực tiếp. Tùy thuộc vào loại mã thanh toán VietQR, một số tham số khác nhau sẽ cần được truyền đi.

### <mark style="color:green;">`POST`</mark>

```
https://<vietqr-host>/<basepath>/api/qr/generate-customer
```

**Headers**

<table><thead><tr><th width="249">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td><code>Bearer &#x3C;token></code>từ API ECOMMERCE SYNC.</td></tr></tbody></table>

**Body**&#x20;

<table data-full-width="false"><thead><tr><th width="215">Name</th><th width="90">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>bankCode</code></td><td>String</td><td>Yes</td><td>Mã ngân hàng của tài khoản. </td></tr><tr><td><code>bankAccount</code></td><td>String</td><td>Yes</td><td>Tài khoản ngân hàng tạo mã thanh toán VietQR.</td></tr><tr><td><code>userBankName</code></td><td>String</td><td>Yes</td><td>Họ tên chủ tài khoản. Không dấu tiếng Việt.</td></tr><tr><td><code>content</code></td><td>String</td><td>Yes</td><td>Nội dung chuyển tiền.<br>Tối đa 19 ký tự, tiếng Việt không dấu, không ký tự đặc biệt.</td></tr><tr><td><code>qrType</code></td><td>Integer</td><td>Yes</td><td><p>Tùy loại mã thanh toán cần tạo, nhập giá trị tương ứng:<br>- <mark style="background-color:green;">VietQR tĩnh: 1</mark></p><p>- <mark style="background-color:green;">VietQR bán động: 3</mark></p><p>- <mark style="background-color:green;">VietQR động: 0</mark></p></td></tr><tr><td><code>amount</code></td><td>Long</td><td>Optional</td><td>Số tiền cần thanh toán.<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 0 hoặc 3></mark></td></tr><tr><td><code>orderId</code></td><td>String</td><td>Optional</td><td>Mã ID giao dịch bên đối tác cần quản lý. “orderId” sẽ được trả về khi hệ thống nhận biến động số dư (có thông tin giao dịch trùng với giao dịch được tạo bằng mã QR).<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 0></mark></td></tr><tr><td><code>transType</code></td><td>String</td><td>Optional</td><td>Phân loại giao dịch là ghi nợ/ghi có (giá trị: D/C). <br>Mặc định là “C”.<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 0></mark></td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng/điểm bán.<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 1 hoặc 3></mark></td></tr><tr><td><code>serviceCode</code></td><td>String</td><td>Optional</td><td>Mã sản phẩm, dịch vụ được thanh toán.<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 3></mark></td></tr><tr><td><code>subTerminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng/điểm bán phụ.</td></tr><tr><td><code>sign</code></td><td>String</td><td>Optional</td><td>Chữ ký. </td></tr><tr><td><code>urlLink</code></td><td>String</td><td>Optional</td><td>Trang chuyển đến sau khi quét mã thanh toán.</td></tr><tr><td><code>note</code></td><td>String</td><td>Optional</td><td>Ghi chú cho giao dịch.</td></tr><tr><td><code>additionalData</code></td><td>Object</td><td>Optional</td><td>Các tham số truyền thêm.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200 - mã QR động" %}

<pre class="language-json"><code class="lang-json"><strong>{
</strong>    "bankCode": "mã_ngân_hàng",
    "bankName": "tên_ngân_hàng",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "userBankName": "tên_chủ_tài_khoản",
    "amount": "số_tiền_cần_thanh_toán",
    "content": "nội_dung_thanh_toán",
    "qrCode": "mã_QR_dạng_string",
    "imgId": "id_ảnh_ngân_hàng",
    "existing": "1: đã_được_tạo_trên_hệ_thống_vietQR_thành_công",
    "transactionId": "id_định_danh_của_QR",
    "transactionRefId": "mã_định_danh_của_QR",
    "qrLink": "mã_QR_dạng_link",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "serviceCode": "mã_sản_phẩm",
    "orderId": "mã_đơn_hàng",
    "additionalData": "thông_tin_thêm"
}
</code></pre>

{% endtab %}

{% tab title="200 - mã QR bán động" %}

```json
{
    "bankCode": "mã_ngân_hàng",
    "bankName": "tên_ngân_hàng",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "userBankName": "tên_chủ_tài_khoản",
    "amount": "số_tiền_cần_thanh_toán",
    "content": "nội_dung_thanh_toán",
    "qrCode": "mã_QR_dạng_string",
    "imgId": "id_ảnh_ngân_hàng",
    "existing": "1: đã_được_tạo_trên_hệ_thống_vietQR_thành_công",
    "transactionId": "id_định_danh_của_QR",
    "transactionRefId": "mã_định_danh_của_QR",
    "qrLink": "mã_QR_dạng_link",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "serviceCode": "mã_sản_phẩm",
    "orderId": "mã_đơn_hàng",
    "additionalData": "thông_tin_thêm"
}
```

{% endtab %}

{% tab title="200 - mã QR tĩnh" %}

```json
{
    "bankCode": "mã_ngân_hàng",
    "bankName": "tên_ngân_hàng",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "userBankName": "tên_chủ_tài_khoản",
    "amount": "số_tiền_cần_thanh_toán",
    "content": "nội_dung_thanh_toán",
    "qrCode": "mã_QR_dạng_string",
    "imgId": "id_ảnh_ngân_hàng",
    "existing": "1: đã_được_tạo_trên_hệ_thống_vietQR_thành_công",
    "transactionId": "id_định_danh_của_QR",
    "transactionRefId": "mã_định_danh_của_QR",
    "qrLink": "mã_QR_dạng_link",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "serviceCode": "mã_sản_phẩm",
    "orderId": "mã_đơn_hàng",
    "additionalData": "thông_tin_thêm"
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL tạo mã QR động" %}

```
curl --location 'https://api.vietqr.org/vqr/api/qr/generate-customer' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=D4468C26FD481B215DBF12CB9707B0AD' \
--header 'Content-Type: application/json' \
--data '{
    "amount": "số_tiền_cần_thanh_toán",
    "content": "nội_dung_thanh_toán",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "bankCode": "mã_ngân_hàng",
    "userBankName": "tên_chủ_tài_khoản",
    "transType": "C:giao_dịch_đến/D:giao_dịch_đi",
    "orderId": "mã_đơn_hàng",
    "sign": "chữ_ký",
    "serviceCode": "mã_sản_phẩm",
    "qrType": "loại qr: 0",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "note": "ghi_chú_mã_qr",
    "urlLink": "link_mà_trang_qr_link_sẽ_redirect_nếu_mã_qr_được_thanh_toán_thành công",
    "additionalData": "thông_tin_thêm_mã_QR_có_thể_truyền_empty_do_KH_tự_định_nghĩa",
}'
```

{% endtab %}

{% tab title="cURL tạo mã QR bán động" %}

```
curl --location 'https://api.vietqr.org/vqr/api/qr/generate-customer' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=D4468C26FD481B215DBF12CB9707B0AD' \
--header 'Content-Type: application/json' \
--data '{
    "amount": "số_tiền_của_sản_phẩm",
    "content": "nội_dung_thanh_toán",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "bankCode": "mã_ngân_hàng",
    "userBankName": "tên_chủ_tài_khoản",
    "transType": "C:giao_dịch_đến/D:giao_dịch_đi",
    "qrType": "loại qr: 1",
    "terminalCode": "mã_điểm_bán_đã_đồng_bộ"
    "serviceCode": "mã_sản_phẩm",
    "qrType": 3
}'
```

{% endtab %}

{% tab title="cURL tạo mã QR tĩnh" %}

```
curl --location 'https://api.vietqr.org/vqr/api/qr/generate-customer' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=A2494C77F9BCB561B15CDFDF6FF2CD1F' \
--header 'Content-Type: application/json' \
--data '{
    "content": "nội_dung_thanh_toán",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "bankCode": "mã_ngân_hàng",
    "userBankName": "tên_chủ_tài_khoản",
    "transType": "C:giao_dịch_đến/D:giao_dịch_đi",
    "qrType": "loại qr: 1",
    "terminalCode": "mã_điểm_bán_đã_đồng_bộ"
}'
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp

<details>

<summary>API Generate VietQR Code dùng để làm gì?</summary>

API Generate VietQR Code được sử dụng để tạo mã QR thanh toán cho các giao dịch. Mã QR này có thể được khách hàng quét để thực hiện thanh toán trực tiếp từ tài khoản ngân hàng.

</details>

<details>

<summary>Tôi cần cung cấp những thông tin gì để tạo mã QR thanh toán?</summary>

Để tạo mã QR thanh toán, bạn cần cung cấp các thông tin như số tiền, mã đơn hàng, thông tin người nhận, và thông tin tài khoản ngân hàng của người nhận. Các thông tin này sẽ được mã hóa vào mã QR. Bạn có thể xem chi tiết các thông tin cần thiết cho từng loại mã QR ở trên.

</details>

<details>

<summary>Làm thế nào để biết mã QR đã được tạo thành công?</summary>

Khi mã QR được tạo thành công, API sẽ trả về hình ảnh mã QR dưới dạng string cùng với các thông tin chi tiết liên quan đến giao dịch. Nếu có lỗi xảy ra, bạn sẽ nhận được thông báo lỗi trong phần phản hồi.

</details>

<details>

<summary>Làm thế nào để xử lý lỗi khi gọi API Generate VietQR Code?</summary>

Nếu bạn gặp lỗi khi gọi API, trước tiên hãy kiểm tra lại các thông tin đầu vào như số tiền, thông tin tài khoản, và mã đơn hàng. Đảm bảo rằng các thông tin này chính xác và hợp lệ. Nếu vấn đề vẫn tiếp diễn, hãy liên hệ với bộ phận hỗ trợ kỹ thuật của VietQR để được giúp đỡ.

</details>

<details>

<summary>Mã QR có thể được quét bằng ứng dụng nào?</summary>

Mã QR được tạo bởi API VietQR có thể được quét bằng bất kỳ ứng dụng ngân hàng nào hỗ trợ chuẩn thanh toán QR tại Việt Nam, hoặc các ứng dụng thanh toán ví điện tử có tính năng quét mã QR.

</details>

<details>

<summary>Tôi có cần mã hóa thông tin trước khi gửi đến API không?</summary>

Không, API VietQR sẽ tự động mã hóa các thông tin cần thiết khi tạo mã QR. Bạn chỉ cần đảm bảo rằng các thông tin gửi đến API là chính xác và đầy đủ.

</details>


# API Check Transaction

API kiểm tra trạng thái của giao dịch thuộc ecommerce.

## <mark style="color:green;">`POST`</mark>

```
https://<vietqr-host>/<basepath>/api/ecommerce-transactions/check-order
```

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

<table data-full-width="false"><thead><tr><th width="187">Name</th><th width="92">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>bankAccount</code></td><td>String</td><td>Yes</td><td>Số tài khoản ngân hàng.</td></tr><tr><td><code>type</code></td><td>String</td><td>Yes</td><td>Check by <code>orderId</code>: 0<br>Check by <code>referenceNumber</code>: 1</td></tr><tr><td><code>value</code></td><td>String</td><td>Yes</td><td>Giá trị là<code>orderId</code> nếu <code>type</code> = 0<br>Giá trị là<code>referenceNumber</code> nếu <code>type</code> = 1</td></tr><tr><td><code>checkSum</code></td><td>String</td><td>Yes</td><td><p>Chuỗi mã hóa MD5 của tổ hợp:</p><p>(<code>bankAccount</code> + <code>username</code>)</p></td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
[
    {
        "referenceNumber": "mã_giao_dịch",
        "orderId": "mã_đơn_hàng",
        "amount": số_tiền_giao_dịch,
        "content": "nội_dung_thanh_toán",
        "transType": "giao_dịch_đến_hoặc_đi",
        "status": phân_loại_trạng_thái_giao_dịch_theo_số,
        "type": phân_loại_giao_dịch_theo_số,
        "timeCreated": tem_thời_gian_tạo_mã_QR,
        "timePaid": tem_thời_gian_thanh_toán,
        "terminalCode": "mã_điểm_bán",
        "note": "ghi_chú_giao_dịch",
        "refundCount": số_lần_đã_hoàn_tiền_thuộc_giao_dịch_này,
        "amountRefunded": số_tiền_đã_hoàn_tiền_thuộc_giao_dịch_này
    }
]
```

{% hint style="info" %}
Giá trị trả về của `type`:

* 0: Giao dịch từ hệ thống VietQR.
* 2: Giao dịch ngoài hệ thống VietQR.
* 6: Giao dịch hoàn tiền.
  {% endhint %}

{% hint style="info" %}
Giá trị trả về của `status`:

* 0: Giao dịch chờ thanh toán.
* 1: Giao dịch đã thanh toán.
* 2: Giao dịch hết hạn thanh toán.
  {% endhint %}
  {% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}


# WordPress Plugin

Tài liệu hướng dẫn tích hợp dịch vụ eCommerce-WordPress tạo mã VietQR và nhận biến động số dư.

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2Fl5tvmIAtoFlUKhSy32ta%2FWPlugin%20-VN.png?alt=media&amp;token=01b546a0-8039-4858-8ee5-af319d0e9b01" alt=""><figcaption><p>Chỉ cần Cài đặt Plugin VietQR Wordpres miễn phí để nhận thanh toán và đối soát giao dịch</p></figcaption></figure>

## Giới thiệu VietQR WordPress Plugin

VietQR Plugin WordPress là dịch vụ hỗ trợ tạo mã QR thanh toán và Đối soát khớp lệnh giao dịch tự động với nền tảng thương mại điện tử WordPress.&#x20;

Bằng cách tích hợp VietQR Plugin vào hệ thống WordPress, bạn có thể:

* Tạo mã QR thanh toán cho các sản phẩm trên website của mình.
* Nhận thông báo biến động số dư (BĐSD) ngay khi có giao dịch thanh toán qua mã QR.
* Tối ưu hoá quy trình thanh toán, giúp khách hàng thực hiện thanh toán nhanh chóng và thuận tiện.
* Hỗ trợ các tài khoản ngân hàng phổ biến như MB và BIDV, giúp dễ dàng quản lý dòng tiền từ các giao dịch trực tuyến.

Gói dịch vụ VietQR hướng đến mục tiêu mang lại trải nghiệm thanh toán an toàn, tiện lợi cho người bán hàng trực tuyến và quản lý dễ dàng hơn thông qua các báo cáo giao dịch được đồng bộ liên tục.


# Cài đặt Plugin VietQR

Các bước cài đặt Plugin VietQR vào hệ thống WordPress.

### Đầu tiên, quý khách cần đăng nhập vào hệ thống WordPress của mình.

1. Vào phần Plugins trên thanh công cụ.
2. Chọn `Add New Plugin` (Thêm mới).

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FuNkZjb33xVI78BSH7zvg%2Fimage.png?alt=media&amp;token=e350cd8e-c08e-4362-8517-9157336ad3f7" alt=""><figcaption><p>Màn hình sau khi đăng nhập vào hệ thống WordPress của quý khách</p></figcaption></figure>

3. Chọn nút `Upload Plugin`.
4. Chọn file zip plugin do VietQR cung cấp.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcM7NMf7l4oTsgzAuGZ0qG0tUZZVRASbWcfDvyil_nE4cHOcvx9C0MDk5fw7Xnj-t56s8xXZPzKQ0VbrOettseYct1WNKI7SBPw_w58hfspiZslS5kgiQfuwZi7iTpEyXyzcg5Zvv7MPIX-SihU?key=KNO4jW4YArkKaTQtF2r8Xg" alt=""><figcaption><p>Giao diện trang cài đặt Plugin</p></figcaption></figure>

{% hint style="success" %}
Quý khách hàng cần liên hệ đến kỹ thuật để lấy file Plugin.
{% endhint %}

### Sau khi cài đặt thành công, trên thanh công cụ sẽ hiển thị plugin `VietQR VN`.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXctuEbGnEqGgqmvaAZ4Kjk9X9D0fWftMMevj_fMK8zb9gyGdsucctDBo2oWgkwOA1i6CfIFvTJ2C9gnok6gR_2efc2_EYRP0y_jNSwKvipsONt-btBGPV34-KIve2RqDodINrYFmgEC9jw-6GB61Q?key=KNO4jW4YArkKaTQtF2r8Xg" alt=""><figcaption><p>Màn hình sau khi cài đặt thành công.</p></figcaption></figure>


# Liên kết với VietQR

Đăng ký tài khoản VietQR và liên kết với ngân hàng để bắt đầu sử dụng dịch vụ.

{% hint style="success" %}
Quý khách có thể tham khảo video demo [tại đây](https://doc.vietqr.vn/vietqr-doc#lien-ket-va-quan-ly-tai-khoan).
{% endhint %}

### Đăng ký tài khoản VietQR

{% hint style="info" %}
Nếu quý khách đã có tài khoản VietQR, hẫy đến bước tiếp theo.
{% endhint %}

1. Truy cập trang web [`VietQR.vn`](https://vietqr.vn/register) của chúng tôi để đăng ký tài khoản.
2. Nhập số điện thoại và mật khẩu để tạo một tài khoản mới.
3. Sau khi đăng ký, bạn cần liên kết tài khoản ngân hàng để có thể nhận tiền từ các giao dịch thanh toán qua mã QR.
4. Đăng nhập vào VietQR, nhấn vào nút thêm tài khoản ngân hàng.
5. Chọn ngân hàng MB hoặc BIDV.
6. Nhập các thông tin cần thiết và xác thực để liên kết.

{% hint style="success" %}

* Nếu quý khách chưa có tài khoản tại ngân hàng MB hoặc BIDV, hãy đăng ký ngay  [tại đây](https://omni.bidv.com.vn/static/bidv/share/gioi-thieu-ban-thuong-vo-han.html?data=aH0RHc6MyLk9Cbi5Wa2R2ch1nciRWYr5Wan5nLuZ2LiVlTBRGTS1VbuVVeYZEZo4) để mở tài khoản mới và nhận nhiều ưu đãi hấp dẫn.
* Trong thời gian chờ tài khoản chính thức được kích hoạt, chúng tôi sẽ cung cấp tài khoản ngân hàng thử nghiệm để quý khách có thể tích hợp và trải nghiệm dịch vụ trước.
  {% endhint %}

***

<details>

<summary>Tôi cần làm gì để đăng ký tài khoản VietQR?</summary>

Bạn cần truy cập trang web VietQR.vn, nhập số điện thoại và mật khẩu để tạo tài khoản mới. Sau khi đăng ký thành công, bạn có thể bắt đầu sử dụng các dịch vụ của VietQR.

</details>

<details>

<summary>Tại sao tôi phải liên kết tài khoản ngân hàng với VietQR?</summary>

Việc liên kết tài khoản ngân hàng cho phép bạn nhận tiền từ các giao dịch thanh toán qua mã QR. Tài khoản liên kết sẽ là nơi nhận tiền khi khách hàng thanh toán thông qua mã QR do VietQR cung cấp.

</details>

<details>

<summary>Hiện tại VietQR hỗ trợ liên kết với những ngân hàng nào?</summary>

Hiện tại, VietQR hỗ trợ liên kết với tài khoản ngân hàng tại MB và BIDV. Các ngân hàng khác đang được triển khai và sẽ sớm được hỗ trợ trong thời gian tới.

</details>

<details>

<summary>Tôi chưa có tài khoản tại ngân hàng MB hoặc BIDV, tôi phải làm gì?</summary>

Nếu bạn chưa có tài khoản tại MB hoặc BIDV, bạn có thể đăng ký mở tài khoản mới tại ngân hàng thông qua liên kết trên trang VietQR. Sau khi mở tài khoản, bạn có thể quay lại VietQR để liên kết tài khoản ngân hàng này.

</details>

<details>

<summary>Tôi có thể sử dụng tài khoản ngân hàng thử nghiệm để làm gì?</summary>

Trong thời gian chờ tài khoản chính thức được kích hoạt, VietQR sẽ cung cấp tài khoản ngân hàng thử nghiệm để bạn có thể tích hợp và trải nghiệm các dịch vụ của VietQR trước khi sử dụng tài khoản chính thức.

</details>

<details>

<summary>Liên kết tài khoản ngân hàng có mất phí không?</summary>

Hiện tại, việc liên kết tài khoản ngân hàng với VietQR không mất phí. Ngoài ra, sau khi hoàn thành bước xác thực email, bạn sẽ được tặng key 1 tháng kích hoạt nhận biến động số dư. (\*áp dụng trong khung chương trình khi còn hiệu lực)

</details>


# Đồng bộ tài khoản ngân hàng

### Mở phần Cài đặt VietQR Plugin trong quản trị WordPress.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXctuEbGnEqGgqmvaAZ4Kjk9X9D0fWftMMevj_fMK8zb9gyGdsucctDBo2oWgkwOA1i6CfIFvTJ2C9gnok6gR_2efc2_EYRP0y_jNSwKvipsONt-btBGPV34-KIve2RqDodINrYFmgEC9jw-6GB61Q?key=KNO4jW4YArkKaTQtF2r8Xg" alt=""><figcaption></figcaption></figure>

### Sử dụng ứng dụng VietQR trên điện thoại để quét mã QR hiển thị ở trang trên.

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FEG4Yb472wuOXt3k2XQQs%2Fimage.png?alt=media&amp;token=29c42247-975d-4dc3-879f-6d3310c27075" alt=""><figcaption></figcaption></figure>

* Điền thông tin tài khoản ngân hàng cần liên kết.
* Sau khi nhập xong, nhấn Xác nhận để hoàn tất liên kết.

### Sau khi nhấn xác nhận, hệ thống sẽ gửi thông báo thêm TK thành công.

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FCGfBjd9aVbwz8wyrcx9R%2Fimage.png?alt=media&amp;token=80958d31-5a4a-4762-8f86-2cb79321d2f1" alt=""><figcaption></figcaption></figure>

### Bước tiếp theo, hãy chọn tài khoản ngân hàng để tạo mã thanh toán và nhận biến động số dư.

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FW9eOYlp7txqstmKqRVJ7%2Fimage.png?alt=media&amp;token=f9d69209-1180-43a6-84c0-31c6d4f874c1" alt=""><figcaption></figcaption></figure>


# Tạo mã QR và nhận biến động số dư

Sau khi liên kết thành công, chọn item bất kì trên web đặt hàng và chọn thanh toán bằng VietQR.

### Tạo đơn hàng cần thanh toán.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcFl5u_GhQCrCJQx8AkPNPhcUvDrD4bae2x8J4JCOcACRzbSrm4fUt_30WviWWkdDPDwBOXIMIEOTUBkB6wM6B0ZDhW_e1sprfB5KI_NTeP01sLwPROE2GbiGP56gPXDKEjZ6i2UbiTmuQnvhGfyg?key=KNO4jW4YArkKaTQtF2r8Xg" alt=""><figcaption></figcaption></figure>

### Mã QR thanh toán sẽ được hiển thị

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXe-USmCLrc6W0sYjJ05nDnoC53k-Rh5sWNNLinWhhIUMILge3KaKSo_MTuQGR28Er1SwYRGGXVtykIBegd4pjiwVDTdJhGo4wAhcTIRYXruij-TEqPsm5LlmwldZUzqIlP7LoEnmvIwGNA6gP_ToA?key=KNO4jW4YArkKaTQtF2r8Xg" alt=""><figcaption></figcaption></figure>

### Sau khi khách hàng thanh toán thành công, hệ thống sẽ tự động thông báo đơn hàng thanh toán thành công.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeaWOo7D8h_55k6Ndi-0TibMUsPd9KO_B1YNS98tiJDb8yRdhdiCfx5mM_N8h-J_HGqjwNxHMW7acpCXmK0l2GWEboUBjbo2NmB21Em1AcSm0m8JZOd8qOCpYqWuW4e9GwXlhvZfvd-gI3-fSYU?key=KNO4jW4YArkKaTQtF2r8Xg" alt=""><figcaption></figcaption></figure>


# \[FAQs] Câu hỏi thường gặp

<details>

<summary>Làm thế nào để cài đặt Plugin VietQR trên WordPress?</summary>

Bạn cần liên hệ bộ phận kỹ thuật VietQR để yêu cầu cung cấp file Plugin.

</details>

<details>

<summary>Những ngân hàng nào được hỗ trợ để liên kết?</summary>

Hiện tại, VietQR hỗ trợ liên kết với các tài khoản ngân hàng MB và BIDV.

</details>

<details>

<summary>Tôi có thể tạo mã VietQR cho nhiều tài khoản ngân hàng khác nhau không?</summary>

Có, bạn có thể liên kết nhiều tài khoản ngân hàng và chọn tài khoản mong muốn để tạo mã QR trong phần cài đặt plugin.

</details>

<details>

<summary>Làm thế nào để nhận thông báo biến động số dư khi có giao dịch qua mã VietQR?</summary>

Hệ thống VietQR sẽ tự động gửi thông báo biến động số dư sau khi thanh toán thành công, và bạn có thể kiểm tra thông tin này trong phần cài đặt plugin.

</details>

<details>

<summary>Nếu có sự cố trong quá trình đồng bộ tài khoản ngân hàng thì tôi nên làm gì?</summary>

Vui lòng kiểm tra lại kết nối mạng và thông tin tài khoản, hoặc liên hệ với bộ phận hỗ trợ của VietQR.

</details>


# API CHO SẢN PHẨM IOT

IOTAPI giúp cho kết nối song biên đối tác.

API Kết nối Truyền sản phẩm  và dịch vụ :

![](https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2Fvh3ODm5Ok2nqqkPhTYg9%2Fimage.png?alt=media\&token=8b337584-e697-416b-b7c8-4f9133aafa20)![](https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FVMsBdmECA1JNgwHWEHE7%2Fimage.png?alt=media\&token=f1c2f349-3f84-4bda-9b60-441eaef71de2)

<figure><img src="https://3142601633-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDGqts6lCk1fULljyG3r6%2Fuploads%2FIxLZZSyKOWHSjsZEVbo5%2Fimage.png?alt=media&amp;token=29872e4a-42a4-4af4-be67-b2e670fbc858" alt="" width="375"><figcaption></figcaption></figure>

* Trung gian kết nối truyền :thumbsup:

Ngầm định, đối tác và khách hàng sẽ kết nối với hệ thống API thông qua 6 tham số nút bấm.


# Api Tbị Gọi quầy

QUẦYầy


# API cho thiết bị PAYBox

PAYBox


# API cho thiết bị SoundBox

API cho thiết bị IOT VietQR Sound box

**VietQR cung cấp các API hỗ trợ nhà phát triển thiết bị phần cứng và nhà cung cấp thiết bị dễ dàng kết nối hệ thống của họ với nền tảng VietQR. Thông qua kết nối này, các thiết bị có thể tích hợp và sử dụng phần mềm VietQR, ứng dụng VietQR, cùng toàn bộ hệ sinh thái VietQR để phát triển hoạt động kinh doanh và cung cấp dịch vụ SoundBox đến khách hàng một cách hiệu quả.**

Giới thiệu chung :&#x20;

SoundBox VietQR là giải pháp công nghệ tiên tiến, được thiết kế để hỗ trợ các doanh nghiệp trong việc quản lý thanh toán một cách tiện lợi và chuyên nghiệp. Thiết bị này giúp thông báo giao dịch ngay lập tức qua âm thanh, mang lại trải nghiệm hiện đại và hiệu quả cho cả người bán và khách hàng.

**Tính năng nổi bật:**

&#x20;       • Thông báo âm thanh thời gian thực: Xác nhận giao dịch nhanh chóng và chính xác ngay khi hoàn tất.

&#x20;       • Kết nối API thông minh: Dễ dàng tích hợp với các hệ thống quản lý và thanh toán hiện có.

&#x20;       • Thiết kế nhỏ gọn, thân thiện: Phù hợp với nhiều không gian kinh doanh khác nhau.

&#x20;       • Tương thích đa kênh: Hỗ trợ thanh toán qua VietQR và nhiều phương thức thanh toán hiện đại khác\
**Ứng dụng:    SoundBox VietQR là giải pháp lý tưởng cho**

&#x20;       • Cửa hàng bán lẻ

&#x20;       • Quán cà phê, nhà hàng

&#x20;       • Doanh nghiệp vừa và nhỏ

&#x20;       • Các điểm cung cấp dịch vụ công cộng

**Lợi ích:**

&#x20;       • Tăng hiệu quả xử lý giao dịch

&#x20;       • Nâng cao trải nghiệm khách hàng

&#x20;       • Hạn chế sai sót trong việc xác nhận thanh toán


# Bảng mã lỗi

Mô tả các mã lỗi trong hệ thống.

<table><thead><tr><th width="75">No</th><th width="85">Mã lỗi</th><th>Mô tả lỗi</th></tr></thead><tbody><tr><td>5</td><td>E05</td><td>Unknown error.</td></tr><tr><td>6</td><td>E24</td><td>No bank found for the given bankCode.</td></tr><tr><td>7</td><td>E39</td><td>Invalid checkSum.</td></tr><tr><td>8</td><td>E42</td><td>Đối tác không có quyền truy cập API Hoàn tiền  (API Refund)</td></tr><tr><td>9</td><td>E43</td><td>Refund thất bại (Nguyên nhân chưa xác định)</td></tr><tr><td>10</td><td>E44</td><td>Mã tham chiếu (referenceNumber) không tồn tại hoặc không thể hoàn tiền cho giao dịch vãng lai</td></tr><tr><td>11</td><td>E45</td><td>Số tiền hoàn không chính xác (Tổng tiền hoàn phải bé hơn hoặc bằng giá trị giao dịch đã thanh toán)</td></tr><tr><td>12</td><td>E46</td><td>Invalid Request Body/Parameter.</td></tr><tr><td>13</td><td>E51</td><td>bankCode không chính xác</td></tr><tr><td>16</td><td>E74</td><td>Invalid token.</td></tr><tr><td>17</td><td>E75</td><td>Test Callback không khả dụng</td></tr><tr><td>18</td><td>E76</td><td>Tài khoản chưa đăng ký dịch vụ hoặc đã bị khóa</td></tr><tr><td>19</td><td>E77</td><td>Tài khoản ngân hàng chưa được đối tác đăng ký thành công</td></tr><tr><td>20</td><td>E95</td><td>Loại filter không đúng (field "type" in request body API Check Order)</td></tr><tr><td>21</td><td>E96</td><td>Không tìm thấy giao dịch</td></tr><tr><td>22</td><td>E104</td><td>Không tìm thấy thông tin đăng ký đại lý của đối tác</td></tr><tr><td>23</td><td>E158</td><td>Một request khác đang được xử lý</td></tr></tbody></table>

<table><thead><tr><th width="146">Error Code</th><th>Message (Hiển thị trên web/app)</th><th>Description (Giải thích cho nội bộ)</th></tr></thead><tbody><tr><td>E01</td><td>Mật khẩu không trùng khớp</td><td>Mật khẩu không trùng khớp</td></tr><tr><td>E02</td><td>Số điện thoại đã tồn tại</td><td>Tài khoản đã tồn tại</td></tr><tr><td>E03</td><td>Không thể tạo tài khoản</td><td>Không thể tạo tài khoản</td></tr><tr><td>E04</td><td>Lỗi không xác định</td><td>Không thể thực hiện thao tác này. Vui lòng thử lại sau</td></tr><tr><td>E05</td><td>Lỗi không xác định</td><td>Phiên đăng nhập hết hạn</td></tr><tr><td>E06</td><td>Không thể liên kết. Tài khoản ngân hàng này đã được thêm trước đó</td><td>Không thể liên kết. Tài khoản ngân hàng này đã được thêm trước đó (Bank Account Receive)</td></tr><tr><td>E07</td><td>Thành viên không tồn tài trong hệ thống</td><td>Thành viên không tồn tài trong hệ thống</td></tr><tr><td>E08</td><td>Thành viên đã được thêm vào tài khoản trước đó</td><td>Thành viên đã được thêm vào tài khoản trước đó</td></tr><tr><td>E09</td><td>Không thể thêm thành viên vào tài khoản</td><td>Không thể thêm thành viên vào tài khoản</td></tr><tr><td>E10</td><td>Không thể thêm mẫu nội dung chuyển khoản</td><td>Không thể thêm mẫu nội dung chuyển khoản</td></tr><tr><td>E11</td><td>Không thể xoá mẫu nội dung chuyển khoản</td><td>Không thể xoá mẫu nội dung chuyển khoản</td></tr><tr><td>E12</td><td>Không thể liên kết. Tài khoản thanh toán này đã được thêm trước đó</td><td>Không thể liên kết. Tài khoản thanh toán này đã được thêm trước đó (Bank Account Payment)</td></tr><tr><td>E13</td><td>Thêm tài khoản thanh toán thất bại</td><td>Thêm tài khoản thanh toán thất bại</td></tr><tr><td>E14</td><td>Không thể tạo doanh nghiệp</td><td>Không thể tạo doanh nghiệp</td></tr><tr><td>E15</td><td>CMND/CCCD không hợp lệ</td><td>293 - CMND/CCCD không hợp lệ</td></tr><tr><td>E16</td><td>Trạng thái TK ngân hàng không hợp lệ</td><td>40503 - Trạng thái TK ngân hàng không hợp lệ</td></tr><tr><td>E17</td><td>TK ngân hàng không hợp lệ</td><td>1020 - TK ngân hàng không hợp lệ</td></tr><tr><td>E18</td><td>Tên chủ TK không hợp lệ</td><td>40600 - Tên chủ TK không hợp lệ</td></tr><tr><td>E19</td><td>Số ĐT không hợp lệ</td><td>219 - Số ĐT không hợp lệ</td></tr><tr><td>E20</td><td>TK ngân hàng không tồn tại</td><td>40017 - TK ngân hàng không tồn tại</td></tr><tr><td>E21</td><td>Có vấn đề xảy ra khi gửi OTP. Vui lòng thử lại sau</td><td>40506 - Có vấn đề xảy ra khi gửi OTP. Vui lòng thử lại sau</td></tr><tr><td>E22</td><td>Không thể đăng ký nhận BĐSD. Vui lòng thử lại sau</td><td>40509 - Không thể đăng ký nhận BĐSD. Vui lòng thử lại sau</td></tr><tr><td>E23</td><td>TK đã đăng ký nhận BĐSD</td><td>40504 - TK đã đăng ký nhận BĐSD</td></tr><tr><td>E24</td><td>Không tìm thấy ngân hàng tương ứng với mã Code</td><td>Không tìm thấy ngân hàng tương ứng với mã Code</td></tr><tr><td>E25</td><td>Không tìm thấy tài khoản ngân hàng đã liên kết trong hệ thống VietQR</td><td>Không tìm thấy tài khoản ngân hàng đã liên kết trong hệ thống VietQR</td></tr><tr><td>E26</td><td>Nội dung thanh toán vượt quá giới hạn (bé hơn 50 kí tự - VietQR Plus) (bé hơn 19 kí tự - VietQR Pro)</td><td>Nội dung thanh toán vượt quá giới hạn (bé hơn 50 kí tự - VietQR Plus) (bé hơn 19 kí tự - VietQR Pro)</td></tr><tr><td>E27</td><td>MB Bank trả lỗi 4630</td><td>MB Bank trả lỗi 4630</td></tr><tr><td>E28</td><td>MB Bank trả lỗi 237</td><td>MB Bank trả lỗi 237</td></tr><tr><td>E29</td><td>MB Bank trả lỗi 002</td><td>MB Bank trả lỗi 002</td></tr><tr><td>E30</td><td>update Sync Wp có Request Body NULL</td><td>update Sync Wp có Request Body NULL</td></tr><tr><td>E31</td><td></td><td>update Sync Wp có bankId không hợp lệ</td></tr><tr><td>E32</td><td>Thông tin TK Ngân hàng không hợp lệ (MB trả lỗi)</td><td>Thông tin TK Ngân hàng không hợp lệ (MB trả lỗi)</td></tr><tr><td>E33</td><td>Thông tin PIN sai khi sử dụng api lấy thông tin TK ngân hàng của MB</td><td>Thông tin PIN sai khi sử dụng api lấy thông tin TK ngân hàng của MB</td></tr><tr><td>E34</td><td>Invalid Request Body Invalid (orderId &#x3C;= 13 ký tự, content &#x3C;= 19 ký tự)</td><td>Invalid Request Body Invalid (orderId &#x3C;= 13 ký tự, content &#x3C;= 19 ký tự)</td></tr><tr><td>E35</td><td>Tài khoản ngân hàng không tồn tại trong gói VietQR Pro</td><td>Tài khoản ngân hàng không tồn tại trong gói VietQR Pro</td></tr><tr><td>E36</td><td>Tài khoản ngân hàng không tồn tại trong hệ thống</td><td>Tài khoản ngân hàng không tồn tại trong hệ thống</td></tr><tr><td>E37</td><td>Request Body khi generate token Ecommerce empty or null</td><td>Request Body khi generate token Ecommerce empty or null</td></tr><tr><td>E38</td><td>Không tìm thấy account_information trong hệ thống (Ecommerce)</td><td>Không tìm thấy account_information trong hệ thống (Ecommerce)</td></tr><tr><td>E39</td><td>Invalid checkSum</td><td>Invalid checkSum</td></tr><tr><td>E40</td><td>Không tìm thấy bank account liên kết trong hệ thống</td><td>Không tìm thấy bank account liên kết trong hệ thống</td></tr><tr><td>E41</td><td>Invalid checkSum (SaB)</td><td>Invalid checkSum (SaB)</td></tr><tr><td>E42</td><td>TK chưa được lên luồng 2 (API Service của SaB)</td><td>TK chưa được lên luồng 2 (API Service của SaB)</td></tr><tr><td>E43</td><td>Hoàn tiền thất bại (API Service của SaB)</td><td>Hoàn tiền thất bại (API Service của SaB)</td></tr><tr><td>E44</td><td>FT Code không tồn tại hoặc không được hoàn tiền</td><td>FT Code không tồn tại hoặc không được hoàn tiền</td></tr><tr><td>E45</td><td>Số tiền hoàn không hợp lệ</td><td>Số tiền hoàn không hợp lệ</td></tr><tr><td><br>E46</td><td>Có vấn đề xảy ra khi thực hiện yêu cầu. Vui lòng thử lại sau</td><td>Invalid request body</td></tr><tr><td>E47</td><td>Thông tin đã tồn tại trong danh bạ</td><td>Thông tin đã tồn tại trong danh bạ</td></tr><tr><td>E48</td><td>Có vấn đề xảy ra khi thêm danh bạ. Vui lòng thử lại sau</td><td>Insert thất bại. Lỗi hệ thống</td></tr><tr><td>E49</td><td>Có vấn đề xảy ra khi cập nhật danh bạ. Vui lòng thử lại sau</td><td>Trạng thái update danh bạ không hợp lệ.</td></tr><tr><td>E50</td><td>Số điện thoại không tồn tại trong hệ thống</td><td>Số điện thoại không tồn tại, module API tạo QR nạp tiền vào hệ thống VietQR VN</td></tr><tr><td>E51</td><td>Mã bankCode không hợp lệ</td><td>Module sync transaction RPA</td></tr><tr><td>E52</td><td>Bank account không tồn tại trong hệ thống</td><td>Bank account không tồn tại trong hệ thống</td></tr><tr><td>E53</td><td>List giao dịch không hợp lệ</td><td>List giao dịch không hợp lệ</td></tr><tr><td>E54</td><td>Ghi nhận hệ thống RPA lỗi/Invalid request body</td><td>Ghi nhận hệ thống RPA lỗi/Invalid request body</td></tr><tr><td>E55</td><td>Xác nhận mật khẩu sai.</td><td>Xác nhận mật khẩu sai khi xác nhận thanh toán</td></tr><tr><td>E56</td><td>Hệ thống đang xảy ra vấn đề. Vui lòng thử lại sau.</td><td>Sai Payment type</td></tr><tr><td>E57</td><td>Số điện thoại không đúng định dạng. Vui lòng kiểm tra lại thông tin trên và thực hiện lại.</td><td>Số điện thoại không đúng định dạng</td></tr><tr><td>E58</td><td>Nhà mạng không hợp lệ. Vui lòng kiểm tra lại thông tin trên và thực hiện lại.</td><td>Carrier Type ID sai</td></tr><tr><td>E59</td><td>Hệ thống đang xảy ra vấn đề. Vui lòng thử lại sau.</td><td>Không tìm thấy thông tin theo userId - userId không hợp lệ</td></tr><tr><td>E60</td><td>Hệ thống đang xảy ra vấn đề. Vui lòng thử lại sau.</td><td>Recharge type sai => Số tiền nạp vào số điện thoại không hợp lệ</td></tr><tr><td>E61</td><td>Số dư VQR không đủ. Vui lòng nạp thêm VQR để thực hiện nạp tiền điện thoại</td><td>Số dư không đủ</td></tr><tr><td>E62</td><td>Giao dịch thất bại.</td><td>Giao dịch thất bại, VNPT Epay response.</td></tr><tr><td>E63</td><td>Hệ thống nạp tiền đang bảo trì. Vui lòng thử lại sau</td><td>VNPT bảo trì, response từ VNPT Epay.</td></tr><tr><td>E64</td><td>Hệ thống nạp tiền đang bận. Vui lòng thử lại sau</td><td>VNPT traffic busy (đang quá tải)</td></tr><tr><td>E65</td><td>Xác thực thất bại. Vui lòng thử lại sau</td><td>Mã OTP cho giao dịch này không khớp hoặc đã hết hạn request</td></tr><tr><td>E71</td><td>Kết nối Telegram/Lark thất bại</td><td>Kết nối Telegram thất bại. Không gửi được first message qua chatID/webhook</td></tr><tr><td>E72</td><td>Không thể cập nhật trạng thái giọng nói</td><td>Sai type</td></tr><tr><td>E67</td><td>User setting not found (lỗi này không hiển thị cho user)</td><td>User setting not found</td></tr><tr><td>E68</td><td>Không thể get voice (lỗi này không hiển thị cho user)</td><td>Sai type</td></tr><tr><td>E69</td><td>User disable voice (lỗi này không hiển thị cho user)</td><td>User disable voice (lỗi này không hiển thị cho user)</td></tr><tr><td>E70</td><td>Phương thức thanh toán không hợp lệ</td><td>Sai payment method</td></tr><tr><td>E73</td><td>BankAccount đã tồn tại trong hệ thống</td><td>BankAccount đã tồn tại trong hệ thống</td></tr><tr><td>E74</td><td>Invalid Token Key</td><td>test callback API</td></tr><tr><td>E75</td><td>Service is not available</td><td>Dịch vụ callbackAPI không khả dụng (cho môi trường product)</td></tr><tr><td>E76</td><td>Merchant is not existed</td><td>Khách hàng chưa được đăng ký trong hệ thống</td></tr><tr><td>E77</td><td>TK ngân hàng không khớp với thông tin của khách hàng</td><td>Không tìm được account_customer_bank by bank_account và customer_sync_id</td></tr><tr><td>002</td><td>Invalid amount</td><td></td></tr><tr><td>009</td><td>content is invalid</td><td></td></tr><tr><td>010</td><td>bankAccount is invalid</td><td></td></tr><tr><td>003</td><td>Invalid Transaction Type</td><td></td></tr><tr><td>E78</td><td>Not found lark info</td><td>Not found lark info</td></tr><tr><td>E79</td><td>Not found telegram info</td><td>Not found telegram info</td></tr><tr><td>E80</td><td>Không tìm thấy loại service của KH</td><td>CustomerSync</td></tr><tr><td>E81</td><td>Không tìm thấy thông tin của KH</td><td>CustomerSync</td></tr><tr><td>E82</td><td>Không tìm thấy field "access_token" trong Response Body thuộc API get Token của khách hàng.</td><td>Không tìm thấy field "access_token" trong Response Body thuộc API get Token của khách hàng.</td></tr><tr><td>E83</td><td>TK ngân hàng đã tồn tại trong merchant này</td><td></td></tr><tr><td>E84</td><td>TK ngân hàng chưa liên kết trong hệ thống VietQR. Vui lòng liên hệ KH liên kết TK MB Bank này.</td><td>ONLY GOLIVE response</td></tr><tr><td>E85</td><td>Merchant name đã tồn tại trong hệ thống</td><td></td></tr><tr><td>E86</td><td>Địa chỉ đã được khai báo trước đó. Vui lòng nhập lại thông tin khác</td><td></td></tr><tr><td>E87</td><td>Thông tin kết nối không hợp lệ (URL/ IP + PORT không hợp lệ.)</td><td></td></tr><tr><td>E88</td><td></td><td></td></tr><tr><td>E89</td><td>Invalid insert type (Module add bank fee)</td><td>Invalid insert type (Module add bank fee)</td></tr><tr><td>E90</td><td>Not found Service Fee (Module add bank fee)</td><td>Not found Service Fee (Module add bank fee)</td></tr><tr><td>E91</td><td>Banks not found</td><td>Banks not found (Module insertBankFee)</td></tr><tr><td>E92</td><td>Bloc Data is over 50 records</td><td>Bloc Data is over 50 records (Insert Vcards)</td></tr><tr><td>E93</td><td>Account không phải là đại lý</td><td>Account không phải là đại lý</td></tr><tr><td>E94</td><td>Not found Transaction QR Link</td><td>Not found Transaction QR Link</td></tr><tr><td>E95</td><td>Invalid Check Type</td><td>API Check order for all merchant</td></tr><tr><td>E96</td><td>Not Found transaction check order</td><td>API Check order for all merchant</td></tr><tr><td>E97</td><td>Invalid RefId</td><td>API Cancel QR Link Transaction</td></tr><tr><td>E98</td><td>Service Partner is not available</td><td>Service Partner is not available</td></tr><tr><td>E99</td><td>Get token Vhitek Invalid</td><td>Get token Vhitek Invalid</td></tr><tr><td>E100</td><td>Check Email Vhitek Error</td><td>Check Email Vhitek Error</td></tr><tr><td>E101</td><td>Tài khoản ngân hàng không tồn tại hoặc chưa được liên kết với hệ thống VietQR</td><td>Tài khoản ngân hàng không tồn tại hoặc chưa được liên kết với hệ thống VietQR</td></tr><tr><td>E102</td><td>Dịch vụ kích hoạt máy bán hàng không khả dụng</td><td>Not found merchant info to active terminal</td></tr><tr><td>E103</td><td>Kích hoạt máy thất bại</td><td>Sync TID MB FAILED</td></tr><tr><td>E104</td><td>Merchant không khả dụng</td><td>Merchant not existed (module refund)</td></tr><tr><td>E105</td><td>Tên đại lý đã tồn tại trong hệ thống</td><td>Invalid Merchant Name</td></tr><tr><td>E106</td><td>Invalid Environment to insert customer Sync Mapping</td><td>Invalid Environment to insert customer Sync Mapping</td></tr><tr><td>E107</td><td>Invalid Invironment when insert customer Sync</td><td>Invalid Invironment when insert customer Sync</td></tr><tr><td>E108</td><td>Invalid MMS Active/Not found BankAccount</td><td>Invalid MMS Active/Not found BankAccount</td></tr><tr><td>E109</td><td>Invalid BankCode</td><td>Invalid BankCode module request OTP linked bankAccount</td></tr><tr><td>E110</td><td>Mã cửa hàng đã tồn tại trong hệ thống</td><td>TerminalCode already existed in the system</td></tr><tr><td>E111</td><td>Cửa hàng đã tồn tại tài khoản ngân hàng</td><td>Terminal already have bank-account</td></tr><tr><td>E112</td><td>Tài khoản đã đăng ký dịch vụ thanh toán định danh</td><td>BIDV Merchant VA is registered</td></tr><tr><td>E113</td><td>Dữ liệu cửa hàng không khả dụng</td><td>KH không được truy cập vào terminal này</td></tr><tr><td>E114</td><td>Tài khoản chưa được liên kết trong hệ thống</td><td>BIDV Merchant VA first condition</td></tr><tr><td>E115</td><td>Bạn không có quyền chỉnh sửa giao dịch này</td><td>User dont have permission to do this action</td></tr><tr><td>E116</td><td>Tính năng đang bảo trì</td><td>Tính năng đang bảo trì</td></tr><tr><td>E117</td><td>Không tìm thấy Chứng minh thư, mã số thuế trên hệ thống ngân hàng.</td><td>request OTP BIDV</td></tr><tr><td>E118</td><td>Không tìm thấy SĐT trên hệ thống ngân hàng.</td><td>request OTP BIDV</td></tr><tr><td>E119</td><td>Số tài khoản không tồn tại trên hệ thống ngân hàng.</td><td>request OTP BIDV</td></tr><tr><td>E120</td><td>Tài khoản khách hàng bị tạm giữ. Vui lòng liên hệ với ngân hàng thụ hưởng để kiểm tra vấn đề.</td><td>request OTP BIDV</td></tr><tr><td>E121</td><td>Tài khoản thanh toán không hoạt động. Vui lòng liên hệ với ngân hàng thụ hưởng để kiểm tra vấn đề.</td><td>request OTP BIDV</td></tr><tr><td>E122</td><td>Trạng thái đăng ký dịch vụ BIDV Online không hợp lệ. Vui lòng liên hệ với ngân hàng thụ hưởng để kiểm tra vấn đề.</td><td>request OTP BIDV</td></tr><tr><td>E123</td><td>Quý khách chưa đăng ký dịch vụ E-Banking (BIDV Online/BIDV SmartBanking) hoặc dịch vụ đang KHÔNG ở trạng thái hoạt động. Vui lòng liên hệ với ngân hàng thụ hưởng để kiểm tra vấn đề.</td><td>request OTP BIDV</td></tr><tr><td>E124</td><td>Có lỗi trong quá trình xác thực OTP (Mã OTP không hợp lệ)</td><td>confirm OTP BIDV</td></tr><tr><td>E125</td><td>Có lỗi trong quá trình xác thực OTP hoặc khách hàng bị khóa OTP tạm thời do nhập sai OTP 5 lần liên tiếp</td><td>confirm OTP BIDV</td></tr><tr><td>E126</td><td>Bạn không có quyền thực hiện mở khóa TK ngân hàng này</td><td>Tài khoản ngân hàng không thuộc sở hữu của user</td></tr><tr><td>E127</td><td>Mã không chính xác</td><td>Invalid Key</td></tr><tr><td>E128</td><td>Không tìm thấy yêu cầu, vui lòng thử lại</td><td>Chưa request active => call api confirm sẽ ra lỗi này</td></tr><tr><td>E129</td><td>Quá thời gian thực hiện, vui lòng thử lại</td><td>Hết hạn</td></tr><tr><td>E130</td><td>Key đã được sử dụng, vui lòng thử lại</td><td>Key đã được sử dụng</td></tr><tr><td>E131</td><td>Key không hợp lệ, vui lòng thử lại</td><td>Key invalid</td></tr><tr><td>E132</td><td>Gói phí không tồn tại, vui lòng thử lại</td><td>Gói phí không tồn tại</td></tr><tr><td>E133</td><td>Không tìm thấy thông tin tài khoản ngân hàng. Vui lòng kiểm tra kỹ lại thông tin</td><td>BIDV Merchant VA is registered</td></tr><tr><td>E134</td><td>Thông tin tên khách hàng không đúng.<br>Vui lòng kiểm tra lại thông tin đăng ký.</td><td>BIDV Merchant VA request OTP</td></tr><tr><td>E135</td><td>Mã OTP không hợp lệ. Vui lòng kiểm tra lại thông tin</td><td>BIDV Merchant VA confirm OTP register</td></tr><tr><td>E136</td><td>Không tìm thấy CMT/CCCD/HC trên hệ thống ngân hàng.<br>Vui lòng kiểm tra lại thông tin đăng ký.</td><td>BIDV Merchant VA request OTP</td></tr><tr><td>E137</td><td>Không tìm thấy SĐT trên hệ thống ngân hàng. Vui lòng kiểm tra lại thông tin đăng ký</td><td>BIDV Merchant VA request OTP</td></tr><tr><td>E138</td><td>Quý khách bị khoá tạm thời do nhập sai mã OTP quá 5 lần. Vui lòng thử lại sau</td><td>BIDV Merchant VA confirm OTP register</td></tr><tr><td>E139</td><td>Tài khoản không hoạt động. Vui lòng kiểm tra lại thông tin đăng ký</td><td>BIDV Merchant VA request OTP</td></tr><tr><td>E140</td><td>Item đã được thêm trước đó</td><td></td></tr><tr><td>E141</td><td>Đơn giá danh mục hàng hoá/dịch vụ chưa được chỉnh sửa.</td><td></td></tr><tr><td>E142</td><td>Reset password thất bại</td><td></td></tr><tr><td>E143</td><td>Số điện thoại không đúng</td><td></td></tr><tr><td>E144</td><td>Số điện thoại đã tồn tại</td><td></td></tr><tr><td>E145</td><td>Người dùng đã tồn tại trạng thái này</td><td></td></tr><tr><td>E146</td><td>Cập nhât người dùng thất bại</td><td></td></tr><tr><td>E147</td><td>Không tìm thấy người dùng</td><td></td></tr><tr><td>E148</td><td>QR type không chính xác</td><td>QR Feed</td></tr><tr><td>E149</td><td>Không tìm thấy folder</td><td>QR Feed</td></tr><tr><td>E150</td><td>Đại lý hiện tại không khả dụng truy cập API này</td><td>Đại lý hiện tại không khả dụng truy cập API này</td></tr><tr><td>E151</td><td>Ngân hàng (bankCode) chưa hỗ trợ tạo QR đối soát (qrType) loại này</td><td>Ngân hàng (bankCode) chưa hỗ trợ tạo QR đối soát (qrType) loại này</td></tr><tr><td>E152</td><td>terminalCode không được đồng bộ với tài khoản ngân hàng hiện tại</td><td>terminalCode không được đồng bộ với tài khoản ngân hàng hiện tại</td></tr><tr><td>E153</td><td>Thông tin bị được lặp lại trong Request Body (terminalCode phải là duy nhất khi đồng bộ)</td><td>Thông tin bị được lặp lại trong Request Body (terminalCode phải là duy nhất khi đồng bộ)</td></tr><tr><td>E154</td><td>Không tìm thấy thông tin đại lý dựa trên</td><td>Không tìm thấy thông tin đại lý dựa trên</td></tr><tr><td>E155</td><td>Tài khoản ngân hàng đã được đồng bộ bởi một đại lý (đối tác) khác</td><td>Tài khoản ngân hàng đã được đồng bộ bởi một đại lý (đối tác) khác</td></tr><tr><td>E156</td><td>Input thiếu hoặc sai định dạng</td><td>Update mã QR</td></tr><tr><td>E157</td><td>Giao dịch chỉ cho phép hoàn tiền một lần</td><td>Giao dịch chỉ cho phép hoàn tiền một lần</td></tr><tr><td>E158</td><td>Đang xử lí 1 request khác</td><td>Xử lí queue</td></tr><tr><td>E159</td><td>CCCD không chính xác</td><td></td></tr><tr><td>E160</td><td>SĐT không chính xác</td><td></td></tr><tr><td>E161</td><td>Không tìm thấy thông tin của đại lý</td><td>Không tìm thấy thông tin của đại lý</td></tr><tr><td>E162</td><td>TK đã được xác thực email</td><td>TK đã được xác thực email</td></tr><tr><td>E163</td><td>Mã QR ecommerce không tồn tại</td><td>Mã QR ecommerce không tồn tại</td></tr><tr><td>E164</td><td>Mã điểm bán / mã điểm bán phụ không hợp lệ</td><td>Mã điểm bán / mã điểm bán phụ không hợp lệ</td></tr><tr><td>E165</td><td>Mã đơn hàng (orderId) đã tồn tại</td><td>Mã đơn hàng (orderId) đã tồn tại</td></tr><tr><td>E166</td><td>Nội dung thanh toán không hợp lệ (chỉ cho phép kí tự latin, không chứa kí tự đặc biệt, độ dài &#x3C;19)</td><td>Nội dung thanh toán không hợp lệ (chỉ cho phép kí tự latin, không chứa kí tự đặc biệt, độ dài &#x3C;19)</td></tr><tr><td>E167</td><td>GroupCode không hợp lệ</td><td>GroupCode không hợp lệ</td></tr><tr><td>E171</td><td>Số tài khoản chưa được đăng ký</td><td></td></tr><tr><td>E172</td><td>Số tài khoản chưa được liên kết</td><td></td></tr><tr><td>E175</td><td>OTP hết hiệu lực</td><td>OTP dùng để verify email chỉ có hiệu lực trong 10 phút</td></tr><tr><td>E176</td><td>Key của tài khoản này không chính xác</td><td>Key của tài khoản này không dùng được cho tài khoản khác</td></tr><tr><td>E177</td><td>OTP không chính xác</td><td>nhập OTP không chính xác</td></tr><tr><td>E178</td><td>OTP đã bị vô hiệu hóa</td><td>dùng OTP mới nhất để xác thực</td></tr><tr><td>E179</td><td>Không thể tạo mới Merchant</td><td>Tạo thành công Merchant trên server nhưng không thể tạo dưới database</td></tr><tr><td>E180</td><td>Không thể cập nhật Merchant</td><td>Cập nhật thành công Merchant trên server nhưng không thể cập nhật dưới database</td></tr><tr><td>E181</td><td>Không thể tạo Terminal với Merchant không xác định</td><td>Tạo Terminal với Marchant không có sẵn hoặc không tạo mới với merchantName sẽ không được phép</td></tr><tr><td>E182</td><td>Mật khẩu mới trùng mật khẩu cũ</td><td>Mật khẩu mới trùng mật khẩu cũ</td></tr><tr><td>E183</td><td>Cập nhật MerchantConnection thất bại</td><td>Truyền sai input</td></tr><tr><td>E184</td><td>Xóa MerchantConnection thất bại</td><td>Không truyền id hoặc id rỗng</td></tr><tr><td>E185</td><td>Hiển thị danh sách Terminal thất bại</td><td>Không thể lấy danh sách</td></tr><tr><td>E186</td><td>Lấy thông tin Terminal thất bại</td><td>Không thể lấy thông tin hoăc không có thông tin</td></tr><tr><td>E187</td><td>Cập nhật Terminal thất bại</td><td>Truyền thông tin không thay đổi so với bản cũ</td></tr><tr><td>E188</td><td>Lấy thông tin merchant thất bại</td><td>Không tìm thấy merchant</td></tr><tr><td>E189</td><td></td><td></td></tr><tr><td>E190</td><td>Hiển thị danh sách Merchant đã xóa thất bại</td><td>Không thể lấy danh sách</td></tr><tr><td>E191</td><td>Lấy thông tin khách hàng thất bại</td><td>Không tìm thấy khách hàng</td></tr><tr><td>E192</td><td>Permission not found</td><td>Permission not found</td></tr><tr><td>E193</td><td>Merchant role not found</td><td>Merchant role not found</td></tr><tr><td>E194</td><td>The device code of the box device is duplicated</td><td>The device code of the box device is duplicated</td></tr><tr><td>E195</td><td>The certificate of the box device is duplicated</td><td>The certificate of the box device is duplicated</td></tr><tr><td>E196</td><td>Status of the box device is not active</td><td></td></tr><tr><td>E197</td><td>Status of the box device is not inactive</td><td></td></tr><tr><td>E198</td><td>Status of the box device is deleted</td><td></td></tr><tr><td>E199</td><td>Token has expired</td><td>Token đã hết hạn</td></tr><tr><td>E200</td><td>Invalid signature</td><td>Signature không hợp lệ</td></tr><tr><td>E201</td><td>Invalid JWT token</td><td>Token có định dạng không hợp lệ</td></tr><tr><td>E202</td><td>Unsupported JWT</td><td>JWT không được hỗ trợ</td></tr><tr><td>E203</td><td>Token is null or empty</td><td>Token rỗng hoặc null</td></tr><tr><td>E204</td><td>Not have the necessary permissions</td><td></td></tr><tr><td>E205</td><td>The terminal code of terminal is duplicated</td><td>The terminal code of terminal is duplicated</td></tr><tr><td>E206</td><td>Email is invalid</td><td>Email is invalid</td></tr><tr><td>E207</td><td>Email is not verified</td><td>Email is not verified</td></tr><tr><td>E208</td><td>The product id of the product price is duplicated</td><td>The product id of the product price is duplicated</td></tr><tr><td>E209</td><td>Category not found</td><td>Category not found</td></tr><tr><td>E210</td><td>Category was deleted</td><td>Category was deleted</td></tr><tr><td>E211</td><td>Product price not found</td><td>Product price not found</td></tr><tr><td>E212</td><td>Amount of product price not change</td><td>Amount of product price not change</td></tr><tr><td>E213</td><td>Product not found</td><td>Product not found</td></tr><tr><td>E214</td><td>ProductPriceHistory not found</td><td>ProductPriceHistory not found</td></tr><tr><td>E215</td><td>Hoàn tiền thất bại (Hệ thống ngân hàng quá tải - thử lại sau)</td><td>Hoàn tiền thất bại (Hệ thống ngân hàng quá tải - thử lại sau)</td></tr><tr><td>E216</td><td>Tài khoản ngân hàng của đối tác không thể hoàn tiền (TK ngân hàng đã bị khóa hoặc sử dụng ví điện tử để thanh toán)</td><td>Tài khoản ngân hàng của đối tác không thể hoàn tiền (TK ngân hàng đã bị khóa hoặc sử dụng ví điện tử để thanh toán)</td></tr><tr><td>E217</td><td>Tài khoản ngân hàng của đối tác chưa hợp tác với hệ thống của NAPAS</td><td>Tài khoản ngân hàng của đối tác chưa hợp tác với hệ thống của NAPAS</td></tr><tr><td>E218</td><td>Hệ thống ngân hàng ghi nhận mã giao dịch hiện tại không thể hoàn tiền</td><td>Hệ thống ngân hàng ghi nhận mã giao dịch hiện tại không thể hoàn tiền</td></tr><tr><td>E219</td><td>Amount of transactionList is less than Amount of invoiceItemList</td><td>Amount of transactionList is less than Amount of invoiceItemList</td></tr><tr><td>E220</td><td>Transaction not refunded</td><td>Transaction not refunded</td></tr><tr><td>E221</td><td>Device không đăng ký topic nhận password</td><td>Thiết bị không online hoặc chưa cập nhật phần mềm</td></tr><tr><td>E222</td><td>Lỗi trả về của đối tác không đúng format quy định bởi VietQR</td><td>Lỗi trả về của đối tác không đúng format quy định bởi VietQR</td></tr><tr><td>E223</td><td>Lỗi máy không được bật</td><td>Lỗi máy không được bật</td></tr><tr><td>E224</td><td>Lỗi máy không tồn tại</td><td>Lỗi máy không tồn tại</td></tr><tr><td>E225</td><td>lỗi mã đã giao dịch trùng lặp</td><td>Lỗi mã đã giao dịch trùng lặp</td></tr><tr><td>E226</td><td>Đã hết thời gian thực hiện, vui lòng thử lại</td><td>Session Token hết hạn</td></tr><tr><td>E227</td><td>Có lỗi xảy ra, vui lòng thử lại</td><td>Session Token không thể sử dụng cho TK khác</td></tr><tr><td>E228</td><td>Đã gửi OTP quá 3 lần trong 1 ngày</td><td>Đã gửi OTP quá 3 lần trong 1 ngày</td></tr><tr><td>E229</td><td>OTP cũ chưa hết hạn (5p)</td><td>OTP cũ chưa hết hạn (5p)</td></tr></tbody></table>


# Danh sách mã ngân hàng

Mã danh sách các ngân hàng hỗ trợ thanh toán quét mã VietQR

<table><thead><tr><th width="138.333251953125">bank_code</th><th width="431">bank_name</th><th>bank_short_name</th></tr></thead><tbody><tr><td>TCB</td><td>Ngân hàng TMCP Kỹ thương Việt Nam</td><td>Techcombank</td></tr><tr><td>COOPBANK</td><td>Ngân hàng Hợp tác xã Việt Nam</td><td>COOPBANK</td></tr><tr><td>ACB</td><td>Ngân hàng TMCP Á Châu</td><td>ACB</td></tr><tr><td>KBHN</td><td>Ngân hàng Kookmin - Chi nhánh Hà Nội</td><td>KookminHN</td></tr><tr><td>IBK</td><td>Ngân hàng Công nghiệp Hàn Quốc</td><td>IBK</td></tr><tr><td>VAB</td><td>Ngân hàng TMCP Việt Á</td><td>VietABank</td></tr><tr><td>MSB</td><td>Ngân hàng TMCP Hàng Hải</td><td>MSB</td></tr><tr><td>ABB</td><td>Ngân hàng TMCP An Bình</td><td>ABBANK</td></tr><tr><td>LIOBANK</td><td>Ngân hàng số LioBank</td><td>LioBank</td></tr><tr><td>VPB</td><td>Ngân hàng TMCP Việt Nam Thịnh Vượng</td><td>VPBank</td></tr><tr><td>CBB</td><td>Ngân hàng Thương mại TNHH MTV Xây dựng Việt Nam</td><td>CBBank</td></tr><tr><td>KPB</td><td>Ngân hàng Đại chúng Kasikornbank - Chi nhánh TP. Hồ Chí Minh</td><td>KBank</td></tr><tr><td>WRB</td><td>Ngân hàng TNHH MTV Woori Việt Nam</td><td>Woori</td></tr><tr><td>HSBC</td><td>Ngân hàng TNHH MTV HSBC (Việt Nam)</td><td>HSBC</td></tr><tr><td>BNPHCM</td><td>Ngân hàng BNP Paribas - Chi nhánh TP. Hồ Chí Minh</td><td>BNPHCM</td></tr><tr><td>GPB</td><td>Ngân hàng Thương mại TNHH MTV Dầu Khí Toàn Cầu</td><td>GPBank</td></tr><tr><td>PBVN</td><td>Ngân hàng TNHH MTV Public Việt Nam</td><td>PublicBank</td></tr><tr><td>CAKE</td><td>TMCP Việt Nam Thịnh Vượng - Ngân hàng số CAKE by VPBank</td><td>CAKE</td></tr><tr><td>VTB</td><td>Ngân hàng TMCP Công thương Việt Nam</td><td>Vietinbank</td></tr><tr><td>BVB</td><td>Ngân hàng TMCP Bảo Việt</td><td>BaoVietBank</td></tr><tr><td>HONGLEONG</td><td>Ngân hàng TNHH MTV Hongleong Việt Nam</td><td>HongLeong</td></tr><tr><td>KEBHCM</td><td>Ngân hàng Keb Hana - Chi nhánh TP. Hồ Chí Minh</td><td>KEBHanaHCMBank</td></tr><tr><td>BNPHN</td><td>Ngân hàng BNP Paribas - Chi nhánh Hà Nội</td><td>BNPHN</td></tr><tr><td>VIB</td><td>Ngân hàng TMCP Quốc tế Việt Nam</td><td>VIB</td></tr><tr><td>VRB</td><td>Ngân hàng Liên doanh Việt - Nga</td><td>VRB</td></tr><tr><td>OCB</td><td>Ngân hàng TMCP Phương Đông</td><td>OCB</td></tr><tr><td>BAB</td><td>Ngân hàng TMCP Bắc Á</td><td>BacABank</td></tr><tr><td>KBHCM</td><td>Ngân hàng Kookmin - Chi nhánh Thành phố Hồ Chí Minh</td><td>KookminHCM</td></tr><tr><td>DAB</td><td>Ngân hàng TMCP Đông Á</td><td>DongABank</td></tr><tr><td>CITIBANK</td><td>Ngân hàng Citibank - Chi nhánh Hà Nội</td><td>CitibankHN</td></tr><tr><td>NCB</td><td>Ngân hàng TMCP Quốc Dân</td><td>NCB</td></tr><tr><td>VCAB</td><td>Ngân hàng TMCP Bản Việt</td><td>VietCapitalBank</td></tr><tr><td>DBS</td><td>DBS Bank Ltd - Chi nhánh Thành phố Hồ Chí Minh</td><td>DBSBank</td></tr><tr><td>NHB</td><td>Ngân hàng Nonghyup - Chi nhánh Hà Nội</td><td>Nonghyup</td></tr><tr><td>VTLMONEY</td><td>Tổng Công ty Dịch vụ số Viettel - Chi nhánh tập đoàn công nghiệp viễn thông Quân Đội</td><td>ViettelMoney</td></tr><tr><td>LPB</td><td>Ngân hàng TMCP Lộc Phát Việt Nam</td><td>LPBank</td></tr><tr><td>STB</td><td>Ngân hàng TMCP Sài Gòn Thương Tín</td><td>Sacombank</td></tr><tr><td>Ubank</td><td>TMCP Việt Nam Thịnh Vượng - Ngân hàng số Ubank by VPBank</td><td>Ubank</td></tr><tr><td>SHINHAN</td><td>Ngân hàng TNHH MTV Shinhan Việt Nam</td><td>ShinhanBank</td></tr><tr><td>SBC</td><td>Ngân hàng TMCP Sài Gòn Công Thương</td><td>SaigonBank</td></tr><tr><td>AGR</td><td>Ngân hàng Nông nghiệp và Phát triển Nông thôn Việt Nam</td><td>Agribank</td></tr><tr><td>HDB</td><td>Ngân hàng TMCP Phát triển Thành phố Hồ Chí Minh</td><td>HDBank</td></tr><tr><td>PGB</td><td>Ngân hàng TMCP Xăng dầu Petrolimex</td><td>PGBank</td></tr><tr><td>MB</td><td>Ngân hàng TMCP Quân đội</td><td>MBBank</td></tr><tr><td>BIDC</td><td>Ngân hàng Đầu tư và Phát triển Campuchia – Chi nhánh Hà Nội</td><td>BIDC</td></tr><tr><td>SAB</td><td>Ngân hàng TMCP Đông Nam Á</td><td>SeABank</td></tr><tr><td>VNPTMONEY</td><td>Trung tâm dịch vụ tài chính số VNPT- Chi nhánh Tổng công ty truyền thông (VNPT Fintech)</td><td>VNPTMoney</td></tr><tr><td>SHB</td><td>Ngân hàng TMCP Sài Gòn - Hà Nội</td><td>SHB</td></tr><tr><td>NAB</td><td>Ngân hàng TMCP Nam Á</td><td>NamABank</td></tr><tr><td>CUBHCM</td><td>Ngân hàng Cathay United Bank – Chi nhánh TP. Hồ Chí Minh</td><td>CathayUnitedBank</td></tr><tr><td>PVCB</td><td>Ngân hàng TMCP Đại Chúng Việt Nam</td><td>PVcomBank</td></tr><tr><td>VBC</td><td>Ngân hàng TMCP Việt Nam Thương Tín</td><td>VietBank</td></tr><tr><td>UOB</td><td>Ngân hàng United Overseas - Chi nhánh TP. Hồ Chí Minh</td><td>UnitedOverseas</td></tr><tr><td>TPB</td><td>Ngân hàng TMCP Tiên Phong</td><td>TPBank</td></tr><tr><td>UMEE</td><td>Ngân hàng số Umee – Kiên Long Bank</td><td>KienLongBank</td></tr><tr><td>CIMB</td><td>Ngân hàng TNHH MTV CIMB Việt Nam</td><td>CIMB</td></tr><tr><td>KLB</td><td>Ngân hàng TMCP Kiên Long</td><td>KienLongBank</td></tr><tr><td>VCB</td><td>Ngân hàng TMCP Ngoại Thương Việt Nam</td><td>Vietcombank</td></tr><tr><td>TIMO</td><td>Ngân hàng số Timo by Ban Viet Bank (Timo by Ban Viet Bank)</td><td>Timo</td></tr><tr><td>IVB</td><td>Ngân hàng TNHH Indovina</td><td>IndovinaBank</td></tr><tr><td>SCB</td><td>Ngân hàng TMCP Sài Gòn</td><td>SCB</td></tr><tr><td>BIDV</td><td>Ngân hàng TMCP Đầu tư và Phát triển Việt Nam</td><td>BIDV</td></tr><tr><td>EIB</td><td>Ngân hàng TMCP Xuất Nhập khẩu Việt Nam</td><td>Eximbank</td></tr><tr><td>SCVN</td><td>Ngân hàng TNHH MTV Standard Chartered Bank Việt Nam</td><td>StandardChartered</td></tr><tr><td>MBV</td><td>Ngân hàng Thương mại TNHH MTV Đại Dương</td><td>Oceanbank</td></tr><tr><td>KEBHN</td><td>Ngân hàng Keb Hana - Chi nhánh Hà Nội</td><td>KEBHanaHNBank</td></tr></tbody></table>

**DANH SÁCH APP VÍ ĐIỆN TỬ QUÉT CHẤP NHẬN THANH TOÁN MÃ VIETQR**

<table data-header-hidden><thead><tr><th width="163">No</th><th width="172">Bank Code</th><th>APP</th></tr></thead><tbody><tr><td>1</td><td>ZaloPay</td><td>Ví điện tử Zalo</td></tr><tr><td>2</td><td>VETC</td><td>Ví điện tử <strong>VETC</strong> </td></tr><tr><td>3</td><td>MOMO</td><td>Ví điện tử Momo</td></tr><tr><td>4</td><td>VNPAY</td><td>Ví điện tử Vnpay</td></tr><tr><td>5</td><td>VIETTEL PAY</td><td>Ví điện tử Viettel Pay</td></tr><tr><td>4</td><td>....</td><td>Còn nhiều tổ chức khác sẽ được VietQR tiếp tục cập nhật</td></tr></tbody></table>


# Robot tài chính RPA

Ứng dụng công nghệ phần mêm robot và Dịch vụ thanh toán và ứng dụng mã QRcode để quản lý và tối ưu kinh doanh ch doanh nghiệp

**Công nghệ RPA là gì?**

Robotic Process Automation (RPA) là công nghệ sử dụng robot phần mềm hoặc "bots" để tự động hóa các quy trình kinh doanh lặp đi lặp lại và dựa trên quy tắc. Những bots này có khả năng mô phỏng các hành động của con người khi tương tác với các hệ thống phần mềm và ứng dụng, từ đó giúp thực hiện các nhiệm vụ như nhập liệu, xử lý giao dịch, quản lý dữ liệu và trả lời email một cách tự động và hiệu quả.

Các đặc điểm chính của RPA bao gồm:

* **Tự động hóa công việc lặp đi lặp lại**: RPA giúp tự động hóa các nhiệm vụ tẻ nhạt và lặp đi lặp lại mà nhân viên thường phải làm, giải phóng thời gian cho những công việc có giá trị cao hơn.
* **Tương tác với nhiều hệ thống**: RPA có thể làm việc với nhiều hệ thống và ứng dụng khác nhau mà không cần thay đổi cấu trúc hiện tại của chúng.
* **Độ chính xác cao**: Bots RPA có khả năng thực hiện các nhiệm vụ với độ chính xác cao, giảm thiểu sai sót do con người gây ra.
* **Tiết kiệm chi phí và thời gian**: Sử dụng RPA có thể giảm chi phí vận hành và thời gian hoàn thành các quy trình kinh doanh.
* **Dễ dàng mở rộng**: Các giải pháp RPA có thể dễ dàng mở rộng để đáp ứng nhu cầu kinh doanh ngày càng tăng

RPA đang được ứng dụng rộng rãi trong nhiều ngành công nghiệp khác nhau như tài chính, y tế, bảo hiểm, sản xuất và bán lẻ, nhằm cải thiện hiệu suất làm việc, giảm chi phí và nâng cao trải nghiệm khách hàng.


# Quy trình mẫu cho Doanh nghiệp

<table><thead><tr><th width="73">STT</th><th width="203">Tên bộ phận</th><th width="552">Tên quy trình/Tác vụ</th></tr></thead><tbody><tr><td>1</td><td>Phòng mua Hàng</td><td>Quy trình cài đặt chương trình khuyến mại</td></tr><tr><td>2</td><td>Phòng mua Hàng</td><td>Quy trình điều phối luân chuyển hàng hóa</td></tr><tr><td>3</td><td>Phòng mua Hàng</td><td>Quy trình đặt hàng</td></tr><tr><td>4</td><td>Trải nghiệm KH</td><td>Chăm sóc kh sau bán</td></tr><tr><td>5</td><td>Trải nghiệm KH</td><td>Giám sát vận hành</td></tr><tr><td>6</td><td>Trải nghiệm KH</td><td>Phòng chống thất thoát</td></tr><tr><td>7</td><td>Trải nghiệm KH</td><td>Tổng hợp báo cáo</td></tr><tr><td>8</td><td>Thương mại Điện tử</td><td>Khai báo thông tin đơn hàng lên kho vận</td></tr><tr><td>9</td><td>Thương mại Điện tử</td><td>Theo dõi chấm công</td></tr><tr><td>10</td><td>Thương mại Điện tử</td><td>Quản lý layout trưng bày</td></tr><tr><td>11</td><td>Thương mại Điện tử</td><td>Điều vận đơn hàng theo tuyến</td></tr><tr><td>12</td><td>Thương mại Điện tử</td><td>Kế toán thu tiền từng đơn, cập nhật doanh thu</td></tr><tr><td>13</td><td>Thương mại Điện tử</td><td>Update trạng thái đơn hàng</td></tr><tr><td>14</td><td>Thương mại Điện tử</td><td>Đăng nhập platform vào trang TMĐT lấy thông tin</td></tr><tr><td>15</td><td>Thương mại Điện tử</td><td>Cảnh báo về chỉ số vận hành</td></tr><tr><td>16</td><td>Thương mại Điện tử</td><td>Cập nhật thông tin chính sách khuyến mãi trên mọi sàn thương mại điện tử</td></tr><tr><td>17</td><td>Thương mại Điện tử</td><td>Check comment xấu, đánh giá thấp để liên hệ KH</td></tr><tr><td>18</td><td>Thương mại Điện tử</td><td>Đếm traffic KH</td></tr><tr><td>19</td><td>Kế Toán</td><td>Báo cáo dòng tiền hàng ngày hiện hữu</td></tr><tr><td>20</td><td>Kế Toán</td><td>Dự báo dòng tiền </td></tr><tr><td>23</td><td>Kế Toán</td><td>Tạo lệnh thanh toán ngân hàng</td></tr><tr><td>21</td><td>Kế Toán</td><td>Đối soát tiền giao dịch</td></tr><tr><td>22</td><td>Kế Toán</td><td>Xuất hóa đơn trên hệ thống</td></tr><tr><td>24</td><td>Kế Toán</td><td>Hóa đơn chí phí</td></tr><tr><td>25</td><td>Kế Toán</td><td>Báo cáo Thuế</td></tr><tr><td>26</td><td>Kế Toán</td><td>Nhập thông tin trong hóa đơn điện tử khi xuất HĐ</td></tr><tr><td>27</td><td>Kế Toán</td><td>Phương thức thanh toán</td></tr><tr><td>28</td><td>Kế Toán</td><td>Nhắc nhở hoàn ứng</td></tr><tr><td>29</td><td>Kế Toán</td><td>Bảng lương vận chuyển</td></tr><tr><td>30</td><td>Kế Toán</td><td>Kí HĐ trong ngày</td></tr><tr><td>31</td><td>Phòng Nhân sự</td><td>Thông báo kết thúc thử việc</td></tr><tr><td>32</td><td>Phòng Nhân sự</td><td>Hệ thống HRM, list thông tin BHXH và đẩy lên Efile (báo tăng, báo giảm) </td></tr><tr><td>33</td><td>Phòng Nhân sự</td><td>Nhắc nhở chấm công, đi làm muộn,</td></tr><tr><td>34</td><td>Phòng Nhân sự</td><td>Gửi thư cmsn, thư thông báo nhân viên mới/nghỉ việc, thư cảm ơn nv nghỉ việc</td></tr><tr><td>35</td><td>Phòng Nhân sự</td><td>Báo cáo thông tin tuyển dụng. Cập nhật trạng thái tuyển dụng.</td></tr><tr><td>36</td><td>Phòng Nhân sự</td><td>Thông báo offer</td></tr><tr><td>37</td><td>Phòng Nhân sự</td><td>Ghi nhận sai sót về trả lương</td></tr><tr><td>38</td><td>Phòng Nhân sự</td><td>Hệ thống báo cáo nhân sự: doanh thu, sản phẩm, chi phí lương/doanh số</td></tr><tr><td>39</td><td>Phòng Nhân sự</td><td>Thông báo bổ nhiệm, điều chuyển nhân sự</td></tr><tr><td>40</td><td>Phòng Nhân sự</td><td>Kí HĐLĐ điện tử</td></tr><tr><td>41</td><td>Phòng Nhân sự</td><td>Chuyển dữ liệu từ HRM sang netsuit chi phí lương</td></tr></tbody></table>


# Quy trình mẫu đối với Ngân hàng

Tên quy trình mẫu tham khảo

Một số tên quy trình mẫu tham khảo đối với khách hàng : Liên hệ 0936382222 | 0922333636 để được tư vấn.

<table><thead><tr><th width="71">STT</th><th width="227">Tên quy trình</th><th width="517">Tên quy trình</th></tr></thead><tbody><tr><td>1</td><td>Chạy chương trình và kiểm tra kết quả trùng port</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Chạy chương trình và kiểm tra kết quả trùng port XRPA.Xbank.1</td></tr><tr><td>2</td><td>Check giao dịch sao kê đồng bộ lên EMB</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Check giao dịch sao kê đồng bộ lên EMB XRPA.Xbank.2</td></tr><tr><td>3</td><td>Vận hành F2B hàng ngày</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Vận hành F2B hàng ngày XRPA.Xbank.3</td></tr><tr><td>4</td><td>Quản trị User</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Quản trị User XRPA.Xbank.4</td></tr><tr><td>5</td><td>Nhận điện tại phòng tác nghiệp</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Nhận điện tại phòng tác nghiệp XRPA.Xbank.5</td></tr><tr><td>6</td><td>Báo có tiền về cho KH sau khi hoàn tất việc chuyển khoản quốc tế</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Báo có tiền về cho KH sau khi hoàn tất việc chuyển khoản quốc tế XRPA.Xbank.6</td></tr><tr><td>7</td><td>Kiểm tra và phê duyệt các giao dịch chuyển tiền thường Citad</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Kiểm tra và phê duyệt các giao dịch chuyển tiền thường Citad XRPA.Xbank.7</td></tr><tr><td>8</td><td>Kiểm tra và phê duyệt các giao dịch chuyển tiền nhanh Napas</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Kiểm tra và phê duyệt các giao dịch chuyển tiền nhanh Napas XRPA.Xbank.8</td></tr><tr><td>9</td><td>Đăng ký dịch vụ qua Internet Banking</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Đăng ký dịch vụ qua Internet Banking XRPA.Xbank.9</td></tr><tr><td>10</td><td>Đăng ký dịch vụ VN-TOPUP</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Đăng ký dịch vụ VN-TOPUP XRPA.Xbank.10</td></tr><tr><td>11</td><td>Xử lý hồ sơ cho vay cầm cố sổ tiết kiệm trên hệ thống</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Xử lý hồ sơ cho vay cầm cố sổ tiết kiệm trên hệ thống XRPA.Xbank.11</td></tr><tr><td>12</td><td>Chấm dữ liệu MM (MoneyMarket), phát hiện deal chênh lệch</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Chấm dữ liệu MM (MoneyMarket), phát hiện deal chênh lệch XRPA.Xbank.12</td></tr><tr><td>13</td><td>Chấm dữ liệu FX (ForeignExchange), phát hiện deal chênh lệch</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Chấm dữ liệu FX (ForeignExchange), phát hiện deal chênh lệch XRPA.Xbank.13</td></tr><tr><td>14</td><td>Chấm dữ liệu Bond (Trái phiếu), phát hiện deal chênh lệch</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Chấm dữ liệu Bond (Trái phiếu), phát hiện deal chênh lệch XRPA.Xbank.14</td></tr><tr><td>15</td><td>Báo cáo giao dịch Commo gửi khách hàng</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Báo cáo giao dịch Commo gửi khách hàng XRPA.Xbank.15</td></tr><tr><td>16</td><td>Trả lương theo lô</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Trả lương theo lô XRPA.Xbank.16</td></tr><tr><td>17</td><td>Tra soát giao dịch chuyển tiền nhanh nội địa luồng iss (GD từ MB sang NH khác)</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Tra soát giao dịch chuyển tiền nhanh nội địa luồng iss (GD từ MB sang NH khác) XRPA.Xbank.17</td></tr><tr><td>18</td><td>Tra soát giao dịch chuyển tiền nhanh nội địa luồng ACQ (GD từ NH khác sang MB)</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Tra soát giao dịch chuyển tiền nhanh nội địa luồng ACQ (GD từ NH khác sang MB) XRPA.Xbank.18</td></tr><tr><td>19</td><td>Đối soát dịch vụ VNPay</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Đối soát dịch vụ VNPay XRPA.Xbank.19</td></tr><tr><td>20</td><td>Xử lý yêu cầu khách hàng</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Xử lý yêu cầu khách hàng XRPA.Xbank.20</td></tr><tr><td>21</td><td>Báo cáo thông tin từ các ngân hàng đối thủ</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Báo cáo thông tin từ các ngân hàng đối thủ XRPA.Xbank.21</td></tr><tr><td>22</td><td>Tạo mới danh mục quản lý tài sản cho các khách hàng</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Tạo mới danh mục quản lý tài sản cho các khách hàng XRPA.Xbank.22</td></tr><tr><td>23</td><td>Giám sát hạn mức tín dụng</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Giám sát hạn mức tín dụng XRPA.Xbank.23</td></tr><tr><td>24</td><td>Tạo mới thông tin khách hàng trong quá trình sát nhập ngân hàng</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Tạo mới thông tin khách hàng trong quá trình sát nhập ngân hàng XRPA.Xbank.24</td></tr><tr><td>25</td><td>Quản lý các khoản mua sắm ngoài</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Quản lý các khoản mua sắm ngoài XRPA.Xbank.25</td></tr><tr><td>26</td><td>Gửi thông báo tiền phạt</td><td>Phần mềm tự động hóa bằng Robot cho quy trình Gửi thông báo tiền phạt XRPA.Xbank.26</td></tr></tbody></table>


# Hỗ trợ và liên hệ

### Thông tin liên hệ hỗ trợ kỹ thuật:&#x20;

Hotline kỹ thuật : Mr Hà Trung Hiếu

Email: <itsupport@vietqr.vn>

Số điện thoại : 0922333636

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><td><h4>Trang Web Chính Thức</h4></td><td><strong>URL:</strong> <a href="https://vietqr.com/">https://vietqr.com</a></td><td><strong>Email:</strong> <a href="mailto:sales@vietqr.vn">sales@vietqr.vn</a></td><td><strong>Điện thoại:</strong> +849 2233 3636</td></tr><tr><td><h4>Trang Web Người Dùng</h4></td><td><strong>URL:</strong> <a href="https://vietqr.com/">https://vietqr.com</a></td><td><strong>Email:</strong> <a href="mailto:itsupport@vietqr.vn">itsupport@vietqr.vn</a></td><td><strong>Hotline:</strong> 1900 6234</td></tr><tr><td><h4>Mạng Xã Hội</h4></td><td><a href="https://www.facebook.com/vietqr.vn">Facebook</a> || <a href="https://t.me/vietqrdev">Telegram</a> || <a href="https://www.youtube.com/@VietQR">Youtube</a></td><td></td><td></td></tr><tr><td><h4>Form Liên Hệ Trực Tuyến</h4></td><td><a href="https://vietqr.com/lien-he.html">Liên hệ trực tuyến</a></td><td></td><td></td></tr></tbody></table>

### Các câu hỏi thường gặp (FAQs):

&#x20;Giải đáp các câu hỏi mà người dùng thường gặp phải khi sử dụng API.

Các câu hỏi thường gặp chúng tôi giải đáp và chia sẻ qua các trang web và nhóm chat sau :thumbsup:

Website: [doc.vietqr.vn ](https://doc.vietqr.vn/vietqr-doc)hoặc | [https://docs.vieqr.com](https://docs.vieqr.com/)

Các nhóm chát : Telegram, Zalo 0922333636


# Mở TK VietQR và liên kết

kếtBước đầu tiên trong quá trình tích hợp dịch vụ VietQR Payment APIs

### Cài đặt phần mềm hỗ trợ test API kết nối : <https://www.postman.com/downloads/>

Khai báo môi trường Test - [Mở tài khoản và thông báo](/vi/mo-tk-vietqr-va-lien-ket)

Đăng ký tài khoản VietQR

{% hint style="info" %}
Nếu quý khách đã có tài khoản VietQR, hẫy đến bước tiếp theo.
{% endhint %}

1. Truy cập trang web [`VietQR.vn`](https://vietqr.vn/register) của chúng tôi để đăng ký tài khoản.
2. Nhập số điện thoại và mật khẩu để tạo một tài khoản mới.
3. Sau khi đăng ký, bạn cần liên kết tài khoản ngân hàng để có thể nhận tiền từ các giao dịch thanh toán qua mã QR.
4. Đăng nhập vào VietQR, nhấn vào nút thêm tài khoản ngân hàng.
5. Chọn ngân hàng MB hoặc BIDV.
6. Nhập các thông tin cần thiết và xác thực để liên kết.

{% hint style="success" %}

* Nếu quý khách chưa có tài khoản tại ngân hàng MB hoặc BIDV, hãy đăng ký ngay  [tại đây](https://omni.bidv.com.vn/static/bidv/share/gioi-thieu-ban-thuong-vo-han.html?data=aH0RHc6MyLk9Cbi5Wa2R2ch1nciRWYr5Wan5nLuZ2LiVlTBRGTS1VbuVVeYZEZo4) để mở tài khoản mới và nhận nhiều ưu đãi hấp dẫn.
* Trong thời gian chờ tài khoản chính thức được kích hoạt, chúng tôi sẽ cung cấp tài khoản ngân hàng thử nghiệm để quý khách có thể tích hợp và trải nghiệm dịch vụ trước.
  {% endhint %}

***

<details>

<summary>Tôi cần làm gì để đăng ký tài khoản VietQR?</summary>

Bạn cần truy cập trang web VietQR.vn, nhập số điện thoại và mật khẩu để tạo tài khoản mới. Sau khi đăng ký thành công, bạn có thể bắt đầu sử dụng các dịch vụ của VietQR.

</details>

<details>

<summary>Tại sao tôi phải liên kết tài khoản ngân hàng với VietQR?</summary>

Việc liên kết tài khoản ngân hàng cho phép bạn nhận tiền từ các giao dịch thanh toán qua mã QR. Tài khoản liên kết sẽ là nơi nhận tiền khi khách hàng thanh toán thông qua mã QR do VietQR cung cấp.

</details>

<details>

<summary>Hiện tại VietQR hỗ trợ liên kết với những ngân hàng nào?</summary>

Hiện tại, VietQR hỗ trợ liên kết với tài khoản ngân hàng tại MB và BIDV. Các ngân hàng khác đang được triển khai và sẽ sớm được hỗ trợ trong thời gian tới.

</details>

<details>

<summary>Tôi chưa có tài khoản tại ngân hàng MB hoặc BIDV, tôi phải làm gì?</summary>

Nếu bạn chưa có tài khoản tại MB hoặc BIDV, bạn có thể đăng ký mở tài khoản mới tại ngân hàng thông qua liên kết trên trang VietQR. Sau khi mở tài khoản, bạn có thể quay lại VietQR để liên kết tài khoản ngân hàng này.

</details>

<details>

<summary>Tôi có thể sử dụng tài khoản ngân hàng thử nghiệm để làm gì?</summary>

Trong thời gian chờ tài khoản chính thức được kích hoạt, VietQR sẽ cung cấp tài khoản ngân hàng thử nghiệm để bạn có thể tích hợp và trải nghiệm các dịch vụ của VietQR trước khi sử dụng tài khoản chính thức.

</details>

<details>

<summary>Liên kết tài khoản ngân hàng có mất phí không?</summary>

Hiện tại, việc liên kết tài khoản ngân hàng với VietQR không mất phí. Ngoài ra, sau khi hoàn thành bước xác thực email, bạn sẽ được tặng key 1 tháng kích hoạt nhận biến động số dư. (\*áp dụng trong khung chương trình khi còn hiệu lực)

</details>


# Overview

VietQR and Open API Banking VietQR provide a one-time connection solution for all banks, enabling businesses to manage payments easily and efficiently.

VietQR and Open API Banking VietQR provide a one-time connection solution for all banks, allowing businesses to manage payments easily and efficiently.. :thumbsup:

### API for Payment Reconciliation with Banks

VietQR service is an open solution that enables flexible connectivity between banking systems and businesses. With this solution, businesses can allow customers to use bank accounts or e-wallets to make payments for services across multiple platforms, including websites, mobile applications, point-of-sale (POS) devices, bill payments, Web In App VietQR, as well as vending machines and IoT systems.

### Automatic Invoice Generation API

The standard API set helps you automatically generate invoices for payment transactions.

### Barcode Label Generation API

Generate an Identification Code for Product Traceability Verification, Management Reporting Tools, and Origin Lookup.

### Description of the Integration Process

<figure><img src="https://content.gitbook.com/content/SRgURCFAGmE4PjobTdbe/blobs/YWDqP8a5E39RKeVEHG5j/Process%20Map%20Payment%20APIs.png" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Partners must complete the account registration process with full information to ensure account identification and security. The default integration environment will be the Test (Sandbox) environment.
{% endhint %}

### Basic steps to integrate with VietQR:

### Preparation: Create an account and initiate the test environment.

1\. Create a VietQR account and link your bank account to the VietQR application.

2\. Declare connection information on the VietQR.vn website.

## Connect the service in the test environment.

1. The partner implements the API Transaction Sync on their system.
2. Transmit the username and password provided by VietQR after completing step 4 into the API Get Token.
3. Use the Token obtained in step 5 to call the API Generate VietQR Code to create a payment QR code.
4. Call the API Test Callback to simulate a successful payment for the transaction created in step 6.
5. Perform acceptance testing and request GoLive in the production environment.

### Sign the contract and GoLive the service with a real account.

Contact our sales or technical staff for support and to complete the legal procedures required to launch the service. (HOTLINE 09.2233.3636)

***

***

### Security Keys

• Access Key: Grants access permission to call the API to obtain a token.

• Basic Authen: An encrypted string provided by VietQR for partners.

• Check Sum: An MD5 encrypted string used to access certain APIs.

• Secret Key: Used to generate an electronic signature.

### Security

A Secret Key is a character string generated by a specific algorithm, used to verify the accuracy of data during transmission between two systems. Some commonly used algorithms include MD5, SHA1, SHA256, and HMAC.

### Our Platforms

{% tabs %}
{% tab title="Mobile IOS" %}

<figure><img src="https://content.gitbook.com/content/SRgURCFAGmE4PjobTdbe/blobs/q13nUronsct6lz8XDz2j/1[1].png" alt="" width="563"><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Mobile Android" %}

<figure><img src="https://content.gitbook.com/content/SRgURCFAGmE4PjobTdbe/blobs/EHchPc6sISvq1pfI7TP5/2[1].png" alt="" width="563"><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Website" %}

* Trang chủ: [https://vietqr.com](https://vietqr.com/)
* Trang người dùng: [https://vietqr.vn](https://vietqr.vn/)
* Bạn còn thấy VietQR ở đâu :thumbsup:
  * kiot.vietqr.vn
  * pro.vietqr.vn
  * Vietqrpro.vn
  * Vietqrplus.vn
  * Vietqr.org
  * Myvietqr.vn
  * App : VietQR Kiot
    {% endtab %}
    {% endtabs %}

### Tích hợp dịch vụ APIs của chúng tôi

<details>

<summary><strong>VietQR Payment APIs</strong></summary>

* Chúng tôi cung cấp một công cụ đơn giản để doanh nghiệp dễ dàng tích hợp dịch vụ thanh toán bằng mã QR vào hệ thống của mình. Với bộ APIs này, bạn có thể tạo mã thanh toán, xử lý các giao dịch, và kiểm tra xem thanh toán đã hoàn tất chưa.
* VietQR Payment API được thiết kế thân thiện, an toàn, và dễ sử dụng, phù hợp cho mọi loại hình doanh nghiệp, dù lớn hay nhỏ.

</details>

<details>

<summary>VietQR Refund API</summary>

* Gói dịch vụ này là một phần bổ sung cho hệ thống thanh toán mã QR hiện có. VietQR Refund API giúp doanh nghiệp dễ dàng xử lý các giao dịch hoàn tiền một cách nhanh chóng và hiệu quả. Khi cần hoàn tiền cho khách hàng, bạn chỉ cần sử dụng API này để thực hiện nhanh chóng và chính xác.
* API này giúp đơn giản hóa quy trình hoàn tiền, giảm thiểu sai sót và nâng cao trải nghiệm khách hàng.

</details>

<details>

<summary>VietQR Payment MQTTs</summary>

Cung cấp một giải pháp thanh toán qua mã QR, sử dụng giao thức truyền thông **MQTTs (Message Queuing Telemetry Transport Secure)** để đảm bảo tính bảo mật và hiệu quả trong việc truyền tải thông tin giao dịch. Đây là một gói dịch vụ hướng đến các doanh nghiệp và tổ chức có nhu cầu tích hợp thanh toán qua mã QR và nhận thông báo biến động số dư theo thời gian thực một cách an toàn.

</details>

<details>

<summary>WordPress Plugin</summary>

Chúng tôi cung cấp Plugin WordPress - VietQR, giúp khách hàng dễ dàng sử dụng dịch vụ thanh toán qua mã QR và đối soát tự động qua mã VietQR chỉ bằng cách cài đặt Plugin và sử dụng ứng dụng App VietQR [(hướng dẫn cài app tại đây)](https://youtu.be/8tFoBjtSFXQ?si=mVzmWmluqgCfbC2F). Sau khi tích hợp Plugin VietQR vào hệ thống WordPress, bạn có thể:

• Tạo mã QR thanh toán cho các sản phẩm trên website của mình.

• Nhận thông báo biến động số dư (BĐSD) và xác nhận giao dịch ngay khi phát sinh, với đầy đủ thông tin chi tiết.

• Hỗ trợ tạo mã QR thanh toán cho tất cả tài khoản ngân hàng đã đăng ký trên ứng dụng VietQR hoặc website VietQR.vn.

• Tự động đối soát và khớp lệnh đơn hàng với ngân hàng MB và BIDV.

• Cung cấp báo cáo doanh số và phân tích giao dịch thông qua hệ thống quản lý thanh toán trên web VietQR.vn hoặc ứng dụng VietQR.

• Chia Sẻ biến động số dư và thông tin khách đặt hàng qua group chat mạng xã hội như Lark, Telegram, Google Chat, Google Sheet, Slark.

</details>

<details>

<summary>VietQR Host to Client</summary>

* Llà công cụ hoàn hảo giúp doanh nghiệp dễ dàng tích hợp các tính năng của VietQR API vào trình duyệt của mình mà không cần viết mã code. Với tiện ích mở rộng này, bạn có thể nhanh chóng tạo mã thanh toán, xử lý giao dịch và quản lý hoàn tiền ngay trên trình duyệt Chrome.
* Thiết kế của tiện ích mở rộng giúp đơn giản hóa quy trình, giảm thiểu sai sót, và nâng cao trải nghiệm người dùng. Đây là giải pháp lý tưởng cho doanh nghiệp muốn sử dụng dịch vụ VietQR một cách nhanh chóng và hiệu quả.

</details>

<details>

<summary>VietQR Host to Host (continue update)</summary>

</details>


# General Introduction

General Introduction to QR Codes and VietQR, VietQR Software, and Service Packages

### Introduction to VietQR

VietQR is a fast and secure QR code payment solution that helps businesses optimize transaction processes, reduce operational costs, and enhance customer experience. With VietQR, you can easily manage cash flow, receive balance change notifications, and support customers with a flexible refund feature available in the Pro service package.

Comparison of VietQR Pro and VietQR Plus Service Packages

| Feature                   | VietQR Pro                                                                                   | VietQR Plus                                           |
| ------------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| Refund Feature            | ✅ Available                                                                                  | ❌ Not Available                                       |
| Service Fee               | % of transaction value                                                                       | 1,600 VND/transaction + VAT                           |
| Minimum Transaction Value | No minimum limit                                                                             | No restriction                                        |
| Recommended for           | Automated control devices, vending machines, and businesses with frequent small transactions | E-commerce businesses with high-value transactions    |
| Technical Standards       | Same as VietQR Plus                                                                          | Same as VietQR Pro                                    |
| Switching Plans           | Automatic fee adjustment when switching between plans                                        | Automatic fee adjustment when switching between plans |

Both VietQR Pro and Plus use the same technical connection standards, ensuring seamless integration and easy plan switching based on business needs. 🚀

### How to Choose Between the Pro and Plus Plans

• VietQR Pro: Includes a refund feature. The service fee is calculated as a percentage of the transaction value.

• VietQR Plus: Does not include the refund feature. The fee is charged at 1,600 VND per transaction + VAT.

### How to Choose the Right Plan

• For automated control devices, VietQR recommends using the Pro plan as it benefits both agents and customers by applying a percentage-based fee without a minimum transaction limit.

• The Plus plan is more suitable for e-commerce businesses, where transactions tend to have higher values.

### Seamless Plan Switching

Both VietQR Pro and Plus share the same technical connection standards. When customers switch between the two plans, the VietQR system will automatically adjust the appropriate fee mechanism, eliminating the need for any additional configuration from customers or partners.


# Description of VietQR API Workflow

Description of VietQR Callback API Integration Workflow

## Description of VietQR API Workflow

### 1. Steps to Generate a VietQR Payment Code:

#### Step 1: Obtain an Access Token

The customer (KH) needs to call VietQR’s Get Token API to authenticate and gain access. Once authentication is successful, VietQR returns a token, which acts as a key to access the API for generating a VietQR code.

🔗 \[Refer to Get Token API]

#### Step 2: Generate a VietQR Payment Code

After obtaining the token, the customer uses it to call the VietQR payment code generation API.

🔗 \[Refer to VietQR Code Generation API]

#### Step 3: Simulate Payment in a Test/Staging/Sandbox Environment

In the test environment, customers do not need to scan the QR code for actual payment. Instead, they can call the Test Callback API to simulate a successful payment transaction.

🔗 \[Refer to Test Callback API]

📌 Note: After completing a payment, customers need a system to receive balance change notifications (BĐSD). Therefore, setting up a payment information reception system is required.

### 2. Setting Up a Payment Information/BĐSD Reception System

#### Step 1: Provide a Get Token API

The customer needs to implement their own Get Token API to authenticate and provide a token to VietQR. This token allows VietQR to access the customer’s system and send payment/BĐSD data.

🔗 \[Refer to Get Token API]

#### Step 2: Develop an API to Receive Transaction Data

The customer needs to implement a Transaction Sync API to receive payment/BĐSD data from VietQR.

🔗 \[Refer to Transaction Sync API]

📌 Summary:

The process includes generating a VietQR payment code, simulating payments (in a test environment), and setting up a payment/BĐSD data reception system to ensure transaction information is fully recorded.

📲 Scan the QR Code to join our open Zalo support group for assistance!

{% embed url="<https://zalo.me/g/tachpp720>" %}
Link vào nhóm mở zalo&#x20;
{% endembed %}

{% tabs %}
{% tab title="Mã QR vào nhóm Chat" %}

<figure><img src="https://content.gitbook.com/content/SRgURCFAGmE4PjobTdbe/blobs/g0vM7w2hWzPVsb2WPzMm/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Second Tab" %}

{% endtab %}
{% endtabs %}


# Declare merchant connection

Bạn cần khai báo các thông tin cần thiết để kết nối merchant của mình với VietQR.

Khai báo thông tin kết nối

Đăng nhập đường link để khai báo kết nối tại đây : <https://vietqr.vn/merchant/request>

<figure><img src="https://content.gitbook.com/content/SRgURCFAGmE4PjobTdbe/blobs/IYpYSqhOetAydW3G4xtE/image.png" alt=""><figcaption></figcaption></figure>

hoặc gửi thông tin yêu cầu khởi tạo môi trường test về địa chỉ email : <Sales@vietqr.vn> với các thông tin như sau :thumbsup:

ác thông tin cần thiết để thiết lập kết nối API nhằm tạo môi trường test cho hệ thống. Vui lòng điền đầy đủ các tham số sau:

```
1.	Địa chỉ kết nối (URL/IP + PORT):
•	URL: [Vui lòng điền URL kết nối]
•	IP + PORT: [Nếu không sử dụng URL, vui lòng cung cấp địa chỉ IP và PORT]
2.	URL Path:
```

\[Vui lòng nhập đường dẫn cụ thể của API] 3. Địa chỉ KH (mã khách hàng, không dấu): \[Cung cấp địa chỉ khách hàng/mã KH để tránh trùng lặp] 4. Ngân hàng thụ hưởng: \[Vui lòng chọn ngân hàng từ danh sách hoặc nhập tên ngân hàng thụ hưởng] 5. Thông tin tài khoản MB Bank (nếu có): • Số tài khoản: \[Vui lòng nhập số tài khoản MB Bank] • Tên chủ tài khoản: \[Vui lòng nhập tên chủ tài khoản không dấu] 6. Basic Authentication: • Username: \[Vui lòng nhập tên đăng nhập] • Password: \[Vui lòng nhập mật khẩu] MB 3888831389 Truong Hiep HungMB 3888831389 Truong Hiep Hung

Sau khi điền đầy đủ thông tin, vui lòng gửi lại để chúng tôi có thể tiến hành tạo môi trường test và kiểm tra kết nối.

<figure><img src="https://content.gitbook.com/content/SRgURCFAGmE4PjobTdbe/blobs/qhosysZanvk85HDerH4T/image.png" alt=""><figcaption></figcaption></figure>

1. Truy cập trang khai báo kết nối [tại đây](https://vietqr.vn/merchant/request).
2. Nhập các thông tin cần khai báo.
3. Nhấn nút `Test Get Token` kiểm tra việc lấy token để đảm bảo kết nối hoạt động đúng cách.
4. Sau khi khai báo hoàn tất, hãy liên hệ đến bộ phận kỹ thuật của chúng tôi.

{% hint style="warning" %}
Lưu ý:&#x20;

* URL hoặc IP + Port cần khai báo là của phía quý khách.
* Hiện chúng tôi đang hỗ trợ liên kết tài khoản ngân hàng MB và BIDV. Danh sách các ngân hàng khác đang được triển khai trong thời gian sắp tới.
  {% endhint %}

***

### Thông báo bộ phận kỹ thuật của VietQR

1. Hãy đảm bảo rằng đội kỹ thuật của chúng tôi đã nhận được thông tin kết nối và hướng dẫn cần thiết để bắt đầu tích hợp. (Khi liên hệ với chúng tôi, hãy gửi lại `Merchant Name` (tên đại lý) đã khai báo).
2. Sau khi tiếp nhận thông tin, chúng tôi sẽ kiểm tra và duyệt kết nối.

{% hint style="success" %}
Sau khi hoàn thành bước này, VietQR sẽ cung cấp lại cho quý khách `username` và `password` để truy cập đến các API của VietQR trên môi trường Test.
{% endhint %}

***

### Các câu hỏi thường gặp

<details>

<summary>Tôi cần khai báo những thông tin gì để kết nối merchant với VietQR?</summary>

Bạn cần khai báo URL hoặc IP + Port mà hệ thống của bạn sẽ sử dụng để kết nối với dịch vụ VietQR. Đảm bảo rằng các thông tin này chính xác và đã được kiểm tra kỹ lưỡng.

</details>

<details>

<summary>Tôi có thể thay đổi thông tin khai báo sau khi đã hoàn tất không?</summary>

Có, bạn có thể thay đổi thông tin khai báo. Tuy nhiên, sau khi thay đổi, bạn cần phải thực hiện lại bước kiểm tra bằng cách nhấn "Test Get Token" để đảm bảo rằng kết nối vẫn hoạt động chính xác.

</details>

<details>

<summary>Nếu tôi gặp lỗi khi thực hiện bước "Test Get Token", tôi nên làm gì?</summary>

Nếu bạn gặp lỗi khi thực hiện "Test Get Token", hãy kiểm tra lại các thông tin khai báo như URL, IP, và Port. Đảm bảo rằng hệ thống của bạn có thể giao tiếp với VietQR. Nếu vấn đề vẫn tiếp diễn, hãy liên hệ với bộ phận kỹ thuật của VietQR để được hỗ trợ.

</details>

<details>

<summary>Tại sao việc Test Get Token lại quan trọng?</summary>

Bước này giúp xác nhận rằng hệ thống của bạn có thể lấy token thành công từ API của VietQR, đồng thời đảm bảo rằng kết nối hoạt động đúng cách trước khi tiến hành các bước tích hợp tiếp theo.

</details>

<details>

<summary>Tôi có thể sử dụng bất kỳ URL hoặc IP + Port nào để khai báo không?</summary>

Không, bạn cần sử dụng URL hoặc IP + Port mà hệ thống của bạn sẽ thực sự sử dụng để kết nối với VietQR. Các thông tin này phải chính xác và phù hợp với môi trường của bạn.

</details>

<details>

<summary>VietQR hỗ trợ những ngân hàng nào cho việc liên kết tài khoản?</summary>

Hiện tại, VietQR hỗ trợ liên kết tài khoản với ngân hàng MB và BIDV. Các ngân hàng khác sẽ được hỗ trợ trong thời gian tới.

</details>

<details>

<summary>Tại sao tôi cần liên hệ với bộ phận kỹ thuật của VietQR sau khi khai báo?</summary>

Liên hệ với bộ phận kỹ thuật của VietQR giúp đảm bảo rằng họ đã nhận được thông tin kết nối của bạn và có thể tiến hành kiểm tra, duyệt kết nối. Đây là bước quan trọng để tiến hành tích hợp dịch vụ.

</details>

<details>

<summary>Khi nào tôi sẽ nhận được username và password để truy cập API của VietQR?</summary>

Sau khi bộ phận kỹ thuật của VietQR kiểm tra và duyệt kết nối của bạn, họ sẽ cung cấp lại username và password để bạn có thể truy cập các API của VietQR trên môi trường Test.

</details>


# About QR Code & VietQR

Những điều cần biết về Mã QR và Viet QR

### 1. What is a QR Code?

A QR code is a type of two-dimensional barcode consisting of black and white squares that can encode hundreds of characters. Devices such as smartphones and tablets can quickly recognize and scan QR codes—hence the name “Quick Response” (QR).

### 2. How is a QR Code Used?

Due to the widespread use of smartphones, QR codes are commonly used in mobile marketing campaigns. Marketers use QR codes to link digital content such as websites, videos, PDF documents, photo albums, or contact information to printed materials like flyers, posters, product catalogs, and business cards.

### 3. How to Create a QR Code?

You can generate a QR code easily using a QR Code Generator in three simple steps:

#### 1. Choose the function of the code.

#### 2. Enter the content you want to display and customize the code with colors and a logo if needed.

#### 3. Download the QR code and prepare it for printing.

#### 4. Can QR Codes Be Customized?

Yes. Thanks to their high error tolerance, QR codes can be customized without affecting their scannability. You can change colors, add a company logo in the center, and modify the design of the code’s corners. Always test the QR code on multiple devices before officially using it.

### 5. What is the Difference Between Static and Dynamic QR Codes?

Dynamic QR codes allow you to edit content and track data even after printing. These codes use a redirect URL to guide users to the target content and can provide statistics such as scan counts, location, and access time. In contrast, static QR codes directly link to the content without tracking capabilities.

### 6. How to Track QR Code Scans?

You can track QR code scans by using a dynamic QR code, which connects to a provider’s server via a redirect URL. All real-time data will be stored in your account.

### 7. What to Consider Before Printing a QR Code?

Use high-resolution file formats such as JPG, PNG, EPS, or SVG. Vector formats like EPS and SVG are especially suitable for large print sizes without quality loss. Always test the QR code by scanning it before distribution.

### 8. Other Factors to Consider When Printing a QR Code

The QR code size should correspond to the amount of encoded information; more data requires a larger code. The minimum recommended size is 2 x 2 cm. Avoid placing the code on uneven surfaces to ensure optimal scanning.

### 9. How to Scan a QR Code

You only need a smartphone or tablet with a QR code scanning application. Open the app, point the camera at the code, and the content will appear within seconds. Choose an app based on its rating in the app store for the best experience.

### 10. How to Use QR Codes Effectively?

Think from the audience’s perspective—would they want to scan the code? Provide valuable and engaging content, optimize landing pages for mobile devices, and include a simple call-to-action like “Scan this code to learn more” to encourage engagement.

### 11. The History of QR Codes

QR codes were developed in 1994 by Denso Wave (a subsidiary of Toyota) in Japan to track components and facilitate logistics in automobile manufacturing. Today, QR codes are widely used in Japan and many other countries and have been standardized internationally. A unique feature of QR codes is their ability to be scanned even when up to 30% of the code surface is damaged or dirty.

### 12. Applications of QR Codes

QR codes can encode URLs, websites, videos, images, discount codes, forms, and various other types of content. Some content, such as event details, WiFi connections, or contact information, does not require an internet connection for use. You can place QR codes on websites, printed materials, products, and many other flat surfaces.


# API VIETQR CALLBACK

Mô tả quy trình test tích hợp bộ dịch vụ APIs nhận Biến động số dư qua mã VietQR.

## Hướng dẫn Test Kiểm thử&#x20;

Để cấu hình kết nối API với VietQR, anh/chị vui lòng cung cấp giúp em các thông tin sau : • Tên merchant: (Tên cửa hàng/doanh nghiệp muốn hiển thị)&#x20;

• URL kết nối: (Địa chỉ API để kết nối)&#x20;

• URL Path (Suffix): (Đường dẫn mở rộng nếu có) (Khoá Key kết nối truyền dữ liệu) • Username: (Tự đặt theo nhu cầu của KH)&#x20;

• Password: (Tự đặt theo nhu cầu của KH) Hoặc mở TK VIETQR và ký TK và tự khai báo trong link liên kết :&#x20;

<https://pro.vietqr.vn/merchant-register>

<https://pro.vietqr.vn/api-service/3a4fb799-7cae-47e4-a56d-59d4944313e3>

## Cấu trúc tài liệu và thực hiện gồm 5 phần :

1. Implement Get Token API
2. Execute Transaction Sync API
3. Call Get Token API
4. Generate VietQR Code API
5. Test Callback

### **Hướng dẫn thực hiện từng bước:**

#### Bước 1: Cấu hình và kết nối API

Khách hàng cần thực hiện theo thứ tự sau:

• Bước 1 → Bước 2 → Bước 3 → Bước 4 → Bước 5

• Sau khi hoàn tất các bước trên, bắt đầu test kết nối

**Quy trình cụ thể:**

&#x20;         ✅ Bắt đầu từ Bước 1 (Triển khai API Get Token)

&#x20;         ✅ Sau đó chuyển sang Bước 2 (API Transaction Sync)

&#x20;         ✅ Tiếp tục với Bước 3 (Call API Get Token)

&#x20;         ✅ Sau đó thực hiện Bước 4 (API Generate VietQR Code)

&#x20;         ✅ Cuối cùng là Bước 5 (Gọi API Test Callback)

#### Bước 2: Kiểm tra dữ liệu

• Kiểm tra lại dữ liệu đã cấu hình tại Bước 1 và Bước 2 để đảm bảo tính chính xác.

• Nếu có lỗi, cần chỉnh sửa trước khi tiếp tục các bước tiếp theo.

🔹 Lưu ý: Sau khi hoàn tất các bước trên, khách hàng có thể tiến hành kiểm thử toàn bộ quy trình để đảm bảo hệ thống hoạt động đúng yêu cầu

**Hướng dẫn sau khi hoàn tất GOLIVE kiểm thử**

✅ Sau khi test thành công, khách hàng sẽ được nghiệm thu và triển khai trên môi trường dịch vụ thực của tài khoản ngân hàng.

📌 Liên hệ bộ phận kinh doanh (Khối khách hàng Doanh nghiệp số) để hỗ trợ triển khai:

| Cán bộ KD         | • Mobile:                               | • Email:                                   |
| ----------------- | --------------------------------------- | ------------------------------------------ |
| 📞 Lê Hương       | <p>0968 383 636</p><p>024 6663 3324</p> | <huong.le@vietqr.vn> <huong.le@bluecom.vn> |
| 📞 Đạo            | 0923 006 234                            | <dao.nguyen@bluecom.vn>                    |
| 📞 Tạ Quang Tuấn  | 0966 266 049                            | <tuan.ta@bluecom.vn>                       |
| 📞 Hoàng Văn Hiển | 0565 606 789                            | <hien.hoang@bluecom.vn>                    |
| 📞 Thịnh Nguyễn   | 0936 381 333                            | <thinh@bluecom.vn>                         |
| 📞 Tuấn Phạm      | 0922 333 636                            | <tuan@bluecom.vn>                          |
| 📞 Hotline        | 0939 603 636                            | <sales@vietqr.vn> <sales@bluecom.vn>       |

🔹 Nếu cần thêm hỗ trợ, vui lòng liên hệ với bộ phận kinh doanh theo thông tin trên.

Mô tả chi tiết về tài liệu API

{% tabs %}
{% tab title="API Get Token" %}
Các bước để nhận biến động số dư từ VietQR

(Áp dụng để đối tác đồng bộ biến động số dư do VietQR trả về)

Bước 1: Cấp quyền truy cập API

• Đối tác cần cấp quyền cho VietQR bằng cách thiết lập quyền truy cập vào API Transaction Sync.

• Cấu hình điểm nhận dữ liệu (Webhook) để VietQR có thể gửi thông tin biến động số dư.

Bước 2: Cấu hình đầu hứng (Webhook)

• Đối tác cung cấp URL endpoint để nhận dữ liệu.

• Đảm bảo endpoint hỗ trợ nhận dữ liệu từ VietQR với phương thức POST.

• Kiểm tra bảo mật, xác thực request từ VietQR.

Bước 3: VietQR gửi dữ liệu biến động số dư

• Khi có giao dịch mới, VietQR sẽ gửi thông tin biến động số dư theo thời gian thực đến webhook của đối tác.

• Dữ liệu bao gồm:

• Số tiền thay đổi

• Số dư mới

• Thời gian giao dịch

• Mã giao dịch

• Các thông tin khác tùy theo cấu hình

Bước 4: Xác nhận và xử lý dữ liệu từ VietQR

• Đối tác nhận request từ VietQR và xác thực dữ liệu.

• Lưu trữ hoặc xử lý thông tin theo nhu cầu (cập nhật vào hệ thống, hiển thị trên ứng dụng, v.v.).

• Trả về response 200 OK để xác nhận đã nhận dữ liệu thành công.

Bước 5: Kiểm tra và giám sát

• Định kỳ kiểm tra logs để đảm bảo không có lỗi kết nối.

• Nếu có lỗi (mất kết nối, dữ liệu sai, v.v.), cần kiểm tra lại cấu hình webhook hoặc liên hệ hỗ trợ từ VietQR.

👉 Lưu ý: VietQR có thể yêu cầu xác thực webhook bằng token hoặc chữ ký số để đảm bảo an toàn khi truyền dữ liệu.
{% endtab %}

{% tab title="API Transaction Sync" %}

{% endtab %}
{% endtabs %}

```
// Some code
```

<table data-view="cards"><thead><tr><th></th></tr></thead><tbody><tr><td></td></tr></tbody></table>


# API Get Token

API này cho phép đối tác cấp quyền truy cập để VietQR có thể kết nối và đồng bộ dữ liệu với API Transaction Sync (đồng bộ biến động số dư). Để cấp quyền, đối tác cần cấu hình và tạo điểm nhận dữ liệu

### <mark style="color:green;">`2.1 POST`</mark> Get Token <a href="#get-token" id="get-token"></a>

```
https://<your-host>/<your-basepath>/api/token_generate
```

**Headers**

<table><thead><tr><th width="249">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td>Basic Authentication: Base64[<code>username:password</code>]</td></tr></tbody></table>

{% hint style="success" %}
`username` và `password` của API này sẽ do bạn định nghĩa và cung cấp cho VietQR.
{% endhint %}

**Body**

<table><thead><tr><th width="201">Name</th><th width="99">Type</th><th width="101">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>access_token</code></td><td>String</td><td>Yes</td><td>Là Bearer Token do đối tác cung cấp.</td></tr><tr><td><code>token_type</code></td><td>String</td><td>Yes</td><td>Là dạng token dạng “Bearer”.</td></tr><tr><td><code>expires_in</code></td><td>String</td><td>Yes</td><td>Thời gian hết hạn của token.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "access_token": "bearer_token",
    "token_type": "Bearer",
    "expires_in": 300
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### 2.2 - Code cài đặt

Test với Posmant :

curl --location --request POST '<https://uat8.thuythu.vn/mrtao/wp-json/tt-vietqr/api/token_generate>' \ --header 'Authorization: Basic dGFpcGhpbTRrOjYxZTU1ZmU0LTBhNjMtNGU4Zi1hZDgyLTBlNjFiYzk4M\mRlNA=='

{% tabs %}
{% tab title="C#" %}

```csharp
namespace YourNamespace.Controllers
{
    [Route("vqr/api")]
    [ApiController]
    public class TokenController : ControllerBase
    {
        private const string VALID_USERNAME = "customer-vietqrtest-user2468";
        private const string VALID_PASSWORD = "Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09"; // Base64 của username:password
        private const string SECRET_KEY = "your-256-bit-secret"; // Bí mật để ký JWT token

        [HttpPost("token_generate")]
        public IActionResult GenerateToken([FromHeader] string Authorization)
        {
            // Kiểm tra Authorization header
            if (string.IsNullOrEmpty(Authorization) || !Authorization.StartsWith("Basic "))
            {
                return BadRequest("Authorization header is missing or invalid");
            }

            // Giải mã Base64
            var base64Credentials = Authorization.Substring("Basic ".Length).Trim();
            var credentials = Encoding.UTF8.GetString(Convert.FromBase64String(base64Credentials));
            var values = credentials.Split(':', 2);

            if (values.Length != 2)
            {
                return BadRequest("Invalid Authorization header format");
            }

            var username = values[0];
            var password = values[1];

            // Kiểm tra username và password
            if (username == VALID_USERNAME && password == VALID_PASSWORD)
            {
                var token = GenerateJwtToken(username);
                return Ok(new
                {
                    access_token = token,
                    token_type = "Bearer",
                    expires_in = 300 // Thời gian hết hạn token
                });
            }
            else
            {
                return Unauthorized("Invalid credentials");
            }
        }

        // Hàm tạo JWT token
        private string GenerateJwtToken(string username)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(SECRET_KEY);

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(ClaimTypes.Name, username)
                }),
                Expires = DateTime.UtcNow.AddMinutes(5), // Token hết hạn sau 5 phút
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature)
            };

            var token = tokenHandler.CreateToken(tokenDescriptor);
            return tokenHandler.WriteToken(token);
        }
    }
}

// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}

{% tab title="Java" %}

```java
@RestController
@RequestMapping("/vqr/api")
public class TokenController {

    private static final String VALID_USERNAME = "customer-vietqrtest-user2468";
    private static final String VALID_PASSWORD = "Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09"; // Đây là chuỗi base64 từ username:password thật của bạn.

    // API để tạo token
    @PostMapping("/token_generate")
    public ResponseEntity<?> generateToken(@RequestHeader("Authorization") String authHeader) {
        // Kiểm tra xem header có Authorization không
        if (authHeader != null && authHeader.startsWith("Basic ")) {
            // Giải mã Base64 từ Authorization header
            String base64Credentials = authHeader.substring("Basic ".length()).trim();
            String credentials = new String(Base64.getDecoder().decode(base64Credentials), StandardCharsets.UTF_8);

            // Phân tách username và password
            final String[] values = credentials.split(":", 2);
            String username = values[0];
            String password = values[1];

            // Kiểm tra tính hợp lệ của username và password
            if (VALID_USERNAME.equals(username) && VALID_PASSWORD.equals(password)) {
                // Nếu hợp lệ, tạo JWT token
                String token = "your-generated-jwt-token"; // Ở đây bạn cần tạo JWT token thực sự, ví dụ với jjwt.

                return ResponseEntity.ok(new TokenResponse(token, "Bearer", 300));
            } else {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
            }
        } else {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Authorization header is missing or invalid");
        }
    }

    // Class cho response
    public static class TokenResponse {
        private String access_token;
        private String token_type;
        private int expires_in;

        public TokenResponse(String access_token, String token_type, int expires_in) {
            this.access_token = access_token;
            this.token_type = token_type;
            this.expires_in = expires_in;
        }

        // Getters và Setters
        public String getAccess_token() {
            return access_token;
        }

        public void setAccess_token(String access_token) {
            this.access_token = access_token;
        }

        public String getToken_type() {
            return token_type;
        }

        public void setToken_type(String token_type) {
            this.token_type = token_type;
        }

        public int getExpires_in() {
            return expires_in;
        }

        public void setExpires_in(int expires_in) {
            this.expires_in = expires_in;
        }
    }
}

// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}

{% tab title="NodeJS" %}

```javascript
const express = require('express');
const jwt = require('jsonwebtoken');
const bodyParser = require('body-parser');

// Khởi tạo ứng dụng Express
const app = express();
app.use(bodyParser.json());

const VALID_USERNAME = 'customer-vietqrtest-user2468';
const VALID_PASSWORD = 'Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09'; // Base64 của username:password
const SECRET_KEY = 'your-256-bit-secret'; // Secret key để ký JWT

// API để tạo token
app.post('/vqr/api/token_generate', (req, res) => {
    // Kiểm tra Authorization header
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Basic ')) {
        return res.status(400).json({ error: 'Authorization header is missing or invalid' });
    }

    // Giải mã Base64 từ Authorization header
    const base64Credentials = authHeader.split(' ')[1];
    const credentials = Buffer.from(base64Credentials, 'base64').toString('utf-8');
    const [username, password] = credentials.split(':');

    // Kiểm tra username và password
    if (username === VALID_USERNAME && password === VALID_PASSWORD) {
        // Tạo JWT token
        const token = jwt.sign(
            { username }, 
            SECRET_KEY, 
            { algorithm: 'HS512', expiresIn: '5m' } // Token hết hạn sau 5 phút
        );

        // Trả về token
        res.json({
            access_token: token,
            token_type: 'Bearer',
            expires_in: 300 // 300 giây = 5 phút
        });
    } else {
        res.status(401).json({ error: 'Invalid credentials' });
    }
});

// Chạy server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require __DIR__ . '/vendor/autoload.php'; // Autoload từ Composer
use \Firebase\JWT\JWT;

class TokenAPI {
    private $validUsername = 'customer-vietqrtest-user2468';
    private $validPassword = 'Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09'; // Base64 của username:password
    private $secretKey = 'your-256-bit-secret'; // Secret key để ký JWT

    public function generateToken() {
        // Kiểm tra Authorization header
        if (!isset($_SERVER['HTTP_AUTHORIZATION'])) {
            http_response_code(400);
            echo json_encode(["error" => "Authorization header is missing or invalid"]);
            return;
        }

        $authHeader = $_SERVER['HTTP_AUTHORIZATION'];
        if (strpos($authHeader, 'Basic ') !== 0) {
            http_response_code(400);
            echo json_encode(["error" => "Invalid Authorization header"]);
            return;
        }

        // Giải mã Base64 từ Authorization header
        $base64Credentials = substr($authHeader, 6);
        $credentials = base64_decode($base64Credentials);
        list($username, $password) = explode(':', $credentials);

        // Kiểm tra username và password
        if ($username === $this->validUsername && $password === $this->validPassword) {
            $token = $this->createJwtToken($username);
            echo json_encode([
                "access_token" => $token,
                "token_type" => "Bearer",
                "expires_in" => 300
            ]);
        } else {
            http_response_code(401);
            echo json_encode(["error" => "Invalid credentials"]);
        }
    }

    // Hàm tạo JWT token
    private function createJwtToken($username) {
        $issuedAt = time();
        $expirationTime = $issuedAt + 300;  // Token hết hạn sau 300 giây
        $payload = [
            'iss' => 'https://yourdomain.com', // Issuer của token
            'iat' => $issuedAt,
            'exp' => $expirationTime,
            'username' => $username
        ];

        return JWT::encode($payload, $this->secretKey, 'HS512');
    }
}

// Khởi tạo đối tượng và gọi hàm generateToken
$api = new TokenAPI();
$api->generateToken();


// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}

{% tab title="Python" %}

```python
from flask import Flask, request, jsonify
import jwt
import time
import base64

app = Flask(__name__)

# Cấu hình username, password hợp lệ và secret key
VALID_USERNAME = 'customer-vietqrtest-user2468'
VALID_PASSWORD = 'Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09' # Base64 của username:password
SECRET_KEY = 'your-256-bit-secret'  # Secret key để ký JWT

# API để tạo token
@app.route('/vqr/api/token_generate', methods=['POST'])
def generate_token():
    # Kiểm tra Authorization header
    auth_header = request.headers.get('Authorization')
    if not auth_header or not auth_header.startswith('Basic '):
        return jsonify({"error": "Authorization header is missing or invalid"}), 400

    # Giải mã Base64 từ Authorization header
    base64_credentials = auth_header.split(' ')[1]
    credentials = base64.b64decode(base64_credentials).decode('utf-8')
    username, password = credentials.split(':')

    # Kiểm tra username và password
    if username == VALID_USERNAME and password == VALID_PASSWORD:
        # Tạo JWT token
        issued_at = int(time.time())
        expiration_time = issued_at + 300  # Token hết hạn sau 300 giây (5 phút)
        payload = {
            'username': username,
            'iat': issued_at,
            'exp': expiration_time
        }

        token = jwt.encode(payload, SECRET_KEY, algorithm='HS512')

        # Trả về token
        return jsonify({
            "access_token": token,
            "token_type": "Bearer",
            "expires_in": 300
        })
    else:
        return jsonify({"error": "Invalid credentials"}), 401

if __name__ == '__main__':
    app.run(port=5000)

// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}
{% endtabs %}

***

### 2.3 - Các câu hỏi thường gặp chủ đề API Get Token

> <details>
>
> <summary>Làm thế nào để cấp quyền truy cập cho VietQR vào API của chúng tôi?</summary>
>
> Bạn cần tạo một username và password dành riêng cho VietQR để họ có thể truy cập vào API Transaction Sync của bạn. Sau đó, bạn chia sẻ thông tin này với đội ngũ VietQR để họ có thể thực hiện đồng bộ dữ liệu.
>
> </details>
>
> <details>
>
> <summary>Thông tin đăng nhập VietQR sử dụng có bảo mật không?</summary>
>
> VietQR cam kết tuân thủ các quy trình bảo mật nghiêm ngặt. Thông tin đăng nhập mà bạn cung cấp sẽ được mã hóa và chỉ sử dụng cho mục đích đồng bộ dữ liệu theo thỏa thuận giữa hai bên.
>
> </details>
>
> <details>
>
> <summary>Có giới hạn nào về tần suất truy cập mà VietQR có thể thực hiện vào API của tôi?</summary>
>
> Nếu có bất kỳ giới hạn nào về tần suất truy cập hoặc tài nguyên, bạn nên thông báo trước với đội ngũ VietQR để họ có thể điều chỉnh tần suất truy cập phù hợp và tránh quá tải hệ thống.
>
> </details>
>
> <details>
>
> <summary>Tôi có thể giới hạn quyền truy cập của VietQR vào một phần nhất định của API không?</summary>
>
> Có, bạn có thể cấu hình quyền truy cập để VietQR chỉ có thể truy cập vào các endpoint cần thiết cho việc đồng bộ dữ liệu. Điều này giúp đảm bảo an toàn và bảo mật cho hệ thống của bạn.
>
> </details>


# API Transaction Sync

Bước để nhận biến động số dư - Hướng dẫn đối tác đồng bộ dữ liệu giao dịch từ VietQR theo thời gian thực.

### <mark style="color:green;">`POST`</mark> API Transaction Sync <a href="#api-transaction-sync" id="api-transaction-sync"></a>

```
https://<your-host>/<your-basepath>/bank/api/transaction-sync
```

**Headers**

<table><thead><tr><th width="203">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td><code>Bearer &#x3C;token></code>  VietQR nhận được từ API Get Token của bạn trả về ở bước 2.</td></tr></tbody></table>

**Body**

<table data-full-width="false"><thead><tr><th width="203">Name</th><th width="98">Type</th><th width="105">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>bankaccount</code></td><td>String</td><td>Yes</td><td>Tài khoản ngân hàng tạo mã thanh toán.</td></tr><tr><td><code>amount</code></td><td>Long</td><td>Yes</td><td>Số tiền giao dịch.</td></tr><tr><td><code>transType</code></td><td>String</td><td>Yes</td><td>Phân loại giao dịch là ghi nợ/ghi có (giá trị: D/C).</td></tr><tr><td><code>content</code></td><td>String</td><td>Yes</td><td>Nội dung chuyển tiền.</td></tr><tr><td><code>transactionid</code></td><td>String</td><td>Optional</td><td>ID của giao dịch.</td></tr><tr><td><code>transactiontime</code></td><td>String</td><td>Optional</td><td>Tem thời gian giao dịch.</td></tr><tr><td><code>referencenumber</code></td><td>String</td><td>Optional</td><td>Mã giao dịch.</td></tr><tr><td><code>orderId</code></td><td>String</td><td>Optional</td><td>ID của đơn hàng.<br><strong>Lưu ý:</strong> Độ dài orderID không quá 19 ký tự và không chứa ký tự đặc biệt</td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng/điểm bán.</td></tr><tr><td><code>subTerminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng phụ/điểm bán phụ.</td></tr><tr><td><code>serviceCode</code></td><td>String</td><td>Optional</td><td>Mã sản phẩm/dịch vụ.</td></tr><tr><td><code>urlLink</code></td><td>String</td><td>Optional</td><td>Link điều hướng sau khi thanh toán thành công.</td></tr><tr><td><code>sign</code></td><td>String</td><td>Optional</td><td>Chữ ký.</td></tr></tbody></table>

**Respons**

{% tabs %}
{% tab title="200 (OK)" %}

```json
{
    "error": false,
    "errorReason": "mã_lỗi_trả_về_từ_đối_tác",
    "toastMessage": "mô_tả_lỗi_trả_về_từ_đối_tác",
    "object": {
        "reftransactionid": "ID_của_giao_dịch"
    }
}
```

{% endtab %}

{% tab title="400 (Error Request)" %}

```json
{
    "error": false,
    "errorReason": "mã_lỗi_trả_về_từ_đối_tác",
    "toastMessage": "mô_tả_lỗi_trả_về_từ_đối_tác",
    "object": null
}
```

{% endtab %}
{% endtabs %}

### 3.2 Code cài đặt

{% tabs %}
{% tab title="C#" %}

```csharp
namespace YourNamespace.Controllers
{
    [Route("bank/api")]
    [ApiController]
    public class TransactionSyncController : ControllerBase
    {
        private const string SECRET_KEY = "your-256-bit-secret"; // Secret key để kiểm tra JWT
        private const string BEARER_PREFIX = "Bearer ";

        // API để xử lý transaction-sync
        [HttpPost("transaction-sync")]
        public IActionResult TransactionSync([FromBody] TransactionCallback transactionCallback)
        {
            // Lấy token từ header Authorization
            string authHeader = Request.Headers["Authorization"];
            if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith(BEARER_PREFIX))
            {
                return StatusCode(401, new ErrorResponse
                {
                    Error = true,
                    ErrorReason = "INVALID_AUTH_HEADER",
                    ToastMessage = "Authorization header is missing or invalid",
                    Object = null
                });
            }

            string token = authHeader.Substring(BEARER_PREFIX.Length).Trim();

            // Xác thực token
            if (!ValidateToken(token))
            {
                return StatusCode(401, new ErrorResponse
                {
                    Error = true,
                    ErrorReason = "INVALID_TOKEN",
                    ToastMessage = "Invalid or expired token",
                    Object = null
                });
            }

            // Xử lý logic của transaction
            try
            {
                // Ví dụ xử lý nghiệp vụ và sinh mã reftransactionid
                string refTransactionId = "GeneratedRefTransactionId"; // Tạo ID của giao dịch
                
                // Trả về response 200 OK với thông tin giao dịch
                return Ok(new SuccessResponse
                {
                    Error = false,
                    ErrorReason = null,
                    ToastMessage = "Transaction processed successfully",
                    Object = new TransactionResponseObject
                    {
                        reftransactionid = refTransactionId
                    }
                });
            }
            catch (Exception ex)
            {
                // Trả về lỗi trong trường hợp có exception
                return StatusCode(400, new ErrorResponse
                {
                    Error = true,
                    ErrorReason = "TRANSACTION_FAILED",
                    ToastMessage = ex.Message,
                    Object = null
                });
            }
        }

        // Phương thức để xác thực token JWT
        private bool ValidateToken(string token)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(SECRET_KEY);

            try
            {
                tokenHandler.ValidateToken(token, new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ClockSkew = TimeSpan.Zero, // Không cho phép độ trễ thời gian
                }, out SecurityToken validatedToken);

                return true;
            }
            catch
            {
                return false;
            }
        }
    }

    // Lớp model cho request body
    public class TransactionCallback
    {
        public string transactionid { get; set; }
        public long transactiontime { get; set; }
        public string referencenumber { get; set; }
        public decimal amount { get; set; }
        public string content { get; set; }
        public string bankaccount { get; set; }
        public string orderId { get; set; }
        public string sign { get; set; }
        public string terminalCode { get; set; }
        public string urlLink { get; set; }
        public string serviceCode { get; set; }
        public string subTerminalCode { get; set; }
    }

    // Lớp model cho success response
    public class SuccessResponse
    {
        public bool Error { get; set; }
        public string ErrorReason { get; set; }
        public string ToastMessage { get; set; }
        public TransactionResponseObject Object { get; set; }
    }

    // Lớp model cho lỗi response
    public class ErrorResponse
    {
        public bool Error { get; set; }
        public string ErrorReason { get; set; }
        public string ToastMessage { get; set; }
        public object Object { get; set; }
    }

    // Lớp model cho object trả về trong success response
    public class TransactionResponseObject
    {
        public string reftransactionid { get; set; }
    }
}

// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}

{% tab title="Java" %}

```java
@RestController
@RequestMapping("/bank/api")
public class TransactionSyncController {

    private static final String SECRET_KEY = "your-256-bit-secret"; // Secret key để kiểm tra JWT
    private static final String BEARER_PREFIX = "Bearer ";

    @PostMapping("/transaction-sync")
    public ResponseEntity<Object> transactionSync(@RequestBody TransactionCallback transactionCallback,
                                                  HttpServletRequest request) {
        // Lấy token từ header Authorization
        String authHeader = request.getHeader("Authorization");
        if (authHeader == null || !authHeader.startsWith(BEARER_PREFIX)) {
            return new ResponseEntity<>(new ErrorResponse(true, "INVALID_AUTH_HEADER", 
                    "Authorization header is missing or invalid", null), HttpStatus.UNAUTHORIZED);
        }

        String token = authHeader.substring(BEARER_PREFIX.length()).trim();

        // Xác thực token
        if (!validateToken(token)) {
            return new ResponseEntity<>(new ErrorResponse(true, "INVALID_TOKEN", 
                    "Invalid or expired token", null), HttpStatus.UNAUTHORIZED);
        }

        try {
            // Xử lý nghiệp vụ, sinh mã refTransactionId (Giả sử tạo một mã ngẫu nhiên)
            String refTransactionId = "GeneratedRefTransactionId"; // Sinh ID của giao dịch

            // Trả về response 200 OK với thông tin giao dịch
            TransactionResponseObject transactionResponse = new TransactionResponseObject(refTransactionId);
            return ResponseEntity.ok(new SuccessResponse(false, null, 
                    "Transaction processed successfully", transactionResponse));
        } catch (Exception ex) {
            // Trả về lỗi trong trường hợp có exception
            return new ResponseEntity<>(new ErrorResponse(true, "TRANSACTION_FAILED", ex.getMessage(), null), HttpStatus.BAD_REQUEST);
        }
    }

    // Phương thức để xác thực token JWT
    private boolean validateToken(String token) {
        // Đây là phương pháp giả sử validate token với SECRET_KEY
        // Bạn có thể tích hợp JWT library như `io.jsonwebtoken` để validate
        try {
            // Giả sử giải mã token với SECRET_KEY
            byte[] secretKeyBytes = SECRET_KEY.getBytes();
            String decodedToken = new String(Base64.getDecoder().decode(token.getBytes()));

            // Kiểm tra token hợp lệ (thực tế nên sử dụng JWT library như jjwt)
            return decodedToken.contains(SECRET_KEY);
        } catch (Exception e) {
            return false;
        }
    }
}

// Lớp model cho request body
class TransactionCallback {
    private String transactionid;
    private long transactiontime;
    private String referencenumber;
    private double amount;
    private String content;
    private String bankaccount;
    private String orderId;
    private String sign;
    private String terminalCode;
    private String urlLink;
    private String serviceCode;
    private String subTerminalCode;

    // Getters and Setters
    // ...
}

// Lớp model cho success response
class SuccessResponse {
    private boolean error;
    private String errorReason;
    private String toastMessage;
    private TransactionResponseObject object;

    public SuccessResponse(boolean error, String errorReason, String toastMessage, TransactionResponseObject object) {
        this.error = error;
        this.errorReason = errorReason;
        this.toastMessage = toastMessage;
        this.object = object;
    }

    // Getters and Setters
    // ...
}

// Lớp model cho lỗi response
class ErrorResponse {
    private boolean error;
    private String errorReason;
    private String toastMessage;
    private Object object;

    public ErrorResponse(boolean error, String errorReason, String toastMessage, Object object) {
        this.error = error;
        this.errorReason = errorReason;
        this.toastMessage = toastMessage;
        this.object = object;
    }

    // Getters and Setters
    // ...
}

// Lớp model cho object trả về trong success response
class TransactionResponseObject {
    private String reftransactionid;

    public TransactionResponseObject(String reftransactionid) {
        this.reftransactionid = reftransactionid;
    }

    // Getters and Setters
    // ...
}

// Đây là Sample Code mang tính chất tham khảo
```

{% endtab %}

{% tab title="NodeJS" %}

```javascript
const express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');

const app = express();
const PORT = process.env.PORT || 3000;

const SECRET_KEY = 'your-256-bit-secret'; // Secret key để kiểm tra JWT
const BEARER_PREFIX = 'Bearer ';

app.use(bodyParser.json());

// Model cho request body
class TransactionCallback {
    constructor(transactionid, transactiontime, referencenumber, amount, content, bankaccount, orderId, sign, terminalCode, urlLink, serviceCode, subTerminalCode) {
        this.transactionid = transactionid;
        this.transactiontime = transactiontime;
        this.referencenumber = referencenumber;
        this.amount = amount;
        this.content = content;
        this.bankaccount = bankaccount;
        this.orderId = orderId;
        this.sign = sign;
        this.terminalCode = terminalCode;
        this.urlLink = urlLink;
        this.serviceCode = serviceCode;
        this.subTerminalCode = subTerminalCode;
    }
}

// API để xử lý transaction-sync
app.post('/bank/api/transaction-sync', (req, res) => {
    const authHeader = req.headers['authorization'];
    if (!authHeader || !authHeader.startsWith(BEARER_PREFIX)) {
        return res.status(401).json(new ErrorResponse(true, "INVALID_AUTH_HEADER", "Authorization header is missing or invalid", null));
    }

    const token = authHeader.substring(BEARER_PREFIX.length).trim();

    // Xác thực token
    if (!validateToken(token)) {
        return res.status(401).json(new ErrorResponse(true, "INVALID_TOKEN", "Invalid or expired token", null));
    }

    const transactionCallback = new TransactionCallback(
        req.body.transactionid,
        req.body.transactiontime,
        req.body.referencenumber,
        req.body.amount,
        req.body.content,
        req.body.bankaccount,
        req.body.orderId,
        req.body.sign,
        req.body.terminalCode,
        req.body.urlLink,
        req.body.serviceCode,
        req.body.subTerminalCode
    );

    try {
        // Ví dụ xử lý nghiệp vụ và sinh mã reftransactionid
        const refTransactionId = "GeneratedRefTransactionId"; // Tạo ID của giao dịch

        // Trả về response 200 OK với thông tin giao dịch
        return res.status(200).json(new SuccessResponse(false, null, "Transaction processed successfully", new TransactionResponseObject(refTransactionId)));
    } catch (error) {
        // Trả về lỗi trong trường hợp có exception
        return res.status(400).json(new ErrorResponse(true, "TRANSACTION_FAILED", error.message, null));
    }
});

// Phương thức để xác thực token JWT
const validateToken = (token) => {
    try {
        const decoded = jwt.verify(token, SECRET_KEY);
        return true;
    } catch (error) {
        return false;
    }
};

// Lớp model cho success response
class SuccessResponse {
    constructor(error, errorReason, toastMessage, object) {
        this.error = error;
        this.errorReason = errorReason;
        this.toastMessage = toastMessage;
        this.object = object;
    }
}

// Lớp model cho lỗi response
class ErrorResponse {
    constructor(error, errorReason, toastMessage, object) {
        this.error = error;
        this.errorReason = errorReason;
        this.toastMessage = toastMessage;
        this.object = object;
    }
}

// Lớp model cho object trả về trong success response
class TransactionResponseObject {
    constructor(reftransactionid) {
        this.reftransactionid = reftransactionid;
    }
}

// Khởi động server
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

//sample code mang tính chất tham khảo
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

require 'vendor/autoload.php';

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Factory\AppFactory;
use Firebase\JWT\JWT;
use Firebase\JWT\ExpiredException;

$app = AppFactory::create();

$SECRET_KEY = 'your-256-bit-secret'; // Secret key để kiểm tra JWT

// Model cho request body
class TransactionCallback {
    public $transactionid;
    public $transactiontime;
    public $referencenumber;
    public $amount;
    public $content;
    public $bankaccount;
    public $orderId;
    public $sign;
    public $terminalCode;
    public $urlLink;
    public $serviceCode;
    public $subTerminalCode;

    public function __construct($data) {
        $this->transactionid = $data['transactionid'];
        $this->transactiontime = $data['transactiontime'];
        $this->referencenumber = $data['referencenumber'];
        $this->amount = $data['amount'];
        $this->content = $data['content'];
        $this->bankaccount = $data['bankaccount'];
        $this->orderId = $data['orderId'];
        $this->sign = $data['sign'];
        $this->terminalCode = $data['terminalCode'];
        $this->urlLink = $data['urlLink'];
        $this->serviceCode = $data['serviceCode'];
        $this->subTerminalCode = $data['subTerminalCode'];
    }
}

// Lớp model cho success response
class SuccessResponse {
    public $error;
    public $errorReason;
    public $toastMessage;
    public $object;

    public function __construct($error, $errorReason, $toastMessage, $object) {
        $this->error = $error;
        $this->errorReason = $errorReason;
        $this->toastMessage = $toastMessage;
        $this->object = $object;
    }
}

// Lớp model cho lỗi response
class ErrorResponse {
    public $error;
    public $errorReason;
    public $toastMessage;
    public $object;

    public function __construct($error, $errorReason, $toastMessage, $object) {
        $this->error = $error;
        $this->errorReason = $errorReason;
        $this->toastMessage = $toastMessage;
        $this->object = $object;
    }
}

// Lớp model cho object trả về trong success response
class TransactionResponseObject {
    public $reftransactionid;

    public function __construct($reftransactionid) {
        $this->reftransactionid = $reftransactionid;
    }
}

// API để xử lý transaction-sync
$app->post('/bank/api/transaction-sync', function (ServerRequestInterface $request, ResponseInterface $response) use ($SECRET_KEY) {
    $authHeader = $request->getHeaderLine('Authorization');
    $bearerPrefix = 'Bearer ';

    if (empty($authHeader) || !str_starts_with($authHeader, $bearerPrefix)) {
        return $this->respondWithError($response, new ErrorResponse(true, "INVALID_AUTH_HEADER", "Authorization header is missing or invalid", null), 401);
    }

    $token = substr($authHeader, strlen($bearerPrefix));

    // Xác thực token
    if (!validateToken($token, $SECRET_KEY)) {
        return $this->respondWithError($response, new ErrorResponse(true, "INVALID_TOKEN", "Invalid or expired token", null), 401);
    }

    $data = json_decode($request->getBody(), true);
    $transactionCallback = new TransactionCallback($data);

    try {
        // Ví dụ xử lý nghiệp vụ và sinh mã reftransactionid
        $refTransactionId = "GeneratedRefTransactionId"; // Tạo ID của giao dịch

        // Trả về response 200 OK với thông tin giao dịch
        $successResponse = new SuccessResponse(false, null, "Transaction processed successfully", new TransactionResponseObject($refTransactionId));
        $response->getBody()->write(json_encode($successResponse));
        return $response->withStatus(200)->withHeader('Content-Type', 'application/json');
    } catch (Exception $e) {
        return $this->respondWithError($response, new ErrorResponse(true, "TRANSACTION_FAILED", $e->getMessage(), null), 400);
    }
});

// Phương thức để xác thực token JWT
function validateToken($token, $secretKey) {
    try {
        JWT::decode($token, $secretKey, ['HS256']);
        return true;
    } catch (ExpiredException $e) {
        return false;
    } catch (Exception $e) {
        return false;
    }
}

// Phương thức để trả về lỗi response
function respondWithError($response, $errorResponse, $statusCode) {
    $response->getBody()->write(json_encode($errorResponse));
    return $response->withStatus($statusCode)->withHeader('Content-Type', 'application/json');
}

// Khởi động server
$app->run();

//sample code mang tính chất tham khảo
```

{% endtab %}

{% tab title="Python" %}

```python
from flask import Flask, request, jsonify
import jwt
from jwt.exceptions import ExpiredSignatureError, InvalidTokenError

app = Flask(__name__)

SECRET_KEY = 'your-256-bit-secret'  # Secret key để kiểm tra JWT

# Model cho request body
class TransactionCallback:
    def __init__(self, data):
        self.transactionid = data.get('transactionid')
        self.transactiontime = data.get('transactiontime')
        self.referencenumber = data.get('referencenumber')
        self.amount = data.get('amount')
        self.content = data.get('content')
        self.bankaccount = data.get('bankaccount')
        self.orderId = data.get('orderId')
        self.sign = data.get('sign')
        self.terminalCode = data.get('terminalCode')
        self.urlLink = data.get('urlLink')
        self.serviceCode = data.get('serviceCode')
        self.subTerminalCode = data.get('subTerminalCode')

# Lớp model cho success response
class SuccessResponse:
    def __init__(self, error, errorReason, toastMessage, object):
        self.error = error
        self.errorReason = errorReason
        self.toastMessage = toastMessage
        self.object = object

# Lớp model cho lỗi response
class ErrorResponse:
    def __init__(self, error, errorReason, toastMessage, object):
        self.error = error
        self.errorReason = errorReason
        self.toastMessage = toastMessage
        self.object = object

# Lớp model cho object trả về trong success response
class TransactionResponseObject:
    def __init__(self, reftransactionid):
        self.reftransactionid = reftransactionid

@app.route('/bank/api/transaction-sync', methods=['POST'])
def transaction_sync():
    auth_header = request.headers.get('Authorization')
    bearer_prefix = 'Bearer '

    if not auth_header or not auth_header.startswith(bearer_prefix):
        return jsonify(ErrorResponse(True, "INVALID_AUTH_HEADER", "Authorization header is missing or invalid", None).__dict__), 401

    token = auth_header[len(bearer_prefix):]

    # Xác thực token
    if not validate_token(token):
        return jsonify(ErrorResponse(True, "INVALID_TOKEN", "Invalid or expired token", None).__dict__), 401

    transaction_callback = TransactionCallback(request.json)

    try:
        # Ví dụ xử lý nghiệp vụ và sinh mã reftransactionid
        ref_transaction_id = "GeneratedRefTransactionId"  # Tạo ID của giao dịch

        # Trả về response 200 OK với thông tin giao dịch
        success_response = SuccessResponse(False, None, "Transaction processed successfully", 
                                           TransactionResponseObject(ref_transaction_id))
        return jsonify(success_response.__dict__), 200

    except Exception as e:
        return jsonify(ErrorResponse(True, "TRANSACTION_FAILED", str(e), None).__dict__), 400

# Phương thức để xác thực token JWT
def validate_token(token):
    try:
        jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
        return True
    except (ExpiredSignatureError, InvalidTokenError):
        return False

if __name__ == '__main__':
    app.run(debug=True, port=5000)

//sample code mang tính chất tham khảo
```

{% endtab %}
{% endtabs %}

### 3.3 - Các câu hỏi thường gặp triển khai API Transaction Sync

> <details>
>
> <summary>API Transaction Sync dùng để làm gì?</summary>
>
> API Transaction Sync được sử dụng để đồng bộ dữ liệu giao dịch từ hệ thống của VietQR với hệ thống của khách hàng. Nó giúp đảm bảo rằng thông tin về các giao dịch luôn được cập nhật và nhất quán giữa hai hệ thống.
>
> </details>
>
> <details>
>
> <summary>Cần chuẩn bị những gì trước khi triển khai API Transaction Sync?</summary>
>
> Trước khi triển khai, bạn cần chuẩn bị thông tin xác thực (username và password) mà VietQR cung cấp, cùng với endpoint API mà bạn sẽ tích hợp. Đảm bảo hệ thống của bạn đã sẵn sàng để tiếp nhận và xử lý dữ liệu đồng bộ từ VietQR.
>
> </details>
>
> <details>
>
> <summary>Dữ liệu đồng bộ qua API Transaction Sync bao gồm những gì?</summary>
>
> Dữ liệu được đồng bộ qua API Transaction Sync thường bao gồm các thông tin giao dịch như mã giao dịch, số tiền, trạng thái giao dịch, và thời gian thực hiện. Các thông tin chi tiết sẽ phụ thuộc vào cấu hình của VietQR và yêu cầu cụ thể của hệ thống bạn.
>
> </details>
>
> <details>
>
> <summary>Làm thế nào để xử lý nếu việc đồng bộ thất bại?</summary>
>
> Nếu việc đồng bộ thất bại, API sẽ trả về mã lỗi và thông báo chi tiết. Bạn nên kiểm tra lại dữ liệu được gửi, đảm bảo rằng thông tin xác thực là chính xác và hệ thống của bạn có thể tiếp nhận dữ liệu từ API. Nếu lỗi vẫn tiếp diễn, hãy liên hệ với bộ phận kỹ thuật của VietQR.
>
> </details>


# API Get Token

Used to generate and retrieve a token. Used to obtain a bearer token for accessing the API to generate VietQR payment codes.

### <mark style="color:green;">`POST`</mark>

```
https://dev.vietqr.org/vqr/api/token_generate
```

**Headers**

<table><thead><tr><th width="225">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td>Basic Authentication: Base64[<code>username:password</code>]</td></tr></tbody></table>

**Body**

<table><thead><tr><th width="226">Name</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>access_token</code></td><td>String</td><td><p>It is the Bearer Token provided by VietQR after completing <strong>Step 4</strong>.</p><p>Used to access and generate VietQR payment codes.</p></td></tr><tr><td><code>token_type</code></td><td>String</td><td>It is a “Bearer” type token.</td></tr><tr><td><code>expires_in</code></td><td>String</td><td>The token expiration time is set to 300 seconds by default.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "access_token": "bearer_token_của_đối_tác",
    "token_type": "Bearer",
    "expires_in": 300
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

Reference code

{% tabs %}
{% tab title="cURL" %}

```
curl --location --request POST 'https://dev.vietqr.org/vqr/api/token_generate' \
--header 'Authorization: Basic Y3VzdG9tZXItdmlldHFydGVzdC11c2VyMjQ2ODpZM1Z6ZEc5dFpYSXRkbWxsZEhGeWRHVnpkQzExYzJWeU1qUTJPQT09'
Response:
{
    "access_token": "eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGRtbGxkSEZ5ZEdWemRDMTFjMlZ5TWpRMk9BPT0iLCJpYXQiOjE3MjEzNzI2MzQsImV4cCI6MTcyMTM3MjkzNH0.D19qvrpYHUgcGjDCXuXXAv3j6lZr6tfmIB0VzdCzAXMJAElGok04sNLysS6PRLdRb0hSgEX5_9KpLjB-xErn-A",
    "token_type": "Bearer",
    "expires_in": 300
}
```

{% endtab %}
{% endtabs %}

***

### Frequently Asked Questions (FAQs)

<details>

<summary>What is the Get Token API used for?</summary>

API Get Token được sử dụng để cấp quyền truy cập vào các dịch vụ của VietQR bằng cách cung cấp một mã token (`access_token`). Mã token này sẽ được sử dụng trong các yêu cầu API khác để xác thực người dùng.

</details>

<details>

<summary>How do I call the Get Token API?</summary>

Bạn cần gửi một yêu cầu POST đến endpoint của API Get Token với thông tin xác thực (username và password) trong phần header. VietQR sẽ cung cấp thông tin này cho bạn sau khi hoàn tất quá trình đăng ký.

</details>

<details>

<summary>How long is the token valid for?</summary>

Token được cấp bởi API Get Token thường có thời gian sử dụng là 300 giây (5 phút). Sau thời gian này, bạn cần gọi lại API để lấy token mới.

</details>

<details>

<summary>What should I do if I receive an error message when calling the Get Token API?</summary>

Kiểm tra lại các thông tin bạn đã gửi, bao gồm username và password. Đảm bảo rằng các thông tin này đúng và vẫn còn hiệu lực. Nếu vấn đề vẫn tiếp diễn, hãy liên hệ với bộ phận hỗ trợ của VietQR để được giúp đỡ.

</details>

<details>

<summary>Why am I receiving an error code when calling the Get Token API?</summary>

Các mã lỗi thường xuất hiện do vấn đề xác thực (sai username hoặc password), yêu cầu không hợp lệ, hoặc lỗi kết nối. Thông báo lỗi sẽ cung cấp chi tiết về nguyên nhân cụ thể, giúp bạn xác định và khắc phục vấn đề.

</details>

<details>

<summary>Which environments can I use the token in?</summary>

Token được cấp có thể sử dụng trên các API của VietQR, tùy thuộc vào môi trường mà bạn đang sử dụng (Test hoặc Prod). Đảm bảo rằng bạn đang gọi API trên đúng môi trường tương ứng.

</details>

<details>

<summary>How can I secure the token after receiving it?</summary>

Token cần được bảo mật như một thông tin nhạy cảm. Không chia sẻ token với bất kỳ ai và lưu trữ nó một cách an toàn. Khi sử dụng token, hãy đảm bảo rằng kết nối của bạn được mã hóa (sử dụng HTTPS) để bảo vệ thông tin khỏi bị lộ.

</details>


# Gọi API Generate VietQR Code

Dịch vụ cho phép đối tác tạo mã QR Code thanh toán để người dùng quét và thực hiện thanh toán trực tiếp. Tùy thuộc vào loại mã thanh toán VietQR, một số tham số khác nhau sẽ cần được truyền đi.

### <mark style="color:green;">`POST`</mark>

```
https://dev.vietqr.org/vqr/api/qr/generate-customer
```

**Headers**

<table><thead><tr><th width="249">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td>Bearer &#x3C;token>  bạn nhận được khi gọi API Get Token ở bước 5.</td></tr></tbody></table>

**Body**&#x20;

<table data-full-width="false"><thead><tr><th width="215">Name</th><th width="90">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>bankCode</code></td><td>String</td><td>Yes</td><td>Mã ngân hàng của tài khoản. </td></tr><tr><td><code>bankAccount</code></td><td>String</td><td>Yes</td><td>Tài khoản ngân hàng tạo mã thanh toán VietQR.</td></tr><tr><td><code>userBankName</code></td><td>String</td><td>Yes</td><td>Họ tên chủ tài khoản. Không dấu tiếng Việt.</td></tr><tr><td><code>content</code></td><td>String</td><td>Yes</td><td>Nội dung chuyển tiền.<br><mark style="color:red;">T<strong>ối đa 19 ký tự,</strong></mark> tiếng Việt không dấu, không ký tự đặc biệt.</td></tr><tr><td><code>qrType</code></td><td>Integer</td><td>Yes</td><td><p>Tùy loại mã thanh toán cần tạo, nhập giá trị tương ứng:<br>- <mark style="background-color:green;">VietQR động: 0</mark><br>- <mark style="background-color:green;">VietQR tĩnh: 1</mark></p><p>- <mark style="background-color:green;">VietQR bán động: 3</mark> </p></td></tr><tr><td><code>amount</code></td><td>Long</td><td>Optional</td><td>Số tiền cần thanh toán.<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 0 hoặc 3></mark></td></tr><tr><td><code>orderId</code></td><td>String</td><td>Optional</td><td>Mã ID giao dịch bên đối tác cần quản lý. “orderId” sẽ được trả về khi hệ thống nhận biến động số dư (có thông tin giao dịch trùng với giao dịch được tạo bằng mã QR).<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 0></mark></td></tr><tr><td><code>transType</code></td><td>String</td><td>Optional</td><td>Phân loại giao dịch là ghi nợ/ghi có (giá trị: D/C). <br>Mặc định là “C”.<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 0></mark></td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng/điểm bán.<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 1 hoặc 3></mark></td></tr><tr><td><code>serviceCode</code></td><td>String</td><td>Optional</td><td>Mã sản phẩm, dịch vụ được thanh toán.<br><mark style="background-color:green;">&#x3C;Bắt buộc nếu "<code>qrType</code>" = 3></mark></td></tr><tr><td><code>subTerminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng/điểm bán phụ.</td></tr><tr><td><code>sign</code></td><td>String</td><td>Optional</td><td>Chữ ký. </td></tr><tr><td><mark style="color:red;"><strong><code>urlLink</code></strong></mark></td><td><mark style="color:red;"><strong>String</strong></mark></td><td><mark style="color:red;"><strong>Optional</strong></mark></td><td><mark style="color:red;">Trang chuyển đến sau khi quét mã thanh toán. Khi thanh toán thành công sẽ trả về tự động.</mark></td></tr><tr><td><code>note</code></td><td>String</td><td>Optional</td><td>Ghi chú cho giao dịch.</td></tr><tr><td><code>additionalData</code></td><td>Object</td><td>Optional</td><td>Các tham số truyền thêm.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200 - mã QR động" %}

<pre class="language-json"><code class="lang-json"><strong>{
</strong>    "bankCode": "mã_ngân_hàng",
    "bankName": "tên_ngân_hàng",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "userBankName": "tên_chủ_tài_khoản",
    "amount": "số_tiền_cần_thanh_toán",
    "content": "nội_dung_thanh_toán",
    "qrCode": "mã_QR_dạng_string",
    "imgId": "id_ảnh_ngân_hàng",
    "existing": "1: đã_được_tạo_trên_hệ_thống_vietQR_thành_công",
    "transactionId": "id_định_danh_của_QR",
    "transactionRefId": "mã_định_danh_của_QR",
    "qrLink": "mã_QR_dạng_link",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "serviceCode": "mã_sản_phẩm",
    "orderId": "mã_đơn_hàng",
    "additionalData": "thông_tin_thêm"
}
</code></pre>

{% endtab %}

{% tab title="200 - mã QR bán động" %}

```json
{
    "bankCode": "mã_ngân_hàng",
    "bankName": "tên_ngân_hàng",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "userBankName": "tên_chủ_tài_khoản",
    "amount": "số_tiền_cần_thanh_toán",
    "content": "nội_dung_thanh_toán",
    "qrCode": "mã_QR_dạng_string",
    "imgId": "id_ảnh_ngân_hàng",
    "existing": "1: đã_được_tạo_trên_hệ_thống_vietQR_thành_công",
    "transactionId": "id_định_danh_của_QR",
    "transactionRefId": "mã_định_danh_của_QR",
    "qrLink": "mã_QR_dạng_link",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "serviceCode": "mã_sản_phẩm",
    "orderId": "mã_đơn_hàng",
    "additionalData": "thông_tin_thêm"
}
```

{% endtab %}

{% tab title="200 - mã QR tĩnh" %}

```json
{
    "bankCode": "mã_ngân_hàng",
    "bankName": "tên_ngân_hàng",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "userBankName": "tên_chủ_tài_khoản",
    "amount": "số_tiền_cần_thanh_toán",
    "content": "nội_dung_thanh_toán",
    "qrCode": "mã_QR_dạng_string",
    "imgId": "id_ảnh_ngân_hàng",
    "existing": "1: đã_được_tạo_trên_hệ_thống_vietQR_thành_công",
    "transactionId": "id_định_danh_của_QR",
    "transactionRefId": "mã_định_danh_của_QR",
    "qrLink": "mã_QR_dạng_link",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "serviceCode": "mã_sản_phẩm",
    "orderId": "mã_đơn_hàng",
    "additionalData": "thông_tin_thêm"
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code tham khảo

{% tabs %}
{% tab title="cURL tạo mã QR động" %}

```
curl --location 'https://dev.vietqr.org/vqr/api/qr/generate-customer' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=D4468C26FD481B215DBF12CB9707B0AD' \
--header 'Content-Type: application/json' \
--data '{
    "amount": "số_tiền_cần_thanh_toán",
    "content": "nội_dung_thanh_toán",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "bankCode": "mã_ngân_hàng",
    "userBankName": "tên_chủ_tài_khoản",
    "transType": "C:giao_dịch_đến/D:giao_dịch_đi",
    "orderId": "mã_đơn_hàng",
    "sign": "chữ_ký",
    "serviceCode": "mã_sản_phẩm",
    "qrType": "loại qr: 0",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "note": "ghi_chú_mã_qr",
    "urlLink": "link_mà_trang_qr_link_sẽ_redirect_nếu_mã_qr_được_thanh_toán_thành công",
    "additionalData": "thông_tin_thêm_mã_QR_có_thể_truyền_empty_do_KH_tự_định_nghĩa",
}'
```

{% endtab %}

{% tab title="cURL tạo mã QR bán động" %}

```
curl --location 'https://dev.vietqr.org/vqr/api/qr/generate-customer' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=D4468C26FD481B215DBF12CB9707B0AD' \
--header 'Content-Type: application/json' \
--data '{
    "amount": "số_tiền_của_sản_phẩm",
    "content": "nội_dung_thanh_toán",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "bankCode": "mã_ngân_hàng",
    "userBankName": "tên_chủ_tài_khoản",
    "transType": "C:giao_dịch_đến/D:giao_dịch_đi",
    "qrType": "loại qr: 1",
    "terminalCode": "mã_điểm_bán_đã_đồng_bộ"
    "serviceCode": "mã_sản_phẩm",
    "qrType": 3
}'
```

{% endtab %}

{% tab title="cURL tạo mã QR tĩnh" %}

```
curl --location 'https://dev.vietqr.org/vqr/api/qr/generate-customer' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=A2494C77F9BCB561B15CDFDF6FF2CD1F' \
--header 'Content-Type: application/json' \
--data '{
    "content": "nội_dung_thanh_toán",
    "bankAccount": "tài_khoản_ngân_hàng_nhận",
    "bankCode": "mã_ngân_hàng",
    "userBankName": "tên_chủ_tài_khoản",
    "transType": "C:giao_dịch_đến/D:giao_dịch_đi",
    "qrType": "loại qr: 1",
    "terminalCode": "mã_điểm_bán_đã_đồng_bộ"
}'
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp

<details>

<summary>Khi gọi API Generate VietQR Code, tôi gặp phải mã lỗi trả về là "E34"??!</summary>

Khi gặp phải mã lỗi này, bạn hãy kiểm tra lại 2 trường sau:

* &#x20;`content` :&#x20;
  * Độ dài không được vượt quá 19 ký tự.&#x20;
  * Không chứa ký tự đặc biệt.
  * Ký tự thuộc dạng chữ cái Latin/Tiếng Việt không dấu.
* `orderId` :&#x20;
  * Độ dài không được vượt quá 19 ký tự.&#x20;
  * Không chứa ký tự đặc biệt.
  * Ký tự thuộc dạng chữ cái Latin/Tiếng Việt không dấu.

</details>

<details>

<summary>API Generate VietQR Code dùng để làm gì?</summary>

API Generate VietQR Code được sử dụng để tạo mã QR thanh toán cho các giao dịch. Mã QR này có thể được khách hàng quét để thực hiện thanh toán trực tiếp từ tài khoản ngân hàng.

</details>

<details>

<summary>Tôi cần cung cấp những thông tin gì để tạo mã QR thanh toán?</summary>

Để tạo mã QR thanh toán, bạn cần cung cấp các thông tin như số tiền, mã đơn hàng, thông tin người nhận, và thông tin tài khoản ngân hàng của người nhận. Các thông tin này sẽ được mã hóa vào mã QR. Bạn có thể xem chi tiết các thông tin cần thiết cho từng loại mã QR ở trên.

</details>

<details>

<summary>Làm thế nào để biết mã QR đã được tạo thành công?</summary>

Khi mã QR được tạo thành công, API sẽ trả về hình ảnh mã QR dưới dạng string cùng với các thông tin chi tiết liên quan đến giao dịch. Nếu có lỗi xảy ra, bạn sẽ nhận được thông báo lỗi trong phần phản hồi.

</details>

<details>

<summary>Làm thế nào để xử lý lỗi khi gọi API Generate VietQR Code?</summary>

Nếu bạn gặp lỗi khi gọi API, trước tiên hãy kiểm tra lại các thông tin đầu vào như số tiền, thông tin tài khoản, và mã đơn hàng. Đảm bảo rằng các thông tin này chính xác và hợp lệ. Nếu vấn đề vẫn tiếp diễn, hãy liên hệ với bộ phận hỗ trợ kỹ thuật của VietQR để được giúp đỡ.

</details>

<details>

<summary>Mã QR có thể được quét bằng ứng dụng nào?</summary>

Mã QR được tạo bởi API VietQR có thể được quét bằng bất kỳ ứng dụng ngân hàng nào hỗ trợ chuẩn thanh toán QR tại Việt Nam, hoặc các ứng dụng thanh toán ví điện tử có tính năng quét mã QR.

</details>

<details>

<summary>Tôi có cần mã hóa thông tin trước khi gửi đến API không?</summary>

Không, API VietQR sẽ tự động mã hóa các thông tin cần thiết khi tạo mã QR. Bạn chỉ cần đảm bảo rằng các thông tin gửi đến API là chính xác và đầy đủ.

</details>


# Gọi API Test Callback

API này được thiết kế để kiểm tra kết nối callback từ hệ thống VietQR đến hệ thống của đối tác. Đây là một phần của quá trình thử nghiệm và giả lập.

{% hint style="danger" %}
**Lưu ý: API này chỉ có thể áp dụng ở môi trường Sandbox (TEST).**
{% endhint %}

{% hint style="success" %}
**Giả Định Giao Dịch:** Trong môi trường thử nghiệm này, API giả định rằng một giao dịch đã được hoàn thành và thanh toán.
{% endhint %}

### <mark style="color:green;">`POST`</mark>&#x20;

```
https://dev.vietqr.org/vqr/bank/api/test/transaction-callback
```

**Headers**

<table><thead><tr><th width="250">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td><code>Bearer &#x3C;token></code></td></tr></tbody></table>

**Body**

<table data-full-width="false"><thead><tr><th width="213">Name</th><th width="92">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>bankAccount</code></td><td>String</td><td>Yes</td><td>Tài khoản ngân hàng tạo mã thanh toán VietQR.</td></tr><tr><td><code>content</code></td><td>String</td><td>Yes</td><td>Nội dung chuyển tiền. <br><em>Bạn cần truyền đúng nội dung ở phần response khi tạo mã (bước 6).</em></td></tr><tr><td><code>amount</code></td><td>Long</td><td>Yes</td><td><em>Số tiền mà bạn đã tạo mã thanh toán ở bước 6.</em></td></tr><tr><td><code>transType</code></td><td>String</td><td>Yes</td><td>Phân loại giao dịch là ghi nợ/ghi có (giá trị: D/C). Mặc định là “C”.</td></tr><tr><td><code>bankCode</code></td><td>String</td><td>Yes</td><td>Mã ngân hàng. <br>VD: "MB" cho ngân hàng MBBank.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "status": "SUCCESS",
    "message": "ID_của_giao_dịch"
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://dev.vietqr.org/vqr/bank/api/test/transaction-callback' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIxNDUwMzEzLCJleHAiOjE3MjE0NTA2MTN9.u0hK2fZVFvtaZQ3jyVJmMvhyqW8aRFGJIgpL8C71jtXbAPfPhqyJIdGc0Lv-XOY7e1NcjZQWH3FUhc4SXxgqlQ' \
--header 'Cookie: JSESSIONID=5DAD675C6D1BFEB2305B2340FE3BEDEC' \
--data '{
    "bankAccount": "tài_khoản_ngân_hàng_đồng_bộ",
    "content": "nội_dung_test_callback_là_nội_dung_khi_quét_mã_qr_thanh_toán",
    "amount": "số_tiền",
    "bankCode": "mã_ngân_hàng", //VD: "MB" cho ngân hàng MBBank.
    "transType": "C:giao_dịch_đến, D:giao_dịch_đi"
}'
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp

<details>

<summary>API Test Callback dùng để làm gì?</summary>

API Test Callback được sử dụng để kiểm tra khả năng tiếp nhận và xử lý callback từ hệ thống của VietQR đến hệ thống của bạn. Nó giúp xác minh rằng hệ thống của bạn có thể nhận và xử lý thông báo từ VietQR khi có sự kiện xảy ra.

</details>

<details>

<summary>Tại sao cần phải thực hiện Test Callback?</summary>

Thực hiện Test Callback giúp đảm bảo rằng hệ thống của bạn có thể nhận thông báo (callback) một cách chính xác từ VietQR, điều này rất quan trọng trong việc đồng bộ trạng thái giao dịch và phản hồi kịp thời cho khách hàng.

</details>

<details>

<summary>Khi nào nên thực hiện Test Callback?</summary>

Bạn nên thực hiện Test Callback sau khi đã cấu hình xong các endpoint cần thiết trên hệ thống của mình và trước khi triển khai dịch vụ vào môi trường sản xuất. Điều này giúp phát hiện và khắc phục sớm các vấn đề tiềm ẩn.

</details>

<details>

<summary>Làm thế nào để kiểm tra rằng hệ thống của tôi đã nhận đúng callback?</summary>

Bạn có thể theo dõi log hệ thống của mình hoặc kiểm tra các phản hồi từ API Test Callback để xác nhận rằng hệ thống đã nhận đúng callback và xử lý nó theo mong đợi.

</details>

<details>

<summary>Phản hồi của API Test Callback sẽ như thế nào?</summary>

API Test Callback sẽ gửi một yêu cầu HTTP POST đến endpoint của API Transaction Sync mà bạn đã cấu hình, với dữ liệu mô phỏng giao dịch đã được thanh toán thực tế. Hệ thống của bạn cần trả về một phản hồi HTTP 200 OK để xác nhận rằng callback đã được nhận và xử lý thành công.

</details>

<details>

<summary>Sau khi tôi gọi API Test Callback thành công, nhưng vẫn chưa nhận được báo có giao dịch từ API Transaction Sync?</summary>

Hãy truyền đúng 2 trường `content` và `amount` được trả về ở phần response lúc tạo mã ở bước 6.

</details>

<details>

<summary><strong>Nếu callback không được xử lý thành công thì cần làm gì?</strong></summary>

Nếu callback không được xử lý thành công, bạn cần kiểm tra lại cấu hình endpoint, logic xử lý callback trên hệ thống của bạn, và thử lại Test Callback. Kiểm tra log và các thông báo lỗi để xác định nguyên nhân và khắc phục.

</details>

<details>

<summary>Có thể thực hiện Test Callback bao nhiêu lần?</summary>

Bạn có thể thực hiện Test Callback nhiều lần cho đến khi đảm bảo rằng hệ thống của bạn có thể xử lý callback một cách chính xác và ổn định.

</details>

<details>

<summary>Làm thế nào để xác nhận rằng callback đã được xử lý đúng cách?</summary>

Sau khi nhận được callback, hệ thống của bạn cần thực hiện các bước xử lý theo yêu cầu và gửi phản hồi HTTP 200 OK. Kiểm tra log hệ thống để đảm bảo rằng tất cả các bước đã được thực hiện đúng.

</details>


# Synchronize information

Hỗ trợ đối tác quản lý các giao dịch của cửa đại lý/cửa hàng/điểm bán một cách dễ dàng hơn.

{% tabs %}
{% tab title="Mục đích" %}
Việc đồng bộ thông tin giữa các đơn vị trong mạng lưới phân phối là vô cùng quan trọng. Mục đích chính của việc này bao gồm:

<table data-header-hidden><thead><tr><th width="148"></th><th></th></tr></thead><tbody><tr><td>Tổng Đại Lý</td><td>Quản trị kết nối và theo dõi hiệu quả hoạt động của mạng lưới phân phối.</td></tr><tr><td>Đại Lý</td><td><ul><li>Sử dụng dịch vụ tạo mã VietQR tĩnh cho các cửa hàng/điểm bán trực thuộc.</li><li>Nhận báo cáo doanh số và quản trị giao dịch theo từng mã cửa hàng/điểm bán.</li></ul></td></tr></tbody></table>

Việc đồng bộ thông tin các cửa hàng/điểm bán với Đại Lý là vô cùng cần thiết để đảm bảo các tiện ích trên được vận hành hiệu quả.
{% endtab %}

{% tab title="Quy trình thực hiện" %}
**Đối với Tổng Đại Lý:**

* Đối tác sử dụng [API Sync MID(s)](broken://pages/Qtfq4VAcFRmxjJJEtG8b) để đồng bộ thông tin các đại lý phân phối trực thuộc.

**Đối với Đại Lý:**

* Đối tác sử dụng [API Get MID(s)](broken://pages/ghOhkaCcp4jorSIxpbKv) để lấy thông tin đại lý của mình.
* Đối tác truyền tham số `MID` vào [API Get TID(s)](broken://pages/G51YmPkxAqaE9YkqRFWQ) để lấy danh sách thông tin các điểm bán/cửa hàng đã đồng bộ.
* Đối tác sử dụng[ API Sync TID(s)](broken://pages/t3Z08nJLgFa3gUmjRVcj) để đồng bộ thông tin các điểm bán/cửa hàng trực thuộc.
* Đối tác sử dụng giá trị của `terminalCode` để gọi [API Generate VietQR Code](broken://pages/jiuumbNC6UuMA2B0vUdE) để tạo mã VietQR và đánh dấu giao dịch.
  {% endtab %}
  {% endtabs %}

> Trường hợp Đại Lý không có nhu cầu sử dụng mã VietQR tĩnh và quản trị trên hệ thống VietQR, có thể bỏ qua bước này.


# Synchronize master agent

This API is used to synchronize the information of agents under the master agent.

{% hint style="danger" %}
Customers and partners who are not under the master agent category can skip this step.
{% endhint %}

<mark style="color:green;">**`POST`**</mark> API Sync MID

```
https://<vietqr-host>/<basepath>/api/mid/synchronize/v1
```

**Headers**

<table><thead><tr><th width="209.5703125">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td><code>Bearer &#x3C;token></code></td></tr></tbody></table>

**Body**

<table data-full-width="false"><thead><tr><th width="211">Name</th><th width="106.296875">Type</th><th width="88.3671875">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>merchants</code></td><td>List object</td><td>Yes</td><td>List of agents to be synchronized.</td></tr><tr><td><code>merchantId</code></td><td>String</td><td>Yes</td><td>Agent ID. (Set to null if it is a new synchronization)</td></tr><tr><td><code>merchantFullName</code></td><td>String</td><td>Yes</td><td>Agent name.</td></tr><tr><td><code>merchantName</code></td><td>String</td><td>Yes</td><td><p>Agent short name.</p><p>Must not contain Vietnamese accents, spaces, or special characters.</p></td></tr><tr><td><code>merchantAddress</code></td><td>String</td><td>Yes</td><td>Registered business address.</td></tr><tr><td><code>merchantIdentity</code></td><td>String</td><td>Yes</td><td>Tax Identification Number (MST) / Citizen Identification Number (CCCD) / Business Registration Number (ĐKKD)</td></tr><tr><td><code>checkSum</code></td><td>String</td><td>Yes</td><td><p>MD5 hash string of the combination:</p><p>(password + merchantName + merchantIdentity)</p><p>(<code>password</code>+ <code>merchantName</code>+<code>merchantIdentity</code>)</p></td></tr><tr><td><code>contactEmail</code></td><td>String</td><td>Optional</td><td>Agent’s contact email address.</td></tr><tr><td><code>contactPhone</code></td><td>String</td><td>Optional</td><td>Agent’s contact phone number.</td></tr><tr><td><code>career</code></td><td>String</td><td>Optional</td><td>Registered business industry.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "status": "SUCCESS",
    "data": [
        {
            "mid": "ID_đại_lý",
            "merchantName": "tên_rút_gọn_đại_lý"
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

### Sample Code

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://api.vietqr.org/vqr/api/mid/synchronize/v1' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIxMzc1MzUzLCJleHAiOjE3MjEzNzU2NTN9.Wi5BTmJ63f7h_p7rimfaycfGIs4TNBkzVGlCUSkOxzWU-QaYZF3rCNndlgPjO89LpRmU3VliSYcf5iHHNrnC7A' \
--header 'Cookie: JSESSIONID=068E5AFD023BFA9AAFBA841C0BF00B62' \
--data-raw '{
    "merchants": [ // List of stores to be synchronized.
        {
            "merchantFullName": "Full name of the agent.",
            "merchantName": "Abbreviated name.",
            "merchantAddress": "Agent’s address.",
            "merchantIdentity": "Tax Identification Number.",
            "contactEmail": "Contact email",
            "contactPhone": "Contact phone number",
            "checkSum": "HASHMD5 128bit của: mật_khẩu_get_token + merchant_name + merchantIdentity"
        }
    ]
}'
```

{% endtab %}
{% endtabs %}

### Frequently Asked Questions (FAQs)


# Kiểm tra danh sách đại lý

Dùng để lấy danh sách thông tin các đại lý đã đồng bộ thuộc tổng đại lý.

<mark style="color:green;">**`GET`**</mark> API Get MID

```
https://<vietqr-host>/<basepath>/api/mid/list-mid
```

**Headers**

<table><thead><tr><th width="283">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td><code>Bearer &#x3C;token></code></td></tr></tbody></table>

**Body**

<table data-full-width="false"><thead><tr><th width="197">Name</th><th width="93">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>page</code></td><td>Integer</td><td>Optional</td><td>Giá trị trang muốn hiển thị.</td></tr><tr><td><code>size</code></td><td>Integer</td><td>Optional</td><td>Giá trị số item tối đa hiển thị của page.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "metadata": {
        "page": 1,
        "size": 20,
        "totalPage": 1,
        "totalElement": 1
    },
    "data": [
        {
            "merchantIdentify": "MST/CCCD/ĐKKD",
            "mid": "ID_của_đại_lý",
            "merchantName": "tên_rút_gọn_đại_lý",
            "merchantFullName": "tên_đại_lý",
            "merchantAddress": "địa_chỉ_đại_lý",
            "contactEmail": "email_liên_hệ",
            "contactPhone": "điện_thoại_liên_hệ"
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://api.vietqr.org/vqr/api/mid/list-mid?page=page_cần_chọn&size=số_record_cần_hiển_thị_trong_1_lần&mid=id_của_đại_lý' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIxMzc1MTUyLCJleHAiOjE3MjEzNzU0NTJ9.M-Yfnvm_mZGVteqoZ4aLdN2m_7_c8BwUHnzHm0WPOMW5ayTk49HWLtpl562AdgS_BUBUAS0648BktOaGzy6h8Q' \
--header 'Cookie: JSESSIONID=483ACB24C22E803DCFB52C2D89CCB4B0'
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp


# Đồng bộ điểm bán

Dùng để đồng bộ thông tin các cửa hàng/điểm bán.

<mark style="color:green;">**`POST`**</mark> API Sync TID

```
https://<vietqr-host>/<basepath>/api/tid/synchronize/v1
```

**Headers**

<table><thead><tr><th width="283">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td><code>Bearer &#x3C;token></code></td></tr></tbody></table>

**Body**

{% hint style="warning" %}
Đối tác truyền `merchantId` thì không cần truyền `merchantName`.
{% endhint %}

<table data-full-width="false"><thead><tr><th width="240">Name</th><th width="110">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>terminals</code></td><td>List object</td><td>Yes</td><td>Danh sách các điểm bán.</td></tr><tr><td><code>merchantId</code></td><td>String</td><td>Yes</td><td>ID của đại lý.</td></tr><tr><td><code>merchantName</code></td><td>String</td><td>Yes</td><td>Tên rút gọn đại lý.</td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Yes</td><td>Mã cửa hàng/điểm bán.</td></tr><tr><td><code>terminalName</code></td><td>String</td><td>Yes</td><td>Tên cửa hàng/điểm bán.</td></tr><tr><td><code>terminalAddress</code></td><td>String</td><td>Yes</td><td>Địa chỉ cửa hàng/điểm bán.</td></tr><tr><td><code>bankCode</code></td><td>String</td><td>Yes</td><td>Mã ngân hàng.</td></tr><tr><td><code>bankAccount</code></td><td>String</td><td>Yes</td><td>Số tài khoản ngân hàng.</td></tr><tr><td><code>checkSum</code></td><td>String</td><td>Yes</td><td><p>Chuỗi mã hóa MD5 của tổ hợp:</p><p>(<code>password</code> + <code>bankCode</code> + <code>bankAccount</code>)</p></td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "status": "SUCCESS",
    "data": [
        {
            "tid": "ID_điểm_bán",
            "terminalName": "tên_điểm_bán",
            "terminalCode": "mã_điểm_bán",
            "bankAccount": "số_tài_khoản_áp_dụng_cho_điểm_bán",
            "bankCode": "mã_ngân_hàng"
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://api.vietqr.org/vqr/api/tid/synchronize/v1' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIwMDg4MDE3LCJleHAiOjE3MjAwODgwNzZ9.3_jljTg8llYVANJW4MVqW6YsJZbFl10r2AC66NNXCuSDWMyNYd2MlbnStNuyjHIqYDO5E5jD0izl4puPckYSyw' \
--header 'Cookie: JSESSIONID=EB9099326C4526CAA29AD331FFE6B789' \
--data '{
    "terminals": [ //DANH SÁCH CỬA HÀNG CỦA ĐẠI LÝ C ̀N ĐỒNG BỘ
        {
            "mid": "id_của_đại_lý", 
            "merchantName": "tên_viết_tắt_của_đại_lý", 
            "terminalName": "tên_cửa_hàng",
            "terminalCode": "mã_code_của_cửa_hàng",
            "terminalAddress": "địa_chỉ_của_cửa_hàng",
            "bankAccount": "số_tài_khoản_ngân_hàng",
            "bankCode": "mã_code_của_ngân_hàng",
            "checkSum": "HASHMD5 128 bit của: password_khi_get_token + bank_code + bankAccount" 
            
        }
    ]
}'
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp


# Kiểm tra danh sách điểm bán

Dùng để lấy danh sách thông tin các cửa hàng/điểm bán đã đồng bộ.

<mark style="color:green;">**`GET`**</mark> API Get TID

```
https://<vietqr-host>/<basepath>/api/tid/list-tid
```

**Headers**

<table><thead><tr><th width="283">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td><code>Bearer &#x3C;token></code></td></tr></tbody></table>

**Body**

<table><thead><tr><th width="192">Name</th><th width="89">Type</th><th width="99">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>page</code></td><td>Integer</td><td>Optional</td><td>Giá trị trang muốn hiển thị.</td></tr><tr><td><code>size</code></td><td>Integer</td><td>Optional</td><td>Giá trị số item tối đa hiển thị của page.</td></tr><tr><td><code>mid</code></td><td>String</td><td>Yes</td><td>ID của đại lý.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "metadata": {
        "page": 1,
        "size": 20,
        "totalPage": 1,
        "totalElement": 1
    },
    "data": [
        {
            "bankAccount": "số_tài_khoản_áp_dung_cho_điểm_bán",
            "bankCode": "mã_ngân_hàng",
            "terminalCode": "mã_điểm_bán",
            "terminalName": "tên_điểm_bán",
            "terminalAddress": "địa_chỉ_điểm_bán",
            "tid": "ID_của_điểm_bán"
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://api.vietqr.org/vqr/api/tid/list-tid?page=page_cần_chọn&size=số_record_cần_hiển_thị_trong_1_lần&mid=id_của_đại_lý' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIxMzc0ODQxLCJleHAiOjE3MjEzNzUxNDF9.q2VEtZfITLi-Odvf0PPSyG_BDCzYeTNR3E8KkfUWg9yMOgczZYjcAS7-UyQZe6_TZh874CHcjw6NvGc8Fd8i3g' \
--header 'Cookie: JSESSIONID=EB9099326C4526CAA29AD331FFE6B789' \
--data ''
```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp


# MASTER MERCHANT

## 1- API tạo merchant mới :&#x20;

## 2 -  QR ACTIVE ACTIVE  (CHIỀU APP VIETQR)

Đối tác Master merchant được cấp API dạng token đê in ra Mã QR hoặc hiển thị trên Web hoặc app của Merchant Giúp khách hàng có thể quét Mã QR lựa chọn tài khoản Kích hoạt dịch vụ :

<figure><img src="https://content.gitbook.com/content/SRgURCFAGmE4PjobTdbe/blobs/jHTXda8msdqQNjSmTUmh/image.png" alt=""><figcaption></figcaption></figure>

Ví dụ :&#x20;

| Mã Active trên thiết bị                                                                                                               | Mã Active trên Website | Mã Active trên App |
| ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | ------------------ |
| <img src="https://content.gitbook.com/content/SRgURCFAGmE4PjobTdbe/blobs/qziSTabh0ZnSUgI5EIBv/image.png" alt="" data-size="original"> |                        |                    |

## 2 - API ATCITIVE (CHIỀU TỪ ĐẠI LÝ)

Khách hàng mở ứng dụng VietQR, tiến hành cài đặt và thiết lập QRBox tự động (do VietQR tạo và phê duyệt).

Sau đó, hệ thống thực hiện API call đến Master để kiểm tra trạng thái, xác định thành công hoặc thất bại.


# Retry giao dịch

Hướng dẫn nghiệp vụ Retry trong hệ thống VietQR

Nghiệp vụ Retry là quá trình VietQR sẽ tự động đẩy lại thông tin biến động số dư (BĐSD) bị lỗi trước đó đến phía đối tác. Quá trình này bao gồm hai phần chính:

1\. Giao dịch bị lỗi do timeout hoặc lỗi kết nối giữa hệ thống VietQR và đối tác: VietQR sẽ thực hiện retry, tức là đẩy lại thông tin BĐSD.

2\. Giao dịch nhận được mã lỗi từ API Transaction-sync của đối tác: Nếu mã lỗi thuộc bộ mã lỗi yêu cầu thực hiện retry, VietQR sẽ tiến hành retry lại giao dịch.

### Quy trình Retry của VietQR

• VietQR sẽ thực hiện retry thông tin BĐSD cho đến khi nhận được phản hồi thành công từ phía đối tác hoặc phản hồi với các mã lỗi không yêu cầu retry.

• Số lần retry tối đa là 10 lần. Trong phút đầu tiên, VietQR sẽ retry 5 lần. Từ phút thứ 2 trở đi, hệ thống sẽ retry mỗi phút một lần.

• Khi tích hợp nghiệp vụ retry, đối tác cần kiểm tra kỹ mã giao dịch (referenceNumber) để tránh tình trạng trùng lặp giao dịch. VietQR đảm bảo không ghi nhận giao dịch bị trùng lặp.

### Các bước thực hiện tích hợp nghiệp vụ Retry

1\. VietQR cung cấp một file định dạng để đối tác khai báo bộ mã lỗi.

2\. Đối tác cung cấp thông tin về bộ mã lỗi của mình vào file.

3\. VietQR tiến hành cấu hình tích hợp retry dựa trên bộ mã lỗi của đối tác.

4\. Hai bên thực hiện kiểm thử và nghiệm thu quy trình.

5\. Đối tác tiến hành golive nghiệp vụ retry.

Hướng dẫn này nhằm đảm bảo quá trình retry diễn ra suôn sẻ và tránh những lỗi không mong muốn.


# GOLIVE API

Guide to Registering Golive Services for Customers and Partners

<figure><img src="https://2475115081-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSRgURCFAGmE4PjobTdbe%2Fuploads%2F6qY5nGYcvjFmzAzLSx74%2Fimage.png?alt=media&amp;token=818b3e90-a4fa-4979-8311-8bf6a2999378" alt="Golive dịch vụ VietQR" width="123"><figcaption><p>Dev.VietQR.vn --> Api.VietQR.vn</p></figcaption></figure>

3 Steps to Successfully Connect to the VietQR API

Sau khi đại lý và khách hàng golive kết nối thành công có thể tiến hành golive dịch vụ!

Chú ý về nhận diện thương hiệu :thumbsup:

oàn bộ Kết nối thanh toán qua Mã VietQR cần có Logo VietQR Để tạo sự thuận lợi cho khách hàng trong quá trình thanh toán.

Có những hướng dẫn cơ bản để người dùng&#x20;


# Nghiệm thu và yêu cầu GoLive

Sau khi hoàn thành việc tích hợp và kiểm tra, bạn hãy yêu cầu nghiệm thu và tiến hành đưa dịch vụ vào hoạt động chính thức (GoLive).

{% file src="/files/En5py3ExCQhp66F53GO8" %}

{% hint style="success" %}
Download file trên, xác thực lại các thông tin sẽ được cấu hình GOLive (môi trường PROD).
{% endhint %}

{% hint style="success" %}
Sau khi đã hoan tất xác thực thông tin, hãy gửi lại file copy cho đội kỹ thuật để hoàn tất cấu hình và tiến hành đưa dịch vụ vào hoạt động chính thức (GoLive).
{% endhint %}


# OTHER API SERVICE

Refund, MQTT, Host To Client, Sound Box Cloud...

We provide a variety of APIs to support business expansion and product diversification for our clients, including:

* **VietQR Refund APIs**
* **API Host to Device (MQTTs)**
* **Host To Client**
* **API Sound Box Cloud.**


# VietQR Refund APIs

Mô tả yêu cầu nghiệp vụ và quy trình tích hợp cho bộ API Services dịch vụ hoàn tiền VietQR.

### Mô tả

<figure><img src="https://content.gitbook.com/content/SRgURCFAGmE4PjobTdbe/blobs/RgNhMVvcp3Bxv3e9er1n/Process%20Map%20Refund%20API.png" alt=""><figcaption></figcaption></figure>

**Dịch vụ hoàn tiền qua VietQR hoạt động theo các bước sau:**

1. Khách hàng đã tích hợp xong dịch vụ [VietQR Payment APIs](/en/vn/api-vietqr-callback).
2. Yêu cầu VietQR cấp `secretKey` để dùng dịch vụ hoàn tiền.
3. Gọi [API Check Transaction](/en/vn/other-api-service/vietqr-refund-apis/goi-api-check-transaction) để kiểm tra và khởi tạo giao dịch cần hoàn tiền.
4. Gọi [API Refund](/en/vn/other-api-service/vietqr-refund-apis/goi-api-refund) để thực hiện hoàn tiền.

***

### Quy định về quy trình kết nối

Đối tác cần tuân thủ theo quy trình kết nối dịch vụ để đảm bảo hệ thống vận hành một cách hiệu quả nhất, giảm thiểu rủi ro không mong muốn. (Tham khảo quy trình tích hợp [VietQR Payment API](/en/vn/api-vietqr-callback))


# Gọi API Check Transaction

Dùng để tra soát thông tin các giao dịch đã thực hiện.

### <mark style="color:green;">`POST`</mark>

```
https://<vietqr-host>/<basepath>/api/transactions/check-order
```

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

<table data-full-width="false"><thead><tr><th width="187">Name</th><th width="92">Type</th><th width="98">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>bankAccount</code></td><td>String</td><td>Yes</td><td>Số tài khoản ngân hàng.</td></tr><tr><td><code>type</code></td><td>String</td><td>Yes</td><td>Check by <code>orderId</code>: 0<br>Check by <code>referenceNumber</code>: 1</td></tr><tr><td><code>value</code></td><td>String</td><td>Yes</td><td>Giá trị là<code>orderId</code> nếu <code>type</code> = 0<br>Giá trị là<code>referenceNumber</code> nếu <code>type</code> = 1</td></tr><tr><td><code>checkSum</code></td><td>String</td><td>Yes</td><td><p>Chuỗi mã hóa MD5 của tổ hợp:</p><p>(<code>bankAccount</code> + <code>username</code>)</p></td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
[
    {
        "referenceNumber": "mã_giao_dịch",
        "orderId": "mã_đơn_hàng",
        "amount": số_tiền_giao_dịch,
        "content": "nội_dung_thanh_toán",
        "transType": "giao_dịch_đến_hoặc_đi",
        "status": phân_loại_trạng_thái_giao_dịch_theo_số,
        "type": phân_loại_giao_dịch_theo_số,
        "timeCreated": tem_thời_gian_tạo_mã_QR,
        "timePaid": tem_thời_gian_thanh_toán,
        "terminalCode": "mã_điểm_bán",
        "note": "ghi_chú_giao_dịch",
        "refundCount": số_lần_đã_hoàn_tiền_thuộc_giao_dịch_này,
        "amountRefunded": số_tiền_đã_hoàn_tiền_thuộc_giao_dịch_này
    }
]
```

{% hint style="info" %}
Giá trị trả về của `type`:

* 0: Giao dịch từ mã VietQR động.
* 1: Giao dịch từ mã VietQR tĩnh.
* 2: Giao dịch ngoài hệ thống VietQR.
* 3: Giao dịch từ mã VietQR bán động.
  {% endhint %}

{% hint style="info" %}
Giá trị trả về của `status`:

* 0: Giao dịch chờ thanh toán.
* 1: Giao dịch đã thanh toán.
* 2: Giao dịch hết hạn thanh toán.
  {% endhint %}
  {% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://api.vietqr.org/vqr/api/transactions/check-order' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=F40E5CBDEEB02F82DF40BAD476A6222B' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIxMzc2MzQ2LCJleHAiOjE3MjEzNzY2NDZ9.QfnN8-p79uB8w5rTRmuOBoANrku276Jtzd7osltE9-E1zQfiXo0YlGCiX1cOHe4A0_VRWJPC5s0tymhND2kGnQ' \
--data '{
    "bankAccount": "tài_khoản_ngân_hàng",
    "type": "loại_check_giao_dịch: 0: mã_đơn_hàng, 1: mã_giao_dịch",
    "value": "giá_trị_cần_check",
    "checkSum": "HASH MD5 128 bit của: bankAccount + username"
    }'

```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp

<details>

<summary>API Check Transaction dùng để làm gì?</summary>

API này được sử dụng để kiểm tra trạng thái của một giao dịch cụ thể trước khi thực hiện các thao tác tiếp theo như hoàn tiền.

</details>

<details>

<summary><code>checkSum</code> là gì và tại sao nó quan trọng?</summary>

`checkSum` là một chuỗi mã hóa MD5 128 bit của các giá trị `bankAccount` và `username`, đảm bảo tính toàn vẹn và bảo mật của yêu cầu. Nó giúp xác thực rằng dữ liệu không bị thay đổi trong quá trình truyền.

</details>

<details>

<summary>Nếu API Check Transaction trả về trạng thái "FAILED", điều đó có nghĩa là gì?</summary>

Trạng thái "FAILED" có thể chỉ ra rằng mã giao dịch hoặc mã đơn hàng không hợp lệ, hoặc giao dịch đã bị hủy. Bạn nên kiểm tra lại các thông tin đầu vào hoặc liên hệ với bộ phận hỗ trợ.

</details>

<details>

<summary>Làm thế nào để xử lý các lỗi phổ biến khi sử dụng API Check Transaction?</summary>

* Một số lỗi phổ biến bao gồm:
  * Sai thông tin đầu vào (`bankAccount`, `value`, hoặc `checkSum` không chính xác).
  * Token hết hạn hoặc không hợp lệ.
  * Kết nối không thành công.
* Đảm bảo rằng bạn đã kiểm tra kỹ các thông tin và token trước khi gọi API.

</details>

<details>

<summary>Tôi có thể kiểm tra trạng thái của bất kỳ giao dịch nào bằng API này không?</summary>

Bạn chỉ có thể kiểm tra trạng thái của các giao dịch đã thực hiện qua hệ thống VietQR và phải cung cấp thông tin chính xác tương ứng với mã giao dịch hoặc mã đơn hàng.

</details>


# Gọi API Refund

API Refund cho phép đối tác thực hiện hoàn tiền cho các giao dịch đã được thanh toán qua mã VietQR.

### <mark style="color:green;">`POST`</mark>

```
https://<vietqr-host>/<basepath>/api/transaction/refund
```

**Headers**

<table><thead><tr><th width="214">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Authorization</td><td><code>Bearer &#x3C;token></code></td></tr></tbody></table>

**Body**

<table data-full-width="false"><thead><tr><th width="200">Name</th><th width="93">Type</th><th width="101">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>bankAccount</code></td><td>String</td><td>Yes</td><td>TK ngân hàng của đối tác.</td></tr><tr><td><code>referenceNumber</code></td><td>String</td><td>Yes</td><td>Mã giao dịch (GD TT đang cần hoàn tiền).</td></tr><tr><td><code>amount</code></td><td>String</td><td>Yes</td><td>Số tiền cần hoàn tiền cho KH của đối tác.</td></tr><tr><td><code>content</code></td><td>String</td><td>Yes</td><td>Nội dung hoàn tiền.</td></tr><tr><td><code>checkSum</code></td><td>String</td><td>Yes</td><td><p>Chuỗi mã hóa MD5 các tham số: (<strong><code>secretKey</code></strong>+<strong><code>referenceNumber</code></strong>+</p><p><strong><code>amount</code></strong> + <strong><code>bankAccount)</code></strong></p></td></tr><tr><td><code>multiTimes</code></td><td>Boolean</td><td>Optional</td><td><p>Cho phép hoàn tiền nhiều lần.</p><p>Chỉ có thể chọn vào lần hoàn tiền đầu tiên.</p></td></tr><tr><td><code>bankCode</code></td><td>String</td><td>Yes</td><td>Tên viết tắt của ngân hàng.</td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng/điểm bán.</td></tr><tr><td><code>subTerminalCode</code></td><td>String</td><td>Optional</td><td>Mã cửa hàng phụ/điểm bán phụ.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "status": "SUCCESS",
    "message": "mã_giao_dịch"
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": "FAILED",
    "message": "mã_lỗi_và_mô_tả_lỗi"
}
```

{% endtab %}
{% endtabs %}

***

### Code mẫu

{% tabs %}
{% tab title="cURL" %}

```
curl --location 'https://api.vietqr.org/vqr/api/transaction/refund' \
--header 'Cookie: JSESSIONID=5CAD2D74C5EBDF9B1CAC5684F2DB47CE; JSESSIONID=C1711954475F66AE09967ADFFA4C80CD; JSESSIONID=F40E5CBDEEB02F82DF40BAD476A6222B' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwidXNlciI6IlkzVnpkRzl0WlhJdGJtZDFlV1Z1TFhWelpYSXlORGt5IiwiaWF0IjoxNzIxMjk3NjAxLCJleHAiOjE3MjEyOTc5MDF9.SEy2kqjhNup2UVaKhldXZQ1bVJn6o69LxgF9r0yA7zBqJWC5n9PhFUYk3G_oBsmCrAbobMohNHzJRsgqbwsUUA' \
--data '{
    "bankCode": "mã_ngân_hàng",
    "bankAccount": "tài_khoản_ngân_hàng_đồng_bộ",
    "referenceNumber": "mã_giao_dịch_đã_thanh_toán_cần_hoàn_tiền",
    "amount": "số_tiền_được_hoàn",
    "content": "nội_dung_hoàn_tiền",
    "multiTimes": "true: cho_phép_hoàn_tiền_nhiều_lần",
    "terminalCode": "mã_điểm_bán",
    "subTerminalCode": "mã_con_điểm_bán",
    "checkSum": "HASH MD5 128 bit: secret_key_do_vietqr_cung_cấp + referenceNumber + amount + bankAccount"
}'

```

{% endtab %}
{% endtabs %}

***

### Các câu hỏi thường gặp

<details>

<summary><strong><code>secretKey</code></strong> tôi phải lấy ở đâu?</summary>

Sau khi bạn tích hợp xong dịch vụ thanh toán qua mã VietQR, hãy liên hệ đến bộ phận kỹ thuật của VietQR để được cấp **`secretKey`**.

</details>

<details>

<summary>API Refund hỗ trợ những loại giao dịch nào?</summary>

API Refund chỉ hỗ trợ hoàn tiền cho các giao dịch đã thanh toán qua mã VietQR và còn hiệu lực.

</details>

<details>

<summary>Làm thế nào để kiểm tra trạng thái hoàn tiền?</summary>

Bạn có thể kiểm tra trạng thái của yêu cầu hoàn tiền bằng cách gọi lại API `Check Transaction` với mã giao dịch hoặc mã đơn hàng.

</details>

<details>

<summary>Có giới hạn về số lần hoàn tiền cho một giao dịch không?</summary>

Tùy thuộc vào chính sách của VietQR và cấu hình của bạn, có thể có giới hạn về số lần hoàn tiền cho một giao dịch cụ thể.

</details>


# Chú ý đối với refund

Chú ý về các giao dịch Refund

Lưu ý:&#x20;

Khi hoàn tiền cho khách hàng thanh toán qua Ví điện tử Momo hoặc ZaloPay, cần thông báo rằng tiền hoàn sẽ không được nhận ngay lập tức. Khách hàng sẽ phải chờ ví điện tử xử lý và chuyển lại tiền.&#x20;

Để quá trình nhanh hơn, khách hàng có thể liên hệ trực tiếp với ví điện tử của mình để yêu cầu ghi có nhanh. Đối với các khoản hoàn qua ngân hàng, ngân hàng đã hoàn tất việc chuyển tiền, chỉ còn chờ ví điện tử trả lại cho khách hàng.


# API Host to Device (MQTTs)

Mô tả quy trình tích hợp bộ dịch vụ thanh toán qua mã VietQR sử dụng giao thức MQTT để truyền thông tin giao dịch đến hệ thống khác .

### Mô tả

<figure><img src="https://content.gitbook.com/content/SRgURCFAGmE4PjobTdbe/blobs/ddwHj1rDKRWrcKNqp5Dr/Process%20Map.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/SRgURCFAGmE4PjobTdbe/blobs/5dmYlHxitGkNjZuOqnnq/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Đối tác cần hoàn tất quá trình đăng ký tài khoản với đầy đủ thông tin nhằm định danh và bảo mật tài khoản. Thông tin tích hợp mặc định sẽ là môi trường Test (Sandbox).
{% endhint %}

**Các bước cơ bản để tích hợp với VietQR:**

1. Liên kết với VietQR.
2. Thiết lập và kết nối với VIetQR MQTTs.
3. Đối tác triển khai trước MQTT nhận Biến Động Số Dư.
4. Đối tác triển khai MQTT yêu cầu tạo mã thanh toán VietQR.
5. Đối tác triển khai MQTT nhận phản hồi thanh toán VietQR.
6. Đối tác triển khai MQTT giả lập thanh toán thành công (Áp dụng bước này đối với môi trường Test).
7. Nghiệm thu và yêu cầu GoLive trên môi trường sản xuất.

***

### Thông số kết nối

| Param          | Type   | Description                                                                         |
| -------------- | ------ | ----------------------------------------------------------------------------------- |
| Broker         | String | Địa chỉ của broker để **publishers** và **subscribers** kết nối                     |
| Username       | String | Tên đăng nhập để xác thực với broker (nếu có).                                      |
| Password       | String | Mật khẩu đăng nhập để xác thực với broker (nếu có).                                 |
| Topic request  | String | Topic để **publishers** gửi yêu cầu.                                                |
| Topic response | String | Topic để **publishers** gửi phản hồi lại cho **subscribers** sau khi xử lý yêu cầu. |

{% hint style="success" %}
**Thông số kết nối sẽ được VietQr cung cấp cho đối tác.**
{% endhint %}

{% hint style="info" %}
**Publishers** : Là các thực thể (thiết bị, ứng dụng) gửi dữ liệu hoặc thông điệp lên một topic cụ thể trên broker. Publishers không cần biết đến các subscribers (người nhận) mà chỉ cần gửi thông điệp lên topic.
{% endhint %}

{% hint style="info" %}
**Subscribers** : Là các thực thể đăng ký nhận thông điệp từ một hoặc nhiều topics trên broker. Khi có một thông điệp mới được gửi lên topic mà họ đã đăng ký, broker sẽ chuyển tiếp thông điệp đó đến subscribers.
{% endhint %}

***


# Liên kết với VietQR

Bước đầu tiên trong quá trình tích hợp dịch vụ VietQR Payment MQTTs

{% hint style="success" %}
Quý khách có thể tham khảo video demo [tại đây](https://doc.vietqr.vn/vietqr-doc#lien-ket-va-quan-ly-tai-khoan).
{% endhint %}

### Đăng ký tài khoản VietQR

{% hint style="info" %}
Nếu quý khách đã có tài khoản VietQR, hẫy đến bước tiếp theo.
{% endhint %}

1. Truy cập trang web [`VietQR.vn`](https://vietqr.vn/register) của chúng tôi để đăng ký tài khoản.
2. Nhập số điện thoại và mật khẩu để tạo một tài khoản mới.
3. Sau khi đăng ký, bạn cần liên kết tài khoản ngân hàng để có thể nhận tiền từ các giao dịch thanh toán qua mã QR.
4. Đăng nhập vào VietQR, nhấn vào nút thêm tài khoản ngân hàng.
5. Chọn ngân hàng MB hoặc BIDV.
6. Nhập các thông tin cần thiết và xác thực để liên kết.

{% hint style="success" %}

* Nếu quý khách chưa có tài khoản tại ngân hàng MB hoặc BIDV, hãy đăng ký ngay  [tại đây](https://omni.bidv.com.vn/static/bidv/share/gioi-thieu-ban-thuong-vo-han.html?data=aH0RHc6MyLk9Cbi5Wa2R2ch1nciRWYr5Wan5nLuZ2LiVlTBRGTS1VbuVVeYZEZo4) để mở tài khoản mới và nhận nhiều ưu đãi hấp dẫn.
* Trong thời gian chờ tài khoản chính thức được kích hoạt, chúng tôi sẽ cung cấp tài khoản ngân hàng thử nghiệm để quý khách có thể tích hợp và trải nghiệm dịch vụ trước.
  {% endhint %}

***

<details>

<summary>Tôi cần làm gì để đăng ký tài khoản VietQR?</summary>

Bạn cần truy cập trang web VietQR.vn, nhập số điện thoại và mật khẩu để tạo tài khoản mới. Sau khi đăng ký thành công, bạn có thể bắt đầu sử dụng các dịch vụ của VietQR.

</details>

<details>

<summary>Tại sao tôi phải liên kết tài khoản ngân hàng với VietQR?</summary>

Việc liên kết tài khoản ngân hàng cho phép bạn nhận tiền từ các giao dịch thanh toán qua mã QR. Tài khoản liên kết sẽ là nơi nhận tiền khi khách hàng thanh toán thông qua mã QR do VietQR cung cấp.

</details>

<details>

<summary>Hiện tại VietQR hỗ trợ liên kết với những ngân hàng nào?</summary>

Hiện tại, VietQR hỗ trợ liên kết với tài khoản ngân hàng tại MB và BIDV. Các ngân hàng khác đang được triển khai và sẽ sớm được hỗ trợ trong thời gian tới.

</details>

<details>

<summary>Tôi chưa có tài khoản tại ngân hàng MB hoặc BIDV, tôi phải làm gì?</summary>

Nếu bạn chưa có tài khoản tại MB hoặc BIDV, bạn có thể đăng ký mở tài khoản mới tại ngân hàng thông qua liên kết trên trang VietQR. Sau khi mở tài khoản, bạn có thể quay lại VietQR để liên kết tài khoản ngân hàng này.

</details>

<details>

<summary>Tôi có thể sử dụng tài khoản ngân hàng thử nghiệm để làm gì?</summary>

Trong thời gian chờ tài khoản chính thức được kích hoạt, VietQR sẽ cung cấp tài khoản ngân hàng thử nghiệm để bạn có thể tích hợp và trải nghiệm các dịch vụ của VietQR trước khi sử dụng tài khoản chính thức.

</details>

<details>

<summary>Liên kết tài khoản ngân hàng có mất phí không?</summary>

Hiện tại, việc liên kết tài khoản ngân hàng với VietQR không mất phí. Ngoài ra, sau khi hoàn thành bước xác thực email, bạn sẽ được tặng key 1 tháng kích hoạt nhận biến động số dư. (\*áp dụng trong khung chương trình khi còn hiệu lực)

</details>


# Thiết lập và kết nối

Hướng dẫn các bước thiết lập và kết nối dịch vụ thanh toán luồng MQTT.

### Bước 1: Cài đặt ứng dụng hỗ trợ MQTT

Bạn cần một ứng dụng hoặc phần mềm hỗ trợ giao thức MQTT để kết nối với hệ thống. Một số ứng dụng phổ biến mà bạn có thể tải về như:

* MQTTBox (cho máy tính)
* MQTT Dashboard (cho điện thoại Android hoặc iOS)

### Bước 2: Nhận thông tin từ VietQR

Sau khi đăng ký sử dụng dịch vụ, bạn sẽ nhận được các thông tin cần thiết từ VietQR, bao gồm:

* Địa chỉ kết nối (Broker): Đây là địa chỉ của hệ thống VietQR mà bạn cần kết nối để thực hiện các giao dịch.
* Tên đăng nhập và mật khẩu: Bạn sẽ dùng thông tin này để đăng nhập vào hệ thống.

{% hint style="success" %}
Nếu bạn chưa có thông tin này, hãy liên hệ với bộ phận hỗ trợ của VietQR.
{% endhint %}

### **Bước 3: Cấu hình kết nối với hệ thống**

Mở ứng dụng MQTT mà bạn đã cài đặt và thực hiện các bước kết nối với hệ thống VietQR bằng cách nhập các thông tin mà VietQR cung cấp như:

* Broker: Địa chỉ máy chủ kết nối VietQR (được cung cấp).
* Username và Password: Thông tin đăng nhập VietQR (được cung cấp).


# MQTT Nhận Biến Động Số Dư

Nhận biến động số dư sau khi thực hiện giao dịch.

### <mark style="color:green;">`MQTT`</mark> Transaction Alerts <a href="#get-token" id="get-token"></a>

```
mqtt://<vietqr-port>/vietqr/bdsd/{terminalCode}
```

**Message**

<table><thead><tr><th width="207">Param</th><th width="131">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>bankAccount</code></td><td>String</td><td>Số tài khoản nhận tiền</td></tr><tr><td><code>amount</code></td><td>Long</td><td>Số tiền nhận</td></tr><tr><td><code>transType</code></td><td>String</td><td>Loại giao dịch</td></tr><tr><td><code>referenceNumber</code></td><td>String</td><td>Mã tham chiếu</td></tr><tr><td><code>orderId</code></td><td>String</td><td>Mã đơn hàng</td></tr><tr><td><code>content</code></td><td>String</td><td>Nội dung chuyển tiền</td></tr><tr><td><code>status</code></td><td>String</td><td>Trạng thái chuyển tiền</td></tr><tr><td><code>timePaid</code></td><td>String</td><td>Thời gian thanh toán</td></tr></tbody></table>

### Code mẫu

{% tabs %}
{% tab title="Message" %}

```
{
  "bankAccount": "9876543210",
  "amount": 25000.0,
  "timePaid": "01/09/2024 14:30:00",
  "transType": "C",
  "referenceNumber": "TXN876543210123",
  "content": "SampleTransaction Payment",
  "status": 1
}
```

{% endtab %}
{% endtabs %}

***


# MQTT Tạo Mã Thanh Toán VietQR

Từ thông tin nhận được, thực hiện tạo mã thanh toán VietQR cho giao dịch.

### <mark style="color:green;">`MQTT`</mark> **Request** Generate VietQR Code <a href="#get-token" id="get-token"></a>

```
mqtt://<vietqr-port>/vietqr/request/{terminalCode}
```

**Message**

<table><thead><tr><th width="209">Param</th><th width="134">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>amount</code></td><td>Long</td><td>Số tiền nhận.</td></tr><tr><td><code>content</code></td><td>String</td><td>Nội dung chuyển tiền.</td></tr><tr><td><code>bankAccount</code></td><td>String</td><td>Số tài khoản nhận tiền.</td></tr><tr><td><code>bankCode</code></td><td>String</td><td>Mã ngân hàng.</td></tr><tr><td><code>userBankName</code></td><td>String</td><td>Tên chủ tài khoản ngân hàng.</td></tr><tr><td><code>transType</code></td><td>String</td><td>Loại giao dịch.</td></tr><tr><td><code>orderId</code></td><td>String</td><td>Mã đơn hàng.</td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Mã điểm bán hoặc mã cửa hàng</td></tr><tr><td><code>serviceCode</code></td><td>String</td><td>Mã sản phẩm.</td></tr><tr><td><code>additionalData</code></td><td>List&#x3C;Object></td><td>Thông tin thêm của đối tác muốn lưu trữ kèm giao dịch.</td></tr></tbody></table>

### Code mẫu

{% tabs %}
{% tab title="Message" %}

```
{
  "amount": 15000,
  "content": "PaymentForOrder",
  "bankAccount": "1234567890",
  "bankCode": "MB",
  "userBankName": "ABC Corporation",
  "transType": "C",
  "orderId": "ORD12345XYZ",
  "terminalCode": "987",
  "serviceCode": "SVC001",
  "additionalData": [
    {
      "info": "AdditionalInfo1"
    }
  ]
}
```

{% endtab %}
{% endtabs %}

***


# MQTT Nhận Mã Thanh Toán VietQR

Gửi phản hồi lại cho MQTT Generate VietQR Code đã tạo và các thông tin liên quan.

### <mark style="color:green;">`MQTT`</mark> **Request** Generate VietQR Code <a href="#get-token" id="get-token"></a>

```
mqtt://<vietqr-port>/vietqr/response/{terminalCode}
```

**Message**

<table><thead><tr><th width="212">Param</th><th width="133">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>bankCode</code></td><td>String</td><td>Mã ngân hàng.</td></tr><tr><td><code>bankName</code></td><td>String</td><td>Tên của ngân hàng</td></tr><tr><td><code>bankAccount</code></td><td>String</td><td>Số tài khoản nhận tiền</td></tr><tr><td><code>userBankName</code></td><td>String</td><td>Tên chủ tài khoản ngân hàng</td></tr><tr><td><code>amount</code></td><td>Long</td><td>Số tiền nhận</td></tr><tr><td><code>content</code></td><td>String</td><td>Nội dung chuyển tiền</td></tr><tr><td><code>qrCode</code></td><td>String</td><td>Mã QR</td></tr><tr><td><code>orderId</code></td><td>String</td><td>Mã đơn hàng</td></tr><tr><td><code>imgId</code></td><td>String</td><td>Hình ảnh qrCode</td></tr><tr><td><code>existing</code></td><td>String</td><td>Có tồn tại trong hệ thống VietQR</td></tr><tr><td><code>transactionId</code></td><td>String</td><td>Id của giao dịch</td></tr><tr><td><code>transactionRefId</code></td><td>String</td><td>Mã tham chiếu giao dịch</td></tr><tr><td><code>qrLink</code></td><td>String</td><td>Đường link hiện qrCode</td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Mã điểm bán hoặc mã cửa hàng</td></tr><tr><td><code>serviceCode</code></td><td>String</td><td>Mã sản phẩm</td></tr><tr><td><code>additionalData</code></td><td>List&#x3C;Object></td><td>Thông tin thêm của đối tác muốn lưu trữ kèm giao dịch</td></tr></tbody></table>

### Code mẫu

{% tabs %}
{% tab title="Message" %}

```
{
  "bankCode": "MB",
  "bankName": "MB Bank",
  "bankAccount": "1234567890",
  "userBankName": "XYZ Ltd",
  "amount": "50000",
  "content": "SampleTransactionDescription",
  "qrCode": "00020101021138540010A00000072701240006970422011012345678900208QRIBFTTA53037045405200005802VN62350831SampleTransactionDescription6304AAB8",
  "imgId": "abcd1234-5678-90ef-ghij-klmn01234567",
  "existing": 1,
  "transactionId": "",
  "transactionRefId": "ABC1234567890XYZ",
  "qrLink": "https://vietqr.vn/test/qr-generated?token=ABC1234567890XYZ",
  "terminalCode": "987",
  "serviceCode": "SVC002",
  "additionalData": [
    {
      "info": "AdditionalInfo1"
    }
  ]
}
```

{% endtab %}
{% endtabs %}

***


# MQTT Giả Lập Thanh Toán

Bước này được áp dụng đối với quá trình kiểm thử trên môi trường TEST. Khách hàng không cần thanh toán thật trong quá trình kiểm thử.

{% hint style="info" %}
Chúng tôi đang bảo trì để cập nhật MQTT này, trong lúc chờ đợi, quý khách hàng và đối tác có thể liên hệ chúng tôi để thao tác bước này nhé.
{% endhint %}


# Nghiệm thu và yêu cầu GoLive

Sau khi hoàn thành việc tích hợp và kiểm tra, bạn hãy yêu cầu nghiệm thu và tiến hành đưa dịch vụ vào hoạt động chính thức (GoLive).


# MQTT Tra Cứu Thông Tin Giao Dịch

Tra cứu thông tin giao dịch

### <mark style="color:green;">`MQTT`</mark> Request Check Transaction <a href="#get-token" id="get-token"></a>

```
mqtt://<vietqr-port>/vietqr/request-status/{terminalCode}
```

**Message**

<table><thead><tr><th width="171">Param</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>bankAccount</code></td><td>String</td><td>Số tài khoản nhận tiền</td></tr><tr><td><code>type</code></td><td>int</td><td>Loại kiểm tra (0: kiểm tra theo OrderId, 1: kiểm tra theo ReferenceNumber).</td></tr><tr><td><code>value</code></td><td>String</td><td>Giá trị cần kiểm tra (OrderId hoặc referenceNumber)</td></tr><tr><td><code>checkSum</code></td><td>String</td><td>Mã kiểm tra bảo mật được tạo từ bankAccount và userBankName.</td></tr></tbody></table>

**Note**&#x20;

{% hint style="success" %}
&#x20;"***checkSum***" sẽ do bên khách hàng cung cấp .

\- Kết hợp bankAccount và userBankName thành một chuỗi duy nhất

\- Mã hóa chuỗi đó bằng thuật toán MD5.

\- Mã MD5 sẽ được sử dụng làm ***checksum***.
{% endhint %}

### Code mẫu

{% tabs %}
{% tab title="Message" %}

```
{
  "bankAccount": "1234567890",
  "type": 0,
  "value": "ORD98765XYZ",
  "checkSum": "abc1234567890def1234567890abcdef"
}
```

{% endtab %}
{% endtabs %}

***


# MQTT Phản Hồi Tra Cứu Thông Tin

Nhận phản hồi sau khi gửi yêu cầu kiểm tra trạng thái giao dịch

### <mark style="color:green;">`MQTT`</mark> Response Check Transaction <a href="#get-token" id="get-token"></a>

```
mqtt://<vietqr-port>/vietqr/response-status/{terminalCode}
```

**Message**

<table><thead><tr><th width="204">Param</th><th width="113">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>referenceNumber</code></td><td>String</td><td>Mã tham chiếu giao dịch</td></tr><tr><td><code>orderId</code></td><td>String</td><td>Mã đơn hàng.</td></tr><tr><td><code>amount</code></td><td>Long</td><td>Số tiền giao dịch</td></tr><tr><td><code>content</code></td><td>String</td><td>Nội dung giao dịch</td></tr><tr><td><code>transType</code></td><td>String</td><td>Số tiền giao dịch</td></tr><tr><td><code>status</code></td><td>int</td><td>Trạng thái giao dịch</td></tr><tr><td><code>type</code></td><td>int</td><td>Loại kiểm tra</td></tr><tr><td><code>timeCreated</code></td><td>Long</td><td>Thời gian tạo giao dịch</td></tr><tr><td><code>timePaid</code></td><td>Long</td><td>Thời gian thanh toán giao dịch</td></tr><tr><td><code>terminalCode</code></td><td>String</td><td>Mã điểm bán hoặc mã cửa hàng</td></tr><tr><td><code>note</code></td><td>String</td><td>Ghi chú</td></tr><tr><td><code>refundCount</code></td><td>int</td><td>Số lần hoàn tiền</td></tr><tr><td><code>amountRefunded</code></td><td>int</td><td>Số tiền đã hoàn lại</td></tr></tbody></table>

**Note**&#x20;

{% hint style="info" %}
**status**:

* 0: Giao dịch đang chờ thanh toán
* 1: Giao dịch thành công
* 2: Giao dịch đã hủy
  {% endhint %}

{% hint style="info" %}
**type**:

* 0: Kiểm tra theo Mã đơn hàng
* 1: Kiểm tra theo Mã tham chiếu giao dịch
  {% endhint %}

{% hint style="info" %}
**transType**:

* "C": Giao dịch đến
* "D": Giao dịch đi
  {% endhint %}

### Code mẫu

{% tabs %}
{% tab title="Message" %}

```
{
  "referenceNumber": "TXN123456789012",
  "orderId": "ORD98765XYZ",
  "amount": 25000,
  "content": "SampleProductPurchase",
  "transType": "C",
  "status": 1,
  "type": 0,
  "timeCreated": 1623039658,
  "timePaid": 1623039685,
  "terminalCode": "",
  "note": "",
  "refundCount": 0,
  "amountRefunded": 0
}
```

{% endtab %}
{% endtabs %}

***


# Các bước đồng bộ MQTT

Các bước đồng bộ MQTT

Bước 1: Đồng bộ thiết bị với tài khoản VietQR -> Đăng kí 2 topic : Topic đăng kí : /vqr/handle-box\
Topic nhận phản hồi : /vqr/handle-box/response/11.78.36.89.21

Bước 2: Sau khi message được phản hồi về topic : /vqr/handle-box/response/11.78.36.89.21 - Ta sử dụng giá trị của filed "boxId" để đăng kí nhận phản hồi từ topic mới : vietqr/boxId/{boxId} để nhận các thông tin từ đồng bộ điểm bán

```
    - Ví dụ: "boxId":"VlZCNDA5MDY4VmlldFFSQm94QWNjZXNzS2V5" Thì topic tương ứng là: vietqr/boxId/VlZCNDA5MDY4VmlldFFSQm94QWNjZXNzS2V5.
```

Bước 3: Sử dụng giá trị của "qrCertificate" được phản hồi từ topic /vqr/handle-box/response/11.78.36.89.21 để quét mã QR từ app VietQR với mục đích đồng bộ điểm bán

Bước 4: Sau khi đồng bộ điểm bán từ app VietQR thì sẽ nhận được phản hồi từ topic vietqr/boxId/{boxId} mà ta đã đăng kí từ bước 2




---

[Next Page](/llms-full.txt/1)

