# 二维码合并 **Repository Path**: swift-slogan/qr-code-merging ## Basic Information - **Project Name**: 二维码合并 - **Description**: 将微信二维码和支付宝二维码合并成一个 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-03-13 - **Last Updated**: 2025-03-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 二维码合并 #### 介绍 将微信二维码和支付宝二维码合并成一个 主要合并方式实现有三种: - 通过 UA 判断 - 图片合并 - 第三方支付平台接入 ### UA(User Agent)判断 原理 根据访问者的 User Agent 信息判断访问者使用的 App(支付宝或微信)。 如果检测到 User Agent 包含微信标识,则跳转微信收款链接。 如果检测到 User Agent 包含支付宝标识,则跳转支付宝收款链接。 优点 实现简单:只需一个中间页面进行 UA 判断并跳转。 可以纯前端,把两个链接都包含在二维码中. 也可以把数据放后端 缺点 UA 可能变更:微信和支付宝的 User Agent 格式可能会更新。 微信不支持直接拉起:需要客户长按识别二维码。 不稳定:需要中间页面的服务器响应。服务器挂了就没办法使用 不安全: 跑路还好,最多不能用.如果后台恶意修改代码,钱就没了 ![输入图片说明](https://imgse.com/i/pE9TYxs) 原理 通过二维码的纠错机制,即使有一部分二维码被覆盖,也能正确解析. 支付宝的链接是https://qr.alipay.com/xxx 微信的链接是wxp://xxxx 微信识别二维码偏向于从左到右识别,支付宝不搭理微信的链接wxp://xxxx 其实不限于支付,其他微信/支付宝扫码都可以这个搞 所以可以这么实现: 把链接解析出来,然后用最高容错H(30%纠错),重新生成二维码 把微信作为底层,支付宝放在上层的右下角 顺时针旋转支付宝180°,防止微信优先识别支付宝二维码 删除支付宝的一部分,防止微信优先识别支付宝二维码 优点 简单易用:纯物理方式。没有服务器,不担心安全问题 缺点 兼容性有限:就能两个,3个(比如)都实现不了。 抗污能力差:如果涂黑了一部分,很容易导致用不了,不再像原生二维码那样有强大纠错能力。 微信拉起失败:极少部分情况下微信还是会打开支付宝的链接 ``` // 绘制支付宝二维码(旋转180度并裁剪) const alipayPicWidth = qrSize.value / 2 if (alipayQrContent.value) { const alipayQrCanvas = document.createElement('canvas') await QRCode.toCanvas(alipayQrCanvas, alipayQrContent.value, { errorCorrectionLevel: 'H', margin: picMargin / 2, width: alipayPicWidth, color: { dark: '#000000', light: '#ffffff' } }) // 创建临时画布来处理支付宝二维码 const tempCanvas = document.createElement('canvas') tempCanvas.width = alipayPicWidth tempCanvas.height = alipayPicWidth const tempCtx = tempCanvas.getContext('2d') if (tempCtx) { // 绘制原始支付宝二维码 tempCtx.drawImage(alipayQrCanvas, 0, 0, alipayPicWidth, alipayPicWidth) const clearHeight = alipayPicWidth / 2 / 2 // 清除右下角1/4区域 tempCtx.clearRect(alipayPicWidth / 2 + clearHeight, alipayPicWidth / 2, alipayPicWidth / 2 - clearHeight, alipayPicWidth / 2) // 保存当前状态 ctx.save() // 设置旋转中心点并旋转 ctx.translate(qrPosition.value.x + alipayPicWidth / 2, qrPosition.value.y + alipayPicWidth / 2) ctx.rotate(Math.PI) ctx.translate(-(qrPosition.value.x + alipayPicWidth / 2), -(qrPosition.value.y + alipayPicWidth / 2)) // 绘制处理后的支付宝二维码 ctx.drawImage(tempCanvas, qrPosition.value.x, qrPosition.value.y, alipayPicWidth, alipayPicWidth ) ```