Browse Source

app支付相关

yh 1 week ago
parent
commit
08f605917a

+ 7 - 2
fs-service/pom.xml

@@ -123,7 +123,7 @@
         <dependency>
             <groupId>com.github.binarywang</groupId>
             <artifactId>weixin-java-pay</artifactId>
-            <version>4.7.2.B</version>
+            <version>4.8.0</version>
         </dependency>
         <dependency>
             <groupId>com.github.binarywang</groupId>
@@ -302,7 +302,12 @@
             <version>1.0.250</version>
         </dependency>
 
-
+        <!-- 支付宝-->
+        <dependency>
+            <groupId>com.alipay.sdk</groupId>
+            <artifactId>alipay-sdk-java</artifactId>
+            <version>4.38.0.ALL</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 21 - 0
fs-service/src/main/java/com/fs/app/service/AppPayService.java

@@ -0,0 +1,21 @@
+package com.fs.app.service;
+
+import com.fs.common.core.domain.R;
+import com.fs.his.param.FsPackageOrderDoPayParam;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+
+
+import java.util.Map;
+
+public interface AppPayService {
+
+    /**
+     * 支付宝回调
+     */
+    String aliNotify(Map<String, String> params);
+
+    /**
+     * 微信支付回调
+     */
+    String wxNotify(WxPayOrderNotifyResult result);
+}

+ 139 - 0
fs-service/src/main/java/com/fs/app/service/impl/AppPayServiceImpl.java

@@ -0,0 +1,139 @@
+package com.fs.app.service.impl;
+
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.diagnosis.DiagnosisUtils;
+import com.alipay.api.domain.AlipayTradeAppPayModel;
+import com.alipay.api.internal.util.AlipaySignature;
+import com.alipay.api.request.AlipayTradeAppPayRequest;
+import com.alipay.api.response.AlipayTradeAppPayResponse;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.fs.app.service.AppPayService;
+import com.fs.common.core.domain.R;
+import com.fs.common.exception.CustomException;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.ip.IpUtils;
+import com.fs.core.config.WxPayProperties;
+import com.fs.core.utils.OrderCodeUtils;
+import com.fs.his.domain.*;
+import com.fs.his.dto.PayConfigDTO;
+import com.fs.his.enums.FsPackageOrderStatusEnum;
+import com.fs.his.mapper.FsPackageOrderMapper;
+import com.fs.his.mapper.FsStorePaymentMapper;
+import com.fs.his.mapper.FsUserWxMapper;
+import com.fs.his.param.FsPackageOrderDoPayParam;
+import com.fs.his.service.*;
+import com.fs.huifuPay.service.HuiFuService;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.mapper.SysConfigMapper;
+import com.fs.system.service.ISysConfigService;
+import com.fs.tzBankPay.TzBankService.TzBankService;
+import com.fs.tzBankPay.doman.PayType;
+import com.fs.ybPay.domain.OrderResult;
+import com.fs.ybPay.dto.OrderQueryDTO;
+import com.fs.ybPay.service.IPayService;
+import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
+import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.google.gson.Gson;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class AppPayServiceImpl implements AppPayService {
+
+    @Autowired
+    private SysConfigMapper sysConfigMapper;
+    @Autowired
+    private IFsInquiryOrderService inquiryOrderService;
+    @Lazy
+    @Autowired
+    private IFsStoreOrderService storeOrderService;
+    @Autowired
+    private IFsPackageOrderService packageOrderService;
+
+    /**
+     * 支付宝回调
+     */
+    @Override
+    public String aliNotify(Map<String, String> params) {
+        log.info("支付宝回调参数: {}", params);
+        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+        try {
+            boolean flag = AlipaySignature.rsaCheckV1(params, fsPayConfig.getAliPublicKey(), "UTF-8","RSA2");
+            if (!flag) {
+                log.info("支付宝回调验签失败:{}", params);
+            }
+
+            String tradeStatus = params.get("trade_status");
+            if (!"TRADE_SUCCESS".equals(tradeStatus)) {
+                return "success";
+            }
+
+            String[] arr = params.get("out_trade_no").split("-");
+            String tradeNo = params.get("trade_no");
+            switch (arr[0]) {
+                case "inquiry":
+                    inquiryOrderService.payConfirm("", arr[1],"","",1,tradeNo,"");
+                    break;
+                case "store":
+                    storeOrderService.payConfirm("", arr[1],"","",1,tradeNo,"");
+                    break;
+                case "package":
+                    packageOrderService.payConfirm("", arr[1],"","",1,tradeNo,"");
+                    break;
+            }
+
+
+        } catch (Exception e) {
+            log.info("支付宝回调异常:{}", e);
+            throw new RuntimeException(e);
+        }
+
+        return "success";
+    }
+
+    @Override
+    public String wxNotify(WxPayOrderNotifyResult result) {
+        log.info("微信回调参数: {}", result);
+        if (!"SUCCESS".equals(result.getReturnCode())){
+            return WxPayNotifyResponse.success("微信回调失败");
+        }
+
+        if (!"SUCCESS".equals(result.getResultCode())){
+            return WxPayNotifyResponse.success("交易失败");
+        }
+
+        String[] tradeNoArr = result.getOutTradeNo().split("-");
+        switch (tradeNoArr[0]) {
+            case "inquiry":
+                inquiryOrderService.payConfirm("", tradeNoArr[1],"","",1,result.getTransactionId(),"");
+                break;
+            case "store":
+                storeOrderService.payConfirm("", tradeNoArr[1],"","",1,result.getTransactionId(),"");
+                break;
+            case "package":
+                packageOrderService.payConfirm("", tradeNoArr[1],"","",1,result.getTransactionId(),"");
+                break;
+        }
+        return WxPayNotifyResponse.success("OK");
+    }
+
+}

