Files
keyboard/keyBoard/Class/Pay/M/IAPVerifyTransactionObj.m

184 lines
7.1 KiB
Mathematica
Raw Normal View History

2025-11-13 19:20:57 +08:00
//
// IAPVerifyTransactionObj.m
//
#import "IAPVerifyTransactionObj.h"
#import "PayVM.h"
#import "KBAuthManager.h"
#import "KBHUD.h"
2025-12-08 19:48:13 +08:00
//#import "KBLoginSheetViewController.h"
2025-12-03 12:55:51 +08:00
#import "KBBizCode.h"
2025-12-15 15:22:27 +08:00
2025-12-16 13:49:08 +08:00
NSNotificationName const KBIAPDidCompletePurchaseNotification = @"KBIAPDidCompletePurchaseNotification";
2025-11-13 19:20:57 +08:00
@interface IAPVerifyTransactionObj ()
@property (nonatomic, strong) PayVM *payVM;
@end
@implementation IAPVerifyTransactionObj
- (instancetype)init {
if (self = [super init]) {
_payVM = [PayVM new];
}
return self;
}
2025-12-16 13:49:08 +08:00
- (void)verifyReceipt:(NSString *)receipt
completion:(void (^)(BOOL success, NSString * _Nullable message, NSInteger statusCode))completion {
if (![receipt isKindOfClass:NSString.class] || receipt.length == 0) {
if (completion) {
completion(NO, KBLocalized(@"Receipt missing"), KBBizCodeReceiptError);
}
return;
}
NSDictionary *params = @{ @"receipt": receipt ?: @"" };
__weak typeof(self) weakSelf = self;
[self.payVM applePayReqWithParams:params needShow:NO completion:^(NSInteger sta, NSString * _Nullable msg) {
2025-12-16 14:14:49 +08:00
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(weakSelf) self = weakSelf;
(void)self;
BOOL success = (sta == KBBizCodeSuccess);
NSString *tip = msg ?: (success ? KBLocalized(@"Success") : KBLocalized(@"Payment failed"));
if (completion) {
completion(success, tip, sta);
}
});
}];
}
- (void)verifySignedPayload:(NSString *)payload
completion:(void (^)(BOOL success, NSString * _Nullable message, NSInteger statusCode))completion {
if (![payload isKindOfClass:NSString.class] || payload.length == 0) {
if (completion) {
completion(NO, KBLocalized(@"Payload missing"), KBBizCodeReceiptError);
}
return;
}
NSDictionary *params = @{ @"signedPayload": payload ?: @"" };
__weak typeof(self) weakSelf = self;
[self.payVM applePayReqWithParams:params needShow:NO completion:^(NSInteger sta, NSString * _Nullable msg) {
2025-12-16 13:49:08 +08:00
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(weakSelf) self = weakSelf;
(void)self;
BOOL success = (sta == KBBizCodeSuccess);
NSString *tip = msg ?: (success ? KBLocalized(@"Success") : KBLocalized(@"Payment failed"));
if (completion) {
completion(success, tip, sta);
}
});
}];
}
2025-11-13 19:20:57 +08:00
#pragma mark - FGIAPVerifyTransaction
- (void)pushSuccessTradeReultToServer:(NSString *)receipt
transaction:(SKPaymentTransaction *)transaction
complete:(FGIAPVerifyTransactionPushCallBack)handler {
if (![self checkLogin]) { return; }
2025-12-15 18:56:29 +08:00
KBLOG(@"receipt = %@", receipt);
KBLOG(@"transactionId = %@, originalId = %@", transaction.transactionIdentifier,transaction.originalTransaction.transactionIdentifier);
2025-12-15 21:02:48 +08:00
#if DEBUG
// [self kb_debugLogReceipt:receipt transaction:transaction];
#endif
#if DEBUG
// [self kb_debugLogReceipt:receipt transaction:transaction];
#endif
2025-11-13 19:20:57 +08:00
2025-12-15 18:56:29 +08:00
2025-11-13 19:20:57 +08:00
__weak typeof(self) weakSelf = self;
2025-12-15 15:40:25 +08:00
[KBHUD showWithStatus:@"请稍等..."];
2025-12-16 13:49:08 +08:00
[self verifyReceipt:receipt completion:^(BOOL success, NSString * _Nullable message, NSInteger statusCode) {
__strong typeof(weakSelf) self = weakSelf;
(void)self;
if (success) {
2025-11-13 19:20:57 +08:00
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
2025-12-15 15:22:27 +08:00
[KBHUD showInfo:@"Success"];
[[NSNotificationCenter defaultCenter] postNotificationName:KBIAPDidCompletePurchaseNotification object:nil];
2025-11-17 20:07:39 +08:00
if (handler) handler(KBLocalized(@"Success"), nil);
2025-12-16 13:49:08 +08:00
} else if (statusCode == KBBizCodeReceiptError) {
2025-12-15 21:02:48 +08:00
[KBHUD dismiss];
2025-12-12 16:09:14 +08:00
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
2025-12-16 13:49:08 +08:00
} else {
[KBHUD showError:message ?: KBLocalized(@"Failed")];
if (handler) handler(message ?: KBLocalized(@"Failed"), nil);
2025-11-13 19:20:57 +08:00
}
}];
}
#pragma mark - Helpers
- (BOOL)checkLogin {
2025-12-05 20:18:18 +08:00
BOOL loggedIn = [[KBUserSessionManager shared] isLoggedIn];
2025-11-13 19:20:57 +08:00
if (!loggedIn) {
2025-12-05 20:18:18 +08:00
[[KBUserSessionManager shared] goLoginVC];
2025-11-13 19:20:57 +08:00
}
return YES;
}
2025-12-15 21:02:48 +08:00
#if DEBUG
- (void)kb_debugLogReceipt:(NSString *)receipt transaction:(SKPaymentTransaction *)transaction {
if (![receipt isKindOfClass:[NSString class]] || receipt.length == 0) {
KBLOG(@"[IAPVerifyTransactionObj] debug receipt empty");
return;
}
NSURL *url = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
if (!url) { return; }
NSDictionary *payload = @{ @"receipt-data": receipt, @"exclude-old-transactions": @NO };
NSError *jsonError = nil;
NSData *body = [NSJSONSerialization dataWithJSONObject:payload options:0 error:&jsonError];
if (jsonError || !body) {
KBLOG(@"[IAPVerifyTransactionObj] debug receipt json error: %@", jsonError);
return;
}
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = body;
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
request.timeoutInterval = 30;
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
KBLOG(@"[IAPVerifyTransactionObj] debug receipt request error: %@", error);
return;
}
if (data.length == 0) {
KBLOG(@"[IAPVerifyTransactionObj] debug receipt empty response");
return;
}
NSError *parseError = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (!json || parseError) {
KBLOG(@"[IAPVerifyTransactionObj] debug receipt parse error: %@", parseError);
return;
}
NSNumber *status = json[@"status"];
KBLOG(@"[IAPVerifyTransactionObj] receipt status: %@, env transaction: %@ / %@", status, transaction.transactionIdentifier, transaction.originalTransaction.transactionIdentifier);
void (^logEntries)(NSArray *entries, NSString *label) = ^(NSArray *entries, NSString *label) {
for (NSDictionary *item in entries) {
KBLOG(@"[IAPVerifyTransactionObj][%@] product:%@ transaction:%@ original:%@ purchase_date:%@", label, item[@"product_id"], item[@"transaction_id"], item[@"original_transaction_id"], item[@"purchase_date"]);
}
};
NSArray *latestInfos = json[@"latest_receipt_info"];
if ([latestInfos isKindOfClass:[NSArray class]] && latestInfos.count > 0) {
logEntries(latestInfos, @"latest_receipt_info");
}
NSDictionary *receiptDict = json[@"receipt"];
NSArray *inAppInfos = receiptDict[@"in_app"];
if ([inAppInfos isKindOfClass:[NSArray class]] && inAppInfos.count > 0) {
logEntries(inAppInfos, @"receipt.in_app");
}
}];
[task resume];
}
#endif
2025-11-13 19:20:57 +08:00
@end