iOS 应用内购买总是返回 SKPaymentTransactionStateFailed 并且应用崩溃且日志中没有错误

标签 ios in-app-purchase storekit

我已经实现了应用内购买,并且一直有效到现在。我添加了一些新的应用内购买并进行了测试。它总是切换到 SKPaymentTransactionStateFailed 并且应用程序在那个阶段崩溃并且没有给出错误消息。这是应用内购买的代码:

-(void)fetchAvailableProducts{
    NSSet *productIdentifiers = [NSSet
                                 setWithObjects:@"xxx.template8",nil];
    productsRequest = [[SKProductsRequest alloc]
                       initWithProductIdentifiers:productIdentifiers];
    productsRequest.delegate = self;
    [productsRequest start];
}

- (BOOL)canMakePurchases
{
    return [SKPaymentQueue canMakePayments];
}
- (void)purchaseMyProduct:(SKProduct*)product{
    if ([self canMakePurchases]) {
        SKPayment *payment = [SKPayment paymentWithProduct:product];
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
        [[SKPaymentQueue defaultQueue] addPayment:payment];
    }
    else{
        UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:
                                  @"Purchases are disabled in your device" message:nil delegate:
                                  self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
        [alertView show];
    }
}
-(IBAction)purchase:(id)sender{
    [self purchaseMyProduct:[validProducts objectAtIndex:0]];
    purchaseButton.enabled = NO;
}

#pragma mark StoreKit Delegate

-(void)paymentQueue:(SKPaymentQueue *)queue
updatedTransactions:(NSArray *)transactions {
    for (SKPaymentTransaction *transaction in transactions) {
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"Purchasing");
                break;
            case SKPaymentTransactionStatePurchased:
                if ([transaction.payment.productIdentifier
                     isEqualToString:@"xxx.template8"]) {
                    NSLog(@"Purchased ");
                    UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:
                                              @"Purchase is completed succesfully" message:nil delegate:
                                              self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
                    [alertView show];
                }
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                NSLog(@"Restored ");
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                break;
            case SKPaymentTransactionStateFailed:
                NSLog(@"Purchase failed ");
                //[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                //break;
            default:
                break;
        }
    }
}

-(void)productsRequest:(SKProductsRequest *)request
    didReceiveResponse:(SKProductsResponse *)response
{
    SKProduct *validProduct = nil;
    NSInteger count = [response.products count];
    if (count>0) {
        validProducts = response.products;
        validProduct = [response.products objectAtIndex:0];
        if ([validProduct.productIdentifier
             isEqualToString:@"xxx.template8"]) {
            [productTitleLabel setText:[NSString stringWithFormat:
                                        @"Product Title: %@",validProduct.localizedTitle]];
            [productDescriptionLabel setText:[NSString stringWithFormat:
                                              @"Product Desc: %@",validProduct.localizedDescription]];
            [productPriceLabel setText:[NSString stringWithFormat:
                                        @"Product Price: %@",validProduct.price]];
        }
    } else {
        UIAlertView *tmp = [[UIAlertView alloc]
                            initWithTitle:@"Not Available"
                            message:@"No products to purchase"
                            delegate:self
                            cancelButtonTitle:nil
                            otherButtonTitles:@"Ok", nil];
        [tmp show];
    }    
    [activityIndicatorView stopAnimating];
    purchaseButton.hidden = NO;
}

最佳答案

有一种方法可以检查 SKPaymentTransaction 发生的错误,您可以这样做:

...
case SKPaymentTransactionStateFailed:
    [self failedTransaction:transaction];
...


- (void)failedTransaction:(SKPaymentTransaction *)transaction {

    NSLog(@"failedTransaction...");
    if (transaction.error.code != SKErrorPaymentCancelled)
    {
        NSLog(@"Transaction error: %@", transaction.error.localizedDescription);
    }

    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}

应用此代码并告诉我们日志内容

编辑:

因为日志说产品标识符为空检查方法

- (void)purchaseMyProduct:(SKProduct*)product{

 NSLog(@"product id = %@",product.productIdentifier);

关于iOS 应用内购买总是返回 SKPaymentTransactionStateFailed 并且应用崩溃且日志中没有错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28947052/

相关文章:

ios - 是否可以从 Objective-c 中的服务器下载完整目录

ios - 如何在等待 App Store 响应应用内购买时运行 'loading spinner' 或类似代码?

ios - 来自 appStoreReceiptURL 的应用程序内购买 Objective C 状态

ios - 折扣与购买的商品数量成正比

ios - 在多个ios设备之间共享应用程序订阅中的非续订

ios - 推送通知在开发中工作正常,但设备在生产中未收到通知

objective-c - 检查它是否相等,Normal int 和 #define 宏。但它不起作用

ios - 使用UTC-5时区格式化程序将NSString转换为NSDate

ios - 如果用户取消了 InApp 购买或只是另一个失败状态,如何处理

iphone - 为什么应用内购买沙盒总是询问 "Verification Required"?