LICENSE SERVER — SETUP INSTRUCTIONS (v2: automatic claim-by-email flow) ========================================================================== Separate small app from HoneySub itself. This backend issues and checks license keys for every copy of HoneySub (or any future product) you sell. THE FLOW THIS BUILDS ===================== 1. Someone buys → you (or later, your store's payment webhook) record the sale by EMAIL ONLY, via Admin -> "Record a Purchase". No code is generated at this point — you don't send them anything. 2. Buyer downloads the one universal HoneySub zip, uploads it, runs the installer. 3. Installer asks for their purchase email, shows a "Generate" button. 4. That button calls POST /api/claim.php with their email + the domain the installer is running on. The server finds their pending purchase, generates the actual code for the FIRST time right there, binds it immediately to that domain, and returns it. 5. The code auto-fills in the installer. Installation continues normally (DB credentials, admin account creation). Nobody had to manually generate or email a code to anyone. The only manual step left is clicking "Record a Purchase" once per sale (or later, automating that click via your checkout platform's webhook). 1. HOSTING Subdomain — license.olasteve.com — upload this whole license_server/ folder to its document root. 2. DATABASE Run install/schema.sql in phpMyAdmin. 3. CONFIGURE includes/config.php - DB_USER / DB_PASS — this subdomain's own database credentials - LICENSE_MASTER_SECRET — a long random string. MUST exactly match HONEYSUB_LICENSE_SECRET in the buyer-side includes/license.php. Generate once, use in both places, never change it afterward. 4. CREATE YOUR ADMIN LOGIN php -r "echo password_hash('yourpassword', PASSWORD_BCRYPT);" Then in phpMyAdmin: INSERT INTO license_admins (email, password) VALUES ('hi@olasteve.com', 'PASTE_THE_HASH_HERE'); 5. TODAY, BEFORE ANY STORE EXISTS Someone pays you however they currently do → you go to license.olasteve.com/admin/dashboard.php → "Record a Purchase" → type their email → done. Tell them to enter that same email in their installer's Generate button. That's the entire manual step. 6. LATER: AUTOMATING THE PURCHASE STEP Once you build/pick a checkout, its payment-success webhook calls the exact same "record_purchase" logic automatically — nothing here needs rebuilding. API ENDPOINTS ============== POST /api/claim.php { email, domain, product } The installer's "Generate" button calls this. First time: generates and binds a code. Same domain again (reinstall): returns the same code. Different domain: rejected. Unknown email: rejected. POST /api/verify.php { license_key, domain } Periodic background re-check from an already-installed site, to catch a revocation without needing constant live calls. Both return { success, license_key?, token } — the token is a signed proof the buyer's site caches locally so it works day-to-day even if this server is briefly unreachable.