fix: standardize billing order status values and fix expiration lookup

- billing_integration.php: admin-created servers now use status='Active' (was 'installed')
- home_handling_functions.php: expiration query uses status IN ('Active','Invoiced') only
- my_account.php: renewable_statuses includes canonical 'active'/'invoiced'; legacy labels updated
- admin_orders.php: add orphaned home_id diagnostics section
- normalize_billing_order_status.sql: new migration to convert installed/paid→Active, suspended→Invoiced

Agent-Logs-Url: https://github.com/GameServerPanel/GSP/sessions/c56f04bb-ecce-4f1b-9bbd-c5f83107da1d

Co-authored-by: iaretechnician <2749183+iaretechnician@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-05-05 15:55:39 +00:00 committed by GitHub
parent edb2f90b4a
commit 2f62bd32c9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 116 additions and 14 deletions

View file

@ -514,15 +514,13 @@ function get_server_billing_expiration_html(int $home_id): string
// billing_orders.home_id is VARCHAR(255), so we quote the value in the query.
// We exclude rows where home_id = '0' (not yet provisioned).
//
// Status whitelist — covers all active/paid states regardless of billing flow:
// 'Active' set by payment_processor.php after PayPal capture
// 'Invoiced' renewal invoice generated by cron-shop.php
// 'installed' used by the invoice-first provisioning flow
// 'paid' used by the invoice-first provisioning flow
// 'suspended' overdue but not yet fully expired; date still meaningful
// Only canonical active statuses are considered:
// 'Active' provisioned and current (set by payment capture or admin creation)
// 'Invoiced' renewal invoice generated; service still running while unpaid
//
// Terminal statuses ('Expired', 'in-cart', 'cancelled', 'refunded') are excluded
// because they represent orders with no active service period.
// Terminal statuses ('Expired', 'in-cart', 'cancelled', 'refunded') and legacy
// statuses ('installed', 'paid', 'suspended') are not matched here.
// Run normalize_billing_order_status.sql to migrate any legacy rows first.
//
// OGP_DB_PREFIX is replaced at runtime by the panel DB wrapper (str_replace).
$rows = $db->resultQuery(
@ -530,7 +528,7 @@ function get_server_billing_expiration_html(int $home_id): string
FROM OGP_DB_PREFIXbilling_orders
WHERE home_id = '" . intval($home_id) . "'
AND home_id != '0'
AND status IN ('Active','Invoiced','installed','paid','suspended')
AND status IN ('Active','Invoiced')
ORDER BY end_date DESC
LIMIT 1"
);