对话笔记直发:7.9 虚拟支付 沙箱切到现网。分类:小程序接单。
1.当前项目目录下的小程序使用的是沙箱。模式如何切换到现网模式。改哪些参数?改完之后需要重启后台服务吗? 2.如果我把沙箱 和 现网的切换操作添加到后台,让商家后台管理界面 可以手动点击按钮 切换 沙箱和现网 3.甚至可以在后台管理界面手动输入虚拟支付的相关的所有参数 (比如 AppID、OfferID、沙箱 API Key、线网 API Key,以及虚拟支付商户号等参数配置)。 目前这些参数配置是直接保存在一个配置文件中吗?后期如果变更虚拟支付主体的所有信息的话,是不是只需要修改这一个配置文件,然后重启对应的后台就可以了? 从第一性原理出发,用奥卡姆剃刀定律来看,你建议不建议把这些参数放到商家后台进行可视化编辑配置,从而支持商家在后台直接进行切换?
结论
- 当前项目虚拟支付确实处于沙箱模式:有效配置来自
yoshop2.0/.env的[VIRTUAL_PAYMENT] ENV = 1。 - 切到现网最小改动是把
ENV从1改成0,并确保使用PRODUCTION_APP_KEY。 - 不需要重新发布小程序前端,因为小程序端使用后台返回的
signData/paySig/signature/env;但如果改的是.env,我建议至少 reload/restart PHP 后台进程和队列/定时任务,避免长驻进程继续读旧配置。 - 不建议把所有虚拟支付密钥参数开放给普通商家后台随意编辑。从第一性原理看,虚拟支付配置属于“签名密钥 + 收款主体 + 交易环境”的高风险生产配置,应该优先由部署/超级管理员管理;后台最多做“只读展示 + 健康检查 + 超级管理员受控切换”。
1. 当前项目如何从沙箱切到现网?
当前有效配置在:
yoshop2.0/.env
[VIRTUAL_PAYMENT]
ENABLED = 1
ENV = 1
OFFER_ID = ...
SANDBOX_APP_KEY = ...
PRODUCTION_APP_KEY = ...
MERCHANT_ID = ...
NOTIFY_BASE_URL = ...
MESSAGE_PUSH_TOKEN = ...
MESSAGE_PUSH_ENCODING_AES_KEY = ...
其中:
ENV = 1 // 沙箱
ENV = 0 // 现网
所以切换现网最小改动是:
[VIRTUAL_PAYMENT]
ENABLED = 1
-ENV = 1
+ENV = 0
OFFER_ID = 你的虚拟支付应用 ID
SANDBOX_APP_KEY = 沙箱 AppKey
PRODUCTION_APP_KEY = 现网 AppKey
MERCHANT_ID = 虚拟支付商户号
NOTIFY_BASE_URL = 正式回调域名
MESSAGE_PUSH_TOKEN = 消息推送 Token
MESSAGE_PUSH_ENCODING_AES_KEY = 消息推送 EncodingAESKey
代码依据:
Payment.php会把$config['env']写进signData.env。- 当
env === 1时使用sandbox_app_key。 - 当
env === 0时使用production_app_key。
也就是这里:
$env = (int)$config['env'];
$signDataPayload = [
'offerId' => (string)$config['offer_id'],
'env' => $env,
...
];
$appKey = $env === CommonGoodsModel::VP_ENV_SANDBOX
? (string)$config['sandbox_app_key']
: (string)$config['production_app_key'];
对应文件:
yoshop2.0/app/api/service/cashier/Payment.php
2. 改哪些参数?
必改
| 参数 | 当前含义 | 沙箱 | 现网 |
|---|---|---|---|
ENV | 虚拟支付环境 | 1 | 0 |
必须确认
| 参数 | 说明 |
|---|---|
PRODUCTION_APP_KEY | 现网签名密钥,ENV=0 时必须有值 |
OFFER_ID | 虚拟支付应用 ID,必须属于当前小程序/虚拟支付主体 |
MERCHANT_ID | 虚拟支付商户号 |
NOTIFY_BASE_URL | 回调基础域名,现网必须公网可访问、HTTPS、已在微信侧配置 |
MESSAGE_PUSH_TOKEN | 微信消息推送 Token |
MESSAGE_PUSH_ENCODING_AES_KEY | 微信消息推送 AES Key |
商品 vp_product_id | 必须已经在微信虚拟支付后台现网道具配置中创建、发布并生效 |
商品 vp_price_snapshot | 必须和微信后台道具价格一致,单位是分 |
不属于这个配置块,但也相关
AppID/AppSecret 不在 [VIRTUAL_PAYMENT] 里,而是在小程序基础配置里:
yoshop_wxapp_setting.key = basic
values.app_id
values.app_secret
代码里查单、发货确认等会读取:
WxappSettingModel::getConfigBasic()
所以如果你是“换虚拟支付主体 / 换小程序主体”,不是只改 [VIRTUAL_PAYMENT],还要同步检查小程序 AppID/AppSecret。
3. 改完之后需要重启后台服务吗?
分情况。
A. 当前这种:改 .env
建议做:
- 修改
yoshop2.0/.env:ENV=0- 确认
PRODUCTION_APP_KEY有值。
- reload/restart PHP 后台进程:
- PHP-FPM:建议
reload或restart。 - 如果有 supervisor / queue / timer / 常驻任务,也要重启这些 worker。
- PHP-FPM:建议
- 不需要重新发布小程序前端。
- 用一笔小额现网订单验证:
signData.env是否为0- 日志里
app_key_scope是否为production - 前端是否能调起支付
- 服务端是否能收到回调并发货
严格说,普通 PHP-FPM 每次请求会重新初始化应用,可能不重启也能读到新 .env;但支付配置是生产交易配置,不要赌运行时缓存/长驻进程行为,我建议改完就 reload/restart。
B. 如果以后改成后台数据库配置
走 SettingModel::edit() 保存时,代码会自动删除:
Cache::delete('setting_' . self::$storeId);
也就是如果通过后台 API 正常保存配置,通常不需要重启 Web 后台,只需要确保:
- 没有
.env覆盖; - 队列/定时任务不是长驻旧配置;
- 支付相关缓存已失效。
4. 当前这些参数是保存在一个配置文件中吗?
不是完全是。当前是“DB 默认/存储 + .env 覆盖”的混合模式。
代码逻辑是:
StoreSettingModel::getItem(SettingEnum::VIRTUAL_PAYMENT)
先从 store_setting 读取配置,然后这里会用 .env 覆盖:
private const VIRTUAL_PAYMENT_ENV_MAP = [
'enabled' => ['virtual_payment.enabled', null],
'env' => ['virtual_payment.env', null],
'offer_id' => ['virtual_payment.offer_id', null],
'sandbox_app_key' => ['virtual_payment.sandbox_app_key', null],
'production_app_key' => ['virtual_payment.production_app_key', null],
'merchant_id' => ['virtual_payment.merchant_id', null],
'notify_base_url' => ['virtual_payment.notify_base_url', null],
'message_push_token' => ['virtual_payment.message_push_token', null],
'message_push_encoding_aes_key' => ['virtual_payment.message_push_encoding_aes_key', null],
];
也就是说:
store_setting里可以存virtual_payment;- 但
.env [VIRTUAL_PAYMENT]中有值时,.env优先级更高; - 当前项目实际有效值主要来自
.env; - 小程序
AppID/AppSecret又在wxapp_setting,不在这个配置块。
所以如果你现在直接做一个商家后台页面保存到数据库,只要 .env 还配置了这些字段,后台保存的值可能不会生效。
5. 如果后期变更虚拟支付主体,是不是只改一个配置文件 + 重启后台?
不建议这么理解。
如果只是同一个主体从沙箱切现网:
ENV: 1 -> 0
基本可以认为是“小改配置 + 重启/reload + 验证”。
但如果是“变更虚拟支付主体 / 换小程序 / 换商户号 / 换 OfferID”,那不只是一个配置文件:
需要同步检查
-
小程序基础配置:
AppIDAppSecret
-
虚拟支付配置:
OfferID- 沙箱 AppKey
- 现网 AppKey
- 虚拟支付商户号
- 回调域名
- 消息推送 Token
- 消息推送 EncodingAESKey
-
商品配置:
- 当前商品表里的
vp_product_id vp_price_snapshot- 微信虚拟支付后台是否已经创建并发布同名道具
- 当前商品表里的
-
微信公众平台配置:
- 虚拟支付基础配置
- 道具配置
- 回调地址
- 消息推送配置
- 沙箱测试白名单
- 服务器域名
-
历史订单风险:
- 当前代码查单、发货确认、退款等会读取“当前配置”。
- 如果你切了主体,旧订单可能还需要旧主体的 AppKey/AppID 才能继续查单、发货确认或退款。
- 因此生产环境不能在有未完成虚拟支付订单时随意换主体。
6. 是否建议把这些参数放到商家后台可视化编辑?
我的建议分层:
不建议:普通商家后台可随意编辑全部参数
尤其不建议让普通商家自己改:
AppIDAppSecretSANDBOX_APP_KEYPRODUCTION_APP_KEYMERCHANT_IDOFFER_IDMESSAGE_PUSH_TOKENMESSAGE_PUSH_ENCODING_AES_KEY
原因很简单:这些不是普通业务配置,而是支付签名和收款主体配置。一旦填错:
- 轻则用户无法支付;
- 重则订单支付成功但发货/查单/退款失败;
- 更严重的是密钥泄露、误切主体、历史订单不可追踪。
可以做:超级管理员受控配置页
如果你的业务目标是“部署后不想每次改 .env”,可以做,但我建议只给超级管理员/技术管理员开放,并加保护:
后台可视化配置应具备
-
权限隔离
- 只有平台超级管理员可编辑。
- 普通商家最多看状态,不允许改密钥。
-
密钥脱敏
- 列表和详情只显示前后几位。
- 不回显完整 AppKey/AppSecret/AESKey。
- 修改时采用“留空表示不变”。
-
加密存储
- 不要明文存在
store_setting.values。 - 至少应用层加密。
- 数据库备份泄露时不能直接暴露支付密钥。
- 不要明文存在
-
审计日志
- 谁改的?
- 什么时候改的?
- 从哪个环境切到哪个环境?
- 改了哪些字段?
- 不记录完整密钥,只记录字段变更。
-
二次确认
- 沙箱 -> 现网必须二次确认。
- 现网 -> 沙箱在 release 小程序上会导致支付不可用,也必须强提示。
-
配置体检
- 保存后自动检查:
enabledenv
- 保存后自动检查: