MerchantLogin登录授权接口文档说明

概述

手机银行开放了用户登录和认证接口,通过该接口可以进行客户核身,并获取部分客户信息。根据商户类型的不同,返回不同的权限内容。文档已经迁移到新网站,此文档不再更新和维护,请移步 MerchantLogin(Json)登录授权-通用


名词解释

1.1商户

对第三方应用的统称,包括分行应用、外部合作公司应用、非手机银行平台的内部应用。


1.2联合登录

招商银行APP登录后将令牌发送给第三方应用,第三方应用通过解析令牌即可获得用户相关信息,这一过程称为联合登录。联合登录将手机银行用户体系开放给第三方,使得在第三方应用中无需执行登录即可获得用户信息。


1.3授权

第三方应用想要通过联合登录获取用户信息需要经过手机银行侧授权:即先要在线下通过商户管理员申请商户号、密钥等信息,并在线上发起联合登录请求时通过参数带入的方式传入商户号等信息,手机银行校验通过后方才将令牌回调给第三方应用。


1.4令牌

手机银行登录成功后将用户信息加密并签名后回调第三方的success方法,加密后的用户信息称为令牌。


1.5签名与验签

手机银行发送给第三方应用的加密数据中包含了一段签名数据,它经过手机银行私钥加密产生,第三方应用需在拿到密文数据并解密后,对签名数据进行验签,即使用手机银行公钥匹配验证,防止数据被篡改。详见“安全控制”章节。


交互流程

参数说明

3.1传入参数

以下方法只支持客户端7.4版本以上调用,7.4以下版本调用无效,并且需要在前端引入客户端提供的js文,下载地址为:https://www.showdoc.cc/cmb?page_id=2171142945748576

第三方商户前端调用方式如下:

cmblapi.merchantLogin({
corpNo:'003102',
authInfo:{
timestamp:'20190418173950',
nonceStr:'5K8264ILTKCH16CQ2502SI8ZNMTM67VS',
sign:'C7153C773C49F3D5CE9847BBA5153F9C'
},
success:function(res){
// res结果如下:
// {body ="xxx",cryptType = 2,resultType = Y}
},
fail:function(res){
}
})


参数说明:

属性

类型

默认值

必填

描述

最低版本

corpNo

string


商户号


authInfo

object


鉴权参数


reAuth

boolean

false

是否需要重新授权,如果用户已同意设置该参数无效


extendData

object


扩展参数对象,目前没有支持的扩展参数


success

function


接口调用成功的回调函数


fail

function


接口调用失败的回调函数




authInfo参数说明:


属性

类型

默认值

必填

描述

最低版本

timestamp

string


服务器当前时间,格式为

yyyyMMddHHmmss


nonceStr

string


随机字符串,主要保证签名不可预测,长度不超过32

推荐调用随机函数生成,将得到的值转换为字符串


sign

string


签名



3.2签名计算

sign = MD5(corpNo + timestamp + nonceStr +secretkey)


签名举例:

corpNo:123456//商户号
tiemstamp:20190418173950//时间戳
nonceStr:ABCDEDFHIGKLMN//随机字符串
secretKey:mykey//商户申请的秘钥
//将corpNo、timestamp、nonceStr、secretkey按字符串拼接起来然后计算MD5值
sign=MD5(12345620190418173950ABCDEDFHIGKLMNmykey)



3.3传出参数

成功回调success返回参数说明:


属性

类型

描述

最低版本

body

string

客户信息报文,第三方应用需先Base64解码并进行DES解密后方能看到明文数据。


cryptType

string

body加密类型:1表示明文,2表示DES加密,3表示非对称加密

resultType

string

登录授权结果:Y表示成功,N表示失败




失败回调fail返回参数说明:

属性

类型

描述

最低版本

errCode

number

错误码


errMsg

string

错误信息



第三方应用在进行DES解密用户授权信息时,关于DES算法一些参数指定如下:

●密钥:即corpkey(开发联调环境统一使用“cmbtest1”,生产环境需上线前申请);

●解密模式:ECB

