MODULE 4

THANH TOÁN QR CHO KHÁCH


Trang của cô Lan giờ có đủ 9 section, chạy mượt, không lỗi. Nhưng khách bấm "Đăng ký ngay" thì tới đâu? Module này lấp đúng khối <div id="thanh-toan"></div> còn để trống từ Module 3 — bằng một form thu thông tin và một mã QR chuyển khoản thật, không cần cổng thanh toán, không cần backend, không cần biết lập trình.


Bước 4.1

Vì sao cần mã đơn riêng cho từng khách

Xong bước này bạn có: Hiểu vì sao không thể chỉ dán một cái STK trần trên trang, và mã đơn giải quyết đúng vấn đề gì.


Vấn đề không phải là nhận tiền — là biết ai đã trả

Dán số tài khoản trần lên trang, khách chuyển khoản được, tiền vào tài khoản thật. Vấn đề lộ ra ngay sau đó: sao kê ngân hàng chỉ hiện "chuyển khoản 2.900.000đ, không nội dung" hoặc nội dung khách tự gõ tuỳ ý — bạn không biết đây là ai, đăng ký khoá nào, đã liên hệ xác nhận chưa.

Mã đơn giải quyết đúng việc này: mỗi khách bấm "Tạo mã QR" sẽ nhận một mã riêng (ví dụ DH412922), mã này tự động điền vào nội dung chuyển khoản của QR. Mở sao kê, bạn thấy đúng mã, đối chiếu ra đúng người.

Vì sao không cần cổng thanh toán (Casso, cổng ngân hàng, ví điện tử...)

Với vài chục đơn/tháng — đúng quy mô một khoá học của giáo viên/chuyên gia cá nhân — việc tự đối chiếu sao kê bằng mã đơn mất vài phút mỗi ngày. Cổng thanh toán tự động đáng cân nhắc khi số đơn lên tới hàng trăm/tháng, không phải điểm khởi đầu.




Bước 4.2

Prompt: chèn khối thanh toán vào file đã có

Xong bước này bạn có: Khối thanh toán QR đã nằm trong đúng file index.html từ Module 3 — chưa cần deploy để thấy nó chạy.


📋 PROMPT — Chèn khối thanh toán QR

Đây là file index.html hiện tại của tôi (dán toàn bộ nội dung file):
[DÁN TOÀN BỘ index.html TỪ MODULE 3]

Tôi cần thay khối <div id="thanh-toan"></div> đang để trống bằng một khối
thanh toán hoàn chỉnh, gồm:

1. Một form thu 2 trường: Họ tên, Số điện thoại. Có nút "Tạo mã QR thanh toán".
2. Khi bấm nút, JavaScript thuần (không cần thư viện ngoài) tự sinh 1 mã đơn
   dạng "DH" + 6 số cuối của Date.now(), rồi dựng URL ảnh QR theo định dạng:
   https://img.vietqr.io/image/{bankId}-{accountNo}-compact2.png?amount={price}&addInfo={maDon}&accountName={accountName}
   Đặt 5 giá trị bankId, accountNo, accountName, price, zaloPhone thành một
   object CONFIG ở đầu đoạn script, có ghi chú rõ để tôi tự sửa.
3. Sau khi tạo mã, ẩn form đi, hiện: mã đơn, ảnh QR, số tài khoản/tên/ngân
   hàng để gõ tay dự phòng, và số tiền.
4. Một nút "Tôi đã chuyển khoản — báo qua Zalo": copy vào clipboard 1 đoạn
   tin nhắn dựng sẵn (có tên, SĐT, số tiền, mã đơn khách vừa nhập/tạo), rồi
   mở tab mới tới https://zalo.me/{zaloPhone}.
5. Toàn bộ khối này phải dùng đúng màu/font đã có trong file (không tự chọn
   màu mới nằm ngoài hệ thống thiết kế hiện tại của trang).
