Pārlūkot izejas kodu

feat(store): 添加支付退款功能并优化收款码获取逻辑

- 实现微信和支付宝退款接口,支持汇付和小雨点支付模式- 增加退款金额校验和交易状态检查-优化公司收款码缓存键,增加 appId 参数支持多应用
- 引入支付宝 SDK 依赖,完善支付配置和签名验证
- 添加事务管理确保退款操作的数据一致性
- 补充退款日志记录和异常处理机制
xw 2 nedēļas atpakaļ
vecāks
revīzija
0c59954592

+ 6 - 0
fs-company/pom.xml

@@ -112,6 +112,12 @@
             <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
             <version>3.1.0</version>
         </dependency>
+        <dependency>
+            <groupId>com.alipay.sdk</groupId>
+            <artifactId>alipay-sdk-java</artifactId>
+            <version>4.13.45.ALL</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 
     <build>

+ 144 - 16
fs-company/src/main/java/com/fs/hisStore/controller/FsStorePaymentScrmController.java

@@ -1,32 +1,43 @@
 package com.fs.hisStore.controller;
 
-import java.util.List;
-
+import cn.hutool.json.JSONUtil;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.domain.AlipayTradeRefundModel;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ParseUtils;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.controller.pay.bean.AliPayBean;
+import com.fs.company.service.ICompanyService;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.service.TokenService;
 import com.fs.hisStore.domain.FsStorePaymentScrm;
 import com.fs.hisStore.param.FsStorePaymentParam;
 import com.fs.hisStore.service.IFsStorePaymentScrmService;
 import com.fs.hisStore.vo.FsStorePaymentVO;
-import org.springframework.security.access.prepost.PreAuthorize;
+import com.fs.huifuPay.domain.HuiFuRefundResult;
+import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
+import com.fs.huifuPay.service.HuiFuService;
+import com.ijpay.alipay.AliPayApi;
+import com.ijpay.alipay.AliPayApiConfig;
+import com.ijpay.alipay.AliPayApiConfigKit;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import com.fs.common.annotation.Log;
-import com.fs.common.core.controller.BaseController;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.enums.BusinessType;
-import com.fs.common.core.page.TableDataInfo;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.web.bind.annotation.*;
+
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 支付明细Controller
@@ -42,6 +53,14 @@ public class FsStorePaymentScrmController extends BaseController
     private IFsStorePaymentScrmService fsStorePaymentService;
     @Autowired
     private TokenService tokenService;
+    @Autowired
+    private AliPayBean aliPayBean;
+
+    @Autowired
+    private ICompanyService companyService;
+
+    @Autowired
+    HuiFuService huiFuService;
     /**
      * 查询支付明细列表
      */
@@ -141,4 +160,113 @@ public class FsStorePaymentScrmController extends BaseController
         List<FsStorePaymentVO> list = fsStorePaymentService.selectFsMyStorePaymentListQueryVO(fsStorePayment);
         return getDataTable(list);
     }
