APP支付
在商家移动端APP内使用支付宝支付功能
用户在商家APP内消费,在支付时选择支付宝付款,调起支付宝APP完成支付
开发文档
接入准备
创建
网页/移动应用
使用企业账号登录支付宝开发平台
创建
网页/移动应用
自动生成唯一标识 APPID,用于调用API
开通 APP 支付
- 使用应用所属账号登录商家平台开通
- 如果是个人账号申请,需提供营业执照,且登录账号名称需与营业执照主体一致
绑定APP支付
配置应用信息
配置应用信息
-
使用密钥方式,平台生成RSA2密钥
通过平台生成的私钥是PKCS8格式的,需要转换为 PKCS1 格式,否则报错ASN1_CHECK_TLEN
应用私钥:用来给应用消息进行签名,请务必要妥善保管,避免遗失或泄露。
应用公钥:需要提供给支付宝开放平台,平台会对应用发送的消息进行签名验证。
支付宝公钥:应用收到支付宝发送的同步、异步消息时,使用支付宝公钥验证签名信息。
支付宝网关
应用网关
接收支付宝异步通知消息,需要传入 http(s) 公网可访问网页地址
接口内容加密方式【选填】
对请求业务内容和响应内容进行AES加密
结算
收款账户:默认收款到签约账号的支付宝余额账户,实时到账
接入
交互流程图
第 1 步用户在商户 App 客户端/小程序中购买商品下单
第 2 步商户 App 客户端/小程序将用户订单信息发送到商户服务端
第 3 步商户服务端通过支付宝服务端 SDK生成 orderStr(orderStr 中包含了订单信息和签名)
第 4 步商户服务端将 orderStr 返回给商户 App 客户端/小程序
服务端根据订单信息生成 orderStr(只是加签数据),不经过支付宝服务端,直接发给App客户端,由App客户端调起支付宝App,根据 orderStr 向支付宝服务端发送请求
第 5 步商户客户端/小程序发起支付,调起支付宝,将 orderStr 发送给支付宝。
第 6 步支付预下单:支付宝客户端将会按照商家客户端提供的请求参数进行支付预下单。正常场景下,会唤起支付宝收银台等待用户核身;异常场景下,会返回异常信息。
第 11 步返回商家 App/小程序:用户在支付宝 App 完成支付后,会跳转回商家页面,并返回最终的支付结果(即同步通知)
第 13 步支付结果异步通知,支付宝会根据步骤3 传入的异步通知地址 notify_url,发送异步通知
下单
业务逻辑
防止重复下单
金额
- amount 字段,单位为元
支付宝订单
- 用户在支付宝App输入正确的支付密码后创建
- 支付宝订单号 trade_no
商户订单
- 商户App将订单信息发送给商户服务端后创建
- 商户订单号 out_trade_no
支付
业务逻辑
防止重复支付
不同网关重复支付
- 加redis锁
- 后支付的自动退款
相同网关重复支付
通过支付日志 paymentLog解决
API
formData
1 | > 'https://openapi.alipaydev.com/gateway.do?method=alipay.trade.pay&app_id=2021000118646670&charset=utf-8&version=1.0&sign_type=RSA2×tamp=2022-03-23 22:21:56¬ify_url=https://api-dev.paihaole.cn/payment/listener/alipay&sign=r1VW6cRRgJqXAquJcTRE+b7Zsyo1bBk0YmINn9hAXwnHNMMVN0q2/sF+4i8hbIkApkAQLS4j0yfFNzvgfx6pSX+hVI8aC7hX50JdtYDWzJJP9mxlEIGJMQ2kFBiGI02GHRanLj8LiKYduy9o2VDYmz75z5hQp35Tff/7eUYeSJHsTL/AcZT2q4AKH0p5MBgciBmIak/8okv1at+8jF85enwMa6uUG0MOmlTAQC9cdUqf4UwaDp783yiBPmBpjLrrjMiTs6nLVVVZDJSEJluKxOWElw2IbJPv4aOi23BW6gChzh+J61A/UgNE9yxxuYdHM9yAh0g/TrS8YTI1jHcyCw==&alipay_sdk=alipay-sdk-nodejs-3.2.0&biz_content={"out_trade_no":"AQP164804531604457","total_amount":0.01,"auth_code":"286806172615687397","subject":"动力引擎-天津店-商品","store_id":"409","goods_detail":[{"goods_id":"service_353","goods_name":"体验课","quantity":1,"price":1}],"terminal_id":"::1","query_options":["1464-8888890657"],"product_code":"OFFLINE_PAYMENT","scene":"bar_code","timeout_express":"30m"}'.split('&') |
超时时间
订单超时时间
- 由商户控制,订单超时后由商户服务端向支付宝服务端发起[交易关闭]操作
支付超时时间
- 可在交易创建时指定一个超时时间,设置范围5min-15d
- 支付宝默认超时时间为15天(第15天24点后,交易关闭)
退款
交易发生后的一段时间内,由于业务原因(如金额错误、用户退款或者对账不平等)需要退款
默认交易发生后的 12 个月内,商家可退款。退款资金按原路退还至用户账户。
退款退费:退款时服务费不退回。
业务逻辑
防止重复退款
通过 refund 表记录
API
FAQ
如何判断退款是否成功
- 接口返回code为10000仅表示接口调用成功
异步通知如何判断对应哪笔退款交易
关闭
API
返回
1 | { |
交易状态
- 前端查询交易状态都直接向支付宝查询最新的,不要从数据库获取
状态机
wait_buyer_pay 交易创建
等待用户付款
trade_success 交易成功
trade_finished 交易完成
不可退款
trade_closed 交易关闭
- 一直部分退款退完所有交易金额则交易状态转为 TRADE_CLOSED
- 如果未退完所有交易金额,超过有效退款时间后交易状态转为 TRADE_FINISHED 不可退款
支付状态
- 异步或查询接口返回的 trade_status(交易状态)为 TRADE_SUCCESS 或 TRADE_FINISHED 时,支付宝才会认定为买家付款成功
API
放弃交易后查询
1 | { |
退款后查询
1 | { |
退款状态
API
返回
1 | { |
异步通知
支付宝通过 POST 请求向下单时传入的 notify_url 发送通知
异步地址(notify_url)需保证无任何字符,如空格、HTML 标签,且不能重定向
商户服务端需要及时响应
响应值 描述 异步是否重试发送 fail 消息获取失败 重试 success 消息获取成功 不重试 成功返回 success 字符串,失败返回 fail 字符串,否则支付宝会认为通知失败,会通过一定的策略定期重新发起通知。通知的间隔频率为:4m、10m、10m、1h、2h、6h、15h。
针对同一条异步通知重试时,异步通知参数中的 notify_id 保持不变
触发条件
==状态变化==
trade_finished
触发条件:
- 不支持退款功能且用户付款成功
- 支持退款功能且超时未退款
trade_success
触发条件:
- 支持退款功能且用户付款成功
1 | { |
trade_closed
触发条件
- 全额退款
1 | { |
验证
验证签名
- 使用支付宝sdk 中的 checkNotifySign 方法
校验数据
过滤重复的通知
验证订单信息
out_trade_no 是否为商家系统中创建的订单号
total_amount 是否确实为该订单的实际金额
验证 app_id 是否为该商家本身