Hướng dẫn

Tạo Mã QR VietQR Thanh Toán Trong Google Sheets Bằng SePay (2026)

Tuân HoangTuân Hoang
5 tháng 10, 2026
10 phút đọc
Ảnh minh họa bài viết: Tạo Mã QR VietQR Thanh Toán Trong Google Sheets Bằng SePay (2026)

Trả lời nhanh: Cách nhanh nhất là dùng hàm IMAGE gọi API ảnh VietQR miễn phí để chỉ hiện mã QR tĩnh; muốn Sheets tự biết khách đã chuyển tiền thì phải nối thêm SePay qua webhook/Apps Script, hoặc dùng sẵn phần mềm Tạo QR Thanh Toán Ngân Hàng Trực Tiếp Trên Google Sheets (59.000đ, hỗ trợ 20+ ngân hàng, dùng thử 7 ngày).

Giả sử bạn bán hàng online nhỏ, mỗi ngày nhận vài chục đơn qua Zalo và chuyển khoản. Việc đầu tiên khách hỏi luôn là "chuyển khoản vào đâu". Dán số tài khoản bằng tay, gõ sai một số, rồi lại phải xác nhận thủ công bằng cách soi sao kê — quy trình này lặp đi lặp lại mỗi ngày và dễ sót đơn. Mã QR VietQR giải quyết phần nhập liệu, nhưng phần "ai đã chuyển, chuyển bao nhiêu, khớp đơn nào" mới là chỗ tốn thời gian thật.

VietQR trong Google Sheets giải quyết đúng vấn đề gì

VietQR là chuẩn mã QR do Napas và các ngân hàng Việt Nam cùng xây, mã hoá sẵn số tài khoản, tên ngân hàng, số tiền và nội dung chuyển khoản vào một hình ảnh. Khách chỉ cần mở app ngân hàng, quét, kiểm tra số tiền rồi xác nhận — không phải gõ tay số tài khoản 15-16 số.

Trong Google Sheets, bài toán tách làm hai lớp rõ ràng. Lớp một là hiển thị: Sheets chỉ cần gọi một API ảnh công khai, dán số tài khoản và số tiền vào, ra một ảnh QR. Lớp hai là xác nhận: biết khách đã chuyển hay chưa, số tiền có khớp không. Lớp một làm bằng công thức thuần, không cần tài khoản gì cả. Lớp hai thì bắt buộc phải có một bên trung gian đọc được biến động số dư ngân hàng theo thời gian thực — đó là chỗ SePay vào cuộc, vì Sheets không tự kết nối trực tiếp với ngân hàng được.

Hai cách tạo mã QR, chọn cách nào

Trước khi đi vào chi tiết, nên biết mình đang cần gì: chỉ cần in QR để dán ở quầy/gửi khách thì công thức thủ công là đủ. Cần Sheets tự động đánh dấu "đã thanh toán" khi tiền về thì phải có webhook SePay.

Tiêu chíCông thức IMAGE + API ảnhSePay (webhook)
Chi phíMiễn phíTheo gói dịch vụ SePay, ngoài phạm vi Sheets
Thời gian dựng5-10 phútCần Apps Script + cấu hình webhook, vài giờ nếu chưa quen
Tự xác nhận giao dịchKhông, chỉ hiện ảnhCó, ghi log vào sheet khi tiền về
Phụ thuộcAPI ảnh bên thứ baTài khoản ngân hàng đã đăng ký với SePay
Phù hợpIn QR tĩnh, gửi khách lẻBán hàng liên tục, cần đối soát tự động

Phần lớn người mới nên bắt đầu từ công thức thủ công để hiểu cấu trúc dữ liệu QR, rồi mới quyết có cần nối SePay hay không. Nếu mục tiêu cuối là tự động hoá hoàn toàn, có thể nhảy thẳng xuống phần SePay — nhưng vẫn cần hiểu cột nào chứa gì vì webhook sẽ ghi dữ liệu về đúng các cột đó.

