feat(admin): 支付配置表单按服务商分字段并收敛高级配置
This commit is contained in:
@@ -4,11 +4,14 @@ import {
|
||||
Alert,
|
||||
App,
|
||||
Button,
|
||||
Collapse,
|
||||
Col,
|
||||
Form,
|
||||
Input,
|
||||
InputNumber,
|
||||
Modal,
|
||||
Row,
|
||||
Segmented,
|
||||
Select,
|
||||
Space,
|
||||
Switch,
|
||||
@@ -63,23 +66,120 @@ const statusOptions = Object.entries(statusLabels).map(([value, label]) => ({ va
|
||||
const providerOptions = Object.entries(providerLabels).map(([value, label]) => ({ value, label }))
|
||||
const payWayOptions = Object.entries(payWayLabels).map(([value, label]) => ({ value, label }))
|
||||
|
||||
const defaultGateways: Record<string, string> = {
|
||||
leshua: 'https://paygate.leshuazf.com/cgi-bin/lepos_pay_gateway.cgi',
|
||||
mock: '',
|
||||
}
|
||||
|
||||
const lakalaGateways: Record<string, string> = {
|
||||
production: 'https://s2.lakala.com',
|
||||
sandbox: 'https://test.wsmsd.cn/sit',
|
||||
}
|
||||
|
||||
const shunchengGateways: Record<string, string> = {
|
||||
production: 'http://jyzxapi.ydxnhb.com',
|
||||
sandbox: 'http://jyzxapi.ydxnhb.com',
|
||||
}
|
||||
|
||||
const defaultNotifyPaths: Record<string, string> = {
|
||||
leshua: '/api/payments/leshua/notify',
|
||||
lakala: '/api/payments/lakala/notify',
|
||||
shuncheng: '/api/payments/shuncheng/notify',
|
||||
mock: '',
|
||||
}
|
||||
|
||||
const lakalaPayModeByPayWay: Record<string, string> = {
|
||||
ZFBZF: 'ALIPAY',
|
||||
WXZF: 'WECHAT',
|
||||
}
|
||||
|
||||
function defaultGateway(provider: string, environment = 'production') {
|
||||
if (provider === 'lakala') {
|
||||
return lakalaGateways[environment] ?? lakalaGateways.production
|
||||
}
|
||||
if (provider === 'shuncheng') {
|
||||
return shunchengGateways[environment] ?? shunchengGateways.production
|
||||
}
|
||||
return defaultGateways[provider] ?? ''
|
||||
}
|
||||
|
||||
function defaultNotifyURL(provider: string) {
|
||||
const path = defaultNotifyPaths[provider]
|
||||
return path ? `${window.location.origin}${path}` : ''
|
||||
}
|
||||
|
||||
function defaultJumpURL(provider: string) {
|
||||
return provider === 'mock' ? '' : `${window.location.origin}/orders`
|
||||
}
|
||||
|
||||
function defaultSignType(provider: string) {
|
||||
return provider === 'lakala' ? 'SHA256withRSA' : 'MD5'
|
||||
}
|
||||
|
||||
function defaultExtraConfig(provider: string): Record<string, unknown> {
|
||||
if (provider === 'lakala') {
|
||||
return {
|
||||
app_id: '',
|
||||
serial_no: '',
|
||||
term_no: '',
|
||||
lakala_cert: '',
|
||||
pay_mode: 'ALIPAY',
|
||||
order_expire_minutes: 15,
|
||||
}
|
||||
}
|
||||
if (provider === 'shuncheng') {
|
||||
return {
|
||||
secret_id: '',
|
||||
shop_no: '',
|
||||
refund_type: '',
|
||||
token_refresh_margin_seconds: 300,
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
function extraFormDefaults(provider: string) {
|
||||
const extra = defaultExtraConfig(provider)
|
||||
return {
|
||||
extra_app_id: String(extra.app_id ?? ''),
|
||||
extra_serial_no: String(extra.serial_no ?? ''),
|
||||
extra_term_no: String(extra.term_no ?? ''),
|
||||
extra_lakala_cert: String(extra.lakala_cert ?? ''),
|
||||
extra_pay_mode: String(extra.pay_mode ?? ''),
|
||||
extra_order_expire_minutes: Number(extra.order_expire_minutes ?? 15),
|
||||
extra_secret_id: String(extra.secret_id ?? ''),
|
||||
extra_shop_no: String(extra.shop_no ?? ''),
|
||||
extra_refund_type: String(extra.refund_type ?? ''),
|
||||
extra_token_refresh_margin_seconds: Number(extra.token_refresh_margin_seconds ?? 300),
|
||||
}
|
||||
}
|
||||
|
||||
interface ConfigFormValues {
|
||||
name: string
|
||||
provider: string
|
||||
merchant_id: string
|
||||
pay_way: string
|
||||
gateway_url?: string
|
||||
sign_key?: string
|
||||
notify_key?: string
|
||||
notify_url?: string
|
||||
jump_url?: string
|
||||
pay_way?: string
|
||||
jspay_flag?: string
|
||||
sign_type?: string
|
||||
is_default: boolean
|
||||
status: string
|
||||
environment: string
|
||||
jump_url?: string
|
||||
jspay_flag?: string
|
||||
sign_type?: string
|
||||
business_tags_text?: string
|
||||
extra_config_json?: string
|
||||
extra_app_id?: string
|
||||
extra_serial_no?: string
|
||||
extra_term_no?: string
|
||||
extra_lakala_cert?: string
|
||||
extra_pay_mode?: string
|
||||
extra_order_expire_minutes?: number
|
||||
extra_secret_id?: string
|
||||
extra_shop_no?: string
|
||||
extra_refund_type?: string
|
||||
extra_token_refresh_margin_seconds?: number
|
||||
}
|
||||
|
||||
function errorText(error: unknown) {
|
||||
@@ -88,21 +188,16 @@ function errorText(error: unknown) {
|
||||
return error instanceof Error ? error.message : '请求失败,请稍后重试'
|
||||
}
|
||||
|
||||
function parseExtraConfig(text?: string) {
|
||||
const trimmed = text?.trim()
|
||||
if (!trimmed) return undefined
|
||||
const parsed = JSON.parse(trimmed)
|
||||
if (!parsed || Array.isArray(parsed) || typeof parsed !== 'object') {
|
||||
throw new Error('额外配置必须是 JSON 对象')
|
||||
}
|
||||
return parsed as Record<string, unknown>
|
||||
}
|
||||
|
||||
export function AdminPaymentConfigsPage() {
|
||||
const { message, modal } = App.useApp()
|
||||
const queryClient = useQueryClient()
|
||||
const [form] = Form.useForm<ConfigFormValues>()
|
||||
const providerValue = Form.useWatch('provider', form)
|
||||
const isMock = providerValue === 'mock'
|
||||
const isLakala = providerValue === 'lakala'
|
||||
const isShuncheng = providerValue === 'shuncheng'
|
||||
const signKeyLabel = isLakala ? '商户私钥' : isShuncheng ? 'SecretKey' : '签名密钥'
|
||||
const notifyKeyLabel = isLakala ? '通知证书' : '通知密钥'
|
||||
const [draft, setDraft] = useState<AdminPaymentConfigQuery>({})
|
||||
const [filters, setFilters] = useState<AdminPaymentConfigQuery>({})
|
||||
const [page, setPage] = useState(1)
|
||||
@@ -149,65 +244,114 @@ export function AdminPaymentConfigsPage() {
|
||||
name: '',
|
||||
provider: 'leshua',
|
||||
merchant_id: '',
|
||||
gateway_url: '',
|
||||
pay_way: 'ZFBZF',
|
||||
gateway_url: defaultGateway('leshua', 'production'),
|
||||
sign_key: '',
|
||||
notify_key: '',
|
||||
notify_url: '',
|
||||
jump_url: '',
|
||||
pay_way: 'WXZF',
|
||||
jspay_flag: '',
|
||||
sign_type: 'MD5',
|
||||
notify_url: defaultNotifyURL('leshua'),
|
||||
jump_url: defaultJumpURL('leshua'),
|
||||
sign_type: defaultSignType('leshua'),
|
||||
jspay_flag: '2',
|
||||
is_default: false,
|
||||
status: 'active',
|
||||
environment: 'production',
|
||||
business_tags_text: '',
|
||||
extra_config_json: '',
|
||||
...extraFormDefaults('leshua'),
|
||||
})
|
||||
setEditorOpen(true)
|
||||
}
|
||||
|
||||
const openEdit = (row: AdminPaymentConfig) => {
|
||||
setEditing(row)
|
||||
const extra = { ...defaultExtraConfig(row.provider), ...(row.extra_config ?? {}) }
|
||||
form.setFieldsValue({
|
||||
name: row.name,
|
||||
provider: row.provider,
|
||||
merchant_id: row.merchant_id,
|
||||
pay_way: row.pay_way,
|
||||
gateway_url: row.gateway_url,
|
||||
sign_key: '',
|
||||
notify_key: '',
|
||||
notify_url: row.notify_url,
|
||||
jump_url: row.jump_url,
|
||||
pay_way: row.pay_way,
|
||||
jspay_flag: row.jspay_flag,
|
||||
sign_type: row.sign_type,
|
||||
is_default: row.is_default,
|
||||
status: row.status,
|
||||
environment: row.environment,
|
||||
business_tags_text: (row.business_tags ?? []).join(', '),
|
||||
extra_config_json: row.extra_config ? JSON.stringify(row.extra_config, null, 2) : '',
|
||||
extra_app_id: String(extra.app_id ?? ''),
|
||||
extra_serial_no: String(extra.serial_no ?? ''),
|
||||
extra_term_no: String(extra.term_no ?? ''),
|
||||
extra_lakala_cert: String(extra.lakala_cert ?? ''),
|
||||
extra_pay_mode: String(extra.pay_mode ?? ''),
|
||||
extra_order_expire_minutes: Number(extra.order_expire_minutes ?? 15),
|
||||
extra_secret_id: String(extra.secret_id ?? ''),
|
||||
extra_shop_no: String(extra.shop_no ?? ''),
|
||||
extra_refund_type: String(extra.refund_type ?? ''),
|
||||
extra_token_refresh_margin_seconds: Number(extra.token_refresh_margin_seconds ?? 300),
|
||||
})
|
||||
setEditorOpen(true)
|
||||
}
|
||||
|
||||
const handleProviderChange = (provider: string) => {
|
||||
if (editing) return
|
||||
const environment = (form.getFieldValue('environment') as string) || 'production'
|
||||
form.setFieldsValue({
|
||||
gateway_url: defaultGateway(provider, environment),
|
||||
notify_url: defaultNotifyURL(provider),
|
||||
jump_url: defaultJumpURL(provider),
|
||||
sign_type: defaultSignType(provider),
|
||||
jspay_flag: '2',
|
||||
...extraFormDefaults(provider),
|
||||
})
|
||||
}
|
||||
|
||||
const handlePayWayChange = (payWay: string | number) => {
|
||||
if (isLakala) {
|
||||
form.setFieldsValue({ extra_pay_mode: lakalaPayModeByPayWay[String(payWay)] ?? 'AUTO' })
|
||||
}
|
||||
}
|
||||
|
||||
const handleEnvironmentChange = (environment: string) => {
|
||||
const gateway = form.getFieldValue('gateway_url') as string | undefined
|
||||
if (isLakala && (!gateway || Object.values(lakalaGateways).includes(gateway))) {
|
||||
form.setFieldsValue({ gateway_url: defaultGateway('lakala', environment) })
|
||||
return
|
||||
}
|
||||
if (isShuncheng && (!gateway || Object.values(shunchengGateways).includes(gateway))) {
|
||||
form.setFieldsValue({ gateway_url: defaultGateway('shuncheng', environment) })
|
||||
}
|
||||
}
|
||||
|
||||
const buildPayload = (values: ConfigFormValues): AdminPaymentConfigPayload => {
|
||||
let extraConfig: Record<string, unknown> | undefined
|
||||
try {
|
||||
extraConfig = parseExtraConfig(values.extra_config_json)
|
||||
} catch (error) {
|
||||
throw new Error(error instanceof Error ? error.message : '额外配置 JSON 不正确', {
|
||||
cause: error,
|
||||
})
|
||||
if (values.provider === 'lakala') {
|
||||
const extra: Record<string, unknown> = {
|
||||
app_id: values.extra_app_id?.trim() ?? '',
|
||||
serial_no: values.extra_serial_no?.trim() ?? '',
|
||||
term_no: values.extra_term_no?.trim() ?? '',
|
||||
pay_mode: values.extra_pay_mode || 'AUTO',
|
||||
order_expire_minutes: values.extra_order_expire_minutes ?? 15,
|
||||
}
|
||||
if (values.extra_lakala_cert?.trim()) extra.lakala_cert = values.extra_lakala_cert.trim()
|
||||
extraConfig = extra
|
||||
} else if (values.provider === 'shuncheng') {
|
||||
const extra: Record<string, unknown> = {
|
||||
secret_id: values.extra_secret_id?.trim() ?? '',
|
||||
token_refresh_margin_seconds: values.extra_token_refresh_margin_seconds ?? 300,
|
||||
}
|
||||
if (values.extra_shop_no?.trim()) extra.shop_no = values.extra_shop_no.trim()
|
||||
if (values.extra_refund_type !== undefined && values.extra_refund_type !== '') {
|
||||
extra.refund_type = values.extra_refund_type
|
||||
}
|
||||
extraConfig = extra
|
||||
}
|
||||
const payload: AdminPaymentConfigPayload = {
|
||||
name: values.name.trim(),
|
||||
provider: values.provider,
|
||||
merchant_id: values.merchant_id.trim(),
|
||||
gateway_url: values.gateway_url?.trim() || '',
|
||||
notify_url: values.notify_url?.trim() || '',
|
||||
jump_url: values.jump_url?.trim() || '',
|
||||
pay_way: values.pay_way,
|
||||
jspay_flag: values.jspay_flag?.trim() || '',
|
||||
sign_type: values.sign_type,
|
||||
is_default: values.is_default,
|
||||
status: values.status,
|
||||
environment: values.environment,
|
||||
@@ -215,10 +359,17 @@ export function AdminPaymentConfigsPage() {
|
||||
.split(',')
|
||||
.map(item => item.trim())
|
||||
.filter(Boolean),
|
||||
extra_config: extraConfig,
|
||||
}
|
||||
if (values.sign_key?.trim()) payload.sign_key = values.sign_key.trim()
|
||||
if (values.notify_key?.trim()) payload.notify_key = values.notify_key.trim()
|
||||
if (values.provider !== 'mock') {
|
||||
payload.gateway_url = values.gateway_url?.trim() ?? ''
|
||||
payload.notify_url = values.notify_url?.trim() ?? ''
|
||||
payload.jump_url = values.jump_url?.trim() ?? ''
|
||||
payload.jspay_flag = values.jspay_flag?.trim() ?? ''
|
||||
payload.sign_type = values.sign_type
|
||||
payload.extra_config = extraConfig
|
||||
if (values.sign_key?.trim()) payload.sign_key = values.sign_key.trim()
|
||||
if (values.notify_key?.trim()) payload.notify_key = values.notify_key.trim()
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
@@ -556,69 +707,178 @@ export function AdminPaymentConfigsPage() {
|
||||
<Form<ConfigFormValues> form={form} layout="vertical" disabled={submitting}>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Form.Item name="name" label="配置名称" rules={[{ required: true }]}>
|
||||
<Input maxLength={128} />
|
||||
<Form.Item
|
||||
name="name"
|
||||
label="配置名称"
|
||||
rules={[{ required: true, message: '请输入配置名称' }]}
|
||||
>
|
||||
<Input maxLength={128} placeholder="如:乐刷生产商户1" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item name="provider" label="服务商" rules={[{ required: true }]}>
|
||||
<Select options={providerOptions} disabled={Boolean(editing)} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Form.Item name="merchant_id" label="商户号" rules={[{ required: true }]}>
|
||||
<Input maxLength={128} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item name="pay_way" label="支付方式">
|
||||
<Select allowClear options={payWayOptions} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Form.Item name="gateway_url" label="网关地址">
|
||||
<Input maxLength={512} />
|
||||
</Form.Item>
|
||||
<Form.Item name="notify_url" label="回调地址">
|
||||
<Input maxLength={512} />
|
||||
</Form.Item>
|
||||
<Form.Item name="jump_url" label="跳转地址">
|
||||
<Input maxLength={512} />
|
||||
</Form.Item>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="sign_key"
|
||||
label="SignKey"
|
||||
extra={editing ? '留空不修改' : '按服务商要求填写'}
|
||||
>
|
||||
<Input.Password autoComplete="new-password" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="notify_key"
|
||||
label="NotifyKey"
|
||||
extra={editing ? '留空不修改' : '按服务商要求填写'}
|
||||
>
|
||||
<Input.Password autoComplete="new-password" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={16}>
|
||||
<Col span={8}>
|
||||
<Form.Item name="sign_type" label="签名类型">
|
||||
<Select
|
||||
allowClear
|
||||
options={[
|
||||
{ value: 'MD5', label: 'MD5' },
|
||||
{ value: 'SHA256withRSA', label: 'SHA256withRSA' },
|
||||
]}
|
||||
options={providerOptions}
|
||||
disabled={Boolean(editing)}
|
||||
onChange={handleProviderChange}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="merchant_id"
|
||||
label="商户号"
|
||||
rules={[{ required: true, message: '请输入商户号' }]}
|
||||
>
|
||||
<Input maxLength={128} placeholder="渠道商户号" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item name="pay_way" label="支付方式" rules={[{ required: true }]}>
|
||||
<Segmented
|
||||
options={[
|
||||
{ label: '支付宝', value: 'ZFBZF' },
|
||||
{ label: '微信', value: 'WXZF' },
|
||||
]}
|
||||
onChange={value => handlePayWayChange(value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{!isMock ? (
|
||||
<Form.Item
|
||||
name="gateway_url"
|
||||
label="网关地址"
|
||||
rules={[{ required: true, message: '请输入支付网关地址' }]}
|
||||
>
|
||||
<Input maxLength={512} />
|
||||
</Form.Item>
|
||||
) : null}
|
||||
|
||||
{isLakala ? (
|
||||
<Row gutter={16}>
|
||||
<Col span={8}>
|
||||
<Form.Item
|
||||
name="extra_app_id"
|
||||
label="App ID"
|
||||
rules={[{ required: true, message: '请输入拉卡拉开放平台 App ID' }]}
|
||||
>
|
||||
<Input maxLength={128} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Form.Item
|
||||
name="extra_serial_no"
|
||||
label="证书序列号"
|
||||
rules={[{ required: true, message: '请输入商户证书序列号' }]}
|
||||
>
|
||||
<Input maxLength={128} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Form.Item
|
||||
name="extra_term_no"
|
||||
label="终端号"
|
||||
rules={[{ required: true, message: '请输入拉卡拉终端号' }]}
|
||||
>
|
||||
<Input maxLength={64} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
) : null}
|
||||
|
||||
{isShuncheng ? (
|
||||
<Form.Item
|
||||
name="extra_secret_id"
|
||||
label="Secret ID"
|
||||
rules={[{ required: true, message: '请输入顺成 Secret ID' }]}
|
||||
>
|
||||
<Input maxLength={128} />
|
||||
</Form.Item>
|
||||
) : null}
|
||||
|
||||
{!isMock ? (
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="sign_key"
|
||||
label={signKeyLabel}
|
||||
rules={
|
||||
editing
|
||||
? undefined
|
||||
: [
|
||||
{
|
||||
required: true,
|
||||
message: isLakala ? '请输入商户私钥 PEM' : '请输入签名密钥',
|
||||
},
|
||||
]
|
||||
}
|
||||
extra={editing ? '留空不修改' : undefined}
|
||||
>
|
||||
{isLakala ? (
|
||||
<Input.TextArea
|
||||
rows={5}
|
||||
placeholder="请输入商户私钥 PEM"
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
) : (
|
||||
<Input.Password placeholder="请输入签名密钥" autoComplete="new-password" />
|
||||
)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="notify_key"
|
||||
label={notifyKeyLabel}
|
||||
rules={
|
||||
editing
|
||||
? undefined
|
||||
: [
|
||||
{
|
||||
required: true,
|
||||
message: isLakala ? '请输入通知验签证书 PEM' : '请输入通知密钥',
|
||||
},
|
||||
]
|
||||
}
|
||||
extra={editing ? '留空不修改' : undefined}
|
||||
>
|
||||
{isLakala ? (
|
||||
<Input.TextArea
|
||||
rows={5}
|
||||
placeholder="请输入拉卡拉通知验签证书 PEM"
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
) : (
|
||||
<Input.Password placeholder="请输入通知密钥" autoComplete="new-password" />
|
||||
)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
) : null}
|
||||
|
||||
{!isMock ? (
|
||||
<Form.Item
|
||||
name="notify_url"
|
||||
label="回调地址"
|
||||
rules={[{ required: true, message: '请输入异步通知回调地址' }]}
|
||||
>
|
||||
<Input maxLength={512} />
|
||||
</Form.Item>
|
||||
) : null}
|
||||
|
||||
<Form.Item
|
||||
name="is_default"
|
||||
label="是否默认"
|
||||
valuePropName="checked"
|
||||
extra="同一支付方式只保留一个启用默认配置"
|
||||
>
|
||||
<Switch checkedChildren="默认" unCheckedChildren="普通" />
|
||||
</Form.Item>
|
||||
|
||||
<Row gutter={16}>
|
||||
<Col span={8}>
|
||||
<Form.Item name="status" label="状态">
|
||||
<Select options={statusOptions} />
|
||||
@@ -631,35 +891,113 @@ export function AdminPaymentConfigsPage() {
|
||||
{ value: 'production', label: '生产' },
|
||||
{ value: 'sandbox', label: '沙箱' },
|
||||
]}
|
||||
onChange={handleEnvironmentChange}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Form.Item name="jspay_flag" label="JSAPI 标识">
|
||||
<Input maxLength={64} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item name="is_default" label="默认配置" valuePropName="checked">
|
||||
<Switch checkedChildren="默认" unCheckedChildren="普通" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Form.Item name="business_tags_text" label="业务标签" extra="逗号分隔">
|
||||
<Input maxLength={255} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="extra_config_json"
|
||||
label="额外配置 JSON"
|
||||
extra="拉卡拉需 app_id / serial_no / term_no;顺诚需 secret_id"
|
||||
>
|
||||
<Input.TextArea
|
||||
rows={5}
|
||||
placeholder='{"app_id":"...","serial_no":"...","term_no":"..."}'
|
||||
/>
|
||||
<Input maxLength={255} placeholder="逗号分隔" />
|
||||
</Form.Item>
|
||||
|
||||
<Collapse
|
||||
ghost
|
||||
items={[
|
||||
{
|
||||
key: 'advanced',
|
||||
label: '高级配置',
|
||||
children: (
|
||||
<>
|
||||
<Form.Item name="jump_url" label="跳转地址">
|
||||
<Input maxLength={512} placeholder="支付完成跳转地址" />
|
||||
</Form.Item>
|
||||
{isLakala ? (
|
||||
<>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Form.Item name="extra_pay_mode" label="拉卡拉模式">
|
||||
<Select
|
||||
options={[
|
||||
{ value: 'ALIPAY', label: '支付宝' },
|
||||
{ value: 'WECHAT', label: '微信' },
|
||||
{ value: 'AUTO', label: '不限制,由收银台选择' },
|
||||
{ value: 'UQRCODEPAY', label: '银联' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item name="extra_order_expire_minutes" label="有效期分钟">
|
||||
<InputNumber min={1} max={1440} style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Form.Item
|
||||
name="extra_lakala_cert"
|
||||
label="平台证书"
|
||||
extra="拉卡拉平台响应验签证书 PEM,可与通知证书一致"
|
||||
>
|
||||
<Input.TextArea rows={4} />
|
||||
</Form.Item>
|
||||
</>
|
||||
) : null}
|
||||
{isShuncheng ? (
|
||||
<Row gutter={16}>
|
||||
<Col span={8}>
|
||||
<Form.Item name="extra_shop_no" label="门店编号">
|
||||
<Input maxLength={64} placeholder="可选,顺成商户门店编号" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Form.Item name="extra_refund_type" label="退款出资">
|
||||
<Select
|
||||
options={[
|
||||
{ value: '', label: '顺成默认' },
|
||||
{ value: '0', label: '当日交易抵扣' },
|
||||
{ value: '1', label: '优先交易抵扣,不足走余额' },
|
||||
{ value: '2', label: '仅商户余额' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Form.Item name="extra_token_refresh_margin_seconds" label="Token 刷新秒">
|
||||
<InputNumber min={60} max={1800} style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
) : null}
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Form.Item name="jspay_flag" label="支付形态">
|
||||
<Select
|
||||
allowClear
|
||||
options={[
|
||||
{ value: '1', label: 'H5 / JSAPI' },
|
||||
{ value: '2', label: '简易支付 / 收银台' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item name="sign_type" label="签名类型">
|
||||
<Select
|
||||
allowClear
|
||||
options={[
|
||||
{ value: 'MD5', label: 'MD5' },
|
||||
{ value: 'SHA256withRSA', label: 'SHA256withRSA' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<Typography.Paragraph type="secondary" className="admin-form-hint">
|
||||
<CreditCardOutlined /> 支付配置变更会记录审计日志;密钥不会回显。
|
||||
</Typography.Paragraph>
|
||||
|
||||
Reference in New Issue
Block a user