Selaa lähdekoodia

账户资金变动+ 支付回调

wulei 3 kuukautta sitten
vanhempi
commit
bb037d2acd

+ 40 - 0
snowy-common/src/main/java/vip/xiaonuo/common/util/CommonCouponGeneratorUtil.java

@@ -0,0 +1,40 @@
+package vip.xiaonuo.common.util;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.UUID;
+
+/**
+ * @author wulei
+ * @date 2025/2/7
+ * @Version 1.0
+ * @Description 优惠券编码唯一生成器
+ */
+public class CommonCouponGeneratorUtil {
+    public static String generateCouponCode() {
+        try {
+            // 生成 UUID 作为输入
+            String input = UUID.randomUUID().toString();
+            // 使用 MD5 哈希算法
+            MessageDigest digest = MessageDigest.getInstance("MD5");
+            byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
+            // 将哈希值转换为十六进制字符串
+            StringBuilder sb = new StringBuilder();
+            for (byte b : hash) {
+                sb.append(String.format("%02X", b));
+            }
+            return "BBT-" + sb.substring(0, 12); // 取前 10 位
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("MD5 算法不可用", e);
+        }
+    }
+
+
+    public static void main(String[] args) {
+        for (int i = 0; i < 20; i++) {
+            System.out.println("生成的优惠券编码: " + generateCouponCode());
+        }
+
+    }
+}

+ 4 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rebaterecord/entity/BizRebateRecord.java

