Panel/docs/modules/website_billing_rebuild.md
2026-06-17 18:00:53 -05:00

11 KiB

Gameservers.World Website Billing Rebuild

Scope

The current production website remains in Panel/modules/website/. The extracted backup-website/ tree is reference-only and must not be included at runtime or copied wholesale into production.

This rebuild restores the standalone sales-site responsibilities inside the current website module:

  • customer login, registration, logout, and password reset
  • account, orders, invoices, and server-order review pages
  • public catalog, order configuration, anonymous cart, checkout, and PayPal capture/webhook handlers
  • website staff pages for services, coupons, invoices, orders, payments, PayPal settings, migrations, and provisioning queue review
  • idempotent database setup for billing support tables

The GSP Panel remains responsible for operational game-server administration and final server provisioning.

Documentation and Reference Audit

Reviewed current documentation under docs/, Panel/docs/, Panel/modules/website/, and pricing/, plus backup documentation including invoice, payment, coupon, migration, testing, and status notes.

Reviewed current website implementation under Panel/modules/website/ and backup reference files including:

  • login.php, logout.php, register.php, forgot_password.php, reset_password.php
  • serverlist.php, order.php, add_to_cart.php, cart.php
  • payment_success.php, payment_cancel.php, api/create_order.php, api/capture_order.php, webhook.php
  • admin.php, adminserverlist.php, admin_config.php, admin_coupons.php, admin_invoices.php, admin_payments.php
  • create_servers.php, cron-shop.php

Backup Behaviors Recreated

  • Shared Panel-user authentication for the website, using the same user ID and password hash.
  • Separate website and Panel sessions.
  • Customer registration and password-reset pages.
  • Public game-server catalog and order.php?service_id=... order entry.
  • Cart, checkout, invoices, payments, and order records.
  • Staff catalog, coupon, invoice, payment, PayPal, and provisioning views.

Backup Behaviors Improved

  • Login now verifies the Panel password hash before creating a website session.
  • The cart can be used anonymously until checkout.
  • Checkout creates invoices only after the customer is authenticated.
  • PayPal credentials are read from environment variables or website settings, never hardcoded in production source.
  • PayPal payment state is verified server-side.
  • Webhook events are deduplicated.
  • CSRF tokens protect state-changing website and staff forms.
  • Staff pages enforce server-side authorization.
  • The backup folder is denied by .htaccess.

Backup Behaviors Rejected

  • No fabricated website sessions from a submitted username.
  • No production display_errors=1.
  • No hardcoded PayPal client ID, client secret, or webhook ID.
  • No browser-editable arbitrary PHP configuration file.
  • No public inclusion of files from backup-website/.
  • No provisioning before payment/approval.
  • No SSO for this phase.

Credential Rotation

The backup contains historical credentials and must be treated as compromised. Rotate any credentials that were ever used from these files:

  • backup-website/cart.php
  • backup-website/api/create_order.php
  • backup-website/api/capture_order.php
  • backup-website/webhook.php
  • backup-website/includes/config.inc.php
  • backup-website/includes/config.inc.php.orig

Do not copy credential values from those files into documentation, commits, tickets, or chat.

Authentication

The Panel users table is the identity source. The website stores only its own PHP session state:

  • website_user_id
  • website_users_login
  • website_users_role
  • login timestamps

The website and Panel are on different parent domains, so they intentionally use separate cookies and sessions. Customers can use the same username and password on both sites, but logging into one site does not automatically log into the other.

Password verification currently matches the Panel-compatible MD5 hash used by the deployed Panel user table. Do not migrate hashes unless the Panel login system is upgraded at the same time and compatibility is tested.

Ordering Flow

  1. Visitor browses serverlist.php.
  2. Visitor opens order.php?service_id=<id>.
  3. order.php validates the enabled service server-side.
  4. Visitor chooses slots, location, duration, and optional server name.
  5. The item is added to a session cart.
  6. Checkout requires login or registration.
  7. After login/registration, the same cart remains in the website session.
  8. Checkout creates a due invoice and pending-payment order rows.
  9. PayPal order creation and capture are performed server-side.
  10. Verified payment marks the invoice paid and orders ready for provisioning.

Prices, slot limits, service status, and locations are revalidated on the server. Browser-submitted prices are ignored.

Database Prefix and Migrations

The website reads the current Panel database settings and table prefix from Panel/billing configuration files. Empty prefixes are supported.

Run billing setup from the staff page:

Panel/modules/website/staff_migrations.php

The migration runner creates missing tables idempotently:

  • billing_invoices
  • billing_orders
  • billing_payments
  • billing_coupons
  • website_settings
  • password_reset_tokens
  • payment_webhook_events
  • provisioning_attempts

It also adds missing catalog columns to billing_services when that table already exists:

  • description
  • img_url
  • price_monthly
  • slot_min_qty
  • slot_max_qty
  • enabled
  • remote_server_id

Take a database backup before running migrations in production.

PayPal

