2015-01-14 33 views
7

サーバー側でリンゴの領収書の検証に問題があります。 私はインターネットで解決策を見つけようとしましたが、成功しませんでした。アップルのアプリ購入の領収書 - サーバー側の確認

説明: まず、iOS7のアプリケーションが作成されています。第二に、私はいくつかの項目を持っています(type = Non-Renewing Subscription)。ユーザーは1つまたは複数のアイテムを購入することができます。その後、手動で更新する必要があります。

アプリケーションはサーバー側に領収書を送信し、私はアップルに要求し、の結果を多くの in_app領収書で取得します。ような何か:

"in_app":[ 
{ 
"quantity":"1", "product_id":"...", "transaction_id":"...", 
"original_transaction_id":"...", "purchase_date":"...", 
"purchase_date_ms":"...", "purchase_date_pst":"...", 
"original_purchase_date":"...", 
"original_purchase_date_ms":"...", "original_purchase_date_pst":"...", 
"is_trial_period":"..."}, 
{ 
"quantity":"1", "product_id":"...", 
"transaction_id":"...","original_transaction_id":"...", 
"purchase_date":"...", "purchase_date_ms":"...", 
"purchase_date_pst":"...", "original_purchase_date":"...", 
"original_purchase_date_ms":"...", "original_purchase_date_pst":"...", 
"is_trial_period":"..."} 
] 

ので、 "in_app" の各 "領収書は" TRANSACTION_IDました。しかし、どのようにして現在の購入のトランザクションIDを特定できますか?それを検証して、これがユニークであることを確認したいと思います。

私の懸念は、誰かが有効な領収書を受け取った場合、サーバーサイドAPIをハックして、同じ有効な領収書で無制限にアプリ内購入を行うことができるということです。

私は何とか復号化し、「元の」領収書であるtransaction_idを確認する必要がありますか?

ご協力いただきありがとうございます。 ありがとうございます。

よろしく、 マクシム

+0

LOL私はこれがちょうどSUX ...私はaccidentalyこれを発見し、あなたが8時間前にこれを尋ねたことがわかりました。..ちょうど同じ質問の男に聞いていた、私は何をすべきかも手掛かりを持っていませんすべての領収書... – Adrian

+0

そして私はあなたがここでやりたかったのと同じ種類の小切手をしたいと思います。私は誰かがこれを見てそれに答えることを願っています! :\ – Adrian

+3

私はキーが* app *側で現在の購入のトランザクションIDを取得し、領収書と共に、サーバーに送信することだと思う。アプリケーション側でトランザクションIDをトランザクションオブジェクトから取得できます。 –

答えて

0

@Dougスミス

https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html

あなたはこのページの異なるフィールドを通過した場合、あなたは見つけるでしょう

オリジナルトランザクション識別子:: 以前のトランザクションを復元するトランザクションの場合、元のトランザクションのトランザクション識別子。それ以外の場合は、トランザクション識別子と同じです。 この値は、元のトランザクションのtransactionIdentifierプロパティに対応します。 自動更新サブスクリプションの更新チェーンに含まれるすべての領収書は、このフィールドに同じ値を持ちます。

だからあなたの非自動再生可能なサブスクリプションのために、あなたは、サーバー側で二つのことを追跡する必要があります。

  1. あなたはiTunesサーバを検証する領収書の元のトランザクション識別子、アソシエイトこれは、データベース内のユーザーIDで行います。
  2. クライアント側から受け取った要求が購入または復元購入であるかどうか。

あなたがあなたと一緒にこれら二つのことをしたら、あなたは以下のようなこれら2つのパラメータであなたのロジックを記述することができます

::要求がタイプ「購入」であり、あなたはすでに元のトランザクション識別子を使用している場合他のユーザーIDに関連付けられた領収書のうち、その購入をブロックすることができます。

::リクエストが "Restore Purchase"タイプで、要求が、元のトランザクションIDがDBに関連付けられている同じユーザーIDから来ている場合は、別の方法で彼のリストアをブロックできます。

さらに、必要に応じて、これらのことに基づいて独自のロジックを導出できます。

ご不明な点がありましたら教えてください。

+0

私の問題は、トランザクションIDプロパティがレシートJSONの元のものから更新されないということです。 –

+0

しかし、あなたはJSONで2つの辞書を2つ受け取ります。 1つは元のトランザクションに対応し、もう1つは今実行したトランザクションに対応します。 –

0

新しいトランザクションごとに、リンゴはユニークな新しい領収書を送信し、誰もデータを偽造できないようにエンコードします。

完了したトランザクションのトランザクション領収書をエンコードしてサーバーに送信し、サーバー側でそれをデコードし、サーバーに送信する1つのappleと一致させます。

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions 
{ 
    _transactionArray = transactions; 
    for (SKPaymentTransaction * transaction in transactions) 
    { 
     switch (transaction.transactionState) 
     { 
      case SKPaymentTransactionStatePurchased: { 
       NSData *receipt = transaction.transactionReceipt; 
       [self sendReceiptToServer]; 
      } break; 

      case SKPaymentTransactionStateFailed: { 
       // finish this transaction 
      } break; 

      case SKPaymentTransactionStateRestored: 
       NSData *receipt = transaction.transactionReceipt; 
       [self sendReceiptToServer:receipt]; 
      } break; 

      default: 
       break; 
     } 
    }; 
} 


-(void)sendReceiptToServer:(NSData *)receipt { 
    // encode receipt 
    // send receipt to server 
    // add success and error callback 
} 

-(void) receiptSuccess { 
    // finish transaction here 
} 

-(void) receiptError { 
    // try again sending receipt to server 
} 
+0

このコードの問題点は、 です。1) ' - [SKPaymentTransaction transactionReceipt]'は、iOS7以降では非推奨です。代わりに '[[NSBundle mainBundle] appStoreReceiptURL]'を使用してください。 2)トランザクションは完了ステータスにかかわらず終了する必要があるため、すべてのケースで(デフォルトの場合を除いて) ' - [SKPaymentQueue finishTransaction:]'を呼び出す必要があります。 –

関連する問題