@@ -45,6 +45,10 @@ public class BizRebateRecord extends CommonEntity {
     @Schema(description = "推荐人")
     private String recommendUserId;
 
+    /** 充值记录id */
+    @Schema(description = "充值记录id")
+    private String rechargeRecordId;
+
     /** 充值人 */
     @Schema(description = "充值人")
     private String rechargeUserId;

+ 1 - 2
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/rechargerecord/controller/BizRechargeRecordController.java

@@ -74,8 +74,7 @@ public class BizRechargeRecordController {
     @PostMapping("/biz/rechargerecord/add")
     @CommonNoRepeat
     public CommonResult<Map<String, Object>> add(@RequestBody @Valid BizRechargeRecordAddParam bizRechargeRecordAddParam) {
-        bizRechargeRecordService.add(bizRechargeRecordAddParam);
-        return CommonResult.ok();
+        return CommonResult.data( bizRechargeRecordService.add(bizRechargeRecordAddParam));
     }
 
 //    /**

+ 38 - 11
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/wx/WxPayNotifyController.java

@@ -14,10 +14,14 @@ import com.wechat.pay.java.service.partnerpayments.app.model.Transaction;
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletRequest;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionStatus;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.support.DefaultTransactionDefinition;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RestController;
 import vip.xiaonuo.biz.api.BizUserApi;
+import vip.xiaonuo.biz.core.enums.FundChangeTypeEnum;
 import vip.xiaonuo.biz.modular.couponrecord.entity.BizCouponRecord;
 import vip.xiaonuo.biz.modular.couponrecord.service.BizCouponRecordService;
 import vip.xiaonuo.biz.modular.rebaterecord.entity.BizRebateRecord;
@@ -27,13 +31,22 @@ import vip.xiaonuo.biz.modular.rechargerecord.service.BizRechargeRecordService;
 import vip.xiaonuo.biz.modular.user.entity.BizUser;
 import vip.xiaonuo.biz.modular.user.mapper.BizUserMapper;
 import vip.xiaonuo.biz.modular.user.service.BizUserService;
+import vip.xiaonuo.biz.modular.userfundchangerecord.entity.BizUserFundChangeRecord;
+import vip.xiaonuo.biz.modular.userfundchangerecord.service.BizUserFundChangeRecordService;
+import vip.xiaonuo.common.util.CommonCouponGeneratorUtil;
 import vip.xiaonuo.common.wx.HttpServletUtils;
 import vip.xiaonuo.sys.api.SysUserApi;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.time.Instant;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ThreadLocalRandom;
 
 /**
  * @author wulei
@@ -55,6 +68,10 @@ public class WxPayNotifyController {
     private BizCouponRecordService bizCouponRecordService;
     @Resource
     private BizRebateRecordService bizRebateRecordService;
+    @Resource
+    private BizUserFundChangeRecordService bizUserFundChangeRecordService;
+    @Resource
+    private PlatformTransactionManager transactionManager;
 
     /**
      * 微信支付回调通知
@@ -64,9 +81,10 @@ public class WxPayNotifyController {
      * @throws Exception
      */
     @PostMapping("/biz/wx/notify")
-    @Transactional(rollbackFor = Exception.class)
-    public synchronized String payNotify(HttpServletRequest request) throws Exception {
+    public synchronized String payNotify(HttpServletRequest request) {
+        TransactionStatus transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());
         log.info("------收到支付通知------");
+        log.info("request ========: {}", request);
         // 请求头Wechatpay-Signature
         String signature = request.getHeader("Wechatpay-Signature");
         // 请求头Wechatpay-nonce
@@ -98,7 +116,7 @@ public class WxPayNotifyController {
             log.info("验签成功!-支付回调结果:{}", transaction.toString());
             //实际支付金额
             BigDecimal realPayAmount = new BigDecimal(transaction.getAmount().getPayerTotal()).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
-            //修改订单前,建议主动请求微信查询订单是否支付成功,防止恶意post
+            //查询充值记录数据
             BizRechargeRecord bizRechargeRecord = bizRechargeRecordService.getOne(new LambdaQueryWrapper<BizRechargeRecord>().eq(BizRechargeRecord::getOrderNo, transaction.getOutTradeNo()));
             if (ObjectUtil.isNull(bizRechargeRecord)) {
                 log.info("未查询到系统订单编号所关联的充值记录:{}========", transaction.getOutTradeNo());
@@ -111,18 +129,18 @@ public class WxPayNotifyController {
                 return JSONObject.toJSONString(returnMap);
             }
             // 查询用户信息
-            log.info("=========== 更新用户账户余额 ========");
             BizUser bizUser = bizUserMapper.selectById(bizRechargeRecord.getUserId());
             if (ObjectUtil.isNull(bizUser)) {
                 log.info("未查询到用户信息:{}========", bizRechargeRecord.getUserId());
                 return JSONObject.toJSONString(returnMap);
             }
+            log.info("=========== 更新用户:{},账户余额 ========", bizUser.getName());
             bizRechargeRecord.setOldAccountBalance(bizUser.getAccountBalance());
             bizRechargeRecord.setOldVoucherBalance(bizUser.getVoucherBalance());
             //计算新金额
             if (ObjectUtil.isNotEmpty(bizRechargeRecord.getRechargePlanId())) {
                 //有充值计划
-                bizUser.setAccountBalance( bizUser.getAccountBalance().add(bizRechargeRecord.getPlanAccountBalance()));
+                bizUser.setAccountBalance(bizUser.getAccountBalance().add(bizRechargeRecord.getPlanAccountBalance()));
             } else {
                 bizUser.setAccountBalance(bizUser.getAccountBalance().add(realPayAmount));
             }
@@ -141,7 +159,7 @@ public class WxPayNotifyController {
                 DateTime date = DateUtil.date();
                 for (int i = 0; i < bizRechargeRecord.getCouponNum(); i++) {
                     BizCouponRecord bizCouponRecord = new BizCouponRecord();
-                    bizCouponRecord.setCouponNo(IdUtil.objectId());
+                    bizCouponRecord.setCouponNo(CommonCouponGeneratorUtil.generateCouponCode());
                     bizCouponRecord.setTime(date);
                     bizCouponRecord.setRechargePlanId(bizRechargeRecord.getRechargePlanId());
                     bizCouponRecord.setRechargeRecordId(bizRechargeRecord.getId());
@@ -150,8 +168,9 @@ public class WxPayNotifyController {
             }
             // 生成推荐人返点
             if (ObjectUtil.isNotEmpty(bizUser.getReferralUser())) {
-                log.info("=========== 生成推荐人返点 ========");
+                log.info("=========== 生成推荐人返点记录 ========");
                 BizRebateRecord bizRebateRecord = new BizRebateRecord();
+                bizRebateRecord.setRechargeRecordId(bizRechargeRecord.getId());
                 bizRebateRecord.setRebateAmout(bizRechargeRecord.getRebateAmount());
                 bizRebateRecord.setRechargeUserId(bizRechargeRecord.getUserId());
                 bizRebateRecord.setRecommendUserId(bizUser.getReferralUser());
@@ -159,12 +178,20 @@ public class WxPayNotifyController {
             }
             // 记录用户账户资金变动记录
             log.info("=========== 记录用户账户资金变动记录 ========");
-
-
-
-
+            BizUserFundChangeRecord bizUserFundChangeRecord = new BizUserFundChangeRecord();
+            bizUserFundChangeRecord.setChangeType(FundChangeTypeEnum.RECHARGE.getValue());
+            bizUserFundChangeRecord.setUserId(bizRechargeRecord.getUserId());
+            bizUserFundChangeRecord.setOldAccountBalance(bizRechargeRecord.getOldAccountBalance());
+            bizUserFundChangeRecord.setOldVoucherBalance(bizRechargeRecord.getOldVoucherBalance());
+            bizUserFundChangeRecord.setNewAccountBalance(bizRechargeRecord.getNewAccountBalance());
+            bizUserFundChangeRecord.setNewVoucherBalance(bizRechargeRecord.getNewVoucherBalance());
+            bizUserFundChangeRecordService.save(bizUserFundChangeRecord);
+            //手动提交事务
+            transactionManager.commit(transactionStatus);
             log.info("微信订单回调成功------------------");
         } catch (Exception e) {
+            e.printStackTrace();
+            transactionManager.rollback(transactionStatus);
             log.error("wx pay error , 支付回调异常:{}", e.getMessage());
             returnMap.put("code", "FAIL");
             returnMap.put("message", "失败");

+ 2 - 0
snowy-web-app/src/main/java/vip/xiaonuo/core/config/GlobalConfigure.java

@@ -126,6 +126,8 @@ public class GlobalConfigure implements WebMvcConfigurer {
             "/auth/c/wxRegister",
             "/auth/c/smsSend",
             "/auth/c/doLoginByCode",
+            /* 支付回调 */
+            "/biz/wx/notify",
 
             "/auth/b/getPicCaptcha",
             "/auth/b/getPhoneValidCode",

+ 1 - 0
snowy-web-app/src/main/resources/application-dev.properties

@@ -40,3 +40,4 @@ mybatis-plus.global-config.db-config.logic-not-delete-value=NOT_DELETE
 mybatis-plus.mapper-locations=classpath*:vip/xiaonuo/**/mapping/*.xml
 mybatis-plus.type-handlers-package=vip.xiaonuo.common.handler
 
+wx.pay.payNotifyUrl=http://1.94.182.71:18999/api/biz/wx/notify

+ 1 - 1
snowy-web-app/src/main/resources/application-local.properties

@@ -40,4 +40,4 @@ mybatis-plus.global-config.db-config.logic-not-delete-value=NOT_DELETE
 mybatis-plus.mapper-locations=classpath*:vip/xiaonuo/**/mapping/*.xml
 mybatis-plus.type-handlers-package=vip.xiaonuo.common.handler
 
-
+wx.pay.payNotifyUrl=http://1.94.182.71:18999/api/biz/wx/notify

+ 2 - 0
snowy-web-app/src/main/resources/application-prod.properties

@@ -42,3 +42,5 @@ mybatis-plus.global-config.db-config.logic-delete-value=DELETED
 mybatis-plus.global-config.db-config.logic-not-delete-value=NOT_DELETE
 mybatis-plus.mapper-locations=classpath*:vip/xiaonuo/**/mapping/*.xml
 mybatis-plus.type-handlers-package=vip.xiaonuo.common.handler
+
+wx.pay.payNotifyUrl=http://1.94.182.71:18999/api/biz/wx/notify