Referral programs

A referral program (rfl_…) defines two percent rule sets: for the referee (buyer who opened ?ref=… and paid for a subscription) and the referrer (link owner). Create at Promotions → Referral programs → New (/dashboard/promotions/referral/create). Edit at /dashboard/promotions/referral/[referralId]. You must also enable the program on each offer (Offer → Promotions).

Referral discounts are always percent (0-100). Fixed gross amounts are coupons-only.

Program name

Required, 1-120 characters. Internal label in the program list and offer picker. Not shown to the buyer on the payment page.

Referee rules (refereeRules)

Referee discount (%)

Required 0-100. Lowers the referee subscription payments according to duration. UI default: 10%.

Referee discount duration

  • Once - applies on the payment where the referee used the link; grant consumed on that pay_….
  • Payment count (repeating_payment_count) - first N cycles (1-999), including the starting payment.
  • Repeating interval - from subscription start via presets or custom 1-999 + D/W/M/Y (^[1-9]\d{0,2}[DWMY]$). UI default interval 1Y.
  • Forever - every later referee cycle while the entry stays active (UI default).

Referrer rules (referrerRules)

Referrer discount (%)

Required 0-100 awarded to the link owner after a successful referee conversion. UI default: 5%.

Referrer discount duration

  • Once - grant starts with consumed: false and applies on the referrer's next cycle payment after conversion.
  • Payment count / interval / forever - same semantics on the referrer subscription, within the max percent cap.

Max referrer discount (%)

Required 0-100 (default 20). Cap on the sum of active referrer percent grants on one subscription. New grants are clipped to remaining room; if remaining ≤ 0 the reward is skipped silently.

Max referrals per customer

Optional integer ≥ 1: how many times the same referrer may receive a reward. Empty/null = unlimited. Further grants are skipped after the cap.

Portal visibility

  • showRefer (default true) - hides Refer UI when false; links may still work technically.
  • showReferChoice (only if showRefer) - referrer may pick another eligible recurring offer as the link target.
  • rewardAfterTrial - when true, referrer reward requires SUCCESS without trialAccess and totalAmount > 0.

Enable on offer

Offer → Promotions: allow referral links + select one ACTIVE program. Disabled unless the offer is recurring. REST: PUT /promotions/referrals/{qrId} with { enabled, referralId }.

  • Program must be ACTIVE in the same organization.
  • Optional API-only eligibleQrIds scopes the program; empty = all org offers.

Link creation and behavior

  • Subscriber must be ACTIVE or TRIAL on a recurring offer with referrals enabled.
  • One ReferralLink per (program, customer); 10-char uppercase code; URL uses `?ref=CODE`.
  • Attribution stored in sessionStorage (zevio_referral_attribution) scoped by qrId.
  • Self-referral → errors.referral.self_referral.
  • ref on /pay auto-applies and hides the manual coupon field.

Conversion pipeline

  • 1. Referee SUCCESS on an eligible offer.
  • 2. Referee grant + conversionCount + referralLinkId + promotion.redeemed (side: referral).
  • 3. Referrer grant attempt (trial/cap/max checks).
  • 4. On success: referral.converted with link/subscription/payment/grant/redemption ids.

Stacking with trial, offer discounts, coupons

  • Preview: percent code/ref becomes generalDiscount and replaces offer generalDiscount; offer trial usually kept.
  • Billing: active percent entries sum (cap 100). Active fixed_gross coupon wins alone.
  • Applying a new coupon marks prior coupon entries replacedAt; referral entries stay.
  • Referral codes cannot be applied via subscription contents edit.

Statuses, archive, delete

  • PATCH status: ACTIVE|INACTIVE only.
  • Archive → ARCHIVED (no restore). Archived GET → program_not_found.
  • Delete only if linkCount=0 and conversionCount=0; else program_in_use.

Ineligibility reasons

  • subscription_not_active, referral_not_enabled, referral_program_unavailable, show_refer_hidden, not_recurring

Error keys

  • errors.referral.program_not_found|inactive|archived|in_use|self_referral|subscription_required
  • errors.promotion.not_recurring|code_redemption_disabled|qr_not_eligible
  • cap_reached / max_referrals_reached exist in the catalog; runtime usually skips grants silently.

Identifiers

  • Program rfl_…, link rlink_…, redemption pred_…
  • Referrer grant key referrer_sub_{refereeSubscriptionId} (legacy referrer_{paymentId}).