mirror of
https://github.com/stackblitz/bolt.new
synced 2025-06-26 18:17:50 +00:00
feat: 增加认证机制以安全地查询支付状态
This commit is contained in:
parent
cd3a79e954
commit
bf1d6cb2d9
@ -1,6 +1,7 @@
|
|||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import { Dialog, DialogTitle, DialogDescription, DialogRoot } from '~/components/ui/Dialog';
|
import { Dialog, DialogTitle, DialogDescription, DialogRoot } from '~/components/ui/Dialog';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
import { useAuth } from '~/hooks/useAuth'; // 导入 useAuth hook
|
||||||
|
|
||||||
interface PaymentModalProps {
|
interface PaymentModalProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -22,6 +23,7 @@ interface PaymentResponse {
|
|||||||
did: string;
|
did: string;
|
||||||
expires_in: string;
|
expires_in: string;
|
||||||
return_url: string;
|
return_url: string;
|
||||||
|
orderNo: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PaymentStatusResponse {
|
interface PaymentStatusResponse {
|
||||||
@ -31,10 +33,20 @@ interface PaymentStatusResponse {
|
|||||||
|
|
||||||
export function PaymentModal({ isOpen, onClose, paymentData, onPaymentSuccess }: PaymentModalProps) {
|
export function PaymentModal({ isOpen, onClose, paymentData, onPaymentSuccess }: PaymentModalProps) {
|
||||||
const [timeLeft, setTimeLeft] = useState(parseInt(paymentData.expires_in));
|
const [timeLeft, setTimeLeft] = useState(parseInt(paymentData.expires_in));
|
||||||
|
const { token } = useAuth(); // 获取认证token
|
||||||
|
|
||||||
const checkPaymentStatus = useCallback(async () => {
|
const checkPaymentStatus = useCallback(async () => {
|
||||||
|
if (!token) {
|
||||||
|
console.error('No authentication token available');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/check-payment-status?orderNo=${paymentData.no}`);
|
const response = await fetch(`/api/check-payment-status?orderNo=${paymentData.orderNo}`, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (response.status === 404) {
|
if (response.status === 404) {
|
||||||
console.error('Order not found');
|
console.error('Order not found');
|
||||||
@ -52,7 +64,7 @@ export function PaymentModal({ isOpen, onClose, paymentData, onPaymentSuccess }:
|
|||||||
console.error('Error checking payment status:', error);
|
console.error('Error checking payment status:', error);
|
||||||
toast.error('检查支付状态时出错,请稍后再试');
|
toast.error('检查支付状态时出错,请稍后再试');
|
||||||
}
|
}
|
||||||
}, [paymentData.no, onPaymentSuccess, onClose]);
|
}, [paymentData.orderNo, onPaymentSuccess, onClose, token]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isOpen) return;
|
if (!isOpen) return;
|
||||||
@ -89,7 +101,7 @@ export function PaymentModal({ isOpen, onClose, paymentData, onPaymentSuccess }:
|
|||||||
</div>
|
</div>
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<p className="text-bolt-elements-textPrimary">订单金额: ¥{paymentData.order_amount}</p>
|
<p className="text-bolt-elements-textPrimary">订单金额: ¥{paymentData.order_amount}</p>
|
||||||
<p className="text-bolt-elements-textSecondary">订单号: {paymentData.no}</p>
|
<p className="text-bolt-elements-textSecondary">订单号: {paymentData.orderNo}</p>
|
||||||
<p className="text-bolt-elements-textSecondary">支付方式: {paymentData.pay_type}</p>
|
<p className="text-bolt-elements-textSecondary">支付方式: {paymentData.pay_type}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
|
|||||||
@ -11,7 +11,7 @@ export async function action({ request }: { request: Request }) {
|
|||||||
return error as Response;
|
return error as Response;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { planId, billingCycle } = await request.json() as { planId: string; billingCycle: string };
|
const { planId, billingCycle } = (await request.json()) as { planId: string; billingCycle: string };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 获取订阅计划详情
|
// 获取订阅计划详情
|
||||||
@ -36,7 +36,7 @@ export async function action({ request }: { request: Request }) {
|
|||||||
`${plan.name} 订阅 (${billingCycle === 'yearly' ? '年付' : '月付'})`,
|
`${plan.name} 订阅 (${billingCycle === 'yearly' ? '年付' : '月付'})`,
|
||||||
'alipay', // 或其他支付方式
|
'alipay', // 或其他支付方式
|
||||||
price, // 不用转换为分
|
price, // 不用转换为分
|
||||||
userId.toString()
|
userId.toString(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// 创建待处理的交易记录
|
// 创建待处理的交易记录
|
||||||
@ -51,7 +51,7 @@ export async function action({ request }: { request: Request }) {
|
|||||||
transaction_id: orderNo,
|
transaction_id: orderNo,
|
||||||
});
|
});
|
||||||
|
|
||||||
return json({ success: true, paymentData });
|
return json({ success: true, paymentData: { ...paymentData, orderNo } });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('初始化订阅购买时出错:', error);
|
console.error('初始化订阅购买时出错:', error);
|
||||||
return json({ error: '初始化订阅购买失败' }, { status: 500 });
|
return json({ error: '初始化订阅购买失败' }, { status: 500 });
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user