2016-08-17 14 views
2

私はサンドボックスユーザーを設定し、iPhoneデバイス上の1か月の自動更新サブスクリプションにサブスクライブしました。ユーザーのサブスクリプションが終了したかどうかを検出するにはどうすればよいですか?それは最終的に、この方法およびロジックを呼び出します有効期限の自動更新サブスクリプションの確認

[[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; 

私は、次のコードを持っている

- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue 
{ 
    for (SKPaymentTransaction *transaction in queue.transactions) { 
     if (transaction.transactionState == SKPaymentTransactionStateRestored) { 
      [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
      [self setSubscriptionActive]; // <-- Probably not the right way to restore subscriptions? 
      return; // Return because we have successfully set the subscribed state of the app. 
     } 
    } 
    [self purchase:self.validProduct]; // No valid transactions, so ask them to purchase. 
} 

私の問題は私の現在のロジック、そのなって二時間になりましたし、このテストを与えられたということですユーザーは常にコード行[self setSubscriptionActive];になります。したがって、彼のテストアカウントで支払った唯一の支払い額は常にSKPaymentTransactionStateRestoredです。 according to the documentation from Table 3-1 (Subscription durations for testing)が期限切れになることを期待しています...今私は何か間違っていますか、誰かがこの1ヶ月/タイムリーな定期購読の有効期限が切れているかどうかを検証する正しい方法を知っていますか?

私は、受信確認の記事に続いて、Appleのサンドボックスサーバー上の領収書をJSONに照会しようとしました。慎重にこのデータを見て、すべてがあり、これを破らどのように自分の目で確かめてください:私が見る二つの問題があります

"original_purchase_date" = "2013-08-01 07:00:00 Etc/GMT"; 
"original_purchase_date_ms" = 1375340400000; 
"original_purchase_date_pst" = "2013-08-01 00:00:00 America/Los_Angeles"; 
"receipt_creation_date" = "2016-08-18 01:05:09 Etc/GMT"; 
"receipt_creation_date_ms" = 1471482309000; 
"receipt_creation_date_pst" = "2016-08-17 18:05:09 America/Los_Angeles"; 
"receipt_type" = ProductionSandbox; 
"request_date" = "2016-08-18 01:05:09 Etc/GMT"; 
"request_date_ms" = 1471482309971; 
"request_date_pst" = "2016-08-17 18:05:09 America/Los_Angeles"; 

  1. は、これが最初の購入ですが、まだそれは2013-08-01 07:00:00 Etc/GMToriginal_purchase_dateを示しています。私は今日それを購入しました。この時間は8月17日のどこにもありません。これは非常に間違っています。

  2. receipt_creation_dateは、2016-08-18 01:05:09 Etc/GMTである。 request_date2016-08-18 01:05:09 Etc/GMTです...私は領収書を作成した分割をWebリクエストにしなければなりませんでした。私はrequest_date(このゴミのAPIの多くのようなもの)は有効なインターネット時刻が記録されていないので、(ローカル時間の代わりに)それとreceipt_creation_dateの間のデルタ時間を比較するために使用できると仮定しています。神様はこのような悪夢です...誰も誰もがこのような複雑でばかげたバックエンドシステムを作れるようにするのはなぜですか?これは絶対に恐ろしいことです。 Appleの他のAPIは一般的に優れているので、そのような残念なことです。

答えて

1

私は私のサブスクリプションは月のために良いです知っているので、このように私は月によってtransaction.transactionDateをインクリメントし、UTC時刻と比較することができます(ちなみに、ここで良いアイデアを得ることです解決策を見つけましたプロセスのうちUTC時刻ユーザーが自分のシステムクロックをバック設定することにより、自分のサブスクリプションを回避するような状況を持っていないように):

- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue 
{ 
    // Check all transactions for any that might be restoration candidates. 
    for (SKPaymentTransaction *transaction in queue.transactions) { 
     if (transaction.transactionState == SKPaymentTransactionStateRestored) { 
      [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
      NSCalendar *calendar = [NSCalendar currentCalendar]; 
      NSDate *expiration = [calendar dateByAddingUnit:NSCalendarUnitMonth value:1 toDate:transaction.originalTransaction.transactionDate options:0]; 
      if ([expiration earlierDate:self.currentUTCTime] == self.currentUTCTime) { 
       [self setSubscriptionInterfaceActive:true]; 
       return; 
      } 
     } 
    } 
    // There are no valid restorations, so we ask the user to subscribe here (this may obviously differ in your application as I am using a Purchase or Restore Subscription button in my app). 
    [self setSubscriptionInterfaceActive:false]; 
    [self purchase:self.validProduct]; 
} 
1

は、手動で日付を計算しないでください。 Apple's Validate App Store Receiptによれば、expires_dateを使用する必要があります。

このキーは、自動更新可能な定期購読でのみ表示されます。サブスクリプションが更新または期限切れになる日付を識別し、顧客がコンテンツまたはサービスにアクセスする必要があるかどうかを判断するには、この値を使用します。最新の領収書を検証した後、最新の更新トランザクションのサブスクリプション有効期限が過去の日付である場合、サブスクリプションが期限切れであると想定することは安全です。

関連する問題