diff --git a/backend/internal/service/payment/waffo.go b/backend/internal/service/payment/waffo.go
index c8bb58d..cccd73e 100644
--- a/backend/internal/service/payment/waffo.go
+++ b/backend/internal/service/payment/waffo.go
@@ -453,15 +453,17 @@ func productIDForPlan(cfg WaffoConfig, planType string) string {
}
func currencyForPlan(cfg WaffoConfig, planType string) string {
- switch strings.TrimSpace(planType) {
+ switch strings.TrimSpace(strings.ToLower(planType)) {
case "yearly", "monthly":
if cfg.CurrencyYearly != "" {
return cfg.CurrencyYearly
}
+ return "CNY" // OpsXshell 包年默认人民币 // Logan.Li
case "perpetual", "lifetime":
if cfg.CurrencyPerpetual != "" {
return cfg.CurrencyPerpetual
}
+ return "USD" // OpsXshell 永久默认美元 // Logan.Li
}
if cfg.Currency != "" {
return cfg.Currency
diff --git a/frontend/src/views/Payments.vue b/frontend/src/views/Payments.vue
index f9fd638..3d960ad 100644
--- a/frontend/src/views/Payments.vue
+++ b/frontend/src/views/Payments.vue
@@ -22,7 +22,7 @@
type="info"
:closable="false"
show-icon
- title="测试 / 生产的私钥与 Product 映射相互隔离。改映射后需点「保存」;调试不会自动写库。生产 create-session 需 Waffo 门店已 Go-Live。"
+ title="改映射后需点「保存」。调试只探测不写库。生产 create-session 需 Waffo 门店已 Go-Live。"
style="margin-bottom: 16px"
/>
@@ -46,7 +46,7 @@
{{ isLive ? 'live' : 'test' }}
-
切换前会暂存当前映射到对应环境;未配置私钥的环境需单独粘贴保存。
+ 测试 / 生产私钥与 Product 映射隔离;未配私钥的环境需单独粘贴保存。
@@ -76,10 +76,6 @@
style="margin-top: 8px"
/>
-
-
- 映射表可按计划覆盖(包年 CNY / 永久 USD)
-
@@ -111,7 +107,7 @@
type="warning"
:closable="false"
show-icon
- title="调试按钮不会写库。改完映射请点右上角「保存配置」。生产与测试可点「填充 OpsXshell 商品」一键写入包年/永久 Product ID。"
+ title="下单时按计划选用对应 PROD_xxx:包年→yearly,永久→perpetual。货币由后端按计划自动带(包年 CNY / 永久 USD),无需手填。"
style="margin-bottom: 12px"
/>
@@ -129,24 +125,16 @@
-
+
-
+
-
-
-
-
-
-
-
-
删除
@@ -169,19 +157,17 @@ import { getWaffoSettings, updateWaffoSettings, testWaffoConnection } from '@/ap
const planKeyOptions = ['trial', 'yearly', 'perpetual', 'monthly', 'lifetime']
-// OpsXshell 线上商品(pancake 购买链接对应) // Logan.Li
+// OpsXshell 线上商品(与 pancake 购买链接一致) // Logan.Li
const OPSXSHELL_PRODUCTS = [
{
plan_key: 'yearly',
label: 'OpsXshell Yearly',
product_id: 'PROD_5PqVJyEiCM4nDgVoA0RKjN',
- currency: 'CNY',
},
{
plan_key: 'perpetual',
label: 'OpsXshell Perpetual',
product_id: 'PROD_3BSJqDRkVBoYNgO78NsTAU',
- currency: 'USD',
},
]
@@ -217,8 +203,8 @@ const isLive = computed(() => waffo.environment === 'live')
function defaultMappings() {
return [
- { plan_key: 'yearly', label: '包年', product_id: '', currency: 'CNY' },
- { plan_key: 'perpetual', label: '永久', product_id: '', currency: 'USD' },
+ { plan_key: 'yearly', label: '包年', product_id: '' },
+ { plan_key: 'perpetual', label: '永久', product_id: '' },
]
}
@@ -228,30 +214,24 @@ function normalizeMappings(data = {}) {
plan_key: m.plan_key || m.key || m.plan_type || '',
label: m.label || '',
product_id: m.product_id || '',
- currency: (m.currency || '').toUpperCase() || guessCurrency(m.plan_key),
}))
}
const rows = []
if (data.product_id_yearly) {
- rows.push({
- plan_key: 'yearly',
- label: '包年',
- product_id: data.product_id_yearly,
- currency: 'CNY',
- })
+ rows.push({ plan_key: 'yearly', label: '包年', product_id: data.product_id_yearly })
}
if (data.product_id_perpetual || data.product_id) {
rows.push({
plan_key: 'perpetual',
label: '永久',
product_id: data.product_id_perpetual || data.product_id,
- currency: 'USD',
})
}
return rows.length ? rows : defaultMappings()
}
-function guessCurrency(planKey) {
+// 按计划自动带货币,不再展示币种列 // Logan.Li
+function currencyForKey(planKey) {
const k = (planKey || '').toLowerCase()
if (k === 'perpetual' || k === 'lifetime') return 'USD'
return 'CNY'
@@ -259,12 +239,10 @@ function guessCurrency(planKey) {
function mappingsToCompatFields(rows) {
const map = {}
- const currencyMap = {}
for (const row of rows) {
const key = (row.plan_key || '').trim()
if (!key) continue
map[key] = (row.product_id || '').trim()
- currencyMap[key] = (row.currency || '').trim().toUpperCase()
}
return {
product_mappings: rows
@@ -273,13 +251,13 @@ function mappingsToCompatFields(rows) {
plan_key: r.plan_key.trim(),
label: r.label || '',
product_id: (r.product_id || '').trim(),
- currency: (r.currency || '').trim().toUpperCase(),
+ currency: currencyForKey(r.plan_key),
})),
product_id_yearly: map.yearly || '',
product_id_perpetual: map.perpetual || map.lifetime || '',
product_id: map.perpetual || map.lifetime || map.yearly || '',
- currency_yearly: currencyMap.yearly || '',
- currency_perpetual: currencyMap.perpetual || currencyMap.lifetime || '',
+ currency_yearly: 'CNY',
+ currency_perpetual: 'USD',
}
}
@@ -307,14 +285,13 @@ function onEnvSwitch(live) {
const next = live ? 'live' : 'test'
const prev = waffo.environment === 'live' ? 'live' : 'test'
if (next === prev) return
- // 必须先把当前表写入「切换前」环境,再加载目标环境(勿用会提前改 environment 的 v-model) // Logan.Li
stashEnv(prev)
applyEnv(next)
ElMessage.info(live ? '已切换到生产映射(记得保存)' : '已切换到测试映射(记得保存)')
}
function addMapping() {
- productMappings.value.push({ plan_key: '', label: '', product_id: '', currency: 'CNY' })
+ productMappings.value.push({ plan_key: '', label: '', product_id: '' })
}
function removeMapping(index) {
@@ -328,12 +305,10 @@ function fillOpsxshellProducts() {
if (byKey[item.plan_key]) {
byKey[item.plan_key].product_id = item.product_id
byKey[item.plan_key].label = item.label
- byKey[item.plan_key].currency = item.currency
} else {
productMappings.value.push({ ...item })
}
}
- // 保证 yearly / perpetual 在前 // Logan.Li
const order = ['yearly', 'perpetual']
productMappings.value.sort((a, b) => {
const ia = order.indexOf(a.plan_key)
@@ -397,7 +372,7 @@ async function save() {
store_id: waffo.store_id,
store_slug: waffo.store_slug,
environment: waffo.environment,
- currency: waffo.currency,
+ currency: waffo.currency || 'CNY',
success_url: waffo.success_url,
clear_private_key: clearKeyFlag.value,
...compat,