'Unauthorized']); exit; } $pdo = new PDO("pgsql:host=127.0.0.1;dbname=adx_system", "postgres", ""); $pdo->exec("CREATE SCHEMA IF NOT EXISTS billing"); $pdo->exec("CREATE TABLE IF NOT EXISTS billing.config (id SERIAL PRIMARY KEY, key TEXT UNIQUE, value TEXT, created_at TIMESTAMP DEFAULT NOW())"); $pdo->exec("CREATE TABLE IF NOT EXISTS billing.customers (id SERIAL PRIMARY KEY, email TEXT UNIQUE, stripe_customer_id TEXT, name TEXT, plan TEXT DEFAULT 'free', status TEXT DEFAULT 'active', created_at TIMESTAMP DEFAULT NOW())"); $pdo->exec("CREATE TABLE IF NOT EXISTS billing.invoices (id SERIAL PRIMARY KEY, customer_id INT, stripe_invoice_id TEXT, amount_cents INT, currency TEXT DEFAULT 'usd', status TEXT, created_at TIMESTAMP DEFAULT NOW())"); $action = $_POST['action'] ?? $_GET['action'] ?? 'status'; function getStripeKey($pdo) { $r = $pdo->query("SELECT value FROM billing.config WHERE key='stripe_secret_key'")->fetch(PDO::FETCH_ASSOC); return $r ? $r['value'] : null; } function stripeCall($method, $endpoint, $data, $key) { $ch = curl_init("https://api.stripe.com/v1/$endpoint"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15, CURLOPT_USERPWD => "$key:", CURLOPT_HTTPHEADER => ["Content-Type: application/x-www-form-urlencoded"], ]); if ($method === 'POST') { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); } $r = curl_exec($ch); curl_close($ch); return json_decode($r, true); } if ($action === 'status') { $sk = getStripeKey($pdo); $customers = $pdo->query("SELECT COUNT(*) FROM billing.customers")->fetchColumn(); echo json_encode(['ok'=>true, 'stripe_configured'=>!empty($sk), 'customers'=>(int)$customers, 'note'=>$sk?'Stripe active':'Set keys via action=set_keys']); } elseif ($action === 'set_keys') { $sk = $_POST['secret_key'] ?? ''; $pk = $_POST['publishable_key'] ?? ''; if (!$sk) { echo json_encode(['error'=>'secret_key required (sk_live_... or sk_test_...)']); exit; } $pdo->prepare("INSERT INTO billing.config (key, value) VALUES ('stripe_secret_key', ?) ON CONFLICT (key) DO UPDATE SET value=EXCLUDED.value")->execute([$sk]); $pdo->prepare("INSERT INTO billing.config (key, value) VALUES ('stripe_publishable_key', ?) ON CONFLICT (key) DO UPDATE SET value=EXCLUDED.value")->execute([$pk]); // Test connection $r = stripeCall('GET', 'balance', [], $sk); echo json_encode(['ok'=>isset($r['available']), 'balance'=>$r, 'message'=>'Stripe keys saved']); } elseif ($action === 'create_customer') { $sk = getStripeKey($pdo); if (!$sk) { echo json_encode(['error'=>'Stripe not configured']); exit; } $email = $_POST['email'] ?? ''; $name = $_POST['name'] ?? ''; $r = stripeCall('POST', 'customers', ['email'=>$email, 'name'=>$name], $sk); if (!empty($r['id'])) { $pdo->prepare("INSERT INTO billing.customers (email, stripe_customer_id, name) VALUES (?,?,?) ON CONFLICT (email) DO UPDATE SET stripe_customer_id=EXCLUDED.stripe_customer_id") ->execute([$email, $r['id'], $name]); } echo json_encode(['ok'=>!empty($r['id']), 'customer'=>$r]); } elseif ($action === 'create_checkout') { $sk = getStripeKey($pdo); if (!$sk) { echo json_encode(['error'=>'Stripe not configured']); exit; } $price = $_POST['price_id'] ?? ''; $email = $_POST['email'] ?? ''; $r = stripeCall('POST', 'checkout/sessions', [ 'mode'=>'subscription','customer_email'=>$email, 'line_items[0][price]'=>$price,'line_items[0][quantity]'=>1, 'success_url'=>'https://weval-consulting.com/products/workspace.html?success=1', 'cancel_url'=>'https://weval-consulting.com/products/workspace.html?cancel=1', ], $sk); echo json_encode(['ok'=>!empty($r['url']), 'checkout_url'=>$r['url']??null, 'session'=>$r]); } else { echo json_encode(['actions'=>['status','set_keys','create_customer','create_checkout']]); }