跳转至

配置支付方式

场景:admin 配置平台支持的支付方式(开关 + 通道参数) 实际路径:admin 后台 → 维护 → 配置管理 → 支付配置


📋 演示脚本

演示准备

  1. 登录 admin 后台 https://mall.ijcode.com/admin/login
  2. 账号:admin / admin123

演示步骤

步骤 1:进入 admin 后台

打开 admin 后台登录页,输入 admin 账号密码登录(验证码可通过 Redis 注入绕过)。

登录后看到工作台首页:

admin 工作台

步骤 2:导航到配置管理

从左侧菜单:维护配置管理

路径:左侧菜单"维护"展开后看到"配置管理"链接

配置管理列表

页面展示所有现有配置项的列表(配置 key、说明、类型、是否显示、操作),顶部有"添加配置"按钮可新增配置项。

步骤 3:进入支付配置分类

在配置管理页面,从左侧分类树选择 "支付配置"(或上方 tab 切换到支付配置):

支付基础配置

实际功能

  • 添加配置:点击右上角"添加配置"按钮,弹窗中填写配置 key、说明、类型、选项、值
  • 编辑配置:点击操作列的"编辑",弹窗中修改当前值
  • 删除配置:点击操作列的"删除"
  • 显示/隐藏:切换"是否显示"开关

步骤 4:关键支付开关

主要支付相关配置项(位于 ij_system_config_value 表):

配置 key 作用 默认值
yue_pay_status 余额支付开关 1(开)
balance_func_status 余额功能开关(充值/提现) 1(开)
pay_weixin_open 微信支付开关 0(关)
pay_routine_open 小程序支付开关 0(关)
alipay_open 支付宝开关 0(关)
offline_switch 货到付款开关 0(关)

🎓 培训材料

配置生效机制

admin 在后台修改配置
  ↓
save config_value
  ↓
写入 ij_system_config_value 表(值 JSON 编码)
  ↓
Redis 缓存 merchant_sys_config_0:<key> 600 秒
  ↓
下次用户访问 /api/order/pay 时读取最新配置

关键

  • 配置修改后不会立即对在线用户生效(缓存 600 秒)
  • 需要立即生效:手动清缓存 redis-cli DEL merchant_sys_config_0:<key>

常见演示场景

  1. 演示余额支付流程 → 确保 yue_pay_status=1 + balance_func_status=1
  2. 演示关闭某个支付方式 → 把对应开关改成 0 → 用户端支付页不再显示该选项
  3. 演示修改充值套餐 → 编辑 group_data/user_recharge_quota 项 → 用户端充值页实时更新

必懂:测试 vs 生产

配置项 测试服(mall.ijcode.com) 生产(待部署)
余额支付 ✅ 开启 ✅ 开启
微信支付 ❌ 关闭(DB 无商户号) ❌ 待配置
支付宝 ❌ 关闭(DB 无密钥) ❌ 待配置

🔧 故障排查

场景 A:用户端支付页看不到某个支付方式

排查步骤

  1. 后台确认对应开关已开启
  2. 确认配置项 value 非空
  3. 清 Redis 缓存
    redis-cli -a <password> DEL merchant_sys_config_0:yue_pay_status
    redis-cli -a <password> DEL merchant_sys_config_0:balance_func_status
    
  4. 用户端刷新页面

场景 B:配置保存失败(提示"系统错误")

排查

  1. 看 swoole error log:runtime/log/$(date +%Y%m%d)_error.log
  2. 可能是 JSON 编码失败(值含非法字符)
  3. 可能是 merchant_id 不匹配(编辑时不允许改 mer_id)

场景 C:配置修改后没生效(缓存问题)

# 查看当前缓存值
redis-cli -a <password> GET merchant_sys_config_0:yue_pay_status

# 删缓存
redis-cli -a <password> DEL merchant_sys_config_0:yue_pay_status

# 等 600 秒也会自动失效

⚙️ 后端关键点

存储位置

  • ij_system_config_value
  • 关键列config_keyvalue(JSON 编码)、mer_id(0=全局)
  • 查询 APIPOST /sys/config/save/:key
  • 读 APIGET /sys/config/value?key=...

数据流向

// 后端实现位置
app/common/repositories/system/config/ConfigValueRepository.php
  ├─ public function get($key)         // 读单个配置
  ├─ public function more(array $keys) // 批量读
  └─ private function clearCache($merId = 0)  // 清缓存(Round 36 改为细粒度 Lua)

// 商户写时的强制校验
crmeb/services/merchant/MerchantWriteGuardService.php
  └─ 校验 merchant 字段不允许改(除 super admin)

Redis 缓存机制(Round 36 修复)

-- 修复前:clearCache() 实际 flushDB(清整个 Redis!破坏其他业务)
-- 修复后:Lua EVAL 精确删除 prefix = "merchant_sys_config_<merId>:"
EVAL "for _,k in ipairs(redis.call('KEYS', KEYS[1])) do redis.call('DEL', k) end"
  KEYS[1] = 'merchant_sys_config_0:*'

关联场景