在OpenAPI对接联调期间,若请求接口返回报文“签名失败”、对通知接口验签失败,常见的失败原因及解决方案如下,请逐一排查。
请求类接口验签失败应答码
"code"="UP40030000","subCode"="OP40039911" 或 "respCd"="9911"
1.1 请求报文签名密钥
根据API接口规范或者询问业务方,确定认证方式(Oauth2.0/RSA2非对称认证/SM2非对称认证),并在个人中心-认证账号页面(https://open.unionpay.com/tjweb/user/gateway/list)查看/设置对应的密钥,如下图位置。
Oauth2.0认证方式:
l请检查计算签名时使用的“用户签名密钥signature”是否与此处查询的完全一致,中间前后无空格、引号、括号等
l请检查计算签名时使用的“用户签名密钥signature”是否属于获取token时的appId,避免出现多个appId的密钥混用情况
l若将密钥串存储至配置文件、数据库等位置,请通过打断点、打印日志等形式,检查是否存在读取密钥时填充了不可见字符,造成签名失败
非对称认证方式:
l请检查HTTP请求Header中signMethod字段是否与实际计算签名的算法一致,例如:若使用SHA256计算摘要、RSA2计算签名,则signMethod字段必须填“RSA2”;若使用SM3计算摘要、SM2计算签名,则signMethod字段必须填“SM2”
l请检查签名时使用的私钥,与在“API认证账号信息详情”页配置的公钥是否匹配(即为同时生成的一对公钥、私钥)。若无法确定,可使用开放平台提供的方法重新生成公私钥对(详见接口规范文档附录,或【接入指南-开始开发-非对称认证方式】),重新配置公钥,并更新系统的签名私钥后,等候十五分钟重新进行尝试。
1.2 通知报文验签密钥
目前通知报文均为非对称认证方式签名/验签,认证方式、公钥查询位置如图。
l请检查是否在“API认证账号信息详情”页设置签名验签算法(默认为RSA)、成功获取算法对应的验签公钥
l请检查获取的公钥串和用于验签计算的公钥串是否完全一致,中间前后无空格、引号、括号等
l将公钥串直接传入示例代码进行验签,不进行任何其他格式转换、编码转换等
签名计算过程请参考API接口规范附录,或【接入指南-开始开发-OAuth2.0功能接口调用】、【接入指南-开始开发-RSA2/SM2签名方式】
l请检查系统签名过程与规范要求的是否一致,不可有所遗漏
OAuth2.0签名:拼接待签名串、使用SHA-256算法计算摘要,得到sign
非对称签名:拼接待签名串、对待签名串计算摘要、使用私钥计算签名,得到sign,算法要与报文头signMethod参数匹配
l请通过打断点、打印日志等形式,检查待签名串拼接组成是否无误
OAuth2.0签名:取signature、body、ts的值按顺序拼接;中间无“+”、“[]”等符号;body为HTTP请求的JSON报文,由“{”、“}”作为首尾
非对称签名:将Header部分的version、appid、bizMethod、reqId和报文body以键值对形式拼接,并用&作为连接符, 型如([]包裹部分替换为值,[]不保留):version=[version]&appId=[appId]&bizMethod=[bizMethod]&reqId=[reqId]&body=[body]
l请检查待签名串中参数值与HTTP请求URL、Header中对应值是否完全一致(包括值与类型),待签名串中body是否与HTTP请求报文JSON串是否完全一致。例如:
a.可能出现JSON报文每次转换String时参数顺序不一致
b.请求URL或请求头中ts值因多出一个空格,导致解析为字符串类型
c.待签名串中ts与请求URL或Header中ts值分别取值,导致时间戳不同
d.使用部分封装工具使得实际发出的HTTP报文体参数间带上了空格或换行符等,导致与待签名串中的body不一致
通知报文验签仅支持非对称算法,通知报文验签过程请参考API接口规范附录,后续会在【接入指南】中更新。
l请检查系统验签过程与规范要求的是否一致,不可有所遗漏:拼接待签名串、对待签名串计算摘要、使用公钥做验签计算,算法要与收到的HTTP Header中signMethod参数匹配(网关发送通知时,signMethod实际取值取决于您在API认证账号详情页的选择)
l请通过打断点、打印日志等形式,检查待签名串拼接组成是否无误
将Header部分的version、appid、bizMethod、reqId和报文body以键值对形式拼接,并用&作为连接符, 型如([]包裹部分替换为值,[]不保留):version=[version]&appId=[appId]&bizMethod=[bizMethod]&reqId=[reqId]&body=[body]
l请检查待签名串中参数值与HTTP请求Header中对应值是否完全一致(包括值与类型),待签名串中body是否直接取自HTTP请求报文JSON串,未做任何转换。如:
a.通知接口HTTP报文中某参数为int类型,接收方将参数值转为string,导致待签名串中body与实际报文头不匹配从而验签失败
现阶段银联开放平台暂未提供其他语言的签名验签示例代码,请参考JAVA示例代码,其他语言如有开发困难可通过业务方联系平台进行支持。