Просмотр исходного кода

优化代码加入退费逻辑

java110 лет назад: 4
Родитель
Сommit
62ebf29387

+ 9 - 0
java110-bean/src/main/java/com/java110/dto/onlinePay/OnlinePayDto.java

@@ -15,6 +15,15 @@ import java.util.Date;
  **/
 public class OnlinePayDto extends PageDto implements Serializable {
 
+    //状态 W待支付 C 支付完成 F 通知失败 WT 待退费 CT退费完成
+    public static final String STATE_WAIT = "W";
+    public static final String STATE_PAY_FAIL = "PF"; // 支付失败
+    public static final String STATE_COMPILE = "C";
+    public static final String STATE_FAIL = "F";
+    public static final String STATE_WT = "WT"; // 待退费
+    public static final String STATE_CT = "CT"; // 退费完成
+    public static final String STATE_FT = "FT"; // 退费失败
+
     private String refundFee;
     private String mchId;
     private String orderId;

+ 4 - 3
java110-db/src/main/resources/mapper/acct/OnlinePayV1ServiceDaoImplMapper.xml

@@ -79,9 +79,7 @@
         <if test="mchId !=null and mchId != ''">
             , t.mch_id= #{mchId}
         </if>
-        <if test="orderId !=null and orderId != ''">
-            , t.order_id= #{orderId}
-        </if>
+
         <if test="totalFee !=null and totalFee != ''">
             , t.total_fee= #{totalFee}
         </if>
@@ -107,6 +105,9 @@
         <if test="payId !=null and payId != ''">
             and t.pay_id= #{payId}
         </if>
+        <if test="orderId !=null and orderId != ''">
+            and t.order_id= #{orderId}
+        </if>
 
     </update>
 

+ 3 - 0
java110-db/src/main/resources/mapper/store/SmallWeChatServiceDaoImplMapper.xml

@@ -173,6 +173,9 @@
         <if test="objId !=null and objId != ''">
             and t.obj_id= #{objId}
         </if>
+        <if test="mchId !=null and mchId != ''">
+            and t.mch_id= #{mchId}
+        </if>
         order by t.create_time desc
         <if test="page != -1 and page != null ">
             limit #{page}, #{row}

+ 214 - 0
service-job/src/main/java/com/java110/job/adapt/fee/ReturnPayFeeMoneyAdapt.java

@@ -0,0 +1,214 @@
+package com.java110.job.adapt.fee;
+
+import com.alibaba.fastjson.JSONObject;
+import com.java110.core.client.FtpUploadTemplate;
+import com.java110.core.client.OssUploadTemplate;
+import com.java110.dto.file.FileDto;
+import com.java110.dto.onlinePay.OnlinePayDto;
+import com.java110.dto.smallWeChat.SmallWeChatDto;
+import com.java110.entity.order.Business;
+import com.java110.intf.acct.IOnlinePayV1InnerServiceSMO;
+import com.java110.intf.fee.IReturnPayFeeInnerServiceSMO;
+import com.java110.intf.order.IOrderInnerServiceSMO;
+import com.java110.intf.store.ISmallWeChatInnerServiceSMO;
+import com.java110.job.adapt.DatabusAdaptImpl;
+import com.java110.po.onlinePay.OnlinePayPo;
+import com.java110.utils.cache.MappingCache;
+import com.java110.utils.constant.WechatConstant;
+import com.java110.utils.util.BeanConvertUtil;
+import com.java110.utils.util.OSSUtil;
+import com.java110.utils.util.PayUtil;
+import com.java110.utils.util.StringUtil;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContexts;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import javax.net.ssl.SSLContext;
+import java.io.ByteArrayInputStream;
+import java.security.KeyStore;
+import java.util.*;
+
+/**
+ * 退费审核通过后 通知 银联支付平台退款处理
+ *
+ * @author fqz
+ * @Date 2021-08-19 10:12
+ */
+@Component(value = "returnPayFeeMoneyAdapt")
+public class ReturnPayFeeMoneyAdapt extends DatabusAdaptImpl {
+
+    @Autowired
+    private IReturnPayFeeInnerServiceSMO returnPayFeeInnerServiceSMOImpl;
+
+    @Autowired
+    private IOrderInnerServiceSMO orderInnerServiceSMOImpl;
+
+    @Autowired
+    private IOnlinePayV1InnerServiceSMO onlinePayV1InnerServiceSMOImpl;
+
+
+    @Autowired
+    private ISmallWeChatInnerServiceSMO smallWeChatInnerServiceSMOImpl;
+
+
+    @Autowired
+    private RestTemplate outRestTemplate;
+
+    public static final String wechatReturnUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
+
+    private static Logger logger = LoggerFactory.getLogger(ReturnPayFeeMoneyAdapt.class);
+
+    @Autowired
+    private FtpUploadTemplate ftpUploadTemplate;
+
+    @Autowired
+    private OssUploadTemplate ossUploadTemplate;
+
+
+    @Override
+    public void execute(Business business, List<Business> businesses) {
+        JSONObject data = business.getData();
+        OnlinePayPo oaWorkflowDataPo = BeanConvertUtil.covertBean(data, OnlinePayPo.class);
+
+        try {
+            doPayFeeMoney(oaWorkflowDataPo);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     * 通知退款
+     *
+     * @param oaWorkflowDataPo
+     */
+    public void doPayFeeMoney(OnlinePayPo oaWorkflowDataPo) throws Exception {
+
+        //查询小区信息
+        OnlinePayDto onlinePayDto = new OnlinePayDto();
+        onlinePayDto.setPayId(oaWorkflowDataPo.getPayId());
+        onlinePayDto.setState(OnlinePayDto.STATE_WT);
+        List<OnlinePayDto> onlinePayDtos = onlinePayV1InnerServiceSMOImpl.queryOnlinePays(onlinePayDto);
+
+        if (onlinePayDtos == null || onlinePayDtos.size() < 1) {
+            return;
+        }
+
+        String payPassword = "";
+        String certData = "";
+
+        SmallWeChatDto smallWeChatDto = new SmallWeChatDto();
+        smallWeChatDto.setMchId(onlinePayDtos.get(0).getMchId());
+        smallWeChatDto.setAppId(onlinePayDtos.get(0).getAppId());
+        List<SmallWeChatDto> smallWeChatDtos = smallWeChatInnerServiceSMOImpl.querySmallWeChats(smallWeChatDto);
+        if (smallWeChatDto == null || smallWeChatDtos.size() <= 0) {
+            payPassword = MappingCache.getValue(WechatConstant.WECHAT_DOMAIN, "key");
+            certData = MappingCache.getRemark(WechatConstant.WECHAT_DOMAIN, "cert");
+        } else {
+            payPassword = smallWeChatDtos.get(0).getPayPassword();
+            certData = smallWeChatDtos.get(0).getRemarks();
+
+        }
+
+        SortedMap<String, String> parameters = new TreeMap<String, String>();
+        parameters.put("appid", onlinePayDtos.get(0).getAppId());//appid
+        parameters.put("mch_id", onlinePayDtos.get(0).getMchId());//商户号
+        parameters.put("nonce_str", PayUtil.makeUUID(32));//随机数
+        parameters.put("out_trade_no", onlinePayDtos.get(0).getMchId());//商户订单号
+        parameters.put("out_refund_no", onlinePayDtos.get(0).getPayId());//我们自己设定的退款申请号,约束为UK
+        parameters.put("total_fee", PayUtil.moneyToIntegerStr(Double.parseDouble(onlinePayDtos.get(0).getTotalFee())));//订单金额 单位为分!!!这里稍微注意一下
+        parameters.put("refund_fee", PayUtil.moneyToIntegerStr(Double.parseDouble(onlinePayDtos.get(0).getRefundFee())));//退款金额 单位为分!!!
+        parameters.put("sign", PayUtil.createSign(parameters, payPassword));
+        String xmlData = PayUtil.mapToXml(parameters);
+
+
+        KeyStore keyStore = KeyStore.getInstance("PKCS12");
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(getPkcs12(certData));
+        try {
+            //这里写密码..默认是你的MCHID
+            keyStore.load(inputStream, onlinePayDtos.get(0).getMchId().toCharArray());
+        } finally {
+            inputStream.close();
+        }
+
+        SSLContext sslcontext = SSLContexts.custom()
+                //这里也是写密码的
+                .loadKeyMaterial(keyStore, onlinePayDtos.get(0).getMchId().toCharArray())
+                .build();
+        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
+                sslcontext,
+                SSLConnectionSocketFactory.getDefaultHostnameVerifier());
+        CloseableHttpClient httpclient = HttpClients.custom()
+                .setSSLSocketFactory(sslsf)
+                .build();
+        String jsonStr = "";
+        try {
+            HttpPost httpost = new HttpPost(wechatReturnUrl);
+            httpost.setEntity(new StringEntity(xmlData, "UTF-8"));
+            CloseableHttpResponse response = httpclient.execute(httpost);
+            try {
+                HttpEntity entity = response.getEntity();
+                //接受到返回信息
+                jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
+                EntityUtils.consume(entity);
+            } finally {
+                response.close();
+            }
+        } finally {
+            httpclient.close();
+        }
+
+        Map<String, String> resMap = PayUtil.xmlStrToMap(jsonStr);
+
+        if ("SUCCESS".equals(resMap.get("return_code")) && "SUCCESS".equals(resMap.get("result_code"))) {
+            doUpdateOnlinePay(onlinePayDtos.get(0).getOrderId(), OnlinePayDto.STATE_CT, "退款完成");
+        } else {
+            doUpdateOnlinePay(onlinePayDtos.get(0).getOrderId(), OnlinePayDto.STATE_FT, resMap.get("return_msg"));
+        }
+
+    }
+
+    private void doUpdateOnlinePay(String orderId, String state, String message) {
+        OnlinePayPo onlinePayPo = new OnlinePayPo();
+        onlinePayPo.setMessage(message.length() > 1000 ? message.substring(0, 1000) : message);
+        onlinePayPo.setOrderId(orderId);
+        onlinePayPo.setState(state);
+        onlinePayV1InnerServiceSMOImpl.updateOnlinePay(onlinePayPo);
+    }
+
+    private byte[] getPkcs12(String fileName) {
+        List<FileDto> fileDtos = new ArrayList<>();
+
+        byte[] context = null;
+        String ftpPath = MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_PATH);
+
+        String ossSwitch = MappingCache.getValue(OSSUtil.DOMAIN, OSSUtil.OSS_SWITCH);
+        if (StringUtil.isEmpty(ossSwitch) || !OSSUtil.OSS_SWITCH_OSS.equals(ossSwitch)) {
+            String ftpServer = MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_SERVER);
+            int ftpPort = Integer.parseInt(MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_PORT));
+            String ftpUserName = MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_USERNAME);
+            String ftpUserPassword = MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_USERPASSWORD);
+            context = ftpUploadTemplate.downFileByte(ftpPath, fileName, ftpServer,
+                    ftpPort, ftpUserName,
+                    ftpUserPassword);
+        } else {
+            context = ossUploadTemplate.downFileByte(ftpPath, fileName, "",
+                    0, "",
+                    "");
+        }
+
+        return context;
+    }
+}