ApplePay アプリ内購入の新機能
iPhone、iPad、Mac、Apple Watchでアプリ内課金体験をさらに良くする方法を学びましょう。
StoreKit 2とApp Store Server APIの機能強化を案内し、App Store Server通知の改善を検討します。
App Transaction APIを使用してアプリの購入を検証し、StoreKitモデルにプロパティを追加し、SwiftUIフレンドリーなAPIとStoreKitメッセージを組み込み、トランザクションでapplicationUsernameを保持する方法を発見してください。
サーバー側で作業している人のために、App Storeサーバー通知を最大限に活用する方法、ユーザーのトランザクション履歴を取得する追加の方法、およびサーバーが停止した場合の回復手順を紹介します。
♪まろやかなインストゥルメンタルヒップホップ音楽♪ ♪ Dani Chootong: こんにちは、「アプリ内購入の新機能」へようこそ。私はダニで、StoreKitチームのエンジニアです。
WWDC
今日は同僚のイアンと発表し、今年のアプリ内購入にもたらす新しい改善点について見いきます。
昨年、アプリ内購入を簡単に統合できるように、ゼロから設計された新しいAPIのセットであるStoreKit 2を導入しました。
StoreKit 2は、async/awaitパターンを使用したSwiftの並行性を含む最新の言語機能を使用しています。
サーバー側では、まったく新しいApp Store Serverエンドポイントセットでこれらの新しいStoreKit機能を補完しました。
これらのサーバーエンドポイントを使用すると、トランザクション情報を簡単に取得し、サーバーのサブスクリプションステータスを確認できます。
また、サーバー上のサブスクリプションライフサイクルの追跡をこれまで以上に簡単にするために、App Storeサーバー通知のバージョン2をリリースしました。
今日は、これらの新しいAPIと、新しいStoreKitモデルにもたらす機能強化について取りに行きます。
その後、イアンは、App Store Server APIの強化やApp Store Server通知用の新しいAPIなど、いくつかのエキサイティングな新しいサーバーアップデートをご案内します。
まず、アプリの購入を確認するために、新しいアプリトランザクションAPIを確認します。
次に、StoreKitモデルに追加した新しいプロパティを掘り下げます。
サブスクリプションオファーコードを引き換え、顧客にアプリのレビューを依頼するための新しいSwiftUIフレンドリーなAPIを紹介します。
次に、App Storeメッセージを顧客に表示するために使用されるAPIであるStoreKitメッセージを紹介します。
そして最後に、オリジナルから最新のStoreKit APIに移行する際に、アプリケーションのユーザー名を維持するために追加している機能強化について検討します。
このプレゼンテーションを通して、私はお気に入りのアプリ、フードトラックを使います。
フードトラックアプリでは、ドーナツの配達をするためにさまざまな都市を訪れるポップアップドーナツフードトラックを管理しています。
では、始めましょう!アプリトランザクションに会う。
アプリトランザクションは、アプリの購入を確認するための新しいAPIです。
アプリトランザクションは、実行中のデバイスのアプリを購入するための署名された情報を表します。
JWSを使用して署名され、元のStoreKit APIからアプリの領収書のアプリ詳細部分を置き換えます。
トランザクション検証と同様に、StoreKitはアプリトランザクションの自動検証を実行します。
ただし、必要に応じて、独自の検証を実行することもできます。
JWS署名の検証は、十分に文書化された標準です。
公開ドキュメントを参照して、独自の検証を実装できます。
StoreKitは、必要に応じてアプリトランザクションを自動的に更新します。
しかし、まれにユーザーが何か問題があると思う場合は、リフレッシュすることができます。
顧客がアプリトランザクションを更新できるように、アプリにUIを提供する必要があります。
これは、アプリトランザクションを更新するとユーザーに認証を促すため、ユーザーのアクションに応答してのみ使用する必要があります。
詐欺を防ぐことは、アプリトランザクションを愛する唯一の理由ではありません。
ビジネスモデルを有料アプリからアプリ内購入を提供する無料アプリに切り替えたい場合、どの顧客がアプリを予約注文したかに興味がある場合、またはアプリがいつ購入されたかを知りたい場合でも、これらはすべてApp Transactionで処理できる状況です。
アプリの領収書では、領収書のペイロードは、アプリケーションに関する購入データと、発生したすべてのアプリ内購入を組み合わせます。
これらは現在、StoreKitで2つの別々のコンポーネントに分かれています。
1つ目は取引履歴です。
StoreKitのトランザクションAPIは、デバイス上で、ユーザーのアプリ内購入履歴全体についての洞察を提供します。
これらのAPIを使用すると、ユーザーの最新のトランザクション、未完了のトランザクション、現在の資格など、必要な正確な情報を見つけることができます。
サーバーでこれらの計算を実行したい場合は、App Store Server APIからユーザーの購入履歴を取得することもできます。
イアンは、このセッションの後半にいくつかのエキサイティングなアップデートを行います。
そして、2番目のコンポーネントはアプリトランザクションで、アプリが実行されているデバイスに対して有効であることを確認するために必要なデータが含まれています。
アプリトランザクションを使用してアプリの購入を確認するのは簡単で、すぐに、それを使用する方法の例について説明します。
しかし、まず、私のお気に入りのアプリについての背景をいくつかお伝えします。
フードトラックを使用すると、ドーナツの配達を行い、基本的なソーシャルフィードをチェックし、販売履歴を視覚化することができます。
これらすべての情報をデータベースに保存することは、私のアプリの継続的なコストなので、コストをカバーするために、年間販売履歴チャートを1回限りの購入に変えるつもりです。
さらに、ソーシャルフィードを強化したいです。
だから、他の人が私のフードトラックについて言っていることを見るのではなく、私も顧客と関わることができるようにツールを提供したいです。
これはサブスクリプションサービスになり、私は月額プランと年間プランを持っています。
フードトラックは有料アプリとして始まりましたが、アプリ内購入を提供する無料アプリに切り替えるつもりです。
しかし、すでにフードトラックを購入した既存の顧客に取り残されたと感じてほしくない。
したがって、アプリトランザクションを使用して、フードトラックを購入した顧客が支払ったプレミアムコンテンツに引き続きアクセスできるようにします。
これがフードトラックのタイムラインです。
最初のリリースでは、フードトラックは4.99ドルの有料アプリとして始まりました。
バージョン1.0は、ドーナツの配達、基本的なソーシャルフィード、販売履歴チャートを提供しました。
その後、バージョン8.0のリリースで、私のビジネスモデルが変わりました。
フードトラックは現在無料ですが、プレミアム機能のロックを解除するさまざまなアプリ内購入が含まれています。
年間販売履歴チャートは現在、非消費の1回限りの購入であり、高度なエンゲージメントツールを提供するプレミアムソーシャルフィードの新しいサブスクリプションサービスがあります。
それでは、この影響を受ける可能性のある2種類の顧客を見てみましょう。
アリスはバージョン2.5で私のフードトラックアプリについて知り、デジタル世界でドーナツへの情熱を共有したいと決めました。
それで、彼女は私のアプリを4.99ドルで購入し、ドーナツ配達の旅を始めました。
2番目の顧客、ボブは、友人を通して私のフードトラックアプリについて知り、バージョン8.2のApp Storeで無料でダウンロードします。
このシナリオでは、無料になる前に私のアプリを購入したアリスは、すでに支払ったすべてのプレミアムコンテンツにアクセスできるはずです。
彼女はまだプレミアムソーシャルフィードサブスクリプションを購入するオプションを持っていますが、最初に含まれていた年間販売履歴チャートを否定したくありません。
しかし、ボブは私のアプリを無料で手に入れました。
私は、彼らがアプリ内購入を完了するまで、機能やコンテンツのロックを解除しないことを知っています。
では、コード内のアプリトランザクションでこれをどのように達成できるかを見てみましょう。
AppTransaction.sharedを呼び出してアプリトランザクションを取得することから始めます。
この呼び出しは、私のアプリトランザクションを含むVerificationResultを取得します。
結果の中で、AppTransactionタイプにはJWSペイロードが含まれています。
次に、結果をオンにします。
結果が未確認の場合、これはアプリの購入がApp Storeで確認できないことをユーザーに警告する良い機会であり、その後、アプリのトランザクションを更新するように促すことができます。
現時点では、私のアプリに最小限の体験を提供します。
結果が確認されたら、これをユーザーが私のアプリを購入したかどうかを確認する機会として利用します。
私のアプリを購入したお客様には、支払ったサービスが付与されるべきです。
これには、元のアプリバージョンのプロパティを使用します。
このプロパティは、顧客が私のアプリを初めてダウンロードしたアプリのバージョンを知らせてくれます。
バージョン8.0は、私のアプリがアプリ内購入で無料になったバージョンです。
ユーザーの元のアプリバージョンを私の機能に渡して、ユーザーがバージョン8.0より前にアプリを購入したかどうかを確認します。
そして、それにより、ユーザーにプレミアムコンテンツをどのように提供すべきかについて、情報に基づいた決定を下すことができます。
私のアプリを購入したアリスのようなお客様には、ユーザーが購入時に持っていたコンテンツを提供します。
私の場合、私は彼女の配達の年間販売履歴チャートのロックを解除するつもりです。
また、彼らが行った可能性のある追加のアプリ内購入を確認したいので、それも提供できます。
そうでなければ、ボブのようにビジネスモデルを切り替えた後、ユーザーが私のアプリをダウンロードしたと確信できます。
これは、ユーザーが支払った機能やコンテンツのロックを解除できるように、ユーザーの現在の資格を確認する良い機会です。
そして、ほんの数行のコードで、アプリの購入を確認し、ユーザーが私のアプリの有料版をダウンロードしたかどうかを確認し、顧客が私のアプリを購入したかどうかにかかわらず、すぐにプレミアムコンテンツの提供を開始できます。
App Transactionを使用すると、早期のサポーターでも、最近アプリをダウンロードしたばかりの場合でも、顧客を簡単にサポートできます。
では、StoreKitモデルに追加する新しいプロパティに移りたいと思います。
これらのプロパティの最初のものは、価格ロケールです。
価格ロケールは現在、StoreKit製品に含まれています。
オリジナルの購入APIとのインターフェースから、すでに価格ロケールに精通しているかもしれません。
次に、サーバー環境のプロパティを掘り下げます。
これで、トランザクションまたは更新情報が発生したことをサーバー環境に伝えることができます。
次に、最近のサブスクリプション開始日のプロパティに移動します。
これをツールとして使用して、サブスクリプションパターンに基づいて顧客のために情報に基づいた決定を下すことができます。
そして最後に、XcodeのStoreKitテストで使用する際に、これらのプロパティに関するいくつかの特別な考慮事項について説明します。
これらのプロパティは、古いオペレーティングシステムでセンチネル値を返し、これが何を意味するのかを少し説明します。
StoreKit APIは柔軟性を念頭に置いて設計されているため、もともと出荷されていなかったにもかかわらず、昨年のオペレーティングシステムにさかのぼるデバイスでこれらの新しいプロパティを活用できることを発表できることを誇りに思います。
これを実現するために必要なのは、Xcode 14を使用してアプリを構築することだけで、以前のオペレーティングシステムでこれらのプロパティにアクセスできます。
これは、これらのプロパティの実装がアプリにコンパイルされるため、顧客が新しいバージョンに更新すると、オペレーティングシステムを更新せずにこれらの機能強化の恩恵を受けることができます。
ただし、これらのプロパティを使用する際に留意すべき点が1つあります。
これらの古いオペレーティングシステムでXcodeでStoreKitテストを使用している場合、これらのプロパティはセンチネル値を返します。
私がセンチネル値と言うとき、私はこれらがあなたが作業すべき実際の値ではないことを示すプレースホルダ値を指しています、そして私はこれが起こる理由を説明します。
サンドボックスと本番環境は、App Storeサーバーの応答から値を抽出することで、これらのプロパティを利用します。
ただし、XcodeでのStoreKitテストは、App Storeサーバーとは独立して動作するローカルテスト環境です。
これは、これらのプロパティの値を以前のオペレーティングシステムにバックポートできないことを意味します。
テストデバイスを新しいオペレーティングシステムに更新することで、この制限を簡単に回避でき、ローカル環境でこれらの値をテストできます。
これらの新しいプロパティの使用を開始する方法を示すいくつかの状況について話し合いましょう。最初は価格ロケールです。
StoreKit製品にはすでに購入価格をラベル付けするための表示価格プロパティがありますが、価格ロケールを使用すると、製品の10進価格から派生した数字をフォーマットできます。
年間サブスクリプションをお持ちの場合は、これを顧客に月額の費用を示す機会として使用するかもしれません。
この例では、年間サブスクリプションの金額が月額4.17ドルであることがわかります。
または、毎月のサービスよりも年間サービスを購入した場合、どれだけ節約できるかを彼らに示したいと思うかもしれません。
この情報により、顧客は購入オプションを検討する際に、情報に基づいた決定を下すことができます。
では、環境プロパティに移りましょう。
環境プロパティは、トランザクションと更新情報で利用できます。
このプロパティは、トランザクションまたは更新情報が発信されたサーバー環境を示します。これは、Xcode、サンドボックス、または本番環境です。
顧客が簿記と分析のために購入した後、アプリは取引情報をサーバーに伝達することがあります。
アプリがこれらのトランザクションを生成するとき、それはこれらのサーバー環境のいずれかからである可能性があります。
ほとんどの人と同じように、私は無関係なテストデータで私の分析にノイズを追加したくありません。
したがって、環境を知ることは、不要な情報がサーバーに送信されるのをフィルタリングするのに役立ちます。
最後に、最近のサブスクリプション開始日を見てみましょう。
最近のサブスクリプション開始日は、製品のサブスクリプション情報内で利用でき、継続的なサブスクリプションの最新の期間を表します。
サブスクリプションは、2つの購読期間の間に60日以上のギャップがない場合、継続的と見なされます。
この期間には、顧客が製品を購読していないギャップが含まれている可能性があるので、これを顧客が購読した日数の指標として使用しないでください。
最近のサブスクリプション開始日は、あなたとあなたの顧客との間の忠誠心のパターンを決定するのに役立ちます。
あなたの忠実な顧客のために、あなたは彼らがあなたの製品に従事し続ける方法として彼らに報酬を提供するかもしれません。
または、顧客がサービスの購読を解除したことに気付いた場合は、製品を再び使用し始めるインセンティブを提供することで、失効した顧客を取り戻すチャンスとして使用できます。
先ほど、これらのプロパティのセンチネル値を詳しく調べると述べました。
リマインダーとして、私がセンチネル値と言うとき、私は実際の値の欠如の指標として機能するプレースホルダ値を指しています。
これらのプロパティのセンチネル値は簡単に識別できます。
価格ロケールを扱う場合、センチネル値は識別子xx_XXのロケールです。
環境プロパティの場合、空の文字列になります。
そして最後に、最近のサブスクリプション開始日の場合、この値はDate.distantPastです。
幸いなことに、これらのセンチネル値の発生は予測可能です – 古いオペレーティングシステムでXcodeでStoreKitテストを使用している場合にのみそれらに遭遇し、テストデバイスを更新することでこれを回避できます。
これで、StoreKitモデルの機能強化がわかりました。
そして、私のお気に入りの部分は、モデルが導入されたオペレーティングシステムまでずっと下位互換性があるので、顧客はアプリを更新するだけですぐに利点を見ることができます。
価格値で算術を実行すると、価格ロケールはApp Storeのロケールと一致するように正しくフォーマットするのに役立ちます。
トランザクションとサブスクリプション情報の場合、環境はそれらがどこから発信されたかを正確に教えてくれるので、このデータをサーバーに保存すると、環境に応じてそれに応じて行動することができます。
最近のサブスクリプション開始日は、顧客のロイヤルティを理解するのに役立つため、長年の顧客に特定のオファーを調整したり、購読を解除した顧客にインセンティブを提供することもできます。
そして、あなたが疑問に思っていた場合に備えて、はい、環境と最近のサブスクリプション開始日は、イアンが議論するApp Store Server APIとApp Store Server Notificationsを介しても利用できます。
さて、オファーコードの引き換えとレビューのリクエストのために提供している新しいSwiftUI APIについて話したいと思います。
オファーコードは、期間限定でサブスクリプションを割引または無料で提供することで、加入者を獲得し、維持し、獲得するのに役立ちます。
App Store Connectでは、一意の名前のカスタムコードを作成できます。
そこでは、最大償還限度額を設定し、有効期限を設定するかどうかを選択できます。
SwiftUIの実装を見て、アプリから直接オファーコードの引き換えシートを提示しましょう。
ここでは、オファーコード引き換えシートをトリガーするボタン付きのSwiftUIビューがあります。
オファーコード償還シートには、SwiftUIで独自のビュー修飾子が追加されました。
ビュー修飾子は使いやすく、プロセスを開始するにはバインディングブール値が必要です。
そして、オファーコードシートが却下されると、シートが正常に提示されたかどうかを表す結果が得られます。
顧客がアプリのオファーコードを引き換えると、結果のトランザクションがトランザクションリスナーに送信されます。
したがって、アプリの実行中に新規および更新されたトランザクションを受信するために、アプリが起動したらすぐにトランザクションリスナーを設定してください。
オファーコードビュー修飾子は、iOS 16から利用できます。
次に、レビューをリクエストするための更新について話したいと思います。
顧客からのフィードバックを得ることは重要です。
潜在的な新規顧客は、アプリをダウンロードする決定の決定的な要因としてレビューを使用するかもしれません。
他の人は、フィードバックや提案を提供する方法としてレビューを残したいと思うかもしれません。
いずれにせよ、顧客に簡単に評価をリクエストできるツールを提供したいので、あなたが聞いていることを彼らに知らせ、彼らと関わり続けることができます。
コードを見直しましょう。
ここでは、リクエストレビューAPIを実証するための非常に簡単なビューがあります。
SwiftUIには、requestReviewという環境値が追加されました。
この値を使用してRequestReviewActionのインスタンスを取得でき、評価を要求する準備ができたら、レビュープロンプトを表示するように要求する関数としてインスタンスを呼び出すだけです。
アプリのレビューをリクエストする適切な時期を決めることができます。
ただし、プロンプトは365日以内に最大3回しか顧客に表示されないことに注意してください。
また、同じバージョンのアプリを複数回確認するよう顧客に依頼すべきではありません。
レビュープロンプトで顧客の邪魔をしないでください。
レビューを求めるのに良い時期は、eコマースアプリでの購入を完了したり、ゲームのレベルを完了したりするなど、ポジティブなやり取りをした後かもしれません。
最後に、顧客はデバイスに表示されるリクエストを無効にできるため、ユーザーのアクションの結果としてレビューをリクエストすべきではありません。
これらのAPIは、SwiftUIアプリに本当に役に立ちます。
次に、StoreKitメッセージ用の新しいAPIをご紹介します。
StoreKitメッセージは、重要な情報をユーザーに表示するためにアプリ上に表示されるシートを表します。
メッセージはApp Storeによって販売されます。
各メッセージには理由があり、メッセージのメタデータに含まれています。
StoreKitメッセージは、アプリがフォアグラウンドになると取得されます。
例として、メッセージの理由の1つである値上げの同意を見てみましょう。
サブスクリプションの価格を引き上げ、ユーザーの同意が必要な場合、App Storeは電子メール、プッシュ通知、およびアプリ内価格同意シートを通じて影響を受ける加入者に通知します。
この場合、App Storeでは、より高い価格で更新する前に、ユーザーがサブスクリプションの新しい価格に同意する必要があります。
したがって、サブスクリプションに対してより多くを請求することにした場合、ユーザーがアプリを開くと、値上げにまだ応答していない場合、値上げ同意書が表示される場合があります。
デフォルトでは、ユーザーがアプリをフォアグラウンドに持ち込むと、StoreKitメッセージがアプリ上に表示され、アプリに関連する何らかのアクションを実行するようユーザーに要求する場合があります。
これを見直しましょう。
プロセス全体はアプリから始まります。
アプリがフォアグラウンドに入ると、StoreKitは表示する保留中のメッセージがあるかどうかを確認することを知っています。
そして、もしあれば、StoreKitはApp Storeにチェックインします。
App Storeは、メッセージに関する情報をStoreKitに返します。
現時点では、StoreKitはアプリがメッセージを受信するように設定されているかどうかを確認します。
アプリでメッセージリスナーを設定することでこれを行うことができます。すぐに取り込みます。
アプリがメッセージリスナーを設定している場合、StoreKitはメッセージに関する情報をアプリに送信します。
今が、アプリがメッセージを表示するのに良い時期かどうか、またはプレゼンテーションを後で延期するかどうかを決定するチャンスです。
メッセージリスナーを設定しない場合、StoreKitはアプリ上にメッセージシートを表示することで、すぐにメッセージを表示します。
コードでこれを行う方法について説明します。
しかし、その前に、App Storeメッセージの表示を制御するのに役立つ状況を説明します。
フードトラックアプリでは、さまざまな都市に配達するドーナツをカスタマイズできます。
この間にメッセージが私のアプリに配信された場合、メッセージシートによって突然中断された場合、ユーザーは混乱を招くので、受信メッセージがいつ表示されるかを制御することによって、これが起こらないようにメッセージAPIを実装するつもりです。
では、コードに入りましょう。
ここでは、ドーナツエディタの簡単なビューがあります。
先に述べたように、アプリがフォアグラウンドに来るたびに保留中のメッセージが送信されます。
だから、メッセージの提示を延期したい各ビューでメッセージリスナーを設定したい。
編集ビューにいる間にアプリに配信されるすべてのメッセージを収集するためのバインディング配列を追加します。
メッセージリスナーを設定しないと、アプリがフォアグラウンドになるとすぐにメッセージシートを表示するので、これは重要です。
ビューが表示されたらすぐに、メッセージリスナーを設定しました。
これを行うには、メッセージタイプの静的プロパティを反復するタスクを設定します。
このプロパティは非同期シーケンスであり、メッセージが入ってくると受信できます。
私のユースケースでは、pendingMessages配列にメッセージを保存します。
保留中のメッセージは、アプリがフォアグラウンドに入るたびに配信されるため、アプリは同じメッセージを複数回受信する可能性があるため、配列に重複したメッセージを追加しないようにします。
次に、ビューが閉じたら、親ビューにメッセージを表示します。
これは、ドーナツエディタへのナビゲーションリンクを保持する親ビューです。
ここでは、このpendingMessages配列に表示する必要があるすべての保留中のメッセージを収集しました。
では、これらの保留中のメッセージを表示するにはどうすればよいですか?さて、今は環境valuedisplayStoreKitMessageがあります。
これにより、DisplayMessageActionのインスタンスを取得し、特定のメッセージを表示するために使用できます。
ビューが表示されたら、保留中のメッセージに反復し、表示したいメッセージでdisplayStoreKitMessagepassingを呼び出します。
StoreKitはメッセージシートの提示を担当します。
先ほど、同じメッセージがアプリに複数回配信される可能性があると述べました。
これは、メッセージがユーザーに提示されるまで既読としてマークされないためです。
したがって、StoreKitは、各固有のメッセージが1回しか表示されないようにします。
そして、それはメッセージAPIの迅速な実装でした。
StoreKitメッセージはフォアグラウンドに来るたびにアプリに送信されるので、メッセージが表示されるタイミングを制御する各ビューでメッセージリスナーを設定する必要があります。
メッセージシートが予期せぬ瞬間に表示されないようにすることで、顧客が素晴らしい体験を得られるようにします。
または、特定のメッセージタイプに合わせてロジックを調整したいかもしれません。
値上げ同意メッセージを使用すると、値上げ同意シートが表示される前に、提供している付加価値について顧客を教育したいと思うかもしれません。
最後に、ユーザーが購入した後、StoreKitがapplicationUsernameをappAccountTokenとして保存する方法を確認しましょう。
サーバーにユーザーアカウントシステムがある場合は、すでにapplicationUsernameプロパティを使用している可能性があります。
applicationUsernameは、トランザクションをサービスのユーザーアカウントに関連付けるために作成する文字列です。
アプリ内購入の元のAPIでは、支払いキューに支払いを追加するときにapplicationUsername値を設定します。
applicationUsernameは任意の文字列を受け入れますが、UUIDの文字列表現を提供することをお勧めします。
UUID文字列を指定すると、StoreKitは値を保持し、キューが更新するトランザクションにそれが表示されます。
applicationUsernameにUUID文字列を提供しない場合、StoreKitはそれを保持しない可能性があります。
支払いトランザクションをキューに追加してからキューがトランザクションを更新するまで、値が持続する保証はありません。
UUIDの文字列表現を提供すると、どのアプリのユーザーアカウントがトランザクションを開始し、トランザクションを完了しているかを識別できます。
現代のStoreKit APIでは、この概念をappAccountTokenと呼ばれる購入オプションとして実装しており、UUID形式が必要です。
これで、支払い時にapplicationUsernameをUUID文字列に設定すると、App StoreサーバーはそれをappAccountTokenとして保存します。
したがって、そのUUIDは、App Store Server APIによって返された署名されたトランザクション情報とV2 App Store Server Notificationsに表示されます。
また、UUIDとして、最新のStoreKitトランザクションAPIのappAccountTokenと互換性があります。
したがって、コードベースを最新のStoreKit APIに更新すると、アプリケーションユーザー名に使用したUUIDがStoreKitトランザクションでappAccountTokenとして保持されることを確認できます。
今日はたくさんのことに触れました。
サーバーのアップデートに進む前に、今年のStoreKitのアップデートを確認しましょう。
App Transactionでアプリの購入を検証し、オファーコードを引き換え、SwiftUIでレビューを要求し、StoreKitメッセージの表示を制御することについて話し合いました。
新しい価格ロケール、環境、最近のサブスクリプション開始日のプロパティについて話しました。
そして、アプリケーションユーザー名にUUIDの文字列表現を使用して、アプリアカウントトークンとして永続化することの重要性について説明しました。
他のセッション「StoreKitテストの新機能」をチェックすることを強くお勧めします。また、StoreKit 2 APIの復習が必要な場合は、昨年のセッション「Meet StoreKit 2」をチェックしてください。今、私はそれをイアンに渡して、App Storeサーバーのアップデートを案内したいと思います。
イアン・ザンガー:ありがとう、ダニ。
みなさん、こんにちは。私の名前はイアンで、App Store Serverチームのエンジニアです。
StoreKitでのアプリ内購入に関する最新情報を聞いたので、ギアを切り替えてサーバーについて話します。
まず、App Store Server APIとApp Store Server Notifications Version 2に登場するエキサイティングな新しいアップデートに進む前に、過去1年間の最近の開発を確認します。
始めましょう。
去年は大きかった。
これらすべての新機能の完全なサンドボックステストサポートを含む、App Store Server APIとApp Store Server Notifications V2を備えたまったく新しいエンドポイントスイートをご用意しました。
トランザクション履歴の取得エンドポイントを使用してユーザーのアプリ内購入の完全な履歴を取得する方法、またはすべてのサブスクリプションステータスの取得エンドポイントを使用して、ユーザーのサブスクリプションの現在の状態を最新の状態に保つ方法を共有しました。
これらのエンドポイントは両方とも、ユーザーの元のTransactionIdから便利にキーオフするので、この1つの単純な値だけを格納することで、このデータの宝庫にアクセスできます。
また、App Store Server Notificationsのバージョン2がサーバー上のイベント処理を簡素化し、App Store Server APIを補完する方法についても説明しました。
V2通知を使用すると、App Storeサーバーはサーバーに直接電話をかけ、アプリ内購入の更新を提供します。
合理化された通知タイプとサブタイプにより、何が起こっているのかを簡単に理解できます。
これらを使用して、アプリ内サブスクリプションやその他のイベントに関連する変更を追跡できます。
これらすべてのデータソースで、私たちはそのデータをできるだけ簡単に解析できるようにしたいと考えました。
これらの新しいサービスは、署名されたJSON形式でアプリ内データを提供するため、簡単に解析し、App Storeサーバーから来たことを信頼できるため、領収書は過去のものになりました。
昨年はApp Storeサーバーにとって大きな年でした。
これらすべての新機能を活用するためにサーバーコードの更新に取り組んだ場合、それはあなたにとっても大きかったかもしれません。
App Store Server APIとApp Store Server Notifications V2に強力な新しい機能強化と機能をもたらすため、努力は引き続き報われますのでご安心ください。
それは私たちのレビューの年ですが、今年のアップデートを聞いた後、より多くの復習をご希望の場合は、「サーバーでのアプリ内購入の管理」、「StoreKit 2に会う」、「顧客をサポートし、払い戻しを処理する」というタイトルのWWDC21セッションを必ずチェックしてください。それでは、WWDC22のApp Storeサーバーに登場するまったく新しいアップデートに移りましょう。
まず、トランザクションと更新情報フィールドの更新を共有します。
次に、App Store Server APIの新しい機能強化について説明します。
そして最後に、App Store Server Notifications V2に登場するエキサイティングな新機能を紹介します。
それでは、新しいトピックの最初のトピックに飛び込みましょう。トランザクションと更新情報で見つかった新しいフィールドです。
以前、アプリ内購入の取引と更新情報にいくつかの新しいフィールドについてDaniから聞きました。
これらのフィールド、環境、および最近のSubscriptionStartDateは、App Store Server APIおよびV2 App Store Server通知から受け取るトランザクションおよび更新情報のペイロードにも届きます。
これらの新しいフィールドを含めて、App Storeサーバーから受け取ることが期待できるデータをもう一度見てみましょう。
1つ目は、デコード後にここで見ることができるトランザクション情報ペイロードです。
下部には、私たちの新しい分野である環境が見えます。
トランザクションが本番環境で行われたかサンドボックス環境で行われたかを一目で確認できます。
次は更新情報ペイロードで、デコード後にここでも見られます。
ご覧のとおり、環境フィールドもここで参照できます。
さらに、最近のSubscriptionStartDateは、すべての更新情報ペイロードに表示されるようになりました。
これは、60日以下のギャップを無視して、最新の更新でユーザーの最初のサブスクリプション購入の開始日です。
recentSubscriptionStartDateは、顧客のロイヤルティを一目で把握する簡単な方法です。
ただし、サービスのギャップのタイミングや長さなど、詳細をご希望の場合は、Get Transaction Historyエンドポイントに電話して、ユーザーのサブスクリプション更新購入の完全な履歴を調べることができます。
または、さらに詳細については、App Store Server Notifications V2では、App Storeサーバーはユーザーのサブスクリプションに関する更新を自動的にサーバーに送信します。
これらの通知は、更新設定の変更、オファーの償還、請求の失敗などのイベントのタイミングについて最大限の洞察を提供します。
ご覧のとおり、最近のSubscriptionStartDateは、顧客ロイヤルティを決定するための一連のオプションを締めくくっています。
これらのツールを使用して、オファーをターゲットにし、最も忠実な顧客に報酬を与えます。
それでは、Get Transaction Historyエンドポイントの便利な新しい機能強化に移りましょう。
トランザクション履歴の取得エンドポイントを使用すると、アプリでユーザーの購入履歴の全履歴を取得できます。
エンドポイントの応答はページ分割されているため、このデータを合理的なチャンクで処理できます。
各応答には、次のページを取得するために次のリクエストで提供するリビジョントークンが含まれています。
また、ページは変更された日付でソートされています。つまり、後続の各ページには、最近変更されたトランザクションが含まれています。
これがどのように機能するかを見てみましょう。
トランザクション履歴の取得エンドポイントを呼び出すと、元のトランザクションIDが提供されます。
App Storeサーバーは、そのユーザーに対して最大20件の署名済みトランザクションを返します。
また、このユーザーの次のページリクエストで提供する更新されたリビジョン値も返されます。
応答のhasMoreフィールドが真である場合、利用可能なデータが増えることがわかっています。
この場合、利用可能なデータの別のページがあるとしましょう。
エンドポイントに別のリクエストを行い、最初の応答からそのリビジョン値を含めます。
更新されたリビジョン値を含むデータの次のページを受け取ります。
hasMoreはfalseになったので、最新の取引データが最新であることを知っています。
今回を除いて、あなたは応答で最終的な取引について何かに気づきます。あなたは以前にそれを見たことがあります!それはあなたが最初の要求に応えて受け取った最初の20のうちの1つでした。
これは、トランザクションが変更された必要があるため、ソート順の一番上に戻されたことを意味します。
これで、そのトランザクションのデータを調べて、何が変更されたかをメモすることができます。
この場合、refvocationDateフィールドとrevocationReasonフィールドが入力され、トランザクションが取り消されたことを意味します。
購入に関連するコンテンツを取り消すことで、アクションを実行できます。
この最終応答のリビジョン値を、ユーザーを識別するために使用した元のTransactionIdと一緒に保存することをお勧めします。
次回このユーザーのエンドポイントを呼び出すときは、そのリビジョンを提供し、前回のリクエスト以降に変更された新しいトランザクションデータのみが戻ってくることを知ることができます。
ご覧のとおり、取引履歴の取得エンドポイントは、アプリ内購入データの包括的なセットを取得する簡単な方法を提供します。
しかし、時にはそれは少し包括的すぎるかもしれません。
一部のユーザーは、数年前にさかのぼる長い購入履歴を持っています。
これらのユーザーにとって、このエンドポイントはさまざまなタイプの何百もの購入を返す可能性があります。
ページがあっても、これは処理することが多いです。
そのため、今年は、さまざまな新しいソートとフィルターオプションでこのエンドポイントを強化しています。
これで、最初から必要なデータを正確に伝えることができ、サーバーの処理時間を節約し、利用可能なすべてのページを取得するために必要なネットワークコールの数を減らすことができます。
結果の最初のページで最近変更された購入を見ることに興味がある場合は、変更日を降順に並べ替えることができます。
また、製品タイプ、製品ID、ファミリー共有ステータスなど、いくつかの便利なフィールドでフィルタリングすることもできます。
これらの新しいソートとフィルターオプションを適用するには、トランザクション履歴の取得エンドポイントにリクエストにクエリパラメータとして追加するだけです。
それがどのように機能するかを詳しく見てみましょう。
ここでは、すべての新しいパラメータオプションを見ることができます。
ほとんどがトランザクション情報ペイロードから直接取得されるため、これらは見覚えがあるかもしれません。
これらのパラメータを混ぜ合わせると、非常に具体的な結果が得られます。
たとえば、今年の初めからユーザーが行った非消耗性の購入のみを取得したいのかもしれません。
また、取り消された購入も除外したいと考えています。
productTypeをNON_CONSUMABLEに設定し、startDateをミリ秒単位で表される今年の初めとして指定することで、カスタムリクエストを構築します。
最後に、excludeRevokedをtrueに設定します。
そして、それが私たちの要求です!ソート順を指定しなかったため、応答はデフォルトで昇順の変更日でソートされます。
このような特定のリクエストがあっても、取得する購入ページが複数ある可能性があります。
フォローアップリクエストについては、以前の応答からのリビジョンに加えて、まったく同じクエリパラメータを含める必要があります。
さらに柔軟性を高めるために、3つのフィルターフィールドは複数の値をサポートしているため、提供された値の少なくとも1つに一致する購入のみにフィルタリングできます。
これらのフィールドは、productType、productId、およびsubscriptionGroupIdentifierです。
これらのパラメータに複数の値を提供するには、複数回定義するだけです。
次に、App Store Serverの通知の更新に進みましょう。
App Store Server Notifications V2を使用すると、サーバーを次のレベルに引き上げることができます。
V2通知は、他では得られないアプリ内購入イベントに関する詳細な洞察を提供します。
これらは、アプリで提供される自動更新サブスクリプションのライフサイクルを追跡するのに特に便利です。
これらの洞察を使用して、顧客を維持し、混乱した顧客を取り戻し、カスタマーサポートのリクエストを解決することができます。
これらすべての利点で、あなたはどのように始めるのか疑問に思うかもしれません。
他の新機能と同様に、サンドボックステスト環境は始めるのに最適な場所です。
そのため、昨年、サンドボックスでApp Storeサーバー通知を受信するために、App Store Connectで別のサーバーURLを設定する機能を追加しました。
サーバーのURLを登録した後、サーバーがApp Storeサーバーから通知を受信していることを確認する必要があります。
ユーザーアクションを通じて通知をトリガーするためだけに、サンドボックスアカウントを設定できます。
たとえば、そのサンドボックスアカウントを使用してサブスクリプションを初めて購入するとします。
SUBSCRIBEDタイプとサブタイプINITIAL_BUYのV2通知を受け取る必要があります。
しかし、その通知が来ない場合はどうなりますか?サーバーに問題があるのか、通知をトリガーするために実行した手順があったのか疑問に思うかもしれません。
この状況は、始めるときに多くの不確実性を生み出す可能性があります。
このエクスペリエンスを簡素化し、App Storeサーバー通知がサーバーに到達できることを簡単に確認する方法を提供したいと考えています。
そのため、今年は新しいテスト通知リクエストエンドポイントを導入します。
このシンプルなエンドポイントを呼び出すことで、App Store Connectでアプリに登録されたサーバーURLにTESTタイプのV2通知を送信するように依頼することができます。
新しいTEST通知タイプは、このエンドポイントにのみ使用されます。
サンドボックスまたは本番環境でエンドポイントを呼び出して、いずれかの環境で保存したURLをテストできます。
この新しいエンドポイントを使用して、新しいサーバーのURLと構成をすばやくテストします。
これが初めてのセットアップをどのように簡素化するかを見てみましょう。
さて、最初の通知をトリガーしようとしているだけなら、サンドボックスアカウントを設定したり、購入を実行したりする必要はありません。
テストしたい環境で新しいエンドポイントを呼び出すだけで、リクエストを確認するHTTP 200応答が届きます。
応答には、サーバーが受信するテスト通知を識別する新しいフィールド、testNotificationTokenが含まれます。
後でこの分野に戻ります。
その後まもなく、サーバーはApp Store Connectに保存されたURLでTESTタイプのV2通知を受け取るはずです。
では、このエンドポイントを呼び出す方法を見てみましょう。
App Storeサーバー上のこの新しいパスに簡単なPOSTリクエストを送信するだけです。
HTTP 200の応答を受け取り、リクエストが送信されたことを知ることができます。
応答には、私が言及した新しいフィールド、testNotificationTokenが含まれます。
後でこれをメモしておいてください。
まもなく、署名されたテスト通知が届きます。
デコードされると、その通知はこんな感じになります。
新しいnotificationType、TESTを含む、V2通知の通常の最上位フィールドがすべて含まれていることに気付くでしょう。
データオブジェクトの内容は、通常の通知よりも少し短いです。
これは単なるテストであるため、含めるトランザクション関連のデータがないため、トランザクション固有のフィールド、特にsignedTransactionInfoを省略します。
新しいテスト通知要求エンドポイントを呼び出すときは、App Storeサーバー通知が非同期に送信されることに注意してください。
エンドポイントへの呼び出しが成功すると、HTTP 200が返されますが、実際のテスト通知はしばらくして別々に届きます。
このエンドポイントはサーバー構成のテストがすべてであることを考えると、そのテストが失敗したときに何をすべきか疑問に思うかもしれません。
言い換えれば、テスト通知が届かない場合はどうなりますか?テスト機能をさらに強化するために、テスト通知のリクエストエンドポイントと組み合わせて使用するテスト通知ステータスを取得するエンドポイントをリリースします。
この新しいエンドポイントを使用すると、以前に要求されたTEST通知のステータスを確認できます。
エンドポイントの応答は、App Storeサーバーがサーバーに到達し、TEST通知を正常に送信できたかどうかを教えてくれます。
送信に失敗した場合は、その理由がわかるので、サーバー設定のトラブルシューティングをより良くすることができます。
このエンドポイントの使用方法を確認しましょう。
App Storeサーバー上のこのパスにGETリクエストを送信します。
パスには、Request a Test Notificationエンドポイントから受け取ったtestNotificationTokenを含めます。
これにより、どのテスト通知のステータスを確認したいかがわかります。
さて、応答のために。
signedPayloadフィールドには、App Storeサーバーがサーバーに送信しようとしたTEST通知ペイロードが含まれています。
そして、最初のSendAttemptResultフィールドは、その送信試行の結果を示します。
ここで、SUCCESSは送信が成功したことを示します。つまり、App StoreサーバーがサーバーからHTTP 200応答を受信したことを意味します。
送信に失敗した場合、代わりにいくつかの異なるエラー値のいずれかが表示されます。
これらの値は、App Storeサーバーがテスト通知でサーバーに到達しようとして経験したエラーを示しています。
この情報を使用して、サーバーの問題をトラブルシューティングし、必要に応じて新しいテスト通知を要求し、サーバーを確実に実行することができます。
全体として、これらのテスト通知エンドポイントは使いやすく、V2 App Storeサーバー通知を受信するようにサーバーを設定または再構成するときに多くの手間を省くことができます。
これらのエンドポイントの助けを借りて、サーバーを設定し、スムーズに実行されていることを確認できます。
しかし、サーバーは完璧ではなく、停止が発生します。
サーバーがダウンし、App Storeサーバー通知を見逃すときに、どのように回復しますか?これに対する現在の解決策は、再試行システムです。
App Storeサーバーがサーバーに到達できない場合、再試行プロセスが開始されます。
同じ通知を最大5回まで再送信し、各試行の間により長い待ち時間があります。
これらの再試行は、本番環境でのみ行われます。
再試行は最終的に停止から回復するのに役立ちますが、すべての状況に完璧ではありません。
たとえば、一部の停電は広範囲に及ぶ可能性があります。
サーバーがApp Storeサーバーからの最終再試行を見逃すのに十分な長さでダウンしている場合、その通知は失われます。
または、より一般的には、サーバーは非常に短い問題が発生する可能性があり、その間、ほんの一握りの通知しか見逃しません。
しかし、1つの通知を見逃すということは、顧客記録の一部が少なくとも1時間時代遅れであることを意味します。
しかし、あなたはどれか知らない!明らかに、サーバーの停止はストレスであり、それらからの回復は複雑な作業になる可能性があります。
そのため、見逃したApp Storeサーバー通知をできるだけ簡単に回復できるようにし、できるだけ早くサーバーを軌道に戻すことができます。
そのため、今年は新しい通知履歴の取得エンドポイントを導入します。
このエンドポイントを使用すると、アプリ用に生成されたV2 App Storeサーバー通知の履歴を取得できます。
サーバーが通知を正常に受信したかどうかにかかわらず、その通知はこのエンドポイントの応答に表示されます。
このエンドポイントを呼び出すときは、取得する通知の日付範囲を指定します。
WWDCでは、このデータの記録を開始し、利用可能な最新の6ヶ月間のローリング履歴の上限まで構築します。
オプションで、タイプとサブタイプでリクエストをフィルタリングするか、元のTransactionIdを提供することで単一のユーザーの通知のみを取得できます。
また、既存の再試行システムはまだ利用可能であるため、この新しいエンドポイントと並行して使用できます。
このエンドポイントをどのように呼び出すかを見てみましょう。
App Storeサーバー上のこの新しいパスにPOSTリクエストを送信します。
リクエスト本文には、startDateとendDateが含まれます。
応答には、このウィンドウで最初に送信しようとした通知のみが含まれます。
利用可能な最も早い通知は、リクエストの日付の6ヶ月前に送信されることに注意してください。
オプションで、notificationTypeとnotificationSubtypeを指定できます。
そうすると、履歴はこれらの値の両方に一致する通知のみにフィルタリングされます。
一部の通知にはサブタイプがないことを覚えておいてください。
または、ユーザーの元のTransactionIdを提供して、そのユーザーのみの通知履歴を取得することもできます。
最後に、次のページを取得するために、すべてのフォローアップリクエストのクエリパラメータとしてpaginationTokenを提供する必要があります。
フォローアップリクエストに同じリクエストボディを使用し、このpaginationTokenのみを変更してください。
では、その反応を見てみましょう。
notificationHistory配列には最大20件の通知が含まれており、最も古い通知が最初に含まれています。
この配列の各エントリは通知を表し、内部には署名されたPayloadがあり、通常どおりデコードしてトランザクションデータを表示できます。
内部のデータは、元の通知でApp Storeサーバーが送信したペイロードと同じです。
また、このエンドポイント応答に新しいfirstSendAttemptResultフィールドをもたらしたことがわかります。
このフィールドを使用して、タイムアウトやその他のエラーのシーケンスを検索し、サーバーが過去に通知を見逃した理由をよりよく理解できます。
応答には、取得するページがもっとある場合、paginationTokenも含まれています。
通知の次のページを取得するには、次のリクエストでこれを提供する必要があります。
hasMoreフィールドがtrueである限り、取得するページがもっとあることがわかるでしょう。
そして、この便利な新しいエンドポイントについて知っておくべきことはすべてです。
これで、今日のApp Storeサーバーのアップデートは終了です。
本日発表されたすべてのサーバー機能は、サンドボックスと本番の両方で利用可能になりました。
これらの新機能を活用して、サーバーを最高のものにすることを願っています。
レガシークライアントをサポートしながら最新の機能を使用する方法など、アプリ内購入でサーバーを使用する際のより優れたコンテンツについては、WWDC22で別のセッション「アプリ内購入の統合と移行を探る」をチェックすることをお勧めします。両方:WWDC22に参加してくれてありがとう!♪
コメント