banner
约 3,300 字
11 分钟

PayQrcode 部署教程:微信支付宝二合一收款码的物理合并方案

PayQrcode 部署教程:微信支付宝二合一收款码的物理合并方案

摘要

PayQrcode 用物理图像合并把微信、支付宝收款码合成一张图,完全离线可扫。含合并原理、三个必知局限、一键与 Pages 部署、双端扫码实测流程。

PayQrcode 部署教程:微信支付宝二合一收款码的物理合并方案

收款码这件事有个很低级但很真实的痛点:桌面上并排放着微信和支付宝两张码,顾客举着手机来回比划,扫了微信的却掏出了支付宝,然后你俩都愣一下。多数人最后选择打印两张、贴上「微信」「支付宝」的标签——问题没解决,只是被标注了。

PayQrcode 换了个思路:不做跳转,直接把两张码「物理合并」成一张图。 顾客扫哪张都是这张,微信自动跳微信、支付宝自动跳支付宝。不需要服务器、不需要 API,图片可离线打印,一次生成永久有效

这篇教程除了部署步骤,会把合并原理三个必须提前知道的局限讲清楚——因为这两部分决定了你打印出来的码靠不靠谱。

PayQrcode 二合一收款码生成工具界面:上传支付宝与微信收款码、选择主题与比例
PayQrcode 二合一收款码生成工具界面:上传支付宝与微信收款码、选择主题与比例

一、它和「软件识别版」的根本区别

市面上更常见的方案是「软件识别版」:用一个中间页面,靠设备 UA 或网络环境判断你用的是微信还是支付宝,再跳转到对应收款页。

这条路的问题不在技术,在环节

  • 它必须依赖服务器,服务器挂了或域名被拦,码就废了

  • 中间多一次跳转,就多一次跳出和封禁风险

  • UA 判断会误判,尤其是应用内浏览器、平板、模拟器

PayQrcode 把判断这件事从「网络层」搬到了「图像层」——不做判断,让两个 App 自己只看自己想看的部分。 这就是「物理合并」的含义:它输出的是一张真真切切的静态图片。

一个额外的好处值得单独说:整个过程在你的浏览器里完成。 我读了它的源码,src/ 目录下没有任何网络请求代码,只有三个浏览器端库在干活:jsQR(解码识别上传的码)、QrCode(生成)、html2canvas(导出图片)。这意味着你上传的收款码图片不会离开你的浏览器——对收款码这种敏感素材来说,这一点比省事更重要。

二、合并原理:为什么一张图能被两个 App 正确识别

这一节是这个项目最值得收藏的部分。它成立的前提是微信和支付宝的扫码逻辑存在明确差异

平台

识别逻辑

微信

采用「从左到右优先识别」策略,并且会解析 wxp://xxxx 格式的微信支付链接

支付宝

直接忽略微信支付链接格式,只识别自身 https://qr.alipay.com/xxx 格式,确保跳转正确

利用这个差异,合并分五步完成:

  1. 用最高容错等级 H(30% 纠错能力) —— 这是整件事的地基。二维码被局部覆盖后还能解析,靠的就是纠错冗余。

  2. 以微信收款码作为背景层 —— 微信码保持完整。

  3. 提取支付宝收款码的核心数据区,删除 3 个定位角点中的「无点位角」 —— 保留 3 个定位角。定位角是二维码的标准结构,保留它们才能被正确识别。

  4. 把处理后的支付宝码顺时针旋转 180° —— 目的是破坏微信对支付宝码的定位识别逻辑,让微信「看不见」它。

  5. 叠加到微信码的右下角「无点位区域」 —— 通过像素级融合形成完整二维码。不占用定位角的位置,是为了不互相干扰。

用一句话总结这套设计的聪明之处:微信从左到右扫过去,先撞见自己完整的码,直接跳微信;支付宝则忽略微信链接、对旋转 180° 的支付宝码做正常识别,跳支付宝。两个 App 各看各的,全程没有中间人。

三、三个真实优势

特性

说明

纯物理实现

无需服务器 / API 支持,生成后可直接打印使用,杜绝网络篡改风险

即生即用

一次生成永久有效,适用于静态收款场景(实体店、地摊、海报等)

多场景通用

不限于支付——支持微信 / 支付宝扫码跳转的通用场景(官网、表单等)