Preferred production configuration uses environment variables:

  • GSP_WEBSITE_PAYPAL_CLIENT_ID
  • GSP_WEBSITE_PAYPAL_CLIENT_SECRET
  • GSP_WEBSITE_PAYPAL_WEBHOOK_ID

The staff PayPal page can store non-environment fallback values in website_settings. Client secrets are masked and only replaced when a new value is entered.

Payment handlers:

  • api/create_order.php
  • api/capture_order.php
  • webhook.php

Browser callbacks alone do not mark an invoice paid. Capture is verified through PayPal server-side, and webhooks are verified with PayPal before processing.

Staff Pages

Website staff pages are separate from Panel administration:

  • staff.php
  • staff_services.php
  • staff_locations.php
  • staff_coupons.php
  • staff_orders.php
  • staff_invoices.php
  • staff_payments.php
  • staff_paypal.php
  • staff_settings.php
  • staff_provisioning.php
  • staff_migrations.php

Access is currently limited to Panel users with users_role = admin. Future role expansion can add granular permissions such as catalog.manage, orders.manage, payments.manage, and provisioning.manage.

Provisioning Boundary

The website records paid orders and exposes a provisioning queue. The Panel remains the authority for:

  • creating game homes
  • assigning homes to shared user_id
  • selecting agents and locations
  • installing server files
  • operational server management

Provisioning integration must remain idempotent: paid orders should be claimed before processing, record home_id on success, and store failure details for safe retry.

Customer Pages

Customer-facing account pages:

  • account.php
  • orders.php
  • invoices.php
  • my_servers.php

my_servers.php shows website order records and links customers to the GSP control panel for operational server management.

Deployment Notes

  • Serve the production website from Panel/modules/website/.
  • Keep backup-website/ out of the web root where possible. The repository copy includes .htaccess deny rules as a secondary guard.
  • Configure HTTPS before enabling checkout.
  • Configure PayPal environment variables or staff settings.
  • Run the billing migration page as an authorized staff user.
  • Test sandbox PayPal before live mode.

Rollback

  1. Revert changed website files.
  2. Restore the database backup taken before migrations if schema rollback is required.
  3. Disable PayPal in staff_paypal.php or remove the environment variables.
  4. Keep backup-website/ protected; do not make it public as a rollback mechanism.

Manual Test Checklist

  • Customer registration, login, invalid login, logout, forgot password, reset password.
  • Catalog list, valid service_id, invalid service_id, disabled service.
  • Anonymous configure, add to cart, update/remove cart item.
  • Checkout prompt while logged out, login/register return to cart.
  • Invoice creation, PayPal sandbox order, capture verification, webhook verification, duplicate webhook.
  • Staff dashboard access as admin and denial as non-admin.
  • Staff service, coupon, invoice, payment, PayPal, and provisioning pages.
  • Paid order appears in provisioning queue.
  • Customer orders, invoices, and My Servers pages show only the authenticated user's records.
  • No hardcoded credentials or raw PHP errors are displayed.

HTTP 500 Troubleshooting

Login remains on login.php

Check:

  • submitted field names are login, password, and csrf_token
  • CSRF token validates
  • the Panel user exists in the configured users table
  • users_passwd matches the current Panel-compatible hash
  • account role is not banned
  • no output is sent before the redirect
  • successful login redirects to my_account.php unless a safe internal return path is stored

The website also provides account.php and my_account.php as compatible account routes.

staff.php HTTP 500 or blank output

Common causes:

  • PHP 8-only syntax deployed on a PHP 7.x host
  • missing production files from Panel/modules/website/pages/
  • missing includes/billing.php
  • fatal error suppressed by production display_errors=0
  • non-admin account expecting staff access

The website bootstrap avoids PHP 8-only constructs and installs a shutdown handler that logs fatal errors with a short reference ID. Staff pages must render through shared website templates and must not point to the Panel activity logger.

staff_services.php HTTP 500

Check:

  • billing_services exists
  • staff migrations have been run
  • expected catalog columns exist or can be added by the idempotent migration runner
  • remote_servers schema is the current Panel schema
  • the page is not assuming remote_servers.enabled exists
  • website_table_exists() is not using SHOW TABLES LIKE ?; MySQL does not support binding the table pattern in that statement through mysqli prepared placeholders

The current helper treats missing remote_servers.enabled as enabled for display and lets staff assign locations from current Panel remote-server rows.

order.php?service_id=... HTTP 500

Check:

  • billing_services exists
  • the requested service_id exists
  • the service is enabled if the enabled column exists
  • remote_server_id contains at least one valid location ID
  • configured slot columns are present or defaults are acceptable
  • config_homes exists when game metadata is needed

The order page no longer requires config_homes; it can render from the service row alone. Missing or disabled services produce a styled unavailable page instead of blank output.

Wrong Panel Administration URL

Website staff administration must link to:

  • staff.php

It must not link to:

  • home.php?m=administration&p=watch_logger

The Panel activity logger is operational administration, not website sales/billing administration.

Log Locations

Production PHP or web-server logs are deployment-specific. Check Apache, Nginx, PHP-FPM, cPanel error_log, and PHP error_log paths. The local repository does not contain live web-server error logs.