介绍
微信、支付宝双收款码贴在摊位上占地方又不美观,这个方案把两个码合成一个:一张二维码扫开是一个 H5 落地页,页面按扫码者的 User-Agent 判断来源——微信扫码自动跳微信收款页,支付宝扫码自动跳支付宝收款页,浏览器扫码就弹一个支付方式选择按钮,全程不用二次扫码。思路来自吾爱破解论坛的这篇帖子,代码本身没有技术含量,核心就是 UA 判断加一个好看的过渡页,胜在实用。【摆摊、开店不收手续费的老办法里最顺手的方案,淘宝上卖几十块的"聚合收款码"商家版,原理也就是这个】
两个关键点要记住:微信那边不能用个人收款码,得先申请微信官方的【经营码】(其实就是商家收款码),申请下来后用二维码解码器把里面的 URL 解出来;支付宝这边简单,个人收款码就能用,同样解码出 URL。把两个 URL 分别替换进下面的源码里,部署到任意静态空间或服务器,生成一个二维码就完事了。
特征
🔍 按扫环境自动分流:微信、支付宝 App 内扫码直接跳各自支付页
🌐 浏览器扫码显示支付方式选择,不会打死路
📱 一个二维码搞定两套收款,摊位只贴一张码
⏱ 300ms 内自动跳转,过渡页有加载动画不显突兀
🎨 移动端卡片式 UI,圆角、阴影、图标齐全,观感干净
🔧 纯 HTML + 原生 JS,无依赖不放任何服务器框架,静态托管即可用
源码
以下为完整页面源码,把 PAY_URL 里的两个地址替换成你解码出来的收款 URL 即可直接使用:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>收款</title>
<style>
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
background: #f7f7f7;
font-family:
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
"PingFang SC",
"Microsoft YaHei",
Arial,
sans-serif;
}
body {
display: flex;
align-items: center;
justify-content: center;
}
.box {
width: calc(100% - 40px);
max-width: 420px;
padding: 40px 25px;
background: #fff;
border-radius: 16px;
text-align: center;
box-shadow: 0 8px 30px rgba(0, 0, 0, .06);
}
.icon {
width: 64px;
height: 64px;
margin: 0 auto 20px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: #f1f1f1;
font-size: 30px;
}
.title {
font-size: 20px;
font-weight: 600;
color: #222;
margin-bottom: 12px;
}
.desc {
font-size: 14px;
color: #999;
line-height: 1.7;
}
.loading {
width: 28px;
height: 28px;
margin: 22px auto 0;
border: 3px solid #eee;
border-top-color: #999;
border-radius: 50%;
animation: rotate .8s linear infinite;
}
@keyframes rotate {
to {
transform: rotate(360deg);
}
}
.button {
display: none;
margin-top: 22px;
width: 100%;
height: 46px;
border: 0;
border-radius: 8px;
background: #1677ff;
color: #fff;
font-size: 15px;
}
</style>
</head>
<body>
<div class="box">
<div class="icon" id="icon">💳</div>
<div class="title" id="title">
正在跳转收款页面
</div>
<div class="desc" id="desc">
请稍候...
</div>
<div class="loading" id="loading"></div>
<button class="button" id="button">
点击继续
</button>
</div>
<script>
(function () {
// ==============================
// 收款地址
// ==============================
const PAY_URL = {
wechat: "https://payapp.wechatpay.cn/sjt/qr/AQHcRjMZMLHpYnXkgZnw4jtU#",
alipay: "https://qr.alipay.com/2m618208kwnpfxzl24zfbfb"
};
// ==============================
// 获取 URL 参数
// ==============================
function getParam(name) {
const params = new URLSearchParams(window.location.search);
return params.get(name);
}
// ==============================
// 判断当前环境
// ==============================
function detectPayType() {
// 第一优先级:URL 参数
//
// ?type=wechat
// ?type=alipay
const type = (getParam("type") || "").toLowerCase();
if (type === "wechat" || type === "wx") {
return "wechat";
}
if (type === "alipay" || type === "ali" || type === "zfb") {
return "alipay";
}
// 第二优先级:UA 判断
const ua = navigator.userAgent.toLowerCase();
// 微信
if (
ua.indexOf("micromessenger") !== -1 ||
ua.indexOf("wechat") !== -1
) {
return "wechat";
}
// 支付宝
if (
ua.indexOf("alipayclient") !== -1 ||
ua.indexOf("aliapp") !== -1
) {
return "alipay";
}
// 无法判断
return null;
}
// ==============================
// 更新页面
// ==============================
function showPayType(type) {
const icon = document.getElementById("icon");
const title = document.getElementById("title");
const desc = document.getElementById("desc");
const loading = document.getElementById("loading");
const button = document.getElementById("button");
if (type === "wechat") {
icon.innerHTML = "💚";
title.innerHTML = "正在打开微信支付";
desc.innerHTML = "即将跳转到微信收款页面,请稍候...";
setTimeout(function () {
window.location.replace(PAY_URL.wechat);
}, 300);
return;
}
if (type === "alipay") {
icon.innerHTML = "💙";
title.innerHTML = "正在打开支付宝";
desc.innerHTML = "即将跳转到支付宝收款页面,请稍候...";
setTimeout(function () {
window.location.replace(PAY_URL.alipay);
}, 300);
return;
}
// ==============================
// 无法判断
// ==============================
icon.innerHTML = "💳";
title.innerHTML = "选择支付方式";
desc.innerHTML = "请选择您要使用的支付方式";
loading.style.display = "none";
button.style.display = "block";
button.innerHTML = "打开微信支付";
button.onclick = function () {
window.location.href = PAY_URL.wechat;
};
const aliButton = document.createElement("button");
aliButton.className = "button";
aliButton.style.display = "block";
aliButton.style.marginTop = "10px";
aliButton.innerHTML = "打开支付宝";
aliButton.onclick = function () {
window.location.href = PAY_URL.alipay;
};
button.parentNode.appendChild(aliButton);
}
// ==============================
// 开始检测
// ==============================
const payType = detectPayType();
showPayType(payType);
})();
</script>
</body>
</html>两个小提示:一是微信经营码申请和收款码 URL 解码时注意时效,部分链接带有效期,掉链了重新解码替换即可;二是支付宝 App 内打开非阿里的域名会提示"非支付宝页面",属正常现象,不影响支付流程。整套东西部署到 GitHub Pages、Codeberg Pages 这类免费静态托管上,配个短域名或短链,就能当正式收款入口用了。