自动续订订阅:尽管未调用finishTransaction,app-store也会完成事务

时间:2013-11-19 08:27:43

标签: ios iphone in-app-purchase auto-renewing

我正在iPhone上模拟在我的应用中购买自动续订订阅。我的问题是,购买被认为是由App商店完成的,而不是。

以下是发生的事情:

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

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

    这是预期的行为吗? app-store不应该将未完成的交易视为未完成,或者我错过了什么? 我欢迎任何解决这个问题的建议。

    -(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");
        }
    

5 个答案:

答案 0 :(得分:0)

我认为在您调用recordSubscription方法之前,您可以调用finish finishTransaction方法从付款队列中删除付款,因为您已完成Apple服务器的购买操作。

如果网络故障导致您无法验证应用收据,只需记录收据并再次将收据验证到您自己的服务器,或验证何时可以再次访问网络。

我希望它可以帮到你。

答案 1 :(得分:0)

用户在过期前无法购买相同的订阅。在您的情况下,购买交易已完成,但由于网络故障,您未提供服务。 我曾经有类似的问题。您可能需要让用户恢复所有已完成的交易。

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

答案 2 :(得分:0)

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

因此,即使出现网络错误,您也应该重试API调用。如果您关闭应用程序并重新打开,则应获得交易更新,以表明已经购买了该应用程序'给你时间再次提交给你的服务器:)

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

答案 3 :(得分:-1)

如果您的应用程序不符合以下声明,那么您将无法使用自动续订订阅。以下内容来自App App Guidelines;

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

如果您的应用确实适合此支架,那么您可以设置您的应用,以便它认为自己暂时“已订阅”并且它一直尝试通过服务器进行身份验证(如果已经过了太久,请通知用户它连接到互联网。)

答案 4 :(得分:-1)

我以前在应用程序商店购买和游戏中心都有这样的问题。而且我知道这听起来像是一个无答案,但它对我有用。

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

虽然我从未使用过基于订阅的购买,但就我所知,您的代码中没有任何内容显得不正确。

祝你好运。