-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocess-payment.php
More file actions
128 lines (108 loc) · 3.87 KB
/
process-payment.php
File metadata and controls
128 lines (108 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php
require_once 'config.php';
require_once __DIR__ . '/vendor/autoload.php';
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['error' => 'Method not allowed']);
exit;
}
if (!isLoggedIn()) {
http_response_code(401);
echo json_encode(['error' => 'You must be logged in to subscribe']);
exit;
}
$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
http_response_code(400);
echo json_encode(['error' => 'Invalid request body']);
exit;
}
if (empty($input['csrf_token']) || !verifyCSRFToken($input['csrf_token'])) {
http_response_code(403);
echo json_encode(['error' => 'Invalid CSRF token. Please refresh the page and try again.']);
exit;
}
$planType = $input['plan_type'] ?? '';
$userId = $_SESSION['user_id'];
if (!in_array($planType, ['monthly', 'yearly'])) {
http_response_code(400);
echo json_encode(['error' => 'Invalid plan type selected']);
exit;
}
if (hasActiveSubscription($userId)) {
http_response_code(400);
echo json_encode(['error' => 'You already have an active subscription']);
exit;
}
\Stripe\Stripe::setApiKey(STRIPE_SECRET_KEY);
try {
$db = db();
$stmt = $db->prepare("SELECT id, email, full_name FROM users WHERE id = ? LIMIT 1");
$stmt->execute([$userId]);
$user = $stmt->fetch();
if (!$user) {
throw new Exception('User account not found');
}
// Always create fresh customer to avoid stale ID errors
$customer = \Stripe\Customer::create([
'email' => $user['email'],
'name' => $user['full_name'],
'metadata' => ['user_id' => (string)$userId]
]);
// USD pricing: $3/month | $30/year
if ($planType === 'monthly') {
$unitAmount = 300; // $3.00 in cents
$interval = 'month';
$productName = SITE_NAME . ' — Monthly Subscription';
$productDesc = 'Unlimited access to all premium articles — billed monthly';
} else {
$unitAmount = 3000; // $30.00 in cents
$interval = 'year';
$productName = SITE_NAME . ' — Yearly Subscription';
$productDesc = 'Unlimited access to all premium articles — billed yearly (save 17%)';
}
$session = \Stripe\Checkout\Session::create([
'customer' => $customer->id,
'payment_method_types' => ['card'],
'line_items' => [[
'price_data' => [
'currency' => 'usd',
'product_data' => [
'name' => $productName,
'description' => $productDesc,
],
'unit_amount' => $unitAmount,
'recurring' => ['interval' => $interval],
],
'quantity' => 1,
]],
'mode' => 'subscription',
'success_url' => rtrim(SITE_URL, '/') . '/payment-success.php?session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => rtrim(SITE_URL, '/') . '/pricing.php?canceled=1',
'metadata' => [
'user_id' => (string)$userId,
'plan_type' => $planType,
],
'subscription_data' => [
'metadata' => [
'user_id' => (string)$userId,
'plan_type' => $planType,
]
],
]);
logActivity($userId, 'checkout_initiated', 'subscription', null, [
'plan_type' => $planType,
'session_id' => $session->id,
]);
echo json_encode(['sessionId' => $session->id]);
} catch (\Stripe\Exception\ApiErrorException $e) {
http_response_code(500);
error_log('Stripe API error: ' . $e->getMessage());
echo json_encode(['error' => $e->getMessage()]);
} catch (Exception $e) {
http_response_code(500);
error_log('process-payment error: ' . $e->getMessage());
echo json_encode(['error' => $e->getMessage()]);
}
?>