第二条是它对比「跳转方案」最大的优势:静态图片不会过期。 不用维护域名、不用续费、不用担心哪天服务停了码变砖。

四、三个必须提前知道的局限

官方文档写得很坦诚,这三条我原样转述——它们决定你的使用边界,不是可以忽略的小字

局限

具体表现

仅支持双码合并

暂无法扩展到 3 个及以上码种。要同时收微信、支付宝、云闪付?这个方案做不到

抗损能力下降

局部污损超过 30% 纠错范围可能导致识别失败,必须避免遮挡二维码区域

极端识别问题

极少数情况下微信可能误解析支付宝链接,概率<0.5%,建议配置兜底测试流程

「抗损能力下降」这条要特别理解:二维码本身的 H 级容错是 30%,而叠加了第二张码之后,可用的冗余被消耗掉了一部分——因为一部分像素已经被支付宝码占用了。所以它比单张二维码更怕脏、更怕磨损

落实到使用上就是两条:印在耐磨材质上,别贴在容易被蹭到的地方别在码上盖 logo、贴透明胶带、或者压在小票下面

五、部署方案一:一键部署(最省事)

仓库 README 里还给了两个官方一键部署按钮,不需要自己配任何构建参数

  • Vercel 自动部署 —— 点 README 里的 Vercel 按钮,授权后自动建项目并部署

  • Cloudflare Pages 自动部署 —— 点对应按钮,走 Cloudflare 的 Deploy to Workers / Pages 流程

这种方式最合适「只想拿个能用的工具」的人。想自己控制构建细节(比如指定分支、调整 Node 版本),再用下面这种方式。

六、部署方案二:Cloudflare Pages 手动部署

前置条件

部署步骤

  1. 进入 Cloudflare Pages 控制台 —— 左侧导航栏选「Workers 和 Pages」→「创建应用程序」→「Pages」

  2. 连接 GitHub 仓库 —— 点「连接到 Git」,选择刚 Fork 的 PayQrcode 仓库,部署分支选 main

  3. 配置构建参数 —— 在「构建设置」里按下面填:

配置项

说明

项目名称

自定义,如 pay-qrcode

——

构建预设

Vue

项目确实是 Vue 3

构建命令

npm run build

来自 package.json 的 scripts

输出目录

dist

Vite 的默认输出目录

Node 版本

18+

建议 18.x 或 20.x

这里的技术栈是 Vue 3 + Vite,不是 Astro。 你可能会在 README 的按钮图片上看到 vhAstro-Theme 的字样——那只是作者复用的按钮图,构建预设请按 Vue 填

  1. 启动部署 —— 点「部署站点」,Cloudflare 会自动执行:克隆代码 → npm installnpm run build → 部署 dist 目录

  2. 验证部署 —— 用默认域名打开,上传两张收款码试试能否生成合并图、能否下载

七、部署方案三:自建或任意静态托管

这本质上是一个纯静态站点,所以 Vercel、Netlify、自己的服务器、甚至本地文件都能跑。

本地构建:

bash
# 克隆仓库(或直接用你 Fork 的地址)
git clone https://github.com/uxiaohan/PayQrcode.git
cd PayQrcode

# 安装依赖
pnpm install

# 仅构建(跳过 type-check,产物在 dist/)
pnpm run build-only

为什么建议用 build-only 而不是 build 因为 build 实际执行的是 run-p type-check "build-only {@}" --——它会并行跑一行类型检查vue-tsc --build)。类型检查失败会直接中断构建,而你只是想拿产物的时候,没必要被它拦住。

构建完成后把 dist/ 目录丢给任意静态服务器即可。如果部署在自己服务器上,记得给单页应用配回退路由,否则刷新非根路径会 404:

nginx
location / {
    try_files $uri $uri/ /index.html;
}

八、生成与实测流程:这一步不能省

先说一条页面上就写着的提示,它直接影响识别成功率:

⚠️ 请尽量把非二维码区域裁剪后上传,以提升识别准确性!

也就是说,别直接上传手机拍的那张「收款牌」整图(带logo、文字、边框、背景),先用工具把二维码本身裁出来再上传。原因很直接:这个方案靠像素级融合,非二维码区域会稀释可用空间,也会干扰算法对二维码边界的判定。

