RMStore收据验证失败流程

时间:2014-08-25 19:46:51

标签: objective-c in-app-purchase rmstore

我正在使用RMStore来验证收据。请注意,我没有将RMStore用于实际购买部分。如果收据无效,该流程可成功处理抛出错误和未提供内容的成功与失败。我故意改变了捆绑以迫使失败作为测试。我的问题是失败过程和Apple发送的确认。

问题在于,虽然此过程确实检测到验证失败,因此确实阻止将内容发送给用户,但Apple之后仍会返回有关购买成功的对话框。好消息是购买不成功且内容未送达,但我希望Apple的这个对话框不显示,因为它会造成混淆。

这是我的支票实施。目前我只是在故障块中执行更多操作之前测试故障情况。

- (void)completeTransaction:(SKPaymentTransaction *)transaction {
    NSLog(@"completeTransaction...");

    RMStoreAppReceiptVerificator *verifyReceipt = [[RMStoreAppReceiptVerificator alloc]init];

    [verifyReceipt verifyTransaction:transaction success:^{
        [self provideContentForProductIdentifier:transaction.payment.productIdentifier];
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    }failure:^(NSError *error){
        NSLog(@"failure to verify: %@",error.description);
    }];
}

在故障块中是否有办法停止在Apple创建成功对话框的过程,或者我是否需要在早期阶段执行此检查?

更新

在进一步观察时,状态SKPaymentTransactionStatePurchased正在调用上述方法。每个Apple的状态定义为:

“App Store已成功处理付款。您的应用程序应提供用户购买的内容。”

这告诉我防止对话可能为时已晚。有一个较早的州,但是,我认为收据验证必须在购买之后但在交付内容之前(否则将无法进行购买验证)。那么这只是一个必须处理冲突消息的问题,还是我错过了什么?

更新2:在评论中为每个请求添加更多方法

@interface IAPHelper () <SKProductsRequestDelegate, SKPaymentTransactionObserver>
@end

@implementation IAPHelper
{
    SKProductsRequest * _productsRequest;
    RequestProductsCompletionHandler _completionHandler;

    NSSet * _productIdentifiers;
    NSMutableSet * _purchasedProductIdentifiers;
    NSDictionary *_mappingDict;
}

- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers andMappings:(NSDictionary *)mappingDict
{

    if ((self = [super init])) {

        // Store product identifiers & mappings
        _productIdentifiers = productIdentifiers;
        _mappingDict = mappingDict;

        // Add self as transaction observer
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

    }
    return self;

}

- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler {


    // 1
    _completionHandler = [completionHandler copy];

    // 2
    _productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers];
    _productsRequest.delegate = self;
    [_productsRequest start];

}

- (BOOL)productPurchased:(NSString *)productIdentifier {
    return [_purchasedProductIdentifiers containsObject:productIdentifier];
}

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

    NSLog(@"Buying %@...", product.productIdentifier);

    SKPayment * payment = [SKPayment paymentWithProduct:product];
    [[SKPaymentQueue defaultQueue] addPayment:payment];

}

#pragma mark - SKProductsRequestDelegate

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {

    NSLog(@"Loaded list of products...");
    _productsRequest = nil;

    NSArray * skProducts = response.products;
    for (SKProduct * skProduct in skProducts) {
        NSLog(@"Found product: %@ %@ %0.2f",
              skProduct.productIdentifier,
              skProduct.localizedTitle,
              skProduct.price.floatValue);
    }

    if (_completionHandler)
    {
        _completionHandler(YES, skProducts);
        _completionHandler = nil;
    }
}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {

    NSLog(@"Failed to load list of products.");
    _productsRequest = nil;

    if (_completionHandler)
    {
        _completionHandler(NO, nil);
        _completionHandler = nil;
    }
}

以下是调用completeTransaction

的具体方法
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction * transaction in transactions) {
        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchased:
                [self completeTransaction:transaction];
                break;
            case SKPaymentTransactionStateFailed:
                [self failedTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                [self restoreTransaction:transaction];
            default:
                break;
        }
    };
}

1 个答案:

答案 0 :(得分:0)

我们在评论中确定此问题与RMStore没有任何关系。

您没有测试真实的欺诈行为,因此Apple显示警报无关紧要。

这将涉及使用虚假收据或向Store Kit交易观察员发送虚假调用。在这两种情况下,您都不会收到警报。

使用有效的事务来模拟故障情况时,您不能指望Apple也认为该事务无效。没有API告诉Apple交易是欺诈性的。您只能完成交易。