手机网站支付结果异步通知

发布于:2016年09月08日 已被阅读

对于手机网站支付产生的交易,支付宝会根据原始支付API中传入的异步通知地址notify_url,通过POST请求的形式将支付结果作为参数通知到商户系统。

https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.imYUy9&treeId=193&articleId=105286&docType=1#s5

异步通知参数

参数参数名称类型必填描述范例
notify_time通知时间Date通知的发送时间。格式为yyyy-MM-dd HH:mm:ss2015-14-27 15:45:58
notify_type通知类型String(64)通知的类型trade_status_sync
notify_id通知校验IDString(128)通知校验IDac05099524730693a8b330c5ecf72da9786
sign_type签名类型String(10)签名算法类型,目前支持RSARSA
sign签名String(256)请参考异步返回结果的验签601510b7970e52cc63db0f44997cf70e
trade_no支付宝交易号String(64)支付宝交易凭证号2013112011001004330000121536
app_id开发者的app_idString(32)支付宝分配给开发者的应用Id2014072300007148
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:ss2015-04-27 15:45:57
gmt_payment交易付款时间Date该笔交易的买家付款时间。格式为yyyy-MM-dd HH:mm:ss2015-04-27 15:45:57
gmt_refund交易退款时间Date该笔交易的退款时间。格式为yyyy-MM-dd HH:mm:ss.S2015-04-28 15:45:57.320
gmt_close交易结束时间Date该笔交易结束时间。格式为yyyy-MM-dd HH:mm:ss2015-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交易关闭true(触发通知)

资金明细信息说明

参数参数名称类型参数说明是否可为空样例
fundChannel支付渠道String支付渠道,参见下面的“支付渠道说明”。可空ALIPAYACCOUNT
amount支付金额String使用指定支付渠道支付的金额,单位为元。可空15.00

支付渠道说明

支付渠道代码支付渠道
COUPON支付宝红包
ALIPAYACCOUNT支付宝余额
POINT集分宝
DISCOUNT折扣券
PCARD预付卡
FINANCEACCOUNT余额宝
MCARD商家储值卡
MDISCOUNT商户优惠券
MCOUPON商户红包
PCREDIT蚂蚁花呗

服务器异步通知页面特性

  • 必须保证服务器异步通知页面(notify_url)上无任何字符,如空格、HTML标签、开发系统自带抛出的异常提示信息等;

  • 支付宝是用POST方式发送通知信息,因此该页面中获取参数的方式,如:request.Form(“out_trade_no”)、$_POST[‘out_trade_no’];

  • 支付宝主动发起通知,该方式才会被启用;

  • 只有在支付宝的交易管理中存在该笔交易,且发生了交易状态的改变,支付宝才会通过该方式发起服务器通知(即时到账交易状态为“等待买家付款”的状态默认是不会发送通知的);

  • 服务器间的交互,不像页面跳转同步通知可以在页面上显示出来,这种交互方式是不可见的;

  • 第一次交易状态改变(即时到账中此时交易状态是交易完成)时,不仅会返回同步处理结果,而且服务器异步通知页面也会收到支付宝发来的处理结果通知;

  • 程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h);

  • 程序执行完成后,该页面不能执行页面跳转。如果执行页面跳转,支付宝会收不到success字符,会被支付宝服务器判定为该页面程序运行出现异常,而重发处理结果通知;

  • cookies、session等在此页面会失效,即无法获取这些数据;

  • 该方式的调试与运行必须在服务器上,即互联网上能访问;

  • 该方式的作用主要防止订单丢失,即页面跳转同步通知没有处理订单更新,它则去处理;

  • 当商户收到服务器异步通知并打印出success时,服务器异步通知参数notify_id才会失效。也就是说在支付宝发送同一条异步通知时(包含商户并未成功打印出success导致支付宝重发数次通知),服务器异步通知参数notify_id是不变的。

异步返回结果的验签

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

1
https://api.xx.com/receive_notify.htm?total_amount=2.00&buyer_id=2088102116773037&body=大乐透2.1&trade_no=2016071921001003030200089909&refund_fee=0.00&notify_time=2016-07-19 14:10:49&subject=大乐透2.1&sign_type=RSA&charset=utf-8&notify_type=trade_status_sync&out_trade_no=0719141034-6418&gmt_close=2016-07-19 14:10:46&gmt_payment=2016-07-19 14:10:47&trade_status=TRADE_FINISHED&version=1.0&sign=kPbQIjX+xQc8F0/A6/AocELIjhhZnGbcBN6G4MM/HmfWL4ZiHM6fWl5NQhzXJusaklZ1LFuMo+lHQUELAYeugH8LYFvxnNajOvZhuxNFbN2LhF0l/KL8ANtj8oyPM4NN7Qft2kWJTDJUpQOzCzNnV9hDxh5AaT9FPqRS6ZKxnzM=&gmt_create=2016-07-19 14:10:44&app_id=2015102700040153&seller_id=2088102119685838&notify_id=4a91b7a78a503640467525113fb7d8bg8e

第一步: 在通知返回参数列表中,除去sign、sign_type两个参数外,凡是通知返回回来的参数皆是待验签的参数。

第二步: 将剩下参数进行url_decode, 然后进行字典排序,组成字符串,得到待签名字符串:

1
body=大乐透2.1&buyer_id=2088102116773037&charset=utf-8&notify_time=2016-07-19 14:10:49&notify_type=trade_status_sync&gmt_close=2016-07-19 14:10:46&gmt_payment=2016-07-19 14:10:47&out_trade_no=0719141034-6418&refund_fee=0.00&subject=大乐透2.1&total_amount=2.00&trade_no=2016071921001003030200089909&trade_status=TRADE_FINISHED&version=1.0

第三步: 将签名参数(sign)使用base64解码为字节码串。

第四步: 使用RSA的验签方法,通过签名字符串、签名参数(经过base64解码)及支付宝公钥验证签名。

第五步:需要严格按照如下描述校验通知数据的正确性。

1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email),4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。在支付宝的业务通知中,只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功。

注意:

  • 状态TRADE_SUCCESS的通知触发条件是商户签约的产品支持退款功能的前提下,买家付款成功;

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

FAQ

https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.imYUy9&treeId=193&articleId=105286&docType=1#s5