免密支付

签订支付协议(未安装招商银行APP)

1. 接口介绍

功能简述:

招行网页嵌入商户app的方式来实现免密签约功能

应用场景:

1、 客户在招行侧未签订免密支付协议,商户需调用该接口为客户签约。
2、 调用该接口成功后,客户即在招行侧签订协议,并成功开通免密支付功能,商户侧收到“支付协议签订成功回调通知”。
3、 客户关闭支付协议的免密功能,可调用该接口重新开通,开通成功后,商户侧收到“支付协议签订成功回调通知”。

调用方式:

目前支持以下三种调用方式:
1、商户客户端集成招行SDK,通过SDK判断客户是否安装招行APP并发起签约。集成SDK方法请参考【SDK接口】,签约字段定义请参考本文档第3节jsonRequestData的参数定义。
2、商户客户端编写代码或采用其他方式,判断客户是否安装招行APP,未安装则参考本文档第2—3节内容进行调用。
3、商户不判断客户是否安装招行APP,仅对接H5免密签约流程,则参考本文档第2—3节内容进行调用。

约束条件:

1、秘钥及表单提交地址,商户需通过配置管理,方便后续调整。
2、该接口采用招行网页嵌入商户app的方式来实现功能,若商户采用调用方式2或3,则app头部导航由商户自行实现,参见【接口规范—常见问题】;若商户采用调用方式1,则可使用SDK导航栏或自定义,参见【iOS接入常见问题】【Android接入常见问题】
3、商户需要判断是否安装招行手机银行APP,未安装采用此方案。参见【判断手机是否安装招商银行APP

正常流程:

1、用户在商户APP内点击按钮跳转到招行H5页面进行签约
2、用户信息校验通过后,正常签约成功

异常流程:

1、用户信息校验不通过,界面报错,签约停止

2. 请求地址

测试环境URL:

http://121.15.180.66:801/netpayment/BaseHttp.dll?MB_OSNPSign_Json

生产环境URL:

https://netpay.cmbchina.com/netpayment/BaseHttp.dll?MB_OSNPSign_Json

3. 请求报文

请求报文参数类型(长度)必填描述示例
charsetString(8)M编码格式,固定为UTF-8(默认)UTF-8
jsonRequestDataStringMjson格式的请求参数,详见jsonRequestData定义

jsonRequestData参数定义

参数名类型(长度)必填描述示例
versionString(3)M固定为1.01.0
signStringM使用商户支付密钥对reqData内的数据进行签名
signTypeStringM固定为SHA-256SHA-256
reqData请求数据


dateTimeString(14)M请求时间,商户发起该请求的时间,精确到秒。
格式:yyyyMMddHHmmss
20160623101430
merchantSerialNoString(30)M协议开通请求流水号,商户生成。
同一交易日期唯一,长度不超过30位,数字字母都可以,建议纯数字
2016062310143088
agrNoString(32)M客户协议号,不超过32位的数字字母组合。
未签约(首次支付)客户,填写新协议号,用于协议开通;已签约(再次支付)客户,填写该客户已有的协议号。商户必须对协议号进行管理,确保客户与协议号一一对应。
201606238888888
agrCodeStringO签约产品类型。
P 免密支付签约 
F 免密冻结签约
 该字段可“不送”或送“空”,视为“免密支付签约”
