异步通知验签

什么是异步通知?

异步通知是通过POST方法给接口调用者异步返回的接口调用结果。在调用支付宝接口时,通知页需要被设置目标URL以便之后能够处理接收到的异步通知信息。

发送异步通知之后,支付宝会调用通知页来检查是否异步通知已被接收方收到。如果通知页没有打印出“SUCCESS”这七个字符(注意:无引号),支付宝会继续重发异步通知。通知页在不同编程语言示例代码中是以下页面:

  • Java: notify_url.jsp
  • Php: notify_url.php
  • C#: notify_url.aspx.cs

注意:

  • 支付宝异步通知的重发会在25小时之内重发八次,直到接收方打印出“SUCCESS”这七个字符。八次异步通知重发频率:2m,10m,10m,1h,2h,6h,15h
  • 仅当交易存在于支付宝交易管理中心,交易的状态才可以被变更。唯一的例外是当交易状态为“等待买家付款”时,不需要强制交易存在于支付宝交易管理中心,即可变更交易状态。

异步通知验签

收到异步通知之后,您需要对签名进行验证以确保通知确实来自支付宝并未在传播途径中被非法修改。请完成以下步骤进行异步通知验签:

MD5签名类型

  1. 验证通知发送方:
    通过使用Notify_verify 方法来确认通知是否是由支付宝发送。如果通知来自支付宝,您会在运行Notify_verify 方法之后得到 ResponseTxt==true。如果通知不是来自支付宝,则停止处理并无需进行其他下列步骤。
  2. 生成待签名字符串:
    a. 将signsign_type字段移除。
    b. 将剩下的字段用字母顺序排列。
    c. 将所有字段通过&符号拼接起来。
    例如,来自create_forex_trade接口的异步通知示例:
    notify_id=5b89a773c60af059d96b1693dd3b3d6nc1&notify_type=trade_status_sync&sign=b34d89788d9012f77f5b74ac232145f5&trade_no=2018110922001332950500389138&total_fee=0.01&out_trade_no=test20181109153145&notify_time=2018-11-09 15:36:17&currency=USD&trade_status=TRADE_FINISHED&sign_type=MD5
    其待签名字符串:
    currency=USD&notify_id=5b89a773c60af059d96b1693dd3b3d6nc1&notify_time=2018-11-0915:36:17&notify_type=trade_status_sync&out_trade_no=test20181109153145&total_fee=0.01&trade_no=2018110922001332950500389138&trade_status=TRADE_FINISHED
  3. 获取mysign参数的值:
    a. 将MD5密钥拼接到待签名字符串的尾部。
    b. 使用各自语言对应的MD5加密函数对拼接了MD5密钥的字符串进行加密,得到的加密值即为mysign的值。
  4. mysignsign的值做相等判断: 得到的加密值mysign与支付宝返回的参数sign做相等判断,如果相等,则验证通过。

RSA2/RSA签名类型

  1. 验证通知发送方:
    通过使用Notify_verify 方法来确认通知是否是由支付宝发送。如果通知来自支付宝,您会在运行Notify_verify 方法之后得到 ResponseTxt==true。如果通知不是来自支付宝,则停止处理并无需进行其他下列步骤。
  2. 生成待签名字符串:
    a. 将signsign_type字段移除。
    b. 将剩下的字段用字母顺序排列。
    c. 将所有字段通过&符号拼接起来。
    例如,来自create_forex_trade接口的异步通知示例:
    currency=USD&notify_id=5ac236e4cf7822d205cedcc252b54ebwg1&notify_time=2020-01-14 15:23:12&notify_type=trade_status_sync&out_trade_no=FALCN32YWXN2CL4KFT8&sign=NN2trlV3PKBjZN7KS4oE8PG8WkHFqXIvvQl32fJ2FO9J+HniSuvv36VYPWbARVmodnTvYVkFmR2FB9ioDX0iRTRRSCkz8+ox3ytrlRdRfaeGMSGBuHN6WP/tAHscBbNvjkzyshjTCoXO6MFFg92CR2K50DvtNNUerZa/mx4lA5I=&sign_type=RSA2&total_fee=108.00&trade_no=2020011421001003050502834160&trade_status=TRADE_FINISHED
    其待签名字符串:
    currency=USD&notify_id=5ac226e4cf7822d205cedcc252b54ebge1&notify_time=2017-08-16 15:24:12&notify_type=trade_status_sync&out_trade_no= test20170816150740&total_fee=0.01&trade_no=2017081621001003050502834160&trade_status=TRADE_FINISHED
  3. 将签名参数使用base64解码为字节码串。
  4. 使用RSA2/RSA验签方法验证签名。将待签名字符串,经过based64解码的签名参数及支付宝公钥传入RSA2/RSA验签方法,根据返回结果判定是否验签通过。RSA验签方法示例:
copy
public static boolean verify(String content, String sign, String ali_public_key, String input_charset)

