【原创】独角兽商店接上 V免签,自动发货全流程跑通了!易支付 | V免签 | 支付宝 | 微信

【原创】独角兽商店接上 V免签,自动发货全流程跑通了!易支付 | V免签 | 支付宝 | 微信

新版独角兽商店移除了V免签支付支持,无法直接通过易支付网关兼容。作者自行开发并开源了一个协议转换网关,在商店的标准易支付接口与V免签原生API之间进行翻译,使支付链路恢复。

网关通过Docker和Nginx反向代理部署,配置后实测下单、异步回调与自动发货全流程正常。同时整理了配置要点、常见排障方法与安全建议。

前两天我把发卡站从零搭了一遍,用的是独角兽商店 dujiao-next。搭完发现一个大坑:新版把 V免签的支付方式砍了。折腾了一晚上,最后自己写了个协议转换网关把它接上了,全流程实测通过,代码也开源了。

图片[1]-【原创】独角兽商店接上 V免签,自动发货全流程跑通了!易支付 | V免签 | 支付宝 | 微信-Appstoy-发现好软件,让AI更好用

踩坑:新版没有 V免签

老版 dujiaoka 是支持 V免签的,很多人都这么用。我装完新版 dujiao-next v1.4.3,去后台找支付渠道,翻遍了没找到。

不信邪,我把容器里的程序拉出来看了下支付驱动白名单:

docker exec dujiao-next sh -c 'strings ./dujiao-next | grep -oE "epay_[a-z_]+"'

内置一共 8 种:official、epay、dujiaopay、bepusdt、epusdt、okpay、tokenpay,还有 PayPal 和 Stripe。搜 vmq、vpay 这些关键词,0 个结果。新版确实原生不支持 V免签。

图片[2]-【原创】独角兽商店接上 V免签,自动发货全流程跑通了!易支付 | V免签 | 支付宝 | 微信-Appstoy-发现好软件,让AI更好用

有人会说,V免签不算易支付吗,直接把易支付网关地址填成 V免签域名不就行了?

我一开始也这么想。实测直接打脸:

curl -o /dev/null -w '%{http_code}' https://pay.你的域名.com/submit.php

返回 404。/mapi.php/api.php 全是 404。

原因很简单:易支付的标准端点是 /submit.php/mapi.php,V免签只有自己的 /createOrder。我试了一下:

curl https://pay.你的域名.com/createOrder

返回 {"code":-1,"msg":"请传入商户订单号"}。接口活着,但它说的是另一套语言。商店发过去的请求它听不懂,所以后台报 epay request failed

两条路,我自己写了一条

查了一圈,能走的就两条。

第一条是换成 Vmq-pro。这个项目确实兼容易支付接口,也兼容 V免签的监控端,手机挂机 App 和收款码都不用换。但实测之后发现后台配置有问题。

第二条是自己写个协议转换网关。夹在中间做翻译,对商店伪装成标准易支付,对 V免签说它的原生接口。两边源码一行都不用改。

我选了第二条。

图片[3]-【原创】独角兽商店接上 V免签,自动发货全流程跑通了!易支付 | V免签 | 支付宝 | 微信-Appstoy-发现好软件,让AI更好用

我把项目的代码给Agent,让Agent帮我进行文件的适配和项目的完善,下面是他帮我改的地方:

为了搞清楚双边的签名规则,把 V免签源码翻了一遍,主要看这两个文件:

  • app/controller/index/Index.phpcreateOrder 方法
  • app/controller/api/Monitor.phporderNotify 方法

扒出来的签名规则:

场景签名串
建单 createOrdermd5(payId + param + type + price + key)
支付回调md5(payId + param + type + price + reallyPrice + key)
监控端心跳md5(t + key)

type 是 1 微信、2 支付宝。

易支付那边的验签规则:除了 sign 和 sign_type,剔掉空值,参数按 key 升序拼成 a=1&b=2,末尾直接接商户密钥(不加 & 也不加 key=),整串取 MD5 小写。

搞明白这两套,中间的翻译层就好写了。

部署网关

我把它打包开源了,纯 Python 标准库写的,零第三方依赖,Docker 直接部署。

项目地址:https://github.com/HANDSOMEskuld/epay-vmq-gateway

具体的配置方式可以看项目的 Readme,也可以看下面的描述,因为太多了我就给折叠起来了。

Readme:

拉下来:

git clone https://github.com/HANDSOMEskuld/epay-vmq-gateway.git
cd epay-vmq-gateway
cp .env.example .env

先生成一个商户密钥,别用默认值:

openssl rand -hex 16

然后编辑配置文件。vim .env 之后按 I 进入编辑,改完按 ESC:wq 保存。

要填的 5 项:

VMQ_BASE=https://pay.你的域名.com
VMQ_KEY=你V免签后台的通讯密钥
EPAY_PID=1000
EPAY_KEY=刚才openssl生成的那串
GW_PUBLIC=https://shop.你的域名.com/paygw

VMQ_KEY 在 V免签后台的系统设置里能找到。GW_PUBLIC 是网关的公网地址,我这里没单独开域名,直接挂在商店域名一个路径下,省一个域名和一张证书。

启动:

docker compose up -d
docker compose logs -f

看到这行就好了:

INFO gateway listening on :8091  vmq=https://pay.xxx.com  public=https://...

配反向代理

网关默认只监听 127.0.0.1:8091,外网进不来,得用 nginx 反代。

我是宝塔面板,站点配置文件在 /www/server/panel/vhost/nginx/ 下面。在商店站点配置里,找到 location / { 这一行,在它前面加一段:

location /paygw/ {
    proxy_pass http://127.0.0.1:8091/;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_read_timeout 60s;
}

proxy_pass 结尾那个斜杠不能少。少了路径会变成 /paygw/submit.php 整个传给网关,全 404。

重载 nginx:

/www/server/nginx/sbin/nginx -t
/www/server/nginx/sbin/nginx -s reload

验证:

curl https://shop.你的域名.com/paygw/health

返回 {"status": "ok"} 就通了。

商店后台怎么填

后台进支付渠道,新建或编辑,提供方选易支付 epay:

字段填什么
支付网关地址https://shop.你的域名.com/paygw
商户ID PID和 .env 的 EPAY_PID 一致
商户密钥 KEY和 .env 的 EPAY_KEY 一致
接口版本v1
交互方式扫码 qr
渠道类型支付宝填 alipay,微信填 wechat
异步回调 notify_urlhttps://shop.你的域名.com/api/v1/payments/callback
同步跳转 return_urlhttps://shop.你的域名.com/pay

网关地址结尾不要加斜杠,网关自己会拼 /submit.php/mapi.php

图片[4]-【原创】独角兽商店接上 V免签,自动发货全流程跑通了!易支付 | V免签 | 支付宝 | 微信-Appstoy-发现好软件,让AI更好用

虽然钱最后是 V免签收的,但这个地址不能填 V免签域名,必须填网关地址。前面说了,V免签听不懂易支付的话。

一个坑,卡了我半小时

配完之后下单,报了这个:

payment channel not allowed for product

我以为网关写错了。翻了一遍日志,发现网关根本没收到请求。查了半天才明白,dujiao-next 的商品有支付渠道白名单(payment_channel_ids)。

新建的支付渠道,必须去商品编辑页里把它勾上,不然商店压根不会发请求。这跟网关一点关系没有,纯粹是商品设置。

新建渠道之后一定记得去商品里勾一下。别像我一样在这卡半小时。

同步回调和异步回调

这两个很多人搞混,我说清楚。

同步回调就是 return_url,用户付完款浏览器跳回来的地址。它只管展示,不能当发货依据。用户完全可以付完款直接把页面关掉,那这单就永远发不出去。

我在网关里内置了一个扫码收银台页面,每 3 秒轮询订单状态,检测到付款成功自动跳回去,用户不用手动刷新。

异步回调就是 notify_url,这才是发货的唯一依据。服务器对服务器直接通知,跟用户关不关页面没关系。

实际走两跳,你不用配,网关自动处理:

第一跳 V免签通知网关,网关验签之后立刻回一个 success。这步很关键,V免签如果没马上收到 success,会把订单标记成通知失败(数据库里 state=2),然后就不管了。

第二跳网关通知商店,商店返回 success 才算成功。失败按 2、4、8、16、20 秒退避重试 5 次。同一个订单重复回调是幂等的,不会重复发货,代码里做了处理。

实测

配完我拿真实商品跑了一遍,0.01 元测试单。

下单后商店返回:

{
  "channel_type": "alipay",
  "pay_url": "https://shop.xxx.com/paygw/submit.php?_o=202608212208019932",
  "qr_code": "https://qr.alipay.com/fkx19255...",
  "payment_error": null
}

payment_error 是 null,拿到的是真实支付宝收款码。

模拟监控端推送回调,网关日志:

INFO vmq createOrder out_trade_no=DJP20260821221500934762 type=2 price=0.01
INFO vmq paid out_trade_no=DJP20260821221500934762 reallyPrice=0.01
INFO notify upstream attempt=1 resp='success'

第一次就 success。回头查订单:

  • 订单 DJ20260821221500371989 状态 completed
  • paid_at 时间戳已写入
  • 商品 auto_stock_sold 从 0 变成 1

自动发货生效了。全链路通,下单到扣库存一步没断。

图片[5]-【原创】独角兽商店接上 V免签,自动发货全流程跑通了!易支付 | V免签 | 支付宝 | 微信-Appstoy-发现好软件,让AI更好用

顺手把容器重启了一次验证,服务自动恢复,策略是 unless-stopped,服务器重启也会自己拉起来。订单数据落在 ./data/gateway.db,重启不丢。

V免签那边要留意的

4 个点,不注意会白折腾:

  1. 通讯密钥必须一致。 V免签后台改了密钥,要同步改 .envVMQ_KEY,然后 docker compose down && docker compose up -d 重建容器。光 restart 没用,环境变量不会重新读。
  2. V免签后台的 notifyUrl 和 returnUrl 不用管。 网关每次下单都会显式传参覆盖,你后台填什么都不影响。
  3. 监控端必须在线。 数据库里 jkstate 得是 1,手机挂机 App 掉线的话 V免签直接拒绝下单,报”监控端状态异常,请检查”。
  4. 实付金额会有几分钱差异。 V免签用分级微调来避免同金额撞单,用户实际要付的 reallyPrice 可能比订单金额多几分或少几分。收银台页面显示的是 reallyPrice,不会让用户付错。

排障对照

踩过的坑整理成表,出问题直接对着查:

现象原因
payment channel not allowed for product商品没勾这个支付渠道(最常见)
商店报 epay request failed网关地址填错,或容器没起
日志 epay sign mismatch后台商户密钥和 EPAY_KEY 不一致
日志 vmq sign mismatchVMQ_KEY 和 V免签后台通讯密钥不一致
报”监控端状态异常”手机监控端掉线了
报”微信/支付宝支付未配置”V免签后台没配收款码
报”订单超出负荷”同金额并发太多,微调 10 次还撞
notify upstream resp=’fail’商店那边找不到这个订单,或订单超时取消了
访问 /paygw/ 全 404nginx 的 proxy_pass 结尾少了斜杠

另外说一个我遇到的:后台登录接口有频率限制。调试时连着登了几次,被锁了 12 分钟,报”登录尝试过多,请在 739 秒后重试”。调试的时候拿到 token 存下来复用,别反复登录。

安全相关

网关只监听 127.0.0.1,由 nginx 反代出去,别直接把 8091 开到公网。

EPAY_KEYopenssl rand -hex 16 随机生成,别用示例默认值。.env 已写进 .gitignore,不会误传到仓库。

网关和 V免签之间、网关和商店之间,都走 HTTPS,别用裸 IP 明文跑支付回调。


代码全开源,MIT 协议,你自己审一遍再用:https://github.com/HANDSOMEskuld/epay-vmq-gateway

V免签是个人码收款方案,有风控风险,用不用自己评估。我这个网关只做协议转换,不碰资金。

照着上面抄就能跑。有问题评论区见。

上面具体的实现方法和搭建流程你不用看,直接把项目链接给AI,让AI帮你搭建就行。

© 版权声明
THE END
点赞9喜欢这个作者?支持一下吧! 分享
评论 共2条

请登录后发表评论

    • Ricky的头像-Appstoy-发现好软件,让AI更好用超级会员Ricky等级-LV10-Appstoy-发现好软件,让AI更好用作者0