+ 11 - 0
fs-service/src/main/java/com/fs/his/domain/FsPayConfig.java

@@ -33,4 +33,15 @@ public class FsPayConfig {
     private String hfPayOnlineNotifyUrl;
     private String hfRefundNotifyUrl;
     private String hfOnlineRefundNotifyUrl;
+
+    private String aliAppId;
+    private String aliPrivateKey;
+    private String aliPublicKey;
+    private String aliNotifyUrl;
+
+    private String wxAppMchId;
+    private String wxAppMchKey;
+    private String wxAppNotifyUrl;
+    private String wxAppAppId;
+    private String wxAppKeyPath;
 }

+ 1 - 0
fs-service/src/main/java/com/fs/his/param/FsInquiryOrderDoPayParam.java

@@ -10,5 +10,6 @@ public class FsInquiryOrderDoPayParam implements Serializable {
     Long userId;
 
     private String appId;
+    private String payType;
 
 }

+ 1 - 0
fs-service/src/main/java/com/fs/his/param/FsPackageOrderDoPayParam.java

@@ -13,4 +13,5 @@ public class FsPackageOrderDoPayParam implements Serializable {
 
     private String appId;//小程序id
     private String createPackageOrderKey;
+    private String payType;
 }

+ 1 - 0
fs-service/src/main/java/com/fs/his/param/FsStoreOrderDoPayParam.java

@@ -12,4 +12,5 @@ public class FsStoreOrderDoPayParam implements Serializable {
     Long userId;
 
     private String appId;
+    private String payType;
 }

+ 3 - 1
fs-service/src/main/java/com/fs/his/service/IFsPackageOrderService.java

@@ -13,6 +13,8 @@ import com.fs.his.param.*;
 import com.fs.his.vo.*;
 import io.swagger.models.auth.In;
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * 套餐订单Service接口
  *
@@ -95,7 +97,7 @@ public interface IFsPackageOrderService
 
     Integer PackageStoreOrderRefund(Long orderId,String opeName);
 
-    R payment(FsPackageOrderDoPayParam param);
+    R payment(FsPackageOrderDoPayParam param, HttpServletRequest request);
 
     R cancel(FsPackageOrderCancelParam param);
 

+ 74 - 3
fs-service/src/main/java/com/fs/his/service/impl/FsPackageOrderServiceImpl.java

@@ -17,6 +17,12 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.diagnosis.DiagnosisUtils;
+import com.alipay.api.domain.AlipayTradeAppPayModel;
+import com.alipay.api.request.AlipayTradeAppPayRequest;
+import com.alipay.api.response.AlipayTradeAppPayResponse;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.constant.FsConstants;
@@ -74,6 +80,7 @@ import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.google.common.reflect.TypeToken;
 import com.google.gson.Gson;
