Giao diện
Voucher — Mã giảm giá & ưu đãi
2 loại mã: CAMPAIGN (chiến dịch chung) + AFFILIATE_PERSONAL (cá nhân affiliate). Apply tại /checkout, không có page voucher riêng.
Loại code
Hệ thống có 2 loại voucher:
CAMPAIGN — Mã chiến dịch chung
Phát qua landing page, social, email marketing.
text
TKHQ-LAUNCH26- Số lượt redeem giới hạn
- Có thể áp dụng tier cụ thể (PRO, BUSINESS)
- Có ngày hết hạn
AFFILIATE_PERSONAL — Mã cá nhân affiliate
Mã cá nhân do affiliate sở hữu — tracking attribution + commission.
text
JN-X4Y2K9- Unlimited redeem nhưng 1 user / 1 lần
- Auto-credit hoa hồng cho affiliate
- First-touch 60 ngày
Cách dùng
Nhập voucher tại trang /checkout trước khi chuyển khoản. Voucher không có route top-level — embed trong checkout form.

Quy trình:
- Chọn gói tại
/billing - Vào
/checkout - Nhập mã vào field "Mã giảm giá"
- Hệ thống validate realtime (Redis SET NX EX reservation)
- Tổng tiền cập nhật, QR refresh
- Chuyển khoản → webhook → consume voucher
Reservation 5 phút
Voucher được giữ chỗ 5 phút khi bạn nhập. Nếu không CK kịp, slot trả về và user khác có thể redeem.
Quy tắc combo
| Quy tắc | Mô tả |
|---|---|
| 1 voucher / order | Mỗi đơn chỉ áp dụng 1 mã, không cộng dồn |
| stackable=false default | Trừ khi voucher có flag stackable, không kết hợp được với promotion khác |
| perUserLimit | Mỗi user redeem mã CAMPAIGN tối đa N lần (config theo voucher) |
| minOrderVnd | Có thể yêu cầu giá trị đơn tối thiểu (ví dụ: 499.000 ₫) |
| planRestriction | Một số mã chỉ áp dụng tier nhất định (PRO, BUSINESS) |
Annual + Voucher
Có thể combine annual billing (giảm 16%) + voucher — tổng giảm cộng dồn nếu voucher cho phép stackable.
Lịch sử redeem
Lịch sử voucher đã redeem nằm tại /billing → tab Hoá đơn. Mỗi hoá đơn ghi rõ voucher applied + số tiền giảm.
| Mã | Loại | Giảm | Đơn | Ngày |
|---|---|---|---|---|
TKHQ-LAUNCH26 | CAMPAIGN | 20% | ORD-2026-0142 | 12/05 |
JN-X4Y2K9 | AFFILIATE | 10% | ORD-2026-0301 | 20/05 |
Cơ chế Redis Lua atomic
Validation và reservation voucher dùng Redis Lua script để đảm bảo atomic — tránh race condition khi nhiều user cùng redeem cùng lúc:
WATCH voucher:code:TKHQ-LAUNCH26
GET remaining_uses → check > 0
DECRBY remaining_uses 1
SET reservation:user:X:code:TKHQ-LAUNCH26 EX 300 ← 5 phút
EXECNếu 2 user cùng nhấn "Apply" một lúc, chỉ 1 người thành công — người còn lại nhận lỗi VOUCHER_EXHAUSTED.
Analytics voucher
Admin xem analytics tại trang /admin/vouchers:
| Chỉ số | Mô tả |
|---|---|
| Tổng redemptions | Số lần mã được dùng thành công |
| Revenue giảm | Tổng số tiền đã giảm theo voucher |
| Conversion rate | % user nhập mã → thực sự CK thành công |
| Top mã | Mã được dùng nhiều nhất theo kỳ |
| Campaign attribution | Doanh thu từ từng chiến dịch voucher |
FAQ voucher
Voucher hết hạn mà tôi đã reservation 5 phút — có mất không? Reservation 5 phút tính từ lúc bạn nhập mã, độc lập với ngày hết hạn voucher. Nếu voucher hết hạn trong khi bạn đang reservation, bạn vẫn dùng được trong 5 phút đó.
Tôi nhập mã nhưng QR không cập nhật? Thử refresh trang /checkout. Nếu mã hợp lệ, giảm giá sẽ hiển thị và QR code mới được sinh.
Mã AFFILIATE và mã CAMPAIGN có kết hợp được không? Không — mỗi order chỉ một mã. Chọn mã nào giảm nhiều hơn.