-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpayment.ts
More file actions
132 lines (115 loc) · 3.91 KB
/
payment.ts
File metadata and controls
132 lines (115 loc) · 3.91 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
129
130
131
132
import { Express, Request, Response } from "express";
import { storage } from "../storage";
import Stripe from "stripe";
export function registerPaymentRoutes(app: Express) {
// Initialize Stripe with API key
if (!process.env.STRIPE_SECRET_KEY) {
console.warn('Missing STRIPE_SECRET_KEY. Stripe functionality will not work properly.');
}
const stripe = process.env.STRIPE_SECRET_KEY
? new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: "2023-10-16",
})
: null;
// Create payment intent
app.post("/api/payment/create-intent", async (req: Request, res: Response) => {
try {
// Verify user authentication
const userId = req.session.userId;
if (!userId) {
return res.status(401).json({ success: false, message: "Not authenticated" });
}
const { amount, mode } = req.body;
// Validate input
if (!amount) {
return res.status(400).json({
success: false,
message: "Amount is required"
});
}
if (mode === 'preview') {
// For PREVIEW mode, return a mock client secret
// This allows the frontend to test the payment flow without making a real charge
const mockClientSecret = `mock_pi_${Math.random().toString(36).substr(2, 9)}_secret_${Math.random().toString(36).substr(2, 9)}`;
return res.json({
success: true,
clientSecret: mockClientSecret,
mode: 'preview'
});
} else {
// For LIVE mode, create a real payment intent with Stripe
if (!stripe) {
return res.status(500).json({
success: false,
message: "Stripe is not configured"
});
}
// Create a PaymentIntent
const paymentIntent = await stripe.paymentIntents.create({
amount: Math.round(amount * 100), // Convert to cents
currency: "usd",
metadata: {
userId: userId.toString()
},
// Add any additional options here (e.g., receipt_email, description)
});
res.json({
success: true,
clientSecret: paymentIntent.client_secret,
mode: 'live'
});
}
} catch (error: any) {
res.status(500).json({
success: false,
message: error.message || "An error occurred creating payment intent"
});
}
});
// Confirm payment
app.post("/api/payment/confirm", async (req: Request, res: Response) => {
try {
// Verify user authentication
const userId = req.session.userId;
if (!userId) {
return res.status(401).json({ success: false, message: "Not authenticated" });
}
const { paymentIntentId, mode } = req.body;
// Validate input
if (!paymentIntentId) {
return res.status(400).json({
success: false,
message: "Payment intent ID is required"
});
}
if (mode === 'preview') {
// For PREVIEW mode, simulate payment confirmation
return res.json({
success: true,
message: "Payment simulated successfully in PREVIEW mode",
mode: 'preview'
});
} else {
// For LIVE mode, verify payment with Stripe
if (!stripe) {
return res.status(500).json({
success: false,
message: "Stripe is not configured"
});
}
// In a real implementation, you would verify the payment intent status with Stripe
// For this example, we'll simulate success
res.json({
success: true,
message: "Payment processed successfully",
mode: 'live'
});
}
} catch (error: any) {
res.status(500).json({
success: false,
message: error.message || "An error occurred confirming payment"
});
}
});
}