-
Notifications
You must be signed in to change notification settings - Fork 1
Referral System
arminrad edited this page Mar 16, 2026
·
2 revisions
User referral program with automatic bonus rewards
Users can invite friends and earn rewards. When a referred user makes their first purchase of $10+, both users receive a $10 bonus.
- $10 minimum purchase requirement
- $10 bonus for both referrer and referee
- 10 uses per code maximum
- First purchase only bonus
- Automatic credit addition via webhook
1. Alice registers → Gets code "ABC12345"
2. Bob registers with Alice's code → Stores referred_by_code
3. Bob makes first purchase $10+ → Webhook processes
4. System validates:
✓ First purchase?
✓ Has referral code?
✓ Purchase >= $10?
5. Apply rewards:
→ Bob: $10 (payment) + $10 (bonus) = $20
→ Alice: $10 (bonus)
6. Mark Bob's first purchase complete
7. Create referral record
curl http://localhost:8000/referral/code \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"referral_code": "ABC12345",
"user_id": 1,
"username": "alice"
}curl -X POST http://localhost:8000/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "bob",
"email": "bob@example.com",
"auth_method": "email",
"referral_code": "ABC12345"
}'curl http://localhost:8000/referral/stats \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"referral_code": "ABC12345",
"total_uses": 2,
"remaining_uses": 8,
"max_uses": 10,
"total_earned": 20.0,
"referrals": [
{
"user_id": 5,
"username": "bob",
"bonus_earned": 10.0
}
]
}GET /referral/code
Auth: Required (Bearer token)
Response:
- Creates code if user doesn't have one
- Code format: 8 chars (uppercase + digits)
- Each code is unique
POST /referral/validate
Request:
{
"referral_code": "ABC12345"
}Response (Valid):
{
"valid": true,
"message": "Referral code is valid",
"referrer": {
"username": "alice",
"email": "alice@example.com"
},
"remaining_uses": 8
}Response (Invalid):
{
"valid": false,
"message": "Invalid referral code",
"error": "Code not found"
}GET /referral/stats
Auth: Required
Response Fields:
-
referral_code- Your code -
total_uses- Times code was used -
remaining_uses- Uses left (max 10) -
total_earned- Total bonus earned -
current_balance- Current credit balance -
referred_by_code- Code you used (if any) -
referrals- List of users who used your code
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username TEXT UNIQUE,
email TEXT UNIQUE,
credits NUMERIC, -- Credit balance
referral_code TEXT(8) UNIQUE, -- User's code
referred_by_code TEXT(8), -- Code used at signup
has_made_first_purchase BOOLEAN, -- Bonus eligibility
api_key TEXT
);CREATE TABLE referrals (
id INTEGER PRIMARY KEY,
referrer_id INTEGER, -- Code owner
referred_user_id INTEGER, -- Code user
referral_code TEXT, -- Code used
bonus_amount NUMERIC DEFAULT 10.0, -- Bonus given
status TEXT, -- 'completed'
completed_at TIMESTAMP
);Location: src/db/referral.py
def generate_referral_code() -> str:
"""Generate unique 8-character code"""
import random, string
chars = string.ascii_uppercase + string.digits
return ''.join(random.choices(chars, k=8))Location: src/routes/payments.py (webhook handler)
Triggers when:
- Stripe webhook receives
checkout.session.completed - User has
referred_by_codeset -
has_made_first_purchaseis False - Purchase amount >= $10
Actions:
- Add $10 to referee's credits
- Add $10 to referrer's credits
- Set
has_made_first_purchase= True - Create referral record
- Amount: $10.00 USD
- Applies to: First purchase only
- Currency: USD (1000 cents)
- Max uses: 10 per code
- Format: 8 characters (A-Z, 0-9)
- Uniqueness: Globally unique
- Referrer bonus: $10.00
- Referee bonus: $10.00
- Timing: Immediately after payment
- Method: Automatic (webhook)
# 1. Alice registers
curl -X POST http://localhost:8000/auth/register \
-H "Content-Type: application/json" \
-d '{"username":"alice","email":"alice@example.com","auth_method":"email"}'
# Save API key: ALICE_API_KEY
# 2. Get Alice's referral code
curl http://localhost:8000/referral/code \
-H "Authorization: Bearer $ALICE_API_KEY"
# Save code: ALICE_CODE="ABC12345"
# 3. Bob registers with Alice's code
curl -X POST http://localhost:8000/auth/register \
-H "Content-Type: application/json" \
-d '{
"username":"bob",
"email":"bob@example.com",
"auth_method":"email",
"referral_code":"ABC12345"
}'
# Save API key: BOB_API_KEY
# 4. Bob creates checkout for $10
curl -X POST http://localhost:8000/api/stripe/checkout-session \
-H "Authorization: Bearer $BOB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"amount":1000,"currency":"usd"}'
# 5. Complete payment at returned URL
# Use test card: 4242 4242 4242 4242
# 6. Verify Alice got bonus
curl http://localhost:8000/referral/stats \
-H "Authorization: Bearer $ALICE_API_KEY"
# Should show: total_earned: 10.0
# 7. Verify Bob got payment + bonus
curl http://localhost:8000/user/balance \
-H "Authorization: Bearer $BOB_API_KEY"
# Should show: credits: 20.0interface ReferralData {
referral_code: string;
total_uses: number;
remaining_uses: number;
total_earned: number;
}
async function getReferralCode(): Promise<ReferralData> {
const response = await fetch('/referral/code', {
headers: {
'Authorization': `Bearer ${apiKey}`
}
});
return await response.json();
}
// Usage
const data = await getReferralCode();
console.log(`Your code: ${data.referral_code}`);
console.log(`Share link: https://app.gatewayz.ai/signup?ref=${data.referral_code}`);async function validateReferralCode(code: string): Promise<boolean> {
const response = await fetch('/referral/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ referral_code: code })
});
const result = await response.json();
return result.valid;
}function ReferralStats() {
const [stats, setStats] = useState(null);
useEffect(() => {
fetch('/referral/stats', {
headers: { 'Authorization': `Bearer ${apiKey}` }
})
.then(res => res.json())
.then(setStats);
}, []);
if (!stats) return <div>Loading...</div>;
return (
<div className="referral-stats">
<h3>Your Referral Stats</h3>
<div>Code: <strong>{stats.referral_code}</strong></div>
<div>Used: {stats.total_uses} / {stats.max_uses}</div>
<div>Total Earned: ${stats.total_earned}</div>
<div>
<h4>Referrals ({stats.referrals.length})</h4>
<ul>
{stats.referrals.map(r => (
<li key={r.user_id}>
{r.username} - ${r.bonus_earned}
</li>
))}
</ul>
</div>
</div>
);
}- Validation returns
valid: false - Error: "Referral code has reached maximum uses"
- Bonus not applied
- User still gets purchased credits
- No referral record created
- Registration succeeds
- No bonus applied
-
referred_by_coderemains NULL
- No bonus applied
- User gets purchased credits only
- First purchase flag remains False
-- Top referrers
SELECT u.username, u.referral_code, COUNT(*) as referrals
FROM users u
JOIN referrals r ON u.id = r.referrer_id
GROUP BY u.id
ORDER BY referrals DESC
LIMIT 10;
-- Recent referrals
SELECT * FROM referrals
ORDER BY completed_at DESC
LIMIT 20;
-- Total bonus paid
SELECT SUM(bonus_amount * 2) as total_bonuses
FROM referrals;-- Conversion rate
SELECT
COUNT(DISTINCT referred_user_id) as total_referred,
COUNT(*) as total_converted,
(COUNT(*) * 100.0 / COUNT(DISTINCT referred_user_id)) as conversion_rate
FROM referrals;
-- Average time to first purchase
SELECT AVG(completed_at - created_at) as avg_time
FROM referrals r
JOIN users u ON r.referred_user_id = u.id;Edit src/routes/payments.py:
REFERRAL_BONUS = 10.0 # Change to desired amount
MIN_PURCHASE = 10.0 # Minimum purchase for bonusEdit src/db/referral.py:
def generate_referral_code() -> str:
# Change length or character set
return ''.join(random.choices(chars, k=8)) # k=lengthEdit src/routes/referral.py:
MAX_REFERRAL_USES = 10 # Change maximum uses- Stripe Integration - Payment processing
- API Keys - Authentication
- User Management - User endpoints
- Bonus per referral: $20 total ($10 each)
- Max uses per code: 10
- Minimum purchase: $10
-
Implementation:
src/db/referral.py,src/routes/referral.py
Last Updated: December 2024 Status: Production Ready
For questions: See API Reference or Troubleshooting
- Stripe-Integration — Referral triggers on first $10+ purchase
- Coupon-System — Another way users earn credits
- Free-Trial-System — Referrals complement trials
Reading Path (start here, in order)
- Conceptual Model
- Stability Definition
- Conceptual Model Features
- Features
- Delta Report
- Features-Acceptance-Criteria
Testing
Security & Access
Billing
Monitoring
Features
Providers
Operations
Data References