P 或 F
branchNoString(4)M商户分行号,4位数字0755
merchantNoString(6)M商户号,6位数字123456
mobileString(11)O商户用户的手机号13888888888
userIDString(20)O用于标识商户用户的唯一ID。
商户系统内用户唯一标识,不超过20位,数字字母都可以,建议纯数字
123abc
lonString(10)O经度,商户app获取的手机定位数据30.949505
latString(10)O纬度,商户app获取的手机定位数据50.949506
riskLevelString(3)O用户在商户系统内风险等级标识
noticeUrlString(100)M商户接收成功签约结果通知的地址http://www.xxx.com/xxx
noticeParaString(512)O成功签约结果通知附加参数,该参数在发送成功签约结果通知时,将原样返回商户。注意:该参数可为空,商户如果需要不止一个参数,可以自行把参数组合、拼装,但组合后的结果不能带有&字符。
returnUrlStringO返回商户地址,签约成功页面上返回商户按钮跳转地址,默认值:http://CMBNPRM,采用默认值的需要商户app拦截该请求,自行决定跳转交互http://www.xxx.com/yyy
开通用户身份验证或银行卡校验功能时,需上送以下信息:
merchantUserIdTypeStringO商户上送用户的证件类型,若商户端用户未实名,不需要传该字段。
01 身份证 
02 护照 
03 其他
01
merchantUserIdNoStringO商户上送用户的证件编号,需要使用商户秘钥进行AES-256加密(秘钥需32位,不足则右侧补0),若商户端用户未实名,不需要传该字段。(生成签名串时,是直接对密文进行签名)
merchantUserNameStringO商户上送用户的姓名,需要使用商户秘钥进行AES-256加密(秘钥需32位,不足则右侧补0),若商户端用户未实名,不需要传该字段。(生成签名串时,是直接对密文进行签名)
merchantCardTypeStringO商户上送用户的银行卡类型,若商户端用户未实名,或不需要限制签约银行卡,则不需要传该字段。
02 本行借记卡
03 本行信用卡
08 他行借记卡
09 他行信用卡
02
merchantCardNoStringO商户上送用户的银行卡号,需要使用商户秘钥进行AES-256加密(秘钥需32位,不足则右侧补0),若商户端用户未实名,或不需要限制签约银行卡,不需要传该字段。(生成签名串时,是直接对密文进行签名)

请求示例:

json报文组织:

{   
    "version":"1.0",   
    "charset":"UTF-8",   
    "sign":"见签名处理章节",   
    "signType":"SHA-256",   
    "reqData":{        
        "agrNo":"201606238888888",        
        "branchNo":"0755",        
        "dateTime":"20160623101430",        
        "lat":"30.949505",        
        "lon":"50.949506",        
        "merchantNo":"123456",        
        "merchantSerialNo":"2016062310143088",        
        "mobile":"13888888888",        
        "noticePara":"",        
        "noticeUrl":"http://www.xxx.com/xxx",        
        "returnUrl":"http://www.xxx.com/yyy",        
        "riskLevel":"3",        
        "userID":"2016062388888"        
        }   
}

表单组织:

<form action="请求地址" method="post" >    
    <input type="hidden" name="jsonRequestData" value='以上json字符串' />
</form>

待签名字符串(未包含支付密钥):

agrNo=201606238888888&branchNo=0755&dateTime=20160623101430&lat=30.949505&lon=50.949506&merchantNo=123456&merchantSerialNo=2016062310143088&mobile=13888888888&noticePara=&noticeUrl=http://www.xxx.com/xxx&returnUrl=http://www.xxx.com/yyy&riskLevel=3&userID=2016062388888

4. 响应报文

1、网页端直接展示签约成功或失败结果,无响应报文。
2、签约成功后有异步结果通知,失败无通知。

5. 错误码


6. FAQ

Q1. 为什么对接签约时报“非法请求”?
1、参照“请求报文”章节正确组织请求报文
2、确保加密算法、参数排序、编码正确
3、参数请使用post方式提交
4、确保form表单name及value不要有空格

Q2. 为什么对接签约时报“参数校验失败,关键项必输”?
请求报文必填标识为M的必传,请检查必填项,同时form表单name属性不要有空格。

Q3. 为什么对接签约时报“请求已过期”?
请检查dateTime,时间格式yyyyMMddHHmmss,必须取交易发生时标准时间,同招行服务器时间不能相差30分钟。

Q4. 为什么对接签约时报“上送分行号必须为4位长度”?
分行号长度必须4位。

Q5. 为什么对接签约时报“上送商户号必须为6位长度”?
商户号长度必须6位。

Q6. 为什么对接签约时报“配置错误”?
商户号或秘钥配置错误,请联系商户对应支持人员核对商户号、秘钥信息。

Q7. 为什么对接签约时报“json解析失败”?
jsonRequestData解析失败,请检查参数json数据组织格式。

Q8. 为什么对接签约时报“账户校验不通过,请确认账户信息及密码正确后重试或联系客服95555”?
测试卡片信息没有通过校验,请联系商户对应支持人员核对测试卡片信息。

