异步通知验签
什么是异步通知?
异步通知是通过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签名类型
- 验证通知发送方:
通过使用Notify_verify 方法来确认通知是否是由支付宝发送。如果通知来自支付宝,您会在运行Notify_verify 方法之后得到 ResponseTxt==true。如果通知不是来自支付宝,则停止处理并无需进行其他下列步骤。 - 生成待签名字符串:
a. 将sign
和sign_type
字段移除。
b. 将剩下的字段用字母顺序排列。
c. 将所有字段通过&符号拼接起来。
例如,来自create_forex_trade_wap接口的异步通知示例:notify_id=5b89a773c60af059d96b1693dd3b3d6nc1¬ify_type=trade_status_sync&sign=b34d89788d9012f77f5b74ac232145f5&trade_no=2018110922001332950500389138&total_fee=0.01&out_trade_no=test20181109153145¬ify_time=2018-11-09 15:36:17¤cy=USD&trade_status=TRADE_FINISHED&sign_type=MD5
其待签名字符串:currency=USD¬ify_id=5b89a773c60af059d96b1693dd3b3d6nc1¬ify_time=2018-11-0915:36:17¬ify_type=trade_status_sync&out_trade_no=test20181109153145&total_fee=0.01&trade_no=2018110922001332950500389138&trade_status=TRADE_FINISHED
- 获取
mysign
参数的值:
a. 将MD5密钥拼接到待签名字符串的尾部。
b. 使用各自语言对应的MD5加密函数对拼接了MD5密钥的字符串进行加密,得到的加密值即为mysign
的值。 - 对
mysign
和sign
的值做相等判断: 得到的加密值mysign
与支付宝返回的参数sign
做相等判断,如果相等,则验证通过。
RSA2/RSA签名类型
- 验证通知发送方:
通过使用Notify_verify 方法来确认通知是否是由支付宝发送。如果通知来自支付宝,您会在运行Notify_verify 方法之后得到ResponseTxt==true
。如果通知不是来自支付宝,则停止处理并无需进行其他下列步骤。 - 生成待签名字符串:
a. 将sign
和sign_type
字段移除。
b. 将剩下的字段用字母顺序排列。
c. 将所有字段通过&符号拼接起来。
例如,来自create_forex_trade_wap接口的异步通知示例:currency=USD¬ify_id=5ac236e4cf7822d205cedcc252b54ebwg1¬ify_time=2020-01-14 15:23:12¬ify_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¬ify_id=5ac226e4cf7822d205cedcc252b54ebge1¬ify_time=2017-08-16 15:24:12¬ify_type=trade_status_sync&out_trade_no= test20170816150740&total_fee=0.01&trade_no=2017081621001003050502834160&trade_status=TRADE_FINISHED
- 将签名参数使用base64解码为字节码串。
- 使用RSA2/RSA验签方法验证签名。将待签名字符串,经过based64解码的签名参数及支付宝公钥传入RSA2/RSA验签方法,根据返回结果判定是否验签通过。RSA验签方法示例:
public static boolean verify(String content, String sign, String ali_public_key, String input_charset)
Note:
- 更多关于RSA2/RSA验签方法的信息,请参考示例代码下载。
- 为获取支付宝公钥信息,请联系支付宝国际技术支持团队(AlipayGlobalTechService@service.alipay.com)。
Notify_verify 方法
- 目的
验证此次通知信息是否是支付宝服务器发来的信息,以帮助校验反馈回来的数据的真假性。
- 工作原理
获取支付宝返回数据之一的通知校验ID(notify_id
),按照支付宝要求的格式拼接成要请求的链接,如:
https://intlmapi.alipay.com/gateway.do?service=notify_verify&partner=2088002396712354¬ify_id=RqPnCoPT3K9%252Fvwbh3I%252BFioE227%252BPfNMl8jwyZqMIiXQWxhOCmQ5MQO%252FWd93rvCB%252BaiGg
通过访问这个请求链接,利用编程方法来模拟http请求与支付宝服务器进行交互,获得支付宝服务器上处理的结果。
如果获得的信息是true
,则校验成功;如果获得的信息是其他,则校验失败。
请求参数
参数 | 类型 | 说明 | 可空 | 示例 |
基本参数 | ||||
service | String | 接口名 | N | notify_verify |
partner | String(16) | 境外商户在支付宝的用户ID. 2088开头的16位数字 | N | 2088001159940003 |
业务参数 | ||||
notify_id | String(34) | 支付宝通知流水号,境外商户可以用这个流水号询问支付宝该条通知的合法性 | N |
注意:
- 正确的验证异步通知的顺序是:
- 收到异步通知后,先不要回复‘success’。否则会影响支付宝系统的行为(支付宝系统会对所有已经回复了 ‘success’的异步通知的验证请求返回
false
) - 调用这个接口来验证notify id.
- 如果输入参数是无效的,支付宝会返回
Invalid
。 - 如果异步通知是支付宝发出的并且验证请求是在异步通知发出后的1分钟内发起的,则返回
True
。 - 如果该通知不是支付宝发送的,支付宝会返回
False
。 - 如果验证请求在异步通知发送一分钟之后,支付宝会返回
False
。 - 如果商家已经对异步通知返回了
true
, 支付宝会返回False
。
- 异步通知一旦验证成功,商家需要回复 ‘Success’
同步返回
返回是一个状态字符串.
返回示例
如传入的参数无效,则返回:
Invalid
如异步通知是来自支付宝的并且是过去1分钟内的,则返回:
True
如异步通知不是来自支付宝或者已经超过了一分钟,则返回:
False
示例
请求示例
https://intlmapi.alipay.com/gateway.do?service=notify_verify&partner=2088101122136241¬ify_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_SERVICE | Service 参数不正确 |
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_TIMEOUT | Session 超时 |
ILLEGAL_TARGET_SERVICE | 错误的target_service |
ILLEGAL_ACCESS_SWITCH_SYSTEM | partner不允许访问该类型的系统 |
EXTERFACE_IS_CLOSED | 接口已关闭 |