+import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.error.WxErrorException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -84,12 +91,15 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * 套餐订单Service业务层处理
  *
  * @author fs
  * @date 2023-08-25
  */
+@Slf4j
 @Service
 public class FsPackageOrderServiceImpl implements IFsPackageOrderService
 {
@@ -964,7 +974,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
 
     @Override
     @Transactional
-    public R payment(FsPackageOrderDoPayParam param) {
+    public R payment(FsPackageOrderDoPayParam param, HttpServletRequest request) {
         //更新订单状态
         FsPackageOrder fsPackageOrder=fsPackageOrderMapper.selectFsPackageOrderByOrderId(param.getOrderId());
         if(!fsPackageOrder.getStatus().equals(FsPackageOrderStatusEnum.STATUS_1.getValue())){
@@ -1008,7 +1018,9 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
             }
         }
 
-        if(user!=null&& StringUtils.isNotEmpty(openId)){
+        if (user != null
+                && ( "appPay".equals(payConfigDTO.getType()) // appPay类型:跳过openId校验
+                || StringUtils.isNotEmpty(openId) )) {
             if(fsPackageOrder.getPayMoney().compareTo(new BigDecimal(0))==1){
                 String payCode =  OrderCodeUtils.getOrderSn();
                 if(StringUtils.isEmpty(payCode)){
@@ -1021,7 +1033,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 storePayment.setPayCode(payCode);
                 storePayment.setPayMoney(fsPackageOrder.getPayMoney());
                 storePayment.setCreateTime(new Date());
-                storePayment.setPayTypeCode("weixin");
+                storePayment.setPayTypeCode(!"appPay".equals(payConfigDTO.getType()) ? "weixin" : param.getPayType());
                 storePayment.setBusinessType(3);
                 storePayment.setCompanyId(fsPackageOrder.getCompanyId());
                 storePayment.setCompanyUserId(fsPackageOrder.getCompanyUserId());
@@ -1132,6 +1144,65 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                         mt.setAppId(appId);
                         storePaymentService.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "hf");
+                    } else if (payConfigDTO.getType().equals("appPay") && "wx".equals(param.getPayType())) {
+                        //创建微信订单
+                        WxPayConfig payConfig = new WxPayConfig();
+                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+                        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+                        payConfig.setAppId(appId);
+                        payConfig.setMchId(fsPayConfig.getWxAppMchId());
+                        payConfig.setMchKey(fsPayConfig.getWxAppMchKey());
+                        payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                        payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                        payConfig.setKeyPath(null);
+                        payConfig.setNotifyUrl(fsPayConfig.getWxAppNotifyUrl());
+                        wxPayService.setConfig(payConfig);
+                        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
+                        orderRequest.setBody("套餐包订单支付");
+                        orderRequest.setOutTradeNo("package-"+storePayment.getPayCode());
+                        orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));
+                        orderRequest.setTradeType("APP");
+                        orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(request));
+                        orderRequest.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
+                        //调用统一下单接口,获取"预支付交易会话标识"
+                        try {
+                            Object result = wxPayService.createOrder(orderRequest);
+                            return R.ok().put("data",result).put("type","wxApp").put("isPay",0);
+                        } catch (WxPayException e) {
+                            e.printStackTrace();
+                            throw new CustomException("支付失败"+e.getMessage());
+                        }
+                    } else if (payConfigDTO.getType().equals("appPay") && "ali".equals(param.getPayType())) {
+                        // 实例化客户端
+                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+                        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+                        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", fsPayConfig.getAliAppId(), fsPayConfig.getAliPrivateKey(), "json", "utf-8", fsPayConfig.getAliPublicKey(), "RSA2");
+
+                        // 构造请求参数以调用接口
+                        AlipayTradeAppPayRequest aliRequest = new AlipayTradeAppPayRequest();
+                        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
+                        // 商户订单号
+                        model.setOutTradeNo("package-" + storePayment.getPayCode());
+                        // 订单总金额
+                        model.setTotalAmount(storePayment.getPayMoney().toString());
+                        // 订单标题r
+                        model.setSubject("套餐包订单支付");
+
+                        aliRequest.setBizModel(model);
+                        aliRequest.setNotifyUrl(fsPayConfig.getAliNotifyUrl());
+
+                        try {
+                            AlipayTradeAppPayResponse result = alipayClient.sdkExecute(aliRequest);
+                            if (!result.isSuccess()) {
+                                String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(result);
+                                log.error("支付宝支付调用失败 诊断链接:{}", diagnosisUrl);
+                                throw new CustomException(result.getSubMsg());
+                            }
+
+                            return R.ok().put("isPay", 0).put("data", result).put("type", "aliPay");
+                        } catch (Exception e){
+                            log.info("支付宝支付异常: {}", e);
+                        }
                     }
                 }
             }

