Payment Gateway VN — VNPay, MoMo, Casso, Stripe khác nhau thế nào

VNPay là 'cổng thanh toán bank Việt Nam', MoMo là 'ví điện tử', Casso là 'auto-verify chuyển khoản', Stripe là 'cổng quốc tế'. Hiểu 4 lựa chọn để chọn đúng cho ecommerce VN — tiết kiệm 30-70% phí transaction và rút ngắn integration từ 3 tuần xuống 3 ngày.

10 phút đọcCập nhật 2026-05-22
Nghe bài viết
Để Claude đọc bài cho bạn — vừa nghe vừa làm việc khác
Mục lục bài viết(25)
Sơ đồ thị trường payment gateway — các nhà cung cấp thanh toán online toàn cầu

Thị trường payment gateway toàn cầu — các nhà cung cấp cổng thanh toán online phân theo region, transaction volume, target customer. Việt Nam có hệ sinh thái payment riêng (VNPay, MoMo, ZaloPay, Casso) tách biệt khá rõ với Stripe/PayPal phổ biến quốc tế. Hiểu landscape giúp chọn đúng combo cho audience VN vs quốc tế. Nguồn: Wikimedia Commons (CC BY-SA 4.0).

Hiểu đơn giản nhất

Bạn mở quán cafe online. Khách đặt 1 cốc 50k VND. Bạn cần nhận tiền + biết chính xác ai trả + giao đúng đơn.

4 cách phổ biến ở VN:

CáchAnalogyPhí transactionUX cho khách
VNPayQuầy thu ngân có máy POS — cà thẻ là xong1.1-1.65%1 click, redirect sang VNPay, nhập OTP
MoMoVí QR — quét + nhập PIN1.1-2.2%App MoMo scan QR → confirm
CassoHộp đựng tiền + sổ ghi chép — khách chuyển khoản, bạn check200-500 VND/giao dịchKhách quét VietQR + bank app → bạn nhận webhook
StripeMáy POS quốc tế Visa/Master2.9% + $0.31 click, form thẻ inline

4 thuật ngữ cần phân biệt:

Thuật ngữLà gì
Payment GatewayCổng kết nối web bạn → mạng thanh toán (VNPay, Stripe)
Payment ProcessorBackend xử lý giao dịch (Napas cho VN, Visa/Master cho quốc tế)
Acquiring BankBank của bạn nhận tiền (Vietcombank, BIDV...)
Issuing BankBank của khách phát thẻ

User → gateway → processor → acquiring bank → tiền vào tài khoản bạn.

Tại sao bạn cần biết

  • Chọn sai gateway tốn 10x phí. SaaS 1000 đơn/tháng AOV 1tr → VNPay phí 1.5% = 15tr/tháng. Casso 200 VND × 1000 = 200k/tháng. Tiết kiệm 14.8tr/tháng = 178tr/năm.
  • Integration 3 ngày vs 3 tuần. VNPay docs cũ, có docs tiếng Việt nhưng convoluted. Stripe docs world-class. Casso docs medium. Chuẩn bị trước = không stuck.
  • Compliance/PCI-DSS = avoid PCI-DSS audit ($5-50k/năm) bằng cách dùng hosted payment page.
  • Webhook security critical. Audit vietcodex.com mới phát hiện M6 — non-constant-time compare cho Casso webhook. Hacker có thể fake webhook 'đã thanh toán' nếu không verify đúng.
  • UX = conversion. 1-click VNPay/MoMo có conversion 50-70%. Casso (yêu cầu quét QR + note đúng) chỉ 30-50% — phù hợp B2B không phù hợp impulse buy.

VNPay — cổng thanh toán thẻ VN

VNPay = aggregator kết nối web bạn với mọi bank VN. Thành lập 2007, partner với 40+ ngân hàng VN, thị phần > 50% ecommerce VN.

Methods VNPay hỗ trợ

MethodMô tảPhí
ATM/Internet BankingLogin Internet Banking, OTP1.1%
QR Code (VietQR)Scan QR bằng app banking0.8-1.1%
Thẻ tín dụng nội địaNapas1.65%
Thẻ quốc tế Visa/MasterInternational2.95%

Integration flow

  1. Đăng ký merchant tại vnpay.vn — KYC giấy phép kinh doanh, mất 5-10 ngày
  2. Nhận credentials: vnp_TmnCode + vnp_HashSecret
  3. Backend tạo URL redirect với params + vnp_SecureHash HMAC-SHA512
  4. Redirect user → vnpay.vn → khách thanh toán
  5. VNPay redirect về vnp_ReturnUrl của bạn với status (success/fail)
  6. VNPay gửi IPN (Instant Payment Notification) webhook → bạn verify + update DB

Code snippet