Dựng QR VietQR bằng công thức, không cần đăng ký gì

Cách này dùng hàm IMAGE() của Sheets gọi tới một dịch vụ ảnh QR công khai theo chuẩn VietQR. Giả sử sheet "QR" có các cột: B là mã ngân hàng viết tắt (ví dụ MB, VCB, TCB), C là số tài khoản, D là số tiền, E là nội dung chuyển khoản.

Ở ô F2, dán công thức:

=IMAGE("https://img.vietqr.io/image/"&B2&"-"&C2&"-compact2.png?amount="&D2&"&addInfo="&ENCODEURL(E2))

Trong đó B2 ghép với C2 tạo thành đường dẫn ngân hàng-số tài khoản mà dịch vụ ảnh hiểu được, D2 là số tiền (để trống nếu không cố định), E2 là nội dung — nên bọc ENCODEURL() để tránh lỗi khi nội dung có dấu tiếng Việt hoặc khoảng trắng. Kéo công thức xuống các dòng dưới, mỗi dòng đơn hàng sẽ ra một mã QR riêng với đúng số tiền của đơn đó.

Muốn làm nhanh hơn, bạn có thể tham khảo cách dựng QR bằng công thức thuần không gọi API ngoài trong bài Tạo Mã QR Code Tự Động Trong Google Sheets Bằng Công Thức — áp dụng được cho các loại QR khác ngoài thanh toán, ví dụ QR dẫn link, QR mã sản phẩm.

Hạn chế của cách này: ảnh QR chỉ là hình tĩnh, Sheets không biết khách đã quét và chuyển tiền thật hay chưa. Bạn vẫn phải tự vào app ngân hàng kiểm tra sao kê, đối chiếu bằng tay với cột nội dung chuyển khoản.

Nối SePay để Sheets tự biết tiền đã về

SePay hoạt động như một lớp trung gian: nó theo dõi biến động tài khoản ngân hàng của bạn theo thời gian thực, rồi gửi dữ liệu giao dịch (số tiền, nội dung, thời điểm) tới một địa chỉ webhook mà bạn chỉ định. Với Google Sheets, địa chỉ đó thường là một Web App được deploy từ Apps Script.

Luồng dựng cơ bản gồm các bước sau:

  • Đăng ký tài khoản SePay và liên kết với tài khoản ngân hàng bạn dùng để nhận tiền.
  • Trong Apps Script của file Sheets, tạo một hàm doPost(e) nhận dữ liệu POST mà SePay gửi tới, parse JSON lấy số tiền và nội dung chuyển khoản.
  • Deploy Apps Script dưới dạng Web App, lấy URL, dán vào mục webhook trong trang quản trị SePay.
  • Trong hàm doPost, so khớp nội dung chuyển khoản với cột mã đơn hàng trong sheet (ví dụ dùng MATCH() hoặc regex lấy mã đơn từ nội dung), rồi ghi "Đã thanh toán" và thời điểm vào đúng dòng đơn hàng đó.
  • Thêm bước gửi thông báo, ví dụ Telegram hoặc email, để biết ngay khi có giao dịch khớp.

Phần khó nhất thực tế không nằm ở việc nhận webhook, mà ở bước so khớp nội dung chuyển khoản với đúng đơn hàng — vì khách hay xoá bớt chữ trong nội dung, hoặc gõ thiếu dấu cách. Nên thiết kế mã đơn hàng ngắn, không dấu, dễ nhận diện bằng regex (ví dụ DH1023 thay vì "Đơn hàng số 1023 của chị Lan"), và luôn có một cột riêng để đối soát thủ công các giao dịch không khớp tự động.

Nếu bạn cần quản lý luôn cả menu điều khiển cho người dùng không biết Apps Script là gì — ví dụ nút "Đồng bộ lại giao dịch", "Gửi lại QR" — cách dựng menu tuỳ chỉnh trong Cách Tạo Menu Tùy Chỉnh Trong Google Sheets Bằng Apps Script áp dụng trực tiếp được vào sheet QR này.

