Authored by qinchao

实名认证接口-开启图形验证码

package com.yohoufo.dal.user.model;
import lombok.Data;
/**
* 访问银联接口,认证记录日志表
*/
@Data
public class UserAuthorizeHistory {
//主键
private Integer id;
... ... @@ -19,79 +22,14 @@ public class UserAuthorizeHistory {
//银联返回内容
private String responseContent;
//系统错误码、错误信息 :0000 – 成功
private String backErrorCode;
private String backErrorInfo;
//一级错误码,00 和 01 类型是收费的
private String firstErrorCode;
private long createTime;
private long updateTime;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getCardNo() {
return cardNo;
}
public void setCardNo(String cardNo) {
this.cardNo = cardNo;
}
public String getCertNo() {
return certNo;
}
public void setCertNo(String certNo) {
this.certNo = certNo;
}
public String getCertName() {
return certName;
}
public void setCertName(String certName) {
this.certName = certName;
}
public Integer getResponseCode() {
return responseCode;
}
public void setResponseCode(Integer responseCode) {
this.responseCode = responseCode;
}
public String getResponseContent() {
return responseContent;
}
public void setResponseContent(String responseContent) {
this.responseContent = responseContent;
}
public long getCreateTime() {
return createTime;
}
public void setCreateTime(long createTime) {
this.createTime = createTime;
}
public long getUpdateTime() {
return updateTime;
}
public void setUpdateTime(long updateTime) {
this.updateTime = updateTime;
}
}
... ...
package com.yohoufo.dal.user.model;
import lombok.Data;
/**
* 实名认证信息表-具体认证信息
* 提供给前端查询用
*/
@Data
public class UserAuthorizeInfo {
//主键
private Integer id;
... ... @@ -20,67 +24,4 @@ public class UserAuthorizeInfo {
private long updateTime;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public Integer getValidStatus() {
return validStatus;
}
public void setValidStatus(Integer validStatus) {
this.validStatus = validStatus;
}
public String getCardNo() {
return cardNo;
}
public void setCardNo(String cardNo) {
this.cardNo = cardNo;
}
public String getCertNo() {
return certNo;
}
public void setCertNo(String certNo) {
this.certNo = certNo;
}
public String getCertName() {
return certName;
}
public void setCertName(String certName) {
this.certName = certName;
}
public long getCreateTime() {
return createTime;
}
public void setCreateTime(long createTime) {
this.createTime = createTime;
}
public long getUpdateTime() {
return updateTime;
}
public void setUpdateTime(long updateTime) {
this.updateTime = updateTime;
}
}
... ...
... ... @@ -9,6 +9,9 @@
<result column="cert_name" property="certName" jdbcType="VARCHAR" />
<result column="response_code" property="responseCode" jdbcType="INTEGER" />
<result column="response_content" property="responseContent" jdbcType="VARCHAR" />
<result column="back_error_code" property="backErrorCode" jdbcType="VARCHAR" />
<result column="back_error_info" property="backErrorInfo" jdbcType="VARCHAR" />
<result column="first_error_code" property="firstErrorCode" jdbcType="VARCHAR" />
<result column="create_time" property="createTime" jdbcType="INTEGER" />
<result column="update_time" property="updateTime" jdbcType="INTEGER" />
</resultMap>
... ... @@ -19,9 +22,10 @@
<insert id="insert" parameterType="com.yohoufo.dal.user.model.UserAuthorizeHistory" >
insert into authorize_history (uid, card_no, cert_no, cert_name, response_code ,
response_content ,create_time, update_time)
response_content ,back_error_code,back_error_info,first_error_code,create_time, update_time)
values (#{uid,jdbcType=INTEGER},#{cardNo,jdbcType=VARCHAR},#{certNo,jdbcType=VARCHAR},
#{certName,jdbcType=VARCHAR},#{responseCode,jdbcType=INTEGER},#{responseContent,jdbcType=VARCHAR},
#{backErrorCode,jdbcType=VARCHAR},#{backErrorInfo,jdbcType=VARCHAR},#{firstErrorCode,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT},#{updateTime,jdbcType=BIGINT})
</insert>
... ...
package com.yohoufo.user.common;
/**
* 银联定义的返回应答码
* 如有变化,具体以银联文档为准
*/
public enum EnumBankBackCode {
//定义
code_0000("0000","验证一致","00","验证一致"),
code_2314("2314","发卡行无此卡号","01","验证不一致"),
code_2316("2316","发卡行返回该卡状态不正常,建议持卡人与发卡行联系","01","验证不一致"),
code_2319("2319","验证不一致","01","验证不一致"),
code_2320("2320","发卡行返回该卡密码错次数超限,建议持卡人与发卡行联系","01","验证不一致"),
code_2344("2344","发卡行返回该卡未预留手机号,建议持卡人与发卡行联系","01","验证不一致"),
code_2321("2321","不支持发现卡验证交易","02","不支持验证"),
code_2325("2325","发卡行返回该卡不支持验证,建议持卡人与发卡行联系","02","不支持验证"),
code_2334("2334","发卡行返回该卡验证次数已超限,请明日再试","02","不支持验证"),
code_2346("2346","建行卡不支持卡号+手机号两要素组合验证","02","不支持验证"),
code_5000("5000","未知商户,不予通过","02","不支持验证"),
code_5101("5101","该卡交易过于频繁,请稍后重试","02","不支持验证"),
code_5102("5102","该证件号交易过于频繁,请稍后重试","02","不支持验证"),
code_5103("5103","该卡今日验证失败次数过多,请明日重试","02","不支持验证"),
code_5104("5104","该证件号今日验证失败次数过多,请明日重试","02","不支持验证"),
code_5105("5105","短期内有同卡重复交易,请稍后重试","02","不支持验证"),
code_5106("5106","该卡今日验证次数过多,请明日重试","02","不支持验证"),
code_5107("5107","请取得个人授权","02","不支持验证"),
code_5108("5108","当日验证次数已达最大值,请明日再试","02","不支持验证"),
code_4001("4001","无效卡","03","验证要素格式有误"),
code_4002("4002","无效证件类型","03","验证要素格式有误"),
code_4003("4003","无效证件号","03","验证要素格式有误"),
code_4004("4004","无效手机号","03","验证要素格式有误"),
code_4005("4005","无效姓名","03","验证要素格式有误"),
code_4006("4006","多种要素格式错误","03","验证要素格式有误"),
code_1302("1302","发卡行响应超时,请稍后重试","04","系统异常"),
code_1399("1399","发卡行系统异常,请稍后重试","04","系统异常"),
code_2208("2208","渠道方系统异常,请稍后重试","04","系统异常"),
code_2329("2329","系统异常,请稍后重试","04","系统异常")
;
// 成员变量
//应答码细分
private String secondCode;
private String secondCodeDesc;
// 应答码 00 验证一致(收费) 和 01 验证不一致(收费) ,其余情况不收费
private String firstCode;
private String firstCodeDesc;
//构造函数
EnumBankBackCode(String secondCode,String secondCodeDesc,String firstCode,String firstCodeDesc){
this.secondCode = secondCode;
this.secondCodeDesc = secondCodeDesc;
this.firstCode = firstCode;
this.firstCodeDesc = firstCodeDesc;
}
public static String getFirstCodeBySecondCode(String secondCode){
if(secondCode==null){
return "";
}
for(EnumBankBackCode backCode:EnumBankBackCode.values()){
if(secondCode.equals(backCode.secondCode)){
return backCode.firstCode;
}
}
return "";
}
}
... ...
... ... @@ -21,7 +21,7 @@ public class RestTemplateForBank {
*/
@Bean
public RestTemplate authorizeBankRestTemplate(){
ResponseErrorHandler responseErrorHandler = new ResponseErrorHandler() {
/* ResponseErrorHandler responseErrorHandler = new ResponseErrorHandler() {
@Override
public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
int statusCode = getHttpStatusResponseCode(clientHttpResponse);
... ... @@ -46,7 +46,7 @@ public class RestTemplateForBank {
return 400;
}
}
};
};*/
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
... ... @@ -55,7 +55,7 @@ public class RestTemplateForBank {
httpRequestFactory.setReadTimeout(500);
RestTemplate restTemplate= new RestTemplate(httpRequestFactory);
restTemplate.setErrorHandler(responseErrorHandler);
//restTemplate.setErrorHandler(responseErrorHandler);
return restTemplate;
}
}
... ...
... ... @@ -8,10 +8,12 @@ import com.yohoufo.dal.user.IUserAuthorizeInfoDao;
import com.yohoufo.dal.user.model.UserAuthorizeHistory;
import com.yohoufo.dal.user.model.UserAuthorizeInfo;
import com.yohoufo.user.cache.RedisValueCache;
import com.yohoufo.user.common.EnumBankBackCode;
import com.yohoufo.user.requestVO.RealNameAuthorizeReqVO;
import com.yohoufo.user.responseVO.AuthorizeResultRespVO;
import com.yohoufo.user.service.IRealNameAuthorizeService;
import com.yohoufo.user.service.risk.GraphVerifyService;
import lombok.Data;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
... ... @@ -20,12 +22,14 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
... ... @@ -136,14 +140,12 @@ public class RealNameAuthorizeServiceImpl implements IRealNameAuthorizeService {
//根据报文体,生成HTTP报文头的认证内容 (open-body-sig 方式)
String authorizationContentByOpenBodySig=generateAuthorizationByOpenBodySig(msgContentParams);
//请求返回
ResponseEntity<Object> responseEntity = postRequest(msgContentParams,authorizationContentByOpenBodySig);
PostBankResult responseResult = postRequest(msgContentParams,authorizationContentByOpenBodySig);
//返回结果处理:请求成功入认证信息库,请求失败记录的redis,后续超过一定次数则开启验证码
int responseCode=responseEntity.getStatusCodeValue();
String responseContent=String.valueOf(responseEntity.getBody());
ApiResponse apiResponse=new ApiResponse(400,responseContent,null);
ApiResponse apiResponse=new ApiResponse(400,responseResult.getErrInfo(),null);
long ts=getLocalDateTime().toEpochSecond(ZoneOffset.of("+8"));
if(responseCode==200){
if(responseResult.isSucFlag()){
UserAuthorizeInfo userAuthorizeInfo =new UserAuthorizeInfo();
try{
userAuthorizeInfo.setUid(uid);
... ... @@ -166,7 +168,7 @@ public class RealNameAuthorizeServiceImpl implements IRealNameAuthorizeService {
}
//访问银联接口记录日志
recordHistory(uid,cardNo,certNo,name,responseCode,responseContent,ts);
recordHistory(uid,cardNo,certNo,name,responseResult,ts);
return apiResponse;
}
... ... @@ -211,51 +213,104 @@ public class RealNameAuthorizeServiceImpl implements IRealNameAuthorizeService {
* 请求银联接口,获取返回信息
* 捕获所有异常
*/
private ResponseEntity<Object> postRequest(JSONObject msgContentParams,String authorizationContentByOpenBodySig){
ResponseEntity<Object> responseEntity=new ResponseEntity<>(HttpStatus.NOT_EXTENDED);
private PostBankResult postRequest(JSONObject msgContentParams,String authorizationContentByOpenBodySig){
PostBankResult result=new PostBankResult();
try{
//组成post的请求参数
JSONObject dataParams=new JSONObject();
dataParams.put("data",msgContentParams);
//return RealNameAuthorizePostBankUtil.postByhttpClient(authorizationContentByOpenBodySig,dataParams);
//headers
/* HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
headers.add("Authorization",authorizationContentByOpenBodySig);*/
//header
MultiValueMap<String, String> headers = new LinkedMultiValueMap();
headers.set("Content-Type", "application/json; charset=UTF-8");
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
headers.set("Authorization",authorizationContentByOpenBodySig);
//body
HttpEntity<JSONObject> bodyEntity = new HttpEntity<>(dataParams, headers);
logger.info("RealNameAuthorizeServiceImpl authorizeRealNameWithBank request message {} ,headers {} ,body {}",msgContentParams,headers,bodyEntity);
//post
responseEntity = restTemplate.postForEntity(requestUrl, bodyEntity, Object.class);
ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(requestUrl, bodyEntity, JSONObject.class);
logger.info("RealNameAuthorizeServiceImpl authorizeRealNameWithBank response entity {} ",responseEntity);
//处理结果
JSONObject jo=responseEntity.getBody();
if(jo==null){
result.setSucFlag(false);
result.setBackMsg("请求银联返回内容为空");
return result;
}
result.setBackMsg(jo.toString());
result.setStatusCode(responseEntity.getStatusCodeValue());
//实名认证成功的应答码:"0000"
if(responseEntity.getStatusCodeValue()==200&&jo!=null&&"0000".equals(jo.getString("errCode"))){
result.setSucFlag(true);
result.setErrCode("0000");
result.setErrInfo("请求银联实名认证成功");
}else{
result.setSucFlag(false);
result.setErrCode(jo==null?"":jo.getString("errCode"));
result.setErrInfo(jo==null?"":jo.getString("errInfo"));
}
}catch (Exception e){
logger.error("RealNameAuthorizeServiceImpl authorizeRealNameWithBank response entity {} ,error",responseEntity,e);
logger.error("RealNameAuthorizeServiceImpl authorizeRealNameWithBank response msgContentParams {} ,error",msgContentParams,e);
//记录错误码
result.setSucFlag(false);
if(e instanceof HttpClientErrorException){
HttpClientErrorException errorException=(HttpClientErrorException)e;
result.setStatusCode(errorException.getStatusCode().value());
result.setBackMsg(errorException.getResponseBodyAsString());
try{
JSONObject jo=JSONObject.fromObject(result.getBackMsg());
result.setErrCode(jo==null?"":jo.getString("errCode"));
result.setErrInfo(jo==null?"":jo.getString("errInfo"));
}catch (Exception jError){
logger.error("change to json error {} ",result.getBackMsg(),jError);
}
}else if(e instanceof HttpServerErrorException){
HttpServerErrorException errorException=(HttpServerErrorException)e;
result.setStatusCode(errorException.getStatusCode().value());
result.setBackMsg(errorException.getResponseBodyAsString());
try{
JSONObject jo=JSONObject.fromObject(errorException.getResponseBodyAsString());
result.setErrCode(jo==null?"":jo.getString("errCode"));
result.setErrInfo(jo==null?"":jo.getString("errInfo"));
}catch (Exception jError){
logger.error("change to json error {} ",result.getBackMsg(),jError);
}
}else if(e instanceof RestClientException){
RestClientException errorException = (RestClientException)e;
result.setBackMsg(errorException.getMessage());
}else{
result.setBackMsg("error happen unknown reason");
}
}
return responseEntity;
return result;
}
@Data
private static class PostBankResult {
private boolean sucFlag;
private int statusCode;
private String errCode;
private String errInfo;
private String backMsg;
}
/**
* 无论成功还是失败,都把访问记录日志表
*/
private void recordHistory(int uid,String cardNo,String certNo,String name,int responseCode,String responseContent,long ts){
private void recordHistory(int uid,String cardNo,String certNo,String name,PostBankResult responseResult ,long ts){
UserAuthorizeHistory history=new UserAuthorizeHistory();
history.setUid(uid);
history.setCardNo(cardNo);
history.setCertNo(certNo);
history.setCertName(name);
history.setResponseCode(responseCode);
history.setResponseContent(responseContent);
history.setResponseCode(responseResult.getStatusCode());
history.setResponseContent(responseResult.getBackMsg());
history.setBackErrorCode(responseResult.getErrCode());
history.setBackErrorInfo(responseResult.getErrInfo());
history.setFirstErrorCode(EnumBankBackCode.getFirstCodeBySecondCode(responseResult.getErrCode()));
history.setCreateTime(ts);
history.setUpdateTime(ts);
//最后记录日志 ,异步
... ...