fulonglong 3 лет назад
Родитель
Сommit
c10d76004f

+ 7 - 0
src/main/java/com/charging/chargingparking/entity/ParkingInfo.java

@@ -71,8 +71,12 @@ public class ParkingInfo implements Serializable {
      * 燃油车是否能进场
      */
     private Boolean oilCarEnable = true;
+
+    @TableField(exist = false)
     private String oilCarEnableN;
+    @TableField(exist = false)
     private Integer oilCarFreeTime;
+    @TableField(exist = false)
     private BigDecimal oilCarCost;
 
 
@@ -80,8 +84,11 @@ public class ParkingInfo implements Serializable {
      * 新能车是否能进场
      */
     private Boolean newEnergyCarEnable = true;
+    @TableField(exist = false)
     private String newEnergyCarEnableN;
+    @TableField(exist = false)
     private Integer newEnergyCarTime;
+    @TableField(exist = false)
     private BigDecimal newEnergyCarCost;
 
     /**

+ 10 - 0
src/main/java/com/charging/chargingparking/entity/ParkingPay.java

@@ -67,6 +67,16 @@ public class ParkingPay implements Serializable {
      */
     private String codePayType;
 
+    /**
+     * 是否要分账(0:不分账,1:要分账)
+     */
+    private Boolean profitNeedFlag = false;
+
+    /**
+     * 分账结果(fail:失败,success:成功)
+     */
+    private String profitResult;
+
     /**
      * 是否删除
      */

+ 46 - 4
src/main/java/com/charging/chargingparking/modules/pay/wechat/WxPayController.java

@@ -9,14 +9,12 @@ import com.charging.chargingparking.dto.AccessToken;
 import com.charging.chargingparking.dto.MessageResult;
 import com.charging.chargingparking.dto.ParkingCostDTO;
 import com.charging.chargingparking.dto.UserInfo;
+import com.charging.chargingparking.entity.ParkingMerchant;
 import com.charging.chargingparking.entity.ParkingPay;
 import com.charging.chargingparking.entity.ParkingRecord;
 import com.charging.chargingparking.modules.pay.properties.WxPayProperties;
 import com.charging.chargingparking.modules.vo.ProfitVo;
-import com.charging.chargingparking.service.ParkingFeeService;
-import com.charging.chargingparking.service.ParkingPayProfitService;
-import com.charging.chargingparking.service.ParkingPayService;
-import com.charging.chargingparking.service.ParkingRecordService;
+import com.charging.chargingparking.service.*;
 import com.charging.chargingparking.utils.Sign;
 import com.charging.chargingparking.utils.StringUtils;
 import com.charging.chargingparking.utils.WeixinUtil;
@@ -63,6 +61,9 @@ public class WxPayController {
     @Autowired
     private ParkingPayProfitService parkingPayProfitService;
 
+    @Autowired
+    private ParkingMerchantService parkingMerchantService;
+
 
     /**
      * 停车微信JSAPI支付
@@ -114,6 +115,12 @@ public class WxPayController {
             parkingPayService.save(parkingPay);
 
             ProfitVo profitVo = parkingPayProfitService.getProfitVo(parkingPay);
+            String profitSharing = "N";
+            if (profitVo.getProfitFlag()){
+                parkingPay.setProfitNeedFlag(true);
+                parkingPayService.updateById(parkingPay);
+                profitSharing = "Y";
+            }
 
             Map<String, String> params = UnifiedOrderModel
                     .builder()
@@ -131,6 +138,7 @@ public class WxPayController {
                     .notify_url(wxPayProperties.getNotifyUrl())
                     .trade_type(TradeType.JSAPI.getTradeType())
                     .sub_openid(parkingPay.getOpenId())
+                    .profit_sharing(profitSharing)
                     .build()
                     .createSign(wxPayProperties.getMchKey(), SignType.HMACSHA256);
 
@@ -304,4 +312,38 @@ public class WxPayController {
     }
 
 
+    /**
+     * 添加分账接收方
+     */
+    @PostMapping(value = "/profitSharingAddReceiver")
+    public String profitSharingAddReceiver(String merchantId) {
+        try {
+
+            ParkingMerchant parkingMerchant = parkingMerchantService.getById(merchantId);
+
+            ReceiverModel receiver = ReceiverModel.builder()
+                    .type("MERCHANT_ID")
+                    .account(wxPayProperties.getSubMchId())
+                    .relation_type("SERVICE_PROVIDER")
+                    .build();
+
+            Map<String, String> params = ProfitSharingModel.builder()
+                    .sub_mch_id(parkingMerchant.getSubMchId())
+                    .appid(wxPayProperties.getAppId())
+                    .sub_appid(wxPayProperties.getSubAppId())
+                    .nonce_str(WxPayKit.generateStr())
+                    .receiver(JSONObject.toJSONString(receiver))
+                    .build()
+                    .createSign(wxPayProperties.getMchKey(), SignType.HMACSHA256);
+            log.info("请求参数:{}", WxPayKit.toXml(params));
+            String result = WxPayApi.profitSharingAddReceiver(params);
+            log.info("请求结果:{}", result);
+            return JSONObject.toJSONString(WxPayKit.xmlToMap(result));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
 }

+ 3 - 0
src/main/java/com/charging/chargingparking/modules/vo/ProfitVo.java

@@ -14,6 +14,9 @@ public class ProfitVo {
     //分账出资账户
     private String subMchId;
 
+    //出资商户
+    private String merchantName;
+
     //是否要分账
     private Boolean profitFlag;
 

+ 28 - 0
src/main/java/com/charging/chargingparking/modules/vo/ReceiverVo.java

@@ -0,0 +1,28 @@
+package com.charging.chargingparking.modules.vo;
+
+import lombok.Data;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2022/6/16 0016 下午 4:26
+ */
+@Data
+public class ReceiverVo {
+    private Integer amount;
+
+    private String description;
+
+    private String type;
+
+    private String account;
+
+    private String result;
+
+    private String detail_id;
+
+    private String fail_reason;
+
+    private String create_time;
+
+    private String finish_time;
+}

+ 2 - 0
src/main/java/com/charging/chargingparking/service/ParkingPayProfitService.java

@@ -11,4 +11,6 @@ import com.charging.chargingparking.modules.vo.ProfitVo;
 public interface ParkingPayProfitService extends IService<ParkingPayProfit> {
 
     ProfitVo getProfitVo(ParkingPay parkingPay);
+
+    void profitPay(ParkingPay parkingPay);
 }

+ 103 - 14
src/main/java/com/charging/chargingparking/service/impl/ParkingPayProfitServiceImpl.java

@@ -1,24 +1,38 @@
 package com.charging.chargingparking.service.impl;
 
+import cn.hutool.core.convert.Convert;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.charging.chargingparking.entity.*;
+import com.charging.chargingparking.modules.pay.properties.WxPayProperties;
 import com.charging.chargingparking.modules.vo.ProfitVo;
-import com.charging.chargingparking.service.ParkingInfoService;
-import com.charging.chargingparking.service.ParkingMerchantService;
-import com.charging.chargingparking.service.ParkingPayProfitService;
+import com.charging.chargingparking.modules.vo.ReceiverVo;
+import com.charging.chargingparking.service.*;
 import com.charging.chargingparking.mapper.ParkingPayProfitMapper;
-import com.charging.chargingparking.service.ParkingRecordService;
+import com.ijpay.core.enums.SignType;
+import com.ijpay.core.kit.WxPayKit;
+import com.ijpay.wxpay.WxPayApi;
+import com.ijpay.wxpay.model.ProfitSharingModel;
+import com.ijpay.wxpay.model.ReceiverModel;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
 /**
  *
  */
 @Service
 @Slf4j
 public class ParkingPayProfitServiceImpl extends ServiceImpl<ParkingPayProfitMapper, ParkingPayProfit>
-    implements ParkingPayProfitService{
+        implements ParkingPayProfitService {
 
     @Autowired
     private ParkingRecordService parkingRecordService;
@@ -26,6 +40,12 @@ public class ParkingPayProfitServiceImpl extends ServiceImpl<ParkingPayProfitMap
     @Autowired
     private ParkingInfoService parkingInfoService;
 
+    @Autowired
+    private ParkingPayService parkingPayService;
+
+    @Autowired
+    private WxPayProperties wxPayProperties;
+
     @Autowired
     private ParkingMerchantService parkingMerchantService;
 
@@ -35,28 +55,97 @@ public class ParkingPayProfitServiceImpl extends ServiceImpl<ParkingPayProfitMap
         ProfitVo profitVo = new ProfitVo();
         profitVo.setProfitFlag(false);
 
-        try{
+        try {
             ParkingRecord parkingRecord = parkingRecordService.getById(parkingPay.getParkingRecordId());
             //停车场
             ParkingInfo parkingInfo = parkingInfoService.getById(parkingRecord.getParkId());
             //商户
             ParkingMerchant parkingMerchant = parkingMerchantService.getById(parkingInfo.getMerchantId());
-            if (parkingMerchant.getProfitFlag()){
-                profitVo.setProfitFlag(true);
-                profitVo.setProfitScale(parkingMerchant.getProfitScale());
-
+            if (parkingMerchant.getProfitFlag()) {
+
+                //待分账金额
+                BigDecimal waitProfitAmount = parkingPay.getPayAmount().multiply(parkingMerchant.getProfitScale()).setScale(2, RoundingMode.DOWN);
+
+                //分账金额大于0才有分账意义
+                if (waitProfitAmount.compareTo(BigDecimal.ZERO) > 0) {
+                    profitVo.setProfitFlag(true);
+                    profitVo.setProfitScale(parkingMerchant.getProfitScale());
+                    if (parkingPay.getPayStatus() == 20) {
+                        profitVo.setSubMchId(parkingMerchant.getSubMchId());
+                        profitVo.setProfitAmount(waitProfitAmount);
+                        profitVo.setTransactionId(parkingPay.getTransactionNo());
+                        profitVo.setOutOrderNo(parkingPay.getOutOrderNo());
+                        profitVo.setDescription("分账金来自:" + parkingMerchant.getMerchantName());
+                    }
+                }
 
             }
 
-
-        }catch (Exception ex){
-            log.error(ex.getMessage(),ex);
+        } catch (Exception ex) {
+            log.error(ex.getMessage(), ex);
         }
 
 
-
         return profitVo;
     }
+
+    @Override
+    public void profitPay(ParkingPay parkingPay) {
+        try {
+
+            if (parkingPay.getProfitNeedFlag()) {
+                ProfitVo profitVo = getProfitVo(parkingPay);
+                List<ReceiverModel> list = new ArrayList<>();
+                list.add(ReceiverModel.builder()
+                        .type("MERCHANT_ID")
+                        .account(wxPayProperties.getSubMchId())
+                        .amount(Convert.toInt(profitVo.getProfitAmount().multiply(new BigDecimal(100))))
+                        .description(profitVo.getDescription())
+                        .build());
+
+                Map<String, String> params = ProfitSharingModel.builder()
+                        .sub_mch_id(profitVo.getSubMchId())
+                        .appid(wxPayProperties.getAppId())
+                        .nonce_str(WxPayKit.generateStr())
+                        .transaction_id(profitVo.getTransactionId())
+                        .out_order_no(profitVo.getOutOrderNo())
+                        .receivers(JSONObject.toJSONString(list))
+                        .build()
+                        .createSign(wxPayProperties.getMchKey(), SignType.HMACSHA256);
+
+                log.warn("请求分账参数:{}", WxPayKit.toXml(params));
+                String result = WxPayApi.profitSharing(params, wxPayProperties.getCertPath(), wxPayProperties.getMchId());
+                log.warn("请求分账结果:{}", result);
+                Map<String, String> resultMap = WxPayKit.xmlToMap(result);
+                if ("FINISHED".equals(resultMap.get("state"))){
+                    parkingPay.setProfitResult("success");
+                }else {
+                    parkingPay.setProfitResult("fail");
+                }
+                parkingPayService.updateById(parkingPay);
+
+                String re  = JSONObject.toJSONString(resultMap.get("receivers"));
+                List<ReceiverVo> receiverVoList = JSONArray.parseArray(re,ReceiverVo.class);
+
+                ParkingPayProfit parkingPayProfit = new ParkingPayProfit();
+                parkingPayProfit.setParkingPayId(parkingPay.getId());
+                parkingPayProfit.setFundingSourceMchId(profitVo.getSubMchId());
+                parkingPayProfit.setProfitTotalAmount(parkingPay.getPayAmount());
+                parkingPayProfit.setProfitScale(profitVo.getProfitScale());
+                parkingPayProfit.setProfitMchId(wxPayProperties.getSubMchId());
+                parkingPayProfit.setProfitAmount(profitVo.getProfitAmount());
+                parkingPayProfit.setProfitTime(new Date());
+                parkingPayProfit.setProfitOrderId(resultMap.get("order_id"));
+
+                //   return JSONObject.toJSONString(WxPayKit.xmlToMap(result));
+
+            }
+
+
+        } catch (Exception ex) {
+            log.error(ex.getMessage(), ex);
+        }
+    }
 }
 
 

+ 9 - 0
src/main/java/com/charging/chargingparking/service/impl/ParkingPayServiceImpl.java

@@ -6,6 +6,7 @@ import com.charging.chargingparking.entity.ParkingMember;
 import com.charging.chargingparking.entity.ParkingPay;
 import com.charging.chargingparking.entity.ParkingRecord;
 import com.charging.chargingparking.modules.common.dto.Sort;
+import com.charging.chargingparking.service.ParkingPayProfitService;
 import com.charging.chargingparking.service.ParkingPayService;
 import com.charging.chargingparking.mapper.ParkingPayMapper;
 import com.charging.chargingparking.service.ParkingRecordService;
@@ -34,6 +35,9 @@ public class ParkingPayServiceImpl extends ServiceImpl<ParkingPayMapper, Parking
     @Autowired
     private ParkingPayMapper parkingPayMapper;
 
+    @Autowired
+    private ParkingPayProfitService parkingPayProfitService;
+
     @Override
     public void saveAndUpdateRecord(String outTradeNo, Date payTime, BigDecimal buyerPayAmount,String openId,String transactionNo,String payName) throws Exception {
         QueryWrapper<ParkingPay> parkingPayQueryWrapper = new QueryWrapper<>();
@@ -59,6 +63,11 @@ public class ParkingPayServiceImpl extends ServiceImpl<ParkingPayMapper, Parking
         }
         parkingRecord.setPayAmount(parkingRecord.getPayAmount().add(buyerPayAmount));
         parkingRecordService.updateById(parkingRecord);
+
+        //分账
+        parkingPayProfitService.profitPay(parkingPay);
+
+
     }
 
     @Override

+ 1 - 2
src/main/resources/mapper/ParkingInfoMapper.xml

@@ -34,8 +34,7 @@
     <insert id="insert" parameterType="com.charging.chargingparking.entity.ParkingInfo">
         <![CDATA[
 		insert into base_parking_info
-	    (id,merchant_id,park_uname,park_key,password_,company_name,parking_name,pic_url,charging_free_duration,oil_car_enable,
-	        new_energy_car_enable,del_flag,create_by,create_time,update_by,update_time,address_)
+	    (id,merchant_id,park_uname,park_key,password_,company_name,parking_name,pic_url,charging_free_duration,oil_car_enable,new_energy_car_enable,del_flag,create_by,create_time,update_by,update_time,address_)
 		values
 		(
 			#{id,jdbcType=VARCHAR}

+ 3 - 1
src/main/resources/mapper/ParkingPayMapper.xml

@@ -15,6 +15,8 @@
             <result property="payTime" column="pay_time" jdbcType="TIMESTAMP"/>
             <result property="openId" column="open_id" jdbcType="VARCHAR"/>
             <result property="codePayType" column="code_pay_type" jdbcType="VARCHAR"/>
+            <result property="profitNeedFlag" column="profit_need_flag" jdbcType="BIT"/>
+            <result property="profitResult" column="profit_result" jdbcType="VARCHAR"/>
             <result property="delFlag" column="del_flag" jdbcType="BIT"/>
             <result property="createBy" column="create_by" jdbcType="VARCHAR"/>
             <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
@@ -25,7 +27,7 @@
     <sql id="Base_Column_List">
         id,parking_record_id,pay_amount,
         out_order_no,transaction_no,pay_status,pay_name,
-        pay_time,open_id,code_pay_type,del_flag,create_by,
+        pay_time,open_id,code_pay_type,profit_need_flag,profit_result,del_flag,create_by,
         create_time,update_by,update_time
     </sql>
     <select id="findOneByParam" parameterType="hashmap" resultMap="BaseResultMap">