Przeglądaj źródła

提交部分代码

yangyafei 5 lat temu
rodzic
commit
199f3571ea
2 zmienionych plików z 505 dodań i 0 usunięć
  1. 449 0
      gateway/BMDLoanService.java
  2. 56 0
      gateway/BMDResponse.java

+ 449 - 0
gateway/BMDLoanService.java

@@ -0,0 +1,449 @@
+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;
+    }
+
+}

+ 56 - 0
gateway/BMDResponse.java

@@ -0,0 +1,56 @@
+package com.jbkd.loan.payday.trdorder.shkj;
+
+public class BMDResponse{
+
+        private Boolean isSuccess;
+
+        private String reqId;
+
+        private int code;
+
+        private String msg;
+
+        private JSONObject data;
+
+        public String getReqId() {
+            return reqId;
+        }
+
+        public void setReqId(String reqId) {
+            this.reqId = reqId;
+        }
+
+        public int getCode() {
+            return code;
+        }
+
+        public void setCode(int code) {
+            this.code = code;
+        }
+
+        public String getMsg() {
+            return msg;
+        }
+
+        public void setMsg(String msg) {
+            this.msg = msg;
+        }
+
+        public JSONObject getData() {
+            return data;
+        }
+
+        public void setData(JSONObject data) {
+            this.data = data;
+        }
+
+        public Boolean getSuccess() {
+            return isSuccess;
+        }
+
+        public void setSuccess(Boolean success) {
+            isSuccess = success;
+        }
+    }
+
+}