package com.nova.sankuai.domain.api.doudouqian;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.nova.sankuai.domain.dto.DdqBindCardDto;
|
import com.nova.sankuai.domain.entity.Customer;
|
import com.nova.sankuai.domain.entity.CustomerUser;
|
import com.nova.sankuai.infra.config.CommonException;
|
import com.nova.sankuai.security.HttpClientUtil;
|
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModelProperty;
|
import org.apache.commons.lang.StringUtils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Component;
|
import org.springframework.util.DigestUtils;
|
|
import java.util.Map;
|
import java.util.Optional;
|
|
/**
|
* <p>
|
* 豆豆钱接口调用工具类
|
* </p>
|
*
|
* @author Weikangdi
|
* @since 2022/4/26
|
**/
|
@Component
|
@ApiModel(value = "豆豆钱接口对接工具类")
|
public class DdqUtil {
|
|
@Value("${doudouqian.conf.api-url}")
|
@ApiModelProperty(value = "请求地址")
|
private String apiUrl;
|
|
@Value("${doudouqian.conf.public_key}")
|
@ApiModelProperty(value = "公钥")
|
private String publicKey;
|
|
@Value("${doudouqian.conf.md5_key}")
|
@ApiModelProperty(value = "MD5秘钥")
|
private String md5Key;
|
|
@Value("${doudouqian.conf.channel_code}")
|
@ApiModelProperty(value = "机构申请得到的渠道号")
|
private String channelCode;
|
|
@Value("${doudouqian.conf.download_url}")
|
@ApiModelProperty(value = "下载链接地址")
|
public String downloadUrl;
|
|
@Value("${doudouqian.conf.system_public_key}")
|
@ApiModelProperty(value = "系统内公钥")
|
private String systemPublicKey;
|
|
@Value("${doudouqian.conf.system_private_key}")
|
@ApiModelProperty(value = "系统内私钥")
|
private String systemPrivateKey;
|
|
private static final Logger log = LoggerFactory.getLogger("capitalLogger");
|
|
/**
|
* 撞库-API预检MD5
|
*
|
* @param customer 用户信息
|
* @return
|
*/
|
public boolean apiMd5Check(Customer customer) {
|
String url = "/foreign/api/customer/md5_check";
|
JSONObject params = new JSONObject();
|
String phoneMd5 = DigestUtils.md5DigestAsHex(customer.getPhone().getBytes());
|
String nameMd5 = DigestUtils.md5DigestAsHex(customer.getName().getBytes());
|
String idCardMd5 = DigestUtils.md5DigestAsHex(customer.getIdCard().getBytes());
|
params.put("mobile", phoneMd5);
|
params.put("identityNo", nameMd5);
|
params.put("realName", idCardMd5);
|
try {
|
log.info("豆豆钱对接:API预检MD5参数->:{}", params.toJSONString());
|
String paramStr = DdqSignUtil.buildRequest(params.toJSONString(), channelCode, publicKey, md5Key);
|
log.info("豆豆钱对接:API预检MD5加密参数->:{}", paramStr);
|
String result = HttpClientUtil.getInstance().postJsonData(apiUrl + url, paramStr);
|
log.info("豆豆钱对接:API预检MD5返回参数->:{}", result);
|
DdqResponse response = getResponse(result);
|
if (response.isSuccess()) {
|
ApiMd5CheckVo checkVo = JSON.parseObject(response.getData(), ApiMd5CheckVo.class);
|
if (checkVo.isIfCanLoan()) {
|
return true;
|
}
|
} else {
|
log.error("豆豆钱对接:API预检MD5失败,错误原因" + response.getMsg());
|
}
|
} catch (Exception e) {
|
log.error("豆豆钱对接:API预检MD5接口请求错误", e);
|
e.printStackTrace();
|
}
|
return false;
|
}
|
|
|
/**
|
* 用户注册
|
*
|
* @param customer 用户信息
|
* @return
|
*/
|
public boolean register(Customer customer) {
|
String url = "/foreign/api/customer/login";
|
JSONObject params = new JSONObject();
|
params.put("mobile", customer.getPhone());
|
params.put("identityNo", customer.getIdCard());
|
params.put("realName", customer.getName());
|
try {
|
log.info("豆豆钱对接:用户注册参数->:{}", params.toJSONString());
|
String paramStr = DdqSignUtil.buildRequest(params.toJSONString(), channelCode, publicKey, md5Key);
|
log.info("豆豆钱对接:用户注册加密参数->:{}", paramStr);
|
String result = HttpClientUtil.getInstance().postJsonData(apiUrl + url, paramStr);
|
log.info("豆豆钱对接:用户注册返回参数->:{}", result);
|
DdqResponse response = getResponse(result);
|
if (response.isSuccess()) {
|
return true;
|
} else {
|
log.error("豆豆钱对接:用户注册失败,错误原因" + response.getMsg());
|
}
|
} catch (Exception e) {
|
log.error("豆豆钱对接:用户注册接口请求错误", e);
|
e.printStackTrace();
|
}
|
return false;
|
}
|
|
|
/**
|
* 获取支持的银行卡列表
|
*
|
* @param phone 用户手机号
|
* @return
|
*/
|
public BankListVo getBankList(String phone) {
|
String url = "/foreign/card/banklist";
|
JSONObject params = new JSONObject();
|
params.put("mobile", phone);
|
try {
|
log.info("豆豆钱对接:获取支持的银行卡列表参数->:{}", params.toJSONString());
|
String paramStr = DdqSignUtil.buildRequest(params.toJSONString(), channelCode, publicKey, md5Key);
|
log.info("豆豆钱对接:获取支持的银行卡列表加密参数->:{}", paramStr);
|
String result = HttpClientUtil.getInstance().postJsonData(apiUrl + url, paramStr);
|
log.info("豆豆钱对接:获取支持的银行卡列表返回参数->:{}", result);
|
DdqResponse response = getResponse(result);
|
if (response.isSuccess()) {
|
BankListVo bankListVo = JSON.parseObject(response.getData(), BankListVo.class);
|
return bankListVo;
|
} else {
|
log.error("豆豆钱对接:获取支持的银行卡失败,错误原因" + response.getMsg());
|
}
|
} catch (Exception e) {
|
log.error("豆豆钱对接:获取支持的银行卡列表接口请求错误", e);
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
/**
|
* 获取合同链接(协议)
|
*
|
* @param customerUser 用户信息
|
* @return
|
*/
|
public ContractLinkVo getContractLink(CustomerUser customerUser) {
|
String url = "/foreign/api/get/contractlink";
|
JSONObject params = new JSONObject();
|
params.put("mobile", customerUser.getPhone());
|
params.put("identityNo", customerUser.getIdCard());
|
params.put("realName", customerUser.getName());
|
try {
|
log.info("豆豆钱对接:获取合同链接参数->:{}", params.toJSONString());
|
String paramStr = DdqSignUtil.buildRequest(params.toJSONString(), channelCode, publicKey, md5Key);
|
log.info("豆豆钱对接:获取合同链接加密参数->:{}", paramStr);
|
String result = HttpClientUtil.getInstance().postJsonData(apiUrl + url, paramStr);
|
log.info("豆豆钱对接:获取合同链接返回参数->:{}", result);
|
DdqResponse response = getResponse(result);
|
if (response.isSuccess()) {
|
ContractLinkVo bankListVo = JSON.parseObject(response.getData(), ContractLinkVo.class);
|
return bankListVo;
|
} else {
|
log.error("豆豆钱对接:获取合同链接失败,错误原因" + response.getMsg());
|
}
|
} catch (Exception e) {
|
log.error("豆豆钱对接:获取合同链接接口请求错误", e);
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
|
/**
|
* 银行卡验卡
|
*
|
* @param bindCardDto 绑卡信息
|
* @return
|
*/
|
public BankCardCheckVo bankCardCheck(DdqBindCardDto bindCardDto) {
|
String url = "/foreign/card/cardcheck";
|
JSONObject params = new JSONObject();
|
params.put("mobile", bindCardDto.getPhone());
|
params.put("payCardNo", bindCardDto.getCardNo());
|
params.put("payCardBank", bindCardDto.getBankName());
|
params.put("payBankCode", bindCardDto.getBankCode());
|
params.put("cardReseRveMobile", bindCardDto.getBankPhoneNo());
|
try {
|
log.info("豆豆钱对接:银行卡验卡参数->:{}", params.toJSONString());
|
String paramStr = DdqSignUtil.buildRequest(params.toJSONString(), channelCode, publicKey, md5Key);
|
log.info("豆豆钱对接:银行卡验卡加密参数->:{}", paramStr);
|
String result = HttpClientUtil.getInstance().postJsonData(apiUrl + url, paramStr);
|
log.info("豆豆钱对接:银行卡验卡返回参数->:{}", result);
|
DdqResponse response = getResponse(result);
|
if (response.isSuccess()) {
|
BankCardCheckVo checkVo = JSON.parseObject(response.getData(), BankCardCheckVo.class);
|
return checkVo;
|
} else {
|
log.error("豆豆钱对接:银行卡验卡失败,错误原因" + response.getMsg());
|
}
|
} catch (Exception e) {
|
log.error("豆豆钱对接:银行卡验卡接口请求错误", e);
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
/**
|
* 银行卡绑卡接口(验证码绑卡)
|
*
|
* @param bindCardDto 绑卡信息
|
* @return
|
*/
|
public BindCardVo bindCard(DdqBindCardDto bindCardDto) {
|
String url = "/foreign/card/bindCard";
|
JSONObject params = new JSONObject();
|
params.put("mobile", bindCardDto.getPhone());
|
params.put("payCardNo", bindCardDto.getCardNo());
|
params.put("payCardBank", bindCardDto.getBankName());
|
params.put("payBankCode", bindCardDto.getBankCode());
|
params.put("cardReseRveMobile", bindCardDto.getBankPhoneNo());
|
params.put("smsCode", bindCardDto.getVerifyCode());
|
try {
|
log.info("豆豆钱对接:银行卡绑卡参数->:{}", params.toJSONString());
|
String paramStr = DdqSignUtil.buildRequest(params.toJSONString(), channelCode, publicKey, md5Key);
|
log.info("豆豆钱对接:银行卡绑卡加密参数->:{}", paramStr);
|
String result = HttpClientUtil.getInstance().postJsonData(apiUrl + url, paramStr);
|
log.info("豆豆钱对接:银行卡绑卡返回参数->:{}", result);
|
DdqResponse response = getResponse(result);
|
if (response.isSuccess()) {
|
BindCardVo bindCardVo = JSON.parseObject(response.getData(), BindCardVo.class);
|
return bindCardVo;
|
} else {
|
log.error("豆豆钱对接:银行卡绑卡失败,错误原因" + response.getMsg());
|
}
|
} catch (Exception e) {
|
log.error("豆豆钱对接:银行卡绑卡接口请求错误", e);
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
/**
|
* 额度信息查询接口
|
*
|
* @param phone 用户注册手机号
|
* @return
|
*/
|
public CreditQueryVo creditQuery(String phone) {
|
String url = "/foreign/api/credit/query";
|
JSONObject params = new JSONObject();
|
params.put("mobile", phone);
|
try {
|
log.info("豆豆钱对接:额度信息查询参数->:{}", params.toJSONString());
|
String paramStr = DdqSignUtil.buildRequest(params.toJSONString(), channelCode, publicKey, md5Key);
|
log.info("豆豆钱对接:额度信息查询加密参数->:{}", paramStr);
|
String result = HttpClientUtil.getInstance().postJsonData(apiUrl + url, paramStr);
|
log.info("豆豆钱对接:额度信息查询返回参数->:{}", result);
|
DdqResponse response = getResponse(result);
|
if (response.isSuccess()) {
|
CreditQueryVo queryVo = JSON.parseObject(response.getData(), CreditQueryVo.class);
|
return queryVo;
|
} else {
|
log.error("豆豆钱对接:额度信息查询失败,错误原因" + response.getMsg());
|
}
|
} catch (Exception e) {
|
log.error("豆豆钱对接:额度信息查询接口请求错误", e);
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
/**
|
* 订单结果查询接口
|
*
|
* @param phone 用户注册手机号
|
* @return
|
*/
|
public OrderQueryVo orderQuery(String phone) {
|
String url = "/foreign/api/order/query";
|
JSONObject params = new JSONObject();
|
params.put("mobile", phone);
|
try {
|
log.info("豆豆钱对接:订单结果查询参数->:{}", params.toJSONString());
|
String paramStr = DdqSignUtil.buildRequest(params.toJSONString(), channelCode, publicKey, md5Key);
|
log.info("豆豆钱对接:订单结果查询加密参数->:{}", paramStr);
|
String result = HttpClientUtil.getInstance().postJsonData(apiUrl + url, paramStr);
|
log.info("豆豆钱对接:订单结果查询返回参数->:{}", result);
|
DdqResponse response = getResponse(result);
|
if (response.isSuccess()) {
|
OrderQueryVo orderQueryVo = JSON.parseObject(response.getData(), OrderQueryVo.class);
|
return orderQueryVo;
|
} else {
|
log.error("豆豆钱对接:订单结果查询失败,错误原因" + response.getMsg());
|
}
|
} catch (Exception e) {
|
log.error("豆豆钱对接:订单结果查询接口请求错误", e);
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
|
/**
|
* 交单进件接口(提交用户数据)
|
*
|
* @param customer 用户申请记录信息
|
* @return
|
*/
|
public boolean submitOrder(Customer customer, String logPrefix) {
|
logPrefix = Optional.ofNullable(logPrefix).orElse("DEFAULT") + ", ";
|
|
String url = "/foreign/api/credit/submitorder";
|
JSONObject params = new JSONObject();
|
params.put("mobile", customer.getPhone());
|
params.put("realName", customer.getName());
|
params.put("identityNo", customer.getIdCard());
|
params.put("gender", customer.getSex());
|
params.put("nation", customer.getNation());
|
params.put("agency", customer.getSignOrganization());
|
params.put("address", customer.getIdAddress());
|
params.put("expireEnd", customer.getIdValidDateEnd());
|
params.put("expireStart", customer.getIdValidDateBegin());
|
params.put("degree", DdqParamParseUtil.parseDegree(customer.getEducation()));
|
params.put("marryStatus", DdqParamParseUtil.parseMarryStatus(customer.getMaritalStatus()));
|
params.put("faceConfidence", customer.getVerifySimilarity());
|
params.put("faceThresholds", "le-4-baidu");
|
String paramString = params.toJSONString();
|
params.put("front", DdqParamParseUtil.parseBase64(customer.getIdCardFrontPath()));
|
params.put("back", DdqParamParseUtil.parseBase64(customer.getIdCardBackPath()));
|
params.put("hand", DdqParamParseUtil.parseBase64(customer.getFacePhotoPath()));
|
try {
|
log.info(logPrefix + "豆豆钱对接:交单进件参数->:{}", paramString);
|
String paramStr = DdqSignUtil.buildRequest(params.toJSONString(), channelCode, publicKey, md5Key);
|
// log.info(logPrefix + "豆豆钱对接:交单进件加密参数->:{}", paramStr);
|
String result = HttpClientUtil.getInstance().postJsonData(apiUrl + url, paramStr);
|
log.info(logPrefix + "豆豆钱对接:交单进件返回参数->:{}", result);
|
DdqResponse response = getResponse(result);
|
if (response.isSuccess()) {
|
return true;
|
} else {
|
log.error(logPrefix + "豆豆钱对接:交单进件失败,错误原因" + response.getMsg());
|
}
|
} catch (Exception e) {
|
log.error(logPrefix + "豆豆钱对接:交单进件接口请求错误", e);
|
e.printStackTrace();
|
}
|
return false;
|
}
|
|
|
private DdqResponse getResponse(String result) {
|
if (StringUtils.isNotEmpty(result)) {
|
try {
|
DdqResponse response = JSON.parseObject(result, DdqResponse.class);
|
if (response != null) {
|
return response;
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
log.error("豆豆钱对接:转换响应返回数据失败", e);
|
}
|
}
|
log.error("豆豆钱对接:请求返回结果为空");
|
throw new CommonException("请求失败");
|
}
|
|
public String parseRequest(String param) throws Exception {
|
Map<String, Object> paramMap = JSON.parseObject(param, Map.class);
|
String sign = DdqSignUtil.getValue(paramMap, "sign"); // 签名
|
String secretKey = DdqSignUtil.getValue(paramMap, "secret_key"); // 秘钥签
|
String bizData = DdqSignUtil.getValue(paramMap, "biz_data"); // 业务数据
|
String channelCode = DdqSignUtil.getValue(paramMap, "channel_code"); // 机构申请得到的渠道号
|
String timestamp = DdqSignUtil.getValue(paramMap, "timestamp"); // 时间戳(秒)
|
// 1. 验证参数
|
if (org.apache.commons.lang3.StringUtils.isAnyBlank(sign, secretKey, channelCode, timestamp)) {
|
throw new CommonException("请求不正确,缺失必要参数");
|
}
|
// 3. 验证MD5签名
|
String tempSignStr = "biz_data=" + bizData + "&channel_code=" + channelCode + "&secret_key=" + secretKey + "×tamp=" + timestamp;
|
String md5Sign = DdqSignUtil.md5Encrypt(tempSignStr + md5Key);
|
if (!org.apache.commons.lang3.StringUtils.equalsIgnoreCase(md5Sign, sign)) {
|
throw new CommonException("验签不通过");
|
}
|
// 4. 解码SecretKey
|
String aesKey = DdqSignUtil.decryptByPrivateKey(secretKey, systemPrivateKey);
|
if (org.apache.commons.lang3.StringUtils.isBlank(aesKey)) {
|
throw new CommonException("解密失败");
|
}
|
return DdqSignUtil.decrypt(bizData, aesKey);
|
}
|
|
/**
|
* 模拟第三方请求加密参数,使用系统内公钥加密
|
*
|
* @return StringEntity
|
*/
|
public String buildTestRequest(JSONObject param) {
|
try {
|
String paramStr = DdqSignUtil.buildRequest(param.toJSONString(), channelCode, systemPublicKey, md5Key);
|
return paramStr;
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
}
|