WWDC Quick Look 💓 By SwiftGGTeam
Manage in-app purchases on your server

Manage in-app purchases on your server

元の動画を見る

ハイライト

App Store Server API は取引履歴、サブスクリプション状態、返金情報の能動的な照会に対応します。Server Notifications V2 は 20 種類以上のイベントタイプを網羅し、Family Sharing 対応とサンドボックス環境の改善も追加されています。

主要内容

あなたの App にアプリ内課金機能があるとします。ユーザーが購入した後、クライアントは receipt をサーバーへ送り検証します。ただし、ユーザーがオフラインで購入したり、クライアントリクエストが失敗したりすることがあります。サーバー上の購入記録が完全であることをどう保証すればよいでしょうか。

App Store Server API と Server Notifications V2 を使うと、クライアントからの報告を受動的に待つのではなく、データを能動的に取得できます。

詳細

App Store Server API

01:14

Server API は RESTful インターフェイスの集合で、サーバーは JWT で認証してから呼び出せます。

取引履歴を照会する:

GET https://api.storekit.itunes.apple.com/inApps/v1/history/{originalTransactionId}

ユーザーの完全な取引履歴を返します。すべての更新、アップグレード、ダウングレード、返金が含まれます。

サブスクリプション状態を照会する:

GET https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/{originalTransactionId}

現在のサブスクリプションの詳細状態を返します。有効期限、自動更新状態、オファー種別などが含まれます。

02:30

キーポイント:

  • transactionId ではなく originalTransactionId で照会します
  • originalTransactionId はサブスクリプションのライフサイクル全体で変わりません
  • JWS(JSON Web Signature)形式の署名済みデータを返します
  • データが Apple 由来であることを確認するため、署名検証が必要です

Server Notifications V2

04:00

V2 の通知タイプは V1 の 10 種類から 20 種類以上に拡張され、サブスクリプションのライフサイクルにおける主要イベントをすべてカバーします。

通知タイプ説明
SUBSCRIBED新規サブスクリプション
RENEWAL自動更新の成功
DID_CHANGE_RENEWAL_STATUSユーザーが自動更新をオンまたはオフにした
DID_CHANGE_RENEWAL_PREFユーザーがサブスクリプションをアップグレードまたはダウングレードした
EXPIREDサブスクリプションの期限切れ
REFUND返金
REFUND_DECLINED返金の却下
CONSUMPTION_REQUEST消費データのリクエスト
REVOKEFamily Sharing の取り消し

05:15

キーポイント:

  • V2 通知にはより豊富な情報が含まれます
  • すべての通知は JWS 形式です
  • 署名検証が必要です
  • 200 以外を返した場合、Apple は数日以内に再試行します

JWS 署名を検証する

06:30

Server API と通知が返すデータはいずれも JWS 形式で、署名検証が必要です。

import CryptoKit

func verifyJWS(_ jwsString: String) throws -> Transaction {
    // 1. JWS の 3 つの部分を分離する
    let parts = jwsString.split(separator: ".")
    guard parts.count == 3 else { throw VerificationError.invalidFormat }

    // 2. header を解析し、証明書を取得する
    let headerData = base64Decode(String(parts[0]))
    let header = try JSONDecoder().decode(JWSHeader.self, from: headerData)

    // 3. Apple から公開鍵を取得し、証明書チェーンを検証する
    let certificate = try validateCertificateChain(header.x5c)

    // 4. 署名を検証する
    let signedData = Data((parts[0] + "." + parts[1]).utf8)
    let signature = base64Decode(String(parts[2]))
    let isValid = certificate.publicKey.isValidSignature(signature, for: signedData)

    guard isValid else { throw VerificationError.invalidSignature }

    // 5. payload を解析する
    let payloadData = base64Decode(String(parts[1]))
    return try JSONDecoder().decode(Transaction.self, from: payloadData)
}

07:45

キーポイント:

  • JWS は header、payload、signature の 3 部分で構成されます
  • Apple からルート証明書を取得し、証明書チェーンを検証します
  • 署名を検証して、データが改ざんされていないことを確認します
  • payload を解析して取引情報を取得します

Family Sharing

09:00

iOS 15 はアプリ内課金の Family Sharing に対応します。ユーザーが購入すると、家族メンバーは追加料金なしで自動的にアクセスできます。

Server API では inAppOwnershipType フィールドで区別できます。

  • PURCHASED:ユーザー本人が購入
  • FAMILY_SHARED:Family Sharing で取得

Family Sharing が取り消されると、サーバーは REVOKE 通知を受け取ります。

10:15

キーポイント:

  • inAppOwnershipType は購入と共有を区別します
  • REVOKE 通知は共有が取り消されたことを示します
  • 共有ユーザーのアクセス権を処理する必要があります
  • サブスクリプションと非消耗型アプリ内課金に適しています

サンドボックス環境の改善

11:30

サンドボックス環境には新機能が追加されました。

  • サブスクリプション加速テスト:サンドボックス内のサブスクリプション期間が圧縮されます(1 年 = 1 時間)
  • 返金テスト:サンドボックスで返金フローをシミュレートできます
  • Family Sharing テスト:サンドボックスで Family Sharing をテストできます
  • オファーテスト:サンドボックスで introductory offer と promotional offer をテストできます

12:45

キーポイント:

  • サンドボックスのサブスクリプション期間は加速され、更新テストがしやすくなります
  • サンドボックスは返金テストに対応します
  • サンドボックスは Family Sharing テストに対応します
  • テストアカウントは App Store Connect で管理します

重要ポイント

  1. Server API で購入状態を能動的に同期する。クライアント報告だけに依存せず、サーバーが定期的に取得してデータの一貫性を保ちます。入口 API:GET /inApps/v1/history/{originalTransactionId}

  2. Server Notifications V2 で状態変化にリアルタイム対応する。20 種類以上のイベントタイプがサブスクリプションのライフサイクル全体をカバーします。入口 API:サーバー URL を設定して JWS 通知を受信します。

  3. すべての JWS データの署名を検証する。中間者攻撃とデータ改ざんを防ぎます。入口 API:Apple ルート証明書 + JWS 署名検証。

  4. Family Sharing に対応するPURCHASEDFAMILY_SHARED を区別し、REVOKE 通知を処理します。入口 API:inAppOwnershipType + REVOKE 通知。

  5. サンドボックスで完全な購入フローをテストする。加速されたサブスクリプション期間を使い、更新、アップグレード、ダウングレード、返金をすばやくテストします。入口 API:App Store Connect サンドボックステストアカウント。

関連セッション

コメント

GitHub Issues · utterances