+ 76 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsStoreAfterSalesServiceImpl.java

@@ -14,6 +14,12 @@ import cn.hutool.core.util.IdUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.domain.AlipayTradeRefundModel;
+import com.alipay.api.request.AlipayTradeRefundRequest;
+import com.alipay.api.response.AlipayTradeRefundResponse;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.CustomException;
@@ -71,6 +77,7 @@ import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
 import com.github.binarywang.wxpay.config.WxPayConfig;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
+import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
 import com.google.gson.Gson;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -591,6 +598,61 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
                 } else {
                     throw new CustomException("退款请求失败" + refund.getResp_desc());
                 }
+            } else if ("appPay".equals(payment.getPayMode()) && "wx".equals(payment.getPayTypeCode())) {
+                // 处理微信退款
+                WxPayService wxPayService = getWxPayService();
+                WxPayRefundRequest refundRequest = new WxPayRefundRequest();
+                refundRequest.setOutTradeNo(orderType+"-"+payment.getPayCode());
+                refundRequest.setOutRefundNo(orderType+"-"+payment.getPayCode());
+                refundRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(payment.getPayMoney().toString()));
+                refundRequest.setRefundFee(WxPayUnifiedOrderRequest.yuanToFen(payment.getPayMoney().toString()));
+                try {
+                    WxPayRefundResult refundResult = wxPayService.refund(refundRequest);
+                    WxPayRefundQueryResult refundQueryResult = wxPayService.refundQuery("", refundResult.getOutTradeNo(), refundResult.getOutRefundNo(), refundResult.getRefundId());
+                    if (refundQueryResult != null && refundQueryResult.getResultCode().equals("SUCCESS")) {
+                        FsStorePayment paymentMap = new FsStorePayment();
+                        paymentMap.setPaymentId(payment.getPaymentId());
+                        paymentMap.setStatus(-1);
+                        paymentMap.setRefundTime(DateUtils.getNowDate());
+                        paymentMap.setRefundMoney(payment.getPayMoney());
+                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
+                    } else {
+                        throw new CustomException("退款请求失败" + refundQueryResult.getReturnMsg());
+                    }
+
+                } catch (WxPayException e) {
+                    throw new CustomException("退款请求失败" + e);
+                }
+
+            } else if ("appPay".equals(payment.getPayMode()) && "ali".equals(payment.getPayTypeCode())) {
+                // 实例化客户端
+                SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+                FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+                AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", fsPayConfig.getAliAppId(), fsPayConfig.getAliPrivateKey(), "json", "utf-8", fsPayConfig.getAliPublicKey(), "RSA2");
+                // 构造请求参数以调用接口
+                AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
+                AlipayTradeRefundModel model = new AlipayTradeRefundModel();
+                model.setOutTradeNo(orderType+"-"+payment.getPayCode());
+                model.setRefundAmount(payment.getPayMoney().toString());
+                request.setBizModel(model);
+                try {
+                    AlipayTradeRefundResponse response = alipayClient.execute(request);
+                    if (response.isSuccess()) {
+                        FsStorePayment paymentMap = new FsStorePayment();
+                        paymentMap.setPaymentId(payment.getPaymentId());
+                        paymentMap.setStatus(-1);
+                        paymentMap.setRefundTime(DateUtils.getNowDate());
+                        paymentMap.setRefundMoney(payment.getPayMoney());
+                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
+                    } else {
+//                        String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
+                        throw new CustomException("支付宝退款请求失败" + response.getSubMsg());
+                    }
+
+                } catch (AlipayApiException e) {
+                    throw new CustomException("支付宝退款请求失败" + e);
+                }
+
             }
             //管易作废
             if (StringUtils.isNotEmpty(fsStoreOrder.getExtendOrderId())) {
@@ -631,6 +693,20 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
         return i;
     }
 
