Panel/backup-website/COUPON_SYSTEM.md

11 KiB

Coupon System Documentation

Overview

The billing module now includes a comprehensive coupon system that allows administrators to create discount codes that customers can apply to their orders. The system supports:

  • Percentage-based discounts (e.g., 10%, 25%, 50% off)
  • One-time or permanent discounts (one-time applies to first invoice only, permanent applies to all renewals)
  • Game-specific filtering (apply coupons to all games or specific games only)
  • Usage limits (optional maximum number of uses per coupon)
  • Expiration dates (optional expiry date for time-limited promotions)
  • Automatic usage tracking (system tracks how many times each coupon has been used)

Database Schema

Table: ogp_billing_coupons

The main coupon table stores all coupon definitions:

CREATE TABLE `ogp_billing_coupons` (
    `coupon_id` INT(11) NOT NULL AUTO_INCREMENT,
    `code` VARCHAR(50) NOT NULL UNIQUE,
    `name` VARCHAR(255) NOT NULL DEFAULT '',
    `description` TEXT,
    `discount_percent` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
    `usage_type` ENUM('one_time', 'permanent') NOT NULL DEFAULT 'one_time',
    `game_filter_type` ENUM('all_games', 'specific_games') NOT NULL DEFAULT 'all_games',
    `game_filter_list` TEXT COMMENT 'JSON array of game keys',
    `max_uses` INT(11) DEFAULT NULL COMMENT 'NULL for unlimited',
    `current_uses` INT(11) NOT NULL DEFAULT 0,
    `expires` DATETIME DEFAULT NULL,
    `created_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `created_by` INT(11) DEFAULT NULL,
    `is_active` TINYINT(1) NOT NULL DEFAULT 1,
    PRIMARY KEY (`coupon_id`),
    UNIQUE KEY `idx_code` (`code`)
);

Updated Tables

ogp_billing_invoices

Added columns:

  • coupon_id INT(11) - Links to the coupon used
  • discount_amount DECIMAL(10,2) - Actual discount amount applied

ogp_billing_orders

Added columns:

  • coupon_id INT(11) - Links to the coupon used (for permanent discounts)
  • discount_amount DECIMAL(10,2) - Discount amount for renewals

Installation

  1. Run the SQL migration:

    mysql -u [username] -p [database_name] < modules/billing/create_coupons_table.sql
    
  2. Verify installation:

    • Check that the ogp_billing_coupons table exists
    • Verify that coupon_id and discount_amount columns were added to both ogp_billing_invoices and ogp_billing_orders

Admin Interface

Accessing Coupon Management

  1. Log in as an administrator
  2. Navigate to /modules/billing/admin.php
  3. Click on "Manage Coupons" button
  4. Or go directly to /modules/billing/admin_coupons.php

Creating a New Coupon

  1. On the Manage Coupons page, scroll to "Add New Coupon" section

  2. Fill in the required fields:

    • Coupon Code: Unique alphanumeric code (e.g., "SUMMER2025", "WELCOME10")
    • Display Name: User-friendly name shown in admin interface
    • Description: Internal notes about the coupon
    • Discount Percentage: Number between 0-100 (e.g., 25 for 25% off)
    • Usage Type:
      • One Time: Discount applies only to the first invoice
      • Permanent: Discount applies to initial order AND all future renewals
    • Apply To:
      • All Games: Works for any game server
      • Specific Games: Works only for selected games
    • Maximum Uses: Optional limit on total uses (blank = unlimited)
    • Expiration Date: Optional expiry date (blank = never expires)
  3. Click "Add Coupon" to save

Example Coupons

Welcome Discount (One-Time, All Games)

Code: WELCOME10
Name: Welcome 10% Off
Discount: 10%
Usage Type: One Time
Apply To: All Games
Max Uses: (unlimited)
Expires: (none)

Arma Series Promotion (Permanent, Specific Games)

Code: ARMA25
Name: Arma Series 25% Off
Discount: 25%
Usage Type: Permanent
Apply To: Specific Games
  - arma2_win32
  - arma2oa_win32
  - arma3_linux32
  - arma3_linux64
  - arma3_win64
  - arma-reforger_linux64
  - arma-reforger_win64
Max Uses: 100
Expires: 2025-12-31

Editing Coupons

  1. On the Manage Coupons page, find the coupon in the list
  2. Click the "Edit" button
  3. Modify any fields (except code uniqueness is enforced)
  4. Click "Save Changes"

Deactivating Coupons

  1. Click "Edit" on the coupon
  2. Uncheck the "Active" checkbox
  3. Click "Save Changes"

Note: Deactivating prevents new uses but doesn't affect existing orders.

Deleting Coupons

  1. Find the coupon in the list
  2. Click "Delete" button
  3. Confirm the deletion

Warning: This permanently removes the coupon. Orders that used it will retain the discount but lose the coupon reference.

Customer Usage

Applying a Coupon

  1. Customer adds items to cart at /modules/billing/cart.php
  2. In the coupon section, enter coupon code in the input field
  3. Click "Apply Coupon"
  4. If valid, a success message appears showing:
    • Coupon code
    • Discount percentage
    • Whether it's one-time or permanent
  5. Cart totals update automatically with discounted prices
  6. Proceed to checkout with PayPal as normal

Coupon Validation

The system validates:

  • Code exists and is active
  • Coupon hasn't expired
  • Usage limit hasn't been reached
  • Game matches filter (if game-specific)

Error messages shown if:

  • Code is invalid or expired
  • Usage limit reached
  • Coupon doesn't apply to games in cart

Removing a Coupon

  1. On cart page, click "Remove" button next to active coupon
  2. Cart prices revert to original amounts

Coupon Behavior

One-Time Coupons

  • Applied to the initial invoice only
  • When order is renewed, renewal invoice uses original price
  • Coupon is cleared from session after first payment
  • Example: "WELCOME10" gives 10% off first month only

Permanent Coupons

  • Applied to initial invoice AND stored in order record
  • When order is renewed, the discount is automatically applied to renewal invoices
  • Coupon stays associated with the order forever
  • Example: "VIP50" gives 50% off forever for that specific server

Game Filtering

All Games

  • Coupon applies to any game server in the cart
  • All cart items receive the discount

Specific Games

  • Coupon checks each cart item's home_name field
  • Only matching games receive the discount
  • Uses partial string matching (e.g., "arma3" matches "arma3_linux64")
  • Non-matching games show original price

Example:

Cart contains:
1. Arma 3 Server → ARMA25 coupon applies (25% off)
2. Minecraft Server → ARMA25 doesn't apply (full price)
3. Arma Reforger → ARMA25 applies (25% off)

Total discount = 25% off Arma servers only

Technical Implementation

Session Storage

Coupons are stored in $_SESSION['applied_coupon'] when applied:

$_SESSION['applied_coupon'] = [
    'coupon_id' => 1,
    'code' => 'ARMA25',
    'discount_percent' => 25.00,
    'usage_type' => 'permanent',
    'game_filter_type' => 'specific_games',
    'game_filter_list' => '["arma3_linux64","arma2_win32"]',
    // ... other fields
];

Cart Calculation

In cart.php, the couponAppliesTo() function checks if a coupon applies to a specific game:

function couponAppliesTo($coupon, $game_name) {
    if (!$coupon || $coupon['game_filter_type'] === 'all_games') {
        return true;
    }
    
    if ($coupon['game_filter_type'] === 'specific_games') {
        $allowed_games = json_decode($coupon['game_filter_list'], true);
        foreach ($allowed_games as $allowed_game) {
            if (stripos($game_name, $allowed_game) !== false) {
                return true;
            }
        }
    }
    
    return false;
}

Discount calculation:

$rowtotal = $row['amount'] * $row['qty'] * $row['max_players'];

if ($applied_coupon && couponAppliesTo($applied_coupon, $row['home_name'])) {
    $discountPercent = floatval($applied_coupon['discount_percent']);
    $itemDiscount = ($rowtotal * $discountPercent) / 100;
    $rowtotal = $rowtotal - $itemDiscount;
}

Payment Processing

In api/capture_order.php, when PayPal payment completes:

  1. Coupon info is retrieved from session
  2. Invoices are updated with coupon_id
  3. Coupon usage count is incremented
  4. For one-time coupons, cleared from session
  5. For permanent coupons, stored in order record
// Update invoice with coupon
UPDATE ogp_billing_invoices 
SET status='paid', coupon_id=?, discount_amount=?
WHERE user_id=? AND status='due'

// Increment usage count
UPDATE ogp_billing_coupons 
SET current_uses = current_uses + 1 
WHERE coupon_id = ?

// For permanent coupons, store in order
INSERT INTO ogp_billing_orders (
    ..., coupon_id, discount_amount
) VALUES (
    ..., ?, ?
)

Display

Cart Page

  • Shows applied coupon with code and percentage
  • Displays success/error messages
  • Updates prices in real-time

My Servers Page

  • Shows original price (strikethrough)
  • Shows discounted price (bold)
  • Shows coupon code and percentage (green text)

Admin Invoices Page

  • Same display as My Servers
  • Visible to administrators for all orders

Troubleshooting

Coupon not applying

  • Check if code is typed correctly (case-sensitive)
  • Verify coupon is active in admin panel
  • Check expiration date hasn't passed
  • Verify usage limit hasn't been reached
  • For game-specific coupons, ensure game matches filter

Discount not showing after payment

  • Check discount_amount column exists in both tables
  • Verify coupon_id was saved to invoice/order
  • Clear browser cache and refresh page

Permanent coupon not applying to renewals

  • Verify usage_type is set to "permanent"
  • Check order record has coupon_id populated
  • Ensure renewal invoice creation copies coupon from order

Security Considerations

  1. Code uniqueness: System enforces unique coupon codes
  2. Usage tracking: Prevents abuse by tracking total uses
  3. Expiration: Automatic validation prevents expired coupon use
  4. Admin-only creation: Only admins can create/edit coupons
  5. SQL injection protection: All inputs are sanitized with mysqli_real_escape_string()
  6. CSRF protection: Admin forms include CSRF tokens

Future Enhancements

Potential features for future development:

  • Minimum purchase amount requirements
  • First-time customer restrictions
  • User-specific coupons (assign to individual users)
  • Combination rules (allow/prevent stacking)
  • Auto-generated unique codes for campaigns
  • Email notification when coupon is used
  • Analytics dashboard for coupon performance
  • Referral system integration

Support

For issues or questions:

  1. Check the troubleshooting section above
  2. Review error logs in /modules/billing/logs/
  3. Verify database schema matches documentation
  4. Contact system administrator

Last Updated: 2025-10-29 Version: 1.0 Module: Billing/Coupons