9

我的应用程序中有很多 1 次购买 IAP。用户可以很好地购买它们。

我的问题是,我正在与 Flurry 集成以跟踪实际购买,而不仅仅是恢复购买,但我SKPaymentTransactiontransactionState总是以.SKPaymentTransactionStatePurchased而不是SKPaymentTransactionStateRestored.

显然SKPaymentTransactionStateRestored只在 when 被调用- (void)restoreCompletedTransactions,但是我什么时候调用这个方法呢?

我的想法是购买应该是这样的:1)用户选择产品,2)询问用户是否愿意以 X 金额购买产品。3)服务器检查用户之前是否购买过,是否通过设置恢复SKPaymentTransactionStateRestored。否则,处理事务并设置SKPaymentTransactionStatePurchased。显然这是错误的,我想- (void)restoreCompletedTransactions在两者之间打电话???

谢谢,

将要

4

5 回答 5

9

编辑:

最初我发布了一个很长的、不需要的方法来完成我需要完成的工作,但正如您将在下面看到的那样,Matt 帮助我找出了我正在寻找的变量。

例如,假设用户之前购买了我的应用程序,购买了所有可用的非消耗性 IAP,然后删除了该应用程序。当用户重新安装应用程序时,我希望能够确定他们何时再次“购买”产品,是原始(第一次)购买,还是恢复购买?

我已经实现了一个“恢复所有购买”按钮,但假设用户忽略/没有看到它,并尝试选择他们之前购买的产品。

与正常购买一样,我执行以下操作:

if ([SKPaymentQueue canMakePayments])
{
      self.productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:productID]];

      self.productRequest.delegate = self;
      [self.productRequest start];
}
else
{
     //error message here
}

用户登录到他们的 iTunes 帐户后,该应用程序会告诉他们他们已经购买了这个,现在它将被恢复。将调用以下委托方法:

 -(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{   
    for (SKPaymentTransaction *transaction in transactions)
    {
        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchased:
            {
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                if(transaction.originalTransaction)
                {
                    NSLog(@"Just restoring the transaction");
                }
                else
                {
                    NSLog(@"First time transaction");
                }

                break;
            }
            default:
                break;
        }
    }
}

无论交易是修复还是首次购买,transaction.transactionState都将等于SKPaymentTransactionStatePurchased.

现在从这一点来看,我们如何确定该购买是原始购买还是修复购买?

简单:如上所见,只看是否transaction.originalTransaction被初始化。根据 Apple 的说明:// 仅当状态为 SKPaymentTransactionStateRestored 时才有效。

如果SKPaymentTransaction'soriginalTransaction被初始化,这意味着有一个先前的事务。否则,本次交易为原创!

再次感谢 Matt 为我指明了正确的方向,并使逻辑更加清晰!

于 2013-04-18T19:52:50.193 回答
7

规范的期望似乎是您提供一个调用restoreCompletedTransactions. 至于如果用户忽略了这一点,只是继续尝试通过你的购买界面来带回他已经购买的功能会发生什么,你可能会不必要地担心自己;文档说:

如果用户尝试购买可恢复的产品(而不是使用您实现的恢复接口),应用程序会收到该项目的常规交易,而不是恢复交易。但是,不会再次向用户收取该产品的费用。您的应用程序应将这些交易视为与原始交易相同的交易。

商店会弹出与用户交互的对话框(“你已经购买了这个,要不要再免费下载一次?”),免费重新购买的通知会paymentQueue:updatedTransactions:照常在你的,你可以使用它originalTransaction.transactionIdentifier来识别它与原始购买。

于 2013-04-18T20:57:31.083 回答
2

如果您正在实施应用内购买,则需要在应用中的某处放置一个恢复按钮,否则这是一个拒绝原因。您可以查看获取已购买产品列表,inApp Purchase iPhone一次。

编辑2:除了按下按钮以避免拒绝之外,可能还有其他方法。马特在评论中建议的一种方法是在应用启动时恢复,这对我来说似乎足以符合苹果的指导方针。

另请查看本教程的最后一部分,它提到了相同的问题,并展示了一种实现它的简单方法: http ://www.raywenderlich.com/21081/introduction-to-in-app-purchases-in-ios -6-教程

编辑:

//Draft implementation of transaction observer delegate

-(void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction * transaction in transactions) {
        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchased:                
                ...
            case SKPaymentTransactionStateFailed:
                ...
            case SKPaymentTransactionStateRestored:
                ...
            default:
                break;
        }
    };
}
于 2013-04-18T13:53:29.177 回答
0

Apple IOS SDK 文档实际上在这个问题上具有误导性,因为它说:

@property(nonatomic, readonly) SKPaymentTransaction *originalTransaction
The contents of this property are undefined except when transactionState is set to SKPaymentTransactionStateRestored.

问题是当用户点击你的购买按钮,完成购买过程,最后得到一个他已经支付并且他可以免费重新下载的消息时,你的观察者不会向你发送一个 SKPaymentTransactionStateRestored。它实际上向您发送了一个 SKPaymentTransactionStatePurchased。

好消息是,尽管有文档,但即使您的交易状态为 SKPaymentTransactionStatePurchased,您实际上也会获得属性 originalTransaction。只需测试该属性是否为零,您就会知道该交易是新购买还是免费恢复的旧购买。

于 2013-04-25T04:43:42.010 回答
0

据我观察,有两种可能的情况,用户可能不得不调用恢复购买,

  1. 如果您没有在后端服务器中维护购买信息:如果用户卸载应用程序或应用程序数据丢失的任何此类情况,您可能会丢失购买信息。在这种情况下,用户可以调用恢复,Storekit 将再次提供购买收据,您可以通过该收据确定用户是否之前购买过以及该购买现在是否有效。

  2. 如果您将购买信息存储在您的支持中(支持的 api 决定用户是否有订阅功能的特权):可能存在您能够从 Apple 购买但不知何故无法更新到您的服务器的情况,在这种情况下用户可以恢复购买将在您的后端服务器上更新购买信息,此后用户可以跨多个设备/平台/重新安装使用应用程序,但仍有权获得特权访问。

因此,始终建议在购买时在同一页面中显示恢复选项。如果用户在没有选择恢复的情况下无意中尝试购买,1.如果他选择了与当前有效onr相同的计划,他将被告知现有和订阅2.如果他选择除了当前订阅之外的其他计划,他/她将被告知当前订阅以及根据最新选择的计划升级/降级的选项。

于 2020-01-17T17:31:57.137 回答