import { createHmac } from "node:crypto";
 
const params = {
  vnp_Version: "2.1.0",
  vnp_Command: "pay",
  vnp_TmnCode: process.env.VNPAY_TMN_CODE,
  vnp_Amount: 100000 * 100, // VND × 100 (đơn vị xu)
  vnp_CurrCode: "VND",
  vnp_TxnRef: "ORDER_12345",
  vnp_OrderInfo: "Thanh toan don VC2026000001",
  vnp_OrderType: "other",
  vnp_Locale: "vn",
  vnp_ReturnUrl: "https://vietcodex.com/thanh-toan/vnpay-return",
  vnp_IpAddr: clientIp,
  vnp_CreateDate: format(new Date(), "yyyyMMddHHmmss"),
};
 
const sortedKeys = Object.keys(params).sort();
const queryString = sortedKeys.map(k => `${k}=${encodeURIComponent(params[k])}`).join("&");
const signature = createHmac("sha512", process.env.VNPAY_HASH_SECRET)
  .update(queryString)
  .digest("hex");
 
const paymentUrl = `https://sandbox.vnpayment.vn/paymentv2/vpcpay.html?${queryString}&vnp_SecureHash=${signature}`;
// Redirect user to paymentUrl

⚠️ Khi verify IPN webhook, dùng timingSafeEqual (xem audit M6 vietcodex.com).

MoMo — ví điện tử dẫn đầu VN

MoMo = mobile wallet 30M+ user. Mạnh nhất Gen Z + millennials.

Methods

  • QR App MoMo — scan trong cart, confirm trong app
  • Number phone — nhập số ĐT MoMo của khách
  • Token — khách lưu method trong app, click 1 lần xong

Integration

Tương tự VNPay nhưng API khác. Docs developer.momo.vn — tiếng Anh + Việt.

Lý do dùng MoMo

  • Customer 18-35 tuổi mua hàng tiện lợi
  • F&B, grocery, transport (đã có precedent Grab/Be)
  • Cashback campaign — MoMo subsidize cashback cho merchant tham gia

Casso — auto-reconcile chuyển khoản bank

Casso là tool VN giải quyết bài toán: web không tự biết khách đã chuyển khoản chưa. Cách thủ công = bạn check sao kê bank mỗi giờ. Cách Casso = webhook tự báo.

Flow

  1. Setup: Đăng ký casso.vn, link tài khoản Vietcombank/Techcombank/BIDV (Casso đăng nhập IB của bạn để đọc sao kê)
  2. Web hiển thị VietQR cho khách + nội dung VC2026000001 (mã đơn)
  3. Khách chuyển khoản từ bank app với nội dung đó
  4. Bank notify Casso (Casso check sao kê mỗi 30 giây - 5 phút)
  5. Casso webhook → server bạn kèm secret token
  6. Server verify token + match order theo nội dung chuyển → mark PAID

Code snippet (vietcodex.com đang dùng)

// app/api/webhook/casso/route.ts
import { timingSafeEqual } from "node:crypto";
 
export async function POST(req: Request) {
  const secret = process.env.CASSO_WEBHOOK_SECRET;
  const auth = req.headers.get("secure-token") || "";
 
  // M6 fix: constant-time compare
  if (!safeTokenMatch(auth, secret)) {
    return new Response("Unauthorized", { status: 401 });
  }
 
  const body = await req.json();
  for (const tx of body.data) {
    const match = tx.description.match(/VC[\d]+/);
    if (!match) continue;
 
    const order = await db.query.orders.findFirst({
      where: sql`UPPER(REPLACE(order_number, '-', '')) = ${match[0]}`,
    });
    if (order && tx.amount >= order.total) {
      await markOrderPaid(order.id, tx.id);
    }
  }
 
  return new Response("OK", { status: 200 });
}

Pricing

  • Free tier: 100 transaction/tháng
  • Paid: 200-500 VND/transaction (rẻ hơn VNPay 50-100x)
  • Annual: discount khi mua trước

Khi nào nên dùng Casso

✅ B2B service/SaaS, AOV > 500k ✅ Tech-savvy customer ✅ Không khẩn cấp confirm thanh toán (1-5 phút lag OK) ✅ Cần invoice chính thức (chuyển khoản bank có sao kê rõ)

❌ B2C impulse buy < 200k (khách lười QR + note sai) ❌ Real-time critical (game top-up, đặt vé giờ chót)

Stripe — cổng quốc tế

Stripe dominant ở US/EU. Documentation engineering xuất sắc, developer experience top-tier.

Tại sao Stripe khó dùng ở VN

  • Không nhận pháp nhân VN (cần US/UK/SG entity)
  • Không support thẻ ATM VN nội địa (chỉ Visa/Master quốc tế)
  • Payout USD/EUR (chịu phí FX convert 1-3%)

