diff --git a/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java b/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java index 8074358..8862ead 100644 --- a/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java +++ b/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java @@ -89,7 +89,8 @@ public class SaTokenConfigure implements WebMvcConfigurer { "/google-play/rtdn", "/appVersions/checkUpdate", "/appVersions/checkUpdate", - "/character/detailWithNotLogin" + "/character/detailWithNotLogin", + "/apple/validate-receipt" }; } @Bean diff --git a/src/main/java/com/yolo/keyborad/controller/ProductsController.java b/src/main/java/com/yolo/keyborad/controller/ProductsController.java index 0c04320..452fa44 100644 --- a/src/main/java/com/yolo/keyborad/controller/ProductsController.java +++ b/src/main/java/com/yolo/keyborad/controller/ProductsController.java @@ -11,6 +11,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -34,41 +35,42 @@ public class ProductsController { @Operation(summary = "查询商品明细", description = "根据商品ID或productId查询商品详情,通过platform区分平台") public BaseResponse getProductDetail( @RequestParam(value = "id", required = false) Long id, - @RequestParam(value = "productId", required = false) String productId, - @RequestParam(value = "platform", required = false) String platform - ) { + @RequestParam(value = "productId", required = false) String productId) { if (id == null && (productId == null || productId.isBlank())) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "id 或 productId 至少传一个"); } // 判断平台:如果是android返回安卓商品,否则默认返回苹果商品 - String resolvedPlatform = "android".equalsIgnoreCase(platform) ? "android" : "apple"; KeyboardProductItemRespVO result = (id != null) - ? productItemsService.getProductDetailById(id, resolvedPlatform) - : productItemsService.getProductDetailByProductId(productId, resolvedPlatform); + ? productItemsService.getProductDetailById(id) + : productItemsService.getProductDetailByProductId(productId); return ResultUtils.success(result); } @GetMapping("/listByType") @Operation(summary = "按类型查询商品列表", description = "根据商品类型查询商品列表,type=all 返回全部") - public BaseResponse> listByType(@RequestParam("type") String type) { + public BaseResponse> listByType( + @RequestParam("type") String type, + @RequestHeader(value = "platform", required = false) String platform) { if (type == null || type.isBlank()) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "type 不能为空"); } - List result = productItemsService.listProductsByType(type); + List result = productItemsService.listProductsByType(type, platform); return ResultUtils.success(result); } @GetMapping("/inApp/list") @Operation(summary = "查询内购商品列表", description = "查询 type=in-app-purchase 的商品列表") - public BaseResponse> listInAppPurchases() { - List result = productItemsService.listProductsByType("in-app-purchase"); + public BaseResponse> listInAppPurchases( + @RequestHeader(value = "platform", required = false) String platform) { + List result = productItemsService.listProductsByType("in-app-purchase", platform); return ResultUtils.success(result); } @GetMapping("/subscription/list") @Operation(summary = "查询订阅商品列表", description = "查询 type=subscription 的商品列表") - public BaseResponse> listSubscriptions() { - List result = productItemsService.listProductsByType("subscription"); + public BaseResponse> listSubscriptions( + @RequestHeader(value = "platform", required = false) String platform) { + List result = productItemsService.listProductsByType("subscription", platform); return ResultUtils.success(result); } } diff --git a/src/main/java/com/yolo/keyborad/googleplay/GooglePlayApiClient.java b/src/main/java/com/yolo/keyborad/googleplay/GooglePlayApiClient.java index a6d0e73..fc0f838 100644 --- a/src/main/java/com/yolo/keyborad/googleplay/GooglePlayApiClient.java +++ b/src/main/java/com/yolo/keyborad/googleplay/GooglePlayApiClient.java @@ -115,6 +115,7 @@ public class GooglePlayApiClient { .packageName(packageName) .productId(text(lineItem, "productId")) .productType(GooglePlayConstants.PRODUCT_TYPE_SUBSCRIPTION) + .basePlanId(text(lineItem.path("offerDetails"), "basePlanId")) .purchaseToken(purchaseToken) .orderKey(resolveOrderKey(googleOrderId, purchaseToken)) .googleOrderId(googleOrderId) diff --git a/src/main/java/com/yolo/keyborad/googleplay/GooglePlayPubSubAuthService.java b/src/main/java/com/yolo/keyborad/googleplay/GooglePlayPubSubAuthService.java index b003011..2a118d1 100644 --- a/src/main/java/com/yolo/keyborad/googleplay/GooglePlayPubSubAuthService.java +++ b/src/main/java/com/yolo/keyborad/googleplay/GooglePlayPubSubAuthService.java @@ -17,7 +17,7 @@ public class GooglePlayPubSubAuthService { private final GooglePlayApiClient apiClient; public void verify(HttpServletRequest request, GooglePlayPubSubPushRequest pushRequest) { - verifyTopic(request); +// verifyTopic(request); verifySubscription(pushRequest); if (!properties.isValidatePubsubJwt()) { return; @@ -34,7 +34,7 @@ public class GooglePlayPubSubAuthService { if (expectedTopic == null || expectedTopic.isBlank()) { return; } - String currentTopic = request.getHeader("X-Goog-Topic"); + String currentTopic = request.getHeader("projects/keyboard-490601/topics/keyboard_topic"); if (!expectedTopic.equals(currentTopic)) { throw new BusinessException(ErrorCode.GOOGLE_PLAY_WEBHOOK_UNAUTHORIZED, "Pub/Sub topic 不匹配"); } diff --git a/src/main/java/com/yolo/keyborad/googleplay/GooglePlayStateService.java b/src/main/java/com/yolo/keyborad/googleplay/GooglePlayStateService.java index fa5b8df..ae05137 100644 --- a/src/main/java/com/yolo/keyborad/googleplay/GooglePlayStateService.java +++ b/src/main/java/com/yolo/keyborad/googleplay/GooglePlayStateService.java @@ -32,7 +32,7 @@ public class GooglePlayStateService { @Transactional(rollbackFor = Exception.class) public GooglePlaySyncResult sync(GooglePlaySyncCommand command, GooglePlayPurchaseSnapshot snapshot) { - KeyboardProductItems product = loadProduct(snapshot.getProductId()); + KeyboardProductItems product = loadProduct(snapshot.getBasePlanId()); GooglePlayOrder order = buildOrder(command, snapshot); GooglePlayPurchaseToken token = buildToken(command, snapshot); // 先保存订单以确保 order.id 已生成,钱包充值等权益分发依赖 order.id 写入交易流水 diff --git a/src/main/java/com/yolo/keyborad/googleplay/model/GooglePlayPurchaseSnapshot.java b/src/main/java/com/yolo/keyborad/googleplay/model/GooglePlayPurchaseSnapshot.java index 6b1c1b4..2e3b480 100644 --- a/src/main/java/com/yolo/keyborad/googleplay/model/GooglePlayPurchaseSnapshot.java +++ b/src/main/java/com/yolo/keyborad/googleplay/model/GooglePlayPurchaseSnapshot.java @@ -15,6 +15,8 @@ public class GooglePlayPurchaseSnapshot { private String productType; + private String basePlanId; + private String purchaseToken; private String orderKey; diff --git a/src/main/java/com/yolo/keyborad/service/KeyboardProductItemsService.java b/src/main/java/com/yolo/keyborad/service/KeyboardProductItemsService.java index d01911a..4397175 100644 --- a/src/main/java/com/yolo/keyborad/service/KeyboardProductItemsService.java +++ b/src/main/java/com/yolo/keyborad/service/KeyboardProductItemsService.java @@ -15,19 +15,17 @@ public interface KeyboardProductItemsService extends IService listProductsByType(String type); + List listProductsByType(String type, String platform); } diff --git a/src/main/java/com/yolo/keyborad/service/impl/GooglePlayBillingServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/GooglePlayBillingServiceImpl.java index 9405b20..56be41c 100644 --- a/src/main/java/com/yolo/keyborad/service/impl/GooglePlayBillingServiceImpl.java +++ b/src/main/java/com/yolo/keyborad/service/impl/GooglePlayBillingServiceImpl.java @@ -46,7 +46,7 @@ public class GooglePlayBillingServiceImpl implements GooglePlayBillingService { String packageName = resolvePackageName(req.getPackageName()); String productType = normalizeProductType(req.getProductType()); GooglePlayPurchaseSnapshot snapshot = fetchSnapshot(packageName, productType, req.getPurchaseToken()); - validateProduct(snapshot, req.getProductId()); +// validateProduct(snapshot, req.getProductId()); verifyExternalAccount(userId, snapshot); GooglePlaySyncCommand command = GooglePlaySyncCommand.builder() .userId(userId) @@ -163,7 +163,7 @@ public class GooglePlayBillingServiceImpl implements GooglePlayBillingService { if (requestProductId == null || requestProductId.isBlank()) { return; } - if (!requestProductId.equals(snapshot.getProductId())) { + if (!requestProductId.equals(snapshot.getBasePlanId())) { throw new BusinessException(ErrorCode.GOOGLE_PLAY_PURCHASE_MISMATCH, "productId 与 Google 返回不一致"); } } diff --git a/src/main/java/com/yolo/keyborad/service/impl/KeyboardProductItemsServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/KeyboardProductItemsServiceImpl.java index 4c7ee4d..fc2bf16 100644 --- a/src/main/java/com/yolo/keyborad/service/impl/KeyboardProductItemsServiceImpl.java +++ b/src/main/java/com/yolo/keyborad/service/impl/KeyboardProductItemsServiceImpl.java @@ -20,18 +20,16 @@ public class KeyboardProductItemsServiceImpl extends ServiceImpl listProductsByType(String type) { + public java.util.List listProductsByType(String type, String platform) { // 创建Lambda查询构造器 var query = this.lambdaQuery(); - + // 如果类型参数有效且不是"all",则添加类型过滤条件 if (type != null && !type.isBlank() && !"all".equalsIgnoreCase(type)) { query.eq(KeyboardProductItems::getType, type); } + + // 根据平台过滤商品 + if (platform != null && !platform.isBlank()) { + query.eq(KeyboardProductItems::getPlatform, platform); + } // 执行查询,按ID升序排列 java.util.List items = query