← All guides

Operational deep-dive

Cannabis loyalty program — earn rates that don’t bankrupt the margin

Most cannabis loyalty programs leak margin because the earn rate was set by feel (‘1 point per $’) and the redemption math was never modeled. The customer earns points at retail prices, redeems against retail prices, and the operator absorbs the discount on already-thin margin. Here’s how we run loyalty at Green Life + Seattle Cannabis Co — what we shipped, what we’d undo, and the audit cadence that keeps the program from quietly turning into a 12% margin haircut.

By CannAgent7 min read

The default-bad earn rate

Most operators ship loyalty with ‘1 point per dollar’ + ‘$10 off when you hit 100 points.’ That math is 10% off every customer’s purchase, applied retroactively. On 30% gross margin, that’s a one-third margin haircut on every loyalty member who redeems. The operator doesn’t see it until quarter-close.

The earn rate that doesn’t leak

Set the earn rate as a percentage of MARGIN, not retail. Two-step calculation:

  1. **Pick a target loyalty cost.** Doug’s rule at Green Life + SCC: 3% of net revenue, hard cap. That number gets accounted for as a marketing expense, not a cost-of-goods item — it’s an investment in retention.
  2. **Back into the earn rate from the gross margin.** If gross margin is 30% and target loyalty cost is 3% of net revenue, then redemption-discount-as-%-of-redemption-purchase = 3% / 30% = 10% of the redemption transaction. Translate to earn: 1 point per $1 + redemption at 100 points = $1 off (not $10 off). That’s a 1% discount on each redemption transaction — but at the redemption rate of ~10%, the blended cost equals 0.1% per dollar earned, well inside the 3% cap.
  3. **Kill the round-number redemption tiers.** ‘100 points = $10 off’ is round, easy to remember, and bankrupts you. ‘100 points = $5 off’ or ‘200 points = $15 off’ both run the math under control. We use 200 points = $5 off at Green Life — the inconvenient ratio is a feature; it slows redemption velocity without telling the customer the system is hostile.

Redemption tiers that protect the basket

The classic loyalty trap: a customer accumulates 1,000 points, walks in to redeem, and the budtender applies $50 off a $52 basket. Customer leaves with $2 of cannabis at a 96% effective discount. Three tier rules that stop this:

  • **Cap redemption at a % of the current basket.** No redemption can exceed 25% of the pre-discount basket total. $80 basket → max $20 redemption. Forces the customer to keep buying real product to use their points; prevents the ‘$2-of-cannabis-for-points’ raid.
  • **Lock redemption to in-store, never online.** Online basket is already discount-stacked (delivery, first-visit, online-only deals). Letting points pile on top is a margin compounding event. We allow redemption ONLY at the in-store register where the budtender can see the full basket math.
  • **Disable redemption on already-discounted items.** If the customer already has industry / heroes / medical / sale discount applied, no points on top. The budtender stops the redemption and the customer chooses one or the other. Stacking is the silent margin killer.
  • **Expire points after 12 months of inactivity.** A customer who hasn’t shopped in a year isn’t coming back; their 800 points sitting on the books is a contingent liability. Annual expiry on the customer’s account anniversary, with a 30-day-before-expiry email that triggers re-engagement. Doubles as a clean balance-sheet practice.

What the audit cadence catches

  1. **Monthly: loyalty cost as % of net revenue.** Calculated as (sum of redemptions in dollars) / (sum of net revenue in dollars). Target 2.5-3.0%; alert at 3.5%.
  2. **Monthly: redemption velocity per active member.** Number of redemptions / number of active members in the month. Sudden spikes signal a stacking exploit or a budtender ringing wrong.
  3. **Quarterly: top-redeemer concentration.** What % of redemptions came from the top 5% of members? If >25%, the program is rewarding heavy-discount-seekers more than retention. Re-tune.
  4. **Quarterly: re-engagement rate from the 30-days-before-expiry email.** What % of expiring-points members shop within the email-trigger-to-expiry window? >15% = the program is doing real retention work; <5% = the email is wasted send and the points were already abandoned.
  5. **Annual: full earn-rate re-tune.** Pull the prior 4 quarters of data; recalculate the blended discount-as-%-of-redemption; adjust earn rate or tier structure to keep loyalty cost inside the 3% cap.

What WSLCB / OLCC / DCC actually care about

  • **Loyalty discounts get the same per-transaction audit-log treatment as any other discount.** Activity row stamped with discount type, points used, $-discount applied. Per WAC 314-55 family the audit log is queryable on demand.
  • **No loyalty discount on already-discounted items where the stack would push effective discount above 50%.** Same 50% cap as the industry-discount rule; once the stacked discount approaches that line, the WSLCB starts asking whether the ‘loyalty’ is actually a dressed-up kickback.
  • **Loyalty data is customer-level PII.** Treat it like any other contact data. Don’t sell, don’t share with brand partners without explicit consent, don’t leak via vendor-portal scoping.
  • **Customer can request their loyalty data + opt out.** State privacy laws (WA HB 1155 / OR ORS 646A.602 / CA CCPA all apply). Build the export + delete flow before someone asks; CannAgent ships both as one-click admin actions.

Takeaways

Ready to talk through your migration?

30-minute demo. We end by quoting the cutover from your current setup — fixed scope, no hourly games.