●填充模式:PKCS5Padding(Java)/PKCS7Padding(C#)

●编码字符集:UTF-8


当解密完成时,第三方应用会看到如下json格式的用户明文数据,具体信息视第三方应用需求场景而分配,详细信息字段名及释义见附录1

--------------------------------------------------------------------------------------------------------------------------------

{
"type":"2",
"data":{
"corpInfo":{
"newUserID":"UI3QQS3D+YnE8+l+SvHUZd6q260sU=",
"uniqueUserID":"UQk0qwg8H0ynDQ/KrC+47SScXyV98=",
"expandUserID":"EUgxFOg1xey1BA8j99r2uEx3GlSvY="
},
"customerInfo":{
}
},
"verify":"143|198|70|189|146|178|225|103|193|37|38|18|38|224|193|5|8|104|29|236|170|233|165|198|219|225|201|144|59|115|233|198|46|21|10|231|52|145|238|246|214|115|143|126|81|11|182|197|91|243|236|153|167|23|242|218|249|18|125|77|136|71|237|174|"
}

--------------------------------------------------------------------------------------------------------------------------------


DES解密示例伪代码:

--------------------------------------------------------------------------------------------------------------------------------

//密文数据Base64转码
userdata =base64decoder.decode(UserDataBase64);
//获取密钥byte数组
key = corpkey.getbyte(“UTF-8”);
//设置des解密模式
desdecrypter.mode = ECB;
//设置des填充模式(Java为PKCS5,.NET为PKCS7)
desdecrypter.padding = PKCS5;
//des解密得到明文数据
decryptdata =desdecrypter.decrypt(userdata, key);

--------------------------------------------------------------------------------------------------------------------------------



安全控制

招商银行保证提供给第三方的授权令牌信息是合法有效的,但第三方必须采取以下措施,以避免开放环境下的信息安全风险。

4.1加解密

户信息采用DES对称加密,密钥由手机银行签发,(联调测试环境统一用“cmbtest1,生产环境需上线前申请),第三方应用应妥善保管,避免泄露;第三方应用应禁止在前端解密用户信息,严禁以明文方式在前端展示或缓存用户敏感信息,在解密得到用户信息后必须以安全方式传输。


4.2签名验证

手机银行签发的令牌附有数字签名,为确保授权信息的合法有效性,第三方应用必须调用招商银行提供的验签API(jardll)以及公钥来验证签名。具体做法是,将用户信息中的body解密后中的dataverify拼接,格式为“data&signature=verify内容”,把拼接内容与公钥一起传入验签API进行验证,得到验签结果。需要特别注意的是需先对data内容进行Base64转码后,再拼接进行验签。相关接口及公钥参见附录2“手机银行登录授权API验签工具包.zip”。


另外,令牌中包含有时间戳,第三方应用应验证令牌时间戳,控制到一个合理范围(一般10-30分钟),如超出则当前令牌失效,提示用户重新登录。


签名验证调用示例源代码(注意,此处为验签调用方式为可复用的源代码):

----------------------------------------------------------------------------------------------------------------------------

//首先保证已导入验签API,Java已导入jar包,C#已导入dll(将dll拷至bin目录)
//参数说明:
//signdata为拼接内容即signdata=strBody(Base64转码后)+”&signature=”+strVerify;
//publickeypath为公钥存放的物理路径
//---------Java调用验签示例(需引入命名空间cmb.netpayment.* )------------
import cmb.netpayment.*;
public static booleanVerifySignature(signdata, publickeypath){
Security verifier = new Security(publickeypath);
return verifyer.checkInfoFromBank(signdata.getBytes(Encoder.UTF_8));//成功时返回true
}
//---------C#调用验签示例(需在验签方法前声明外部函数)------------
[DllImport("FirmClient.dll",CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern intCheckInfoFromBank(string sPublicPath, string sBody);
public static int VerifySignature(signdata,publickeypath){
return CheckInfoFromBank(publickeypath,signdata);//成功时返回0
}

--------------------------------------------------------------------------------------------------------------------------------



用户授权申请

招商银行APP版本7.3.0及以上,针对要获取敏感信息的外部商户将增加用户授权申请环节,行内商户无需处理。

5.1 用户授权申请页面

(备注:授权申请页中间的权限描述根据商户权限不同而不同)


5.2 用户授权申请点击

以外部商户获取手机号为例(手机号为敏感数据):

1)用户A,第一次触发cmblapi.merchantLogin

①用户点击“同意”

令牌包含敏感数据,即包含手机号。

②用户点击“拒绝”

令牌不包含敏感数据,即不包含手机号,并且在令牌解密后的明文中新增字段userAttitude”:”0”

2)用户A,第nn>1)次触发cmblapi.merchantLogin

