Ver Fonte

feat:"增加汇付提现回调"

soobin há 4 meses atrás
pai
commit
67f11429f0

+ 5 - 2
src/main/java/com/szwl/constant/HuifuConstant.java

@@ -107,8 +107,6 @@ public class HuifuConstant {
     public final static String Notify_Url_PromoCode = "https://sz.sunzee.com.cn/PAY-SERVER/tOrder/promoCodeNotify";
 //    public final static String Notify_Url_PromoCode = "http://slb.sunzee.com.cn/api/order/promoCodeNotify.htm";
 
-    public final static String Jiesuan_Url = "https://sz.sunzee.com.cn/PAY-SERVER/api/order/jiesuan";
-//    public final static String Jiesuan_Url = "http://slb.sunzee.com.cn/api/order/jiesuan.htm";
 
     public final static Map<String,String> Result_status = new HashMap<>();
     /**
@@ -118,6 +116,11 @@ public class HuifuConstant {
 //    public final static String Notify_Refund_Url = "http://szwltest.sunzee.com.cn:49002/PAY-SERVER/tOrder/refundNotify";
     public final static String Admin_Notify_Refund_Url = "http://app.sunzee.com.cn/api/order/adminNotifyRefund";
 
+    // 提现回调
+    /**
+     *
+     */
+    public final static String Jiesuan_Url = "https://sz.sunzee.com.cn/SZWL-SERVER/callback/withdrawHuifu";
 
     /**
      * 支付回调支付状态代码

+ 50 - 2
src/main/java/com/szwl/controller/CallbackController.java

@@ -5,12 +5,14 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.huifu.bspay.sdk.opps.core.utils.RsaUtils;
+import com.szwl.constant.HuifuConstant;
 import com.szwl.constant.JoinpayConstant;
-import com.szwl.model.entity.TJoinpayMch;
 import com.szwl.model.entity.WithdrawalRecord;
-import com.szwl.service.TJoinpayMchService;
+import com.szwl.model.utils.RSAUtil;
 import com.szwl.service.WithdrawalRecordService;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -26,6 +28,7 @@ import javax.servlet.http.HttpServletRequest;
  * @author soobin
  * @since 2024-03-24
  */
+@Slf4j
 @RestController
 @RequestMapping("/callback")
 public class CallbackController {
@@ -61,4 +64,49 @@ public class CallbackController {
         jsonNodes.put("order_status", "success");
         return jsonNodes;
     }
+
+    @ApiOperation("汇付提现回调")
+    @GetMapping("/withdrawHuifu")
+    public String withdrawHuifu(HttpServletRequest request) {
+        String respData = request.getParameter("resp_data");
+        String respDesc = request.getParameter("resp_desc");
+        try {
+            // 验签请参sign
+            String sign = request.getParameter("sign");
+            // 使用汇付公钥验签
+            if (!RSAUtil.verify(respData, HuifuConstant.HUIFU_PUBLIC_KEY, sign)) {
+                // 验签失败处理
+                log.info("验签失败");
+                return "";
+            }
+            JSONObject data = JSONObject.parseObject(respData);
+
+            String transStat = data.getString("trans_stat");
+            // 订单号
+            String reqSeqId = data.getString("req_seq_id");
+            String subRespCode = data.getString("sub_resp_code");
+            LambdaQueryWrapper<WithdrawalRecord> query = Wrappers.lambdaQuery();
+            query.eq(WithdrawalRecord::getOrderNo, reqSeqId);
+            WithdrawalRecord withdrawalRecord = withdrawalRecordService.getOne(query);
+            withdrawalRecord.setStatus(2);
+            if (HuifuConstant.RESP_CODE.equals(subRespCode)) {
+                // 业务处理成功
+                log.info("处理成功");
+                if (HuifuConstant.TRANS_STAT_S.equals(transStat)) {
+                    withdrawalRecord.setStatus(1);
+                } else {
+                    withdrawalRecord.setResultMsg(data.getString("sub_resp_desc"));
+                }
+            } else {
+                // 业务处理失败
+                log.info("处理失败");
+                withdrawalRecord.setResultMsg(respDesc);
+            }
+            withdrawalRecordService.updateById(withdrawalRecord);
+            return "RECV_ORD_ID_" + reqSeqId;
+        }catch (Exception e){
+            log.info("异步回调开始,参数,request={}", respData ,e);
+        }
+        return "";
+    }
 }

+ 1 - 1
src/main/java/com/szwl/controller/PurseController.java

@@ -124,7 +124,7 @@ public class PurseController {
             query.eq(THuifuMch::getAdminId, withdrawalRecord.getAdminId());
             THuifuMch huifuMch = tHuifuMchService.getOne(query);
             try {
-                result = tHuifuMchService.withdraw(String.valueOf(withdrawalRecord.getAmount()), huifuMch.getHuifuId(), "T1", huifuMch.getTokenNo());
+                result = tHuifuMchService.withdraw(withdrawalRecord, huifuMch);
             } catch (BasePayException e) {
                 throw new RuntimeException(e);
             }

+ 1 - 1
src/main/java/com/szwl/model/entity/WithdrawalRecord.java

@@ -44,7 +44,7 @@ public class WithdrawalRecord implements Serializable {
     @ApiModelProperty(value = "到账时间")
     private Date arrivalDate;
 
-    @ApiModelProperty(value = "提现状态")
+    @ApiModelProperty(value = "提现状态,0:处理中,1:提现成功,2:提现失败")
     private Integer status;
 
     @ApiModelProperty(value = "支付平台  0或null为汇聚,1为汇付支付")

+ 30 - 0
src/main/java/com/szwl/model/utils/RSAUtil.java

@@ -4,12 +4,14 @@ package com.szwl.model.utils;
 import com.szwl.model.utils.constants.Algorithm;
 import com.szwl.model.utils.constants.CommonConst;
 import com.szwl.model.utils.exceptions.JPException;
+import lombok.extern.slf4j.Slf4j;
 
 import javax.crypto.Cipher;
 import java.io.ByteArrayOutputStream;
 import java.security.*;
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -18,6 +20,7 @@ import java.util.Map;
  * @author chenyf
  * @date 2018-12-15
  */
+@Slf4j
 public class RSAUtil {
     public static final String DEFAULT_ENCRYPT_ALGORITHM = "RSA/ECB/PKCS1Padding";
     public static final String SIGNATURE_ALGORITHM_SHA1 = "SHA1withRSA";
@@ -184,4 +187,31 @@ public class RSAUtil {
         KeyFactory keyFactory = KeyFactory.getInstance(Algorithm.RSA);
         return keyFactory.generatePublic(x509KeySpec);
     }
+
+    /**
+     * 使用汇付RSA公钥验签
+     * @param data 待签名字符串
+     * @param publicKeyBase64 公钥(Base64编码)
+     * @return 验签结果
+     * @throws Exception
+     */
+    public static boolean verify(String data, String publicKeyBase64, String sign) {
+        // Base64 --> Key
+        try {
+            byte[] bytes = Base64.getDecoder().decode(publicKeyBase64);
+            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
+            KeyFactory keyFactory;
+            keyFactory = KeyFactory.getInstance("RSA");
+            PublicKey publicKey = keyFactory.generatePublic(keySpec);
+            // verify
+            Signature signature = Signature.getInstance("SHA256WithRSA");
+            signature.initVerify(publicKey);
+            signature.update(data.getBytes("UTF-8"));
+            return signature.verify(Base64.getDecoder().decode(sign));
+        } catch (Exception e) {
+            log.error("Exception", e);
+            return false;
+        }
+
+    }
 }

+ 9 - 0
src/main/java/com/szwl/service/THuifuMchService.java

@@ -6,6 +6,7 @@ import com.szwl.constant.HuifuConstant;
 import com.szwl.model.bo.BalanceBo;
 import com.szwl.model.entity.THuifuMch;
 import com.szwl.model.entity.THuifuMchCheck;
+import com.szwl.model.entity.WithdrawalRecord;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.math.BigDecimal;
@@ -122,4 +123,12 @@ public interface THuifuMchService extends IService<THuifuMch> {
      * @return
      */
     BalanceBo getBalance(THuifuMch huifuMch);
+
+    /**
+     * 提现
+     * @param withdrawalRecord
+     * @param huifuMch
+     * @return
+     */
+    String withdraw(WithdrawalRecord withdrawalRecord, THuifuMch huifuMch) throws BasePayException;
 }

+ 127 - 60
src/main/java/com/szwl/service/impl/THuifuMchServiceImpl.java

@@ -21,9 +21,11 @@ import com.szwl.model.bo.BalanceBo;
 import com.szwl.model.entity.TAdmin;
 import com.szwl.model.entity.THuifuMch;
 import com.szwl.model.entity.THuifuMchCheck;
+import com.szwl.model.entity.WithdrawalRecord;
 import com.szwl.service.TAdminService;
 import com.szwl.service.THuifuMchCheckService;
 import com.szwl.service.THuifuMchService;
+import com.szwl.service.WithdrawalRecordService;
 import com.szwl.util.HuifuUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
@@ -55,7 +57,7 @@ import static com.szwl.util.HuifuUtils.base64ToTempImage;
 
 /**
  * <p>
- *  服务实现类
+ * 服务实现类
  * </p>
  *
  * @author wuhs
@@ -72,10 +74,14 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
     private THuifuMchService tHuifuMchService;
 
     @Autowired
+    WithdrawalRecordService withdrawalRecordService;
+
+    @Autowired
     private TAdminService tAdminService;
 
     /**
      * 汇付用户开户
+     *
      * @param tHuifuMchCheck
      * @return
      * @throws Exception
@@ -92,7 +98,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         // 请求日期
         request.put("req_date", DateTools.getCurrentDateYYYYMMDD());
         // 判断商户类型,“0”为个人,“1”为企业
-        if(tHuifuMchCheck.getType().equals("0")) {
+        if (tHuifuMchCheck.getType().equals("0")) {
             // 个人姓名
             request.put("name", tHuifuMchCheck.getRegName());
             // 个人证件类型
@@ -157,7 +163,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         String sign = HuifuUtils.sign(s1, HuifuConstant.RSA_PRIVATE_KEY);
 
         // 公共参数
-        System.out.println("请求参数:"+ request);
+        System.out.println("请求参数:" + request);
         JSONObject requestData = new JSONObject();
         requestData.put("sys_id", HuifuConstant.SYS_ID);
         requestData.put("product_id", HuifuConstant.PRODUCT_ID);
@@ -165,18 +171,18 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         requestData.put("data", request);
 
         String result = OkHttpClientTools.httpPost(url, requestData.toString(), HuifuConstant.PRODUCT_ID);
-        System.out.println("返回的数据:"+ result);
+        System.out.println("返回的数据:" + result);
         JSONObject jsonObject = JSONObject.parseObject(result);
         JSONObject dataObject = jsonObject.getJSONObject("data");
         String code = dataObject.getString("resp_code");
-        if(code.equals(HuifuConstant.RESP_CODE)) {
+        if (code.equals(HuifuConstant.RESP_CODE)) {
             String huifuId = dataObject.getString("huifu_id");
             tHuifuMchCheck.setModifyDate(new Date());
             tHuifuMchCheck.setStatus("1");
             tHuifuMchCheck.setHuifuId(huifuId);
             tHuifuMchCheckService.updateById(tHuifuMchCheck);
             return HuifuConstant.SUCCESS;
-        }else {
+        } else {
             String respDesc = dataObject.getString("resp_desc");
             tHuifuMchCheck.setModifyDate(new Date());
             tHuifuMchCheck.setStatus("3");
@@ -188,6 +194,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
 
     /**
      * 用户业务入驻
+     *
      * @param tHuifuMchCheck
      * @return
      * @throws Exception
@@ -257,7 +264,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         Integer settType = tHuifuMchCheck.getSettType();
         settleConfig.put("settle_cycle", "T1");
         JSONArray cashConfig = new JSONArray();
-        if (settType!= null && settType == 2) {
+        if (settType != null && settType == 2) {
             // 手动提现
             settleConfig.put("settle_status", "0");
             JSONObject cashConfigValue = new JSONObject();
@@ -282,20 +289,20 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         String sign = HuifuUtils.sign(s1, HuifuConstant.RSA_PRIVATE_KEY);
 
         // 公共参数
-        System.out.println("请求参数:"+ request);
+        System.out.println("请求参数:" + request);
         JSONObject requestData = new JSONObject();
         requestData.put("sys_id", HuifuConstant.SYS_ID);
         requestData.put("product_id", HuifuConstant.PRODUCT_ID);
         requestData.put("sign", sign);
         requestData.put("data", request);
-        System.out.println("最终请求参数:"+ requestData);
+        System.out.println("最终请求参数:" + requestData);
 
         String result = OkHttpClientTools.httpPost(url, requestData.toString(), HuifuConstant.PRODUCT_ID);
-        System.out.println("返回的数据:"+ result);
+        System.out.println("返回的数据:" + result);
         JSONObject jsonObject = JSONObject.parseObject(result);
         JSONObject dataObject = jsonObject.getJSONObject("data");
         String code = dataObject.getString("resp_code");
-        if(code.equals(HuifuConstant.RESP_CODE)) {
+        if (code.equals(HuifuConstant.RESP_CODE)) {
             String huifuId = dataObject.getString("huifu_id");
             tHuifuMchCheck.setModifyDate(new Date());
             tHuifuMchCheck.setStatus("2");
@@ -304,7 +311,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
             wrapper.eq(THuifuMch::getAdminId, tHuifuMchCheck.getAdminId());
             THuifuMch huifuMch = tHuifuMchService.getOne(wrapper);
             if (huifuMch != null) {
-                String[] ignoreProperties = {"id", "createDate","adminId"};
+                String[] ignoreProperties = {"id", "createDate", "adminId"};
                 BeanUtil.copyProperties(tHuifuMchCheck, huifuMch, ignoreProperties);
                 huifuMch.setModifyDate(new Date());
                 String tokenNo = dataObject.getString("token_no");
@@ -316,7 +323,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
                 THuifuMch tHuifuMch = new THuifuMch();
                 BeanUtil.copyProperties(tHuifuMchCheck, tHuifuMch);
                 // 判断持卡人证件有效期类型,1:长期有效,0:非长期有效
-                if(tHuifuMchCheck.getCertValidityType().equals("0")) {
+                if (tHuifuMchCheck.getCertValidityType().equals("0")) {
                     LocalDate date = LocalDate.parse(tHuifuMchCheck.getCertEndDate(), DateTimeFormatter.ofPattern("yyyyMMdd"));
                     String certEndDate = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                     tHuifuMch.setCertDate(certEndDate);
@@ -334,7 +341,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
             }
             tHuifuMchCheckService.updateById(tHuifuMchCheck);
             return HuifuConstant.SUCCESS;
-        }else {
+        } else {
             String respDesc = dataObject.getString("resp_desc");
             tHuifuMchCheck.setModifyDate(new Date());
             tHuifuMchCheck.setStatus("3");
@@ -346,6 +353,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
 
     /**
      * 汇付个人商户入驻
+     *
      * @param tHuifuMchCheck
      * @return
      * @throws Exception
@@ -366,7 +374,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         // 商户名称
         request.put("reg_name", tHuifuMchCheck.getRegName());
         // 商户简称
-        if(StrUtil.isNotEmpty(tHuifuMchCheck.getShortName())) {
+        if (StrUtil.isNotEmpty(tHuifuMchCheck.getShortName())) {
             request.put("short_name", tHuifuMchCheck.getShortName());
         }
         // 经营省
@@ -432,7 +440,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         String sign = HuifuUtils.sign(s1, HuifuConstant.RSA_PRIVATE_KEY);
 
         // 公共参数
-        System.out.println("请求参数:"+ request);
+        System.out.println("请求参数:" + request);
         JSONObject requestData = new JSONObject();
         requestData.put("sys_id", HuifuConstant.SYS_ID);
         requestData.put("product_id", HuifuConstant.PRODUCT_ID);
@@ -440,16 +448,16 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         requestData.put("data", request);
 
         String result = OkHttpClientTools.httpPost(url, requestData.toString(), HuifuConstant.PRODUCT_ID);
-        System.out.println("返回的数据:"+ result);
+        System.out.println("返回的数据:" + result);
         JSONObject jsonObject = JSONObject.parseObject(result);
         JSONObject dataObject = jsonObject.getJSONObject("data");
         String code = dataObject.getString("resp_code");
-        if(code.equals("90000000")) {
+        if (code.equals("90000000")) {
             THuifuMch tHuifuMch = new THuifuMch();
             BeanUtil.copyProperties(tHuifuMchCheck, tHuifuMch);
             String huifuId = dataObject.getString("huifu_id");
             // 判断持卡人证件有效期类型,1:长期有效,0:非长期有效
-            if(tHuifuMchCheck.getCertValidityType().equals("0")) {
+            if (tHuifuMchCheck.getCertValidityType().equals("0")) {
                 LocalDate date = LocalDate.parse(tHuifuMchCheck.getCertEndDate(), DateTimeFormatter.ofPattern("yyyyMMdd"));
                 String certEndDate = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                 tHuifuMch.setCertDate(certEndDate);
@@ -465,7 +473,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
             tHuifuMchService.save(tHuifuMch);
             tHuifuMchCheckService.updateById(tHuifuMchCheck);
             return "success";
-        }else {
+        } else {
             String respDesc = dataObject.getString("resp_desc");
             tHuifuMchCheck.setModifyDate(new Date());
             tHuifuMchCheck.setStatus("3");
@@ -477,6 +485,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
 
     /**
      * 汇付企业商户入驻
+     *
      * @param tHuifuMchCheck
      * @return
      * @throws Exception
@@ -497,7 +506,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         // 商户名称
         request.put("reg_name", tHuifuMchCheck.getRegName());
         // 商户简称
-        if(StrUtil.isNotEmpty(tHuifuMchCheck.getShortName())) {
+        if (StrUtil.isNotEmpty(tHuifuMchCheck.getShortName())) {
             request.put("short_name", tHuifuMchCheck.getShortName());
         }
         // 公司类型
@@ -557,14 +566,14 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         // 所属行业
         request.put("mcc", "6071");
         // 基本存款账户编号或核准号
-        if(StrUtil.isNotEmpty(tHuifuMchCheck.getOpenLicenceNo())){
+        if (StrUtil.isNotEmpty(tHuifuMchCheck.getOpenLicenceNo())) {
             request.put("open_licence_no", tHuifuMchCheck.getOpenLicenceNo());
         }
         // 开户许可证
-        if(StrUtil.isNotEmpty(tHuifuMchCheck.getRegAcctPic())){
+        if (StrUtil.isNotEmpty(tHuifuMchCheck.getRegAcctPic())) {
             request.put("reg_acct_pic", tHuifuMchCheck.getRegAcctPic());
         }
-        if(tHuifuMchCheck.getCardType().equals("1")) {
+        if (tHuifuMchCheck.getCardType().equals("1")) {
             // 结算卡正面
             request.put("settle_card_front_pic", tHuifuMchCheck.getCardFrontPic());
             // 法人身份证人像面
@@ -602,10 +611,10 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
             cardInfo.put("area_id", tHuifuMchCheck.getCardAreaId());
         }
         // 联行号
-        if(StrUtil.isNotEmpty(tHuifuMchCheck.getBranchCode())){
+        if (StrUtil.isNotEmpty(tHuifuMchCheck.getBranchCode())) {
             cardInfo.put("branch_code", tHuifuMchCheck.getBranchCode());
         }
-        if(StrUtil.isNotEmpty(tHuifuMchCheck.getMp())){
+        if (StrUtil.isNotEmpty(tHuifuMchCheck.getMp())) {
             cardInfo.put("mp", tHuifuMchCheck.getMp());
         }
         request.put("card_info", cardInfo);
@@ -613,7 +622,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         JSONObject settleConfig = new JSONObject();
         Integer settType = tHuifuMchCheck.getSettType();
         JSONArray cashConfig = new JSONArray();
-        if (settType!= null && settType == 2) {
+        if (settType != null && settType == 2) {
             // 手动提现
             settleConfig.put("settle_status", "0");
             JSONObject cashConfigValue = new JSONObject();
@@ -638,25 +647,25 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         String sign = HuifuUtils.sign(s1, HuifuConstant.RSA_PRIVATE_KEY);
 
         // 公共参数
-        System.out.println("请求参数:"+ request);
+        System.out.println("请求参数:" + request);
         JSONObject requestData = new JSONObject();
         requestData.put("sys_id", HuifuConstant.SYS_ID);
         requestData.put("product_id", HuifuConstant.PRODUCT_ID);
         requestData.put("sign", sign);
         requestData.put("data", request);
-        System.out.println("请求体:"+ requestData);
+        System.out.println("请求体:" + requestData);
 
         String result = OkHttpClientTools.httpPost(url, requestData.toString(), HuifuConstant.PRODUCT_ID);
-        System.out.println("返回的数据:"+ result);
+        System.out.println("返回的数据:" + result);
         JSONObject jsonObject = JSONObject.parseObject(result);
         JSONObject dataObject = jsonObject.getJSONObject("data");
         String code = dataObject.getString("resp_code");
-        if(code.equals("90000000")) {
+        if (code.equals("90000000")) {
             THuifuMch tHuifuMch = new THuifuMch();
             BeanUtil.copyProperties(tHuifuMchCheck, tHuifuMch);
             String huifuId = dataObject.getString("huifu_id");
             // 判断持卡人证件有效期类型,1:长期有效,0:非长期有效
-            if(tHuifuMchCheck.getCertValidityType().equals("0")) {
+            if (tHuifuMchCheck.getCertValidityType().equals("0")) {
                 LocalDate date = LocalDate.parse(tHuifuMchCheck.getCertEndDate(), DateTimeFormatter.ofPattern("yyyyMMdd"));
                 String certEndDate = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                 tHuifuMch.setCertDate(certEndDate);
@@ -676,7 +685,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
             tHuifuMchService.save(tHuifuMch);
             tHuifuMchCheckService.updateById(tHuifuMchCheck);
             return "success";
-        }else {
+        } else {
             String respDesc = dataObject.getString("resp_desc");
             tHuifuMchCheck.setModifyDate(new Date());
             tHuifuMchCheck.setStatus("3");
@@ -688,6 +697,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
 
     /**
      * 汇付商户基本信息修改
+     *
      * @param huifuMchCheck
      * @return
      */
@@ -708,7 +718,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         // 商户名称
         request.put("reg_name", huifuMchCheck.getRegName());
         // 商户简称
-        if(StrUtil.isNotEmpty(huifuMchCheck.getShortName())) {
+        if (StrUtil.isNotEmpty(huifuMchCheck.getShortName())) {
             request.put("short_name", huifuMchCheck.getShortName());
         }
         // 经营省
@@ -730,10 +740,10 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         cardInfo.put("card_type", huifuMchCheck.getCardType());
         cardInfo.put("card_name", huifuMchCheck.getCardName());
         cardInfo.put("card_no", huifuMchCheck.getCardNo());
-        if(StrUtil.isNotEmpty(huifuMchCheck.getCardProvId())) {
+        if (StrUtil.isNotEmpty(huifuMchCheck.getCardProvId())) {
             cardInfo.put("prov_id", huifuMchCheck.getCardProvId());
         }
-        if(StrUtil.isNotEmpty(huifuMchCheck.getCardAreaId())) {
+        if (StrUtil.isNotEmpty(huifuMchCheck.getCardAreaId())) {
             cardInfo.put("area_id", huifuMchCheck.getCardAreaId());
         }
         cardInfo.put("cert_type", "00");
@@ -741,7 +751,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         cardInfo.put("cert_validity_type", huifuMchCheck.getCertValidityType());
         cardInfo.put("cert_begin_date", huifuMchCheck.getCertBeginDate());
         cardInfo.put("cert_end_date", huifuMchCheck.getCertEndDate());
-        if(StrUtil.isNotEmpty(huifuMchCheck.getMp())) {
+        if (StrUtil.isNotEmpty(huifuMchCheck.getMp())) {
             cardInfo.put("mp", huifuMchCheck.getMp());
         }
         cardInfo.put("settle_card_front_pic", huifuMchCheck.getCardFrontPic());
@@ -749,14 +759,14 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         cardInfo.put("settle_cert_back_pic", huifuMchCheck.getCertBackPic());
         cardInfo.put("legal_cert_front_pic", huifuMchCheck.getLegalCertFrontPic());
         cardInfo.put("legal_cert_back_pic", huifuMchCheck.getLegalCertBackPic());
-        if(StrUtil.isNotEmpty(huifuMchCheck.getSms())) {
+        if (StrUtil.isNotEmpty(huifuMchCheck.getSms())) {
             cardInfo.put("verify_code", huifuMchCheck.getSms());
         }
         request.put("card_info", cardInfo);
         JSONObject settleConfig = new JSONObject();
         Integer settType = huifuMchCheck.getSettType();
         JSONArray cashConfig = new JSONArray();
-        if (settType!= null && settType == 2) {
+        if (settType != null && settType == 2) {
             // 手动提现
             settleConfig.put("settle_status", "0");
             JSONObject cashConfigValue = new JSONObject();
@@ -785,22 +795,22 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         requestData.put("product_id", HuifuConstant.PRODUCT_ID);
         requestData.put("sign", sign);
         requestData.put("data", request);
-        System.out.println("请求体:"+ requestData);
+        System.out.println("请求体:" + requestData);
 
         String result = OkHttpClientTools.httpPost(url, requestData.toString(), HuifuConstant.PRODUCT_ID);
-        System.out.println("返回的数据:"+ result);
+        System.out.println("返回的数据:" + result);
         JSONObject jsonObject = JSONObject.parseObject(result);
         JSONObject dataObject = jsonObject.getJSONObject("data");
         String code = dataObject.getString("resp_code");
-        if(code.equals("90000000")) {
+        if (code.equals("90000000")) {
             LambdaQueryWrapper<THuifuMch> queryWrapper = new LambdaQueryWrapper<>();
-            queryWrapper.eq(THuifuMch::getAdminId,huifuMchCheck.getAdminId());
+            queryWrapper.eq(THuifuMch::getAdminId, huifuMchCheck.getAdminId());
             THuifuMch tHuifuMch = tHuifuMchService.getOne(queryWrapper);
             // 排除掉不复制的属性
-            String[] ignoreProperties = {"id", "createDate","adminId","huifuId"};
+            String[] ignoreProperties = {"id", "createDate", "adminId", "huifuId"};
             BeanUtil.copyProperties(huifuMchCheck, tHuifuMch, ignoreProperties);
             // 判断持卡人证件有效期类型,1:长期有效,0:非长期有效
-            if(huifuMchCheck.getCertValidityType().equals("0")) {
+            if (huifuMchCheck.getCertValidityType().equals("0")) {
                 LocalDate date = LocalDate.parse(huifuMchCheck.getCertEndDate(), DateTimeFormatter.ofPattern("yyyyMMdd"));
                 String certEndDate = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                 tHuifuMch.setCertDate(certEndDate);
@@ -818,7 +828,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
             tHuifuMchService.updateById(tHuifuMch);
             tHuifuMchCheckService.updateById(huifuMchCheck);
             return "success";
-        }else {
+        } else {
             String respDesc = dataObject.getString("resp_desc");
             huifuMchCheck.setStatus("3");
             huifuMchCheck.setSms(null);
@@ -831,6 +841,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
 
     /**
      * 汇付上传图片
+     *
      * @param file
      * @return
      */
@@ -892,7 +903,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         JSONObject request = new JSONObject();
         request.put("req_seq_id", HuifuUtils.initReqSeqId());
         request.put("req_date", DateTools.getCurrentDateYYYYMMDD());
-        if(StrUtil.isNotEmpty(companyType) && companyType.equals("1")) {
+        if (StrUtil.isNotEmpty(companyType) && companyType.equals("1")) {
             request.put("huifu_id", HuifuConstant.SC_DIV_HUIFU_ID);
         } else {
             request.put("huifu_id", HuifuConstant.SZ_DIV_HUIFU_ID);
@@ -911,7 +922,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         String sign = HuifuUtils.sign(s1, HuifuConstant.RSA_PRIVATE_KEY);
 
         // 公共参数
-        System.out.println("请求参数:"+ request);
+        System.out.println("请求参数:" + request);
         JSONObject requestData = new JSONObject();
         requestData.put("sys_id", HuifuConstant.SYS_ID);
         requestData.put("product_id", HuifuConstant.PRODUCT_ID);
@@ -919,7 +930,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         requestData.put("data", request);
         log.info("退款请求参数:{}", requestData);
         String success = OkHttpClientTools.httpPost(url, requestData.toString(), HuifuConstant.PRODUCT_ID);
-        System.out.println("返回的数据:"+ success);
+        System.out.println("返回的数据:" + success);
         // 拿到返回参数
         JSONObject result = JSONObject.parseObject(success);
         log.info("汇付返回参数:{}", result);
@@ -927,7 +938,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         String transStat = data.getString("trans_stat");
         String respCode = data.getString("resp_code");
         String respDesc = data.getString("resp_desc");
-        if(respCode.equals("00000000") || respCode.equals("00000100")) {
+        if (respCode.equals("00000000") || respCode.equals("00000100")) {
             return transStat;
         } else {
             return respDesc;
@@ -936,6 +947,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
 
     /**
      * 汇付发送验证码
+     *
      * @param tHuifuMch
      * @return
      * @throws Exception
@@ -958,16 +970,16 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         String sign = HuifuUtils.sign(s1, HuifuConstant.RSA_PRIVATE_KEY);
 
         // 公共参数
-        System.out.println("请求参数:"+ request);
+        System.out.println("请求参数:" + request);
         JSONObject requestData = new JSONObject();
         requestData.put("sys_id", HuifuConstant.SYS_ID);
         requestData.put("product_id", HuifuConstant.PRODUCT_ID);
         requestData.put("sign", sign);
         requestData.put("data", request);
-        System.out.println("请求体:"+ requestData);
+        System.out.println("请求体:" + requestData);
 
         String success = OkHttpClientTools.httpPost(url, requestData.toString(), HuifuConstant.PRODUCT_ID);
-        System.out.println("返回的数据:"+ success);
+        System.out.println("返回的数据:" + success);
         // 拿到返回参数
         JSONObject result = JSONObject.parseObject(success);
         log.info("汇付返回参数:{}", result);
@@ -978,6 +990,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
 
     /**
      * 汇付上传图片
+     *
      * @param base64Str
      * @return
      */
@@ -990,8 +1003,8 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         params.put("req_seq_id", SequenceTools.getReqSeqId32());
         params.put("req_date", DateTools.getCurrentDateYYYYMMDD());
         params.put("file_type", fileType);
-        if(StringUtils.isNotEmpty(huifuId)) {
-        params.put("huifu_id", huifuId);
+        if (StringUtils.isNotEmpty(huifuId)) {
+            params.put("huifu_id", huifuId);
         }
         String data = JSON.toJSONString(params);
 
@@ -1024,7 +1037,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
             }
         } catch (IOException e) {
             e.printStackTrace();
-        } finally{
+        } finally {
             tempFile.delete();
         }
         return result;
@@ -1047,20 +1060,20 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         String sign = HuifuUtils.sign(s1, HuifuConstant.RSA_PRIVATE_KEY);
 
         // 公共参数
-        System.out.println("请求参数:"+ request);
+        System.out.println("请求参数:" + request);
         JSONObject requestData = new JSONObject();
         requestData.put("sys_id", HuifuConstant.SYS_ID);
         requestData.put("product_id", HuifuConstant.PRODUCT_ID);
         requestData.put("sign", sign);
         requestData.put("data", request);
-        System.out.println("请求体:"+ requestData);
+        System.out.println("请求体:" + requestData);
 
         String success = OkHttpClientTools.httpPost(url, requestData.toString(), HuifuConstant.PRODUCT_ID);
         JSONObject result = JSONObject.parseObject(success);
         log.info("汇付返回参数:{}", result);
         JSONObject data = result.getJSONObject("data");
         String respCode = data.getString("resp_code");
-        if(respCode.equals("00000000") || respCode.equals("00000100")) {
+        if (respCode.equals("00000000") || respCode.equals("00000100")) {
             try {
                 ObjectMapper objectMapper = new ObjectMapper();
                 JsonNode rootNode = objectMapper.readTree(success);
@@ -1157,7 +1170,7 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         log.info("汇付提现返回数据:{}", result);
         JSONObject jsonObject = JSONObject.parseObject(result);
         JSONObject dataObject = jsonObject.getJSONObject("data");
-        if(dataObject.getString("resp_code").equals("00000000")) {
+        if (dataObject.getString("resp_code").equals("00000000")) {
             return jsonObject.getString("resp_desc");
         }
         return "";
@@ -1210,4 +1223,58 @@ public class THuifuMchServiceImpl extends ServiceImpl<THuifuMchMapper, THuifuMch
         }
         return balanceBo;
     }
+
+    @Override
+    public String withdraw(WithdrawalRecord withdrawalRecord, THuifuMch huifuMch) throws BasePayException {
+        // 请求接口
+        String url = "https://api.huifu.com/v2/trade/settlement/enchashment";
+        // 请求参数:Data
+        JSONObject request = new JSONObject();
+        // 请求流水号
+        String reqSeqId = SequenceTools.getReqSeqId32();
+        request.put("req_seq_id", reqSeqId);
+        // 请求日期
+        request.put("req_date", DateTools.getCurrentDateYYYYMMDD());
+        // 取现金额
+        request.put("cash_amt", withdrawalRecord.getAmount().toString());
+        // 汇付ID
+        request.put("huifu_id", huifuMch.getHuifuId());
+        // 到账日期类型
+        request.put("into_acct_date_type", "T1");
+        // 取现卡序列号
+        request.put("token_no", huifuMch.getTokenNo());
+        // 回调地址
+        request.put("notify_url", HuifuConstant.Jiesuan_Url);
+
+        // 签名:sign
+        String jsonString = JSON.toJSONString(JSONObject.parseObject(request.toString(), TreeMap.class));
+        String sign = HuifuUtils.sign(jsonString, HuifuConstant.RSA_PRIVATE_KEY);
+
+
+        // 公共参数
+        log.info("汇付提现请求参数:{}", request);
+        JSONObject requestData = new JSONObject();
+        requestData.put("sys_id", HuifuConstant.SYS_ID);
+        requestData.put("product_id", HuifuConstant.PRODUCT_ID);
+        requestData.put("sign", sign);
+        requestData.put("data", request);
+
+        String result = OkHttpClientTools.httpPost(url, requestData.toString(), HuifuConstant.PRODUCT_ID);
+        log.info("汇付提现返回数据:{}", result);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        JSONObject dataObject = jsonObject.getJSONObject("data");
+        String respCode = dataObject.getString("resp_code");
+        if (StringUtils.isNotEmpty(respCode) && respCode.equals("00000000")) {
+            String transStat = dataObject.getString("trans_stat");
+            if (StringUtils.isNotEmpty(transStat) && (transStat.equals(HuifuConstant.TRANS_STAT_S) || transStat.equals(HuifuConstant.TRANS_STAT_P))) {
+                // 申请提现成功,保存记录
+                withdrawalRecord.setCreateDate(new Date());
+                withdrawalRecord.setOrderNo(reqSeqId);
+                withdrawalRecord.setStatus(0);
+                withdrawalRecordService.save(withdrawalRecord);
+                return transStat;
+            }
+        }
+        return "";
+    }
 }