iOS InAppPurchase 当首次支付失败时,如何判断交易所属?

everettjf
  • 54

网上有很多In-App Purchase(简称IAP)的文章,苹果的教程也比较丰富(https://developer.apple.com/in-app-purchase/https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction.html)。
但遇到一个问题始终没有找到答案。

IAP的基本思路就是:

  1. 查询产品,获取SKProduct的数组。

  2. 发起支付请求。

    SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
    payment.quantity = 1;
    payment.applicationUsername = [self hashedValueForAccountName:accountName];
    [[SKPaymentQueue defaultQueue]addPayment:payment];
    
    

注意:这里发起支付请求,我无法添加(或者说没找到)能在票据(receipt)中返回的数据。applicationUserName只是辅助苹果做一些恶意检测,但最终票据中没有包含。

  1. 等待支付结果

    -(void)paymentQueue:(SKPaymentQueue )queue updatedTransactions:(NSArray )transactions
    {

       for (SKPaymentTransaction *transaction in transactions) {
           switch (transaction.transactionState) {
                   // Call the appropriate custom method for the transaction state.
               case SKPaymentTransactionStatePurchasing:
                   [self showTransactionAsInProgress:transaction deferred:NO];
                   break;
               case SKPaymentTransactionStateDeferred:
                   [self showTransactionAsInProgress:transaction deferred:YES];
                   break;
               case SKPaymentTransactionStateFailed:
                   [self failedTransaction:transaction];
                   break;
               case SKPaymentTransactionStatePurchased:
                   [self completeTransaction:transaction];
                   break;
               case SKPaymentTransactionStateRestored:
                   [self restoreTransaction:transaction];
                   break;
               default:
                   // For debugging
                   NSLog(@"Unexpected transaction state %@", @(transaction.transactionState));
                   break;
           }
       }

    }

  2. 发送凭据到自己的服务器,并验证凭据,客户端完成支付。【关键这里有疑问】
    SKPaymentTransaction *transaction = <# The current payment #>;
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

如果按照正常流程,肯定没有问题。但苹果文档有句话:

if your app fails to mark a transaction as finished, Store Kit calls the observer every time your app is launched until the transaction is properly finished.

如果我没有主动完成交易,苹果会在下次启动App(或者说添加Observer)时,再次通知。
这里本地会有把票据持久化的操作。但有个很关键的问题,票据中不能带有自定义的信息。也就是返回的票据是不能知道哪个账号发起的支付请求(或许有,但我确实没有找到。如果有的话,就能解决这个问题了。)

我公司的App类似QQ(以下假设是QQ),QQ可以支持多个账号在一台手机上登录(比如有两个账号A和B)。

问题来了:
如果账号A使用IAP购买Q币,苹果服务器已经扣款,但

    -(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

还没有来得及调用。(实际测试中出现过这种情况。或者说在交易中的恰当时机主动断网,也能出现)

下次如果使用账号A登录,苹果会再次通知交易。这时把这次交易购买的产品算作账号A的,是没有问题。

但,如果下次使用账号B登录,由于返回的交易票据中没有包含账号的信息,我就不知道该把Q币充值给账号A还是账号B了。

找了好久,没有找到解决办法,请求大家帮忙。
谢谢!

回复
阅读 7.7k
1 个回答
weenxy
  • 2
新手上路,请多包涵

iOS7.0以后SKPayment新增了applicationUsername属性,这个可以用来设置用户信息。可以根据这个值来判断用户

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