异步通知(仅用于扫码支付)

当收银台调用预下单请求 API 生成二维码展示给用户后,用户通过手机扫描二维码进行支付,支付宝会将该笔订单的变更信息,沿着商户调用预下单请求时所传入的异步通知地址 notify_url,通过 POST 请求的形式将支付结果作为参数通知到商户系统。

异步回调地址状态码(http状态码) 为 200 时表示异步通知成功,返回码为 404 或 500 时则表示服务器内部错误,需要商家自行排查。

商家如果因为其他原因没有收到支付宝服务端返回的异步通知,开发者可以在开发者社区查看自查自查方案:

异步通知参数


参数

参数名称

类型

必填

描述

范例

notify_time

通知时间

Date

通知的发送时间。格式为yyyy-MM-dd HH:mm:ss

2011-12-27 06:30:30

notify_type

通知类型

String(64)

通知的类型

trade_status_sync

notify_id

通知校验ID

String(128)

通知校验 ID

ac05099524730693a8b330c5ecf72da9786

sign_type

签名类型

String(10)

商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2(如果开发者手动验签,不使用 SDK 验签,可以不传此参数)

RSA2

sign

签名

String(256)

请参考异步返回结果的验签(如果开发者手动验签,不使用 SDK 验签,可以不传此参数)

601510b7970e52cc63db0f44997cf70e

trade_no

支付宝交易号

String(64)

支付宝交易凭证号

2013112011001004330000121536

app_id

开发者的app_id

String(32)

支付宝分配给开发者的应用Id

2014072300007148

out_trade_no

商户订单号

String(64)

原支付请求的商户订单号

6823789339978248

out_biz_no

商户业务号

String(64)

商户业务ID,主要是退款通知中返回退款申请的流水号

HZRF001

buyer_id

买家支付宝用户号

String(16)

买家支付宝账号对应的支付宝唯一用户号。以 2088 开头的纯 16 位数字

2088102122524333

buyer_logon_id

买家支付宝账号

String(100)

买家支付宝账号

15901825620

seller_id

卖家支付宝用户号

String(30)

卖家支付宝用户号

2088101106499364

seller_email

卖家支付宝账号

String(100)

卖家支付宝账号

zhuzhanghu@alitest.com

trade_status

交易状态

String(32)

交易目前所处的状态

TRADE_CLOSED

total_amount

订单金额

Number(9,2)

本次交易支付的订单金额,单位为人民币(元)

20

receipt_amount

实收金额

Number(9,2)

商家在交易中实际收到的款项,单位为元

15

invoice_amount

开票金额

Number(9,2)

用户在交易中支付的可开发票的金额

10.00

buyer_pay_amount

付款金额

Number(9,2)

用户在交易中支付的金额

13.88

point_amount

集分宝金额

Number(9,2)

使用集分宝支付的金额

12.00

refund_fee

总退款金额

Number(9,2)

退款通知中,返回总退款金额,单位为元,支持两位小数

2.58

send_back_fee

实际退款金额

Number(9,2)

商户实际退款给用户的金额,单位为元,支持两位小数

2.08

subject

订单标题

String(256)

商品的标题/交易标题/订单标题/订单关键字等,是请求时对应的参数,原样通知回来

当面付交易

body

商品描述

String(400)

该订单的备注、描述、明细等。对应请求时的body参数,原样通知回来

当面付交易内容

gmt_create

交易创建时间

Date

该笔交易创建的时间。格式为yyyy-MM-dd HH:mm:ss

2015-04-27 15:45:57

gmt_payment

交易付款时间

Date

该笔交易的买家付款时间。格式为yyyy-MM-dd HH:mm:ss

2015-04-27 15:45:57

gmt_refund

交易退款时间

Date

该笔交易的退款时间。格式为yyyy-MM-dd HH:mm:ss.S

2015-04-28 15:45:57.320

gmt_close

交易结束时间

Date

该笔交易结束时间。格式为yyyy-MM-dd HH:mm:ss

2015-04-29 15:45:57

fund_bill_list

支付金额信息

String(512)

支付成功的各个渠道金额信息,详见资金明细信息说明

[{"amount":"15.00","fundChannel":"ALIPAYACCOUNT"}]


交易状态说明

枚举名称

枚举说明

WAIT_BUYER_PAY

交易创建,等待买家付款

TRADE_CLOSED

未付款交易超时关闭,或支付完成后全额退款

TRADE_SUCCESS

交易支付成功

TRADE_FINISHED

交易结束,不可退款


通知触发条件

触发条件名

触发条件描述

触发条件默认值

TRADE_FINISHED

交易完成

false(不触发通知)

TRADE_SUCCESS

支付成功

true(触发通知)

WAIT_BUYER_PAY

交易创建

false(不触发通知)

TRADE_CLOSED

交易关闭

false(不触发通知)


资金明细信息说明

参数

参数名称

类型

参数说明

是否可为空

样例

fundChannel

支付渠道

String

支付渠道,参见下面的“支付渠道说明”。

可空

ALIPAYACCOUNT

amount

支付金额

String

使用指定支付渠道支付的金额,单位为元。

可空

15.00


支付渠道说明

支付渠道代码

支付渠道

COUPON

支付宝红包

ALIPAYACCOUNT

支付宝余额

POINT

集分宝

DISCOUNT

折扣券

PCARD

预付卡

