支付宝开放平台接入实操:应用类型、RSA2 签名与异步通知
支付宝的技术文档写得很细,但新接入的团队仍然会卡在三个地方:应用类型选错导致产品加不上、密钥模式理解错导致验签一直失败、异步通知处理写错导致订单状态对不上。这三件事都不难,只是顺序和概念必须先理清。
账号与资质部分见 网站接入支付宝/微信支付教程,产品能力与费率结构见 支付宝。本文只讲"从零写代码到第一笔钱进账"这一段。
一、应用类型先选对
支付宝开放平台创建应用时要选类型,这决定了你能挂哪些产品:
| 应用类型 | 适用形态 | 可挂载产品 |
|---|---|---|
| 网页/移动应用 | PC 网站、手机网页、原生 App | 电脑网站支付、手机网站支付、App 支付 |
| 小程序 | 支付宝小程序 | 小程序支付 |
| 生活号 | 内容与营销场景 | 部分场景支付能力 |
选错类型的代价是要重新创建应用并重新签约,历史配置白做。判断标准只有一条:看用户在什么环境里完成支付——浏览器、App 还是小程序。
二、密钥:公钥模式怎么配
支付宝提供两种密钥模式,"公钥模式"是当前主流,理解成本也最低。要做的事有四步:
- 用官方工具在本地生成一对 RSA2 密钥(推荐 2048 位),私钥留在自己服务器;
- 把你的应用公钥上传到开放平台,平台会给你一串支付宝公钥;
- 在代码里配置:应用私钥(你生成的私钥)+ 支付宝公钥(平台给的);
- 加签方式选 RSA2,不要用 RSA。
最容易混淆的一点:签名用你的应用私钥,验签用支付宝公钥。很多团队把"应用公钥"当成验签公钥来用,结果所有回调验签都失败——开放平台里有两个公钥概念,一个是"你上传的应用公钥",另一个是"平台下发的支付宝公钥",两者用途完全不同。
证书模式(应用公钥证书 + 支付宝公钥证书 + 支付宝根证书)能力更强,但维护三份证书的成本也更高。中小团队用公钥模式足够,除非有对账或高级接口要求。
三、签名与请求
签名规则是把公共参数与业务参数按字典序拼接,去掉空值与 sign 字段,用应用私钥做 SHA256-RSA 签名,再做 URL 编码。
三个实操要点:
- 参数字典序拼接要按参数名的 ASCII 码排序,不能按出现顺序;
- 空值字段必须排除,传了空字符串参与签名是最常见的验签失败原因;
- 签名前后不要对参数做二次加工,尤其注意中文字符的编码必须统一为 UTF-8。
建议直接使用官方 SDK,把签名、验签、请求封装都用官方实现,自己手写拼接字符串在参数变多后极难排查。
四、异步通知:五个步骤不能省
支付结果由支付宝以 POST 形式推送到你配置的 notify_url。正确处理顺序是:
- 接收参数,用支付宝公钥按 RSA2 验签;
- 校验
app_id是本应用、seller_id是自己的收款账号; - 校验
out_trade_no存在且金额与本地订单一致; - 判断
trade_status:只有TRADE_SUCCESS或TRADE_FINISHED才视为支付成功; - 业务处理完成后,输出纯文本
success。
第 5 步是最容易漏的:支付宝以是否返回 success 判断通知是否成功,如果返回了 HTML 页面或空响应,它会按策略重复推送——前几次可能看起来没问题,一旦你的接口返回体变了,就会持续重复通知。同样,绝不能返回 success 再异步处理业务,必须先落库再确认。
trade_status 里的两个状态要分清:TRADE_SUCCESS 表示交易成功且可退款,TRADE_FINISHED 表示交易结束、不可退款。判断"是否已收到钱"时两者都算成功,但涉及退款逻辑时只认前者。
五、四类支付产品的适用范围
| 产品 | 接口 | 使用场景 |
|---|---|---|
| 电脑网站支付 | alipay.trade.page.pay |
PC 端跳转收银台 |
| 手机网站支付 | alipay.trade.wap.pay |
手机浏览器 H5 |
| 当面付(扫码) | alipay.trade.precreate |
生成二维码,自行渲染 |
| App 支付 | alipay.trade.app.pay |
原生应用拉起支付宝 |
选择逻辑和微信支付一致:看用户所在环境。需要注意的是扫码支付会返回二维码字符串,需要你在前端生成二维码图片,不要指望接口直接给图片。
六、订单查询、关闭与退款
三个辅助接口在正确性上比支付接口更重要:
- 查询(
alipay.trade.query):用于主动确认状态。同步跳转结果不可信,如果既没收到异步通知、用户又说付了钱,唯一可靠的判断依据就是这个接口。 - 关闭(
alipay.trade.close):用于取消未支付订单,避免用户事后在旧页面完成支付导致重复入账。订单超时后应主动关闭。 - 退款(
alipay.trade.refund):支持部分退款,同一笔订单可多次退款,累计不能超过订单金额。退款是异步的,需要单独处理退款通知或主动查询。
一个常被忽略的细节:关闭订单与用户支付之间存在竞态。如果用户在关闭请求发出的同时完成支付,可能关单失败但钱已到账。正确做法是关单失败后立即查单,确认实际状态再决定后续动作。
七、常见报错对照
- 验签失败:九成是公钥用错(应用公钥 vs 支付宝公钥),或参数拼串时包含了空值字段;
- 应用未上线 / 无权限调用:应用状态未上线,或对应产品未签约;
app_id不一致:配置文件里写的是另一个应用;out_trade_no重复:同一商户订单号被复用,订单号必须全局唯一;- 回调一直重复:接口没有返回
success,或返回体被框架包了一层 JSON。
八、上线检查清单
应用已上线且产品已签约;私钥不入代码库、走环境变量或密钥管理服务;异步通知接口免登录鉴权、可公网访问、返回纯文本 success;金额校验以"元"为单位并保留两位小数;订单号全局唯一且长度符合规范;查询、关闭、退款三个接口都已实现;日志脱敏且保留通知原始报文用于排查。
支付链路的通用时序见 支付交易流程基础,沙箱与联调方法见 支付网关沙箱测试,微信侧的对应教程见 微信支付 APIv3 接入实操,对账见 对账与账单下载操作手册。更多支付方案可参见 支付 分类。
来源:16IDC 原创,文中涉及的产品能力、费率与准入要求以 opendocs.alipay.com 等官网文档及合同为准。