Browse Source

快捷支付

zhijiezhao 2 years ago
parent
commit
ff12186f8c

+ 41 - 35
src/main/java/com/caimei365/order/components/HeliPayUtil.java

@@ -326,45 +326,50 @@ public class HeliPayUtil {
     }
 
     public void setQuickValue(HeliDto heliDto, FirstQuickPayVo firstQuickPayVo, HttpHeaders headers) {
+        /**
+         *  查询银行卡在数据库是否存在,不存在则insert,cm_quickpay_info的id必传,quickPaybindId通过回调修改,用户解绑后再通过
+         *  当前接口下单,quickPaybindId会修改
+         *
+         *
+         *  校验当前卡是否存在
+         */
+        QuickInfoVo info = payOrderMapper.findInfoByBankNumber(heliDto.getQuickPayBankNumber());
+        Integer infoId = 0;
+        if (null != info && null != info.getId()) {
+            infoId = info.getId();
+        } else {
+            QuickInfoVo quickInfoVo = new QuickInfoVo();
+            quickInfoVo.setBankNumber(heliDto.getQuickPayBankNumber());
+            quickInfoVo.setBindMobile(heliDto.getQuickPayMobile());
+            quickInfoVo.setUserId(heliDto.getUserId());
+            quickInfoVo.setQuickPayUserId("U" + heliDto.getUserId());
+            quickInfoVo.setIdCard(heliDto.getIdCard());
+            quickInfoVo.setBankUserName(heliDto.getQuickPayUserName());
+            if (null != heliDto.getQuickPayBankExpireTime()) {
+                quickInfoVo.setBankCvvCode(heliDto.getCvvCode());
+                quickInfoVo.setBankExpireTime(heliDto.getQuickPayBankExpireTime());
+            }
+            payOrderMapper.insertQuickPayInfo(quickInfoVo);
+            infoId = quickInfoVo.getId();
+        }
         firstQuickPayVo.setP1_bizType(BizType.getP1ByType(heliDto.getPayType()));
-//        if (1 == heliDto.getQuickPayType()) {
-        //已绑卡
-        QuickPayUserVo quickPayUserInfo = payOrderMapper.getQuickPayUserInfo(heliDto.getUserId());
-        firstQuickPayVo.setP3_userId(quickPayUserInfo.getQuickPayUserId());
+        // 首次下单接口统一视为未绑卡处理
+        firstQuickPayVo.setP3_userId("U" + heliDto.getUserId());
         //姓名
-        firstQuickPayVo.setP6_payerName(quickPayUserInfo.getBankUserName());
+        firstQuickPayVo.setP6_payerName(heliDto.getQuickPayUserName());
         //身份证号
-        firstQuickPayVo.setP8_idCardNo(quickPayUserInfo.getIdCard());
+        firstQuickPayVo.setP8_idCardNo(heliDto.getIdCard());
         //银行卡号
-        firstQuickPayVo.setP9_cardNo(quickPayUserInfo.getBankNumber());
+        firstQuickPayVo.setP9_cardNo(heliDto.getQuickPayBankNumber());
         //银行绑定手机号
-        firstQuickPayVo.setP13_phone(quickPayUserInfo.getBindMobile());
-        if (2 == quickPayUserInfo.getBankType()) {
-            String[] split = quickPayUserInfo.getBankExpireTime().split("-");
+        firstQuickPayVo.setP13_phone(heliDto.getQuickPayMobile());
+        //信用卡有效期年,月,cvv2 选择信用卡时必填,否则不填
+        if (null != heliDto.getQuickPayBankExpireTime()) {
+            String[] split = heliDto.getQuickPayBankExpireTime().split("-");
             firstQuickPayVo.setP10_year(split[0]);
             firstQuickPayVo.setP11_month(split[1]);
-            firstQuickPayVo.setP12_cvv2(quickPayUserInfo.getBankCvvCode());
+            firstQuickPayVo.setP12_cvv2(heliDto.getCvvCode());
         }
-//        } else {
-//            //未绑卡
-//            firstQuickPayVo.setP3_userId("U" + heliDto.getUserId());
-//            //姓名
-//            firstQuickPayVo.setP6_payerName(heliDto.getQuickPayName());
-//            //身份证号
-//            firstQuickPayVo.setP8_idCardNo(heliDto.getIdCard());
-//            //银行卡号
-//            firstQuickPayVo.setP9_cardNo(heliDto.getQuickPayBankCode());
-//            //银行绑定手机号
-//            firstQuickPayVo.setP13_phone(heliDto.getQuickPayMobile());
-//            //信用卡有效期年,月,cvv2 选择信用卡时必填,否则不填
-//            if (2 == heliDto.getBankType()) {
-//                String[] split = heliDto.getQuickPayBankExpireTime().split("-");
-//                firstQuickPayVo.setP10_year(split[0]);
-//                firstQuickPayVo.setP11_month(split[1]);
-//                firstQuickPayVo.setP12_cvv2(heliDto.getCvvCode());
-//            }
-//        }
-
         /**
          *  快捷支付中回调参数不能带备注,无法在备注区传参,在快捷支付中订单id承担额外参数作用
          *  (见其他支付方式desc参数)
@@ -380,7 +385,7 @@ public class HeliPayUtil {
         if (1 == heliDto.getQuickPayFlag()) {
             //普通订单
             OrderVo order = orderCommonMapper.getOrderByShopOrderId(heliDto.getShopOrderId());
-            orderId = order.getOrderNo() + "_" + order.getOrderId() + "_" + heliDto.getShopOrderId();
+            orderId = order.getOrderNo() + "_" + order.getOrderId() + "_" + heliDto.getShopOrderId() + "_" + infoId;
             //普通订单取传参
             firstQuickPayVo.setP15_orderAmount(heliDto.getPayAmount());
             //回调地址
@@ -391,16 +396,16 @@ public class HeliPayUtil {
             VipRecordBo record = payOrderMapper.getVipPackageRecord(heliDto.getVipRecordId());
             Double price = payOrderMapper.getVipPackagePriceById(record.getPackageId());
             firstQuickPayVo.setP15_orderAmount(price.toString());
-            orderId = "VP_" + record.getPackageId() + "_" + record.getUserId() + "_" + heliDto.getVipRecordId() + "_" + time;
+            orderId = "VP_" + record.getPackageId() + "_" + record.getUserId() + "_" + heliDto.getVipRecordId() + "_" + infoId + "_" + time;
         } else if (3 == heliDto.getQuickPayFlag()) {
             //认证通会员
             VipRecordBo record = payOrderMapper.getAuthVipRecord(heliDto.getVipRecordId());
             Double price = payOrderMapper.getAuthVipPackagePrice(record.getPackageId());
             firstQuickPayVo.setP15_orderAmount(price.toString());
-            orderId = "AVP_" + record.getPackageId() + "_" + record.getUserId() + "_" + heliDto.getVipRecordId() + "_" + time;
+            orderId = "AVP_" + record.getPackageId() + "_" + record.getUserId() + "_" + heliDto.getVipRecordId() + "_" + infoId + "_" + time;
         } else if (4 == heliDto.getQuickPayFlag()) {
             Double couponPrice = payOrderMapper.getCouponPrice(heliDto.getCouponRecordId());
-            orderId = "CP_" + heliDto.getCouponId() + "_" + heliDto.getUserId() + "_" + heliDto.getCouponRecordId() + "_" + heliDto.getSource() + "_" + time;
+            orderId = "CP_" + heliDto.getCouponId() + "_" + heliDto.getUserId() + "_" + heliDto.getCouponRecordId() + "_" + heliDto.getSource() + "_" + infoId + "_" + time;
             firstQuickPayVo.setP15_orderAmount(couponPrice.toString());
         }
         firstQuickPayVo.setP4_orderId(orderId);
@@ -415,5 +420,6 @@ public class HeliPayUtil {
         //同步下发短信
         firstQuickPayVo.setSendValidateCode("true");
         firstQuickPayVo.setP20_orderIp(headers.getFirst("X-CLIENT-IP"));
+        firstQuickPayVo.setSignatureType("SM3WITHSM2");
     }
 }

+ 54 - 1
src/main/java/com/caimei365/order/controller/HeliPayApi.java

@@ -41,6 +41,59 @@ public class HeliPayApi {
     private final HeliPayService heliPayService;
     private final PayOrderService payOrderService;
 
+    @ApiOperation("快捷支付解绑银行卡")
+    @ApiImplicitParam(required = true, name = "cardId", value = "银行卡绑定表Id")
+    @GetMapping("/quick/unbound/card")
+    public ResponseJson unboundCard(Integer cardId) {
+        if (null == cardId) {
+            return ResponseJson.error("绑定卡Id不能为空!");
+        }
+        return heliPayService.unBoundCard(cardId);
+    }
+
+    @ApiOperation("快捷支付银行信息")
+    @ApiImplicitParam(required = false, name = "cardType", value = "银行卡类型")
+    @GetMapping("/quick/bank/infos")
+    public ResponseJson<List<QuickBankVo>> quickBankCode(Integer cardType) {
+        return heliPayService.bankInfos(cardType);
+    }
+
+
+    @ApiOperation("验证码绑卡")
+    @ApiImplicitParams({
+            @ApiImplicitParam(required = true, name = "bindCode", value = "验证码"),
+            @ApiImplicitParam(required = true, name = "orderId", value = "绑定单号")
+    })
+    @GetMapping("/quick/bind/code")
+    public ResponseJson bindCardCheck(String bindCode, String orderId) {
+        if (null == bindCode) {
+            return ResponseJson.error("验证码不能为空!");
+        }
+        if (StringUtils.isBlank(orderId)) {
+            return ResponseJson.error("绑定单号不能为空!");
+        }
+        return heliPayService.bindByCode(bindCode, orderId);
+    }
+
+
+    @ApiOperation("快捷支付预绑卡")
+    @PostMapping("/quick/bind/card")
+    public ResponseJson bindBankCard(HeliDto heliDto) {
+        if (StringUtils.isBlank(heliDto.getQuickPayBankNumber())) {
+            return ResponseJson.error("绑定卡号不能为空!");
+        }
+        if (StringUtils.isBlank(heliDto.getQuickPayUserName())) {
+            return ResponseJson.error("用户名不能为空!");
+        }
+        if (StringUtils.isBlank(heliDto.getIdCard())) {
+            return ResponseJson.error("身份证号不能为空!");
+        }
+        if (StringUtils.isBlank(heliDto.getQuickPayMobile())) {
+            return ResponseJson.error("银行预留手机号码不能为空!");
+        }
+        return heliPayService.bindBankCard(heliDto);
+    }
+
     @ApiOperation("获取子订单信息")
     @ApiImplicitParam(required = true, name = "orderId", value = "订单Id")
     @GetMapping("/shoporders")
@@ -303,7 +356,7 @@ public class HeliPayApi {
 
     @ApiOperation("快捷支付异步通知回调")
     @PostMapping("/quick/callback")
-    public String quickPayCallback(QuickPayConfirmPayResponseVo res){
+    public String quickPayCallback(QuickPayConfirmPayResponseVo res) {
         if (res == null) {
             return "回调参数失败";
         }

+ 15 - 1
src/main/java/com/caimei365/order/mapper/PayOrderMapper.java

@@ -256,5 +256,19 @@ public interface PayOrderMapper {
 
     void updateBySplitStatusByNo(String orderRequestNo);
 
-    QuickPayUserVo getQuickPayUserInfo(Integer userId);
+    QuickInfoVo findInfoByBankNumber(String quickPayBankCode);
+
+    void insertQuickPayInfo(QuickInfoVo quickInfoVo);
+
+    void updateQuickInfo(String bankCode, Integer bankType, Integer infoId);
+
+    void delQuickInfo(String infoId);
+
+    void insertBindId(String bindId, String customerNumber, String userId, Integer infoId);
+
+    List<QuickBankVo> findQuickBank(Integer cardType);
+
+    QuickInfoVo getQuickInfoById(Integer cardId);
+
+    void delQuickBindId(String quickBindId);
 }

+ 2 - 5
src/main/java/com/caimei365/order/model/dto/HeliDto.java

@@ -90,14 +90,11 @@ public class HeliDto implements Serializable {
     @ApiModelProperty("领取渠道1小程序 2网站")
     private Integer source;
 
-    @ApiModelProperty("快捷支付方式 1借记卡 2信用卡")
-    private Integer bankType;
-
     @ApiModelProperty("快捷支付用户姓名")
-    private String quickPayName;
+    private String quickPayUserName;
 
     @ApiModelProperty("快捷支付用户银行卡号/信用卡号")
-    private String quickPayBankCode;
+    private String quickPayBankNumber;
 
     @ApiModelProperty("快捷支付银行卡绑定手机号")
     private String quickPayMobile;

+ 75 - 0
src/main/java/com/caimei365/order/model/vo/BankCardUnbindVo.java

@@ -0,0 +1,75 @@
+package com.caimei365.order.model.vo;
+
+
+import com.caimei365.order.annotation.SignExclude;
+
+/**
+ *  银行卡解绑参数
+ */
+public class BankCardUnbindVo {
+
+    private String P1_bizType;
+    private String P2_customerNumber;
+    private String P3_userId;
+    private String P4_bindId;
+    private String P5_orderId;
+    private String P6_timestamp;
+    @SignExclude
+    private String signatureType;
+
+    public String getP1_bizType() {
+        return P1_bizType;
+    }
+
+    public void setP1_bizType(String p1_bizType) {
+        P1_bizType = p1_bizType;
+    }
+
+    public String getP2_customerNumber() {
+        return P2_customerNumber;
+    }
+
+    public void setP2_customerNumber(String p2_customerNumber) {
+        P2_customerNumber = p2_customerNumber;
+    }
+
+    public String getP3_userId() {
+        return P3_userId;
+    }
+
+    public void setP3_userId(String p3_userId) {
+        P3_userId = p3_userId;
+    }
+
+    public String getP4_bindId() {
+        return P4_bindId;
+    }
+
+    public void setP4_bindId(String p4_bindId) {
+        P4_bindId = p4_bindId;
+    }
+
+    public String getP5_orderId() {
+        return P5_orderId;
+    }
+
+    public void setP5_orderId(String p5_orderId) {
+        P5_orderId = p5_orderId;
+    }
+
+    public String getP6_timestamp() {
+        return P6_timestamp;
+    }
+
+    public void setP6_timestamp(String p6_timestamp) {
+        P6_timestamp = p6_timestamp;
+    }
+
+    public String getSignatureType() {
+        return signatureType;
+    }
+
+    public void setSignatureType(String signatureType) {
+        this.signatureType = signatureType;
+    }
+}

+ 125 - 0
src/main/java/com/caimei365/order/model/vo/BindCardPreOrderResponseVo.java

@@ -0,0 +1,125 @@
+package com.caimei365.order.model.vo;
+
+
+import com.caimei365.order.annotation.SignExclude;
+
+/**
+ *  鉴权绑卡返回值
+ */
+public class BindCardPreOrderResponseVo {
+
+    private String rt1_bizType;
+
+    private String rt2_retCode;
+
+    private String rt3_retMsg;
+
+    private String rt4_customerNumber;
+
+    private String rt5_userId;
+
+    private String rt6_orderId;
+
+    @SignExclude
+    private String smsStatus;
+
+    @SignExclude
+    private String smsMsg;
+
+    @SignExclude
+    private String smsConfirm;
+
+    @SignExclude
+    private String sign;
+
+    @SignExclude
+    private String signatureType;
+
+    public String getRt1_bizType() {
+        return rt1_bizType;
+    }
+
+    public void setRt1_bizType(String rt1_bizType) {
+        this.rt1_bizType = rt1_bizType;
+    }
+
+    public String getRt2_retCode() {
+        return rt2_retCode;
+    }
+
+    public void setRt2_retCode(String rt2_retCode) {
+        this.rt2_retCode = rt2_retCode;
+    }
+
+    public String getRt3_retMsg() {
+        return rt3_retMsg;
+    }
+
+    public void setRt3_retMsg(String rt3_retMsg) {
+        this.rt3_retMsg = rt3_retMsg;
+    }
+
+    public String getRt4_customerNumber() {
+        return rt4_customerNumber;
+    }
+
+    public void setRt4_customerNumber(String rt4_customerNumber) {
+        this.rt4_customerNumber = rt4_customerNumber;
+    }
+
+    public String getRt5_userId() {
+        return rt5_userId;
+    }
+
+    public void setRt5_userId(String rt5_userId) {
+        this.rt5_userId = rt5_userId;
+    }
+
+    public String getRt6_orderId() {
+        return rt6_orderId;
+    }
+
+    public void setRt6_orderId(String rt6_orderId) {
+        this.rt6_orderId = rt6_orderId;
+    }
+
+    public String getSmsStatus() {
+        return smsStatus;
+    }
+
+    public void setSmsStatus(String smsStatus) {
+        this.smsStatus = smsStatus;
+    }
+
+    public String getSmsMsg() {
+        return smsMsg;
+    }
+
+    public void setSmsMsg(String smsMsg) {
+        this.smsMsg = smsMsg;
+    }
+
+    public String getSmsConfirm() {
+        return smsConfirm;
+    }
+
+    public void setSmsConfirm(String smsConfirm) {
+        this.smsConfirm = smsConfirm;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+
+    public String getSignatureType() {
+        return signatureType;
+    }
+
+    public void setSignatureType(String signatureType) {
+        this.signatureType = signatureType;
+    }
+}

+ 128 - 0
src/main/java/com/caimei365/order/model/vo/ConfirmBindCardResponseVo.java

@@ -0,0 +1,128 @@
+package com.caimei365.order.model.vo;
+
+
+import com.caimei365.order.annotation.SignExclude;
+
+/**
+ *  验证码绑卡返回值
+ */
+public class ConfirmBindCardResponseVo {
+    private String rt1_bizType;
+    private String rt2_retCode;
+    private String rt3_retMsg;
+    private String rt4_customerNumber;
+    private String rt5_userId;
+    private String rt6_orderId;
+    private String rt7_bindStatus;
+    private String rt8_bankId;
+    private String rt9_cardAfterFour;
+    private String rt10_bindId;
+    private String rt11_serialNumber;
+    @SignExclude
+    private String sign;
+    @SignExclude
+    private String signatureType;
+
+    public String getRt1_bizType() {
+        return rt1_bizType;
+    }
+
+    public void setRt1_bizType(String rt1_bizType) {
+        this.rt1_bizType = rt1_bizType;
+    }
+
+    public String getRt2_retCode() {
+        return rt2_retCode;
+    }
+
+    public void setRt2_retCode(String rt2_retCode) {
+        this.rt2_retCode = rt2_retCode;
+    }
+
+    public String getRt3_retMsg() {
+        return rt3_retMsg;
+    }
+
+    public void setRt3_retMsg(String rt3_retMsg) {
+        this.rt3_retMsg = rt3_retMsg;
+    }
+
+    public String getRt4_customerNumber() {
+        return rt4_customerNumber;
+    }
+
+    public void setRt4_customerNumber(String rt4_customerNumber) {
+        this.rt4_customerNumber = rt4_customerNumber;
+    }
+
+    public String getRt5_userId() {
+        return rt5_userId;
+    }
+
+    public void setRt5_userId(String rt5_userId) {
+        this.rt5_userId = rt5_userId;
+    }
+
+    public String getRt6_orderId() {
+        return rt6_orderId;
+    }
+
+    public void setRt6_orderId(String rt6_orderId) {
+        this.rt6_orderId = rt6_orderId;
+    }
+
+    public String getRt7_bindStatus() {
+        return rt7_bindStatus;
+    }
+
+    public void setRt7_bindStatus(String rt7_bindStatus) {
+        this.rt7_bindStatus = rt7_bindStatus;
+    }
+
+    public String getRt8_bankId() {
+        return rt8_bankId;
+    }
+
+    public void setRt8_bankId(String rt8_bankId) {
+        this.rt8_bankId = rt8_bankId;
+    }
+
+    public String getRt9_cardAfterFour() {
+        return rt9_cardAfterFour;
+    }
+
+    public void setRt9_cardAfterFour(String rt9_cardAfterFour) {
+        this.rt9_cardAfterFour = rt9_cardAfterFour;
+    }
+
+    public String getRt10_bindId() {
+        return rt10_bindId;
+    }
+
+    public void setRt10_bindId(String rt10_bindId) {
+        this.rt10_bindId = rt10_bindId;
+    }
+
+    public String getRt11_serialNumber() {
+        return rt11_serialNumber;
+    }
+
+    public void setRt11_serialNumber(String rt11_serialNumber) {
+        this.rt11_serialNumber = rt11_serialNumber;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+    public String getSignatureType() {
+        return signatureType;
+    }
+
+    public void setSignatureType(String signatureType) {
+        this.signatureType = signatureType;
+    }
+}

+ 72 - 0
src/main/java/com/caimei365/order/model/vo/ConfirmBindCardVo.java

@@ -0,0 +1,72 @@
+package com.caimei365.order.model.vo;
+
+
+import com.caimei365.order.annotation.FieldEncrypt;
+import com.caimei365.order.annotation.SignExclude;
+
+/**
+ * 验证码绑卡接口参数
+ */
+public class ConfirmBindCardVo {
+    private String P1_bizType;
+
+    private String P2_customerNumber;
+
+    private String P3_orderId;
+
+    private String P4_timestamp;
+
+    @FieldEncrypt
+    private String P5_validateCode;
+
+    @SignExclude
+    private String signatureType;
+
+    public String getP1_bizType() {
+        return P1_bizType;
+    }
+
+    public void setP1_bizType(String p1_bizType) {
+        P1_bizType = p1_bizType;
+    }
+
+    public String getP2_customerNumber() {
+        return P2_customerNumber;
+    }
+
+    public void setP2_customerNumber(String p2_customerNumber) {
+        P2_customerNumber = p2_customerNumber;
+    }
+
+    public String getP3_orderId() {
+        return P3_orderId;
+    }
+
+    public void setP3_orderId(String p3_orderId) {
+        P3_orderId = p3_orderId;
+    }
+
+    public String getP4_timestamp() {
+        return P4_timestamp;
+    }
+
+    public void setP4_timestamp(String p4_timestamp) {
+        P4_timestamp = p4_timestamp;
+    }
+
+    public String getP5_validateCode() {
+        return P5_validateCode;
+    }
+
+    public void setP5_validateCode(String p5_validateCode) {
+        P5_validateCode = p5_validateCode;
+    }
+
+    public String getSignatureType() {
+        return signatureType;
+    }
+
+    public void setSignatureType(String signatureType) {
+        this.signatureType = signatureType;
+    }
+}

+ 26 - 0
src/main/java/com/caimei365/order/model/vo/QuickBankVo.java

@@ -0,0 +1,26 @@
+package com.caimei365.order.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author zzj
+ */
+@Data
+public class QuickBankVo implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private String bankCode;
+    /**
+     * 1借记卡/2贷记卡
+     */
+    private Integer cardType;
+    /**
+     * 银行名
+     */
+    private String bankName;
+    /**
+     * 银行名首字母
+     */
+    private String initial;
+}

+ 30 - 0
src/main/java/com/caimei365/order/model/vo/QuickInfoVo.java

@@ -0,0 +1,30 @@
+package com.caimei365.order.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author zzj
+ */
+@Data
+public class QuickInfoVo implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+    private Integer userId;
+    private String quickPayUserId;
+    private String quickPaybindId;
+    private String idCard;
+    private String bankNumber;
+    private String bankExpireTime;
+    private String bankCvvCode;
+    /**
+     * 用户绑定卡类型1借记卡2信用卡
+     */
+    private String bankType;
+    private String bindMobile;
+    private String bankUserName;
+    private String quickPayBankCode;
+    private String customer;
+}

+ 180 - 0
src/main/java/com/caimei365/order/model/vo/QuickPayBindCardPreOrderVo.java

@@ -0,0 +1,180 @@
+package com.caimei365.order.model.vo;
+
+
+import com.caimei365.order.annotation.FieldEncrypt;
+import com.caimei365.order.annotation.SignExclude;
+
+/**
+ * 合利宝鉴权绑卡预下单参数
+ */
+public class QuickPayBindCardPreOrderVo {
+    private String P1_bizType;
+
+    private String P2_customerNumber;
+
+    private String P3_userId;
+
+    private String P4_orderId;
+
+    private String P5_timestamp;
+
+    private String P6_payerName;
+
+    private String P7_idCardType;
+
+    @FieldEncrypt
+    private String P8_idCardNo;
+
+    @FieldEncrypt
+    private String P9_cardNo;
+
+    @FieldEncrypt
+    private String P10_year;
+
+    @FieldEncrypt
+    private String P11_month;
+
+    @FieldEncrypt
+    private String P12_cvv2;
+
+    @FieldEncrypt
+    private String P13_phone;
+
+    @SignExclude
+    private String sendValidateCode;
+
+    @SignExclude
+    private String protocolType;
+
+    @SignExclude
+    private String signatureType;
+
+    public String getP1_bizType() {
+        return P1_bizType;
+    }
+
+    public void setP1_bizType(String p1_bizType) {
+        P1_bizType = p1_bizType;
+    }
+
+    public String getP2_customerNumber() {
+        return P2_customerNumber;
+    }
+
+    public void setP2_customerNumber(String p2_customerNumber) {
+        P2_customerNumber = p2_customerNumber;
+    }
+
+    public String getP3_userId() {
+        return P3_userId;
+    }
+
+    public void setP3_userId(String p3_userId) {
+        P3_userId = p3_userId;
+    }
+
+    public String getP4_orderId() {
+        return P4_orderId;
+    }
+
+    public void setP4_orderId(String p4_orderId) {
+        P4_orderId = p4_orderId;
+    }
+
+    public String getP5_timestamp() {
+        return P5_timestamp;
+    }
+
+    public void setP5_timestamp(String p5_timestamp) {
+        P5_timestamp = p5_timestamp;
+    }
+
+    public String getP6_payerName() {
+        return P6_payerName;
+    }
+
+    public void setP6_payerName(String p6_payerName) {
+        P6_payerName = p6_payerName;
+    }
+
+    public String getP7_idCardType() {
+        return P7_idCardType;
+    }
+
+    public void setP7_idCardType(String p7_idCardType) {
+        P7_idCardType = p7_idCardType;
+    }
+
+    public String getP8_idCardNo() {
+        return P8_idCardNo;
+    }
+
+    public void setP8_idCardNo(String p8_idCardNo) {
+        P8_idCardNo = p8_idCardNo;
+    }
+
+    public String getP9_cardNo() {
+        return P9_cardNo;
+    }
+
+    public void setP9_cardNo(String p9_cardNo) {
+        P9_cardNo = p9_cardNo;
+    }
+
+    public String getP10_year() {
+        return P10_year;
+    }
+
+    public void setP10_year(String p10_year) {
+        P10_year = p10_year;
+    }
+
+    public String getP11_month() {
+        return P11_month;
+    }
+
+    public void setP11_month(String p11_month) {
+        P11_month = p11_month;
+    }
+
+    public String getP12_cvv2() {
+        return P12_cvv2;
+    }
+
+    public void setP12_cvv2(String p12_cvv2) {
+        P12_cvv2 = p12_cvv2;
+    }
+
+    public String getP13_phone() {
+        return P13_phone;
+    }
+
+    public void setP13_phone(String p13_phone) {
+        P13_phone = p13_phone;
+    }
+
+    public String getSendValidateCode() {
+        return sendValidateCode;
+    }
+
+    public void setSendValidateCode(String sendValidateCode) {
+        this.sendValidateCode = sendValidateCode;
+    }
+
+    public String getProtocolType() {
+        return protocolType;
+    }
+
+    public void setProtocolType(String protocolType) {
+        this.protocolType = protocolType;
+    }
+
+    public String getSignatureType() {
+        return signatureType;
+    }
+
+    public void setSignatureType(String signatureType) {
+        this.signatureType = signatureType;
+    }
+
+}

+ 8 - 0
src/main/java/com/caimei365/order/service/HeliPayService.java

@@ -57,4 +57,12 @@ public interface HeliPayService {
     ResponseJson quickPay(HeliDto heliDto, HttpHeaders headers);
 
     String quickPayCallback(QuickPayConfirmPayResponseVo res);
+
+    ResponseJson bindBankCard(HeliDto heliDto);
+
+    ResponseJson bindByCode(String bindCode, String orderId);
+
+    ResponseJson<List<QuickBankVo>> bankInfos(Integer cardType);
+
+    ResponseJson unBoundCard(Integer cardId);
 }

+ 20 - 10
src/main/java/com/caimei365/order/service/impl/HeliPayNonOrderServiceImpl.java

@@ -1845,11 +1845,12 @@ public class HeliPayNonOrderServiceImpl implements HeliPayNonOrderService {
     private void checkUnOrderStatus(QuickPayConfirmPayResponseVo res) {
         /**
          *  超级会员
-         *  orderId = "VP" + "_" +record.getPackageId() + "_" + record.getUserId() + "_" + heliDto.getVipRecordId() + "_" + time;
+         *  orderId = "VP" + "_" +record.getPackageId() + "_" + record.getUserId() + "_" + heliDto.getVipRecordId() + "_" + infoId + "_" + time;
          *  认证通会员
-         *  orderId ="AVP" + "_" + record.getPackageId() + "_" + record.getUserId() + "_" + heliDto.getVipRecordId() + "_" + time;
+         *  orderId ="AVP" + "_" + record.getPackageId() + "_" + record.getUserId() + "_" + heliDto.getVipRecordId() + "_" + infoId + "_" + time;
          *  优惠券
-         *  orderId ="CP" + "_" + heliDto.getCouponId() + "_" + heliDto.getUserId() + "_" + heliDto.getCouponRecordId() + "_" + heliDto.getSource() + "_" + time;
+         *  orderId ="CP" + "_" + heliDto.getCouponId() + "_" + heliDto.getUserId() + "_" + heliDto.getCouponRecordId()
+         *              + "_" + heliDto.getSource()  + "_" + infoId  + "_" + time;
          */
         String orderId = res.getRt5_orderId();
         boolean vp = orderId.startsWith("VP");
@@ -1859,6 +1860,9 @@ public class HeliPayNonOrderServiceImpl implements HeliPayNonOrderService {
         String orderRequestNo = res.getRt6_serialNumber();
         Double amount = Double.valueOf(res.getRt8_orderAmount());
         String formData = JSON.toJSONString(res);
+        Integer infoId = 0;
+        // 借记卡28,贷记卡29
+        Integer payType = "DEBIT".equals(res.getRt12_onlineCardType()) ? 28 : 29;
         if (vp) {
             /**
              * Integer userId, Integer packageId, Integer payType, Integer recordId,
@@ -1868,7 +1872,8 @@ public class HeliPayNonOrderServiceImpl implements HeliPayNonOrderService {
             Integer packageId = Integer.valueOf(s[1]);
             Integer userId = Integer.valueOf(s[2]);
             Integer recordId = Integer.valueOf(s[3]);
-            superVipStatusCheck(userId, packageId, 28, recordId, amount, formData, mbOrderId, orderRequestNo);
+            infoId = Integer.valueOf(s[4]);
+            superVipStatusCheck(userId, packageId, payType, recordId, amount, formData, mbOrderId, orderRequestNo);
         } else if (avp) {
             /**
              * Integer userId, Integer vipId, Integer recordId, Integer payType, Double amount,
@@ -1878,7 +1883,8 @@ public class HeliPayNonOrderServiceImpl implements HeliPayNonOrderService {
             Integer packageId = Integer.valueOf(s[1]);
             Integer userId = Integer.valueOf(s[2]);
             Integer recordId = Integer.valueOf(s[3]);
-            authVipStatusCheck(userId, packageId, recordId, 28, amount, formData, mbOrderId, orderRequestNo);
+            infoId = Integer.valueOf(s[4]);
+            authVipStatusCheck(userId, packageId, recordId, payType, amount, formData, mbOrderId, orderRequestNo);
         } else if (cp) {
             /**
              * Integer source, Integer userId, Integer couponId, Integer recordId, Integer payType,
@@ -1889,11 +1895,15 @@ public class HeliPayNonOrderServiceImpl implements HeliPayNonOrderService {
             Integer couponId = Integer.valueOf(s[1]);
             Integer recordId = Integer.valueOf(s[3]);
             Integer source = Integer.valueOf(s[4]);
-            couponPayCheck(source, userId, couponId, recordId, 28, amount, formData, mbOrderId, orderRequestNo);
-        }
-
-
-
+            infoId = Integer.valueOf(s[5]);
+            couponPayCheck(source, userId, couponId, recordId, payType, amount, formData, mbOrderId, orderRequestNo);
+        }
+        // quickInfo 信息填充
+        String bankCode = res.getRt11_bankId();
+        Integer bankType = "DEBIT".equals(res.getRt12_onlineCardType()) ? 1 : 2;
+        payOrderMapper.updateQuickInfo(bankCode, bankType, infoId);
+        String userId = res.getRt14_userId().substring(1);
+        payOrderMapper.insertBindId(res.getRt10_bindId(), res.getRt4_customerNumber(), userId, infoId);
     }
 
     public void saveRoleRelation(Integer userId, String roleIds) {

+ 143 - 2
src/main/java/com/caimei365/order/service/impl/HeliPayServiceImpl.java

@@ -252,14 +252,22 @@ public class HeliPayServiceImpl implements HeliPayService {
             shopOrderId = Integer.valueOf(split[2]);
         } else {
             QuickPayConfirmPayResponseVo res = (QuickPayConfirmPayResponseVo) o;
-            payType = "28";
             orderRequestNo = res.getRt5_orderId();
             mbOrderId = res.getRt6_serialNumber();
             amount = Double.valueOf(res.getRt8_orderAmount());
             String[] s = orderRequestNo.split("_");
-            //  orderId = order.getOrderNo() + "_" + order.getOrderId() + "_" + heliDto.getShopOrderId();
+            //  orderId = order.getOrderNo() + "_" + order.getOrderId() + "_" + heliDto.getShopOrderId() + "_" + infoId;
             orderId = Integer.valueOf(s[1]);
             shopOrderId = Integer.valueOf(s[2]);
+            //infoId
+            Integer infoId = Integer.valueOf(s[3]);
+            String bankCode = res.getRt11_bankId();
+            Integer bankType = "DEBIT".equals(res.getRt12_onlineCardType()) ? 1 : 2;
+            payOrderMapper.updateQuickInfo(bankCode, bankType, infoId);
+            String userId = res.getRt14_userId().substring(1);
+            // 快捷支付借记卡支付28,快捷支付贷记卡支付29
+            payType = 1 == bankType ? "28" : "29";
+            payOrderMapper.insertBindId(res.getRt10_bindId(), res.getRt4_customerNumber(), userId, infoId);
         }
         // 订单信息
         OrderVo order = orderCommonMapper.getOrderByOrderId(orderId);
@@ -1317,9 +1325,11 @@ public class HeliPayServiceImpl implements HeliPayService {
                     }
                 } else {
                     log.info("快捷支付付款状态异常============================> res:" + res);
+                    delQuickInfo(res);
                 }
             } else {
                 log.info("快捷支付回调验签失败=========================> res:" + res);
+                delQuickInfo(res);
             }
         } catch (Exception e) {
             e.printStackTrace();
@@ -1327,6 +1337,137 @@ public class HeliPayServiceImpl implements HeliPayService {
         return null;
     }
 
+    public void delQuickInfo(QuickPayConfirmPayResponseVo res) {
+        // 未成功删除cm_quickpay_info中预存的userInfo信息
+        String[] s = res.getRt5_orderId().split("_");
+        String infoId = s[3];
+        payOrderMapper.delQuickInfo(infoId);
+    }
+
+    @Override
+    public ResponseJson bindBankCard(HeliDto heliDto) {
+        QuickPayBindCardPreOrderVo confirmBindCardVo = new QuickPayBindCardPreOrderVo();
+        String time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
+        String orderId = "bd_" + heliDto.getUserId() + "_" + time;
+        confirmBindCardVo.setP1_bizType("QuickPayBindCardPreOrder");
+        //todo 一次请求只能绑定一个e商户,暂定绑定网络,有支付请求走预下单直接绑定
+        confirmBindCardVo.setP2_customerNumber(CUSTOMERNUM2);
+        confirmBindCardVo.setP3_userId("U" + heliDto.getUserId());
+        confirmBindCardVo.setP4_orderId(orderId);
+        confirmBindCardVo.setP5_timestamp(time);
+        confirmBindCardVo.setP6_payerName(heliDto.getQuickPayUserName());
+        confirmBindCardVo.setP7_idCardType("IDCARD");
+        confirmBindCardVo.setP8_idCardNo(heliDto.getIdCard());
+        confirmBindCardVo.setP9_cardNo(heliDto.getQuickPayBankNumber());
+        confirmBindCardVo.setP13_phone(heliDto.getQuickPayMobile());
+        confirmBindCardVo.setProtocolType("protocol");
+        confirmBindCardVo.setSendValidateCode("true");
+        confirmBindCardVo.setSignatureType("SM3WITHSM2");
+        Map reqestMap = null;
+        try {
+            reqestMap = MessageHandle.getReqestMap(confirmBindCardVo);
+            Map<String, Object> resultMap = HttpClientService.getHttpResp(reqestMap, Constant.REQUEST_URL_QUICKPAY);
+            log.info("响应结果:" + resultMap);
+            if ((Integer) resultMap.get("statusCode") != org.apache.commons.httpclient.HttpStatus.SC_OK) {
+                log.info("请求失败--------------------");
+                return ResponseJson.error("请求失败!");
+            }
+
+            String resultMsg = (String) resultMap.get("response");
+            BindCardPreOrderResponseVo responseVo = JSONObject.parseObject(resultMsg, BindCardPreOrderResponseVo.class);
+            if (!MessageHandle.checkSign(responseVo)) {
+                log.info("验签失败");
+                return ResponseJson.error("验签失败!");
+            }
+            if (!"SUCCESS".equals(responseVo.getSmsMsg())) {
+                log.info("短信发送失败------------------------");
+                return ResponseJson.error("短信发送失败!");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return ResponseJson.success(orderId);
+    }
+
+    @Override
+    public ResponseJson bindByCode(String bindCode, String orderId) {
+        ConfirmBindCardVo confirmBindCardVo = new ConfirmBindCardVo();
+        confirmBindCardVo.setP1_bizType("ConfirmBindCard");
+        confirmBindCardVo.setP2_customerNumber(Constant.CUSTOMERNUM2);
+        confirmBindCardVo.setP3_orderId(orderId);
+        String[] s = orderId.split("_");
+        confirmBindCardVo.setP4_timestamp(s[2]);
+        confirmBindCardVo.setP5_validateCode(bindCode);
+        confirmBindCardVo.setSignatureType("SM3WITHSM2");
+        Map reqestMap = null;
+        try {
+            reqestMap = MessageHandle.getReqestMap(confirmBindCardVo);
+            Map<String, Object> resultMap = HttpClientService.getHttpResp(reqestMap, Constant.REQUEST_URL_QUICKPAY);
+            log.info("响应结果:" + resultMap);
+            if ((Integer) resultMap.get("statusCode") != org.apache.commons.httpclient.HttpStatus.SC_OK) {
+                log.info("请求失败");
+                return ResponseJson.error("请求失败");
+            }
+            String resultMsg = (String) resultMap.get("response");
+            ConfirmBindCardResponseVo responseVo = JSONObject.parseObject(resultMsg, ConfirmBindCardResponseVo.class);
+            if (!MessageHandle.checkSign(responseVo)) {
+                return ResponseJson.error("验签失败!");
+            }
+            if (!"SUCCESS".equals(responseVo.getRt7_bindStatus())) {
+                return ResponseJson.error("绑定失败!");
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return ResponseJson.success();
+    }
+
+    @Override
+    public ResponseJson<List<QuickBankVo>> bankInfos(Integer cardType) {
+        return ResponseJson.success(payOrderMapper.findQuickBank(cardType));
+    }
+
+    @Override
+    public ResponseJson unBoundCard(Integer cardId) {
+        BankCardUnbindVo unbind = new BankCardUnbindVo();
+        QuickInfoVo info = payOrderMapper.getQuickInfoById(cardId);
+        String time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
+        unbind.setP1_bizType("BankCardUnbind");
+        unbind.setP2_customerNumber(info.getCustomer());
+        unbind.setP3_userId(info.getQuickPayUserId());
+        unbind.setP4_bindId(info.getQuickPaybindId());
+        unbind.setP5_orderId("ub_" + time + cardId);
+        unbind.setP6_timestamp(time);
+        unbind.setSignatureType("SM3WITHSM2");
+        try {
+            Map reqestMap = MessageHandle.getReqestMap(unbind);
+            Map<String, Object> resultMap = HttpClientService.getHttpResp(reqestMap, REQUEST_URL_QUICKPAY);
+            log.info("响应结果:" + resultMap);
+            if ((Integer) resultMap.get("statusCode") != org.apache.commons.httpclient.HttpStatus.SC_OK) {
+                log.info("----------------解绑银行卡请求失败-----------------");
+                return ResponseJson.error("请求失败!");
+            }
+            String resultMsg = (String) resultMap.get("response");
+            ConfirmBindCardResponseVo responseVo = JSONObject.parseObject(resultMsg, ConfirmBindCardResponseVo.class);
+            if (!MessageHandle.checkSign(responseVo)) {
+                log.info("------------------------解绑银行卡验签失败-------------------");
+                return ResponseJson.error("解绑银行卡验签失败!");
+            }
+            if (!"0000".equals(responseVo.getRt2_retCode())) {
+                log.info("-----------------银行卡解绑失败---------------------");
+                return ResponseJson.error("银行卡解绑失败!");
+            }
+            // 解绑成功 cm_quickpay_info置为删除
+            payOrderMapper.delQuickInfo(cardId.toString());
+            payOrderMapper.delQuickBindId(info.getQuickPaybindId());
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.info("交易异常:" + e.getMessage());
+        }
+        return null;
+    }
+
     public static <T> T postForm(Map<String, String> params, String url, String sign, Class<T> clazz) {
         FormBody.Builder builder = new FormBody.Builder();
         for (Map.Entry<String, String> entry : params.entrySet()) {

+ 61 - 6
src/main/resources/mapper/PayOrderMapper.xml

@@ -41,6 +41,16 @@
         FROM auth_role_user
         WHERE user_id = #{userId}
     </delete>
+    <delete id="delQuickBindId">
+        delete
+        from cm_quickpay_bindcardinfo
+        where quickBindId = #{quickBindId}
+    </delete>
+    <update id="delQuickInfo">
+        update cm_quickpay_info
+        set delFlag = 1
+        where id = #{infoId}
+    </update>
     <insert id="insertOrderPayLink" keyColumn="id" keyProperty="id"
             parameterType="com.caimei365.order.model.vo.OrderPayLinkVo" useGeneratedKeys="true">
         INSERT INTO cm_order_pay_link (orderId, vipRecordId, authVipRecordId, vipMonth, linkLogo, unpaidAmount,
@@ -94,6 +104,19 @@
         INSERT INTO auth_role_user(user_id, role_id)
         VALUES (#{userId}, #{roleId})
     </insert>
+    <insert id="insertQuickPayInfo" keyColumn="id" keyProperty="id" useGeneratedKeys="true"
+            parameterType="com.caimei365.order.model.vo.QuickInfoVo">
+        insert into cm_quickpay_info(userId, quickPayUserId, idCard, bankNumber, bankExpireTime,
+                                     bankCvvCode, bankType, bindMobile, bankUserName, quickPayBankCode)
+        values (#{userId}, #{quickPayUserId}, #{idCard}, #{bankNumber}, #{bankExpireTime},
+                #{bankCvvCode}, #{bankType}, #{bindMobile}, #{bankUserName}, #{quickPayBankCode})
+    </insert>
+    <insert id="insertBindId">
+        insert into cm_quickpay_bindcardinfo(quickbindid, bindcustomer, userid, quickinfoid)
+        select #{bindId}, #{customerNumber}, #{userId}, #{infoId}
+        from DUAL
+        where NOT EXISTS(SELECT id FROM cm_quickpay_bindcardinfo WHERE quickBindId = #{bindId})
+    </insert>
     <update id="updateUserVipInfo">
         UPDATE cm_svip_user
         set userId=#{userId},
@@ -212,6 +235,12 @@
         SET splitStatus = 1
         WHERE orderRequestNo = #{orderRequestNo}
     </update>
+    <update id="updateQuickInfo">
+        update cm_quickpay_info
+        set bankType         = #{bankType},
+            quickPayBankCode = #{bankCode}
+        where id = #{infoId}
+    </update>
     <select id="getPayOnLineSwitch" resultType="java.lang.Integer">
         SELECT STATUS
         FROM cm_pay_online_switch
@@ -496,19 +525,45 @@
         from cm_shop_order
         where shopOrderID = #{shopOrderId}
     </select>
-
-    <select id="getQuickPayUserInfo" resultType="com.caimei365.order.model.vo.QuickPayUserVo">
-        select userId,
+    <select id="findInfoByBankNumber" resultType="com.caimei365.order.model.vo.QuickInfoVo">
+        select id,
+               userId,
                quickPayUserId,
-               quickPaybindId,
                idCard,
                bankNumber,
                bankExpireTime,
                bankCvvCode,
                bankType,
                bindMobile,
-               bankUserName
+               bankUserName,
+               quickPayBankCode
         from cm_quickpay_info
-        where userId = #{userId}
+        where bankNumber = #{quickPayBankCode}
+          and delflag = 0
+    </select>
+    <select id="findQuickBank" resultType="com.caimei365.order.model.vo.QuickBankVo">
+        SELECT bankCode, cardType, bankName, initial
+        FROM cm_quickpay_bankcode
+        where cardType = #{cardType}
+        ORDER BY initial ASC
+    </select>
+    <select id="getQuickInfoById" resultType="com.caimei365.order.model.vo.QuickInfoVo">
+        SELECT cqi.userid,
+               quickpayuserId,
+               idcard,
+               banknumber,
+               bankExpireTime,
+               bankCvvCode,
+               bankType,
+               bindMobile,
+               bankUserName,
+               quickPayBankCode,
+               cqb.quickBindId  as quickPaybindId,
+               cqb.bindCustomer as customer
+        FROM cm_quickpay_info cqi
+                 LEFT JOIN cm_quickpay_bindcardinfo cqb ON cqi.id = cqb.quickInfoId
+        WHERE cqi.id = #{cardId}
+          AND delflag = 0
+        limit 1
     </select>
 </mapper>