iOS Subscription
Overview
iOSのサブスクリプション周りをまとめたセクション。
補足・歴史と検証の観点
StoreKit 1.x では、SKPaymentQueue や SKProductsRequest、SKReceiptRefreshRequest など複数のAPIを組み合わせて状態管理が必要だった。
すべての処理は SKProductsRequest → SKPaymentQueue → onTransactionUpdated のコールバックを通じて逐次処理されており、レシートの検証はアプリ内で独自にAppleのサーバーに送る必要があった。
購読状態の保持・復元・同期はアプリごとの実装に任されていたため、開発者の責任範囲が広かった。
StoreKit 2.x では、Swiftベースの非同期/構造化されたAPIが導入され、Transaction オブジェクトを通じて購入結果を非同期に受け取る形式へと進化した。
Transaction.currentEntitlements や Transaction.latest(for:) などのAPIにより、購読状態の取得・監視が簡易化され、購入処理やレシート検証が統一されたフローで書けるようになった。
ただし、App Storeとサーバー間での完全な購入状態の整合性を担保するには、依然としてレシート検証および App Store Server Notifications(v2)の活用が重要。
ネットワーク不良時には購入直後に即時検証ができないケースもあり、再送機構や再検証のリトライ設計が必要。
StoreKit 2の TransactionListener を導入することで、非同期にトランザクションが追加された際にリアクティブに処理を行うことが可能。
Appleは App Store Server Notifications(v2)の活用を強く推奨しており、初回購入・更新・解約・復旧などのイベントをリアルタイムで受け取ることで状態同期を確実に行える。
特に定期購読では、アプリ内での検出よりもサーバー側でのイベント検知が正確かつ持続性に優れている。
RevenueCatはStoreKit 2とApp Store Server Notificationsの両方に対応しており、初回購入の Transaction 受信とサーバー同期、レシートのアップロードと検証の再送、ネットワークが不安定な環境でもバックグラウンドでレシート送信をリトライ、サブスクリプション状態のクラウド管理とクロスデバイス復元などを自動化してくれる。
このため、アプリ開発者はStoreKitやレシートの信頼性を直接担保する必要がなくなり、ユーザー体験の一貫性を保ちながら安全な課金処理を実装できる。
定期購読課金(初回決済フロー)
初めてサブスクリプションを購入する際の基本的な購入処理フロー。
StoreKitのバージョンによって実装方法や流れが異なるため、以下にそれぞれのパターンを記述する。
StoreKit 1.x フロー
StoreKit 2.x フロー
RevenueCat を使った初回決済フロー
マーメイド図中の「RevenueCat Server」は、開発者が何も用意せずとも、RevenueCatが提供してくれる安全な中継・検証・状態管理のエンジンだと理解すればOK。
自前で Apple の verifyReceipt API を叩く必要も、ASSNの解析をする必要もなくなる。
定期購読課金(継続決済フロー)
定期購読の期間が終了し、App Storeによって自動的に課金・更新されるケース。ユーザーの操作は介在せず、更新結果をアプリまたはサーバーで検知する必要がある。
StoreKit 1.x フロー(継続決済)
StoreKit 2.x フロー(継続決済)
RevenueCat を使った継続決済フロー
補足・注意点
- ユーザー操作なしで行われるため、サーバーサイド通知(ASSN v2)の導入が事実上必須。
- StoreKit 2を使っていても、バックグラウンドで起きる更新を受け取るために
Transaction.updatesの購読が必要。 - RevenueCatを使用している場合、ASSNとStoreKitの監視はすべて自動化される。
定期購読課金(アプリ外購入フロー)
他のデバイスやApp Store経由でユーザーがサブスクリプションを購入した場合に、アプリ内でその購入を検知・反映する処理。
StoreKit 1.x フロー(アプリ外購入)
StoreKit 2.x フロー(アプリ外購入)
RevenueCat を使ったアプリ外購入の反映フロー
補足・注意点(アプリ外購入)
- ローカル状態とApp Storeの状態がずれている場合があるため、常に再確認が必要。
- 起動時または
viewWillAppearなどのタイミングで状態同期を行うのが一般的。 - RevenueCatでは自動的に同期されるため、開発者側で検出処理を書く必要はない。
定期購読課金(リストアフロー)
アプリ再インストール時や端末引き継ぎ時に、以前購入したサブスクリプションを復元するフロー。
StoreKit 1.x フロー(リストア)
StoreKit 2.x フロー(リストア)
RevenueCat を使ったリストアフロー
補足・注意点(リストアフロー)
- StoreKit 1では
restoreCompletedTransactions()の明示呼び出しが必要だが、StoreKit 2ではトランザクションのクエリ取得で代替可能。 - App Storeのレシートが失われている端末でも、Apple IDに紐づいた復元が可能。
- RevenueCatを使えば「復元」ボタンの処理も自動化され、プラットフォームごとの差異を吸収できる。