Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
8e6660cf
authored
Jul 10, 2025
by
wzxjohn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add stripe setting page
parent
81d474ba
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
209 additions
and
0 deletions
+209
-0
web/src/components/settings/PaymentSetting.js
+12
-0
web/src/pages/Setting/Payment/SettingsPaymentGatewayStripe.js
+197
-0
No files found.
web/src/components/settings/PaymentSetting.js
View file @
8e6660cf
...
...
@@ -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 = () => {
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
<
SettingsPaymentGateway
options
=
{
inputs
}
refresh
=
{
onRefresh
}
/
>
<
/Card
>
<
Card
style
=
{{
marginTop
:
'10px'
}}
>
<
SettingsPaymentGatewayStripe
options
=
{
inputs
}
refresh
=
{
onRefresh
}
/
>
<
/Card
>
<
/Spin
>
<
/
>
);
...
...
web/src/pages/Setting/Payment/SettingsPaymentGatewayStripe.js
0 → 100644
View file @
8e6660cf
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
(
<
Spin
spinning
=
{
loading
}
>
<
Form
initValues
=
{
inputs
}
onValueChange
=
{
handleFormChange
}
getFormApi
=
{(
api
)
=>
(
formApiRef
.
current
=
api
)}
>
<
Form
.
Section
text
=
{
t
(
'Stripe 设置'
)}
>
<
Text
>
Stripe
密钥、
Webhook
等设置请
<
a
href
=
'https://dashboard.stripe.com/developers'
target
=
'_blank'
rel
=
'noreferrer'
>
点击此处
<
/a
>
进行设置,最好先在
<
a
href
=
'https://dashboard.stripe.com/test/developers'
target
=
'_blank'
rel
=
'noreferrer'
>
测试环境
<
/a
>
进行测试。
<
br
/>
<
/Text
>
<
Banner
type
=
'info'
description
=
{
`Webhook 填:
${
props
.
options
.
ServerAddress
?
props
.
options
.
ServerAddress
:
'网站地址'
}
/api/stripe/webhook`
}
/
>
<
Banner
type
=
'warning'
description
=
{
`需要包含事件:checkout.session.completed 和 checkout.session.expired`
}
/
>
<
Row
gutter
=
{{
xs
:
8
,
sm
:
16
,
md
:
24
,
lg
:
24
,
xl
:
24
,
xxl
:
24
}}
>
<
Col
xs
=
{
24
}
sm
=
{
24
}
md
=
{
8
}
lg
=
{
8
}
xl
=
{
8
}
>
<
Form
.
Input
field
=
'StripeApiSecret'
label
=
{
t
(
'API 密钥'
)}
placeholder
=
{
t
(
'sk_xxx 或 rk_xxx 的 Stripe 密钥,敏感信息不显示'
)}
type
=
'password'
/>
<
/Col
>
<
Col
xs
=
{
24
}
sm
=
{
24
}
md
=
{
8
}
lg
=
{
8
}
xl
=
{
8
}
>
<
Form
.
Input
field
=
'StripeWebhookSecret'
label
=
{
t
(
'Webhook 签名密钥'
)}
placeholder
=
{
t
(
'whsec_xxx 的 Webhook 签名密钥,敏感信息不显示'
)}
type
=
'password'
/>
<
/Col
>
<
Col
xs
=
{
24
}
sm
=
{
24
}
md
=
{
8
}
lg
=
{
8
}
xl
=
{
8
}
>
<
Form
.
Input
field
=
'StripePriceId'
label
=
{
t
(
'商品价格 ID'
)}
placeholder
=
{
t
(
'price_xxx 的商品价格 ID,新建产品后可获得'
)}
/
>
<
/Col
>
<
/Row
>
<
Row
gutter
=
{{
xs
:
8
,
sm
:
16
,
md
:
24
,
lg
:
24
,
xl
:
24
,
xxl
:
24
}}
style
=
{{
marginTop
:
16
}}
>
<
Col
xs
=
{
24
}
sm
=
{
24
}
md
=
{
8
}
lg
=
{
8
}
xl
=
{
8
}
>
<
Form
.
InputNumber
field
=
'StripeUnitPrice'
precision
=
{
2
}
label
=
{
t
(
'充值价格(x元/美金)'
)}
placeholder
=
{
t
(
'例如:7,就是7元/美金'
)}
/
>
<
/Col
>
<
Col
xs
=
{
24
}
sm
=
{
24
}
md
=
{
8
}
lg
=
{
8
}
xl
=
{
8
}
>
<
Form
.
InputNumber
field
=
'StripeMinTopUp'
label
=
{
t
(
'最低充值美元数量'
)}
placeholder
=
{
t
(
'例如:2,就是最低充值2$'
)}
/
>
<
/Col
>
<
/Row
>
<
Button
onClick
=
{
submitStripeSetting
}
>
{
t
(
'更新 Stripe 设置'
)}
<
/Button
>
<
/Form.Section
>
<
/Form
>
<
/Spin
>
);
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment