异步通知是指一笔订单支付完成后,支付宝会将该笔订单的变更信息,沿着商家调用支付请求时所传入的异步通知地址 notify_url,通过 POST 请求的形式将支付结果作为参数通知到商家系统。
异步回调地址状态码(http 状态码)为 200 时表示异步通知成功,返回码为 404 或 500 时则表示服务器内部错误,需要商家自行排查。
商家如果因为其它原因没有收到支付宝服务端返回的异步通知,可根据 异步通知问题 进行排查。
**接口/**默认通知 | 通知地址 | 触发通知类型 | 通知类型说明 | 通知是否默认开启 |
---|---|---|---|---|
alipay.fund.auth.order.app.freeze | notify_url | fund_auth_freeze.init | 资金预授权订单创建 | 否 |
alipay.fund.auth.order.freeze | notify_url | fund_auth_freeze | 资金预授权冻结成功 | 是 |
alipay.fund.auth.order.voucher.create | notify_url | fund_auth_freeze.closed | 资金预授权订单关闭 | 否 |
alipay.fund.auth.order.unfreeze | notify_url | fund_auth_unfreeze | 资金授权订单解冻 | 是 |
alipay.fund.auth.operation.cancel | notify_url | fund_auth_operation_cancel | 资金预授权明细撤销 | 是 |
到达超时解冻时间触发自动解冻 | 网关配置地址 | fund_auth_unfreeze | 资金授权订单解冻 | 是 |
参数 | 类型 | 是否必填 | 最大长度 | 描述 | 示例值 |
---|---|---|---|---|---|
auth_no | String | 必须 | 64 | 支付宝资金授权订单号 | 2014070800002001550000014417 |
notify_type | String | 必须 | 64 | 通知类型取值见上文<接口与默认通知说明> | fund_auth_freeze |
out_order_no | String | 必须 | 64 | 商家的资金授权订单号 | 4977164666634053 |
operation_id | String | 必须 | 64 | 支付宝的资金操作流水号 | 2014070800032850551 |
out_request_no | String | 必须 | 64 | 商家资金操作流水号 | 8077735255938032 |
operation_type | String | 必须 | 16 | 资金操作类型,枚举值如下:FREEZE:冻结UNFREEZE:解冻PAY:转交易 | FREEZE |
amount | String | 必须 | 11 | 本次操作冻结的金额单位为:元(人民币),精确到小数点后两位 | 0.01 |
status | String | 必须 | 20 | 资金预授权明细的状态,枚举值如下:INIT:初始 SUCCESS: 该明细操作成功 CLOSED:该明细操作已关闭 | SUCCESS |
gmt_create | String | 必须 | 20 | 明细创建时间 | 2014-09-15 11:23:04 |
gmt_trans | String | 必须 | 20 | 明细处理完成时间 | 2014-09-15 11:23:04 |
payer_logon_id | String | 必须 | 100 | 付款方支付宝账号登录号,脱敏 | test***@alitest.com |
payer_user_id | String | 必须 | 32 | 付款方支付宝账号UID | 2088102000275885 |
payee_logon_id | String | 可选 | 100 | 收款方支付宝账号,脱敏 | 159****5620 |
payee_user_id | String | 可选 | 32 | 收款方支付宝账号UID | 2088102000275795 |
total_freeze_amount | String | 必须 | 11 | 累计冻结金额 | 0.01 |
total_unfreeze_amount | String | 必须 | 11 | 累计解冻金额 | 0.01 |
total_pay_amount | String | 必须 | 11 | 累计支付金额 | 0.01 |
rest_amount | String | 必须 | 11 | 剩余冻结金额 | 0.01 |
credit_amount | String | 可选 | 11 | 本次操作中信用金额,单位为:元(人民币),精确到小数点后两位 | 0.01 |
fund_amount | String | 可选 | 11 | 本次操作中自有资金金额,单位为:元(人民币),精确到小数点后两位 | 0.01 |
total_freeze_credit_amount | String | 可选 | 11 | 累计冻结信用金额,单位为:元(人民币),精确到小数点后两位 | 0.01 |
total_freeze_fund_amount | String | 可选 | 11 | 累计冻结自有资金金额,单位为:元(人民币),精确到小数点后两位 | 0.01 |
total_unfreeze_credit_amount | String | 可选 | 11 | 累计解冻信用金额,单位为:元(人民币),精确到小数点后两位 | 0.01 |
total_unfreeze_fund_amount | String | 可选 | 11 | 累计解冻自有资金金额,单位为:元(人民币),精确到小数点后两位 | 0.01 |
total_pay_credit_amount | String | 可选 | 11 | 累计支付信用金额,单位为:元(人民币),精确到小数点后两位 | 0.01 |
total_pay_fund_amount | String | 可选 | 11 | 累计支付自有资金金额,单位为:元(人民币),精确到小数点后两位 | 0.01 |
rest_credit_amount | String | 可选 | 11 | 剩余冻结信用金额,单位为:元(人民币),精确到小数点后两位 | 0.01 |
rest_fund_amount | String | 可选 | 11 | 剩余冻结自有资金金额,单位为:元(人民币),精确到小数点后两位 | 0.01 |
pre_auth_type | String | 可选 | 20 | 预授权类型,目前支持 CREDIT_AUTH(信用预授权); 商家可根据该标识来判断该笔预授权的类型,当返回值为"CREDIT_AUTH"表明该笔预授权为信用预授权,没有真实冻结资金;当返回值为空或者不为"CREDIT_AUTH"则表明该笔预授权为普通资金预授权,会冻结用户资金。 | CREDIT_AUTH |
credit_merchant_ext | String | 可选 | 128 | 芝麻透出给商家的信息,具体内容由商家与芝麻约定后返回 | {"1003190":"true"} |
如果商家传入的 notify_url 为:https://www.merchant.com/receive_notify.htm
,则示例异步通知如下:
https://www.merchant.com/receive_notify.htm?gmt_create=2021-12-06 23%3A59%3A55&charset=utf-8&rest_credit_amount=99.00&operation_type=FREEZE&sign=$$$&rest_fund_amount=0.00&auth_no=2021120610002001030501221111¬ify_id=2021120700222000000090241427601111&total_freeze_credit_amount=99.00¬ify_type=fund_auth_freeze&gmt_trans=2021-12-06 23%3A59%3A59&operation_id=20211206696407711111&total_pay_fund_amount=0.00&out_request_no=210781146788652855760491111&payer_user_id=2088122536931111&app_id=2021002110681111&sign_type=RSA2&amount=99.00&rest_amount=99.00¬ify_time=2021-12-07 00%3A00%3A00&fund_amount=0.00&total_pay_credit_amount=0.00&payee_user_id=2088041032831111&credit_amount=99.00&pre_auth_type=CREDIT_AUTH&out_order_no=2107811467886528557601111&total_freeze_fund_amount=0.00&payee_logon_id=it_***%40meituan.com&version=1.0&total_unfreeze_fund_amount=0.00&total_pay_amount=0.00&total_freeze_amount=99.00&total_unfreeze_credit_amount=0.00&total_unfreeze_amount=0.00&status=SUCCESS&payer_logon_id=131****1111
**注意:**第三方代商家调用支付接口得到的异步通知有所不同,会带上 auth_app_id,即第三方应用的 APPID,第三方代调用场景下,服务商收到的异步通知示例如下:
https://www.merchant.com/receive_notify.htm?gmt_create=2021-12-06 23%3A59%3A55&charset=utf-8&rest_credit_amount=99.00&operation_type=FREEZE&sign=$$$&rest_fund_amount=0.00&auth_no=2021120610002001030501221111¬ify_id=2021120700222000000090241427601111&total_freeze_credit_amount=99.00¬ify_type=fund_auth_freeze&gmt_trans=2021-12-06 23%3A59%3A59&operation_id=20211206696407711111&total_pay_fund_amount=0.00&out_request_no=210781146788652855760491111&payer_user_id=2088122536931111&app_id=2021002110681111&sign_type=RSA2&amount=99.00&rest_amount=99.00¬ify_time=2021-12-07 00%3A00%3A00&fund_amount=0.00&total_pay_credit_amount=0.00&payee_user_id=2088041032831111&credit_amount=99.00&pre_auth_type=CREDIT_AUTH&out_order_no=2107811467886528557601111&total_freeze_fund_amount=0.00&payee_logon_id=it_***%40meituan.com&version=1.0&total_unfreeze_fund_amount=0.00&total_pay_amount=0.00&total_freeze_amount=99.00&total_unfreeze_credit_amount=0.00&auth_app_id=2021002110681111&total_unfreeze_amount=0.00&status=SUCCESS&payer_logon_id=131****1111
推荐使用官方 SDK 封装的 rsaCheckV1 或 rsaCertCheckV1 进行验签,若不使用 SDK,请按照以下流程处理验签。
//官方SDk验签方法
/**
* 如果是RSA或RSA2验签,请调用此方法进行验签
* Params:
* params – 待验签的从支付宝接收到的参数Map
* alipayPublic – 支付宝公钥字符串
* charset – 参数内容编码集
* signType – 指定采用的签名方式,RSA或RSA2
* Returns:
* true:验签通过;false:验签不通过
*/
boolean isSign = AlipaySignature.rsaCheckV1( params, alipayPublic, "UTF-8","RSA2");
/**
* 如果是公钥证书验签,请调用此方法进行验签
* Params:
* params – 待验签的从支付宝接收到的参数Map
* alipayPublicCertPath – 支付宝公钥证书本地路径
* charset – 参数内容编码集
* signType – 指定采用的签名方式,RSA2
* Returns:
* true:验签通过;false:验签不通过
*/
boolean isSign = AlipaySignature.rsaCertCheckV1( params, alipayPublicCertPath, "UTF-8","RSA2");
amount=99.00&app_id=2021002110681111&auth_app_id=2021002110681111&auth_no=2021120610002001030501221111&charset=utf-8&credit_amount=99.00&fund_amount=0.00&gmt_create=2021-12-06 23:59:55&gmt_trans=2021-12-06 23:59:59¬ify_id=2021120700222000000090241427601111¬ify_time=2021-12-07 00:00:00¬ify_type=fund_auth_freeze&operation_id=20211206696407711111&operation_type=FREEZE&out_order_no=2107811467886528557601111&out_request_no=210781146788652855760491111&payee_logon_id=it_***@meituan.com&payee_user_id=2088041032831111&payer_logon_id=131****1111&payer_user_id=2088122536931111&pre_auth_type=CREDIT_AUTH&rest_amount=99.00&rest_credit_amount=99.00&rest_fund_amount=0.00&status=SUCCESS&total_freeze_amount=99.00&total_freeze_credit_amount=99.00&total_freeze_fund_amount=0.00&total_pay_amount=0.00&total_pay_credit_amount=0.00&total_pay_fund_amount=0.00&total_unfreeze_amount=0.00&total_unfreeze_credit_amount=0.00&total_unfreeze_fund_amount=0.00&version=1.0
上述有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。在上述验证通过后商家必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。
参数 | 类型 | 是否必填 | 最大长度 | 描述 | 示例值 |
---|---|---|---|---|---|
notify_time | Date | 是 | - | 通知时间。通知的发送时间。格式为 yyyy-MM-dd HH:mm:ss。 | 2020-12-27 06:20:30 |
notify_type | String | 是 | 64 | 通知类型。枚举值:trade_status_sync。 | trade_status_sync |
notify_id | String | 是 | 128 | 通知校验 ID。 | ac05099524730693a8b330c5ecf72da9786 |
sign_type | String | 是 | 10 | 签名类型。商家生成签名字符串所使用的签名算法类型,目前支持 RSA2 和 RSA,推荐使用 RSA2(如果开发者手动验签,不使用 SDK 验签,可以不传此参数)。 | RSA2 |
sign | String | 是 | 344 | 签名。可查看异步返回结果的验签(如果开发者手动验签,不使用 SDK 验签,可以不传此参数)。 | 601510b7970e52cc63db0f44997cf70e |
trade_no | String | 是 | 64 | 支付宝交易号。支付宝交易凭证号。 | 20213112011001004330000121536 |
app_id | String | 是 | 32 | 开发者的 app_id。支付宝分配给开发者的应用 APPID。 | 2014072300007148 |
auth_app_id | String | 是 | 32 | 开发者的 app_id,在服务商调用的场景下为授权方的 app_id。 | 2014072300007148 |
out_trade_no | String | 是 | 64 | 商户订单号。 | 6823789339978248 |
out_biz_no | String | 否 | 64 | 商家业务号。商家业务 ID,主要是退款通知中返回退款申请的流水号。 | HZRF001 |
buyer_id | String | 否 | 16 | 买家支付宝用户号。买家支付宝账号对应的支付宝唯一用户号。 | 2088102122524333 |
buyer_logon_id | String | 否 | 100 | 买家支付宝账号。 | 180****0062 |
seller_id | String | 否 | 30 | 卖家支付宝用户号。 | 2088101106499364 |
seller_email | String | 否 | 100 | 卖家支付宝账号。 | zhuzhanghu@alitest.com |
trade_status | String | 是 | 32 | 交易状态。咨询目前所处的状态。 | TRADE_CLOSED |
total_amount | Number | 是 | 11 | 订单金额。本次交易支付的订单金额,单位为人民币(元)。支持小数点后两位。 | 20 |
receipt_amount | Number | 是 | 11 | 实收金额。商家在交易中实际收到的款项,单位为人民币(元)。支持小数点后两位。 | 15 |
invoice_amount | Number | 否 | 11 | 开票金额。用户在交易中支付的可开发票的金额。支持小数点后两位。 | 10.00 |
buyer_pay_amount | Number | 否 | 11 | 付款金额。用户在咨询中支付的金额。支持小数点后两位。 | 13.88 |
point_amount | Number | 否 | 11 | 集分宝金额。使用集分宝支付的金额。支持小数点后两位。 | 12.00 |
refund_fee | Number | 否 | 11 | 总退款金额。退款通知中,返回总退款金额,单位为元,支持小数点后两位。 | 2.58 |
send_back_fee | Number | 否 | 11 | 实际退款金额。商家实际退款给用户的金额,单位为元,支持小数点后两位。 | 2.08 |
subject | String | 否 | 256 | 订单标题。商品的标题/交易标题/订单标题/订单关键字等,是请求时对应的参数,原样通知回来。 | XXX交易 |
body | String | 否 | 400 | 商品描述。该订单的备注、描述、明细等。对应请求时的 body 参数,原样通知回来。 | XXX交易内容 |
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.SS。 | 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"}] |
voucher_detail_list | String | 否 | - | 优惠券信息。本交易支付时所使用的所有优惠券信息,详请可查看下表 优惠券信息说明 。 | [{"amount":"0.20","merchantContribute":"0.00","name":"一键创建券模板的券名称","otherContribute":"0.20","type":"ALIPAY_BIZ_VOUCHER","memo":"学生8折优惠"}] |
枚举名称 | 枚举说明 |
---|---|
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 | 否 | 11 | 支付金额。使用指定支付渠道支付的金额,单位为元。 | 15.00 |
参数 | 类型 | 是否必填 | 最大长度 | 描述 | 示例值 |
---|---|---|---|---|---|
voucherId | String | 是 | 32 | 券 ID | 2015102600073002039000002D5O |
templateId | String | 否 | 64 | 券模板 ID | 20171030000730015359000EMZP0 |
name | String | 是 | 64 | 券名称 | 5 元代金券 |
type | String | 是 | 32 | 优惠类型。当前支持以下几种主要类型:ALIPAY_BIZ_VOUCHER:商家全场券。ALIPAY_COMMON_ITEM_VOUCHER:商家单品券。ALIPAY_CASH_VOUCHER:平台优惠券,支付宝或第三方出资。ALICREDIT_INTFREE_VOUCHER:花呗分期券,该券仅做订单外的工作呗分期费用减免,并不抵扣订单内支付金额。**注意:**不排除未来新增其它类型的可能,商家接入时请注意兼容性,避免硬编码。 | ALIPAY_BIZ_VOUCHER |
amount | Number | 是 | 11 | 优惠金额。优惠金额中,由商家出资的金额。 | 10.00 |
merchantContribute | Number | 否 | 11 | 商家出资金额。优惠金额中,由商家出资的金额。 | 9.00 |
otherContribute | Number | 否 | 11 | 其他出资方出资金额。可能是支付宝,可能是品牌商,或者其他方,也可能是他们的共同出资。 | 1.00 |
otherContributeDetail | ContributeDetail[] | 否 | 优惠券的其他出资方明细 | ||
L contributeType | String | 否 | 32 | 出资方类型,如品牌商出资、支付宝平台出资等。 | PLATFORM |
L contributeAmount | Number | 否 | 8 | 出资方金额 | 0.18 |
memo | String | 否 | 256 | 优惠券备注信息。 | 学生专用优惠 |
某商家设置的通知地址为 https://api.xx.com/receive_notify.htm
,对应接收到通知的示例如下:
**注意:**以下示例报文仅供参考,实际返回的详细报文请以实际返回为准。
https://api.xx.com/receive_notify.htm?gmt_payment=2015-06-11 22:33:59¬ify_id=42af7baacd1d3746cf7b56752b91edcj34&seller_email=testyufabu07@alipay.com¬ify_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¬ify_time=2015-06-11 22:34:03&subject=FACE_TO_FACE_PAYMENT_PRECREATE中文&trade_status=TRADE_SUCCESS&sign_type=RSA2
**第一步:**在通知返回参数列表中,除去 sign
、sign_type
两个参数外,通知返回的参数均为待验签的参数。
第二步: 将剩下参数进行 URLDecode,然后进行字典排序,组成字符串,得到待签名字符串:
gmt_create=2015-06-11 22:33:46&gmt_payment=2015-06-11 22:33:59¬ify_id=42af7baacd1d3746cf7b56752b91edcj34¬ify_time=2015-06-11 22:34:03¬ify_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
第三步: 将签名参数(sign)使用 base64 解码为字节码串。
第四步: 使用 RSA 的验签方法,通过签名字符串、签名参数(经过 base64 解码)及支付宝公钥验证签名。
第五步:在步骤四验证签名正确后,必须再严格按照如下描述校验通知数据的正确性。
SDK接收以及验签示例代码(此处以 Java 语言为例,按照服务端 SDK 中提供的工具类,注意区分公钥和公钥证书验签代码):
//获取支付宝POST过来反馈信息,将异步通知中收到的待验证所有参数都存放到map中
Map< String , String > params = new HashMap < String , String > ();
Map requestParams = request.getParameterMap();
for(Iterator iter = requestParams.keySet().iterator();iter.hasNext();){
String name = (String)iter.next();
String[] values = (String [])requestParams.get(name);
String valueStr = "";
for(int i = 0;i < values.length;i ++ ){
valueStr = (i==values.length-1)?valueStr + values [i]:valueStr + values[i] + ",";
}
//乱码解决,这段代码在出现乱码时使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put (name,valueStr);
}
//调用SDK验证签名
//公钥验签示例代码
boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET,sign_type) ;
//公钥证书验签示例代码
// boolean flag = AlipaySignature.rsaCertCheckV1(params,alipayPublicCertPath,"UTF-8","RSA2");
if (signVerified){
// TODO 验签成功后
//按照支付结果异步通知中的描述,对支付结果中的业务内容进行1\2\3\4二次校验,校验成功后在response中返回success
} else {
// TODO 验签失败则记录异常日志,并在response中返回fail.
}
注意:
TRADE_SUCCESS
的通知触发条件是商家开通的产品支持退款功能的前提下,买家付款成功。TRADE_FINISHED
的通知触发条件是商家开通的产品不支持退款功能的前提下,买家付款成功或商家开通的产品支持退款功能的前提下,交易已经成功并且已经超过可退款期限。响应值 | 描述 | 异步是否重试发送 |
---|---|---|
fail | 消息获取失败 | 重试 |
success | 消息获取成功 | 不重试 |
request.Form("out_order_no")
、$_POST['out_order_no']
、request.Form("out_trade_no")
、$_POST['out_trade_no']
。success
。如果商家反馈给支付宝的字符不是 success
这 7 个字符,支付宝服务器会 立即尝试重发 3 次通知(最多 3 次),同时根据重试规则不断重发通知,直到超过 24 小时 22 分钟。一般情况下,将在 25 小时以内完成 8 次通知(不包括立即重试通知次数),通知的间隔频率一般是:4m、10m、10m、1h、2h、6h、15h 。对于支付通知来说: