【问题标题】:Auto-renewing subscription: app-store completes transaction despite finishTransaction not called自动续订订阅:尽管未调用 finishTransaction,但应用商店仍完成交易
【发布时间】:2013-12-02 17:03:48
【问题描述】:

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

这是怎么回事:

  1. 用户按下按钮购买续订订阅
  2. 用户提供他的 iTunes 密码并确认购买
  3. 应用将从应用商店收到的收据提交到我的服务器以检查有效性
  4. 服务器返回“ok”或“not ok”字符串。应用仅在“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");
    }

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

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

      祝你好运。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

          我认为在你调用recordSubscription方法之前,你可以调用finishfinishTransaction方法从支付队列中移除支付,因为你已经完成了苹果服务器的购买动作。

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

          希望对你有帮助。

          【讨论】:

            【解决方案5】:

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

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

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

            【讨论】:

            • 什么是企业,生产力?
            • 企业通常是可以使用订阅或许可(通过订阅)的 B2B(Business 2 Business)应用程序。 Enterprise 也可以是内部应用程序,但除非有业务要求订阅在内部应用程序中,否则您不会使用它。生产力就像 Evernote、Dropbox 等。这些不符合企业定义,因为它们可供普通人群使用,并且并非企业独有
            猜你喜欢
            • 1970-01-01
            • 2011-07-20
            • 2023-03-27
            • 1970-01-01
            • 2011-07-16
            • 1970-01-01
            • 2015-07-25
            • 1970-01-01
            • 2011-12-24
            相关资源
            最近更新 更多