# Refer a Friend

A referral program plugin that allows members to invite friends and earn coupon rewards when the referred friend signs up and places a qualifying order.

## How It Works

1. A member shares their referral link (via email or copy link) from their account page
2. The friend clicks the link and registers as a new member
3. When the friend's first qualifying order is marked as shipped, both the referrer and referee receive a coupon reward
4. Rewards appear on the member's referral page and can be used at checkout

## Setup

The service provider is already registered in `config/app.php`, but the
plugin is disabled at runtime until the env flag is set.

### 1. Enable the plugin

Add to your `.env` file:

```
REFERRALS_ENABLED=true
```

### 2. Run migrations

```sh
php artisan migrate
```

This creates three tables (`referrals`, `referral_rewards`, `referral_activity_log`) and adds the admin menu entry.

### 3. Import styles

Add to `sites/default/includes.less` (with the other plugin imports):

```less
@import '../../plugins/ReferAFriend/css/referrals.less';
```

### 4. Register Vue components

Add to `sites/default/js/main-app.js`:

```js
import referralShare from '@plugins/ReferAFriend/js/components/referral_share.vue';
Vue.component('referral-share', referralShare);

import referralRewards from '@plugins/ReferAFriend/js/components/referral_rewards.vue';
Vue.component('referral-rewards', referralRewards);
```

### 5. Rebuild frontend assets

```sh
npm run build
```

### 6. Template symlink

Ensure the template symlink exists for Twig auto-discovery:

```sh
cd plugins/ReferAFriend
ln -s src/templates templates
```

## Configuration

All settings are in `config/referrals.php`:

| Setting | Default | Description |
|---------|---------|-------------|
| `enabled` | `false` | Feature toggle (env: `REFERRALS_ENABLED`) |
| `reward_amount` | `5.00` | Coupon value for both referrer and referee |
| `max_manual_credit` | `500.00` | Max value of a manual admin credit (store base currency) |
| `min_qualifying_order` | `100.00` | Minimum order total to trigger rewards |
| `coupon_min_spend` | `100.00` | Minimum spend required to use the reward coupon |
| `coupon_expiry_days` | `365` | Days until reward coupon expires |
| `link_expiry_days` | `90` | Days until a referral link expires |
| `max_referrals_per_member` | `50` | Maximum active referrals per member |
| `coupon_prefix` | `RAF` | Prefix for generated coupon codes |
| `qualifying_status` | `4` | Order status that triggers rewards (shipped) |

### Fraud Prevention

| Setting | Default | Description |
|---------|---------|-------------|
| `fraud.max_signups_per_ip_per_day` | `5` | Max registrations from same IP per day |
| `fraud.cookie_name` | `raf_ref` | Cookie used to track referral attribution |
| `fraud.device_cookie_name` | `raf_device` | Per-device token used for cookie reuse fraud detection |
| `fraud.cookie_lifetime_days` | `90` | Cookie expiry in days |

## Routes

### Public
- `GET /refer-a-friend` — Landing page (general info)
- `GET /refer-a-friend/{code}` — Referral link handler (sets cookie/session, redirects to register)

### Member (authenticated)
- `GET /members/referrals` — Member's referral dashboard
- `POST /members/referrals/invite` — Send email invitation (AJAX)
- `POST /members/referrals/reminder` — Resend invitation reminder (AJAX)
- `GET /members/referrals/link` — Get share link (AJAX)

### Admin
- `GET /admin/referrals` — Admin dashboard with stats, filters, and export
- `GET /admin/referrals/detail/{id}` — Referral detail view
- `POST /admin/referrals/manual-credit` — Issue manual reward credit
- `POST /admin/referrals/revoke/{id}` — Revoke a reward
- `GET /admin/referrals/emails` — Email template previews
- `GET /admin/referrals/export` — CSV export of referrals

## File Structure

```
plugins/ReferAFriend/
├── config/referrals.php              # Plugin configuration
├── css/referrals.less                # Frontend styles
├── database/migrations/              # Database migrations
├── js/components/
│   ├── referral_share.vue            # Share link + email invite component
│   └── referral_rewards.vue          # Reward code reveal/copy component
├── src/
│   ├── Classes/
│   │   ├── ReferralService.php       # Core business logic
│   │   └── ReferralFraudChecker.php  # Fraud detection checks
│   ├── Http/Controllers/
│   │   ├── ReferralsController.php         # Member-facing endpoints
│   │   ├── ReferralLandingController.php   # Public landing/link handler
│   │   └── Admin/ReferralsAdminController.php  # Admin dashboard
│   ├── Models/
│   │   ├── Referral.php              # Referral record
│   │   ├── ReferralReward.php        # Reward/coupon record
│   │   └── ReferralActivityLog.php   # Audit trail
│   ├── ReferAFriendServiceProvider.php  # Laravel service provider
│   ├── routes/web.php                # Route definitions
│   └── templates/
│       ├── admin/referrals/          # Admin Twig templates
│       ├── emails/                   # Email templates
│       └── referrals/                # Member-facing templates
└── templates -> src/templates        # Symlink for Twig auto-discovery
```

## Integration Points

The plugin hooks into the existing platform at these points:

- **Member registration** — `ReferralService::processNewMember()` links the new member to their referral
- **Order shipped** — `ReferralService::processShippedOrder()` triggers reward issuance
- **Order cancellation** — `ReferralService::handleOrderCancellation()` revokes pending/issued rewards
- **Coupon system** — Rewards are issued as standard platform coupons via `Coupon::generateCoupon()`