6. Không cần backend, không cần lưu dữ liệu ở đâu ngoài trình duyệt của
   khách — mọi thứ chạy bằng JavaScript thuần ngay trong file.

Trả lại toàn bộ file index.html đã cập nhật.

Prompt này không cần DESIGN.md mới — nó đọc màu/font đã có sẵn trong chính file HTML bạn đưa, nên khối thanh toán tự động khớp phong cách khung bạn đã chọn.


✅ Kết quả thật — đã bấm thử, ảnh QR thật đã hiện ra

Sau khi chạy prompt trên với file thật của cô Lan, điền thử "Nguyễn Thị Test" — "0912345678" vào form và bấm "Tạo mã QR thanh toán":

  • Mã đơn sinh ra: DH412922
  • Ảnh QR tải thành công từ img.vietqr.io — hiện đúng logo VietQR, Napas 247, tên ngân hàng, tên chủ tài khoản TRAN THI LAN, số tài khoản, và số tiền 2.900.000 VND in ngay trên ảnh QR (đây là ảnh do chính VietQR generate, không phải ảnh tĩnh)
  • URL ảnh thật: https://img.vietqr.io/image/VCB-1903123456789-compact2.png?amount=2900000&addInfo=DH412922&accountName=TRAN%20THI%20LAN

Đây là mã QR quét được thật bằng app ngân hàng bất kỳ hỗ trợ VietQR — không phải ảnh minh hoạ.


⚠️ Ba lỗi hay gặp

Quên sửa CONFIG, để nguyên số tài khoản mẫu. Khách quét QR chuyển tiền vào đúng tài khoản trong CONFIG — nếu chưa sửa thành thông tin thật của bạn, tiền không về đúng chỗ. Luôn kiểm tra 5 dòng CONFIG trước khi đưa trang cho ai xem.

Gõ sai mã ngân hàng (bankId). VietQR cần đúng mã viết tắt chuẩn (VCB, ACB, MB, TCB...). Tra đúng mã tại danh sách ngân hàng hỗ trợ VietQR trước khi điền — gõ sai, ảnh QR không tải được hoặc tải sai ngân hàng.

Để accountName có dấu tiếng Việt. Ngân hàng hiển thị tên chủ tài khoản không dấu, in hoa. Nếu điền có dấu, QR vẫn tạo được nhưng tên hiện sai/lỗi font khi khách quét.




Bước 4.3

Sửa 5 dòng CONFIG bằng thông tin thật của bạn

Xong bước này bạn có: Khối thanh toán trỏ đúng về tài khoản của bạn, không phải tài khoản demo.


Năm dòng phải sửa, không dòng nào được bỏ qua

Dòng Là gì Ví dụ
bankId Mã viết tắt ngân hàng theo chuẩn VietQR "VCB", "ACB", "MB", "TCB"
accountNo Số tài khoản nhận tiền "0071234567890"
accountName Tên chủ tài khoản, KHÔNG DẤU, in hoa "NGUYEN THI LAN"
price Giá đúng bằng số trong Brief Offer, không dấu chấm/phẩy 2900000
zaloPhone Số điện thoại Zalo nhận tin xác nhận "0905xxxxxx"

📋 PROMPT — Nhờ AI tự rà lại CONFIG

Nếu không chắc mình sửa đúng chỗ, dán đoạn này kèm file:

Đây là file index.html của tôi (dán toàn bộ):
[DÁN FILE]

Tìm đúng object CONFIG trong khối thanh toán. Liệt kê rõ 5 giá trị hiện tại
của bankId, accountNo, accountName, price, zaloPhone để tôi đối chiếu xem đã
sửa đúng thành thông tin thật của tôi chưa — đừng tự sửa, chỉ liệt kê ra.

⚠️ Ba lỗi hay gặp

Sửa price khác với giá đã viết trong section GIÁ ở Module 2. Khách đọc thấy 2.900.000đ nhưng QR lại ra số khác — mất niềm tin ngay tại bước cuối cùng.

