Explorar o código

支付宝回调

liweifan %!s(int64=3) %!d(string=hai) anos
pai
achega
2f5935f278

+ 0 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderRefundServiceImpl.java

@@ -272,7 +272,6 @@ public class UserOrderRefundServiceImpl extends ServiceImpl<UserOrderRefundDao,
         }
 
         return doOrderRefund(orderRefunds);
-
     }
 
 

+ 5 - 0
toolset/toolset-payment/pom.xml

@@ -60,6 +60,11 @@
             <artifactId>weixin-java-pay</artifactId>
             <version>${binarywang.weixin.java.version}</version>
         </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>2.9.2</version>
+        </dependency>
         <!-- 汇付 -->
         <dependency>
             <groupId>com.huifu.adapay</groupId>

+ 20 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/adapay/AdapayTemplate.java

@@ -31,6 +31,7 @@ import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -206,6 +207,10 @@ public class AdapayTemplate implements PaymentTemplate {
                     ExecutePaymentCallBack executePayment = new ExecutePaymentCallBack();
                     executePayment.setPayAmt(hfRes.getString("pay_amt"));
                     executePayment.setFeeAmt(hfRes.getString("fee_amt"));
+
+                    if(!StringUtil.isEmpty(hfRes.getString("created_time"))){
+                        executePayment.setTradeTime(new Date(Long.parseLong(hfRes.getString("created_time"))));
+                    }
                     paymentCallBack.setExecutePaymentCallBack(executePayment);
                 } else if (type.equals("payment.failed")) {//支付失败
                     paymentCallBack.setId(hfRes.getString("id"));
@@ -215,6 +220,9 @@ public class AdapayTemplate implements PaymentTemplate {
 
                     ExecutePaymentCallBack executePayment = new ExecutePaymentCallBack();
                     executePayment.setPayAmt(hfRes.getString("pay_amt"));
+                    if(!StringUtil.isEmpty(hfRes.getString("created_time"))){
+                        executePayment.setTradeTime(new Date(Long.parseLong(hfRes.getString("created_time"))));
+                    }
                     paymentCallBack.setExecutePaymentCallBack(executePayment);
                 } else if (type.equals("payment.close.succeeded")) {//支付关单成功
                     paymentCallBack.setId(hfRes.getString("payment_id"));
@@ -222,6 +230,9 @@ public class AdapayTemplate implements PaymentTemplate {
                     paymentCallBack.setMethodName(MethodNameEnum.closePayment);
 
                     ClosePaymentCallBack closePayment = new ClosePaymentCallBack();
+                    if(!StringUtil.isEmpty(hfRes.getString("created_time"))){
+                        closePayment.setTradeTime(new Date(Long.parseLong(hfRes.getString("created_time"))));
+                    }
                     paymentCallBack.setClosePaymentCallBack(closePayment);
                 } else if (type.equals("payment.close.failed")) {//支付关单失败
                     paymentCallBack.setId(hfRes.getString("payment_id"));
@@ -230,6 +241,9 @@ public class AdapayTemplate implements PaymentTemplate {
                     paymentCallBack.setMethodName(MethodNameEnum.closePayment);
 
                     ClosePaymentCallBack closePayment = new ClosePaymentCallBack();
+                    if(!StringUtil.isEmpty(hfRes.getString("created_time"))){
+                        closePayment.setTradeTime(new Date(Long.parseLong(hfRes.getString("created_time"))));
+                    }
                     paymentCallBack.setClosePaymentCallBack(closePayment);
                 } else if (type.equals("refund.succeeded")) {//退款成功
                     paymentCallBack.setId(hfRes.getString("payment_id"));
@@ -241,6 +255,9 @@ public class AdapayTemplate implements PaymentTemplate {
                     refundPayment.setTransNo(hfRes.getString("id"));
                     refundPayment.setRefundAmt(hfRes.getString("pay_amt"));
                     refundPayment.setFeeAmt(hfRes.getString("fee_amt"));
+                    if(!StringUtil.isEmpty(hfRes.getString("created_time"))){
+                        refundPayment.setTradeTime(new Date(Long.parseLong(hfRes.getString("created_time"))));
+                    }
                     paymentCallBack.setRefundPaymentCallBack(refundPayment);
                 } else if (type.equals("refund.failed")) {//退款失败
                     paymentCallBack.setId(hfRes.getString("payment_id"));
@@ -253,6 +270,9 @@ public class AdapayTemplate implements PaymentTemplate {
                     refundPayment.setTransNo(hfRes.getString("id"));
                     refundPayment.setRefundAmt(hfRes.getString("pay_amt"));
                     refundPayment.setFeeAmt(hfRes.getString("fee_amt"));
+                    if(!StringUtil.isEmpty(hfRes.getString("created_time"))){
+                        refundPayment.setTradeTime(new Date(Long.parseLong(hfRes.getString("created_time"))));
+                    }
                     paymentCallBack.setRefundPaymentCallBack(refundPayment);
                 }
                 return BaseResult.succeed(paymentCallBack);

+ 1 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/base/constant/PaymentConstant.java

@@ -5,4 +5,5 @@ package com.yonge.toolset.payment.base.constant;
  * @Data: 2022/5/10 15:00
  */
 public interface PaymentConstant {
+    String CHARSET = "UTF-8";
 }

+ 14 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/base/model/callback/ClosePaymentCallBack.java

@@ -1,10 +1,24 @@
 package com.yonge.toolset.payment.base.model.callback;
 
 import java.io.Serializable;
+import java.util.Date;
 
 /**
  * 关闭订单回调对象
  */
 public class ClosePaymentCallBack implements Serializable {
+    /***
+     * 交易时间
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private Date tradeTime;
 
+    public Date getTradeTime() {
+        return tradeTime;
+    }
+
+    public void setTradeTime(Date tradeTime) {
+        this.tradeTime = tradeTime;
+    }
 }

+ 16 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/base/model/callback/ExecutePaymentCallBack.java

@@ -1,6 +1,7 @@
 package com.yonge.toolset.payment.base.model.callback;
 
 import java.io.Serializable;
+import java.util.Date;
 
 /**
  * 支付方法回调对象
@@ -19,6 +20,13 @@ public class ExecutePaymentCallBack implements Serializable {
      */
     private String feeAmt;
 
+    /***
+     * 交易时间
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private Date tradeTime;
+
     public String getPayAmt() {
         return payAmt;
     }
@@ -34,4 +42,12 @@ public class ExecutePaymentCallBack implements Serializable {
     public void setFeeAmt(String feeAmt) {
         this.feeAmt = feeAmt;
     }
+
+    public Date getTradeTime() {
+        return tradeTime;
+    }
+
+    public void setTradeTime(Date tradeTime) {
+        this.tradeTime = tradeTime;
+    }
 }

+ 15 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/base/model/callback/RefundPaymentCallBack.java

@@ -1,6 +1,7 @@
 package com.yonge.toolset.payment.base.model.callback;
 
 import java.io.Serializable;
+import java.util.Date;
 
 /**
  * 退款返回对象
@@ -22,6 +23,12 @@ public class RefundPaymentCallBack implements Serializable {
      * 退款手续费(单位:元)
      */
     private String feeAmt;
+    /***
+     * 交易时间
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private Date tradeTime;
 
     public String getBillNo() {
         return billNo;
@@ -54,4 +61,12 @@ public class RefundPaymentCallBack implements Serializable {
     public void setFeeAmt(String feeAmt) {
         this.feeAmt = feeAmt;
     }
+
+    public Date getTradeTime() {
+        return tradeTime;
+    }
+
+    public void setTradeTime(Date tradeTime) {
+        this.tradeTime = tradeTime;
+    }
 }

+ 195 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/core/util/RequestKitBean.java

@@ -0,0 +1,195 @@
+package com.yonge.toolset.payment.core.util;
+
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.payment.original.wx.OriginalWxAppTemplate;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Iterator;
+import java.util.Map;
+
+/*
+ * 基于spring的 req 工具类
+ *
+ * @author terrfly
+ * @site https://www.jeequan.com
+ * @date 2021/6/7 12:16
+ */
+@Component
+public class RequestKitBean {
+
+    private final static Logger log = LoggerFactory.getLogger(RequestKitBean.class);
+
+    @Autowired(required = false)
+    protected HttpServletRequest request;   //自动注入request
+
+    /**
+     * reqContext对象中的key: 转换好的json对象
+     */
+    private static final String REQ_CONTEXT_KEY_PARAMJSON = "REQ_CONTEXT_KEY_PARAMJSON";
+
+    /**
+     * JSON 格式通过请求主体(BODY)传输  获取参数
+     **/
+    public String getReqParamFromBody() {
+
+        String body = "";
+
+        if (isConvertJSON()) {
+
+            try {
+                String str;
+                while ((str = request.getReader().readLine()) != null) {
+                    body += str;
+                }
+
+                return body;
+
+            } catch (Exception e) {
+                log.error("请求参数转换异常! params=[{}]", body);
+                throw new BizException("转换异常");
+            }
+        } else {
+            return body;
+        }
+    }
+
+
+    /**
+     * request.getParameter 获取参数 并转换为JSON格式
+     **/
+    public JSONObject reqParam2JSON() {
+
+        JSONObject returnObject = new JSONObject();
+
+        if (isConvertJSON()) {
+
+            String body = "";
+            try {
+                String str;
+                while ((str = request.getReader().readLine()) != null) {
+                    body += str;
+                }
+
+                if (StringUtils.isEmpty(body)) {
+                    return returnObject;
+                }
+                return JSONObject.parseObject(body);
+
+            } catch (Exception e) {
+                log.error("请求参数转换异常! params=[{}]", body);
+                throw new BizException("转换异常");
+            }
+        }
+
+        // 参数Map
+        Map properties = request.getParameterMap();
+
+        // 返回值Map
+        Iterator entries = properties.entrySet().iterator();
+        Map.Entry entry;
+        String name;
+        String value = "";
+        while (entries.hasNext()) {
+            entry = (Map.Entry) entries.next();
+            name = (String) entry.getKey();
+            Object valueObj = entry.getValue();
+            if (null == valueObj) {
+                value = "";
+            } else if (valueObj instanceof String[]) {
+                String[] values = (String[]) valueObj;
+                for (int i = 0; i < values.length; i++) {
+                    value = values[i] + ",";
+                }
+                value = value.substring(0, value.length() - 1);
+            } else {
+                value = valueObj.toString();
+            }
+
+            if (!name.contains("[")) {
+                returnObject.put(name, value);
+                continue;
+            }
+            //添加对json对象解析的支持  example: {ps[abc] : 1}
+            String mainKey = name.substring(0, name.indexOf("["));
+            String subKey = name.substring(name.indexOf("[") + 1, name.indexOf("]"));
+            JSONObject subJson = new JSONObject();
+            if (returnObject.get(mainKey) != null) {
+                subJson = (JSONObject) returnObject.get(mainKey);
+            }
+            subJson.put(subKey, value);
+            returnObject.put(mainKey, subJson);
+        }
+        return returnObject;
+
+    }
+
+
+    /**
+     * 获取json格式的请求参数
+     **/
+    public JSONObject getReqParamJSON() {
+
+        //将转换好的reqParam JSON格式的对象保存在当前请求上下文对象中进行保存;
+        // 注意1: springMVC的CTRL默认单例模式, 不可使用局部变量保存,会出现线程安全问题;
+        // 注意2: springMVC的请求模式为线程池,如果采用ThreadLocal保存对象信息,可能会出现不清空或者被覆盖的问题。
+        Object reqParamObject = RequestContextHolder.getRequestAttributes().getAttribute(REQ_CONTEXT_KEY_PARAMJSON, RequestAttributes.SCOPE_REQUEST);
+        if (reqParamObject == null) {
+            JSONObject reqParam = reqParam2JSON();
+            RequestContextHolder.getRequestAttributes().setAttribute(REQ_CONTEXT_KEY_PARAMJSON, reqParam, RequestAttributes.SCOPE_REQUEST);
+            return reqParam;
+        }
+        return (JSONObject) reqParamObject;
+    }
+
+    /**
+     * 判断请求参数是否转换为json格式
+     */
+    private boolean isConvertJSON() {
+
+        String contentType = request.getContentType();
+
+        //有contentType  && json格式,  get请求不转换
+        if (contentType != null
+                && contentType.toLowerCase().indexOf("application/json") >= 0
+                && !request.getMethod().equalsIgnoreCase("GET")
+        ) { //application/json 需要转换为json格式;
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * 获取客户端ip地址
+     **/
+    public String getClientIp() {
+        String ipAddress = null;
+        ipAddress = request.getHeader("x-forwarded-for");
+        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getHeader("Proxy-Client-IP");
+        }
+        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getRemoteAddr();
+        }
+
+        // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
+        if (ipAddress != null && ipAddress.length() > 15) {
+            if (ipAddress.indexOf(",") > 0) {
+                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
+            }
+        }
+        return ipAddress;
+    }
+
+}

+ 117 - 10
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/original/ali/OriginalAliAppTemplate.java

@@ -3,6 +3,7 @@ package com.yonge.toolset.payment.original.ali;
 import com.alibaba.fastjson.JSONObject;
 import com.alipay.api.AlipayApiException;
 import com.alipay.api.AlipayClient;
+import com.alipay.api.internal.util.AlipaySignature;
 import com.alipay.api.request.AlipayTradeAppPayRequest;
 import com.alipay.api.request.AlipayTradeCloseRequest;
 import com.alipay.api.request.AlipayTradeQueryRequest;
@@ -13,25 +14,35 @@ import com.alipay.api.response.AlipayTradeQueryResponse;
 import com.alipay.api.response.AlipayTradeRefundResponse;
 import com.yonge.toolset.base.result.BaseResult;
 import com.yonge.toolset.payment.base.PaymentTemplate;
+import com.yonge.toolset.payment.base.constant.PaymentConstant;
 import com.yonge.toolset.payment.base.enums.MethodNameEnum;
 import com.yonge.toolset.payment.base.enums.OpenEnum;
 import com.yonge.toolset.payment.base.enums.PayChannelEnum;
 import com.yonge.toolset.payment.base.enums.TradeStatusEnum;
 import com.yonge.toolset.payment.base.model.*;
+import com.yonge.toolset.payment.base.model.callback.ClosePaymentCallBack;
+import com.yonge.toolset.payment.base.model.callback.ExecutePaymentCallBack;
 import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
+import com.yonge.toolset.payment.base.model.callback.RefundPaymentCallBack;
 import com.yonge.toolset.payment.core.props.PaymentProperties;
 import com.yonge.toolset.payment.core.service.SysConfigPaymentService;
+import com.yonge.toolset.payment.core.util.RequestKitBean;
+import com.yonge.toolset.payment.original.ali.constant.AlipayConstant;
+import com.yonge.toolset.utils.date.DateUtil;
+import com.yonge.toolset.utils.string.StringUtil;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.math.BigDecimal;
+import java.util.*;
 
 @Component
 public class OriginalAliAppTemplate implements PaymentTemplate {
@@ -44,6 +55,12 @@ public class OriginalAliAppTemplate implements PaymentTemplate {
     @Autowired
     private AlipayClient alipayClient;
 
+    @Autowired
+    private SysConfigPaymentService configPaymentService;
+
+    @Autowired
+    private RequestKitBean requestKitBean;
+
     @Override
     public BaseResult<Map<String, Object>> getOpenAuthMsg(OpenAuth openAuth) {
         return null;
@@ -108,13 +125,13 @@ public class OriginalAliAppTemplate implements PaymentTemplate {
                 payment.setPayAmt(response.getPayAmount());
                 //获取交易状态
                 String tradeStatus = response.getTradeStatus();
-                if("WAIT_BUYER_PAY".equals(tradeStatus)){
+                if ("WAIT_BUYER_PAY".equals(tradeStatus)) {
                     payment.setStatus(TradeStatusEnum.pending);
-                }else if("TRADE_CLOSED".equals(tradeStatus)){
+                } else if ("TRADE_CLOSED".equals(tradeStatus)) {
                     payment.setStatus(TradeStatusEnum.succeeded);
-                }else if("TRADE_SUCCESS".equals(tradeStatus)){
+                } else if ("TRADE_SUCCESS".equals(tradeStatus)) {
                     payment.setStatus(TradeStatusEnum.succeeded);
-                }else if("TRADE_FINISHED".equals(tradeStatus)){
+                } else if ("TRADE_FINISHED".equals(tradeStatus)) {
                     payment.setStatus(TradeStatusEnum.succeeded);
                 }
                 return BaseResult.succeed(payment);
@@ -132,7 +149,7 @@ public class OriginalAliAppTemplate implements PaymentTemplate {
 
     @Override
     public BaseResult<ClosePayment> closePayment(ClosePayment closePayment) {
-        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest ();
+        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
 
         JSONObject bizContent = new JSONObject();
         bizContent.put("trade_no", closePayment.getId());
@@ -186,8 +203,98 @@ public class OriginalAliAppTemplate implements PaymentTemplate {
         }
     }
 
+
     @Override
     public BaseResult<PaymentCallBack> analysisNotice(OpenEnum openType, PayChannelEnum payChannel, MethodNameEnum methodName, HttpServletRequest request) {
-        return null;
+        PaymentCallBack paymentCallBack = new PaymentCallBack();
+        try {
+            JSONObject params = requestKitBean.getReqParamJSON();
+
+            JSONObject jsonParams = (JSONObject) params;
+
+            //获取验签方式 是否使用证书 YES NO
+            String USE_CERT = configPaymentService.getPaymentConfig(OpenEnum.ORIGINAL, AlipayConstant.ALI_USE_CERT).getParamValue();
+            String ALI_SIGN_TYPE = configPaymentService.getPaymentConfig(OpenEnum.ORIGINAL, AlipayConstant.ALI_SIGN_TYPE).getParamValue();
+            String ALI_ALIPAY_PUBLIC_KEY = configPaymentService.getPaymentConfig(OpenEnum.ORIGINAL, AlipayConstant.ALI_ALIPAY_PUBLIC_KEY).getParamValue();
+            String CERT_PATH = configPaymentService.getPaymentConfig(OpenEnum.ORIGINAL, AlipayConstant.ALI_CERT_PATH).getParamValue();
+
+            boolean verifyResult;
+            if ("YES".equals(USE_CERT)) {
+                verifyResult = AlipaySignature.rsaCertCheckV1(jsonParams.toJavaObject(Map.class), CERT_PATH,
+                        PaymentConstant.CHARSET, ALI_SIGN_TYPE);
+            } else {
+                verifyResult = AlipaySignature.rsaCheckV1(jsonParams.toJavaObject(Map.class), ALI_ALIPAY_PUBLIC_KEY, PaymentConstant.CHARSET, ALI_SIGN_TYPE);
+            }
+            //验签失败
+            if (!verifyResult) {
+                return BaseResult.failed(HttpStatus.INTERNAL_SERVER_ERROR, paymentCallBack, "验签失败");
+            }
+
+            paymentCallBack.setId(jsonParams.getString("trade_no"));
+            paymentCallBack.setPaymentNo(params.getString("out_trade_no"));
+
+            //获取订单所处交易状态
+            String trade_status = jsonParams.getString("trade_status");
+            //退款单号
+            String refundNo = jsonParams.getString("out_biz_no");
+
+            paymentCallBack.setStatus(TradeStatusEnum.succeeded);
+            //退款
+            if (!StringUtil.isEmpty(refundNo)
+                    || null != jsonParams.getBigDecimal("refund_fee")) {
+                paymentCallBack.setMethodName(MethodNameEnum.refundPayment);
+                //退款成功
+                RefundPaymentCallBack refundPayment = new RefundPaymentCallBack();
+                refundPayment.setBillNo(refundNo);
+                refundPayment.setTransNo(refundNo);
+
+                refundPayment.setRefundAmt(jsonParams.getString("refund_fee"));
+                refundPayment.setTradeTime(jsonParams.getDate("gmt_refund"));
+            } else {
+
+                if ("TRADE_CLOSED".equals(trade_status)) {
+                    //关单成功
+                    paymentCallBack.setMethodName(MethodNameEnum.closePayment);
+
+                    ClosePaymentCallBack closePayment = new ClosePaymentCallBack();
+                    closePayment.setTradeTime(jsonParams.getDate("gmt_close"));
+                    paymentCallBack.setClosePaymentCallBack(closePayment);
+                } else {
+                    //支付成功
+                    paymentCallBack.setMethodName(MethodNameEnum.executePayment);
+
+                    ExecutePaymentCallBack executePayment = new ExecutePaymentCallBack();
+                    String total_amount = jsonParams.getString("total_amount");
+                    String receipt_amount = jsonParams.getString("receipt_amount");
+
+                    executePayment.setPayAmt(total_amount);
+                    executePayment.setFeeAmt(sub(total_amount, receipt_amount));
+                    executePayment.setTradeTime(jsonParams.getDate("gmt_payment"));
+                    paymentCallBack.setExecutePaymentCallBack(executePayment);
+                }
+            }
+            return BaseResult.succeed(paymentCallBack);
+        } catch (AlipayApiException e) {
+            return BaseResult.failed(HttpStatus.INTERNAL_SERVER_ERROR, paymentCallBack, "微信回调对象转换失败");
+        } catch (Exception e) {
+            return BaseResult.failed(HttpStatus.INTERNAL_SERVER_ERROR, paymentCallBack, "解析异常");
+        }
+    }
+
+    /**
+     * v1-v2
+     *
+     * @param v1
+     * @param v2
+     * @return
+     */
+    private String sub(String v1, String v2) {
+        try {
+            String s = new BigDecimal(v1).subtract(new BigDecimal(v2)).toString();
+            return s;
+        } catch (Exception e) {
+            return null;
+        }
     }
+
 }

+ 14 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/original/ali/constant/AlipayConstant.java

@@ -30,6 +30,7 @@ public interface AlipayConstant {
      * @updateTime 2022/5/12 14:12
      */
     String ALI_ALIPAY_PUBLIC_KEY = "ALI_ALIPAY_PUBLIC_KEY";
+
     /***
      * 支付宝-验签方式
      * @author liweifan
@@ -37,6 +38,19 @@ public interface AlipayConstant {
      */
     String ALI_SIGN_TYPE = "ALI_SIGN_TYPE";
     /***
+     * 支付宝-是否使用证书 YES NO
+     * @author liweifan
+     * @updateTime 2022/5/12 14:12
+     */
+    String ALI_USE_CERT = "ALI_USE_CERT";
+    /***
+     * 支付宝-证书地址
+     * @author liweifan
+     * @updateTime 2022/5/12 14:12
+     */
+    String ALI_CERT_PATH = "ALI_CERT_PATH";
+
+    /***
      * 支付宝-接口内容加密密钥
      * @author liweifan
      * @updateTime 2022/5/12 14:12

+ 64 - 6
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/original/wx/OriginalWxAppTemplate.java

@@ -19,11 +19,14 @@ import com.yonge.toolset.payment.base.model.ClosePayment;
 import com.yonge.toolset.payment.base.model.OpenAuth;
 import com.yonge.toolset.payment.base.model.Payment;
 import com.yonge.toolset.payment.base.model.RefundBill;
+import com.yonge.toolset.payment.base.model.callback.ExecutePaymentCallBack;
 import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
+import com.yonge.toolset.payment.base.model.callback.RefundPaymentCallBack;
 import com.yonge.toolset.payment.core.props.PaymentProperties;
 import com.yonge.toolset.payment.core.service.SysConfigPaymentService;
 import com.yonge.toolset.payment.original.wx.constant.WxpayConstant;
 import com.yonge.toolset.utils.collection.MapUtil;
+import com.yonge.toolset.utils.date.DateUtil;
 import com.yonge.toolset.utils.obj.ObjectUtil;
 import com.yonge.toolset.utils.string.StringUtil;
 import com.yonge.toolset.utils.web.WebUtil;
@@ -35,6 +38,8 @@ import org.apache.http.client.utils.URIBuilder;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.util.EntityUtils;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -44,8 +49,10 @@ import org.springframework.stereotype.Component;
 import javax.servlet.http.HttpServletRequest;
 import java.io.ByteArrayOutputStream;
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.TimeZone;
 
 @Component
 public class OriginalWxAppTemplate implements PaymentTemplate {
@@ -213,30 +220,81 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
         header.setSignature(request.getHeader("Wechatpay-Signature"));
 
         String params = WebUtil.getBodyData(request);
+
         PaymentCallBack paymentCallBack = new PaymentCallBack();
+        paymentCallBack.setMethodName(methodName);
 
-        Map<String,Object> resMsg = new HashMap<>();
+        Map<String, Object> resMsg = new HashMap<>();
         try {
             if (MethodNameEnum.executePayment.equals(methodName)) {
                 WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = wxPayService.parseOrderNotifyV3Result(params, header);
                 //封装支付回调对象
+                WxPayOrderNotifyV3Result.DecryptNotifyResult result = wxPayOrderNotifyV3Result.getResult();
+                paymentCallBack.setId(result.getTransactionId());
+                paymentCallBack.setPaymentNo(result.getOutTradeNo());
+
+                String tradeState = result.getTradeState();
+                if ("SUCCESS".equals(tradeState)) {
+                    paymentCallBack.setStatus(TradeStatusEnum.succeeded);
+                } else if ("NOTPAY".equals(tradeState) || "CLOSED".equals(tradeState) || "REFUND".equals(tradeState)) {
+                    paymentCallBack.setStatus(TradeStatusEnum.close);
+                    paymentCallBack.setErrMsg(result.getTradeStateDesc());
+                } else if ("PAYERROR".equals(tradeState)) {
+                    paymentCallBack.setStatus(TradeStatusEnum.failed);
+                    paymentCallBack.setErrMsg(result.getTradeStateDesc());
+                }
+
+                ExecutePaymentCallBack executePayment = new ExecutePaymentCallBack();
+                if(!StringUtil.isEmpty(result.getAmount().getTotal())){
+                    executePayment.setPayAmt(new BigDecimal(result.getAmount().getTotal()).divide(new BigDecimal("100")).toString());
+                }
+                if(!StringUtil.isEmpty(result.getSuccessTime())){
+                    Date date = new DateTime(result.getSuccessTime()).toDate();
+                    executePayment.setTradeTime(date);
+                }
+                paymentCallBack.setExecutePaymentCallBack(executePayment);
             } else if (MethodNameEnum.refundPayment.equals(methodName)) {
                 WxPayRefundNotifyV3Result wxPayRefundNotifyV3Result = wxPayService.parseRefundNotifyV3Result(params, header);
                 //封装退款回调对象
+                WxPayRefundNotifyV3Result.DecryptNotifyResult result = wxPayRefundNotifyV3Result.getResult();
+                paymentCallBack.setId(result.getTransactionId());
+                paymentCallBack.setPaymentNo(result.getOutTradeNo());
+
+                String refundStatus = result.getRefundStatus();
+                if ("SUCCESS".equals(refundStatus)) {
+                    paymentCallBack.setStatus(TradeStatusEnum.succeeded);
+                } else if ("CLOSED".equals(refundStatus)) {
+                    paymentCallBack.setStatus(TradeStatusEnum.close);
+                    paymentCallBack.setErrMsg("退款关闭");
+                } else if ("ABNORMAL".equals(refundStatus)) {
+                    paymentCallBack.setStatus(TradeStatusEnum.failed);
+                    paymentCallBack.setErrMsg("退款失败");
+                }
+
+                RefundPaymentCallBack refundPayment = new RefundPaymentCallBack();
+                refundPayment.setBillNo(result.getOutRefundNo());
+                refundPayment.setTransNo(result.getRefundId());
+                refundPayment.setRefundAmt(result.getAmount().getRefund());
+
+                if(!StringUtil.isEmpty(result.getSuccessTime())){
+                    Date date = new DateTime(result.getSuccessTime()).toDate();
+                    refundPayment.setTradeTime(date);
+                }
+                paymentCallBack.setRefundPaymentCallBack(refundPayment);
             }
-            resMsg.put("code","SUCCESS");
+            resMsg.put("code", "SUCCESS");
             paymentCallBack.setResMsg(resMsg);
             return BaseResult.succeed(paymentCallBack);
         } catch (WxPayException e) {
-            resMsg.put("code","FAIL");
-            resMsg.put("message","失败");
+            resMsg.put("code", "FAIL");
+            resMsg.put("message", "失败");
             paymentCallBack.setResMsg(resMsg);
             log.error("微信回调对象转换失败, param is {} , err is {}", params, e.toString());
             return BaseResult.failed(HttpStatus.INTERNAL_SERVER_ERROR, paymentCallBack, "微信回调对象转换失败");
         } catch (Exception e) {
             e.printStackTrace();
-            resMsg.put("code","FAIL");
-            resMsg.put("message","失败");
+            resMsg.put("code", "FAIL");
+            resMsg.put("message", "失败");
             paymentCallBack.setResMsg(resMsg);
             return BaseResult.failed(HttpStatus.INTERNAL_SERVER_ERROR, paymentCallBack, "解析异常");
         }