Đối soát và báo cáo doanh thu từ dữ liệu QR đã khớp

Sau khi webhook ghi được dữ liệu giao dịch về sheet, phần còn lại là tổng hợp. Giả sử sheet "GiaoDich" có cột A là thời gian, cột B là số tiền, cột C là nội dung, cột D là trạng thái khớp đơn ("Khớp"/"Chưa khớp").

Để lấy tổng doanh thu đã khớp trong ngày, dùng:

=QUERY(GiaoDich!A2:D, "select sum(B) where D = 'Khớp' and A >= date '"&TEXT(TODAY(),"yyyy-mm-dd")&"'", 0)

Câu lệnh này cộng toàn bộ cột B (số tiền) của các dòng có trạng thái "Khớp" và thời gian từ đầu ngày hôm nay. Muốn xem danh sách giao dịch chưa khớp để xử lý tay, đổi điều kiện thành where D = 'Chưa khớp' và bỏ sum, chọn luôn cột A, B, C để hiện chi tiết.

QUERY xử lý được phần lớn nhu cầu báo cáo theo ngày/tuần/tháng mà không cần PivotTable riêng, miễn dữ liệu nguồn sạch — nếu cột thời gian hoặc số tiền bị lưu dưới dạng text thay vì number/date thì QUERY sẽ trả về rỗng mà không báo lỗi rõ ràng, đây là lỗi hay gặp nhất khi mới ghép webhook vào Sheets. Nếu bạn cần khai thác QUERY sâu hơn cho các báo cáo phức tạp hơn — nhóm theo ngân hàng, theo khung giờ, theo nhân viên nhận đơn — tham khảo thêm Hàm QUERY Trong Google Sheets: Hướng Dẫn Toàn Diện Với 30+ Ví Dụ.

Những lỗi hay gặp khi tự dựng QR VietQR trong Sheets

Ảnh QR không hiện, chỉ thấy ô trống hoặc dấu !, thường vì mã ngân hàng viết sai (API phân biệt chữ hoa/thường hoặc yêu cầu đúng mã BIN ngân hàng, không phải tên viết tắt tuỳ ý) hoặc số tài khoản dính khoảng trắng do copy từ nơi khác. Nên dùng TRIM() bọc quanh C2 trước khi ghép vào URL.

Nội dung chuyển khoản có dấu tiếng Việt làm QR tạo được nhưng app ngân hàng hiển thị sai hoặc từ chối quét, do ký tự có dấu không mã hoá đúng chuẩn URL — ENCODEURL() xử lý được phần lớn trường hợp này, nhưng an toàn nhất vẫn là đặt nội dung chuyển khoản không dấu, không ký tự đặc biệt.

Webhook SePay gọi tới nhưng Sheets không ghi được dữ liệu, phổ biến nhất là do Web App chưa được deploy với quyền "Anyone" (ai cũng gọi được), hoặc bạn deploy phiên bản mới của Apps Script nhưng quên cập nhật URL mới trong SePay — mỗi lần deploy lại tạo một phiên bản, URL có thể đổi nếu chọn sai kiểu deploy.

Một lỗi khác không liên quan QR nhưng hay gặp khi thao tác nhiều trên sheet giao dịch: chèn hoặc xoá dòng ở vùng đã có công thức mảng/merge cell dễ dính lỗi cấu trúc bảng. Nếu gặp thông báo lỗi dạng này, bài Lỗi "Không Thể Chèn/Xóa Ô Trên Một Phần Bảng" Trong Google Sheets giải thích nguyên nhân và cách gỡ.

Khi nào nên dùng sẵn thay vì tự ghép từng phần