+    private WxPayService getWxPayService(){
+        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+        WxPayConfig payConfig = new WxPayConfig();
+        payConfig.setAppId(fsPayConfig.getWxAppAppId());
+        payConfig.setMchId(fsPayConfig.getWxAppMchId());
+        payConfig.setMchKey(fsPayConfig.getWxAppMchKey());
+        payConfig.setKeyPath(fsPayConfig.getWxAppKeyPath());
+        payConfig.setNotifyUrl(fsPayConfig.getWxAppNotifyUrl());
+        WxPayServiceImpl payService = new WxPayServiceImpl();
+        payService.setConfig(payConfig);
+        return payService;
+    }
+
 
 
     @Override

+ 65 - 1
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -6,6 +6,12 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.diagnosis.DiagnosisUtils;
+import com.alipay.api.domain.AlipayTradeAppPayModel;
+import com.alipay.api.request.AlipayTradeAppPayRequest;
+import com.alipay.api.response.AlipayTradeAppPayResponse;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.core.domain.R;
@@ -3016,7 +3022,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 storePayment.setPayMoney(order.getPayMoney());
                 storePayment.setBusinessCode(order.getOrderCode());
                 storePayment.setCreateTime(new Date());
-                storePayment.setPayTypeCode("weixin");
+                storePayment.setPayTypeCode(!"appPay".equals(payConfigDTO.getType()) ? "weixin" : param.getPayType());
                 storePayment.setBusinessType(2);
                 storePayment.setRemark("药品订单支付");
                 storePayment.setOpenId(openId);
@@ -3115,6 +3121,64 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                         mt.setAppId(appId);
                         storePaymentService.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "hf");
+                    } else if (payConfigDTO.getType().equals("appPay") && "wx".equals(param.getPayType())) {
+                        //创建微信订单
+                        WxPayConfig payConfig = new WxPayConfig();
+                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+                        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+                        payConfig.setAppId(appId);
+                        payConfig.setMchId(fsPayConfig.getWxAppMchId());
+                        payConfig.setMchKey(fsPayConfig.getWxAppMchKey());
+                        payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                        payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                        payConfig.setKeyPath(null);
+                        payConfig.setNotifyUrl(fsPayConfig.getWxAppNotifyUrl());
+                        wxPayService.setConfig(payConfig);
+                        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
+                        orderRequest.setBody("药品订单支付");
+                        orderRequest.setOutTradeNo("store-"+storePayment.getPayCode());
+                        orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));
+                        orderRequest.setTradeType("APP");
+                        orderRequest.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
+                        //调用统一下单接口,获取"预支付交易会话标识"
+                        try {
+                            Object result = wxPayService.createOrder(orderRequest);
+                            return R.ok().put("data",result).put("type","wxApp").put("isPay",0);
+                        } catch (WxPayException e) {
+                            e.printStackTrace();
+                            throw new CustomException("支付失败"+e.getMessage());
+                        }
+                    } else if (payConfigDTO.getType().equals("appPay") && "ali".equals(param.getPayType())) {
+                        // 实例化客户端
+                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+                        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+                        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", fsPayConfig.getAliAppId(), fsPayConfig.getAliPrivateKey(), "json", "utf-8", fsPayConfig.getAliPublicKey(), "RSA2");
+
+                        // 构造请求参数以调用接口
+                        AlipayTradeAppPayRequest aliRequest = new AlipayTradeAppPayRequest();
+                        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
+                        // 商户订单号
+                        model.setOutTradeNo("store-" + storePayment.getPayCode());
+                        // 订单总金额
+                        model.setTotalAmount(storePayment.getPayMoney().toString());
+                        // 订单标题r
+                        model.setSubject("药品订单支付");
+
+                        aliRequest.setBizModel(model);
+                        aliRequest.setNotifyUrl(fsPayConfig.getAliNotifyUrl());
+
+                        try {
+                            AlipayTradeAppPayResponse result = alipayClient.sdkExecute(aliRequest);
+                            if (!result.isSuccess()) {
+                                String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(result);
+                                log.error("支付宝支付调用失败 诊断链接:{}", diagnosisUrl);
+                                throw new CustomException(result.getSubMsg());
+                            }
+
+                            return R.ok().put("isPay", 0).put("data", result).put("type", "aliPay");
+                        } catch (Exception e){
+                            log.info("支付宝支付异常: {}", e);
+                        }
                     }
 
                 } else {

+ 77 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java

@@ -16,6 +16,13 @@ import cn.hutool.core.util.IdUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.TypeReference;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.diagnosis.DiagnosisUtils;
+import com.alipay.api.domain.AlipayTradeRefundModel;
+import com.alipay.api.request.AlipayTradeRefundRequest;
+import com.alipay.api.response.AlipayTradeRefundResponse;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -664,11 +671,81 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
                 }else {
                     throw new CustomException("退款请求失败"+refund.getResp_desc());
                 }