Q9. 为什么对接签约时报“[身份证号]格式错误,请输入正确的身份证号!”?
身份证格式不对,js校验没有通过,请联系商户对应支持人员核对测试卡片信息。

Q10. 为什么对接签约时报“属性DrawPwd解密失败”或“密码解密失败!”?
密码解密失败,请核对密码键盘公钥以及正确集成了密码键盘sdk。

Q11. 为什么对接签约时报“您停留在页面太久没操作,请重新进入操作!”?
1、长时间未操作,会话超时
2、如果不是1的情况,请检查webview是否支持会话,可监控下url请求看是否有异 常url请求
3、是否有跨url访问或者人为修改表单参数
4、是否有ip等网络变动

Q12. 为什么点击“下一步”按钮,网页一直在加载或者点击密码框跳转至浏览器默认网页?
请参照密码键盘部分文档,确保密码键盘集成正确。

Q13. 使用一网通支付的用户如何登录招行手机银行?
用户在使用一网通支付成功后,可以在招行官网下载招行手机银行,登录时账号输入第 一次支付时填写的预留手机号,密码随便输,点击登录会有提示并引导用户设置登录密 码,完成密码设置后即可登录手机银行。

Q14. 签约后如何换卡?
先解约再用新的卡签约,也可以登录招行手机银行绑定其他支付卡,支付的时候可以选卡支付。

Q15. 为什么有的测试卡片签约过程中不用设置支付密码而是直接验证支付密码?
部分测试卡片被使用过,提前设置过支付密码,可继续使用该卡片测试完流程,后续再联系商户支持人员提供新的测试卡片测试设置支付密码场景。

Q16. 同一个客户,第一次上送签约号1,绑银行卡A, 绑卡签约支付成功后; 第二次,商户端误当新用户,上送新签约协议号2,银行引导其继续绑卡签约,客户仍然绑银行卡A。 银行是返回绑卡签约成功还是失败? 如成功,第二次重复签约返回的签约号为1还是2?第二次客户新绑银行卡B的情况下,银行会怎么返回?
签约成功,返回的签约协议号是2,同一个客户,在同一个商户下,生产环境最多只能签10条协议,测试环境支持签30条。

Q17. 签约的协议号,有什么要求?
客户协议号 —- 不超过32位,纯数字,
协议开通请求流水号 —- 不超过30位, 数字字母都行,建议纯数字,
协议用户ID —- 不超过20位, 数字字母都行,建议纯数字。

Q18. 为什么添加本行信用卡时,提示“添加银行卡失败,原因:综合支付平台处理失败,本行贷记卡绑定要素检查失败:卡片未开卡(1083)?
可能是卡片状态有问题,建议换卡测试。

Q19. 协议号怎么保存?如用户还没有签协议,那么就发送空的是吗?
协议号属于招行一网通支付同商户用户之间建立的支付协议标识,商户系统在第一次支付时需按照接口文档生成并传给招行支付接口,支付完成后,招行系统会通知商户系统协议签订是否成功,商户系统拿到结果后需保存协议号、商户系统用户、协议状态三者之间的关联关系。这样商户系统就知道该用户是否满足使用一网通支付条件,在后续支付过程中都要传该协议号。

Q20. 开通用户身份验证和银行卡校验是什么功能?
商户侧已收集客户的实名信息和银行卡号,如果需要校验招行侧签约客户与商户侧为同一个人,则需联系招行业务人员,在商户管理系统开通“实名认证”,并在请求报文中上送“merchantUserIdType、merchantUserIdNo、merchantUserName”;如果需要校验校验招行侧签约客户与商户侧为同一个人,且只能使用商户侧预留银行卡进行签约,则需联系招行业务人员,在商户管理系统开通“实名认证”,并在请求报文中上送“merchantUserIdType、merchantUserIdNo、merchantUserName、merchantCardType、merchantCardNo”。

Q21. 客户H5签约过程中,前端为什么提示报错“NP4043.商户证件编号或姓名解密失败[MB144309]”?
原因:招行支付系统会对商户请求数据进行urldecode,当商户上送的“merchantUserIdNo”等与实名认证相关字段中包含某些特殊字符时,可能会导致报文解密或者验签失败。
解决办法:生成签名串时,使用base64密文获取签名,发送请求数据jsonRequestData时,需对base64密文进行urlencode编码。