10

我在 iPhone 上的应用程序中模拟购买自动续订订阅。我的问题是购买被认为是由 App Store 完成的,而实际上不是。

这是发生了什么:

  1. 用户按下按钮购买续订订阅
  2. 用户提供他的 iTunes 密码并确认购买
  3. 该应用程序将从应用程序商店收到的收据提交到我的服务器以检查有效性
  4. 服务器返回“ok”或“not ok”字符串。该应用程序仅在“确定”时调用 finishTransaction

当第 3 步出现网络故障时,我遇到了问题。我无法验证收据。但是如果用户第二次尝试购买,应用商店告诉他他已经订阅了,即使我没有调用该finishTransaction方法完成购买!

这是预期的行为吗?应用商店不应该将未完成的交易视为未完成,还是我错过了什么?我欢迎任何解决此问题的建议。

-(void) userPurchase:(SKProduct*) product{
    SKPayment *payment = [SKPayment paymentWithProduct:product];
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}

-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
    NSLog(@"paymentQueue updatedTransaction");
    for (SKPaymentTransaction * transaction in transactions) {
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchasing:
                break;
            case SKPaymentTransactionStatePurchased:
                [self recordSubscription:transaction];
                break;
            case SKPaymentTransactionStateFailed:
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                [self recordSubscription:transaction];
                break;
            default: NSLog(@"Default");
                break;
        }
    };
}


-(void) recordSubscription:(SKPaymentTransaction*)transaction{
    NSString *jsonObjectString = [self encode:(uint8_t *)transaction.transactionReceipt.bytes length:transaction.transactionReceipt.length];
    NSMutableDictionary *params = [[NSMutableDictionary alloc] initWithObjectsAndKeys:jsonObjectString,@"receiptdata", nil];
    [[AFNetworkSubClass sharedClient] postPath:@"myserver" params:params 
    success:^(AFHTTPRequestOperation *operation, id output) {
        /* some code */
        if([valstring isEqualToString:@"ok"]){
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        }
    }
    }failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"validation failed");
    }
4

5 回答 5

0

I think before you call recordSubscription method, you can call finish finishTransaction method to remove payment from payment queue because you have finished the purchase action with apple server.

If network failure make you can't validate app receipt, just record the receipt and validate the receipt to your own server again or validate when network is reachable another time.

I hope it can help you.

于 2013-11-27T08:40:11.300 回答
0

用户不能购买相同的订阅,直到它过期。你的情况,购买交易已经完成,但是由于网络故障,你没有提供服务。我曾经有过类似的问题。您可能需要要求用户恢复所有已完成的交易。

然后completeTransaction函数将被调用。祝你好运!

于 2013-11-29T04:50:53.937 回答
0

如果你没有打电话finishTransaction,这并不意味着交易没有从用户那里拿钱。该调用所做的只是阻止 StoreKit 在每次启动时通知您的应用程序交易。它只是您告诉 StoreKit 您已完成交易的一种方式,即解锁用户内容并将其保存到您的后端等。

因此,即使出现网络错误,您也应该重试 API 调用。如果您关闭应用程序并重新打开,您应该会收到一个交易更新,表明它已被“购买”,让您有时间再次提交到您的服务器:)

这是预期的行为,否则您将成为双倍/三倍计费用户。

于 2016-07-08T08:52:29.230 回答
-1

我曾经在应用商店购买和游戏中心都遇到过这样的问题。我知道这听起来像是一个没有答案的答案,但它对我有用。

我从我的设备中删除了该应用程序及其所有数据,重新启动了 xcode 并清理了项目。打开设备并设置新的部署。该应用程序开始从 App Store 收到正确的响应。我不确定是不是因为设备上缓存了某些东西,或者 App Store 只是需要更多时间才能正常工作,但在那之后事情就到位了。

尽管我从未处理过基于订阅的购买,但据我所知,您的代码中没有任何内容不正确。

祝你好运。

于 2013-12-02T22:47:09.573 回答
-1

请注意,如果您的应用程序不符合以下声明,那么您将无法使用自动续订订阅。以下来自应用审查指南;

11.15 应用只能对期刊(报纸、杂志)、商业应用(企业、生产力、专业创意、云存储)和媒体应用(视频、音频、语音)使用自动续订,否则应用将被拒绝

如果您的应用程序确实适合这个括号,那么您可以做些什么来设置您的应用程序,使其认为自己暂时“订阅”并不断尝试向服务器进行身份验证(如果连接时间过长,请通知用户到互联网)。

于 2013-11-27T04:21:37.660 回答