Stripe Atlas — workaround cho founder VN

  • Stripe + LLC Delaware US + Mercury bank account
  • Setup $500 + $100/năm maintain
  • Ưu: chuyên nghiệp quốc tế, accept toàn thế giới
  • Nhược: tax US + accounting US (phải hire CPA $1-3k/năm)

Khi nào dùng Stripe

✅ SaaS bán quốc tế, customer paying USD ✅ Subscription billing (Stripe Billing world-class) ✅ Marketplace platform (Stripe Connect) ✅ Có entity quốc tế hoặc willing setup Atlas

ZaloPay, ShopeePay, ViettelMoney

ProviderStrengthUse case
ZaloPayTích hợp Zalo OA, mini-appApp có user base Zalo, chatbot order
ShopeePayInternal Shopee/SEA groupMarketplace seller
ViettelMoneyViettel telco networkMass market, low income demographic

Ít phổ biến hơn VNPay/MoMo nhưng có niche.

Decision matrix

Bạn bánKhuyến nghị stack
SaaS B2B VN < 100 đơn/thángCasso + VietQR display
SaaS B2B VN > 100 đơn/thángVNPay + Casso (backup)
E-commerce B2C VN food/lifestyleMoMo + VNPay (mặc định)
E-commerce B2C VN >5000 đơn/thángVNPay + MoMo + ZaloPay
SaaS bán quốc tế VNDVNPay + Stripe Atlas
SaaS bán quốc tế USDStripe (Atlas LLC)
Marketplace platformStripe Connect (US LLC)
Đào tạo, coaching B2C VNVNPay + Casso
Service freelancer quốc tếWise + Payoneer

Ví dụ thực tế: vietcodex.com payment flow

vietcodex bán web design 5-50tr/dự án, AOV cao, customer B2B → Casso là chọn đúng.

Customer flow:
1. Customer chọn package (vd "Web service business 8tr")
2. Web tạo order với mã VC2026000001, status PENDING_PAYMENT
3. Web hiện VietQR + nội dung "VC2026000001" + bank info
4. Customer chuyển khoản qua app Vietcombank/Techcombank
5. Casso check sao kê → match "VC2026000001"
6. Casso webhook → server vietcodex.com
7. Server verify token (M6 timing-safe) → mark PAID
8. Server provision tenant tự động (template website)
9. Telegram notify admin
10. Customer thấy status update "Đã thanh toán, đang triển khai"

Time: 30 giây - 5 phút sau khi chuyển khoản
Phí: 200 VND × 1 đơn = 200 VND (vs VNPay 8tr × 1.5% = 120.000 VND)
Tiết kiệm 99.8% phí.

Cái gì có thể sai

Vấn đềTriệu chứngCách fix
Khách chuyển khoản nhưng không nhận notiCasso link bank bị disconnectRe-link account Casso, set webhook URL đúng
Webhook bị fake (đơn ship hàng nhưng không có tiền)Không verify secretImplement timing-safe compare + check transaction id unique
VNPay redirect about return URL saiConfig trong VNPay merchant portalMatch exactly vnp_ReturnUrl trong API call
Double charge customerKhông idempotent checkAdd unique constraint trên transaction_id
Stripe payout chậm 7-14 ngàyAccount mới hoặc risk flagKYC đầy đủ + verify identity
MoMo callback timeoutServer bạn xử lý > 5sPush job vào queue + trả 200 ngay
FX rate Stripe cao 4-5%Default Stripe FXConnect Wise bank account để FX rate thấp hơn
Khách phàn nàn không có MoMoDemographic Gen ZAdd MoMo dù phí cao hơn — UX justifies

Tóm tắt 1 dòng

4 lựa chọn VN: VNPay (cổng thẻ + IB, 1.1-1.65%, UX 1-click) — default cho ecommerce mass. MoMo (ví Gen Z, 1.1-2.2%) — pair VNPay cho coverage tối đa. Casso (auto-reconcile bank, 200-500đ/giao dịch) — best cho B2B AOV cao, tiết kiệm 50-100x phí. Stripe (quốc tế, cần Atlas LLC) — SaaS bán USD. Stack tốt nhất 2026 cho ecommerce VN: VNPay + MoMo + Casso (backup). Verify webhook bằng timing-safe compare + idempotency check trên transaction_id.

Đọc tiếp

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