+            } else if ("appPay".equals(fsStorePayment.getPayMode()) && "wx".equals(fsStorePayment.getPayTypeCode())) {
+                // 处理微信退款
+                WxPayService wxPayService = getWxPayService();
+                WxPayRefundRequest refundRequest = new WxPayRefundRequest();
+                refundRequest.setOutTradeNo(orderType+"-"+fsStorePayment.getPayCode());
+                refundRequest.setOutRefundNo(orderType+"-"+fsStorePayment.getPayCode());
+                refundRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(fsStorePayment.getPayMoney().toString()));
+                refundRequest.setRefundFee(WxPayUnifiedOrderRequest.yuanToFen(fsStorePayment.getPayMoney().toString()));
+                try {
+                    WxPayRefundResult refundResult = wxPayService.refund(refundRequest);
+                    WxPayRefundQueryResult refundQueryResult = wxPayService.refundQuery("", refundResult.getOutTradeNo(), refundResult.getOutRefundNo(), refundResult.getRefundId());
+                    if (refundQueryResult != null && refundQueryResult.getResultCode().equals("SUCCESS")) {
+                        FsStorePayment paymentMap = new FsStorePayment();
+                        paymentMap.setPaymentId(fsStorePayment.getPaymentId());
+                        paymentMap.setStatus(-1);
+                        paymentMap.setRefundTime(DateUtils.getNowDate());
+                        paymentMap.setRefundMoney(fsStorePayment.getPayMoney());
+                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
+                    } else {
+                        throw new CustomException("退款请求失败" + refundQueryResult.getReturnMsg());
+                    }
+
+                } catch (WxPayException e) {
+                    throw new CustomException("退款请求失败" + e);
+                }
+
+            } else if ("appPay".equals(fsStorePayment.getPayMode()) && "ali".equals(fsStorePayment.getPayTypeCode())) {
+                // 实例化客户端
+                SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+                FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+                AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", fsPayConfig.getAliAppId(), fsPayConfig.getAliPrivateKey(), "json", "utf-8", fsPayConfig.getAliPublicKey(), "RSA2");
+                // 构造请求参数以调用接口
+                AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
+                AlipayTradeRefundModel model = new AlipayTradeRefundModel();
+                model.setOutTradeNo(orderType+"-"+fsStorePayment.getPayCode());
+                model.setRefundAmount(fsStorePayment.getPayMoney().toString());
+                request.setBizModel(model);
+                try {
+                    AlipayTradeRefundResponse response = alipayClient.execute(request);
+                    if (response.isSuccess()) {
+                        FsStorePayment paymentMap = new FsStorePayment();
+                        paymentMap.setPaymentId(fsStorePayment.getPaymentId());
+                        paymentMap.setStatus(-1);
+                        paymentMap.setRefundTime(DateUtils.getNowDate());
+                        paymentMap.setRefundMoney(fsStorePayment.getPayMoney());
+                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
+                    } else {
+//                        String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
+                        throw new CustomException("支付宝退款请求失败" + response.getSubMsg());
+                    }
+
+                } catch (AlipayApiException e) {
+                    throw new CustomException("支付宝退款请求失败" + e);
+                }
+
             }
         }
         return R.ok();
     }
 
