fix(apple): 增加无效收据原因日志并补充订阅过期时间调试输出
This commit is contained in:
@@ -12,6 +12,9 @@ import org.springframework.ai.retry.RetryUtils;
|
|||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
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() {
|
public OpenAiApi openAiApi() {
|
||||||
return OpenAiApi.builder()
|
return OpenAiApi.builder()
|
||||||
.apiKey(apiKey)
|
.apiKey(apiKey)
|
||||||
|
.headers(MultiValueMap.fromSingleValue(Map.of("X-Title", "key of love")))
|
||||||
.baseUrl(baseUrl)
|
.baseUrl(baseUrl)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public class AppleReceiptController {
|
|||||||
private final ApplePurchaseService applePurchaseService;
|
private final ApplePurchaseService applePurchaseService;
|
||||||
private final SignedDataVerifier signedDataVerifier;
|
private final SignedDataVerifier signedDataVerifier;
|
||||||
|
|
||||||
|
|
||||||
public AppleReceiptController(AppleReceiptService appleReceiptService,
|
public AppleReceiptController(AppleReceiptService appleReceiptService,
|
||||||
ApplePurchaseService applePurchaseService,
|
ApplePurchaseService applePurchaseService,
|
||||||
SignedDataVerifier signedDataVerifier) {
|
SignedDataVerifier signedDataVerifier) {
|
||||||
@@ -83,12 +84,13 @@ public class AppleReceiptController {
|
|||||||
*/
|
*/
|
||||||
@PostMapping("/notification")
|
@PostMapping("/notification")
|
||||||
public BaseResponse<Boolean> receiveNotification(@RequestBody Map<String, String> body, HttpServletRequest request) {
|
public BaseResponse<Boolean> receiveNotification(@RequestBody Map<String, String> body, HttpServletRequest request) {
|
||||||
|
|
||||||
|
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "body 不能为空");
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "body 不能为空");
|
||||||
}
|
}
|
||||||
// 从请求体中获取 Apple 签名的载荷
|
// 从请求体中获取 Apple 签名的载荷
|
||||||
String signedPayload = body.get("signedPayload");
|
String signedPayload = body.get("signedPayload");
|
||||||
|
|
||||||
// 校验 signedPayload 是否为空
|
// 校验 signedPayload 是否为空
|
||||||
if (signedPayload == null || signedPayload.isBlank()) {
|
if (signedPayload == null || signedPayload.isBlank()) {
|
||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "signedPayload 不能为空");
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "signedPayload 不能为空");
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ public class ApplePurchaseServiceImpl implements ApplePurchaseService {
|
|||||||
public void processPurchase(Long userId, AppleReceiptValidationResult validationResult) {
|
public void processPurchase(Long userId, AppleReceiptValidationResult validationResult) {
|
||||||
// 1. 校验收据有效性
|
// 1. 校验收据有效性
|
||||||
if (validationResult == null || !validationResult.isValid()) {
|
if (validationResult == null || !validationResult.isValid()) {
|
||||||
|
log.error("Invalid receipt, reason={}", validationResult.getReason());
|
||||||
throw new BusinessException(ErrorCode.RECEIPT_INVALID);
|
throw new BusinessException(ErrorCode.RECEIPT_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ public class AppleReceiptServiceImpl implements AppleReceiptService {
|
|||||||
try {
|
try {
|
||||||
// 1. 从收据里解析出 transactionId(不做验证,只是解析 ASN.1)
|
// 1. 从收据里解析出 transactionId(不做验证,只是解析 ASN.1)
|
||||||
String transactionId = receiptUtility.extractTransactionIdFromAppReceipt(appReceipt);
|
String transactionId = receiptUtility.extractTransactionIdFromAppReceipt(appReceipt);
|
||||||
|
// todo 验证服务器传输的transactionId
|
||||||
|
// String transactionId = receiptUtility.extractTransactionIdFromTransactionReceipt(appReceipt);
|
||||||
if (transactionId == null) {
|
if (transactionId == null) {
|
||||||
return invalid("no_transaction_id_in_receipt");
|
return invalid("no_transaction_id_in_receipt");
|
||||||
}
|
}
|
||||||
@@ -193,6 +195,7 @@ public class AppleReceiptServiceImpl implements AppleReceiptService {
|
|||||||
// 有 expiresDate 的一般是订阅(自动续订等),过期就无效
|
// 有 expiresDate 的一般是订阅(自动续订等),过期就无效
|
||||||
if (payload.getExpiresDate() != null) {
|
if (payload.getExpiresDate() != null) {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
log.error("Now Date:{} ,Expires Date: {}",now, payload.getExpiresDate());
|
||||||
return now < payload.getExpiresDate();
|
return now < payload.getExpiresDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,9 +56,20 @@ public class JwtParser {
|
|||||||
|
|
||||||
// 获取第一个证书(Base64 编码,标准格式非URL安全格式)
|
// 获取第一个证书(Base64 编码,标准格式非URL安全格式)
|
||||||
String certBase64 = x5cArray.getString(0);
|
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 安全编码)
|
// 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 证书并提取公钥
|
// 生成 X509 证书并提取公钥
|
||||||
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
||||||
|
|||||||
Reference in New Issue
Block a user