+
+    @PreAuthorize("@ss.hasPermi('store:storePayment:refund')")
+    @PostMapping("refundStorePayment")
+    @Transactional
+    public R refundStorePayment(@RequestBody FsStorePaymentScrm fsStorePayment)
+    {
+        FsStorePaymentScrm payment=fsStorePaymentService.selectFsStorePaymentById(fsStorePayment.getPaymentId());
+        if(payment.getStatus()!=1){
+            return R.error("非法操作");
+        }
+        if(fsStorePayment.getRefundMoney().compareTo(new BigDecimal(0))<1){
+            return R.error("退款金额必须大于0");
+        }
+        if(payment.getPayMoney().compareTo(fsStorePayment.getRefundMoney())==-1){
+            return R.error("退款金额必须小于等于付款金额");
+        }
+        if(payment.getPayTypeCode().equals("weixin")){
+
+            if (payment.getPayMode()!=null&&payment.getPayMode().equals("hf")){
+                V2TradePaymentScanpayRefundRequest request = new V2TradePaymentScanpayRefundRequest();
+                request.setOrdAmt(payment.getPayMoney().toString());
+                request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
+                request.setReqSeqId("refund-"+payment.getPayCode());
+                Map<String, Object> extendInfoMap = new HashMap<>();
+                extendInfoMap.put("org_party_order_id", payment.getBankSerialNo());
+                request.setExtendInfo(extendInfoMap);
+                HuiFuRefundResult refund = huiFuService.refund(request);
+                logger.info("退款:"+refund);
+                if((refund.getResp_code().equals("00000000")||refund.getResp_code().equals("00000100"))&&(refund.getTrans_stat().equals("S")||refund.getTrans_stat().equals("P"))){
+                    payment.setRefundMoney(fsStorePayment.getRefundMoney());
+                    payment.setStatus(-1);
+                    payment.setRefundTime(new Date());
+                    fsStorePaymentService.updateFsStorePayment(payment);
+                    //收款 减去所有
+                    if(payment.getCompanyId()!=null&&payment.getCompanyId()>0){
+                        companyService.subCompanyPaymentMoney(payment);
+                    }
+                    return R.ok();
+                }else {
+                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                    return R.error(refund.getResp_desc());
+                }
+
+            }else if (payment.getPayMode()!=null&&payment.getPayMode().equals("wx")){
+
+            }
+
+            //小雨点退款
+//            payment.setRefundMoney(fsStorePayment.getRefundMoney());
+//            fsStorePaymentService.updateFsStorePayment(payment);
+//
+//            RefundDTO refundDTO=new RefundDTO();
+//            refundDTO.setMerchOrderNo(Ids.oid());
+//            refundDTO.setAmount(fsStorePayment.getRefundMoney().toString());
+//            refundDTO.setOrigMerchOrderNo("payment-"+payment.getPayCode());
+//            return payService.refundOrder(refundDTO);
+        }
+        else if(payment.getPayTypeCode().equals("alipay")){
+            try {
+                AliPayApiConfig aliPayApiConfig;
+                try {
+                    aliPayApiConfig = AliPayApiConfigKit.getApiConfig(aliPayBean.getAppId());
+                } catch (Exception e) {
+                    aliPayApiConfig = AliPayApiConfig.builder()
+                            .setAppId(aliPayBean.getAppId())
+                            .setAliPayPublicKey(aliPayBean.getPublicKey())
+                            .setAppCertPath(aliPayBean.getAppCertPath())
+                            .setAliPayCertPath(aliPayBean.getAliPayCertPath())
+                            .setAliPayRootCertPath(aliPayBean.getAliPayRootCertPath())
+                            .setCharset("UTF-8")
+                            .setPrivateKey(aliPayBean.getPrivateKey())
+                            .setServiceUrl(aliPayBean.getServerUrl())
+                            .setSignType("RSA2")
+                            // 普通公钥方式
+                            .build();
+                    // 证书模式
+//					.buildByCert();
+                }
+                AliPayApiConfigKit.putApiConfig(aliPayApiConfig);
+                AlipayTradeRefundModel model = new AlipayTradeRefundModel();
+                model.setOutTradeNo("payment-"+payment.getPayCode());
+                model.setTradeNo(payment.getTradeNo());
+                model.setRefundAmount(fsStorePayment.getRefundMoney().toString());
+                model.setRefundReason("退款");
+                String result= AliPayApi.tradeRefundToResponse(model).getBody();
+                cn.hutool.json.JSONObject json= JSONUtil.parseObj(result);
+                cn.hutool.json.JSONObject jsonInfo= (cn.hutool.json.JSONObject) json.get("alipay_trade_refund_response");
+                String code=(String)jsonInfo.get("code");
+                String msg=(String)jsonInfo.get("sub_msg");
+                //{"alipay_trade_refund_response":{"code":"10000","msg":"Success","buyer_logon_id":"270***@qq.com","buyer_user_id":"2088402776950529","fund_change":"Y","gmt_refund_pay":"2022-04-27 18:27:28","out_trade_no":"goods-202204271826530001","refund_fee":"0.10","send_back_fee":"0.00","trade_no":"2022042722001450521456255417"},"sign":"hU+dy17/juMYQEQpO7Yy7jxkx9h5ebSbN3xdZr58msfOfJEUknqra6w4L37pgoZSx1Vj00jK3Ds06vrph6mSEliq3PQ37PwbZiRK3ZHaaKlz+9ndjoBTFYAxP60zLASfTq+W+dczDq4KOrvwhprFGt7YwKXGU42PgfOPb5EOgWyYUP6ivP0r06OzTo0f2lB28w6AQ4m4IQjdIL/tWbDaKl+ld8MPMLIgw5k9BmMcP8LV8ENC6+Gl1u5GwgAMjwHfk0RfB/kTFTHUTa7fgaO22w3pT8YKFMnOdKA0cVuJ2LE4SdxepqlprWJdCtLOeoQUX6PkEtoJGywPWAyjgdJ6Pg=="}
+                if(code.equals("10000")){
+                    payment.setRefundMoney(fsStorePayment.getRefundMoney());
+                    fsStorePaymentService.updateFsStorePayment(payment);
+                    fsStorePaymentService.refund(payment.getPayCode());
+                    return R.ok("退款成功");
+
+                }
+                else{
+                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                    return R.error("退款失败:"+msg);
+
+                }
+                //退款成功
+            } catch (AlipayApiException e) {
+                e.printStackTrace();
+            }
+        }
+        return R.error("非法操作");
+    }
 }

+ 2 - 3
fs-user-app/src/main/java/com/fs/app/controller/store/CompanyUserScrmController.java

@@ -11,7 +11,6 @@ import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.exception.CustomException;
 import com.fs.common.utils.sign.Md5Utils;
-import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.domain.CompanyUserCard;
 import com.fs.company.param.CompanyUserLoginParam;
@@ -176,9 +175,9 @@ public class CompanyUserScrmController extends AppBaseController {
 
     @ApiOperation("获取公司收款码")
     @GetMapping("/getCompanyWxaCodeByPayment")
-    public R getCompanyWxaCodeByPayment(@RequestParam("companyId")Long companyId,HttpServletRequest request){
+    public R getCompanyWxaCodeByPayment(@RequestParam("companyId")Long companyId, @RequestParam("appId") String appId,HttpServletRequest request){
         //获取用户码
-        String WxaCode = redisCache.getCacheObject("company-wxa-code:"+companyId);
+        String WxaCode = redisCache.getCacheObject("company-wxa-code:"+companyId +":"+appId);
         return R.ok().put("data",WxaCode);
     }