+
+    private WxPayService getWxPayService(){
+        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+        WxPayConfig payConfig = new WxPayConfig();
+        payConfig.setAppId(fsPayConfig.getWxAppAppId());
+        payConfig.setMchId(fsPayConfig.getWxAppMchId());
+        payConfig.setMchKey(fsPayConfig.getWxAppMchKey());
+        payConfig.setKeyPath(fsPayConfig.getWxAppKeyPath());
+        payConfig.setNotifyUrl(fsPayConfig.getWxAppNotifyUrl());
+        WxPayServiceImpl payService = new WxPayServiceImpl();
+        payService.setConfig(payConfig);
+        return payService;
+    }
+
     @Override
     public FsStorePayment selectFsStorePaymentByPaymentCode(String payCode) {
         return fsStorePaymentMapper.selectFsStorePaymentByPaymentCode(payCode);

+ 81 - 0
fs-user-app/src/main/java/com/fs/app/controller/AppPayController.java

@@ -0,0 +1,81 @@
+package com.fs.app.controller;
+
+
+import com.fs.app.service.AppPayService;
+import com.fs.his.domain.FsPayConfig;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.mapper.SysConfigMapper;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
+import com.google.gson.Gson;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+@Slf4j
+@Api("app支付接口")
+@RestController
+@RequestMapping("/appPay")
+public class AppPayController extends AppBaseController {
+
+    @Autowired
+    private AppPayService appPayService;
+    @Autowired
+    private SysConfigMapper sysConfigMapper;
+
+    @ApiOperation("支付宝回调")
+    @PostMapping("/aliNotify")
+    public String aliNotify(HttpServletRequest request) {
+        Map<String, String> params = new HashMap<String, String>();
+        Map requestParams = request.getParameterMap();
+        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
+            String name = (String) iter.next();
+            String[] values = (String[]) requestParams.get(name);
+            String valueStr = "";
+            for (int i = 0; i < values.length; i++) {
+                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
+            }
+            //乱码解决,这段代码在出现乱码时使用。
+            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
+            params.put(name, valueStr);
+        }
+        return appPayService.aliNotify(params);
+    }
+
+
+
+    @ApiOperation("微信支付回调")
+    @PostMapping("/wxNotify")
+    public String wxNotify(@RequestBody String xmlData) throws WxPayException {
+        WxPayService payService = getWxPayService();
+        WxPayOrderNotifyResult result = payService.parseOrderNotifyResult(xmlData);
+        return appPayService.wxNotify(result);
+    }
+
+    private WxPayService getWxPayService(){
+        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+        WxPayConfig payConfig = new WxPayConfig();
+        payConfig.setAppId(fsPayConfig.getWxAppAppId());
+        payConfig.setMchId(fsPayConfig.getWxAppMchId());
+        payConfig.setMchKey(fsPayConfig.getWxAppMchKey());
+        payConfig.setKeyPath(fsPayConfig.getWxAppKeyPath());
+        payConfig.setNotifyUrl(fsPayConfig.getWxAppNotifyUrl());
+        WxPayServiceImpl payService = new WxPayServiceImpl();
+        payService.setConfig(payConfig);
+        return payService;
+    }
+}

+ 71 - 2
fs-user-app/src/main/java/com/fs/app/controller/InquiryOrderController.java

@@ -2,6 +2,13 @@ package com.fs.app.controller;
 
 
 import cn.hutool.json.JSONUtil;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.diagnosis.DiagnosisUtils;
+import com.alipay.api.domain.AlipayTradeAppPayModel;
+import com.alipay.api.request.AlipayTradeAppPayRequest;
+import com.alipay.api.response.AlipayTradeAppPayResponse;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.app.annotation.Login;
@@ -50,6 +57,7 @@ import com.github.pagehelper.PageInfo;
 import com.google.gson.Gson;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.logging.log4j.core.LogEvent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -63,6 +71,7 @@ import java.math.BigDecimal;
 import java.util.*;
 
 
+@Slf4j
 @Api("订单接口")
 @RestController
 @RequestMapping(value="/app/inquiryOrder")
