本文档详细介绍了微信和支付宝的各种协议格式,包括App支付、H5支付、小程序跳转等功能的实现方法和最佳实践。

📋 目录


一、💰 支付宝 alipays:// 协议

1. App支付

协议格式

alipay://alipayclient/h5PayUrl?h5_pay_url=<支付链接URL编码>

使用场景

  • 适用环境:APP内WebView、移动端浏览器
  • 限制环境:微信内置浏览器(会被拦截)
  • 支持平台:iOS、Android

核心参数说明

参数名类型必填说明
appIdString应用ID,由支付宝开放平台分配
privateKeyString应用私钥,用于签名
alipayPublicKeyString支付宝公钥,用于验签
outTradeNoString商户订单号,64个字符内
totalAmountString订单总金额,单位为元
subjectString订单标题
notifyUrlString异步通知地址

官方返回值示例

服务端调用 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&notify_url=https%3A%2F%2Fapi.xx.com%2Freceive_notify.htm&sign_type=RSA2&timestamp=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:固定值 09999988
  • actionType:固定值 toAccount
  • goBack:是否返回(YES/NO)
  • amount:转账金额
  • userId:收款方的支付宝ID
  • memo:转账备注

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:小程序ID
  • page:要跳转的页面路径
  • 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:固定值 20000123
  • actionType:固定值 scan
  • barcodeType:条码类型(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:// 协议。

标准实现流程

  1. 服务端调用 alipay.trade.wap.pay 接口,生成form表单
  2. 服务端执行支付宝SDK中的 pageExecute 方法
  3. 服务端将form表单返回给前端
  4. 前端将form表单插入页面并自动提交
  5. 用户在支付宝收银台完成支付

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:微信开放平台审核通过的应用APPID
  • nonceStr:随机字符串
  • package:固定值 Sign=WXPay
  • partnerId:商户号
  • prepayId:预支付交易会话ID
  • timeStamp:时间戳
  • 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;
}

官方文档

微信App支付官方文档


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;
    }
}

官方文档

微信H5支付官方文档


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
    });
}

官方文档

微信Native支付官方文档


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);
    }
}

注意事项

  1. 订单创建时机:支付订单是在用户输入支付密码后创建,并非唤起收银台时创建
  2. 私钥安全:私钥信息应妥善保管,不要硬编码在代码中
  3. 签名验证:异步通知处理时必须验证签名,确保通知来自官方
  4. URL编码:使用协议时,需要对参数进行正确的URL编码
  5. 版本兼容:定期关注官方文档更新,及时适配新版本变化

本文档基于支付宝和微信官方文档整理,仅供开发参考。实际开发时请以官方最新文档为准。