Files
cbd420/REFERRAL_POINTS_README.md
2025-12-31 07:49:35 +00:00

146 lines
5.6 KiB
Markdown

# Referral Points System
This document describes the referral points system implementation for the CBD420 platform.
## Overview
The referral points system allows:
1. **Earning Points**: Referrers earn points when their referred users make purchases
2. **Spending Points**: Buyers can use their referral points to discount purchases
3. **Configurable Rates**: Both earning and redemption rates are configurable via the `referral_settings` table
## Database Changes
### New Columns
1. **`buyers` table**: Added `referral_points` column (decimal(10,2), default 0.00) to track current point balance
2. **`sales` table**:
- Added `points_used` column (decimal(10,2), default 0.00) to track points used in the sale
- Added `price_amount` column (decimal(10,2)) to track actual amount paid
- Added `price_currency` column (varchar(10), default 'chf') to track currency
3. **`pending_orders` table**: Added `points_used` column (decimal(10,2), default 0.00) to track points used in pending orders
### New Tables
1. **`referral_point_transactions`**: Tracks all point transactions (earned/spent)
- Records when points are earned or spent
- Links to sales and pending orders
- Includes description for audit trail
2. **`referral_settings`**: Stores configurable system settings
- `points_per_chf`: Points earned per 1 CHF purchase (default: 10)
- `points_to_chf`: Points required to redeem 1 CHF discount (default: 100)
### Stored Procedures
1. **`award_referral_points(p_sale_id INT)`**:
- Awards referral points to the referrer when a sale is completed
- Calculates points based on purchase amount and `points_per_chf` setting
- Should be called after a sale is created
2. **`spend_referral_points(p_buyer_id, p_points_to_spend, p_pending_order_id, p_sale_id, OUT p_success)`**:
- Deducts points from buyer's balance
- Records the transaction
- Returns 1 if successful, 0 if insufficient points
## Configuration
The system uses two configurable multipliers stored in `referral_settings`:
- **`points_per_chf`**: Number of points earned per 1 CHF purchase (default: 10)
- Example: If set to 10, a 5 CHF purchase earns 50 points
- **`points_to_chf`**: Number of points required for 1 CHF discount (default: 100)
- Example: If set to 100, 500 points = 5 CHF discount
To update these values:
```sql
UPDATE referral_settings SET setting_value = '20' WHERE setting_key = 'points_per_chf';
UPDATE referral_settings SET setting_value = '50' WHERE setting_key = 'points_to_chf';
```
## Usage Examples
### Awarding Points After Sale Completion
When a sale is created (e.g., in your IPN/webhook handler), call:
```sql
CALL award_referral_points(@sale_id);
```
This will:
1. Check if the buyer was referred by someone
2. Calculate points based on purchase amount
3. Add points to referrer's balance
4. Record the transaction
### Spending Points During Purchase
Before creating a pending order, check available points and calculate discount:
```sql
-- Get buyer's available points
SELECT referral_points FROM buyers WHERE id = @buyer_id;
-- Calculate maximum discount (points / points_to_chf)
SELECT
b.referral_points,
CAST(rs.setting_value AS DECIMAL(10,2)) as points_to_chf,
b.referral_points / CAST(rs.setting_value AS DECIMAL(10,2)) as max_discount_chf
FROM buyers b
CROSS JOIN referral_settings rs
WHERE b.id = @buyer_id AND rs.setting_key = 'points_to_chf';
```
When creating a pending order with points:
```sql
SET @points_to_spend = 500; -- User wants to spend 500 points
SET @success = 0;
CALL spend_referral_points(@buyer_id, @points_to_spend, @pending_order_id, NULL, @success);
IF @success = 1 THEN
-- Points deducted successfully, update pending_order with points_used
UPDATE pending_orders SET points_used = @points_to_spend WHERE id = @pending_order_id;
ELSE
-- Insufficient points, handle error
SELECT 'Insufficient referral points' AS error;
END IF;
```
### Calculating Final Price After Points Discount
```sql
-- Calculate discount amount from points
SELECT
@original_price as original_price,
@points_to_spend as points_used,
CAST((SELECT setting_value FROM referral_settings WHERE setting_key = 'points_to_chf') AS DECIMAL(10,2)) as points_to_chf,
(@points_to_spend / CAST((SELECT setting_value FROM referral_settings WHERE setting_key = 'points_to_chf') AS DECIMAL(10,2))) as discount_amount,
(@original_price - (@points_to_spend / CAST((SELECT setting_value FROM referral_settings WHERE setting_key = 'points_to_chf') AS DECIMAL(10,2)))) as final_price;
```
## Implementation Notes
1. **Price Tracking**: The `sales` table now includes `price_amount` to accurately track the amount paid. When converting a pending_order to a sale, copy the `price_amount` (after points discount) to the sale.
2. **Points Calculation**: Points are awarded based on the actual amount paid (after any points discount), not the original price.
3. **Transaction History**: All point transactions are recorded in `referral_point_transactions` for audit and reporting purposes.
4. **Currency**: Currently assumes CHF as the base currency. If your system uses multiple currencies, you may need to adjust the calculation logic.
5. **Application Integration**: You'll need to:
- Call `award_referral_points()` after creating a sale (in your IPN/webhook handler)
- Handle point spending in your payment/invoice creation flow
- Display available points to users in the UI
- Allow users to select how many points to use during checkout
## Migration
For existing databases, run the `referral_points_migration.sql` file to add all the necessary tables, columns, and procedures.
For new installations, the updated `cbd420.sql` includes all referral points functionality.