Note:

    • 更多关于RSA2/RSA验签方法的信息,请参考示例代码下载
    • 为获取支付宝公钥信息,请联系支付宝国际技术支持团队(overseas_support@service.alibaba.com

Notify_verify 方法

  • 目的

验证此次通知信息是否是支付宝服务器发来的信息,以帮助校验反馈回来的数据的真假性。

  • 工作原理

获取支付宝返回数据之一的通知校验ID(notify_id),按照支付宝要求的格式拼接成要请求的链接,如:

https://intlmapi.alipay.com/gateway.do?service=notify_verify&partner=2088002396712354&notify_id=RqPnCoPT3K9%252Fvwbh3I%252BFioE227%252BPfNMl8jwyZqMIiXQWxhOCmQ5MQO%252FWd93rvCB%252BaiGg

通过访问这个请求链接,利用编程方法来模拟http请求与支付宝服务器进行交互,获得支付宝服务器上处理的结果。 

如果获得的信息是true,则校验成功;如果获得的信息是其他,则校验失败。

请求参数

参数类型说明可空示例
基本参数
serviceString接口名Nnotify_verify
partnerString(16)境外商户在支付宝的用户ID. 2088开头的16位数字N2088001159940003
业务参数
notify_idString(34)支付宝通知流水号,境外商户可以用这个流水号询问支付宝该条通知的合法性N

注意:

  • 正确的验证异步通知的顺序是:
    • 收到异步通知后,先不要回复‘success’。否则会影响支付宝系统的行为(支付宝系统会对所有已经回复了 ‘success’的异步通知的验证请求返回false
    • 调用这个接口来验证notify id.
      • 如果输入参数是无效的,支付宝会返回 Invalid
      • 如果异步通知是支付宝发出的并且验证请求是在异步通知发出后的1分钟内发起的,则返回True
      • 如果该通知不是支付宝发送的,支付宝会返回 False
      • 如果验证请求在异步通知发送一分钟之后,支付宝会返回 False
      • 如果商家已经对异步通知返回了 true, 支付宝会返回 False
    • 异步通知一旦验证成功,商家需要回复 ‘Success’

同步返回

返回是一个状态字符串.

返回示例

如传入的参数无效,则返回:

copy
Invalid

如异步通知是来自支付宝的并且是过去1分钟内的,则返回:

copy
True

如异步通知不是来自支付宝或者已经超过了一分钟,则返回:

copy
False

示例

请求示例

https://intlmapi.alipay.com/gateway.do?service=notify_verify&partner=2088101122136241&notify_id=4465b04e84cb6bacc2bd1b52232c0b8gjg&sign=ciSBXc7gjCfXW8KMBxFiFH2cbMZtFelfTOGKqY2NF7q98RnH3E%2BiF5Cj%2Fu%2Bl8py1D%2FOsE%2FAva1ls8A6Tw1MzhG6ideJSgh4FxWmAjEnlczdfLj%2FqzA6qGzxdKGEXaSDFmTGglOembXUqK8g8ajICD%2BBH7xoxBRY7vtfylEXtojs%3D&sign_type=RSA

错误码

基本上API接口的调用的检查是在支付宝的2个级别进行的

第一个级别是在支付宝网关。在这里会进行一些基础的校验,如签名,商家ID是否有效或者是否有权限使用某个接口等。如果校验失败,就会返回相应的错误码,归类在下面的网关错误中。

一旦网关校验通过了,接口请求就会被转发到内部系统进行进一步的处理。 这里会进行业务逻辑的校验。如果校验失败,就会返回相应的错误码,归类在业务错误代码中。

网关错误

如果请求参数里面有错误,支付宝网关会报错。整个流程还是在支付宝这端而不会返回到商户端。

错误码含义
SYSTEM_EXCEPTION系统异常
ILLEGAL_ARGUMENT接口参数不正确
ILLEGAL_SIGN签名不正确
ILLEGAL_SERVICEService 参数不正确
ILLEGAL_PARTNER商家ID不正确
ILLEGAL_SIGN_TYPE签名类型错误
ILLEGAL_PARTNER_EXTERFACE商家无权使用该接口
ILLEGAL_DYN_MD5_KEY动态密钥信息错误
ILLEGAL_ENCRYPT加密不正确
ILLEGAL_USER用户ID不正确
ILLEGAL_EXTERFACE接口配置错误
ILLEGAL_AGENT代理商不正确
HAS_NO_PRIVILEGE无权访问
INVALID_CHARACTER_SET字符集不正确

系统错误

当出现系统错误提示时,请联系支付宝技术支持协助处理

错误码含义
SYSTEM_ERROR支付宝系统错误
SESSION_TIMEOUTSession 超时
ILLEGAL_TARGET_SERVICE错误的target_service
ILLEGAL_ACCESS_SWITCH_SYSTEMpartner不允许访问该类型的系统
EXTERFACE_IS_CLOSED接口已关闭