Skip to content

Store a referral code and send it with checkout - #364

Open
MehdiMamas wants to merge 3 commits into
Glench:mainfrom
MehdiMamas:feature/referral-code
Open

MehdiMamas wants to merge 3 commits into
Glench:mainfrom
MehdiMamas:feature/referral-code

Conversation

@MehdiMamas

@MehdiMamas MehdiMamas commented Sep 28, 2026 •

Copy link
Copy Markdown

Summary

  • Adds extpay.setReferral(code) and extpay.getReferral() so an extension can keep a first-touch referral code in extension storage.
  • Sends that code as ref on the existing choose-plan, trial, and login URLs, and as ref on the existing POST /api/new-key body. The public links already use ?ref=, so the body uses the same name. No new requests.

This pull request is only the ExtPay.js client. The extensionpay.com server is not in this repository, so the items below need to be built there.

Needs to be added on extensionpay.com

The owner configures one program per extension. The referrer reward is one of: a percentage (first payment, N months, or every renewal), a fixed cash amount, or free time (for example one free month). The referred user can optionally get a percentage or fixed discount (first payment, N months, or forever).

Accept the code this client already sends

  • Read ref from POST /api/new-key and from the choose-plan, trial, and login query strings.
  • Store it on the user (first touch, within a configurable window: 7, 30, 60, or 90 days, default 30).
  • Return it from the user API as user.referral ({code, capturedAt}). The client already copies unknown user fields through.

Configuration

  • Settings page: program on or off, reward type, reward scope, optional discount, attribution window, and a pending period before a reward is payable (to cover refunds).
  • Create and list codes, with optional per-code overrides (for example a higher rate for one influencer).
  • Hosted links such as https://extensionpay.com/extension/<id>?ref=<code> that land on the store listing.
  • Tie a code to a Stripe coupon and pass discounts when creating the Checkout session, so the buyer does not have to type the code.

Attribution and rewards

  • Count clicks, signups, and trials per code.
  • Write the code onto the Stripe Checkout session (metadata or client_reference_id) and onto each renewal from the webhook.
  • Calculate the configured reward. For free time, extend the referrer's subscription (Stripe credit or trial). For cash, record the amount owed.
  • Reverse the reward when the referred payment is refunded or disputed.

Dashboard, referrers, and abuse checks

  • Per-code stats: clicks, signups, trials, paid customers, conversion, revenue, rewards owed. CSV export.
  • Referrer accounts (email, codes, earnings) and a stats page. A payout report is enough for an MVP. Stripe Connect payouts can come later. Free-month rewards can target an existing ExtPay user and do not need a referrer account.
  • Block self-referrals (same email), attribute each customer only once across reinstalls and devices, and throttle clicks.

Stripe promotion codes already cover a typed discount and redemption limits. That workaround is described in docs/referral_guide.md. It does not replace the server work above.

Test plan

  • setReferral('youtuber123') then getReferral() returns that code and a capturedAt date
  • A second setReferral('other') keeps youtuber123; {overwrite: true} replaces it
  • setReferral('bad code') throws
  • openPaymentPage, openTrialPage, and openLoginPage append &ref=
  • The first new-key request body includes ref and does not include referral
  • With no stored code, those URLs have no ref parameter

MehdiMamas and others added 3 commits September 28, 2026 14:09
Lets an extension keep a first-touch referral code and pass it on the existing payment, trial, login, and new-key requests. Attribution stays on the ExtensionPay server.

Co-authored-by: Cursor <cursoragent@cursor.com>
Explains using one promotion code per referrer, plus setReferral, until ExtensionPay attributes the ref parameter.

Co-authored-by: Cursor <cursoragent@cursor.com>
The payment URLs already use ref, so the API-key body uses the same name instead of a second referral field.

Co-authored-by: Cursor <cursoragent@cursor.com>
@MehdiMamas
MehdiMamas marked this pull request as ready for review September 28, 2026 19:28
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