@@ -319,7 +328,7 @@ public class InquiryOrderController extends  AppBaseController {
 //            }
 //        }
 
-        if (StringUtils.isBlank(openId)){
+        if ((!"appPay".equals(payConfigDTO.getType()) && StringUtils.isBlank(openId))) {
             return R.error("用户OPENID不存在");
         }
 
@@ -341,7 +350,7 @@ public class InquiryOrderController extends  AppBaseController {
             storePayment.setBusinessCode(order.getOrderSn());
             storePayment.setPayMoney(order.getPayMoney());
             storePayment.setCreateTime(new Date());
-            storePayment.setPayTypeCode("weixin");
+            storePayment.setPayTypeCode(!"appPay".equals(payConfigDTO.getType()) ? "weixin" : param.getPayType());
             storePayment.setBusinessType(1);
             storePayment.setRemark("问诊订单支付");
             storePayment.setOpenId(openId);
@@ -441,6 +450,66 @@ public class InquiryOrderController extends  AppBaseController {
                     mt.setAppId(appId);
                     storePaymentService.updateFsStorePayment(mt);
                     return R.ok().put("isPay",0).put("data",result).put("type","hf");
+                } else if (payConfigDTO.getType().equals("appPay") && "wx".equals(param.getPayType())) {
+                    //创建微信订单
+                    WxPayConfig payConfig = new WxPayConfig();
+                    SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+                    FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+                    payConfig.setAppId(appId);
+                    payConfig.setMchId(fsPayConfig.getWxAppMchId());
+                    payConfig.setMchKey(fsPayConfig.getWxAppMchKey());
+                    payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                    payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                    payConfig.setKeyPath(null);
+                    payConfig.setNotifyUrl(fsPayConfig.getWxAppNotifyUrl());
+                    wxPayService.setConfig(payConfig);
+                    WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
+                    orderRequest.setBody("问诊订单支付");
+                    orderRequest.setOutTradeNo("inquiry-"+storePayment.getPayCode());
+                    orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));
+                    orderRequest.setTradeType("APP");
+                    orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(request));
+                    orderRequest.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
+                    //调用统一下单接口,获取"预支付交易会话标识"
+                    try {
+                        Object result = wxPayService.createOrder(orderRequest);
+                        return R.ok().put("data",result).put("type","wxApp").put("isPay",0);
+                    } catch (WxPayException e) {
+                        e.printStackTrace();
+                        throw new CustomException("支付失败"+e.getMessage());
+                    }
+                } else if (payConfigDTO.getType().equals("appPay") && "ali".equals(param.getPayType())) {
+                    // 实例化客户端
+                    SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+                    FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+                    AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", fsPayConfig.getAliAppId(), fsPayConfig.getAliPrivateKey(), "json", "utf-8", fsPayConfig.getAliPublicKey(), "RSA2");
+
+                    // 构造请求参数以调用接口
+                    AlipayTradeAppPayRequest aliRequest = new AlipayTradeAppPayRequest();
+                    AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
+                    // 商户订单号
+                    model.setOutTradeNo("package-" + storePayment.getPayCode());
+                    // 订单总金额
+                    model.setTotalAmount(storePayment.getPayMoney().toString());
+                    // 订单标题r
+                    model.setSubject("问诊订单支付");
+
+                    aliRequest.setBizModel(model);
+                    aliRequest.setNotifyUrl(fsPayConfig.getAliNotifyUrl());
+
+                    try {
+                        AlipayTradeAppPayResponse result = alipayClient.sdkExecute(aliRequest);
+                        if (!result.isSuccess()) {
+                            String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(result);
+                            log.error("支付宝支付调用失败 诊断链接:{}", diagnosisUrl);
+                            throw new CustomException(result.getSubMsg());
+                        }
+
+                        return R.ok().put("isPay", 0).put("data", result).put("type", "aliPay");
+                    } catch (Exception e){
+                        log.info("支付宝支付异常: {}", e);
+                        throw new CustomException("支付系统异常,请稍后重试");
+                    }
                 }
             }
             else{

+ 1 - 1
fs-user-app/src/main/java/com/fs/app/controller/PackageOrderController.java

@@ -78,7 +78,7 @@ public class PackageOrderController extends  AppBaseController {
     public R payment(HttpServletRequest request, @Validated @RequestBody FsPackageOrderDoPayParam param)
     {
         param.setUserId(Long.parseLong(getUserId()));
-        return packageOrderService.payment(param);
+        return packageOrderService.payment(param,request);
     }
 
     @Login