Evaluate and adapt

Should You Add a Referral Program?

Decide whether you need referral attribution, cash commissions, or credits before enabling the starter's first-touch tracking.

Sushi SaaS ships referral plumbing, not a finished affiliate program. It is disabled by default. When enabled, it can attribute a new account to a referrer and record a pending reward after payment; it does not verify affiliates, send money, grant credits, or mark payouts complete.

The user journey that ships

  1. A signed-in user creates a short invite code (normally eight characters) and shares /i/<code>.
  2. A visitor opens the link. The application stores the referrer's UUID in a 30-day ref cookie and redirects home.
  3. After the visitor signs in, the client posts that cookie to the attribution endpoint.
  4. The service claims the user's referrer once. Self-referrals are rejected and concurrent retries converge on the first successful attribution.
  5. A qualifying paid order creates one pending commission record. A database uniqueness rule makes webhook replay harmless.

Users can see their invite link and summary on the shipped my-invites page. Operators can inspect rows on the admin affiliates page, but that page is a read-only review surface—not a payout workflow.

The default example records the greater of 5,000 minor currency units or 20% of the paid amount. For a two-decimal USD charge, 5,000 means $50. Those values are examples, not a recommended commission.

See src/config/affiliate.ts at 2a1a04a and the orchestration in src/services/affiliate.ts.

Choose the program before the code

GoalWhat to do
No referral programLeave enabled: false. Remove the pages, routes, tables, and provider later if you want a smaller product
Invitation attribution onlyKeep first-touch attribution, stop creating and presenting commissions, and define what analytics you may retain
Cash affiliate commissionsAdd eligibility, identity/tax collection, fraud review, payout provider integration, audited state changes, and reconciliation
Product-credit rewardsAdd an idempotent credit-ledger grant; changing payoutType alone does not move credits
Last-touch attributionImplement and test a different claim rule in the service; the exported enum alone does not change the shipped first-touch behavior

Commission calculation supports fixed-only, percent-only, greater-of, and sum modes. Attribution does not currently switch on AttributionModel, so treat first touch as the implemented contract.

Policies you still need

  • Which purchases qualify, and when does a pending reward become payable?
  • What happens after refund, dispute, cancellation, or account erasure?
  • Which currency and minor-unit rules apply?
  • May employees, existing customers, or the same household participate?
  • Does the referral cookie require consent in the regions you serve?
  • How will operators investigate abuse and correct a record without losing an audit trail?

Stripe refund handling can cancel a still-pending reward, but completed payout recovery is not implemented. Do not automate money movement until these policies and failure paths exist.

Enable it safely

  1. Configure and test Stripe Billing.
  2. Replace the example window and reward values in src/config/affiliate.ts.
  3. Build the payout or credit workflow and its admin actions before turning the feature on.
  4. Test anonymous visit → signup/sign-in → first-touch attribution → payment → webhook replay → refund.
  5. Test self-referral, two competing links, cookie expiration, and concurrent events.

Use Configure Referrals and Affiliate Rewards for the exact setup and verification steps, then Admin Console Pages and Operations to understand the current review surface.

Should You Add a Referral Program? · Sushi SaaS