Casso và VNPay khác nhau thế nào? Khi nào nên dùng Casso?
VNPay là 'cổng thanh toán' — user click 'Thanh toán VNPay' → redirect sang trang VNPay nhập thẻ/QR → quay về web với status. Phí 1.1-1.65% mỗi giao dịch. Casso là 'auto-reconcile' — bạn vẫn hiện QR VietQR cho khách chuyển khoản bank, Casso webhook báo bạn khi tiền vào. Phí 200-500 VND/giao dịch (rẻ hơn 10-50x). Trade-off: VNPay UX tốt hơn (1 click) nhưng phí cao. Casso UX yêu cầu khách quét QR thủ công + nhập đúng mã đơn, nhưng phí gần như miễn phí. Quy tắc: <100 đơn/ngày dùng Casso. >100 đơn dùng VNPay (UX justifies phí).
VNPay vs MoMo — khách thích cái nào?
Tuỳ demographic. MoMo: ví điện tử, > 30 triệu user VN, phổ biến nhất cho Gen Z + millennials, đặc biệt food/grocery/transport (Grab, Be tích hợp). VNPay: cổng aggregate cho thẻ ngân hàng (Vietcombank, Techcombank, BIDV...), Internet Banking, QR. Phổ biến với khách 30+ tuổi quen Internet Banking. Recommendation: e-commerce VN nên integrate CẢ HAI để không miss customer. Cả 2 đều phí 1.1-1.65%. Bonus: ZaloPay cũng growing (8M+ user), tích hợp Zalo OA mạnh.
KHÔNG chính thức — Stripe chưa support pháp nhân VN (account business). Có 2 workaround: (1) Đăng ký Stripe US/UK qua công ty hợp pháp ở đó (LLC Delaware $300 setup) — phù hợp SaaS bán quốc tế; (2) Atlas program của Stripe giúp founder VN incorporate US LLC + Stripe + bank account, $500 setup. Stripe trade-off VN: không nhận thẻ nội địa NAPAS (chỉ Visa/Master quốc tế), phí 2.9% + $0.3, payout USD/EUR (chịu phí convert). Nếu bán customer VN dùng VNĐ thanh toán → bắt buộc VNPay/MoMo, không Stripe.
PCI-DSS compliant là gì? Có cần khi tích hợp payment?
PCI-DSS (Payment Card Industry Data Security Standard) là chuẩn bảo mật cho web xử lý thẻ tín dụng. 12 yêu cầu: encrypt thẻ, không log CVV, firewall, audit trail, vv. Cách tránh: KHÔNG TỰ XỬ LÝ data thẻ — redirect sang VNPay/MoMo/Stripe (họ PCI compliant rồi), nhận callback status. Pattern này gọi là 'hosted payment page'. Cost compliance tự xử lý: $5-50k audit/năm. Bằng cách dùng cổng thanh toán, bạn không nắm data thẻ → out-of-scope PCI-DSS. 99% e-commerce VN dùng pattern này — không tự build credit card form.
Webhook payment có thể bị fake không?
Có — nếu không verify đúng. Hacker biết endpoint webhook của bạn (/api/webhook/casso, /api/webhook/vnpay-ipn) → POST request giả mạo 'đơn 123 đã thanh toán' → web bạn ship hàng + trừ kho. Cách verify: (1) Casso: gửi secret token trong header `secure-token`, bạn so với env. Dùng `crypto.timingSafeEqual()` chống timing attack; (2) VNPay: ký request bằng HMAC-SHA512 với secret, gửi `vnp_SecureHash`, bạn ký lại body so signature; (3) MoMo: tương tự HMAC, dùng partner secret. Audit vietcodex.com vừa fix M6 vấn đề này: timing-safe compare cho Casso webhook.
Auto-reconcile có thực sự work cho business size khác nhau?
Casso (auto-reconcile bank) tốt nhất cho: SaaS/dịch vụ <1000 giao dịch/tháng, AOV (Average Order Value) cao 500k-50tr, customer là business hoặc tech-savvy. KHÔNG phù hợp: F&B + retail B2C giá thấp (<200k), high-volume — khách lười quét QR + sai cú pháp note 'VC2026000001' rất nhiều. vietcodex.com áp dụng Casso vì AOV cao (web design 5-50tr/dự án), customer biết tech, cần invoice chính thức. Shopee/Tiki KHÔNG dùng Casso, dùng aggregator riêng (Lazada Pay, ShopeePay).
Thanh toán quốc tế cho khách VN nhưng bán USD/EUR — chọn cái nào?
3 lựa chọn: (1) Stripe với Atlas LLC (đã nói) — most flexible nhưng cost setup 500-1000 USD; (2) PayPal — accept VN, KYC strict, phí 4.4% + fx markup 4%, payout chậm; (3) Wise (formerly TransferWise) — fx rate tốt nhất, nhưng business account VN limited; (4) Payoneer — popular cho freelancer VN, accept marketplace payment (Upwork, Amazon). Recommendation: B2C khách quốc tế → Stripe. B2B service xuất khẩu → Wise + invoice. Freelance gig economy → Payoneer.