生成流程:

  1. 先把两张码裁干净 —— 只留二维码本体

  2. 上传支付宝收款码微信收款码(界面区分得很清楚)

  3. 选主题 —— 有「默认」与主题 A / B / C / D 共 5 种,用来匹配你的收款牌风格

  4. 调比例 —— 用「缺省比例」滑块调整支付宝码的覆盖比例

  5. 生成,然后实测 —— 见下面

生成之后必须双端实测。官方原话:生成后使用微信 / 支付宝 APP 分别扫码测试,确保:

  • 微信扫码优先跳转微信支付页面

  • 支付宝扫码正常唤起付款码 / 转账页面

为什么必须两端都测? 因为这个方案的原理就是「赌」两个 App 的识别差异。任何一端的行为变化(App 版本更新、扫码策略调整)都会让合并码失效——而失效的表现是「扫了没反应」或「跳到错的平台」,在收钱现场被发现就太晚了。

如果出现识别延迟或识别失败,官方建议调这两个参数:

参数

建议值

说明

支付宝码的覆盖比例

初始 30%–40% 面积占比

覆盖太少可能不被识别,覆盖太多会吃掉微信码的纠错冗余

旋转角度

±10° 微调

寻找最佳识别平衡点

调参要有耐心:这两个参数是互相影响的——调大覆盖比例会影响微信码的可读面积,旋转角度又会改变支付宝码在实际像素上的可识别性。每改一次,两端各扫一次,别只测一端就下结论。

界面上的「缺省比例」滑块就是控制覆盖比例的入口,配合主题切换(默认 / 主题 A–D)使用。建议把最终满意的参数组合记下来——以后重印时直接复用,不用再试一遍。

九、排错清单

现象

原因与处理

构建失败

检查 Node 版本是否 ≥18;看部署日志里是不是依赖安装失败;本地可以先 pnpm install 验证依赖兼容性

页面白屏

确认 dist/ 里有 index.html 和 js/css 静态资源;自建服务器需配置 SPA 回退路由(try_files

刷新页面 404

同上,缺 location 回退到 index.html

域名访问异常

Cloudflare / Vercel 部署需等 DNS 生效(通常几分钟);自定义域名要完成解析配置

生成的码扫不出来

先确认上传的原图清晰、无变形;再按第八节调覆盖比例(30%–40%)与旋转角度(±10°)

微信扫出来跳到支付宝

极其罕见(官方标注概率 <0.5%)但确实存在。重新生成并调参,直到双端实测都正确再印刷

用久了识别变差

抗损能力下降是方案的固有局限。检查码面是否被磨损、遮挡或反光,必要时换新印

十、安全与合规提醒

收款码是敏感素材,三件事请照做:

第一,只在可信环境生成。 好在 PayQrcode 的合并过程完全在浏览器本地完成,源码里没有任何上传逻辑——这正是你应该自己部署一份、而不是随便用网上某个「在线合并」站点的原因。别人家的站点有没有偷偷上传,你没法验证。

第二,输出图片保存好,别乱传。 收款码泄露意味着别人可以替换你的收款码——把流量导向别人的账户,或者在打印店、复印店的环节被替换。原图和合并图都归档备份,不要让它们停留在不可信的设备或聊天记录里。

第三,印刷环节自己盯。 物理介质的风险比数字文件更直接:贴出去的码被谁覆盖过,你是看不见的。建议定期检查张贴的码,尤其是门口、摊位这类无人看管的位置。

另外,生成的是收款码,涉及实际资金往来,请以微信和支付宝官方的收款规则为准。如果官方改版导致识别率变化,就重新导出清晰原图再合并——这不是一次配置就永久无忧的事。

十一、写在最后

PayQrcode 的价值不在于功能多,而在于它用图像层的巧思绕开了整个服务器环节。理解了这个原理,你就明白为什么它比跳转方案更稳:没有中间人,就没有中间环节可以出故障。

但也正因为如此,它有三个硬边界必须记住:只支持两个码抗损能力比单码更弱极小概率的误识别。所以正确的用法是:生成 → 双端各扫一遍 → 满意后留存原图 → 印在耐磨材质上 → 定期检查

一张纸、一个码,收钱这件事可以非常「土」,也可以非常稳。

END