Zhangbw 2 месяцев назад
Родитель
Сommit
e56d303863

+ 62 - 5
src/main/java/com/yingpai/gupiao/config/WxConfig.java

@@ -6,20 +6,77 @@ import org.springframework.stereotype.Component;
 
 /**
  * 微信配置类
- * 从application.properties读取微信配置
+ * 从application.yml读取微信配置
+ * 支持小程序和H5公众号双端配置
  */
 @Data
 @Component
 @ConfigurationProperties(prefix = "wx")
 public class WxConfig {
-    
+
     /**
-     * 微信小程序AppID
+     * 默认AppID(向后兼容)
      */
     private String appid;
-    
+
     /**
-     * 微信小程序AppSecret
+     * 默认AppSecret(向后兼容)
      */
     private String secret;
+
+    /**
+     * 小程序配置
+     */
+    private MiniappConfig miniapp;
+
+    /**
+     * H5公众号配置
+     */
+    private H5Config h5;
+
+    /**
+     * 小程序配置类
+     */
+    @Data
+    public static class MiniappConfig {
+        private String appid;
+        private String secret;
+    }
+
+    /**
+     * H5公众号配置类
+     */
+    @Data
+    public static class H5Config {
+        private String appid;
+        private String secret;
+    }
+
+    /**
+     * 获取小程序AppID
+     */
+    public String getMiniappAppid() {
+        return miniapp != null ? miniapp.getAppid() : appid;
+    }
+
+    /**
+     * 获取小程序Secret
+     */
+    public String getMiniappSecret() {
+        return miniapp != null ? miniapp.getSecret() : secret;
+    }
+
+    /**
+     * 获取H5公众号AppID
+     */
+    public String getH5Appid() {
+        return h5 != null ? h5.getAppid() : appid;
+    }
+
+    /**
+     * 获取H5公众号Secret
+     */
+    public String getH5Secret() {
+        return h5 != null ? h5.getSecret() : secret;
+    }
 }

+ 6 - 1
src/main/java/com/yingpai/gupiao/domain/po/User.java

@@ -34,7 +34,12 @@ public class User {
      * 微信unionid
      */
     private String unionid;
-    
+
+    /**
+     * 微信小程序openid
+     */
+    private String miniOpenid;
+
     /**
      * 手机号
      */

+ 3 - 3
src/main/java/com/yingpai/gupiao/service/impl/H5AuthServiceImpl.java

@@ -54,7 +54,7 @@ public class H5AuthServiceImpl implements H5AuthService {
             String authUrl = String.format(
                 "%s?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=%s#wechat_redirect",
                 WX_OAUTH_URL,
-                wxConfig.getAppid(),
+                wxConfig.getH5Appid(),
                 encodedRedirectUrl,
                 state
             );
@@ -76,8 +76,8 @@ public class H5AuthServiceImpl implements H5AuthService {
             String tokenUrl = String.format(
                 "%s?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                 WX_ACCESS_TOKEN_URL,
-                wxConfig.getAppid(),
-                wxConfig.getSecret(),
+                wxConfig.getH5Appid(),
+                wxConfig.getH5Secret(),
                 code
             );
 

+ 41 - 11
src/main/java/com/yingpai/gupiao/service/impl/WxPayServiceImpl.java

@@ -9,8 +9,11 @@ import com.wechat.pay.java.core.notification.RequestParam;
 import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
 import com.wechat.pay.java.service.payments.jsapi.model.*;
 import com.wechat.pay.java.service.payments.model.Transaction;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.yingpai.gupiao.config.WxConfig;
+import com.yingpai.gupiao.domain.po.User;
 import com.yingpai.gupiao.domain.vo.WxPayVO;
+import com.yingpai.gupiao.mapper.UserMapper;
 import com.yingpai.gupiao.service.WxPayConfigService;
 import com.yingpai.gupiao.service.WxPayService;
 import lombok.RequiredArgsConstructor;
@@ -34,9 +37,10 @@ import java.util.stream.Collectors;
 @Service
 @RequiredArgsConstructor
 public class WxPayServiceImpl implements WxPayService {
-    
+
     private final WxConfig wxConfig;
     private final WxPayConfigService wxPayConfigService;
+    private final UserMapper userMapper;
     
     private Config config;
     private JsapiServiceExtension jsapiService;
@@ -137,41 +141,45 @@ public class WxPayServiceImpl implements WxPayService {
     @Override
     public WxPayVO createPrepayOrder(String orderNo, String openid, Integer amount, String description) {
         log.info("创建预支付订单,orderNo: {}, openid: {}, amount: {}分", orderNo, openid, amount);
-        
+
         // 确保SDK已初始化,配置变化时自动重新初始化
         ensureInitialized();
-        
+
         if (jsapiService == null) {
             throw new RuntimeException("微信支付未初始化,请检查配置");
         }
-        
+
+        // 判断openid类型,选择对应的appid
+        String appid = determineAppid(openid);
+        log.info("使用appid: {}", appid);
+
         String notifyUrl = wxPayConfigService.getNotifyUrl();
-        
+
         // 构建下单请求
         PrepayRequest request = new PrepayRequest();
-        request.setAppid(wxConfig.getAppid());
+        request.setAppid(appid);
         request.setMchid(wxPayConfigService.getMchId());
         request.setDescription(description);
         request.setOutTradeNo(orderNo);
         request.setNotifyUrl(notifyUrl);
-        
+
         Amount amountObj = new Amount();
         amountObj.setTotal(amount);
         amountObj.setCurrency("CNY");
         request.setAmount(amountObj);
-        
+
         Payer payer = new Payer();
         payer.setOpenid(openid);
         request.setPayer(payer);
-        
+
         // 调用JSAPI下单并获取调起支付参数
         PrepayWithRequestPaymentResponse response = jsapiService.prepayWithRequestPayment(request);
-        
+
         log.info("预支付成功,orderNo: {}", orderNo);
 
         return WxPayVO.builder()
                 .orderNo(orderNo)
-                .appId(wxConfig.getAppid())
+                .appId(appid)
                 .timeStamp(response.getTimeStamp())
                 .nonceStr(response.getNonceStr())
                 .packageValue(response.getPackageVal())
@@ -180,6 +188,28 @@ public class WxPayServiceImpl implements WxPayService {
                 .totalFee(amount)
                 .build();
     }
+
+    /**
+     * 根据openid判断应该使用哪个appid
+     * @param openid 用户的openid(可能是H5的openid或小程序的mini_openid)
+     * @return 对应的appid
+     */
+    private String determineAppid(String openid) {
+        // 查询User表,判断openid是存储在openid字段还是mini_openid字段
+        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(User::getMiniOpenid, openid);
+        User userByMiniOpenid = userMapper.selectOne(wrapper);
+
+        if (userByMiniOpenid != null) {
+            // 是小程序openid,使用小程序appid
+            log.info("检测到小程序openid,使用小程序appid");
+            return wxConfig.getMiniappAppid();
+        }
+
+        // 否则是H5 openid,使用H5 appid
+        log.info("检测到H5 openid,使用H5公众号appid");
+        return wxConfig.getH5Appid();
+    }
     
     @Override
     public String verifyAndDecryptNotify(String serialNumber, String nonce, String timestamp,