// // IAPVerifyTransactionObj.m // #import "IAPVerifyTransactionObj.h" #import "PayVM.h" #import "KBAuthManager.h" #import "KBHUD.h" //#import "KBLoginSheetViewController.h" #import "KBBizCode.h" NSString * const KBIAPDidCompletePurchaseNotification = @"KBIAPDidCompletePurchaseNotification"; @interface IAPVerifyTransactionObj () @property (nonatomic, strong) PayVM *payVM; @end @implementation IAPVerifyTransactionObj - (instancetype)init { if (self = [super init]) { _payVM = [PayVM new]; } return self; } #pragma mark - FGIAPVerifyTransaction - (void)pushSuccessTradeReultToServer:(NSString *)receipt transaction:(SKPaymentTransaction *)transaction complete:(FGIAPVerifyTransactionPushCallBack)handler { if (![self checkLogin]) { return; } KBLOG(@"receipt = %@", receipt); KBLOG(@"transactionId = %@, originalId = %@", transaction.transactionIdentifier,transaction.originalTransaction.transactionIdentifier); #if DEBUG // [self kb_debugLogReceipt:receipt transaction:transaction]; #endif #if DEBUG // [self kb_debugLogReceipt:receipt transaction:transaction]; #endif NSInteger type = 0; #if DEBUG type = 0; #else type = 1; #endif // , @"type": @(type) NSDictionary *params = @{ @"receipt": receipt ?: @""}; __weak typeof(self) weakSelf = self; [KBHUD showWithStatus:@"请稍等..."]; [self.payVM applePayReqWithParams:params needShow:NO completion:^(NSInteger sta, NSString * _Nullable msg) { // [KBHUD dismiss]; // [KBHUD showInfo:(sta == !KBBizCodeSuccess ? KBLocalized(@"Payment failed") : KBLocalized(@"Payment successful"))]; if (sta == KBBizCodeSuccess) { [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; [KBHUD showInfo:@"Success"]; [[NSNotificationCenter defaultCenter] postNotificationName:KBIAPDidCompletePurchaseNotification object:nil]; if (handler) handler(KBLocalized(@"Success"), nil); }else if(sta == KBBizCodeReceiptError){ [KBHUD dismiss]; [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; }else { [KBHUD showError:@"Failed"]; if (handler) handler(KBLocalized(@"Failed"), nil); } (void)weakSelf; // keep self during block life if needed }]; } #pragma mark - Helpers - (BOOL)checkLogin { BOOL loggedIn = [[KBUserSessionManager shared] isLoggedIn]; if (!loggedIn) { [[KBUserSessionManager shared] goLoginVC]; } return YES; } #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 @end