[Vibe Coding Thực Chiến #12] Mở Rộng Hệ Sinh Thái: Tích Hợp Cổng Thanh Toán VietQR / VNPay Sandbox & Đăng Nhập 1 Chạm Google OAuth!
Tác giả: Lee
Series: Vibe Coding Thực Chiến Cùng EzyPlatform (#12)
Hạ tầng thực nghiệm: VPS Ubuntu 22.04 LTS (157.66.47.xxx) | Domain Admin:https://1576647xxx-admin.interdata.io.vn
Bộ công cụ: VS Code + Extensionyoungmonkeys.ezyarticle+ Claude Code CLI / Codex + Google OAuth + VietQR / VNPay Gateway
Ở bài viết số #11, chúng ta đã đưa website tiệm bánh Le Petit Bakery "ra biển lớn": trỏ tên miền chính chủ lepetitbakery.vn, kích hoạt ổ khóa xanh HTTPS miễn phí qua EzySupport và đồng bộ phiên làm việc bằng cơ chế Token Sharing.
Thế nhưng, khi website chính thức mở cửa đón khách mua hàng, bạn sẽ lập tức đối mặt với một "thước đo tàn nhẫn" trong thương mại điện tử: Tỷ Lệ Bỏ Rơi Giỏ Hàng (Cart Abandonment Rate).
Theo thống kê của Baymard Institute, có tới gần 70% khách hàng rời bỏ website ngay tại bước thanh toán chỉ vì 2 lý do:
- Bắt đăng ký tài khoản rườm rà: Điền email, họ tên, tạo mật khẩu 8 ký tự kèm chữ hoa, ký tự đặc biệt rồi chờ email kích hoạt.
- Phương thức thanh toán bất tiện: Đưa số tài khoản ngân hàng bắt khách tự mở app, tự gõ từng con số tài khoản và tự copy mã đơn vào nội dung chuyển khoản. Chỉ cần gõ sai 1 số là tiền đi đằng tiền, đơn đi đằng đơn!
Trong bài viết số #12 này, mình sẽ cùng bạn giải quyết triệt để 2 "nút thắt cổ chai" này bằng bộ đôi giải pháp: Đăng nhập 1 chạm Google OAuth 2.0 (EzyLogin) và Thanh toán quét mã VietQR động / Cổng VNPay Sandbox (EzyPayment) — Khách chạm là đăng nhập, quét là thanh toán, đơn tự nhảy trạng thái PAID trong 1.5 giây!
1. Kiến trúc Thanh Toán VietQR Động & Tự Động Đối Soát Giao Dịch
Khác với mã QR tĩnh (chỉ chứa số tài khoản cố định), VietQR Động (Dynamic VietQR) theo chuẩn quốc tế EMVCo chứa toàn bộ thông tin thanh toán của riêng đơn hàng đó:
- Mã ngân hàng (BIN Code): Ví dụ
970422(MB Bank). - Số tài khoản người thụ hưởng:
0901234xxx. - Số tiền chính xác đến từng đồng: Khóa cứng
185.000 ₫, khách không thể tự sửa. - Cú pháp nội dung chuyển khoản độc nhất:
#ORD-2026-LIVE-9041.
Luồng 4 bước: Sinh mã VietQR động ➔ Khách quét trên App Bank ➔ Ngân hàng bắn Webhook IPN về VPS ➔ Đơn hàng tự cập nhật PAID sau 1.5s.
Khách hàng chỉ cần giơ điện thoại quét mã bằng bất kỳ App ngân hàng nào (Vietcombank, MB, Techcombank, VPBank, MoMo...), toàn bộ thông tin lập tức tự điền chuẩn 100%. Tiền vừa về tài khoản chủ shop, Webhook ngân hàng bắn tín hiệu IPN về VPS 157.66.47.xxx và màn hình web tự động nhảy sang "Thanh toán thành công" mà khách không cần bấm F5!
2. Xác Thực Một Chạm: Luồng Google OAuth 2.0 Qua EzyLogin
Thay vì bắt người dùng nhớ thêm một mật khẩu mới, chúng ta tích hợp luồng Google One-Tap Login:
Luồng OAuth 2.0: Khách chọn tài khoản Google ➔ Google cấp JWT ID Token ➔ EzyLogin map tài khoản và cấp JWT Token Sharing.
- Tầng Client: Thư viện Google Identity Services (GIS) hiển thị popup đăng nhập nổi nhẹ nhàng ở góc phải màn hình.
- Tầng Backend VPS: Plugin
EzyLoginnhận ID Token, verify với Google Authorization Server, tự động tạo tài khoản khách hàng nếu chưa có và gắn Token Sharing Cookie vào domain.lepetitbakery.vn.
3. Thực chiến 4 bước: Tích hợp Thanh toán & Đăng nhập cho Tiệm Bánh
Bây giờ, hãy mở VS Code và bắt tay vào việc nhé!
Bước 1: Nhúng Google One-Tap Login vào Header
Trong file pages/bakery-shop/head.html, chúng ta nhúng Google Identity SDK:
<!-- Nhúng Google Identity Services -->
<script src="https://accounts.google.com/gsi/client" async defer></script>
Trong file pages/bakery-shop/foot.html, khởi tạo Google Prompt:
window.onload = function () {
google.accounts.id.initialize({
client_id: "YOUR_GOOGLE_CLIENT_ID.apps.googleusercontent.com",
callback: handleGoogleCredentialResponse
});
// Hiển thị popup Google One-Tap
google.accounts.id.prompt();
};
async function handleGoogleCredentialResponse(response) {
const credential = response.credential; // JWT ID Token
const res = await fetch('https://1576647xxx-admin.interdata.io.vn/api/v1/auth/google', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: credential })
});
const data = await res.json();
if (data.accessToken) {
location.reload(); // Đăng nhập thành công!
}
}
Và đây là giao diện thực tế khi khách vừa mở trang web:
Popup Google One-Tap nổi bật ở góc phải màn hình giúp khách đăng nhập chỉ với một nút bấm duy nhất.
Bước 2: Sinh mã VietQR động theo chuẩn EMVCo
Để sinh mã VietQR mà không cần cài đặt thư viện nặng nề, chúng ta sử dụng chuẩn API VietQR công khai:
// Hàm sinh link ảnh VietQR động
function generateVietQRUrl({ bankId, accountNo, amount, orderCode, accountName }) {
const encodedName = encodeURIComponent(accountName);
const encodedDesc = encodeURIComponent(orderCode);
return `https://img.vietqr.io/image/${bankId}-${accountNo}-compact2.png?amount=${amount}&addInfo=${encodedDesc}&accountName=${encodedName}`;
}
Khi khách bấm "Đặt Hàng & Thanh Toán VietQR", modal hiển thị sắc nét:
Modal hiển thị mã QR kèm số tiền 185.000 ₫ và nội dung chuyển khoản ORD9041.
Kèm theo đó là một hàm Polling siêu nhẹ kiểm tra trạng thái đơn mỗi 2 giây:
const pollInterval = setInterval(async () => {
const status = await checkOrderStatus(orderCode);
if (status === 'PAID') {
clearInterval(pollInterval);
showSuccessModal();
}
}, 2000);
Bước 3: Tích hợp Cổng thanh toán VNPay Sandbox
Nếu khách hàng muốn thanh toán bằng thẻ ATM nội địa hoặc thẻ Quốc tế (Visa / Mastercard), chúng ta tích hợp cổng VNPay Sandbox:
Giao diện xác nhận thanh toán VNPay Sandbox trả về mã phản hồi 00 hợp lệ.
Bước 4: Bảo mật giao dịch với HMAC-SHA512 Checksum
Khi làm việc với cổng thanh toán, an toàn dữ liệu là vấn đề sống còn. Sẽ ra sao nếu kẻ gian bấm "F12" sửa số tiền từ 185000 thành 1000 rồi mới gửi sang VNPay?
Để ngăn chặn tuyệt đối trò gian lận này, toàn bộ URL thanh toán bắt buộc phải được băm (hash) bằng khóa bí mật (vnp_HashSecret) tại Backend máy chủ VPS 157.66.47.xxx:
Hệ thống phát hiện sai lệch chữ ký số ngay lập tức nếu kẻ gian cố tình sửa đổi tham số giá tiền.
4. 3 bẫy lỗi kinh điển khi tích hợp thanh toán & Cách né 😡
Bẫy lỗi #1: Lộ vnp_HashSecret trong mã nguồn JavaScript Frontend 😣
- Hiện tượng: Viết thuật toán tạo URL thanh toán VNPay ngay trong file
foot.htmltrên trình duyệt. - Hậu quả: Bất kỳ ai cũng có thể đọc được chuỗi Secret Key của bạn và tự tạo các giao dịch giả mạo hợp lệ!
- Cách né (Recommend 👍): Tuyệt đối chỉ sinh chữ ký số HMAC tại tầng Backend VPS (thông qua API EzyPayment hoặc MCP Tool).
Bẫy lỗi #2: Khách quét QR xong màn hình vẫn đứng im (Thiếu Polling / SSE) 😡
- Hiện tượng: Khách đã chuyển tiền, tài khoản đã trừ, nhưng màn hình máy tính vẫn đứng im ở mã QR. Khách hoang mang tưởng mất tiền!
- Cách né (Bí kíp 💡): Luôn thiết lập vòng lặp Polling (mỗi 2s) hoặc kết nối SSE / WebSocket để đón sự kiện
payment:confirmedtừ VPS.
Bẫy lỗi #3: Lệch số tiền do đơn vị nhân 100 trong VNPay (VND x 100) ⚠️
- Hiện tượng: Khách mua bánh 185.000 ₫ nhưng khi chuyển sang VNPay cổng lại bắt thanh toán 1.850 ₫!
- Nguyên nhân: VNPay quy định số tiền gửi lên phải nhân với 100 (
vnp_Amount = amount * 100). - Cách né (Lưu ý ⚠️): Luôn kiểm tra kỹ tài liệu tích hợp: Với đơn hàng 185.000 VND, giá trị
vnp_Amountgửi đi bắt buộc phải là18500000.
5. Cheatsheet & Code Mẫu VietQR Generator Chuẩn EMVCo 📋
// Module VietQR siêu nhẹ không cần thư viện ngoài
const VietQRHelper = {
createPaymentLink({ bankBin, accountNo, amount, orderCode, accountName }) {
const cleanOrderCode = orderCode.replace(/[^a-zA-Z0-9]/g, '');
const encodedName = encodeURIComponent(accountName);
return `https://img.vietqr.io/image/${bankBin}-${accountNo}-compact2.png?amount=${amount}&addInfo=${cleanOrderCode}&accountName=${encodedName}`;
}
};
// Sử dụng:
const qrUrl = VietQRHelper.createPaymentLink({
bankBin: '970422', // MB Bank
accountNo: '0901234xxx',
amount: 185000,
orderCode: 'ORD9041',
accountName: 'LE PETIT BAKERY'
});
6. Tổng kết & Kỳ tiếp theo
Tích hợp Google One-Tap Login và Cổng Thanh Toán VietQR / VNPay là bước chuyển mình đưa website tiệm bánh đạt chuẩn thương mại điện tử chuyên nghiệp: tối ưu tỷ lệ chuyển đổi, bảo vệ doanh thu bằng mã hóa HMAC-SHA512 và mang lại trải nghiệm mua sắm không chạm tuyệt vời cho khách hàng!
🎯 3 bài học đắt giá từ bài viết này:
- Google One-Tap tăng gấp đôi tỷ lệ đăng nhập: Loại bỏ hoàn toàn sự phiền toái của việc điền form và nhớ mật khẩu.
- VietQR động là chuẩn thanh toán số 1 Việt Nam: Khách quét là trả, đối soát tự động qua Webhook mà không cần người duyệt.
- Bảo vệ tài chính bằng HMAC-SHA512: Không bao giờ để lộ Secret Key ra client-side.
Ở bài viết tiếp theo, chúng ta sẽ bước sang một lãnh địa hoàn toàn mới — phá vỡ định kiến "Vibe Coding chỉ làm được Frontend":
👉 [Vibe Coding Thực Chiến #13] Vibe Coding Tầng Backend: Dùng AI Viết Plugin Java/Spring Tùy Biến Cho EzyPlatform!
Chúng ta sẽ dùng Claude Code và ChatGPT Codex viết trực tiếp mã nguồn Java Backend, tạo Plugin tùy biến với Controller, Service, Entity và cơ chế DataAppender để mở rộng nghiệp vụ máy chủ EzyPlatform mà không cần phải là một chuyên gia Java lão luyện!
💬 Góc thảo luận: Anh em thích tích hợp thanh toán quét mã VietQR tự động hơn hay thích đưa khách sang cổng VNPay/MoMo? Tỷ lệ khách bỏ giỏ hàng của anh em giảm được bao nhiêu sau khi có Google One-Tap? Hãy chia sẻ cùng mình bên dưới nhé!
Nếu thấy bài viết này hữu ích, đừng quên bấm Upvote 👍 và Bookmark (Clip) 🔖 để đón đọc tiếp Bài #13 nhé. Chúc anh em Vibe Coding thật thăng hoa!
All rights reserved