Files
2026-06-08 15:44:15 -04:00

70 lines
3.0 KiB
PHP

<?php
define('CYBERCHAT_API', true);
require_once __DIR__ . '/../bootstrap.php';
require_once ROOT_DIR . '/lib/stripe.php';
sendCorsHeaders();
$user = authRequired();
$action = $_POST['action'] ?? $_GET['action'] ?? 'status';
$subscriptionsEnabled = (bool)getConfigVal('subscriptions.enabled', true);
$hasExistingBilling = !empty($user['stripe_customer_id']) || !in_array($user['subscription_status'] ?? 'free', ['free', 'canceled'], true);
switch ($action) {
case 'status':
$availablePlans = [];
if ($subscriptionsEnabled) {
foreach (plans(true) as $plan) {
if ($plan['slug'] === 'free') continue;
$availablePlans[] = [
'id' => $plan['id'], 'slug' => $plan['slug'], 'name' => $plan['name'],
'description' => $plan['description'], 'price_cents' => $plan['price_cents'],
'currency' => $plan['currency'], 'interval' => $plan['billing_interval'],
'features' => $plan['features'], 'checkout_ready' => !empty($plan['stripe_price_id']),
];
}
}
jsonResponse([
'subscriptions_enabled' => $subscriptionsEnabled,
'can_manage' => $hasExistingBilling,
'plans' => $availablePlans,
'user' => userPublicPayload($user),
]);
case 'checkout':
if (!$subscriptionsEnabled) jsonResponse(['error' => 'New subscriptions are not currently available'], 403);
if (in_array($user['subscription_status'] ?? 'free', ['active', 'trialing', 'past_due'], true)) {
jsonResponse(['error' => 'Use Manage in Stripe to change an existing subscription'], 409);
}
$planId = (int)($_POST['plan_id'] ?? 0);
$plan = planById($planId);
if (!$plan || !$plan['active'] || $plan['slug'] === 'free') jsonResponse(['error' => 'Plan not available'], 404);
try {
jsonResponse(['success' => true, 'url' => createStripeCheckout($user, $plan)]);
} catch (Throwable $e) {
jsonResponse(['error' => $e->getMessage()], 400);
}
case 'portal':
if (!$hasExistingBilling) jsonResponse(['error' => 'No subscription is connected'], 404);
try {
jsonResponse(['success' => true, 'url' => createStripePortal($user)]);
} catch (Throwable $e) {
jsonResponse(['error' => $e->getMessage()], 400);
}
case 'cancel':
if (empty($user['stripe_subscription_id'])) jsonResponse(['error' => 'No active subscription'], 404);
try {
$subscription = stripeRequest('POST', 'subscriptions/' . rawurlencode($user['stripe_subscription_id']), [
'cancel_at_period_end' => 'true',
]);
syncSubscriptionFromStripe($subscription);
jsonResponse(['success' => true, 'user' => userPublicPayload(userById((int)$user['id']))]);
} catch (Throwable $e) {
jsonResponse(['error' => $e->getMessage()], 400);
}
default:
jsonResponse(['error' => 'Unknown action'], 400);
}