123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- package com.jbkd.loan.payday.trdorder.shkj;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.jbkd.loan.payday.collection.constants.BaseConstants;
- import com.jbkd.loan.payday.common.service.FileService;
- import com.jbkd.loan.payday.common.util.Digest;
- import com.jbkd.loan.payday.common.util.HttpClientUtils;
- import com.jbkd.loan.payday.core.constant.BeanNameConstant;
- import com.jbkd.loan.payday.core.dto.SignatureProtocolRequestDTO;
- import com.jbkd.loan.payday.core.entity.CoreDictionaryItem;
- import com.jbkd.loan.payday.core.entity.CoreLoan;
- import com.jbkd.loan.payday.core.entity.CoreLoanWithdrawFlow;
- import com.jbkd.loan.payday.core.entity.Customer;
- import com.jbkd.loan.payday.core.entity.CustomerAccount;
- import com.jbkd.loan.payday.core.entity.CustomerFiles;
- import com.jbkd.loan.payday.core.enums.DealTypeEnum;
- import com.jbkd.loan.payday.core.enums.ProtocolTypeEnum;
- import com.jbkd.loan.payday.core.enums.UseageTypeEnum;
- import com.jbkd.loan.payday.core.service.CoreDictionaryItemService;
- import com.jbkd.loan.payday.core.service.CustomerAccountService;
- import com.jbkd.loan.payday.core.service.CustomerFilesService;
- import com.jbkd.loan.payday.core.service.CustomerService;
- import com.jbkd.loan.payday.core.service.CustomerTrdVerifyInfoService;
- import com.jbkd.loan.payday.core.entity.SyncShenhaiFlow;
- import com.jbkd.loan.payday.core.enums.SyncSHTypeEnum;
- import com.jbkd.loan.payday.repayment.info.dto.RepaymentInfoInDTO;
- import com.jbkd.loan.payday.repayment.info.dto.RepaymentInfoOutDTO;
- import com.jbkd.loan.payday.repayment.info.template.IRepaymentInfoTemplate;
- import com.jbkd.loan.payday.trdorder.common.util.RSAEncrypt;
- import java.io.ByteArrayOutputStream;
- import com.jbkd.loan.payday.trdorder.shkj.sync.SyncSHObserver;
- import com.jbkd.loan.payday.trdorder.shkj.sync.SyncSHSubject;
- import java.io.IOException;
- import java.io.InputStream;
- import java.math.BigDecimal;
- import java.text.SimpleDateFormat;
- import java.time.*;
- import java.time.format.DateTimeFormatter;
- import java.util.*;
- import java.net.URLEncoder;
- import java.time.LocalDateTime;
- import java.time.ZoneOffset;
- import java.util.Comparator;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Objects;
- import java.util.TreeMap;
- import java.util.UUID;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.EnumUtils;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.commons.lang3.tuple.ImmutablePair;
- import org.apache.commons.lang3.tuple.Pair;
- import org.apache.http.NameValuePair;
- import org.apache.pdfbox.io.IOUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.stereotype.Service;
- import javax.annotation.Resource;
- /**
- * Created by yangyafei on 19/7/1.
- * 白猫贷接口对接类
- */
- @Slf4j
- @Configuration
- public class BMDLoanService implements SyncSHSubject {
- //白猫贷版本号,配置文件配置注入
- @Value("${bmd.version}")
- private String version;
- //白猫贷产品key,配置文件注入
- @Value("${bmd.product.key}")
- private String productKey;
- //白猫贷appkey,配置文件注入
- @Value("${bmd.app.key}")
- private String appKey;
- @Value("${bmd.private.key}")
- private String privateKey;
- //白猫贷url,配置文件注入
- @Value("${bmd.base.uri}")
- private String bmdBaseUri;
- @Value("${bmd.public.key}")
- private String publicKey;
- @Value("${bmd.loanConfigNo}")
- private String loanConfigNo;
- @Value("${bmd.merchant.no}")
- private String merchantNo;
- @Value("${bmd.merchant.callBack.url}")
- private String callBackUrl;
- @Autowired
- private SyncSHObserver observer;
- @Override
- public void notifyObservers(SyncShenhaiFlow syncShenhaiFlow) {
- this.observer.saveSHFlow(syncShenhaiFlow);
- }
- @Autowired
- private CustomerService customerService;
- @Autowired
- private CustomerTrdVerifyInfoService customerTrdVerifyInfoService;
- @Autowired
- private CustomerFilesService customerFilesService;
- @Autowired
- private FileService fileService;
- @Autowired
- private CustomerAccountService customerAccountService;
- @Resource(name = BeanNameConstant.REPAYMENT_INFO_V0_TEMPLATE)
- private IRepaymentInfoTemplate repaymentInfoTemplate;
- @Autowired
- private CoreDictionaryItemService coreDictionaryItemService;
- public String generateSignature(Map<String,String> params,Long mills,String nonce) throws Exception {
- TreeMap<String,String> treeParams = new TreeMap<>(new Comparator<String>() {
- @Override
- public int compare(String o1, String o2) {
- return o1.compareTo(o2);
- }
- });
- treeParams.putAll(params);
- StringBuilder temp = new StringBuilder();
- temp.append("product_key=").append(productKey).append("&").append("app_key=").append(appKey).append("&").append("nonce=")
- .append(nonce).append("&").append("timestamp=").append(mills);
- treeParams.forEach((key,value) ->temp.append("&").append(key).append("=").append(value));
- String data = temp.toString();
- String signature = RSAEncrypt.rsaSign(data,privateKey,"SHA256withRSA");
- return signature;
- }
- public Map<String,String> generateBaseHeader(Map<String,String> params){
- try {
- String nonce = UUID.randomUUID().toString().replaceAll("-","").substring(0,16);
- Long mills = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
- String signature = generateSignature(params,mills,nonce);
- HashMap<String,String> headers = new HashMap<>();
- headers.put("BMD-COP-SIGNVERSION","1");
- headers.put("BMD-COP-TIMESTAMP",String.valueOf(mills));
- headers.put("BMD-COP-NONCE",nonce);
- headers.put("BMD-COP-PRODUCTKEY",productKey);
- headers.put("BMD-COP-APPKEY",appKey);
- headers.put("BMD-COP-SIGNATURE",signature);
- return headers;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- /**
- * 请求白猫贷方法
- * @param params 白猫贷要求的字符串类参数
- * @param fileMap 白猫贷要求的图片文件类参数
- * @param syncSHTypeEnum
- * @return
- */
- @Override
- public BMDResponse requestBmd(String bmdUri, Map<String, String> params, Map<String,Pair<byte[],String>> fileMap, SyncSHTypeEnum syncSHTypeEnum){
- Map<String,String> headers = generateBaseHeader(params);
- String responseStr = HttpClientUtils.doHttpPost(bmdUri,headers,params,fileMap,"UTF-8");
- BMDResponse bmdResponse = transResponse(responseStr);
- // 更新流水记录
- SyncShenhaiFlow syncShenhaiFlow =new SyncShenhaiFlow();
- syncShenhaiFlow.setCopUserId(params.get("copUserId"))
- .setReqId(bmdResponse.getReqId());
- if(Objects.nonNull(params)){
- String request = JSON.toJSONString(params);
- syncShenhaiFlow.setResult(request);
- syncShenhaiFlow.setLoanNo(params.get("copOrderId"));
- }
- if(Objects.nonNull(bmdResponse) && bmdResponse.getSuccess()) {
- syncShenhaiFlow.setSyncStatus("Y");
- }else{
- syncShenhaiFlow.setSyncStatus("N");
- }
- if(Objects.nonNull(syncSHTypeEnum)) {
- syncShenhaiFlow.setType(syncSHTypeEnum.name().toString());
- }
- if(Objects.nonNull(bmdResponse)){
- syncShenhaiFlow.setResult(JSON.toJSONString(bmdResponse));
- }
- notifyObservers(syncShenhaiFlow);
- return bmdResponse;
- }
- //推送用户注册
- public BMDResponse register(String userNo,String cellphone){
- HashMap<String,String> params = new HashMap<>();
- params.put("copUserId",userNo);
- params.put("copRegPhoneNo",cellphone);
- return requestBmd(bmdBaseUri + "/api/v1/user_create",params,null, SyncSHTypeEnum.USER_CREATE);
- }
- public BMDResponse register(CoreLoan loan){
- HashMap<String,String> params = new HashMap<>();
- Customer customer = customerService.getByCustomerNo(loan.getCustomerNo());
- if(Objects.isNull(customer)){
- return null;
- }
- params.put("copUserId",customer.getCustomerNo());
- params.put("copRegPhoneNo",customer.getCellPhone());
- return requestBmd(bmdBaseUri + "/api/v1/user_create",params,null, SyncSHTypeEnum.USER_CREATE);
- }
- //推送用户身份认证
- public BMDResponse userVerify(CoreLoan loan){
- if(Objects.isNull(loan)){
- return null;
- }
- String userId = loan.getCustomerNo();
- Customer customer = customerService.getByCustomerNo(userId);
- String realName = customer.getIdCardName();
- String idcardNo = customer.getIdCardNo();
- CustomerFiles idObverse = customerFilesService.getLastCustomerFileByCustomerNoAndType(userId, UseageTypeEnum.IDOBVERSE);
- CustomerFiles idReverse = customerFilesService.getLastCustomerFileByCustomerNoAndType(userId,UseageTypeEnum.IDREVERSE);
- String oberseFileName = idObverse.getFileName();
- String reverseFileName = idReverse.getFileName();
- InputStream idObverseIs = fileService.downloadFile(oberseFileName);
- InputStream idReverseIs = fileService.downloadFile(reverseFileName);
- try {
- byte[] idObverseBytes = IOUtils.toByteArray(idObverseIs);
- String oberseMd5 = Digest.signMD5(idObverseBytes,"UTF-8");
- if(StringUtils.isNotBlank(oberseMd5)){
- oberseMd5 = oberseMd5.toUpperCase();
- }
- byte[] idReverseBytes = IOUtils.toByteArray(idReverseIs);
- String reverseMd5 = Digest.signMD5(idReverseBytes,"UTF-8");
- if(StringUtils.isNotBlank(reverseMd5)){
- reverseMd5 = reverseMd5.toUpperCase();
- }
- Pair<byte[],String> obversePair = ImmutablePair.of(idObverseBytes,"image/jpeg");
- Pair<byte[],String> reversePair = ImmutablePair.of(idReverseBytes,"image/jpeg");
- Map<String,Pair<byte[],String>> fileMap = new HashMap<>();
- Map<String,String> params = new HashMap<>();
- fileMap.put("idcardFrontImgFile",obversePair);
- fileMap.put("idcardBackImgFile",reversePair);
- params.put("copUserId",userId);
- params.put("realName",realName);
- params.put("idcardNo",idcardNo);
- params.put("idcardFrontImgMd5",oberseMd5);
- params.put("idcardBackImgMd5",reverseMd5);
- return requestBmd(bmdBaseUri + "/api/v1/user_identify",params,fileMap,SyncSHTypeEnum.USER_IDENTIFY);
- } catch (IOException e) {
- e.printStackTrace();
- }
- //Digest.signMD5()
- return null;
- }
- //用户活体检测
- public BMDResponse userLive(CoreLoan loan){
- CustomerFiles customerFiles = customerFilesService.getLastCustomerFileByCustomerNoAndType(loan.getCustomerNo(),UseageTypeEnum.LIVENESS_FRONT);
- if(Objects.isNull(customerFiles)){
- return null;
- }
- String fileName = customerFiles.getFileName();
- InputStream fileIs = fileService.downloadFile(fileName);
- try {
- byte[] content = IOUtils.toByteArray(fileIs);
- String md5 = Digest.signMD5(content,"UTF-8");
- if(StringUtils.isNotBlank(md5)){
- md5 = md5.toUpperCase();
- }
- Pair<byte[],String> pair = ImmutablePair.of(content,"image/jpeg");
- Map<String,Pair<byte[],String>> fileMap = new HashMap<>();
- fileMap.put("livecheckImgFile",pair);
- Map<String,String> params = new HashMap<>();
- params.put("copUserId",loan.getCustomerNo());
- params.put("livecheckImgMd5",md5);
- return requestBmd(bmdBaseUri + "/api/v1/user_livecheck",params,fileMap,SyncSHTypeEnum.USER_LIVECHECK);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
- //同步用户银行卡四要素
- public BMDResponse userBankCard(CoreLoan loan){
- String customerNo = loan.getCustomerNo();
- CustomerAccount customerAccount = customerAccountService.getLastCustomerAccount(customerNo);
- if(Objects.isNull(customerAccount)){
- return null;
- }
- String copUserId = customerNo;
- String realName = customerAccount.getAccountHolder();
- String idcardNo = customerAccount.getAccountIdCardNo();
- String bankCardNo = customerAccount.getAccountNumber();
- String bankcardPhoneNo = customerAccount.getAccountPhone();
- Map<String,String> params = new HashMap<>();
- params.put("copUserId",copUserId);
- params.put("realName",realName);
- params.put("idcardNo",idcardNo);
- params.put("bankcardNo",bankCardNo);
- params.put("bankcardPhoneNo",bankcardPhoneNo);
- return requestBmd(bmdBaseUri + "/api/v1/user_sync_bankcard_fourelements",params,null,SyncSHTypeEnum.FOURELEMENTS);
- }
- // public boolean pushUserInfo(CoreLoan loan){
- //
- //
- // }
- //推送创建订单
- // String orderNo,String userNo,long amount,String usage,String bankAccountName,String bankAccountNo,String repayPlan
- public BMDResponse orderCreate(CoreLoan loan){
- HashMap<String,String> params = new HashMap<>();
- params.put("copOrderId",loan.getLoanNo());
- params.put("loanConfigNo",loanConfigNo);
- params.put("copUserId",loan.getCustomerNo());
- params.put("amount",String.valueOf(loan.getApprovedPrincipal().movePointRight(2)));
- String loanUdageName = coreDictionaryItemService.getByItemCode("REASON"+loan.getLoanUsageCode()).getItemName();
- params.put("usage",loanUdageName);
- CustomerAccount customerAccount = customerAccountService.getLastCustomerAccount(loan.getCustomerNo());
- if(Objects.isNull(customerAccount)){
- return null;
- }
- params.put("bankAccountName",customerAccount.getAccountHolder());
- params.put("bankAccountNo",customerAccount.getAccountNumber());
- RepayPlan repayPlan = new RepayPlan();
- repayPlan.setType(1);
- repayPlan.setIntervalUnitType("DAY");
- repayPlan.setIntervalUnitCount(loan.getApprovedPeriod());
- repayPlan.setDailyPenaltyRate(0.1);
- repayPlan.setEstimatePayTime(LocalDateToUdate(LocalDate.now()));
- RepayPlanItem repayPlanItem = new RepayPlanItem();
- repayPlanItem.setCopRepayPlanItemId(loan.getLoanNo());
- repayPlanItem.setPrincipal(loan.getApprovedPrincipal().movePointRight(2).longValue());
- LocalDate dueDate = LocalDate.now().plusDays(loan.getApprovedPeriod() - 1);
- repayPlanItem.setEstimateRepayTime(LocalDateToUdate(dueDate));
- repayPlan.setIntervalUnitInterestRate(loan.getInterestRate().movePointRight(2).setScale(3, BigDecimal.ROUND_HALF_UP).toString());
- repayPlanItem.setInterests(0l);
- repayPlanItem.setFee(100l);
- repayPlanItem.setCommission(0l);
- repayPlanItem.setOther(loan.getApprovedInterest().movePointRight(2).longValue()-100l);
- List<RepayPlanItem> repayPlanItemList = new ArrayList<>();
- repayPlanItemList.add(repayPlanItem);
- repayPlan.setItemList(repayPlanItemList);
- params.put("repayPlan",JSONObject.toJSONString(repayPlan));
- return requestBmd(bmdBaseUri + "/api/v1/order_create",params,null,SyncSHTypeEnum.ORDER_CREATE);
- }
- //白猫贷查询订单
- public BMDResponse getOrder(CoreLoan loan){
- Map<String,String> params = new HashMap<>();
- params.put("copUserId",loan.getLoanNo());
- return requestBmd(bmdBaseUri + "/api/v1/order_get",params,null,null);
- }
- public String LocalDateToUdate(LocalDate localDate) {
- ZoneId zone = ZoneId.systemDefault();
- Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
- java.util.Date date = Date.from(instant);
- SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- return simpleDateFormat.format(date);
- }
- public BMDResponse loanContract(CoreLoan loan,String fileName){
- String loanNo = loan.getLoanNo();
- InputStream contractIs = fileService.downloadFile(fileName);
- if(Objects.nonNull(contractIs)) {
- try {
- byte[] contractBytes = IOUtils.toByteArray(contractIs);
- try {
- contractIs.close();
- }catch(Exception e){
- log.error("close contract inputstream has error!");
- }
- String md5 = Digest.signMD5(contractBytes,"UTF-8");
- if(StringUtils.isNotBlank(md5)){
- md5 = md5.toUpperCase();
- }
- Map<String,String> params = new HashMap<>();
- params.put("contractMd5",md5);
- params.put("copOrderId",loanNo);
- Map<String,Pair<byte[],String>> files = new HashMap<>();
- files.put("contractFile",ImmutablePair.of(contractBytes,"application/pdf"));
- return requestBmd(bmdBaseUri + "/api/v1/order_upload_contract",params,files,SyncSHTypeEnum.ORDER_CONTRACT);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return null;
- }
- //订单支付
- public BMDResponse loanWithdraw(CoreLoanWithdrawFlow withdrawFlow){
- if(Objects.isNull(withdrawFlow)){
- return null;
- }
- Map<String,String> params = new HashMap<>();
- params.put("copOrderId",withdrawFlow.getLoanNo());
- params.put("payMerchantNo",merchantNo);
- params.put("copPayRequestId",withdrawFlow.getRequestNo());
- params.put("callbackUrl",callBackUrl);
- return requestBmd(bmdBaseUri + "/api/v1/order_pay",params,null,SyncSHTypeEnum.ORDER_WITHDRAW);
- }
- public BMDResponse transResponse(String responseStr){
- if(StringUtils.isNotBlank(responseStr)){
- JSONObject resultJson = JSONObject.parseObject(responseStr);
- BMDResponse result = new BMDResponse();
- result.setReqId(resultJson.getString("reqId"));
- int code = resultJson.getInteger("code");
- if(0 == code){
- result.setCode(0);
- result.setSuccess(true);
- }else{
- result.setCode(code);
- result.setSuccess(false);
- }
- result.setMsg(resultJson.getString("msg"));
- return result;
- }
- return null;
- }
- }
|