Coupon types

What each villacoupon3 type does and which response field carries the result. See discount-fields for the full contract and coupon-test-matrix for live examples.

TypeBehaviourResult lands in
fixedFlat baht off the cartcartDiscount
percentagePercentage off, honours maxDiscountAmountcartDiscount
bogoBuy N get 1 free, pools units across SKUsbogoDiscount
two_for_xBuy N for a set price, per-set captwo4Discount
free_shippingWaives the delivery feeshippingDiscount + isFreeShipping
shippingFixed baht off the delivery feeshippingDiscount
specific_skuPercentage off matching SKUs onlyspecificSkuDiscount

Two ways to express a partial shipping discount

Both of these exist in production data and behave identically:

  • shipping with discountValue: 50
  • free_shipping with maxDiscountAmount: 50

The second is the one that caused a bug: it is typed as free shipping but is not a full waiver. VillaCoupon3 disambiguates with freeShipping: false. Consumers must read that boolean rather than the type — see 2026-07-29-coupon-test-sheet-failures.

Restrictions

FieldEffect
orderSourceWEB / APP — an app-only coupon rejects a web order
applicableWithNationwideWhether the coupon applies to nationwide shipping
minOrderAmountMinimum subtotal; below it the coupon silently doesn’t apply
excludeControlledProductsExcludes alcohol and similar from the applicable total
maxDiscountAmountCaps the computed amount
Start / expiry datesOutside the window the coupon lands in failedCoupons

minOrderAmount is worth calling out when testing: a free-shipping coupon with a 5,000 baht minimum applied to a 365 baht basket produces no discount and no error, which reads as “the coupon is broken”.

Auto-applied promotions

Coupons flagged isPromotion apply without the customer typing a code. The site fetches them via /api/calculatePrice/suggestCoupon and passes them in couponCodeList alongside any typed code. In the test sheet these appear as “no code” with a numeric coupon id.