Files
dobetternorge-tools/api/stripe-checkout.php
T
daveadmin ba9cddf9a1 Add monetization spine + Build Your Own Case (Min Sak)
- Stripe: StripeClient.php, checkout/portal/webhook endpoints, idempotent event handling
- FreeTier: tier-aware credits (free/light/pro/pro_plus), bonus_balance, hourly caps per tier
- pricing.php + billing.php: 4-tier cards, 3 topups, Customer Portal, balance breakdown
- Min Sak: CaseStore.php, AzureDocIntelligence.php, AzureSearchAdmin.php — per-user hybrid RAG
- api/case/: upload, list, delete, ingest-callback (HMAC-auth'd from n8n)
- award-survey-credits: inter-site HMAC endpoint for dobetternorge.no survey bonus
- dashboard.php: tier badge, balance breakdown card, Min Sak CTA, survey CTA
- KorrespondAgent + all 3 other agents: use_my_case toggle wired to dbnToolsCaseContext()
- bootstrap.php: dbnToolsCaseContext(), dbnToolsIntersiteSecret(), dbnToolsCurrentTier()

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 20:52:54 +02:00

78 lines
2.6 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/../includes/bootstrap.php';
require_once __DIR__ . '/../includes/StripeClient.php';
require_once __DIR__ . '/../includes/FreeTier.php';
dbnToolsRequireMethod('POST');
dbnToolsRequireAuth();
$user = dbnToolsAuthenticatedUser();
$userId = (int)($user['user_id'] ?? 0);
$email = (string)($user['email'] ?? '');
if ($userId <= 0 || $email === '') {
dbnToolsError('User session missing user_id or email.', 401, 'bad_session');
}
$input = dbnToolsJsonInput(2000);
$sku = (string)($input['sku'] ?? '');
$validSubscriptions = ['light', 'pro', 'pro_plus'];
$validTopups = ['topup_s', 'topup_m', 'topup_l'];
if (!in_array($sku, array_merge($validSubscriptions, $validTopups), true)) {
dbnToolsError('Unknown SKU.', 400, 'unknown_sku');
}
try {
$stripe = new StripeClient();
$customerId = $stripe->ensureCustomer($email, $userId);
$baseUrl = (dbnToolsIsHttps() ? 'https://' : 'http://') . ($_SERVER['HTTP_HOST'] ?? 'tools.dobetternorge.no');
$successUrl = $baseUrl . '/billing.php?status=success&session_id={CHECKOUT_SESSION_ID}';
$cancelUrl = $baseUrl . '/pricing.php?status=canceled';
$isSub = in_array($sku, $validSubscriptions, true);
$params = [
'mode' => $isSub ? 'subscription' : 'payment',
'customer' => $customerId,
'success_url' => $successUrl,
'cancel_url' => $cancelUrl,
'line_items' => [[
'price' => StripeClient::priceId($sku),
'quantity' => 1,
]],
'metadata' => [
'user_id' => (string)$userId,
'sku' => $sku,
],
'allow_promotion_codes' => true,
'billing_address_collection' => 'auto',
'locale' => 'auto',
'automatic_tax' => ['enabled' => false],
];
if ($isSub) {
$params['subscription_data'] = [
'metadata' => ['user_id' => (string)$userId, 'tier' => $sku],
];
} else {
$params['payment_intent_data'] = [
'metadata' => ['user_id' => (string)$userId, 'sku' => $sku, 'credits' => (string)StripeClient::topupCredits($sku)],
];
}
$session = $stripe->createCheckoutSession($params);
$url = (string)($session['url'] ?? '');
if ($url === '') {
dbnToolsError('Stripe did not return a checkout URL.', 502, 'stripe_no_url');
}
dbnToolsRespond(['ok' => true, 'url' => $url, 'session_id' => (string)($session['id'] ?? '')]);
} catch (Throwable $e) {
error_log('[stripe-checkout] ' . $e->getMessage());
dbnToolsError('Could not start checkout: ' . $e->getMessage(), 500, 'stripe_failed');
}