Skip to content

fix: refunds lower the fee-free counter; renewals follow the Stripe customer ID - #223

Merged
sonpiaz merged 3 commits into
mainfrom
fix/docs-refund-counter-renewal-email
Oct 24, 2026
Merged

sonpiaz merged 3 commits into
mainfrom
fix/docs-refund-counter-renewal-email

Conversation

@sonpiaz

@sonpiaz sonpiaz commented Oct 24, 2026

Copy link
Copy Markdown
Member

Two public claims contradicted the runtime. This PR corrects them on every page that states them, and retires the old refund wording in CI.

1. Refunds and the $10,000 fee-free tier

Old: refunds do not lower the revenue counted toward the $10,000 fee-free tier.
Code: a refund lowers program.total_revenue (the fee-tier input) by the refunded amount, capped by what that sale added; a full refund takes the remainder.

  • affiliate-cms apps/cms/src/api/affiliate-commission/services/commission-refund.ts (uncountRevenue, amount 'all' when full, else the refund delta)
  • affiliate-cms apps/cms/src/utils/revenue-counter.ts (header: total_revenue is the input to the $10k free tier; every decrement is capped by the sale's revenue_counted)
  • affiliate-cms apps/cms/src/api/affiliate-fee/services/affiliate-fee.ts (Tier 1 $0 to $10K free)

Pages: getting-started/pricing-performance-model.mdx, brand/quickstart/commission-approval-cash-flow.mdx, faq/index.mdx. New scripts/retired-claims.json entry blocks the old sentence.

2. How renewals are matched

Old: after the first attributed payment, renewals match by the buyer's email or the saved Stripe customer ID.
Code: the lookup chain tries the click, then email_hash, then stripe_customer_id. The email step finds a customer only when its email_hash was recorded, which a settled lead does (processLead); a provisional browser lead deliberately writes no identity. The Stripe customer ID is saved on the customer once a payment is attributed.

  • affiliate-cms apps/cms/src/api/webhook-distributor/services/webhook-distributor.ts (lookup chain, email_hash filter, stripe_customer_id saved)
  • affiliate-cms apps/cms/src/api/affiliate-lead-event/services/affiliate-lead-event.ts (recordProvisionalLead writes no email_hash; processLead sets it)

Pages: brand/tracking/payment-tracking-stripe.mdx (three lines), api-reference/attribution.mdx, use-cases/subscriptions.mdx. Renewals now say they follow the saved Stripe customer ID; email is described as matching only a customer whose email Affitor has recorded.

Not changed (still true): integration pages that say a subscription without subscription_data.metadata is attributed "only if the buyer's email or Stripe customer ID matches" a known customer.

Checks

npm run build, check-agent-surface (retired claims 24 patterns, 0 hits), check-docs-host, check-docs-host-http: all pass locally. No media changed.

sonpiaz and others added 2 commits October 24, 2026 08:53
…Stripe customer ID

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
affitor-docs Ready Ready Preview Oct 24, 2026 4:03pm UTC

Request Review

…tches

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@sonpiaz
sonpiaz marked this pull request as ready for review October 24, 2026 16:05
@sonpiaz
sonpiaz merged commit 8ca4aca into main Oct 24, 2026
4 checks passed

This branch was successfully deployed

1 active deployment
Preview — 5928eb33 Deployed Oct 24, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant