moved website outside of panel folder
This commit is contained in:
parent
92ac778956
commit
08f07dca97
10328 changed files with 90 additions and 501 deletions
133
Website/INVOICE_SYSTEM.md
Normal file
133
Website/INVOICE_SYSTEM.md
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
# Billing System - Invoice-Based Architecture
|
||||
|
||||
## Overview
|
||||
The billing system now uses a **dual-table architecture** separating orders (ongoing services) from invoices (payment records).
|
||||
|
||||
## Database Tables
|
||||
|
||||
### 1. `ogp_billing_services`
|
||||
**Purpose:** Available game server packages/products
|
||||
**Key Fields:**
|
||||
- `service_id` - Unique identifier
|
||||
- `service_name` - Display name
|
||||
- `remote_server_id` - Target server(s)
|
||||
- `price_monthly`, `price_year` - Pricing tiers
|
||||
- `enabled` - Availability flag
|
||||
|
||||
### 2. `ogp_billing_orders` (formerly just cart items)
|
||||
**Purpose:** Active game server instances (ongoing services)
|
||||
**Key Fields:**
|
||||
- `order_id` - Unique identifier
|
||||
- `user_id` - Owner
|
||||
- `service_id` - Product reference
|
||||
- `home_id` - Panel game home ID (after provisioning)
|
||||
- `home_name` - Server name
|
||||
- `status` - Current state (see Status Flow below)
|
||||
- `order_date` - When created
|
||||
- `end_date` - Expiration date
|
||||
- `payment_txid` - Last payment transaction
|
||||
- `paid_ts` - Last payment timestamp
|
||||
|
||||
**Status Values:**
|
||||
- `in-cart` - User added to cart, not yet paid
|
||||
- `paid` - Payment received, awaiting provisioning
|
||||
- `installed` - ✅ Server provisioned and running
|
||||
- `suspended` - Server stopped due to non-payment
|
||||
- `expired` - Service ended
|
||||
- `renew` - Renewal pending in cart
|
||||
|
||||
### 3. `ogp_billing_invoices` (NEW)
|
||||
**Purpose:** Payment records (one invoice per payment)
|
||||
**Key Fields:**
|
||||
- `invoice_id` - Unique identifier
|
||||
- `order_id` - Links to the server order
|
||||
- `user_id` - Customer
|
||||
- `customer_name` - Full name
|
||||
- `customer_email` - Email address
|
||||
- `amount` - Total due
|
||||
- `currency` - USD, EUR, etc.
|
||||
- `status` - `unpaid` or `paid`
|
||||
- `invoice_date` - When created
|
||||
- `due_date` - Payment deadline
|
||||
- `paid_date` - When paid
|
||||
- `payment_txid` - PayPal/Stripe transaction ID
|
||||
- `payment_method` - PayPal, Stripe, etc.
|
||||
- `description` - Invoice line items
|
||||
- `invoice_duration` - Billing period (month/year)
|
||||
- `qty` - Quantity/duration multiplier
|
||||
|
||||
## Workflow
|
||||
|
||||
### Initial Purchase
|
||||
1. User selects game server package → Creates row in `billing_orders` (status: `in-cart`)
|
||||
2. System creates `billing_invoices` entry (status: `unpaid`, linked to order_id)
|
||||
3. Cart page shows unpaid invoices
|
||||
4. User pays → Invoice status becomes `paid`, order status becomes `paid`
|
||||
5. Provisioning happens → Order status becomes `installed`
|
||||
6. Server is active until `end_date`
|
||||
|
||||
### Renewal Process
|
||||
1. User clicks "Renew" on active server (My Account page)
|
||||
2. System creates NEW invoice in `billing_invoices` (status: `unpaid`, same order_id)
|
||||
3. Cart shows the unpaid renewal invoice
|
||||
4. User pays → Invoice status becomes `paid`
|
||||
5. Order `end_date` is extended by the renewal period
|
||||
|
||||
### Cron Automation (`cron-shop.php`)
|
||||
The cron job checks invoice status to manage servers:
|
||||
|
||||
**7 days before expiration:**
|
||||
- Check if order has unpaid invoice for upcoming period
|
||||
- If NO unpaid invoice exists → Create one (status: `unpaid`)
|
||||
- Email customer about upcoming renewal
|
||||
|
||||
**On expiration (end_date reached):**
|
||||
- Check if order has unpaid invoice
|
||||
- If YES → Suspend server (stop, disable FTP, unassign from user)
|
||||
- Order status → `suspended`
|
||||
|
||||
**7 days after suspension:**
|
||||
- If still unpaid → Delete server permanently
|
||||
- Order status → `expired`
|
||||
|
||||
## Key Advantages
|
||||
|
||||
1. **Clear Payment History:** Each invoice represents one payment
|
||||
2. **Audit Trail:** Can track when/how much each renewal cost
|
||||
3. **Flexible Pricing:** Can adjust price per renewal (discounts, promotions)
|
||||
4. **Multi-Payment Support:** One order can have many invoices
|
||||
5. **Accurate Status:** Order status reflects server state, invoice status reflects payment
|
||||
6. **No Race Conditions:** Webhook updates invoice, provisioning updates order
|
||||
|
||||
## Cart Logic
|
||||
|
||||
**Cart page displays:**
|
||||
- All invoices with `status = 'unpaid'` for the current user
|
||||
- Groups by order_id to show which server each invoice is for
|
||||
- Total amount = SUM of all unpaid invoice amounts
|
||||
|
||||
**After payment:**
|
||||
- Invoice `status` → `paid`
|
||||
- Invoice `paid_date` → NOW()
|
||||
- Invoice `payment_txid` → transaction ID from PayPal/Stripe
|
||||
- Order `status` → `paid` (if new order) or `end_date` extended (if renewal)
|
||||
|
||||
## My Account Logic
|
||||
|
||||
**Show Invoices Section:**
|
||||
- Group invoices by status (unpaid, paid, overdue)
|
||||
- Display invoice_date, amount, status
|
||||
- Link to view invoice details
|
||||
|
||||
**Show Current Servers Section:**
|
||||
- Display orders with `status = 'installed'`
|
||||
- Show end_date (expiration)
|
||||
- "Renew" button creates new invoice
|
||||
|
||||
## Migration Notes
|
||||
|
||||
- Run `migration_to_invoices.sql` on existing installations
|
||||
- Creates `billing_invoices` table
|
||||
- Adds missing columns to `billing_orders`
|
||||
- Migrates existing paid orders to have invoices
|
||||
- Removes obsolete `billing_carts` table
|
||||
Loading…
Add table
Add a link
Reference in a new issue