简介支付宝协议跳转scheme清单整理自支付宝APK适合移动端开发者在H5、App或自动化脚本中唤起支付宝指定页面时直接取用省去自行逆向提取地址的繁琐环节。资源覆盖扫一扫、蚂蚁森林、转账、账单等常用功能每个key数字对应scheme中的saId参数按需替换即完成页面切换同时保留部分历史活动入口跳转后可能提示已暂停服务建议结合官方权限校验使用。压缩包内共2个文件一份JSON便于程序读取与批量管理一份XML适合人工查阅、导入接口工具或生成文档62KB的体积非常轻量。目前已有5720人学习下载无论是要快速集成支付宝跳转、研究页面路由规则还是搭建跳转测试用例这份梳理好的清单都能提供直接参考能明显缩短协议调试与参数适配的时间。1. 先交代清楚这份清单能做什么、不能做什么1.1 我为什么攒了这份scheme清单事情得从一次活动H5说起。当时运营给了一个需求用户在推广页里点按钮直接唤起支付宝App并落到扫一扫或付款码省去打开支付宝→找到扫一扫这两步。听起来很简单真做起来就发现支付宝没有一个像微信那样被各类技术社区反复整理的公开跳转协议文档网上能找到的资料多半是零散的帖子不少还停留在好几年前的版本。我花了大概一个下午在真机上一遍遍测结合各渠道的调用记录整理出来一份实际可用的scheme清单。这里的scheme指的就是通过alipays://这种协议的链接让手机系统把链接交给支付宝App去处理从而直接打开指定页面。标题里说的开放意思是这些唤起方式不需要你拥有企业支付宝账户也不需要去申请什么白名单权限普通H5页面、App内WebView甚至短信链接里都能直接写。但能用和所有场景都能用是两回事这篇会把我实测下来可用的部分、容易踩的坑和边界一起说清楚。如果你是做活动页、外部流量投放、App内跳转支付宝或者只是想在个人项目里把用户引导到某个支付宝页面这份清单都能直接用。如果你是自己开发小程序想被外部H5唤起那重点看第4节分包路径的问题。如果你在做支付相关服务端开发第5节的回调验签报错大概率能帮你省半小时。1.2 alipays这个协议到底是怎么工作的在给清单之前我觉得有必要先把scheme的工作方式讲明白不然你遇到一个没列出来的场景会不知道怎么排查。一个典型scheme长这样alipays://platformapi/startapp?appId20000056拆开看是这么几段alipays协议名相当于支付宝App在系统里注册的身份证。手机系统收到以这个开头的链接就知道该交给支付宝处理。platformapi固定路径表示走的是支付宝内部的平台能力接口。startapp动作名称意思是启动某个应用模块。这是最常见的动作后面接的参数appId就是你要唤起的目标模块编号。appId目标模块的应用ID就是一个纯数字编号。支付宝内部把扫一扫、付款码、账单这些能力都封装成了一个个应用每个应用有一个固定编号通过appId指定要打开哪个。理解了这套机制后面所有scheme都是同一个套路换协议、换路径、换appId而已。所以后面清单里我不会只是丢一堆链接而是会在关键位置上标注这个appId对应的页面是什么以及实测中可能出现的版本差异。需要特别说明的是这份清单的可复用性依赖支付宝客户端的版本和地区。我测试基于的是中国大陆地区常用版本部分appId在旧版本或灰度版本上行为可能不一样。你拿到清单后强烈建议在目标用户群体最集中的主流版本上先验证一轮再上线。2. 可以直接用的scheme清单按场景整理2.1 基础能力类首页、扫一扫、收付款这类是最常用的尤其是扫码和收付款几乎每个业务方都会用到。我直接列一张表表后面对关键项做说明。目标场景scheme支付宝首页/钱包alipays://platformapi/startapp?appId20000001扫一扫alipays://platformapi/startapp?appId20000056付款码向商家付款alipays://platformapi/startapp?appId20000067收款码别人扫你alipays://platformapi/startapp?appId20000068这几个appId是我实际验证过多次的。20000001打开的是支付宝主路径页面底部Tab会定位在首页20000056直接进入扫一扫取景界面20000067打开的是带条形码和二维码的付款页这个在便利店收银台场景最常用20000068对应的是你向别人收钱时展示的收款二维码页。这里有一个容易混淆的点很多资料会把付款码和收款码搞反或者只给其中一个。建议你在自己的测试机上分别打开一次看页面右上角的功能名确认一下当前版本对应的编号。因为支付宝偶尔会在版本升级时调整内部模块的appId对应关系虽然这种情况不多但真遇上就挺折腾的。除了这几个基础能力还有一个经常被问到的怎么在电脑网站支付时只返回一个二维码链接给用户。这个其实不属于scheme范畴电脑网站支付返回的是一个https://openapi.alipay.com/gateway.do...的收银台地址你要在服务端拿到trade_no后再用官方工具生成二维码图片而不是走alipays://。如果看到网上有人说用scheme实现基本不靠谱别浪费时间尝试。2.2 业务页与生活服务类页面除了基础能力社区里流传比较广的还有一批业务页面的appId。这类页面我在不同版本上验证过稳定性不如基础能力那四个但大多数情况下是能用的。目标场景scheme蚂蚁森林alipays://platformapi/startapp?appId60000002蚂蚁庄园alipays://platformapi/startapp?appId60000001信用生活/芝麻信用alipays://platformapi/startapp?appId20000060手机充值alipays://platformapi/startapp?appId20000055信用卡还款alipays://platformapi/startapp?appId20000058这几个我实测过60000002打开蚂蚁森林后能正常看到能量球页面60000001会进到蚂蚁庄园养鸡页。这两类是营销活动里经常要用的用户从外部落地页点进来直达互动页面会比让他先打开支付宝再搜入口顺畅很多。20000060对应芝麻信用里的信用生活20000055和20000058分别对应充值中心和信用卡还款。需要提醒的是这三个业务页的appId在不同支付宝版本上出现过跳转后页面空白的情况特别是旧版本客户端兼容性一般。如果你面向的是偏低龄或长辈用户他们手机上的支付宝版本可能比较旧最好让用户在首页手动点入口否则跳过去白屏反而影响转化。还有一点值得说不要拿着这份清单里的业务页appId去做什么自动化脚本或批量操作。支付宝App内部对唤起频率有风控同一台设备短时间内被反复用scheme拉起不同页面很容易触发安全限制导致跳转失效。正常业务量级下没问题但别有投机心态。2.3 拉起小程序的scheme写法除了一级页面scheme也可以直接唤起支付宝小程序。写法如下alipays://platformapi/startapp?appId小程序AppIdpage页面路径这里的小程序AppId不是上面那些数字编号而是你在支付宝开放平台创建小程序后拿到的那个以2018或2021开头的字符串ID。page参数就是要打开的小程序内部页面路径。配置项说明appId支付宝小程序的AppId一串字母数字组合page小程序内的页面路径从pages/或分包名开始需URL编码举个例子小程序首页路径是pages/index/index那么完整写法是alipays://platformapi/startapp?appId2021003111111111page%2Fpages%2Findex%2Findex看到%2F了吗这是/的URL编码后的样子。很多人在这一步就踩坑了后面第4节专门展开讲。3. 真机拉起、安装检测与降级加载清单拿到了下一步就是怎么用。不同载体有不同的拉起方式而且绝对不要直接写死一个location.href就算完用户手机没装支付宝时要有降级方案。3.1 H5页面里直接跳转在H5页面里最直接的方式是给按钮加一个click事件location.href alipays://platformapi/startapp?appId20000056;如果是a标签直接写href也可以a hrefalipays://platformapi/startapp?appId20000056扫一扫/a这个方案在绝大多数手机浏览器里都能生效包括微信内置浏览器之外的普通浏览器。注意微信浏览器内对第三方scheme有限制用户在微信里点这个链接往往会弹已停止访问该网页之类的提示这是微信的统一策略。在Safari里还有一个细节首次拉起scheme时iOS可能会弹一个确认框询问是否要在支付宝中打开链接用户点打开之后才能完成跳转。这属于系统行为无法通过前端代码绕过。做转化率分析时要把这一步算进去别因为确认框的损耗觉得是自己的代码写得不对。3.2 App内拉起与安装检测如果你是在自己的App里跳支付宝iOS和Android的写法不一样。iOS使用UIApplication拉起NSString *scheme alipays://platformapi/startapp?appId20000056; NSURL *url [NSURL URLWithString:scheme]; [[UIApplication sharedApplication] openURL:url options:{} completionHandler:nil];需要注意的是iOS 9 以后canOpenURL只能检测到你在Info.plist的LSApplicationQueriesSchemes里声明过的scheme。要检测用户是否安装了支付宝你需要在Info.plist里加上alipayskeyLSApplicationQueriesSchemes/key array stringalipays/string stringalipay/string /arrayAndroid则是用Intent拉起Intent intent new Intent(Intent.ACTION_VIEW, Uri.parse(alipays://platformapi/startapp?appId20000056)); startActivity(intent);Android上检测是否安装支付宝要用PackageManager查包名PackageManager pm getPackageManager(); try { pm.getPackageInfo(com.eg.android.AlipayGphone, PackageManager.GET_ACTIVITIES); // 已安装执行跳转 } catch (PackageManager.NameNotFoundException e) { // 未安装走降级 }这里有个常见坑很多Android国产ROM会限制后台唤起App的权限你调用startActivity时如果不在前台可能被系统拦截并提示XX应用想要打开支付宝。这部分只能靠引导用户在系统设置中允许关联启动没有纯代码的绕法。3.3 下载落地页与URL编码问题当检测到用户没装支付宝时你不能干瞪眼要跳转到下载页。支付宝官方提供了一个落地页网上一些资料里能见到这种形式的链接https://render.alipay.com/p/s/i?schemealipays%3A%2F%2Fplatformapi%2Fstartapp%3FappId%3D20000056注意scheme参数后面的那串乱码就是对完整scheme做URL编码后的结果。官方页面解析这个参数后会自动判断如果用户装了支付宝就拉起App没装就跳转下载。这个落地页的好处是帮你把是否安装的检测逻辑交给官方处理你只需要把原始scheme编码后拼上去。URL编码可以用现成函数var rawScheme alipays://platformapi/startapp?appId20000056; var encoded encodeURIComponent(rawScheme); var finalUrl https://render.alipay.com/p/s/i?scheme encoded;Python后端拼链接时同样有对应的urllib.parse.quote逻辑相同。这段编码要保留完整的协议头和参数绝对不能只编码host部分否则链接传过去会被后台截断。我自己第一次做的时候就只编码了前半段导致Android上偶发跳转失败排查了半天最后发现是和没有编码被解析成落地页自身的query参数了。4. 小程序拉起配置分包路径不行的原因与解决方案4.1 问题现象和根因如果你在小程序后台配置了分包就会遇到一个很典型的报错场景用明文scheme拉起小程序主包页面可以正常打开一旦page参数配成分包下的路径就拉不起来要么页面白屏要么直接跳到小程序首页。我先说结论这不是支付宝的bug是路径格式没过关。小程序分包页面的路径跟主包页面不一样主包页面是pages/index/index这种写法分包页面必须写成分包名/pages/xxx/xxx的完整路径。很多人习惯性写成/pages/...或者在路径前多加了一个/甚至把分包名写成了subpackages这种带s的复数形式导致找不到页面。举个例子你在小程序开发者工具里的分包结构是这样的├── pages │ └── index │ └── index.vue └── packageA └── pages └── detail └── index.vue打开主包页面pages/index/index没问题但打开分包packageA里的页面时page参数应该写成page%2FpackageA%2Fpages%2Fdetail%2Findex注意分包名前没有s路径里的packageA要和开发者工具的配置文件里subPackages字段配置的名字完全一致。4.2 正确路径、URL编码和方案对比如果你是在H5里通过明文scheme拉起小程序完整地址是这样拼的alipays://platformapi/startapp?appId2021003111111111page%2FpackageA%2Fpages%2Fdetail%2Findex也就是说先把路径/packageA/pages/detail/index整体URL编码成%2FpackageA%2Fpages%2Fdetail%2Findex再拼进scheme。很多人配置分包路径不行就是卡在这一步直接在page参数里写了明文路径没有做编码或者只把/替换成了\/。App在解析scheme时会把未编码的/当成路径分隔符导致整个page参数解析错位自然拉不起分包页面。我再放一个对比表方便你自查写法编码后结果page/pages/index/indexpage%2Fpages%2Findex%2Findex正常pagepages/index/indexpagepages%2Findex%2Findex可能正常取决于App版本page/packageA/pages/detail/indexpage%2FpackageA%2Fpages%2Fdetail%2Findex正常pagepackageA/pages/detail/indexpagepackageA%2Fpages%2Fdetail%2Findex部分版本返回首页pagesubpackages/packageA/pages/detail/index编译后报错找不到分包如果排查到这一步还是拉不起来建议在支付宝小程序开发者工具里打开真机调试在App端看日志输出它会直接告诉你page路径匹配失败。这比自己瞎猜高效得多。4.3 为什么模拟器1:1也拉不起来关于模拟器我必须说清楚一个容易产生误导的点。支付宝小程序开发者工具里的模拟器可以做到页面渲染1:1高还原你在这个模拟器里调试页面效果、交互逻辑都没问题但scheme唤起只能在真机支付宝App上验证。原因是scheme的解析者是支付宝App本身开发者工具模拟器里没有完整的App运行时不会注册alipays://协议。所以你在模拟器里点测试链接大概率没有任何反应或者只跳一个错误提示页。这跟沙箱环境类似。支付宝开放平台的沙箱网关主要用于API联调比如手机网站支付、App支付这些接口的请求和回调但沙箱环境不会伪装一个完整版支付宝App来响应scheme。要测alipays://拉起、分包页面跳转这些能力老老实实在真机上装正式版支付宝测。我自己见过不少开发者因为过度依赖模拟器和沙箱开发阶段拖了很久最后在真机上跑一次就发现一堆问题。5. 支付宝回调、沙箱与验签报错连带常见的三个坑5.1 沙箱环境和真机模拟器到底能不能测scheme沙箱环境是开放平台提供的一套联调环境通常在支付业务里用来测下单、退款、异步通知这些功能。这里有一个容易和scheme混在一起的误解很多人以为在沙箱环境里也能测H5唤起App的scheme实际上沙箱环境跟真实支付宝App是隔离的你在沙箱里用自己的账号登录也会被引导去沙箱专用App或沙箱版网页收银台而不是手机里那个正式版支付宝。所以scheme不适合在沙箱里整体联调。那沙箱用来干什么用来验签和回调处理的开发。你可以通过沙箱网关发起一笔支付然后接收支付宝的异步通知在服务端调试验签逻辑。整个过程不需要真实金额适合用来把通知处理、验签、订单状态更新的流程跑通。真机上测试scheme唤起的部分在正式环境小金额走一笔就够了。5.2 异步通知回调不能只验业务数据支付宝的异步通知回调是支付成功后由支付宝服务器主动请求你的回调地址。这一步只做订单状态判断是不行的必须先验签再更新订单。原因是回调地址是公网可访问的任何人都可以伪造一个支付成功的通知推给你如果你不验签就把订单标记为已支付资金损失基本是必然的。验签逻辑并不复杂拿支付宝公钥对通知参数做RSA2验签验签通过后再比对out_trade_no、total_amount、app_id这些业务字段。顺序不能反先验签后处理业务。有些SDK内部封装好了验签方法但如果你在回调里看到验签失败这类日志多半是公钥配置错了或从headers里取的签名值多带了引号、换行符。5.3 Python验签时报argument should be integer or bytes-like object这个报错我见过太多次了尤其是在用Python处理支付宝异步通知时。它的完整报错一般是argument should be integer or bytes-like object, not str原因是支付宝异步通知返回的签名是Base64编码的字符串而有些Python验签库要求你传入的是bytes类型不能直接传字符串进去。很多人直接把通知里的sign字段原样传给验签函数自然就报了这个错。正确做法是先把签名做Base64解码import base64 from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import SHA256 # 1. 把支付宝公钥字符串导入 pub_key RSA.import_key(ALIPAY_PUBLIC_KEY) # 2. 把通知里的sign字段做base64解码得到bytes signature base64.b64decode(sign_str) # sign_str 是支付宝通知参数中的 sign # 3. 对待验签内容做SHA256摘要并验签 message sign_content_str.encode(utf-8) h SHA256.new(message) verifier PKCS1_v1_5.new(pub_key) result verifier.verify(h, signature)这里的ALIPAY_PUBLIC_KEY是完整的-----BEGIN PUBLIC KEY-----到-----END PUBLIC KEY-----的字符串不能只贴中间那段。而且要注意Python SDK版本差异有的库用的是rsa.verify()有的用Crypto.Signature参数格式略有不同但核心都是对sign做base64解码再验。6. scheme的边界感不硬造、不乱用6.1 支付类场景不要自己拼scheme清单里列出来的都是页面唤起类scheme属于相对安全的范围。但有一个原则我希望特别强调不要在页面scheme里试图伪造支付能力。比如你想让用户直接唤起一个支付宝转账页面并自动填好收款人和金额这已经涉及到资金交易支付宝这边不会允许通过一个明文scheme就完成因为里面没有任何签名和白名单机制。支付宝针对转账、收单这类能力提供了官方接口比如转账api、当面付等都要求服务端签名、验签。如果你在网上搜到用一条alipays链接完成转账的方法基本都是不可用的。这不是技不如人而是支付宝从风控设计上就堵死了这条路。想实现这类需求去开放平台申请对应的产品权限别在scheme上浪费时间。我见过一个真实项目前端同学为了省事想在H5里直接拼一条转账scheme结果上线后用户点按钮毫无反应第二天就紧急下掉了。这种问题不是运气问题是方案选型错了。6.2 安全建议和自测appId的小方法最后分享一个我实际验证appId是否可用的小方法用一台Android测试机装好支付宝开USB调试用adb连上后打开支付宝任意页面执行adb logcat | grep -i alipays这时候你在支付宝里访问那些有跳转能力的页面或者自己在浏览器里点一下待验证的scheme日志里就会打出支付宝实际解析出来的scheme内容和路径。用这个方式你可以确认当前版本下各个appId对应的真实页面也可以在跳转异常时快速定位是appId失效了还是参数写错了。另外一个建议所有scheme链接都统一走后端拼接下发不要在前端写死。这样一来一旦支付宝版本升级导致某个appId失效你能在后端一键切换而不用发版。这个经验是从一次线上事故里总结的某个营销页里写死了扫一扫的appId结果灰度版本覆盖期间有人点不动排查了半小时最后发现是客户端版本兼容问题前端改完还得等审核非常被动。还有一点关于明文scheme的安全提醒不要把用户身份信息或订单号明文拼在scheme里。虽然scheme本身不是敏感能力但这类链接会出现在浏览器历史、服务端日志里一旦包含敏感数据就成了泄露风险。如果你需要在跳转时带参数使用官方提供的scheme生成接口或服务端中转的方式别裸奔着拼字符串。我自己至今还保留着这份scheme清单每次大版本支付宝更新后都会在真机上重新过一遍。scheme这种东西看起来只是一串链接但背后牵扯的版本兼容、路径编码、安全边界一不留神就能折腾掉半天。希望这份整理能帮你少走点弯路。本文还有配套的精品资源点击获取