diff --git a/web/src/components/settings/PaymentSetting.js b/web/src/components/settings/PaymentSetting.js index 91a40a2b..4d9e1ccd 100644 --- a/web/src/components/settings/PaymentSetting.js +++ b/web/src/components/settings/PaymentSetting.js @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; import { Card, Spin } from '@douyinfe/semi-ui'; import SettingsGeneralPayment from '../../pages/Setting/Payment/SettingsGeneralPayment.js'; import SettingsPaymentGateway from '../../pages/Setting/Payment/SettingsPaymentGateway.js'; +import SettingsPaymentGatewayStripe from '../../pages/Setting/Payment/SettingsPaymentGatewayStripe.js'; import { API, showError } from '../../helpers'; import { useTranslation } from 'react-i18next'; @@ -17,6 +18,12 @@ const PaymentSetting = () => { TopupGroupRatio: '', CustomCallbackAddress: '', PayMethods: '', + + StripeApiSecret: '', + StripeWebhookSecret: '', + StripePriceId: '', + StripeUnitPrice: 8.0, + StripeMinTopUp: 1, }); let [loading, setLoading] = useState(false); @@ -38,6 +45,8 @@ const PaymentSetting = () => { break; case 'Price': case 'MinTopUp': + case 'StripeUnitPrice': + case 'StripeMinTopUp': newInputs[item.key] = parseFloat(item.value); break; default: @@ -80,6 +89,9 @@ const PaymentSetting = () => { + + + ); diff --git a/web/src/pages/Setting/Payment/SettingsPaymentGatewayStripe.js b/web/src/pages/Setting/Payment/SettingsPaymentGatewayStripe.js new file mode 100644 index 00000000..c8cf3667 --- /dev/null +++ b/web/src/pages/Setting/Payment/SettingsPaymentGatewayStripe.js @@ -0,0 +1,196 @@ +import React, { useEffect, useState, useRef } from 'react'; +import { + Banner, + Button, + Form, + Row, + Col, + Typography, + Spin, +} from '@douyinfe/semi-ui'; +const { Text } = Typography; +import { + API, + removeTrailingSlash, + showError, + showSuccess, + verifyJSON, +} from '../../../helpers'; +import { useTranslation } from 'react-i18next'; + +export default function SettingsPaymentGateway(props) { + const { t } = useTranslation(); + const [loading, setLoading] = useState(false); + const [inputs, setInputs] = useState({ + StripeApiSecret: '', + StripeWebhookSecret: '', + StripePriceId: '', + StripeUnitPrice: 8.0, + StripeMinTopUp: 1, + }); + const [originInputs, setOriginInputs] = useState({}); + const formApiRef = useRef(null); + + useEffect(() => { + if (props.options && formApiRef.current) { + const currentInputs = { + StripeApiSecret: props.options.StripeApiSecret || '', + StripeWebhookSecret: props.options.StripeWebhookSecret || '', + StripePriceId: props.options.StripePriceId || '', + StripeUnitPrice: props.options.StripeUnitPrice !== undefined ? parseFloat(props.options.StripeUnitPrice) : 8.0, + StripeMinTopUp: props.options.StripeMinTopUp !== undefined ? parseFloat(props.options.StripeMinTopUp) : 1, + }; + setInputs(currentInputs); + setOriginInputs({ ...currentInputs }); + formApiRef.current.setValues(currentInputs); + } + }, [props.options]); + + const handleFormChange = (values) => { + setInputs(values); + }; + + const submitStripeSetting = async () => { + if (props.options.ServerAddress === '') { + showError(t('请先填写服务器地址')); + return; + } + + setLoading(true); + try { + const options = [] + + if (inputs.StripeApiSecret !== undefined && inputs.StripeApiSecret !== '') { + options.push({ key: 'StripeApiSecret', value: inputs.StripeApiSecret }); + } + if (inputs.StripeWebhookSecret !== undefined && inputs.StripeWebhookSecret !== '') { + options.push({ key: 'StripeWebhookSecret', value: inputs.StripeWebhookSecret }); + } + if (inputs.StripePriceId !== '') { + options.push({key: 'StripePriceId', value: inputs.StripePriceId,}); + } + if (inputs.StripeUnitPrice !== '') { + options.push({ key: 'StripeUnitPrice', value: inputs.StripeUnitPrice.toString() }); + } + if (inputs.StripeMinTopUp !== '') { + options.push({ key: 'StripeMinTopUp', value: inputs.StripeMinTopUp.toString() }); + } + + // 发送请求 + const requestQueue = options.map(opt => + API.put('/api/option/', { + key: opt.key, + value: opt.value, + }) + ); + + const results = await Promise.all(requestQueue); + + // 检查所有请求是否成功 + const errorResults = results.filter(res => !res.data.success); + if (errorResults.length > 0) { + errorResults.forEach(res => { + showError(res.data.message); + }); + } else { + showSuccess(t('更新成功')); + // 更新本地存储的原始值 + setOriginInputs({ ...inputs }); + props.refresh && props.refresh(); + } + } catch (error) { + showError(t('更新失败')); + } + setLoading(false); + }; + + return ( + +
(formApiRef.current = api)} + > + + + Stripe 密钥、Webhook 等设置请 + + 点击此处 + + 进行设置,最好先在 + + 测试环境 + + 进行测试。 + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+
+ ); +} \ No newline at end of file