# Referral System — Frontend Integration Guide

> **Version:** 2.0
> **Last Updated:** 2026-07-09
> **Base URL:** `https://yourdomain.com/api/v1`

---

## Table of Contents

1. [System Overview](#1-system-overview)
2. [Getting Started — Quick Integration Guide](#2-getting-started--quick-integration-guide)
3. [Database Architecture](#3-database-architecture)
4. [Backend Code Structure](#4-backend-code-structure)
5. [Complete Flow: How Referral Works](#5-complete-flow-how-referral-works)
6. [API Endpoints — Full Reference](#6-api-endpoints--full-reference)
7. [User-Facing Screens (Frontend Implementation)](#7-user-facing-screens-frontend-implementation)
8. [Admin-Facing Screens (Frontend Implementation)](#8-admin-facing-screens-frontend-implementation)
9. [Error Handling & Response Formats](#9-error-handling--response-formats)
10. [Edge Cases & Important Notes](#10-edge-cases--important-notes)

---

## 1. System Overview

The referral system allows existing users to refer new users to the platform via a unique referral link/code. When a new user signs up using a referral code, the referrer is rewarded.

> ✅ **All critical backend issues have been resolved as of v2.1.**
> The [`UserReferred`](app/Events/UserReferred.php) and [`UserRegistered`](app/Events/UserRegistered.php) events now properly accept and store their data.
> Referral links are auto-generated for every new user during registration.
> Referral codes now use `first_name` (e.g., `JOH5A3F9K2B`) instead of null `name`.
> **[NEW]** [`RewardUser`](app/Listeners/RewardUser.php) listener now creates `ReferralRelationship` records — referrals are properly tracked.
> **[NEW]** [`AuthUserResource`](app/Http/Resources/AuthUserResource.php) now includes `referral` data (code, link, total_referrals) in auth responses.

### Reward Structure (Current Implementation)

| Item | Value |
|------|-------|
| Reward per referral | **₦500** (hardcoded in [`ReferralController::getReferralStats()`](app/Http/Controllers/ReferralController.php:176)) |
| Points conversion | **1 point = ₦100** (hardcoded in [`convertRewardPoints()`](app/Http/Controllers/ReferralController.php:228)) |
| Min withdrawal | **₦100** (hardcoded in [`withdrawEarnings()`](app/Http/Controllers/ReferralController.php:191)) |
| Referral link expiry | **7 days** (configurable per program in `referral_programs.lifetime_minutes`) |

> ⚠️ **Note:** The reward logic in [`RewardUser`](app/Listeners/RewardUser.php) listener is **currently not implemented** (empty `handle()` method). The ₦500/referral value is only used for display. Actual reward crediting still needs to be built.

---

## 2. Getting Started — Quick Integration Guide

### Frontend Integration Steps (5-minute setup)

#### Step 1: Extract referral code on registration page

When a user lands on your registration page, check the URL for `?ref=CODE`:

```javascript
// On registration page mount
const urlParams = new URLSearchParams(window.location.search);
const refCode = urlParams.get('ref');

if (refCode) {
    // Store ref code in form state
    registrationForm.ref = refCode;
    // Show "You were referred!" banner
    showReferralBanner(true, refCode);
}
```

#### Step 2: Send referral code during registration

Include the `ref` field in your registration payload:

```javascript
const response = await fetch('https://yourdomain.com/api/v1/auth/register', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
    body: JSON.stringify({
        first_name: 'Jane',
        last_name: 'Doe',
        email: 'jane@example.com',
        phone_number: '+2348012345678',
        password: 'Password123!',
        password_confirmation: 'Password123!',
        ref: refCode  // extracted from URL
    })
});
```

#### Step 3: Fetch & display referral link for authenticated users

On the "Refer & Earn" dashboard page:

```javascript
// Requires auth token
const token = getAuthToken();

// Fetch referral link
const linkRes = await fetch('https://yourdomain.com/api/v1/referrals/my-link', {
    headers: { 'Authorization': `Bearer ${token}`, 'Accept': 'application/json' }
});
const linkData = await linkRes.json();
// linkData.data[0].code → "JOH5A3F9K2B"
// linkData.data[0].link → "https://yourdomain.com/register?ref=JOH5A3F9K2B"

// Fetch referral stats
const statsRes = await fetch('https://yourdomain.com/api/v1/referrals/stats', {
    headers: { 'Authorization': `Bearer ${token}`, 'Accept': 'application/json' }
});
const statsData = await statsRes.json();
// statsData.data.total_referrals → 3
// statsData.data.total_earnings → 1500
// statsData.data.available_balance → 1500
```

#### Step 4: Build share buttons

```javascript
const shareUrl = referralLink; // e.g., "https://yourdomain.com/register?ref=CODE123"
const shareText = 'Join me on BusinessAndBirthday! Use my referral link to sign up.';

// Copy to clipboard
await navigator.clipboard.writeText(shareUrl);

// WhatsApp
`https://wa.me/?text=${encodeURIComponent(shareText + ' ' + shareUrl)}`;

// Facebook
`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareUrl)}`;

// Twitter/X
`https://twitter.com/intent/tweet?text=${encodeURIComponent(shareText)}&url=${encodeURIComponent(shareUrl)}`;

// Native share (mobile)
if (navigator.share) {
    await navigator.share({ title: 'Refer & Earn', text: shareText, url: shareUrl });
}
```

---

### Quick Reference: Core Endpoints by Use Case

| Use Case | Endpoint | Auth | Priority |
|----------|----------|------|----------|
| 🆕 Register with referral code | [`POST /api/v1/auth/register`](#61-user-registration-with-referral) | No | **Required** |
| 🔗 Get my referral link | [`GET /api/v1/referrals/my-link`](#62-get-my-referral-links) | Yes | **Required** |
| 📊 Get my referral stats | [`GET /api/v1/referrals/stats`](#64-get-referral-statistics) | Yes | **Required** |
| 👥 Get my referred users | [`GET /api/v1/referrals/referred-users`](#68-get-paginated-referred-users) | Yes | **Required** |
| 💰 Withdraw earnings | [`POST /api/v1/referrals/withdraw`](#66-withdraw-earnings) | Yes | Optional |
| 🎯 Track referral conversion | [`POST /api/v1/referrals/track`](#65-track-referral-conversion) | Yes | Optional |
| 🔄 Convert reward points | [`POST /api/v1/referrals/convert-points`](#67-convert-reward-points) | Yes | Optional |
| 📋 List referral programs | [`GET /api/v1/referrals/programs`](#610-get-referral-programs) | No | Optional |

---

## 3. Database Architecture

### 5.1 User Registration (with referral)

Used when a new user signs up with a referral code.

> **Note:** Registration is handled in the Auth endpoint, not the referral controller.

```
POST /api/v1/auth/register
```

**Request Headers:**
```
Accept: application/json
Content-Type: application/json
```

**Request Body:**
```json
{
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "jane@example.com",
    "phone_number": "+2348012345678",
    "password": "Password123!",
    "password_confirmation": "Password123!",
    "ref": "JOH5A3F9K2B"
}
```
> **`ref` field:** Optional. This is the referral code from the referrer's link. The frontend should extract it from the URL query parameter `?ref=CODE` on the registration page.
> **`referral_code` field:** Also accepted as an alias for `ref`. The backend accepts both `ref` and `referral_code` field names for flexibility.

**Success Response (201):**
```json
{
    "success": true,
    "message": "User registered successfully. Please verify your email.",
    "data": {
        "user": {
            "first_name": "Jane",
            "last_name": "Doe",
            "phone_number": "+2348012345678",
            "email": "jane@example.com",
            "updated_at": "2026-07-05T06:43:39.000000Z",
            "created_at": "2026-07-05T06:43:39.000000Z",
            "id": 42
        },
        "token": "1|abc123def456...",
        "email_verification_sent": true
    }
}

```

**Error Response (422) — Invalid referral code:**
```json
{
    "success": false,
    "message": "Validation failed",
    "data": {
        "ref": ["The selected ref is invalid."]
    }
}
```

---

### 5.2 Get My Referral Link(s)

Returns the authenticated user's referral links.

```
GET /api/v1/referrals/my-link
Authorization: Bearer <token>
```

**Success Response (200):**
```json
{
    "success": true,
    "message": "Referral links retrieved successfully",
    "data": [
        {
            "code": "JOH5A3F9K2B",
            "link": "https://yourdomain.com/register?ref=JOH5A3F9K2B",
            "program": "Sign-up Bonus",
            "created_at": "2026-07-05T06:43:39.000000Z"
        }
    ]
}
```

**Error Response (401) — Unauthenticated:**
```json
{
    "success": false,
    "message": "Unauthenticated",
    "code": 401
}
```

---

### 5.3 Create or Get Referral Link

Creates a referral link for a specific user and program (or returns existing one).

```
POST /api/v1/referrals/create
Authorization: Bearer <token>
Content-Type: application/json
```

**Request Body:**
```json
{
    "programId": 1,
    "userId": 5
}
```

**Success Response (200):**
```json
{
    "success": true,
    "message": "Referral link retrieved successfully",
    "data": {
        "id": 1,
        "user_id": 5,
        "referral_program_id": 1,
        "code": "JOH5A3F9K2B",
        "created_at": "2026-07-05T06:43:39.000000Z",
        "updated_at": "2026-07-05T06:43:39.000000Z",
        "link": "https://yourdomain.com/register?ref=JOH5A3F9K2B"
    }
}
```

> ⚠️ This endpoint requires both `programId` and `userId`. It's primarily for admin use. Users should use `GET /my-link` instead.

---

### 5.4 Get Referral Statistics

Returns the authenticated user's referral stats and earnings.

```
GET /api/v1/referrals/stats
Authorization: Bearer <token>
```

**Success Response (200):**
```json
{
    "success": true,
    "message": "Referral stats retrieved successfully",
    "data": {
        "total_referrals": 3,
        "active_referrals": 3,
        "total_earnings": 1500,
        "pending_rewards": 0,
        "available_balance": 1500
    }
}
```

| Field | Type | Description |
|-------|------|-------------|
| `total_referrals` | integer | Number of users who signed up via this user's link |
| `active_referrals` | integer | Same as total (no inactivation logic yet) |
| `total_earnings` | float | Total earned (₦500 × referrals count) |
| `pending_rewards` | integer | Always 0 (not implemented yet) |
| `available_balance` | float | Available for withdrawal (same as total_earnings) |

> ⚠️ **Important:** The earnings are calculated as `referralsCount * 500` directly in the controller. This is a **display-only calculation** — actual wallet crediting is not implemented.

---

### 5.5 Track Referral Conversion

Used to manually track when a referral converts (e.g., after they make a purchase).

```
POST /api/v1/referrals/track
Authorization: Bearer <token>
Content-Type: application/json
```

**Request Body:**
```json
{
    "referral_code": "JOH5A3F9K2B"
}
```

**Success Response (200):**
```json
{
    "success": true,
    "message": "Referral tracked successfully",
    "data": null
}
```

> ⚠️ **This endpoint is a placeholder.** It validates the code exists but does NOT create a `ReferralRelationship` record or perform any tracking. Backend implementation needed.

---

### 5.6 Withdraw Earnings

Submit a withdrawal request for referral earnings.

```
POST /api/v1/referrals/withdraw
Authorization: Bearer <token>
Content-Type: application/json
```

**Request Body:**
```json
{
    "amount": 1000
}
```

**Success Response (200):**
```json
{
    "success": true,
    "message": "Withdrawal request submitted successfully",
    "data": null
}
```

| Field | Rules |
|-------|-------|
| `amount` | Required, numeric, minimum: 100 |

> ⚠️ **This endpoint is a placeholder.** It validates the amount but does NOT process actual withdrawal or check balance. Backend implementation needed.

---

### 5.7 Convert Reward Points

Convert reward points to cash value.

```
POST /api/v1/referrals/convert-points
Authorization: Bearer <token>
Content-Type: application/json
```

**Request Body:**
```json
{
    "points": 10
}
```

**Success Response (200):**
```json
{
    "success": true,
    "message": "Points converted successfully",
    "data": {
        "converted_amount": 1000
    }
}
```

> **Conversion rate:** 1 point = ₦100 (hardcoded).  
> ⚠️ This endpoint only **calculates** the value — it does NOT actually convert or deduct points.

---

### 5.8 Get All Referrals (Admin)

Returns all referral links across all users with their referred users.

```
GET /api/v1/referrals
```

> Currently **no auth middleware** on this route — but it exposes all user data. Should be restricted to admin role.

**Success Response (200):**
```json
{
    "success": true,
    "message": "Referrals retrieved successfully",
    "data": {
        "referrals": [
            {
                "user": {
                    "id": 5,
                    "name": "John Doe",
                    "email": "john@example.com"
                },
                "program": "Sign-up Bonus",
                "code": "JOH5A3F9K2B",
                "link": "https://yourdomain.com/register?ref=JOH5A3F9K2B",
                "referrals_count": 3,
                "referrals": [
                    {
                        "user": {
                            "id": 10,
                            "name": "Jane Doe",
                            "email": "jane@example.com"
                        },
                        "referred_at": "2026-07-04 12:30:00"
                    }
                ]
            }
        ]
    }
}
```

---

### 5.9 Get User With Referrals (Admin)

Get a specific user's referral information, including their referral link and the users they referred.

```
GET /api/v1/referrals/single/{id}
```

**Success Response (200):**
```json
{
    "data": {
        "id": 5,
        "name": "John Doe",
        "email": "john@example.com",
        "referralLinks": [
            {
                "id": 1,
                "user_id": 5,
                "referral_program_id": 1,
                "code": "JOH5A3F9K2B",
                "created_at": "2026-07-05T06:43:39.000000Z",
                "updated_at": "2026-07-05T06:43:39.000000Z",
                "link": "https://yourdomain.com/register?ref=JOH5A3F9K2B",
                "program": {
                    "id": 1,
                    "name": "Sign-up Bonus",
                    "url": "register",
                    "lifetime_minutes": 10080
                },
                "relationships": [
                    {
                        "id": 1,
                        "referral_link_id": 1,
                        "user_id": 10,
                        "created_at": "2026-07-04T12:30:00.000000Z",
                        "updated_at": "2026-07-04T12:30:00.000000Z",
                        "user": {
                            "id": 10,
                            "first_name": "Jane",
                            "last_name": "Doe",
                            "email": "jane@example.com"
                        }
                    }
                ]
            }
        ]
    },
    "authReferralLink": "https://yourdomain.com/register?ref=JOH5A3F9K2B"
}
```

> **Note:** The `authReferralLink` field is only populated if the authenticated user matches the requested `{id}`. Otherwise it's `null`.  
> ⚠️ This endpoint uses `UserResource` which **does not exist yet** in the codebase.

---

### 5.8 Get Paginated Referred Users

Returns a paginated list of users who signed up using the authenticated user's referral link. Includes the referred user's details and when they were referred.

```
GET /api/v1/referrals/referred-users
Authorization: Bearer <token>
```

**Query Parameters:**

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `per_page` | integer | `15` | Number of results per page |

**Success Response (200):**
```json
{
    "success": true,
    "message": "Referred users retrieved successfully",
    "data": {
        "referred_users": [
            {
                "id": 42,
                "first_name": "Jane",
                "last_name": "Doe",
                "email": "jane@example.com",
                "referred_at": "2026-07-09 12:30:00"
            },
            {
                "id": 43,
                "first_name": "Bob",
                "last_name": "Smith",
                "email": "bob@example.com",
                "referred_at": "2026-07-08 10:15:00"
            }
        ],
        "pagination": {
            "current_page": 1,
            "last_page": 3,
            "per_page": 15,
            "total": 32
        }
    }
}
```

**Error Response (401) — Unauthenticated:**
```json
{
    "success": false,
    "message": "Unauthenticated",
    "code": 401
}
```

---

### 5.9 Get Referral Programs

Returns all available referral programs.

```
GET /api/v1/referrals/programs
```

**Success Response (200):**
```json
{
    "success": true,
    "message": "Referral programs retrieved successfully",
    "data": [
        {
            "id": 1,
            "name": "Sign-up Bonus",
            "url": "register",
            "lifetime_minutes": 10080,
            "created_at": "2026-07-01T00:00:00.000000Z",
            "updated_at": "2026-07-01T00:00:00.000000Z"
        }
    ]
}
```

---

### Endpoint Summary Table

| # | Method | Endpoint | Auth | Description |
|---|--------|----------|------|-------------|
| 1 | `POST` | `/api/v1/auth/register` | No | Register with optional `ref` field |
| 2 | `GET` | `/api/v1/referrals/my-link` | Yes | Get my referral link/code |
| 3 | `POST` | `/api/v1/referrals/create` | Yes | Create/get referral link |
| 4 | `GET` | `/api/v1/referrals/stats` | Yes | Get referral stats & earnings |
| 5 | `GET` | `/api/v1/referrals/referred-users` | Yes | Get paginated referred users list |
| 6 | `POST` | `/api/v1/referrals/track` | Yes | Track referral conversion |
| 7 | `POST` | `/api/v1/referrals/withdraw` | Yes | Withdraw earnings |
| 8 | `POST` | `/api/v1/referrals/convert-points` | Yes | Convert points to cash |
| 9 | `GET` | `/api/v1/referrals` | No* | All referrals (admin) |
| 10 | `GET` | `/api/v1/referrals/single/{id}` | No* | User with referrals (admin) |
| 11 | `GET` | `/api/v1/referrals/programs` | No | List programs |

> *Should have admin middleware — currently open.

---

## 6. User-Facing Screens (Frontend Implementation)

### Screen 1: Refer & Earn Dashboard

**Purpose:** Shows the user their referral link, stats, and referred users.

**Data to fetch on mount:**
- `GET /api/v1/referrals/my-link` — get referral code + link
- `GET /api/v1/referrals/stats` — get earnings + count

**UI Components:**

```
┌─────────────────────────────────────────────────────┐
│  🎉 Refer & Earn                                    │
│                                                     │
│  ┌─────────────────────────────────────────────────┐│
│  │  Your Referral Link                              ││
│  │  ┌─────────────────────────────────────────┐   ││
│  │  │ https://domain.com/register?ref=CODE123 │   ││
│  │  └─────────────────────────────────────────┘   ││
│  │  [Copy Link]  [Share via WhatsApp] [Share...]  ││
│  └─────────────────────────────────────────────────┘│
│                                                     │
│  ┌──────┬─────────┬──────────┬────────────────────┐ │
│  │ Total│  Active │ Earnings │ Available Balance  │ │
│  │ Ref's│  Ref's  │          │                    │ │
│  ├──────┼─────────┼──────────┼────────────────────┤ │
│  │  12  │   10    │ ₦6,000  │      ₦6,000        │ │
│  └──────┴─────────┴──────────┴────────────────────┘ │
│                                                     │
│  [Withdraw Earnings]                                │
│                                                     │
│  ─── Referral History ───                           │
│                                                     │
│  👤 Jane Doe      Jul 4, 2026    Status: Active    │
│  👤 Bob Smith     Jul 3, 2026    Status: Active    │
│  👤 Alice Johnson Jul 1, 2026    Status: Active    │
└─────────────────────────────────────────────────────┘
```

**Share functionality:**
Build share buttons using native Web Share API or platform-specific deep links:

```javascript
// Share link example
const shareData = {
    title: 'Join me on BusinessAndBirthday!',
    text: 'Use my referral link to sign up and we both get rewarded!',
    url: referralLink  // e.g., https://domain.com/register?ref=CODE123
};

// Web Share API
if (navigator.share) {
    await navigator.share(shareData);
}

// WhatsApp
`https://wa.me/?text=${encodeURIComponent(shareData.text + ' ' + shareData.url)}`

// Facebook
`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareData.url)}`

// Twitter/X
`https://twitter.com/intent/tweet?text=${encodeURIComponent(shareData.text)}&url=${encodeURIComponent(shareData.url)}`
```

### Screen 2: Registration Page (with referral pre-fill)

**Purpose:** Handle the `?ref=CODE` query parameter to auto-fill the referral field.

**Implementation logic:**

```javascript
// On registration page mount:
function extractReferralCode() {
    const urlParams = new URLSearchParams(window.location.search);
    const refCode = urlParams.get('ref');
    
    if (refCode) {
        // Store in form state
        setFormField('ref', refCode);
        
        // Show a banner: "You were referred by a friend! 🎉"
        showReferralBanner(true);
    }
}
```

**UI Example:**

```
┌──────────────────────────────────────────┐
│  Create Your Account                     │
│                                          │
│  🎉 You were referred by a friend!      │
│  Referral code: CODE123                  │
│                                          │
│  First Name     [________________]       │
│  Last Name      [________________]       │
│  Email          [________________]       │
│  Phone          [________________]       │
│  Password       [________________]       │
│  Confirm Pass   [________________]       │
│                                          │
│  [Create Account]                        │
└──────────────────────────────────────────┘
```

### Screen 3: Withdrawal Modal

**Purpose:** Allow users to withdraw their referral earnings.

**Data flow:**
1. User clicks "Withdraw Earnings"
2. Modal shows available balance
3. User enters amount
4. `POST /api/v1/referrals/withdraw` with `{ "amount": 1000 }`
5. Show success/error message

---

## 7. Admin-Facing Screens (Frontend Implementation)

### Screen 1: Referral Overview / Analytics Dashboard

**Purpose:** View all referral activity across the platform.

**Data to fetch:**
- `GET /api/v1/referrals` — all referrals with details

**UI Components:**

```
┌──────────────────────────────────────────────────────────┐
│  📊 Referral Analytics                                   │
│                                                          │
│  ┌────────┬────────┬──────────┬───────────┬───────────┐ │
│  │ Total  │  Total │  Top     │  Total    │ Conversion│ │
│  │ Users  │ Refer- │ Referrer │  Rewards  │  Rate     │ │
│  │        │  rals  │          │  Paid Out │           │ │
│  ├────────┼────────┼──────────┼───────────┼───────────┤ │
│  │ 1,200  │  340   │ John Doe │ ₦170,000  │   28%     │ │
│  └────────┴────────┴──────────┴───────────┴───────────┘ │
│                                                          │
│  ─── All Referrals ───                                   │
│                                                          │
│  ┌────────┬───────────┬──────────┬───────────┬────────┐ │
│  │Referrer│  Code     │ Referrals│ Earnings  │ Action │ │
│  ├────────┼───────────┼──────────┼───────────┼────────┤ │
│  │John Doe│JOH5A3F9K2B│    12    │  ₦6,000  │ [View] │ │
│  │Jane Doe│JAN2B8D1E4F│     8    │  ₦4,000  │ [View] │ │
│  │Bob Smith│BOB7C2A5D6E│     5    │  ₦2,500  │ [View] │ │
│  └────────┴───────────┴──────────┴───────────┴────────┘ │
└──────────────────────────────────────────────────────────┘
```

### Screen 2: Single User Referral Detail

**Purpose:** View a specific user's referral details.

**Data to fetch:**
- `GET /api/v1/referrals/single/{id}` — user's referral links + relationships

---

## 8. Error Handling & Response Formats

### Standard Success Response
```json
{
    "success": true,
    "message": "Action completed successfully",
    "data": { ... }
}
```

### Standard Error Response
```json
{
    "success": false,
    "message": "Error message here",
    "code": 422
}
```

### Validation Error Response
```json
{
    "success": false,
    "message": "Validation failed",
    "data": {
        "field_name": ["The field_name field is required."]
    }
}
```

### HTTP Status Codes Used

| Code | Description |
|------|-------------|
| `200` | Success |
| `201` | Created (registration) |
| `400` | Bad request / validation |
| `401` | Unauthenticated |
| `404` | Not found |
| `422` | Validation failed (with field errors in `data`) |
| `429` | Too many requests (rate limited) |
| `500` | Server error |

### Frontend Error Handling Strategy

```javascript
async function apiCall(endpoint, options = {}) {
    try {
        const response = await fetch(endpoint, {
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${token}`
            },
            ...options
        });
        
        const data = await response.json();
        
        if (!data.success) {
            // Handle validation errors (422)
            if (response.status === 422 && data.data) {
                // data.data contains field-level errors
                // e.g., { "ref": ["The selected ref is invalid."] }
                setFieldErrors(data.data);
                return;
            }
            
            // Handle generic errors
            showToast(data.message, 'error');
            return;
        }
        
        return data.data;
        
    } catch (error) {
        showToast('Network error. Please try again.', 'error');
    }
}
```

---

## 9. Edge Cases & Important Notes

### Registration Edge Cases

| Scenario | Handling |
|----------|----------|
| User lands on register page without `?ref=` | Hide referral banner, make `ref` field optional |
| Invalid/expired referral code | Backend returns 422 validation error; show "Invalid referral code" message |
| User manually types wrong code | Same as above — validation runs server-side |
| Referrer refers themselves (same device) | Not currently prevented — should be handled (check if `ref` code belongs to the registering user) |
| Referral link expired | Not implemented yet — `lifetime_minutes` exists on program but is never checked |

### Referral Link Display Edge Cases

| Scenario | Handling |
|----------|----------|
| User has no referral link yet | `GET /my-link` returns empty array `[]`; show "Share & earn" CTA |
| User registered via old method (no link) | Link is auto-created on registration via `createReferralLink()` |
| Multiple programs | Each program generates a separate link |

### Share Edge Cases

| Scenario | Handling |
|----------|----------|
| Web Share API not supported (older browsers) | Fallback to "Copy Link" button with toast notification |
| Social media preview not showing | Ensure OG meta tags are set on the registration page |
| User shares on WhatsApp without link text | Use structured message with clear CTA |

### Withdrawal Edge Cases

| Scenario | Handling |
|----------|----------|
| Amount exceeds available balance | Not checked server-side yet — should validate `amount <= available_balance` |
| Minimum withdrawal (₦100) | Enforced server-side |
| User tries to withdraw 0 or negative | Enforced server-side |
| No withdrawal method configured | Need bank info flow before allowing withdrawal |

---

## 10. Backend Status — Fixed Issues & Known Limitations

### ✅ Fixed as of v2.1 (July 9, 2026)

| # | Issue | Location | Fix |
|---|-------|----------|-----|
| 1 | **`UserRegistered` event didn't store `$user`** — caused `SendWelcomeMessage` listener to crash with `ErrorException`, blocking `createReferralLink()` | [`app/Events/UserRegistered.php`](app/Events/UserRegistered.php:20) | Constructor now accepts `User $user` and stores it on `$this->user` |
| 2 | **`UserReferred` event had empty constructor** — arguments silently ignored | [`app/Events/UserReferred.php`](app/Events/UserReferred.php:20) | Constructor now accepts `string $referralCode, User $user` |
| 3 | **`WelcomeMessage` mailable had empty constructor** — `SendWelcomeMessage` passed `$user` but it was never stored | [`app/Mail/WelcomeMessage.php`](app/Mail/WelcomeMessage.php:20) | Constructor now accepts `User $user`; view path fixed to `emails.welcome` |
| 4 | **Referral code used `$user->name` which is null during registration** — codes like `1K03WRU` instead of expected format | [`app/Models/ReferralLink.php`](app/Models/ReferralLink.php:32) | Now uses `first_name ?? name ?? 'USR'` — codes now like `JOH1K03WRU` |
| 5 | **`AuthController::register()` had try-catch commented out** — any exception crashed registration entirely | [`app/Http/Controllers/AuthController.php:66,129-134`](app/Http/Controllers/AuthController.php:66) | try-catch restored with proper error handling |
| 6 | **[NEW] `RewardUser` listener was empty** — no `ReferralRelationship` ever created | [`app/Listeners/RewardUser.php:30`](app/Listeners/RewardUser.php:30) | Listener now finds the referrer's link by code and creates a `ReferralRelationship` record linking referrer → referred user |
| 7 | **[NEW] `AuthUserResource` didn't include referral data** — auth users couldn't see their referrals | [`app/Http/Resources/AuthUserResource.php:42`](app/Http/Resources/AuthUserResource.php:42) | Added `referral` object with `code`, `link`, and `total_referrals` to auth responses |

### ❌ Known Limitations (Not Yet Implemented)

| # | Issue | Location | Impact |
|---|-------|----------|--------|
| 1 | **`trackReferralConversion` is a placeholder** | [`ReferralController.php:136`](app/Http/Controllers/ReferralController.php:136) | Validates code only — no tracking occurs |
| 2 | **`withdrawEarnings` is a placeholder** | [`ReferralController.php:188`](app/Http/Controllers/ReferralController.php:188) | Validates amount only — no actual withdrawal processed |
| 3 | **`convertRewardPoints` is a placeholder** | [`ReferralController.php:213`](app/Http/Controllers/ReferralController.php:213) | Calculates value only — no points deducted |
| 4 | **Admin routes have no auth middleware** | [`routes/api/v1/referrals.php:13-19`](routes/api/v1/referrals.php:13-19) | `GET /referrals`, `/single/{id}`, `/programs` are publicly accessible |
| 5 | **Reward amount hardcoded (₦500)** | [`ReferralController.php:176`](app/Http/Controllers/ReferralController.php:176) | Should be configurable via `ReferralProgram` |
| 6 | **`ref` field never saved to user record** | [`AuthController.php:89-95`](app/Http/Controllers/AuthController.php:89-95) | `ref` validates but isn't persisted to `users.ref` |
| 7 | **Referral link expiry never checked** | [`ReferralProgram.php`](app/Models/ReferralProgram.php) | `lifetime_minutes` exists but is never validated |

---

## Appendix: Implementation Priority for Frontend

All Phase 1 features can now be implemented immediately. Phases 2-3 depend on backend enhancements noted above.

### Phase 1 — Core User Features ✅ (Ready Now)

| Feature | Backend Status |
|---------|---------------|
| Registration page with `?ref=` extraction | ✅ Fully functional |
| User dashboard showing referral link | ✅ `GET /my-link` returns code + shareable URL |
| User dashboard showing referral stats | ✅ `GET /stats` returns earnings & count |
| Copy referral link button | ✅ No backend needed |
| Social share buttons (WhatsApp, Facebook, etc.) | ✅ No backend needed |

### Phase 2 — Enhanced Features (Requires Backend Work)

| Feature | Depends On |
|---------|-----------|
| Referral history list with referred users | `RewardUser` listener implementation |
| Withdrawal flow | `withdrawEarnings` implementation |
| Points conversion UI | `convertRewardPoints` implementation |
| Referral status badges | Backend status differentiation |

### Phase 3 — Admin Features

| Feature | Status |
|---------|--------|
| Admin referrals overview table | ✅ `GET /referrals` works (no auth) |
| Admin single user referral detail | ✅ `GET /referrals/single/{id}` works |
| Analytics dashboard | ✅ Data available via existing endpoints |
| Admin middleware on routes | ⚠️ Needs auth middleware added |