Tự dựng bằng công thức và Apps Script phù hợp khi bạn muốn hiểu rõ từng lớp, hoặc nhu cầu đơn giản chỉ cần vài chục QR một ngày. Nhưng khi số lượng giao dịch tăng, việc viết và bảo trì logic so khớp nội dung chuyển khoản, xử lý webhook lỗi, hỗ trợ nhiều ngân hàng khác nhau cho từng khách — bắt đầu tốn thời gian hơn giá trị nó mang lại.

Tạo QR Thanh Toán Ngân Hàng Trực Tiếp Trên Google Sheets đóng gói sẵn phần này: tạo mã QR chuẩn VietQR/Napas cho hơn 20 ngân hàng, xác nhận giao dịch tự động qua SePay, chạy thẳng trên Google Sheets mà không cần hosting hay viết lại Apps Script từ đầu. Giá 59.000đ trả một lần, có 7 ngày dùng thử trước khi quyết định mua.

Nếu bạn chỉ đang thử nghiệm mô hình bán hàng nhỏ và chưa chắc cần tự động hoá đến mức nào, cứ bắt đầu bằng công thức IMAGE thủ công ở phần trên — nó đủ cho vài chục đơn mỗi ngày và không ràng buộc gì cả. Khi khối lượng giao dịch vượt quá khả năng đối soát bằng tay, đó là lúc nên nhảy qua webhook hoặc phần mềm có sẵn.

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

Chỉ cần in mã QR tĩnh dán ở quầy thì dùng cách nào?

Dùng công thức IMAGE() gọi API ảnh VietQR miễn phí, dựng trong 5-10 phút, không cần đăng ký tài khoản gì. Ghép mã ngân hàng, số tài khoản, số tiền và nội dung chuyển khoản vào URL ảnh. Hạn chế là ảnh chỉ tĩnh, Sheets không biết khách đã chuyển tiền hay chưa, vẫn phải tự kiểm tra sao kê bằng tay.

Vì sao Google Sheets không tự biết khách đã chuyển khoản?

Vì Sheets không kết nối trực tiếp được với ngân hàng để đọc biến động số dư. Phải nối thêm SePay làm lớp trung gian, theo dõi tài khoản ngân hàng theo thời gian thực rồi gửi dữ liệu giao dịch qua webhook tới một Web App deploy từ Apps Script, ghi kết quả khớp đơn vào sheet.

Tại sao ảnh mã QR không hiện ra, chỉ thấy ô trống hoặc dấu !?

Thường do mã ngân hàng viết sai (API phân biệt hoa/thường, cần đúng mã BIN chứ không phải tên viết tắt tuỳ ý) hoặc số tài khoản dính khoảng trắng khi copy từ nơi khác. Nên dùng TRIM() bọc quanh ô chứa số tài khoản trước khi ghép vào URL ảnh.

Phần nào khó nhất khi tự dựng webhook SePay nối với Sheets?

Khó nhất là so khớp nội dung chuyển khoản với đúng đơn hàng, vì khách hay xoá bớt chữ hoặc gõ thiếu dấu cách trong nội dung. Nên đặt mã đơn hàng ngắn, không dấu, dễ nhận diện bằng regex (ví dụ DH1023), và luôn có cột riêng để đối soát thủ công các giao dịch không khớp tự động.

Bạn muốn áp dụng ngay mà không phải tự xây từ đầu?

Khám phá các mẫu Google Sheets và phần mềm quản lý dựng sẵn cho doanh nghiệp Việt tại SheetStore Marketplace.

Chia sẻ bài viết:

Tuân Hoang

Tuân Hoang

Đội ngũ SheetStore

Google SheetsGoogle Apps ScriptCRMAutomationPhần mềm quản lý doanh nghiệp

Google Workspace Certified, 5+ years experience

Bạn thấy bài viết hữu ích?

Đăng ký nhận thông báo khi có bài viết mới.

Nhận thông báo khi có bài viết mới. Không spam, hứa luôn! 😊

Bình luận (0)

Vui lòng đăng nhập để tham gia thảo luận