FINANCEACCOUNT

余额宝

MCARD

商家储值卡

MDISCOUNT

商户优惠券

MCOUPON

商户红包

PCREDIT

蚂蚁花呗


异步返回结果的验签


某商户设置的通知地址为 https://api.xx.com/receive_notify.htm,对应接收到通知的示例如下:


https://api.xx.com/receive_notify.htm?gmt_payment=2015-06-11 22:33:59&notify_id=42af7baacd1d3746cf7b56752b91edcj34&seller_email=testyufabu07@alipay.com&notify_type=trade_status_sync&sign=kPbQIjX+xQc8F0/A6/AocELIjhhZnGbcBN6G4MM/HmfWL4ZiHM6fWl5NQhzXJusaklZ1LFuMo+lHQUELAYeugH8LYFvxnNajOvZhuxNFbN2LhF0l/KL8ANtj8oyPM4NN7Qft2kWJTDJUpQOzCzNnV9hDxh5AaT9FPqRS6ZKxnzM=&trade_no=2015061121001004400068549373&out_trade_no=21repl2ac2eOutTradeNo322&gmt_create=2015-06-11 22:33:46&seller_id=2088211521646673&notify_time=2015-06-11 22:34:03&subject=FACE_TO_FACE_PAYMENT_PRECREATE中文&trade_status=TRADE_SUCCESS&sign_type=RSA2


  1. 在通知返回参数列表中,除去sign、sign_type两个参数外,凡是通知返回回来的参数皆是待验签的参数。
  2. 将剩下参数进行 url_decode, 然后进行字典排序,组成字符串,得到待签名字符串:


gmt_create=2015-06-11 22:33:46&gmt_payment=2015-06-11 22:33:59&notify_id=42af7baacd1d3746cf7b56752b91edcj34&notify_time=2015-06-11 22:34:03&notify_type=trade_status_sync&out_trade_no=21repl2ac2eOutTradeNo322&seller_email=testyufabu07@alipay.com&seller_id=2088211521646673&subject=FACE_TO_FACE_PAYMENT_PRECREATE中文&trade_no=2015061121001004400068549373&trade_status=TRADE_SUCCESS


  1. 将签名参数(sign)使用 base64 解码为字节码串。
  2. 使用 RSA/RSA2 的验签方法,通过签名字符串、签名参数(经过 base64 解码)及支付宝公钥验证签名。
  3. 需要严格按照如下描述校验通知数据的正确性。


  • 商户需要验证该通知数据中的 out_trade_no 是否为商户系统中创建的订单号;
  • 判断 total_amount 是否确实为该订单的实际金额(即商户订单创建时的金额);
  • 校验通知中的 seller_id(或者seller_email) 是否为 out_trade_no 这笔单据的对应的操作方(有的时候,一个商户可能有多个 seller_id/seller_email)。


上述有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。在支付宝的业务通知中,只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时,支付宝才会认定为买家付款成功。


注意

  • 状态 TRADE_SUCCESS 的通知触发条件是商户签约的产品支持退款功能的前提下,买家付款成功;
  • 交易状态 TRADE_FINISHED 的通知触发条件是商户签约的产品不支持退款功能的前提下,买家付款成功;或者,商户签约的产品支持退款功能的前提下,交易已经成功并且已经超过可退款期限。


服务器异步通知页面特性


  1. 商户设置的异步地址必须是外网能够顺利访问到的地址,并且保证服务器异步通知页面(notify_url)上无任何字符,如空格、HTML 标签、开发系统自带抛出的异常提示信息等;
  2. 支付宝是用 POST 方式发送通知信息,因此该页面中获取参数的方式,如:request.Form("out_trade_no")$_POST['out_trade_no']
  3. 支付宝主动发起通知,该方式才会被启用;
  4. 只有在支付宝的交易管理中存在该笔交易,且发生了交易状态的改变,支付宝才会通过该方式发起服务器通知(即时到账中交易状态为“等待买家付款”的状态默认是不会发送通知的);
  5. 服务器间的交互,不像页面跳转同步通知可以在页面上显示出来,这种交互方式是不可见的;
  6. 第一次交易状态改变(即时到账中此时交易状态是交易完成)时,不仅会返回同步处理结果,而且服务器异步通知页面也会收到支付宝发来的处理结果通知;
  7. 程序执行完后必须通过 PrintWriter 类打印输出"success"(不包含引号)。如果商户反馈给支付宝的字符不是 success 这7个字符,支付宝服务器会不断重发通知,直到超过 24 小时 22 分钟。一般情况下,25 小时以内完成 8 次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h);
  8. 程序执行完成后,该页面不能执行页面跳转。如果执行页面跳转,支付宝会收不到 success 字符,会被支付宝服务器判定为该页面程序运行出现异常,而重发处理结果通知;
  9. cookies、session 等在此页面会失效,即无法获取这些数据;
  10. 该方式的调试与运行必须在服务器上,即互联网上能访问;
  11. 该方式的作用主要防止订单丢失,即页面跳转同步通知没有处理订单更新,它则去处理;
  12. 当商户收到服务器异步通知并打印出 success 时,服务器异步通知参数 notify_id 才会失效。也就是说在支付宝发送同一条异步通知时(包含商户并未成功打印出 success 导致支付宝重发数次通知),服务器异步通知参数 notify_id 是不变的。
onlineServer