class SKReceiptRefreshRequest (英語)
概要
App Storeのレシートは、Apple証明書で署名されたバイナリ形式の暗号化ファイルです。この暗号化ファイルの内容を読み取るには、このファイルをverifyReceipt(英語)エンドポイントで処理する必要があります。エンドポイントからの応答には、読み取り可能なJSON形式の本文が含まれます。App Storeとの通信は、RFC 4627で定義されているJSON辞書によって構造化されています。バイナリデータは、RFC 4648で定義されているように、Base64でエンコードされています。安全なサーバからApp Storeでレシートを検証します。App Storeとの安全なネットワーク接続を確立する方法については、「安全でないネットワーク接続の回避(英語)」を参照してください。
警告
AppからApp StoreサーバのverifyReceipt(英語)エンドポイントを呼び出さないでください。接続のどちらの終端もコントロールすることができず、中間者攻撃を受けやすくなるため、ユーザーのデバイスとApp Storeとの間で信頼できる接続を直接構築することができません。
レシートデータを取得する
デバイス上のAppからレシートデータを取得するには、NSBundle(英語)のapp
(英語)メソッドでAppのレシートがある場所を特定した後、データをBase64でエンコードします。このBase64エンコードしたデータをサーバに送信します。
// Get receipt if available
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
do {
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
print(receiptData)
let receiptString = receiptData.base64EncodedString(options: [])
// Read ReceiptData
}
catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
}
レシートデータをApp Storeに送信する
サーバ上で、receipt-data
、password
(レシートに自動更新サブスクリプションが含まれる場合)、exclude-old-transactions
の各鍵を使ってJSONオブジェクトを作成します。詳細については、requestBody(英語)を参照してください。
このJSONオブジェクトを、HTTP POSTリクエストのペイロードとして送信します。SandboxでAppをテストする際やAppの審査中は、テスト環境URL https://sandbox
を使います。App StoreでAppが公開されている場合は、プロダクションURL https://buy
を使います。これらのエンドポイントの詳細については、verifyReceipt(英語)を参照してください。
重要
ステータスコード21007
が表示される場合は、まずプロダクションURLでレシートを検証してから、SandboxのURLで検証してください。この方法に従うと、Appのテスト中、App Reviewによる審査中、App Storeでの公開中にURLを切り替える必要がなくなります。
応答を解析する
App Storeの応答ペイロードは、responseBody(英語)にて詳細が示されるキーと値を含むJSONオブジェクトです。
配列に、非消耗型、非更新サブスクリプション、および以前にユーザーが購入した自動更新サブスクリプションのアイテムが含まれます。応答に含まれる値でApp内課金のタイプを確認し、必要に応じてトランザクションを検証します。
自動更新サブスクリプションのアイテムでは、応答を解析して、現在有効なサブスクリプションの期間に関する情報を取得します。サブスクリプションのレシートの検証時、latest
には最新のエンコードしたレシートが含まれ、これはリクエストのreceipt-data
と同じ値になります。また、latest
には、サブスクリプションのすべてのトランザクション(初回の購入とその後の更新を含むが、復元は含まない)が含まれます。
これらの値を使って、自動更新サブスクリプションの期限が切れているかどうかを確認できます。これらの値とexpiration
(英語)サブスクリプションフィールドを使って、期限切れの理由を取得します。