Dùng zaloPhone là số bàn/số tổng đài ít check. Chọn số bạn thực sự mở Zalo mỗi ngày — đây là kênh duy nhất bạn biết ai vừa chuyển khoản.

Test xong quên đổi lại thông tin demo khi làm cho khoá học thật tiếp theo. Nếu dùng lại file này làm mẫu cho một khoá khác, kiểm tra lại cả 5 dòng, không riêng giá.




Bước 4.4

Test luồng thật trước khi đưa cho ai xem

Xong bước này bạn có: Bằng chứng luồng thanh toán chạy đúng từ đầu đến cuối, trên chính máy/điện thoại của bạn.


Tự đóng vai khách hàng, làm đúng 4 bước

  1. Mở file index.html bằng trình duyệt (hoặc link demo nếu đã deploy).
  2. Cuộn xuống khối thanh toán, điền tên/SĐT thật của chính bạn, bấm "Tạo mã QR thanh toán".
  3. Nhìn kỹ ảnh QR vừa hiện: có đúng ngân hàng, đúng tên, đúng số tiền không? Mở app ngân hàng trên điện thoại, thử quét — không cần chuyển khoản thật, chỉ cần app đọc được QR và hiện đúng thông tin người nhận.
  4. Bấm nút "Tôi đã chuyển khoản" — kiểm tra Zalo có mở lên không, dán thử (Ctrl+V) xem tin nhắn đã copy có đúng và đủ ý không.

Về nút xác nhận và giới hạn cần biết trước

Nút "Tôi đã chuyển khoản" copy tin nhắn vào clipboard rồi mở Zalo — nó không tự động phát hiện bạn đã chuyển khoản thật hay chưa. Đây là do chủ đích, không phải thiếu sót: trang không có backend, nghĩa là không có gì để tự động đối chiếu ngân hàng. Việc xác nhận cuối cùng luôn là bạn tự nhìn sao kê và mã đơn khách gửi qua Zalo.

Trên một số trình duyệt hoặc khi mở file trực tiếp từ máy (chưa deploy lên HTTPS), lệnh copy vào clipboard có thể bị chặn vì lý do bảo mật. Sau khi deploy lên Cloudflare Pages (Module 5), trang chạy trên HTTPS thật, tính năng này hoạt động ổn định trên Chrome/Safari — nút mở Zalo vẫn chạy được ngay cả nếu riêng phần copy bị chặn, khách chỉ cần tự gõ lại tin nhắn.


⚠️ Ba lỗi hay gặp

Chỉ test bằng mắt, không thử quét QR bằng app ngân hàng thật. Ảnh hiện ra không có nghĩa app ngân hàng đọc được — quét thử một lần trước khi công bố trang.

Quên test trên điện thoại, chỉ test trên máy tính. Khách hàng thật sẽ quét QR ngay trên điện thoại đang đọc trang — trải nghiệm khác hẳn máy tính.

Nghĩ trang chưa deploy thì không cần test. Test ngay từ khi còn là file trên máy — lỗi cấu hình QR phát hiện càng sớm càng đỡ mất công sửa sau khi đã deploy.




Bước 4.5

🔒 Trước khi sang Module 5

Tự kiểm bốn câu:

  • Đã sửa cả 5 dòng CONFIG thành thông tin thật của bạn chưa, không còn số demo?
  • Đã quét thử QR bằng app ngân hàng thật ít nhất 1 lần chưa?
  • Nút "Tôi đã chuyển khoản" có mở đúng Zalo của bạn, không phải số demo?
  • Giá hiện trên QR có khớp 100% với giá đã viết ở section GIÁ (Module 2) chưa?

Nếu có ô chưa tick, quay lại bước 4.3. Module 5 chỉ đưa nguyên file này lên internet — không sửa gì thêm, nên sai ở đây sẽ đi thẳng lên trang thật.