fix(apple): 增加无效收据原因日志并补充订阅过期时间调试输出

This commit is contained in:
2025-12-15 21:21:47 +08:00
parent 0ad9de1011
commit c305dfaae4
5 changed files with 24 additions and 3 deletions

View File

@@ -12,6 +12,9 @@ import org.springframework.ai.retry.RetryUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.MultiValueMap;
import java.util.Map;
/*
@@ -32,6 +35,7 @@ public class LLMConfig {
public OpenAiApi openAiApi() {
return OpenAiApi.builder()
.apiKey(apiKey)
.headers(MultiValueMap.fromSingleValue(Map.of("X-Title", "key of love")))
.baseUrl(baseUrl)
.build();
}

View File

@@ -36,6 +36,7 @@ public class AppleReceiptController {
private final ApplePurchaseService applePurchaseService;
private final SignedDataVerifier signedDataVerifier;
public AppleReceiptController(AppleReceiptService appleReceiptService,
ApplePurchaseService applePurchaseService,
SignedDataVerifier signedDataVerifier) {
@@ -83,12 +84,13 @@ public class AppleReceiptController {
*/
@PostMapping("/notification")
public BaseResponse<Boolean> receiveNotification(@RequestBody Map<String, String> body, HttpServletRequest request) {
if (body == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "body 不能为空");
}
// 从请求体中获取 Apple 签名的载荷
String signedPayload = body.get("signedPayload");
// 校验 signedPayload 是否为空
if (signedPayload == null || signedPayload.isBlank()) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "signedPayload 不能为空");

View File

@@ -70,6 +70,7 @@ public class ApplePurchaseServiceImpl implements ApplePurchaseService {
public void processPurchase(Long userId, AppleReceiptValidationResult validationResult) {
// 1. 校验收据有效性
if (validationResult == null || !validationResult.isValid()) {
log.error("Invalid receipt, reason={}", validationResult.getReason());
throw new BusinessException(ErrorCode.RECEIPT_INVALID);
}

View File

@@ -86,6 +86,8 @@ public class AppleReceiptServiceImpl implements AppleReceiptService {
try {
// 1. 从收据里解析出 transactionId不做验证只是解析 ASN.1
String transactionId = receiptUtility.extractTransactionIdFromAppReceipt(appReceipt);
// todo 验证服务器传输的transactionId
// String transactionId = receiptUtility.extractTransactionIdFromTransactionReceipt(appReceipt);
if (transactionId == null) {
return invalid("no_transaction_id_in_receipt");
}
@@ -193,6 +195,7 @@ public class AppleReceiptServiceImpl implements AppleReceiptService {
// 有 expiresDate 的一般是订阅(自动续订等),过期就无效
if (payload.getExpiresDate() != null) {
long now = System.currentTimeMillis();
log.error("Now Date:{} ,Expires Date: {}",now, payload.getExpiresDate());
return now < payload.getExpiresDate();
}

View File

@@ -56,9 +56,20 @@ public class JwtParser {
// 获取第一个证书Base64 编码标准格式非URL安全格式
String certBase64 = x5cArray.getString(0);
// 调试信息
System.out.println("Cert Base64 length: " + certBase64.length());
System.out.println("First 50 chars: " + certBase64.substring(0, Math.min(50, certBase64.length())));
// x5c 中的证书使用标准 Base64 编码(非 URL 安全编码)
byte[] certBytes = Base64.getDecoder().decode(certBase64);
byte[] certBytes;
try {
certBytes = Base64.getDecoder().decode(certBase64); // 使用标准 Base64 解码
System.out.println("Decoded cert bytes length: " + certBytes.length);
} catch (IllegalArgumentException e) {
System.err.println("Base64 decode error: " + e.getMessage());
throw new Exception("Failed to decode certificate from x5c", e);
}
// 生成 X509 证书并提取公钥
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");