不再出现授权申请页面,沿用第一次用户A的选择,即第一次选择“同意”,之后cmblapi.merchantLogin请求获取的令牌均包含敏感数据;第一次选择“拒绝”,之后cmblapi.merchantLogin请求获取的令牌均不包含敏感数据。


5.3 商户再次向用户申请授权

若是商户需要再次向用户A申请授权,需在cmblapi.merchantLogin中设置reAuthtrue将再次出现授权申请页面。


测试客户端下载、申请测试环境小程序商户号

测试说

分行(或合作商户)在开发和测试阶段,若需要进行接口的联调和测试,可通过测试客户端连接到我行的测试环境。请按以下步骤进行(各个步骤的详细内容在下文中将有详述)

1、申请测试环境的商户号、申请配置测试入口

2、安装测试客户端,并连接所需的环境

3、在测试客户端内找到测试入口,进行联调和测试

申请测试商户号/测试入

发邮件给ben_chan@cmbchina.com,抄送给lilizao@cmbchina.com

邮件需要提供以下信息

商户类型(行内/行外

测试用的小程序URL

小程序名

页面顶部是否需要使用手机银行默认的导航栏(是/

该小程序是否需要使用一网通支付(是/

需要在邮件中提及JSON报文格

我行人员完成配置后,会回复邮件,邮件包含:测试安装包下载地址、测试商户号、测试入口在测试客户端内的位置、测试秘钥

测试环境说

打开测试客户端,会弹框提示选择需要连接的测试环境,请根据自己的实际情况进行选择

行外使用(DMZ

121.15.180.72,端口号:80

行内使

99.12.73.80,端口号:888(不需要使用一网通支付

99.12.69.80,端口号:80802(需要用到一网通支付

测试商户号/

测试商户号以邮件反馈的为准,测试秘钥统一使用cmbtest1

测试用一网通账号/银行卡

银行卡号:6225886551249897,登录密码:774411

一网通账户(登录密码均为774411

18943444960

13840831542

15835605832

一网通非实名账

17577441100(密码:77441100

测试安装包下载地

测试安装包下载请点击这里

测试客户端使用方

安装后,会弹框提示,请选择需要连接的环境(请确认host和端口号与申请的是否一致



申请正式环境小程序商户号申请

在小程序正式上线前,需要提前向总行申请生产环境正式的商户号和秘钥等配置信息。从手机银行7.0版本开始,小程序可以纳入手机银行APP首页的十宫格推荐算法,希望纳入推荐算法的小程序,需要单独申请一个商户号,不可与其他小程序共用。关于商户号共用的问题,具体请看这里:多个小程序可否共用一个商户号和秘钥?

由于手机银行侧配置发布采取灰度策略,每个版本发布需要经历约一周时间,因此请在自身应用上线前(或营销推广前)至少提前2周向总行发起参数上线申请,如果上线时间紧迫,可以无需等到应用开发完成,提前申请商户号和秘钥。

申请方式为:由分行的业务部门或分行信息技术部的相关同事(如果是外部商户,须由商户拓展分行发送邮件)发邮件给招商银行小程序管理/80266529(邮箱:xiaochengxu@cmbchina.com),并抄送给发件人的主管和李立早/01149824、郑璇/224899,邮件标题为:xx分行申请小程序商户号和秘钥,并在邮件内填写如下表格,表格内有填表说明;小程序商户号申请表(模板&填表说明)_20181218.xls邮件中需要注明申请报文格式为json版本。

注:如对上表有疑问可直接咨询总行李立早/01149824


附录1.内部商户授权信息字典

参数

参数释

卡列表信息(cardNoList节点内容

CardNoType

账户类

01:本行借记

02:本行信用

11:他行借记

12:他行信用

99:一网通账

cardNo

卡号(一卡通)或账户号(信用卡


customerID

核心客户


mobileNo

手机号


defaultCardFlag

默认卡标


bankName

所属银

如:招商银

acctBranch

一级分行

如:0755

accountLevel

账户等级(I类户、II类户等

V0:I类户(掌上生活开户的电子一卡通) V1:I类户  V2:II类户 V3:III类户 F0:一卡通附属卡空:未知/信用

商户信息(corpInfo节点内容

corpName

商户名


corpNo

商户


appName

APP


appVersion

APP版本


newUserID

用户ID,由身份证+姓名+商户号生

逐渐废弃,不建议使

uniqueUserID

用户ID,由身份证+姓名生

推荐使

expandUserID

用户ID,由一网通ID

ExpandUserID为非实名用户的唯一ID,当UniqueUserIDNewUserID均为空时,该用户为非实名用

timeStamp

时间

24小时

客户信息(customInfo节点内容

realName

客户姓


idType

证件类

01-身份证,02-护照,03-

personalID

证件号


mobile2

银行预留手机

优先取值为一卡通预留手机号,若取不到,则根据登录类型获取,即信用卡登录为信用卡预留手机号,一网通登录为一网通注册手机

level

客户等

客户所持卡中的最高卡等

LV1-普卡、LV2-金卡、LV3-金葵花、LV4-砖石卡、LV5-私人银

登录信息(loginInfo节点内容

loginType

登录类

A-一卡通,C-信用卡,D-一网

loginID

登录ID

A-一卡通卡号,C-身份证号,D-一网通用户

netBankUserName

一网通登录


appID

设备ID


version

客户端版


clientIP

客户端IP


netBankMobile

一网通预留手机


netBankEMail

一网通注册邮


netBankLoginName

一网通注册自定义用户


备注:加粗部分为20181120后新增的字段,原有内部商户需要时请向李立早报备,新的内部商户均开放。


附录2.外部商户授权信息字典

参数

参数释

newUserID

用户ID,由身份证+姓名+商户号生

逐渐废弃,不建议使

uniqueUserID

用户ID,由身份证+姓名生

推荐使

expandUserID

用户ID,由一网通ID

ExpandUserID为非实名用户的唯一ID,当UniqueUserIDNewUserID均为空时,该用户为非实名用


附录3.支持小组

1、总行业务联系人:李立早/01149824

2、测试环境技术支持:陈伟锋/80274221

3、疑难问题技术支持:张星/80230395

4、手机银行登录授权API验签工具包下载:手机银行登录授权API验签工具包



FAQ

Q1:请求失败,[CorpNo为空-M001]

A1:发起cmblapi.merchantLogin时没有传商户号。

Q2:请求失败![无效的商户号-M005]

A2:服务端无此商户的配置,测试环境联系陈伟锋,生产环境需联系总行李立早提前2周申请。

Q3:请求失败![商户号配置有误-M006]

A3:服务端商户配置没有配置为json的格式,测试环境请联系陈伟锋。

Q4Android点击取消登录又唤起一次登录。

A4:请通过前端发起tplogins请求,使用window.location.href= tplogins://…”;

Q5:请求失败![sign校验失败-M005]

A5:检查是否按照文档签名计算部分的内容进行正确MD5签名;


Q6DES解密失败。

A6:解密前需要对body进行Bbase64解码后再进行DES解密;


Q7:数字验证签名失败。

A7:待验证参数 = “原文&signature=签名
原文:DES解密结果中data的内容(需要将data内容转成json字符串,注意datajson字符串中字段的顺序,需要和des解密后的data字符串顺序一致,并且进行base64转码);
签名:DES解密结果中verify的内容。
例如原文为“this is a test”,签名为“123|456|789|”,那么参数就是“this is a test&signature=123|456|789|”


注:如果使用的是alibabafastsjon,需要使用JSONObject reqJSON = JSONObject.parseObject(body,Feature.OrderedField);

(1)C#签名验证失败

返回

0

验签成

13

public.key文件的路径错

14

待验证的数据拼接不正


(2)Java签名验证失败

返回

true

验签成

false

验签失败(public.key路径不正确,验签内容不正确



Q7:内部商户测试数据

{

"resultType":"Y",

"cryptType":"2",

"body":"u9su4Mi92g8b2l1GjBEllZQBpjFxRbKYY4MNjgS7qyS4GajzsQbyHPC6Xon2lc+gPjF3kjQalI2WNWw3UpY6M3RU4B6GFEC6IWf6KxYtcF4D9BJ6SrnW+LG1ncaArA8yJaAnlF42uMP4pHnWfJcIwBlobdjBJtCM/jgyvqSDq8EbGuUbEzfTBdWNGul6Zfr4MfvQFNE/KcsETGb6HrXayCR+ZD7aQ6dfk4wdd47Lpw14apcdMK8S3YaoOWN5NTgFgvqN8CyoZWJWFtZvntMozOWfKcgSIC5iTnVQsDYtnyvoPXvLMQRK2RngCMfHNyj8KHmtqLvapwCimVrD34/vV3n4WmQ4d+yPpMthMwg9NH6dxuC92tmfmeSNnfB3Ru3sZyo5PlxCrAyEaP7V2nnMg+JC9KuBf43TcrvQFAMJ9/YzjnYQLw4uVH58q0ebCcCY5Wvoda74aMRM+uWYY8RTFclmCyyyCEcttY1XzDS+zOCDu6rhjiDswDXno+YWbgU3G2skHRoMMxjOGmCUS1u6rrHp+6ERZa/YiRH77PFcilAsIbINkmBKgm8r/qe3m81nO8u2U6pEHp4="

}

上述标红部分(body内容)即用户授权信息,先经Base64解码后DES解密,若解密成功显示json结果如下,若解密失败首先考虑返回报文中“+”号被转义成了空格。

{

"type":"2",

"data":{

"corpInfo":{

"newUserID":"UI3QQS3D+YnE8+l+SvHUZd6q260sU=",

"uniqueUserID":"UQk0qwg8H0ynDQ/KrC+47SScXyV98=",

"expandUserID":"EUgxFOg1xey1BA8j99r2uEx3GlSvY="

},

"customerInfo":{

}

},

"verify":"143|198|70|189|146|178|225|103|193|37|38|18|38|224|193|5|8|104|29|236|170|233|165|198|219|225|201|144|59|115|233|198|46|21|10|231|52|145|238|246|214|115|143|126|81|11|182|197|91|243|236|153|167|23|242|218|249|18|125|77|136|71|237|174|"

}


data内容转base64后的结果为:

"eyJjb3JwSW5mbyI6eyJuZXdVc2VySUQiOiJVSTNRUVMzRCtZbkU4K2wrU3ZIVVpkNnEyNjBzVT0iLCJ1bmlxdWVVc2VySUQiOiJVUWswcXdnOEgweW5EUS9LckMrNDdTU2NYeVY5OD0iLCJleHBhbmRVc2VySUQiOiJFVWd4Rk9nMXhleTFCQThqOTlyMnVFeDNHbFN2WT0ifSwiY3VzdG9tZXJJbmZvIjp7fX0="

Q8:报错排查。

A10

报错信

报错原

No.1

[301]您的一网通用户需要先进行实名认证才能继续操作

该一网通用户未实名,可通过绑卡实

No.2

对不起,此功能正在维护中,暂停使用#M1

服务端配置有误,测试环境请联系陈伟锋处理,生产环境请联系支持小组

No.3

对不起,此功能正在维护中,暂停使用#M2

服务端系统异常,测试环境请联系陈伟锋处理,生产环境请联系支持小组

No.4

对不起,此功能正在维护中,暂停使用#M3

No.5

对不起,此功能正在维护中,暂停使用#M4

No.6

对不起,此功能正在维护中,暂停使用#M5

No.7

对不起,此功能正在维护中,暂停使用#MR

No.8

系统忙,请稍后再试#S1

No.9

系统忙,请稍后再试#S2

No.10

系统忙,请稍后再试#S3

No.11

系统忙,请稍后再试#R1




Q9:多个小程序可否共用一个商户号和秘钥?

A9:每个小程序必须申请独立的商户号和秘钥,做到“一号一用”。多个小程序混用同一个商户号会导致数据统计不准确、无法使用短链接、无法通过算法推荐出现在首页宫格等问题。


Q10ST环境可以登录验签成功,UAT环境不行?

A12:数字签名验证方法未覆盖所有场景,测试账号不同,授权数据也就不同,用于验签的body内容也会不同。


Q11:手机银行已登录状态可以进入测试页面,未登录进入测试入口报405错误?

A13:登录授权接口要求小程序应用允许getpost两种请求,针对分行小程序应用部署在paas上的nginx容器里,其解决方案:在nginx.conf配置error_page 405 = $urierror_page 405 = 200 $uri


Q12:验签API中,Java导入的jar包如何引用?

A14:没放maven,采用本地引用方式。