本文档详细介绍了微信和支付宝的各种协议格式,包括App支付、H5支付、小程序跳转等功能的实现方法和最佳实践。
📋 目录
一、💰 支付宝 alipays:// 协议
1. App支付
协议格式
alipay://alipayclient/h5PayUrl?h5_pay_url=<支付链接URL编码>
使用场景
- 适用环境:APP内WebView、移动端浏览器
- 限制环境:微信内置浏览器(会被拦截)
- 支持平台:iOS、Android
核心参数说明
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| appId | String | 是 | 应用ID,由支付宝开放平台分配 |
| privateKey | String | 是 | 应用私钥,用于签名 |
| alipayPublicKey | String | 是 | 支付宝公钥,用于验签 |
| outTradeNo | String | 是 | 商户订单号,64个字符内 |
| totalAmount | String | 是 | 订单总金额,单位为元 |
| subject | String | 是 | 订单标题 |
| notifyUrl | String | 是 | 异步通知地址 |
官方返回值示例
服务端调用 alipay.trade.app.pay 接口后返回的 orderStr:
alipay_sdk=alipay-sdk-java-dynamicVersionNo&app_id=2014100900013000&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%22IQJZSRC1YMQB5HU%22%7D&charset=utf-8&format=json&method=alipay.trade.app.pay¬ify_url=https%3A%2F%2Fapi.xx.com%2Freceive_notify.htm&sign_type=RSA2×tamp=2016-08-25%2020%3A26%3A31&version=1.0&sign=cYmuUnKi5QdBsoZEAbMXVMmRWjsuUj%2By48A2DvWAVVBuYkiBj13CFDHu2vZQvmOfkjE0YqCUQE04kqm9Xg3tIX8tPeIGIFtsIyp%2FM45w1ZsDOiduBbduGfRo1XRsvAyVAv2hCrBLLrDI5Vi7uZZ77Lo5J0PpUUWwyQGt0M4cj8g%3D
Java实现示例
/**
* 支付宝App支付实现
*/
public class AlipayAppPayUtil {
/**
* 生成支付宝App支付的orderStr
*/
public static String getOrderStr(String appId, String privateKey, String alipayPublicKey,
String outTradeNo, String totalAmount, String subject) {
// 实际业务逻辑实现
// 返回官方示例的orderStr
return "alipay_sdk=alipay-sdk-java-dynamicVersionNo&app_id=2014100900013000...";
}
/**
* 生成支付宝App支付的alipays协议URL
*/
public static String getAlipaysUrl(String orderStr) {
try {
String encodedOrderStr = java.net.URLEncoder.encode(orderStr, "UTF-8");
return "alipay://alipayclient/h5PayUrl?h5_pay_url=" + encodedOrderStr;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
JavaScript实现示例
/**
* 支付宝App支付唤起
*/
function openAlipayAppPay(orderStr) {
const encodedOrderStr = encodeURIComponent(orderStr);
location.href = `alipay://alipayclient/h5PayUrl?h5_pay_url=${encodedOrderStr}`;
}
官方文档
2. 转账到账户
协议格式
alipays://platformapi/startapp?appId=09999988&actionType=toAccount&goBack=NO&amount=<金额>&userId=<收款方ID>&memo=<备注>
参数说明
appId:固定值 09999988actionType:固定值 toAccountgoBack:是否返回(YES/NO)amount:转账金额userId:收款方的支付宝IDmemo:转账备注
JavaScript实现示例
/**
* 支付宝转账到账户唤起
*/
function alipayTransfer(userId, amount, memo) {
const url = `alipays://platformapi/startapp?appId=09999988&actionType=toAccount&goBack=NO&amount=${amount}&userId=${userId}&memo=${encodeURIComponent(memo)}`;
location.href = url;
}
官方文档
3. 小程序跳转
协议格式
alipays://platformapi/startapp?appId=<小程序ID>&page=<页面路径>&query=<查询参数>
参数说明
appId:小程序IDpage:要跳转的页面路径query:查询参数,格式为 key1=value1&key2=value2
JavaScript实现示例
/**
* 支付宝小程序跳转唤起
*/
function openAlipayMiniProgram(appId, page, queryParams) {
const queryString = Object.keys(queryParams)
.map(key => `${key}=${encodeURIComponent(queryParams[key])}`)
.join('&');
const url = `alipays://platformapi/startapp?appId=${appId}&page=${encodeURIComponent(page)}&query=${encodeURIComponent(queryString)}`;
location.href = url;
}
官方文档
4. 扫一扫功能
协议格式
alipays://platformapi/startapp?appId=20000123&actionType=scan&barcodeType=<条码类型>&scanType=<扫码类型>
参数说明
appId:固定值 20000123actionType:固定值 scanbarcodeType:条码类型(qr=二维码,bar=条形码)scanType:扫码类型(qr=扫描二维码,bar=扫描条形码)
JavaScript实现示例
/**
* 支付宝扫一扫唤起
*/
function openAlipayScan(barcodeType = 'qr', scanType = 'qr') {
const url = `alipays://platformapi/startapp?appId=20000123&actionType=scan&barcodeType=${barcodeType}&scanType=${scanType}`;
location.href = url;
}
官方文档
5. 手机网站支付
实现方式
支付宝手机网站支付通过表单提交到支付宝收银台实现,不直接使用 alipays:// 协议。
标准实现流程
- 服务端调用
alipay.trade.wap.pay接口,生成form表单 - 服务端执行支付宝SDK中的
pageExecute方法 - 服务端将form表单返回给前端
- 前端将form表单插入页面并自动提交
- 用户在支付宝收银台完成支付
JavaScript实现示例
/**
* 处理支付宝手机网站支付返回的表单
*/
function processAlipayWapForm(formHtml) {
const div = document.createElement('div');
div.innerHTML = formHtml;
document.body.appendChild(div);
const form = div.querySelector('form');
if (form) {
form.submit();
}
}
特殊场景:提取alipays协议
/**
* 从支付宝手机网站支付返回的表单中提取并构造alipays协议
* 注意:此方法非官方推荐,仅供特殊场景使用
*/
public class AlipayWapPayUtil {
public static String extractAlipaysUrlFromWapPay(String payOrderId) throws Exception {
// 1. 获取支付宝表单
String formHtml = getAlipayFormFromServer(payOrderId);
// 2. 解析HTML
Document doc = Jsoup.parse(formHtml);
Element form = doc.selectFirst("form");
if (form == null) {
throw new Exception("支付宝返回的表单格式不正确");
}
// 3. 提取表单action地址
String actionUrl = form.attr("action");
// 4. 构造alipays协议URL
String alipaysUrl = "alipays://platformapi/startapp?appId=20000067&url="
+ java.net.URLEncoder.encode(actionUrl, "UTF-8");
return alipaysUrl;
}
}
官方文档
6. 电脑网站支付
实现方式
电脑网站支付不使用 alipays:// 协议,而是通过表单提交到支付宝收银台。
适用场景
- 主要环境:PC端浏览器
- 不适用:移动APP环境
JavaScript实现示例
/**
* 处理支付宝电脑网站支付
*/
function processAlipayPcForm(formHtml) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = formHtml;
document.body.appendChild(tempDiv);
tempDiv.querySelector('form').submit();
}
官方文档
7. 扫码支付(Native支付)
协议格式
alipays://platformapi/startapp?saId=10000007&qrcode=<二维码内容URL编码>
参数说明
saId:固定值 10000007,表示支付宝内置的扫码功能qrcode:经过URL编码的支付宝收款二维码内容
支付类型说明
此协议用于唤起支付宝APP的扫码功能,并自动识别指定的二维码内容,实现Native支付(扫码支付)。
官方接口调用
需要调用 alipay.trade.precreate(统一收单线下交易预创建接口)获取二维码内容。
接口文档:https://opendocs.alipay.com/open/02ekfg
请求参数示例:
{
"out_trade_no": "20150320010101001",
"seller_id": "2088102146225135",
"total_amount": "88.88",
"subject": "Iphone6 16G",
"body": "Iphone6 16G",
"product_code": "QR_CODE_OFFLINE"
}
返回值结构:
{
"alipay_trade_precreate_response": {
"code": "10000",
"msg": "Success",
"out_trade_no": "20150320010101001",
"qr_code": "https://qr.alipay.com/bax03783b9b89qye3sax0066"
},
"sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE"
}
Java实现示例
/**
* 支付宝扫码支付(Native支付)
*/
public class AlipayNativePayUtil {
private static final String GATEWAY_URL = "https://openapi.alipay.com/gateway.do";
private static final String CHARSET = "UTF-8";
private static final String FORMAT = "json";
private static final String SIGN_TYPE = "RSA2";
/**
* 调用支付宝统一收单线下交易预创建接口,获取二维码内容
*/
public String createQrCode(String appId, String privateKey, String alipayPublicKey,
String outTradeNo, String totalAmount, String subject) throws AlipayApiException {
AlipayClient alipayClient = new DefaultAlipayClient(
GATEWAY_URL, appId, privateKey, FORMAT, CHARSET, alipayPublicKey, SIGN_TYPE);
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", outTradeNo);
bizContent.put("total_amount", totalAmount);
bizContent.put("subject", subject);
bizContent.put("product_code", "QR_CODE_OFFLINE");
request.setBizContent(bizContent.toString());
AlipayTradePrecreateResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
return response.getQrCode();
} else {
throw new AlipayApiException("创建支付宝二维码失败,错误码:" + response.getCode());
}
}
/**
* 生成支付宝扫码支付的alipays协议URL
*/
public String generateAlipaysUrl(String qrCode) throws Exception {
String encodedQrCode = URLEncoder.encode(qrCode, CHARSET);
return "alipays://platformapi/startapp?saId=10000007&qrcode=" + encodedQrCode;
}
}
JavaScript实现示例
/**
* 支付宝扫码支付唤起
*/
function openAlipayQrcodePay(qrcodeContent) {
const encodedQrcode = encodeURIComponent(qrcodeContent);
location.href = `alipays://platformapi/startapp?saId=10000007&qrcode=${encodedQrcode}`;
}
二、💬 微信 wx:// 协议
1. App支付
协议格式
weixin://app/<APPID>/pay/?nonceStr=<随机字符串>&package=Sign%3DWXPay&partnerId=<商户号>&prepayId=<预支付交易会话ID>&timeStamp=<时间戳>&sign=<签名>&signType=<签名类型>
参数说明
APPID:微信开放平台审核通过的应用APPIDnonceStr:随机字符串package:固定值 Sign=WXPaypartnerId:商户号prepayId:预支付交易会话IDtimeStamp:时间戳sign:签名signType:签名类型,如MD5
使用场景
- 适用环境:APP内WebView、移动端浏览器
- 限制环境:支付宝内置浏览器(会被拦截)
- 不适用:微信内(已有原生支付接口)
JavaScript实现示例
/**
* 微信App支付唤起
*/
function openWeixinAppPay(payParams) {
const weixinUrl = `weixin://app/${payParams.appid}/pay/?nonceStr=${payParams.nonceStr}&package=Sign%3DWXPay&partnerId=${payParams.partnerId}&prepayId=${payParams.prepayId}&timeStamp=${payParams.timeStamp}&sign=${payParams.sign}&signType=${payParams.signType}`;
location.href = weixinUrl;
}
官方文档
2. H5支付
协议格式
weixin://wap/pay?<payment_params>
使用场景
- 适用环境:APP内WebView、移动端浏览器
- 不适用:微信内(已有JSAPI支付)
JavaScript实现示例
/**
* 微信H5支付唤起
*/
function openWeixinH5Pay(payUrl) {
const isWeixinBrowser = /MicroMessenger/i.test(navigator.userAgent);
if (isWeixinBrowser) {
// 在微信内直接跳转到支付链接
location.href = payUrl;
} else {
// 在外部浏览器中尝试使用weixin://协议唤起微信
const weixinUrl = `weixin://wap/pay?${payUrl.split('?')[1]}`;
location.href = weixinUrl;
}
}
官方文档
3. 小程序跳转
协议格式
wx<AppID>://
实现方式
微信小程序跳转通常通过微信开放标签或JS-SDK实现,不直接使用协议。
使用场景
- 完全支持:微信内(可通过JSSDK直接跳转)
- 有限支持:APP内WebView(需要通过微信开放标签)
- 不支持:支付宝内
JavaScript实现示例(使用开放标签)
<!-- 引入微信JS-SDK -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
// 配置微信JS-SDK
wx.config({
debug: false,
appId: 'YOUR_APP_ID',
timestamp: 'TIMESTAMP',
nonceStr: 'NONCE_STR',
signature: 'SIGNATURE',
jsApiList: ['launchMiniProgram']
});
/**
* 跳转到微信小程序
*/
function navigateToMiniProgram(appId, path) {
wx.ready(function() {
wx.launchMiniProgram({
appId: appId,
path: path
});
});
}
</script>
官方文档
4. Native支付(扫码支付)
实现方式
微信Native支付是指用户通过微信"扫一扫"扫描商户的二维码完成支付,不使用 wx:// 协议。
使用场景
- 适用环境:PC端浏览器,生成二维码供用户扫描
- 不适用:APP内唤起微信支付、微信内
JavaScript实现示例(生成二维码)
/**
* 生成微信支付二维码
*/
function generateWeixinPayQRCode(codeUrl, containerId) {
// 使用qrcode.js库生成二维码
new QRCode(document.getElementById(containerId), {
text: codeUrl,
width: 256,
height: 256
});
}
官方文档
5. 开放标签
实现方式
微信开放标签不使用 wx:// 协议,而是通过微信JS-SDK和特定的HTML标签实现。
使用场景
- 完全支持:微信内(官方推荐方式)
- 支持:移动端和PC端浏览器
- 有限支持:APP内WebView(需要进行签名验证)
JavaScript实现示例
<!-- 引入微信JS-SDK -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
// 配置微信JS-SDK
wx.config({
debug: false,
appId: 'YOUR_APP_ID',
timestamp: 'TIMESTAMP',
nonceStr: 'NONCE_STR',
signature: 'SIGNATURE',
openTagList: ['wx-open-launch-weapp', 'wx-open-launch-app']
});
</script>
<!-- 打开小程序 -->
<wx-open-launch-weapp id="launch-btn" appid="wx1234567890" path="pages/index/index">
<template>
<button>打开小程序</button>
</template>
</wx-open-launch-weapp>
官方文档
三、🔧 兼容性与降级处理
1. 浏览器兼容性
不同浏览器对自定义协议的支持程度不同:
- iOS Safari:iOS 9及以上版本对自定义协议唤起有严格限制,需要用户手动触发
- Android Chrome:较新版本也增加了对自定义协议的限制
- 微信内置浏览器:对非微信协议有拦截
- 支付宝内置浏览器:对非支付宝协议有拦截
2. 通用降级处理方案
/**
* 通用协议唤起函数(含降级处理)
*/
function launchApp(scheme, fallbackUrl) {
// 记录唤起时间
const startTime = Date.now();
// 尝试唤起应用
location.href = scheme;
// 添加超时检测
setTimeout(() => {
// 如果页面仍然可见,说明唤起失败
if (!document.hidden) {
// 跳转到降级页面
location.href = fallbackUrl;
}
}, 2000);
}
3. 环境检测
/**
* 检测当前环境
*/
function detectEnvironment() {
const ua = navigator.userAgent;
return {
isWeixin: /MicroMessenger/i.test(ua),
isAlipay: /AlipayClient/i.test(ua),
isIOS: /iPhone|iPad|iPod/i.test(ua),
isAndroid: /Android/i.test(ua),
isMobile: /Mobile|Android|iPhone|iPad|iPod/i.test(ua)
};
}
/**
* 根据环境选择合适的支付方式
*/
function choosePaymentMethod(env) {
if (env.isWeixin) {
// 微信内使用JSAPI支付
return 'weixinJSAPI';
} else if (env.isAlipay) {
// 支付宝内使用支付宝内置支付
return 'alipayInApp';
} else if (env.isMobile) {
// 移动端浏览器使用协议唤起
return 'mobileScheme';
} else {
// PC端使用扫码支付
return 'qrcode';
}
}
四、✨ 最佳实践
1. 安全性考虑
- 服务端生成:所有支付相关的签名和敏感参数应在服务端生成,前端只负责展示和跳转
- 避免存储:避免在前端存储敏感支付信息
- HTTPS协议:使用HTTPS协议保证传输安全
- 参数验证:对所有输入参数进行严格验证
2. 用户体验优化
- 明确引导:提供明确的支付引导和状态提示
- 超时处理:实现合理的超时处理和降级方案
- 兼容性测试:考虑不同设备和浏览器的兼容性
- 错误处理:提供友好的错误提示和重试机制
3. 开发建议
- 官方文档:严格按照官方文档实现,避免使用非官方API
- 版本更新:定期检查和更新协议格式,确保与最新版本兼容
- 充分测试:在各种环境下充分测试,包括不同设备、浏览器和网络条件
- 监控统计:建立支付成功率监控和统计分析
4. 常见问题处理
协议唤起失败
/**
* 协议唤起失败处理
*/
function handleSchemeFailure(paymentType) {
switch(paymentType) {
case 'alipay':
// 跳转到支付宝下载页面或H5支付页面
location.href = 'https://mobile.alipay.com/index.htm';
break;
case 'weixin':
// 跳转到微信下载页面或提示用户
location.href = 'https://weixin.qq.com/';
break;
default:
alert('请安装相应的支付应用');
}
}
支付状态查询
/**
* 支付状态查询
*/
async function checkPaymentStatus(orderId) {
try {
const response = await fetch(`/api/payment/status/${orderId}`);
const result = await response.json();
if (result.status === 'success') {
// 支付成功处理
window.location.href = '/success';
} else if (result.status === 'pending') {
// 继续查询
setTimeout(() => checkPaymentStatus(orderId), 2000);
} else {
// 支付失败处理
alert('支付失败,请重试');
}
} catch (error) {
console.error('查询支付状态失败:', error);
}
}
注意事项
- 订单创建时机:支付订单是在用户输入支付密码后创建,并非唤起收银台时创建
- 私钥安全:私钥信息应妥善保管,不要硬编码在代码中
- 签名验证:异步通知处理时必须验证签名,确保通知来自官方
- URL编码:使用协议时,需要对参数进行正确的URL编码
- 版本兼容:定期关注官方文档更新,及时适配新版本变化
本文档基于支付宝和微信官方文档整理,仅供开发参考。实际开发时请以官方最新文档为准。