diff --git a/payment_callback_implementation.md b/docs/payment_callback_implementation.md similarity index 100% rename from payment_callback_implementation.md rename to docs/payment_callback_implementation.md diff --git a/unified_payment_with_order_api.md b/docs/unified_payment_with_order_api.md similarity index 100% rename from unified_payment_with_order_api.md rename to docs/unified_payment_with_order_api.md diff --git a/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java b/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java index 0ac4e3b..ec7c1b6 100644 --- a/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java +++ b/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java @@ -665,6 +665,32 @@ public class WxLoginController extends BaseController { return sample; } + @Operation(summary = "调试:获取AccessToken") + @GetMapping("/debug/getAccessToken") + public ApiResult debugGetAccessToken() { + try { + // 获取当前线程的租户ID + Integer tenantId = getTenantId(); + if (tenantId == null) { + tenantId = 10550; // 默认租户 + } + + System.out.println("=== 开始调试获取AccessToken,租户ID: " + tenantId + " ==="); + + // 手动调用获取AccessToken + String accessToken = getAccessTokenForTenant(tenantId); + + String result = "获取AccessToken成功: " + (accessToken != null ? accessToken.substring(0, Math.min(10, accessToken.length())) + "..." : "null"); + System.out.println("调试结果: " + result); + + return success(result); + } catch (Exception e) { + System.err.println("调试获取AccessToken异常: " + e.getMessage()); + e.printStackTrace(); + return fail("获取AccessToken失败: " + e.getMessage()); + } + } + /** * 从scene参数中提取租户ID * scene格式可能是: uid_33103 或其他包含用户ID的格式 @@ -736,9 +762,25 @@ public class WxLoginController extends BaseController { String apiUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret; System.out.println("调用微信API获取token - 租户ID: " + tenantId + ", AppID: " + (appId != null ? appId.substring(0, Math.min(8, appId.length())) + "..." : "null")); + System.out.println("微信API请求URL: " + apiUrl.replaceAll("secret=[^&]*", "secret=***")); String result = HttpUtil.get(apiUrl); System.out.println("微信API响应: " + result); JSONObject json = JSON.parseObject(result); + + // 检查是否有错误 + if (json.containsKey("errcode")) { + Integer errcode = json.getInteger("errcode"); + String errmsg = json.getString("errmsg"); + System.err.println("微信API错误 - errcode: " + errcode + ", errmsg: " + errmsg); + + if (errcode == 40125) { + throw new RuntimeException("微信AppSecret配置错误,请检查并更新正确的AppSecret"); + } else if (errcode == 40013) { + throw new RuntimeException("微信AppID配置错误,请检查并更新正确的AppID"); + } else { + throw new RuntimeException("微信API调用失败: " + errmsg + " (errcode: " + errcode + ")"); + } + } if (json.containsKey("access_token")) { String accessToken = json.getString("access_token"); diff --git a/test_payment_fix.md b/test_payment_fix.md deleted file mode 100644 index 9b626a4..0000000 --- a/test_payment_fix.md +++ /dev/null @@ -1,99 +0,0 @@ -# 微信Native支付修复验证 - -## 🔧 修复内容 - -### 问题描述 -微信支付API调用失败,错误信息: -1. **第一个错误**: -``` -PARAM_ERROR: "输入源"/body/appid"映射到字段"公众号ID"必填性规则校验失败,此字段为必填项" -``` - -2. **第二个错误**(修复appid后出现): -``` -PARAM_ERROR: "输入源"/body/notify_url"映射到字段"通知地址"必填性规则校验失败,此字段为必填项" -``` - -### 根本原因 -在 `WechatNativeStrategy.buildPrepayRequest()` 方法中缺少设置必填字段: -1. 缺少 `appId` 和 `mchId` 字段 -2. 缺少 `notify_url` 字段的正确处理 - -### 修复方案 -1. **添加PaymentService注入**:获取Native支付配置 -2. **新增getNativePaymentConfig方法**:专门获取type=102的Native支付配置 -3. **修改buildPrepayRequest方法**: - - 添加appId和mchId设置 - - 完善notify_url的处理逻辑 - -### 修复后的关键代码 - -```java -// 1. 获取Native支付配置 -Payment paymentConfig = getNativePaymentConfig(request.getTenantId()); - -// 2. 构建预支付请求时设置必填字段 -prepayRequest.setAppid(paymentConfig.getAppId()); -prepayRequest.setMchid(paymentConfig.getMchId()); - -// 3. 设置回调URL(必填字段) -String notifyUrl = null; -if (StringUtils.hasText(request.getNotifyUrl())) { - notifyUrl = request.getNotifyUrl(); -} else if (StringUtils.hasText(paymentConfig.getNotifyUrl())) { - notifyUrl = paymentConfig.getNotifyUrl(); -} else { - throw new RuntimeException("回调通知地址不能为空"); -} -prepayRequest.setNotifyUrl(notifyUrl); -``` - -## 🎯 支付类型区分 - -### 数据库配置 -- **type = 1**: 微信小程序支付(使用小程序appid) -- **type = 102**: 微信Native支付(使用开放平台appid) - -### 使用场景 -- **小程序支付**: 在微信小程序内调用支付 -- **Native支付**: PC端扫码支付,生成二维码 - -## ✅ 验证步骤 - -1. **确保数据库配置**: - ```sql - SELECT * FROM sys_payment WHERE type = 102 AND tenant_id = ?; - ``` - 确保有Native支付配置且appId不为空 - -2. **测试支付调用**: - - 调用Native支付接口 - - 检查日志中是否包含AppID和商户号信息 - - 验证微信API不再返回PARAM_ERROR - -3. **检查日志输出**: - ``` - 构建微信预支付请求完成, 订单号: xxx, 金额: xxx分, AppID: wxXXX, 商户号: xxx, 回调URL: xxx - ``` - -## ⚠️ 常见问题 - -### APPID_MCHID_NOT_MATCH 错误 -如果出现 "appid和mch_id不匹配" 错误,请检查: - -1. **确保appid和mchid是绑定关系**: - ```sql - SELECT app_id, mch_id FROM sys_payment WHERE type = 102 AND tenant_id = ?; - ``` - -2. **验证微信支付配置**: - - appid:必须是微信开放平台的网站应用appid(用于Native支付) - - mchid:必须是与该appid绑定的微信支付商户号 - -3. **检查微信支付后台**: - - 登录微信支付商户平台 - - 确认该商户号下绑定了正确的appid - - 确认产品权限已开通(Native支付) - -## 🚀 预期结果 -修复后,微信Native支付应该能够正常调用,不再出现参数错误。