ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
StoreKit 2とApp StoreサーバAPIを使ったカスタマーサポート
StoreKit 2、App StoreサーバAPI、App Storeサーバ通知を使って、優れたApp内課金の体験を提供し、カスタマーサポートを提供し返金リクエストに対応する方法について確認します。実装のアプローチや、ベストプラクティス、顧客管理、返金の管理についても紹介します。
リソース
- App Store Server API
- Auto-renewable subscriptions overview
- Handling refund notifications
- In-App Purchase
- In-app purchase overview
- Introducing StoreKit 2
関連ビデオ
WWDC22
-
ダウンロード
こんにちは David Wendlandです App StoreのCommerce Technical Advocateです 本日はバーチャルで 私たちがチーム全体として 取り組んできたことを紹介します 始めるにあたり クパティーノの同僚に 自己紹介をしてもらいます こんにちは Manjeet Chawlaです App Storeのテクニカルプログラム マネージャをしています こんにちは Joeです App Storeのプログラムマネージャです 「StoreKit 2とApp StoreサーバAPI を使ったカスタマーサポート」 と題した本日のセッションを この3人が3部構成でお届けします StoreKit 2のフレームワークと App StoreサーバAPIにより App内課金やカスタマーサポート および返金処理がどのように改善されるかに 焦点を当てます この3部構成のセッションを通して App体験やユーザー体験の強化を図る際に 考慮すべきインサイトやアプローチと それぞれのメリットをお伝えします 私からはApp内課金について まず秋に発売された製品の概要と クライアントからサーバの新機能や Sandboxまで紹介したいと思います その後 そうしたアップデートを 組み込むためのロードマップを 戦略的に考え 優先順位付けに役立つ 実装に向けたアプローチを説明します 早速ですが 新機能について紹介します iOS 15では 初心に戻って StoreKit 2でのクライアントの 実装を簡素化するために フレームワークを改良し刷新しました その結果 デバイス上の機能性は向上し ステータス情報の提供が改善 されたほか トランザクションに JWS形式を採用することで セキュリティが強化されました 加えて より多くのサービスを App内で直接提供できるよう 3つのスタンドアロン機能が 導入されています サーバについては バージョン2のリリースにより 既存のApp Storeサーバ通知を 大幅にアップデートしました これにより 対応する課金イベントの 数が大幅に増えました 新しいJWS形式も採用しています 最後に App StoreサーバAPIで 一連の機能がリリースされました このAPIには ユーザーの購入履歴の取得や サブスクリプション登録者の 現在のサブスクリプション ステータスの確認といった 様々な機能をサポートする エンドポイントの配列を用意しています ほかにも 顧客管理に関する 様々なシナリオに対応できる各種機能があります これについては同僚のManjeetと Joeが後ほど説明します 今年の広範囲にわたるアップデートは AppleがStoreKitによるApp内課金に 継続的に投資していることを示しています 全体として こうしたアップデートにより セキュリティが向上し 複雑さは軽減され SandboxやXcodeで App内課金を簡単に テストできるようになりました Appleプラットフォームでは Touch IDやFace ID などの機能により 15億台以上のデバイスでユーザーが セキュリティ保護された生体認証や フリクションレス認証を使用して 安全かつ便利に購入できています 現在 175のストアフロントから 40以上の言語で 毎週6億人がApp Store にアクセスしています デベロッパは地域ごとに価格帯を調整でき 来年には App Storeで対応する 価格帯の数を500以上に拡大する予定です これにより 価格設定の選択肢が増え 各通貨やマーケットに適した価格ポイントを 提供できるようになります App Storeでは 195種類の支払い方法で 45の通貨に対応し ユーザーが希望する支払い方法を より便利に利用したり保存したりできるよう 取り組んでいます プラットフォームのこうした改善点を踏まえつつ ここからはStoreKit 2を掘り下げ そのメリットや従来バージョンからの 主要な機能強化点を紹介したいと思います StoreKit 2の重要な機能は App内課金の新しいトランザクションが ユーザーのすべてのデバイスで 自動的に同期されることです これにより 一貫した信頼性の高いApp体験を 提供できます このフレームワークはデバイス上での 購入検証に対応しており 従来のフレームワークよりも 効率化されているため サーバ側での購入検証に 全面的に依存する必要はなくなりました すべてのトランザクションは JWSで署名されるため デベロッパは 各トランザクションの信頼性を確認できます また このフレームワークでは エンタイトルメントのステータス情報を デバイス上で確認できるので 複雑さが軽減され エンタイトルメントへのアクセスが 適切に確保できます また iOS 15で新たに導入された appAccountTokenでは 購入の開始時にApp内アカウントを設定し トランザクションの完了時に そのアカウントが返されます 加えて StoreKit 2には 従来のStoreKitフレームワークと 一緒に使用できる 独自のスタンドアロン機能もあります それで 今はiOS 15で従来の StoreKitを使用しているAppも StoreKit 2の独立した スタンドアロン機能を追加して 通常はAppの外で行われる体験を App内で提供できます そうした機能の1つ目は showManageSubscriptionsです これを使用すると サブスクリプション 登録者はAppを離れることなく サブスクリプションを管理できます 次に beginRefundRequestは ユーザーにトランザクションを提示し ユーザーがApp内で返金リクエストを 開始できるようにします また これをSandbox環境で使用すれば 保留から承認や却下に至るまでの 返金プロセスをテストしたり シミュレーションしたりできます 加えて ユーザーが お試しオファーの対象かどうか 簡単に確認できる機能も導入しました これは 無料トライアルのような オファーを販売/提供する場合 購入手続きの完了時に ユーザーにオファーのコンテンツが 適切に提供されるために重要です StoreKit 2では isEligibleForIntroOffer メソッドを使用し サブスクリプショングループIDを渡すことで 対象資格をすぐに確認できます これにより ユーザーが そのサブスクリプショングループ内の サブスクリプションについて 何らかのタイプのお試しオファーを 利用したことがあるかどうかを確認します さらに StoreKitで返された場合に限り お試しオファーを販売する必要があります Product.SubscriptionOfferから 利用可能であればお試しオファーの詳細が 返されます 利用可能でない場合は StoreKitによって返されないため オファーを販売することはできません ですので ハードコーディングせずに App Store Connectで設定された 開始日と終了日を使用する StoreKitを活用することが重要です ここからはサーバ側の話になりますが App StoreサーバAPIの 機能について説明します App StoreサーバAPIでは ユーザーとのやり取りなしに サーバ間でリクエストが行われます まず サブスクリプションステータス から説明します これは ユーザーがAppで登録している サブスクリプションの状態を示すものです また 複数のサブスクリプションを 提供している場合は サブスクリプションごとに エンタイトルメントのステータスを確認でき 各サブスクリプションは 一意のオリジナルトランザクションID によって識別されます サブスクリプションステータスの優れた点は サブスクリプションごとに 現在の JWS署名付きトランザクションのみを 返すことです そのため サーバのロジックで ユーザーのトランザクション履歴を解析して 現在のトランザクションを特定したり 資格を付与するコンテンツを 判断したりする必要はありません マルチプラットフォームの サービスプロバイダであれば このサービスを使用して Appを起動することなく サーバ間で いつでも最新のステータスを取得できます 必要なのはオリジナルの トランザクションIDだけです Appのレシートは不要です 推奨されるベストプラクティスを ここで紹介します 購入後またはトランザクションの復元後は 一意のオリジナルトランザクションIDを データベースに必ず保存しておくことが重要です 各サブスクリプションは この値によって識別されます 初回の購入とその後の更新 請求に関する問題と復旧 およびアップグレードとダウングレードまで サブスクリプションのライフサイクルを 追跡する上で重要な値です トランザクションIDは クライアントやサーバAPI およびサーバ通知で使用されます セキュリティのベストプラクティスとして サブスクリプションステータスは サーバ間でのみ使用します Appから直接ステータスを 確認する必要がある場合は StoreKit 2のフレームワークを 活用してください サーバAPIの別の機能は App内課金の履歴で ユーザーの完全かつ最新の トランザクション履歴を サーバ間で取得できることです トランザクション履歴には非消耗型の課金 非自動更新/自動更新サブスクリプション および完了していない消耗型の 課金がすべて含まれ これらはすべてJWS署名付きの 安全なトランザクションです トランザクション履歴と すべてのオリジナルトランザクションID に関する情報は beginRefundRequest APIを 実装する際に役立ちます 実装では 返金リクエストを開始する際に ユーザーが選択できるよう トランザクションを表示する 必要があるからです 従来のStoreKitを使用したAppで 非サブスクリプションの App内課金が行われた場合は verifyReceiptを使用せずに このAPIを使用して 購入が正常に 完了したかどうかを検証したり 障害発生時には最新情報を 確認したりすることができます ベストプラクティスとして 購入件数が多いユーザーもいるため レスポンスには同時に最大20件の トランザクションを含めます それ以上のトランザクションがある場合は 必ずhasMoreフィールドを使用してください trueの場合 そのレスポンスと その後のリクエストで リビジョントークンを使用して トランザクションの次のページを取得します hasMoreフィールドがfalseを返すまで これを繰り返し 使用したリビジョントークンは 今後のために保存します これにより 記録されたリビジョントークンを使用して ユーザーの最新のトランザクション履歴を すぐに取得できるようになるので 再びページネーションをしなくて済みます もう1つの重要なベストプラクティスは コンテンツやサービスが提供された後に finishTransactionを使用することです 終了していないトランザクションが キューに残るため ユーザーに配信する必要がある 購入済みコンテンツの状況を Appで管理するのに役立ちます これは デバイス上で何らかの 中断があった場合に重要です 最後の推奨事項として 返金済みまたは無効になった トランザクションに関する最新情報を できるだけ早く効率的に確認したい場合は バージョン2のサーバ通知を活用してください どのAPIをポーリングするよりも はるかに効率的です では サーバ通知について考えましょう サーバ通知は 主要な購入イベントや ステータスの変更について ほぼリアルタイムでサーバに 直接通知を送信します 今年のバージョン2では この機能が劇的に改良され より効果的で使いやすく 詳細な情報を提供できるようになりました サポートされるイベントの数は2倍に増え 合計で28種類になりました バージョン2では 各イベントごとに 通知が送信されるため 受信時に必要なアクションを取れます これらの通知は ファミリー共有で App内課金コンテンツにアクセスできる ファミリーメンバーにも適用されます また 通知の配信に失敗した場合は 障害が発生している可能性を考慮して 7日間で最大5回通知を再試行します もちろんバージョン2は Sandboxで提供されていますので Sandboxのテスト環境で安全に開発できます ベストプラクティスとしては これらの通知を正常に受信したら HTTPレスポンスコード200で 応答することが重要です これにより Appleは通知が正常に受信され 再送の必要がないことがわかります サーバがエラーを返したり 応答しなかったりすると App Storeは同じ 通知ペイロードを再送します 各通知にはsignedDateがあり オリジナルの通知がいつ送信されたかを 正確に知ることができます また 受信した通知の信頼性について JWS署名付きトランザクションの 情報を使って検証し App Storeによって署名されたもの であることを確認できます なお Sandboxと本番環境のイベントに 固有のサーバURLを 提供できるようになったので ぜひ活用してください 最後のベストプラクティスは 通知のアップデートをすぐに適用することです アップグレードや返金など 一刻を争うイベントもあります そのため アップデートを ほぼリアルタイムで処理することは 有益です 最後に紹介するアップデート内容は Sandbox環境での App内課金のテストに役立つ App Store Connectの 機能に関するものです これらの機能は Sandboxテスターの 「ユーザーとアクセス」タブから アクセスできます ご存じかもしれませんが Sandboxでは現在 サブスクリプションの更新にかかる時間を テスト用に短縮できます 今回 Xcodeでの StoreKitテストのように Sandbox Apple IDごとに 更新のサイクルを速めたり 遅めたりできる機能を追加しました これは 更新と更新の間に アクションを実行するための時間が必要な場合に 役立ちます また 異なるストアフロントでの テストに対応するために Sandbox Apple IDのストアフロントを いつでも変更できるようになりました さらに 1つのSandbox Apple IDの 活用を広げるために 自動更新サブスクリプションと 非消耗型の課金の 購入履歴を削除できるようになりました これにより例えば コンテンツの購入や お試しオファーの利用を 繰り返し行うことができます ここまで StoreKit 2とサーバAPIの メリットやベストプラクティス について考えてきましたが 次に こうした機能や能力を Appやサーバに統合する上で 役立つ手法を紹介します App内課金というと 主に ユーザーの購入コンテンツへの エンタイトルメントの付与や ステータス変更の処理が関わります そのためには サーバのバックエンドを使わずに すべてをローカルで行う オンデバイスアプローチを取るか サーバを信頼できるソースとする サーバ間APIを活用するかを 選択する必要があります まず オンデバイスアプローチを説明します このアプローチでは StoreKit 2のフレームワークによって App内課金やステータスの変更を すべてデバイス上で 完全に管理する機能がAppに提供されます サーバは不要です これは中小企業や 既存のサーババックエンドがない 企業にとって非常に便利です まず これから紹介する StoreKit 2の3つのコア機能を使って 購入フローをサポートしましょう Productsでは 利用可能なコンテンツと その詳細に関する情報を取得して App内の販売を推進できます これにより 常に正確で App Storeと同期された情報が得られます そしてStoreKit 2では VerificationResultと PurchaseResultが 新たに用意されました これらを一緒に使用することで 購入やトランザクションの復元が 正常に完了した後 トランザクションの信頼性を確認できます StoreKit 2のフレームワークを 使用する別の重要なメリットは どのようなトランザクションでも Appを最新の状態に保てることです ユーザーが複数のデバイスを 使用している場合もあり Transaction.updatesを使えば どのデバイスで トランザクションが発生したかにかかわらず Appを同期された状態に保てます currentEntitlementの メソッドを使用すると Appは ユーザーが購入したコンテンツの 即時ステータスをすぐに取得できるので ユーザーにコンテンツをすぐに 提供することができます トランザクションの最新情報が 把握できるため ユーザーにログインや購入の復元を 実行してもらう必要はありません 最後に 自動更新サブスクリプションの情報を デバイス上で取得することは非常に重要です コンテンツ自体の情報だけでなく 現存のサブスクリプション登録者のステータスや 今後の更新期間に関する情報についても これが該当します そこで使用できるのは Product.SubscriptionInfoです 以上取り上げた6つのコア機能を使えば iOS 15でStoreKit 2を活用し サーバへの依存度を減らす またはゼロにして 優れたユーザー体験を提供できます 次に サーバ間のアーキテクチャですが これはサービスを確実に利用できることを ユーザーから求められる マルチプラットフォームや マルチAppのサービスでは非常に重要で ユーザーの購入のステータスが いつでもリアルタイムに更新される システムが必要です 通常 こうしたサービスでは サーバを信頼できるソースとし 24時間365日オンラインでいつでも App Storeを使用して 最新情報を確認できるようにします このフローをAppの視点で見てみましょう これはユーザーのデバイスで Appが従来のStoreKit フレームワークを介して 購入を開始し App StoreのverifyReceipt サーバを使って 購入の検証をしているところです この場合 購入や復元の後には Base64でエンコードされたAppレシートが Appからデベロッパのサーバに送信され それがverifyReceiptサーバに送信されます App Storeがユーザーの トランザクションに応答し デベロッパのサーバは それらのトランザクションを解析して ステータスを判定し サーバ側またはApp内で必要なアクションを 選択します 幸い App StoreサーバAPIは StoreKit 2のフレームワーク全体の App側での採用に依存しないため 心配は無用です つまり 従来のStoreKitを Appで使用したまま App StoreサーバAPIが提供する新機能を すぐに利用できます では その方法をご紹介しましょう 同じデザインであれば 主に2つの変更を行う必要があります まず オリジナルトランザクションIDが 取得されるように Appを更新します 次にサーバを更新し App StoreサーバAPIを 使用できるようにします この2つの変更を行うことで Appは従来のStoreKitまたは StoreKit 2のどちらでも使用でき どのiOSバージョンでも APIはAppの最新バージョンに 簡単に対応できます 最初の変更を行い original_transaction_ID を組み込むには Base64でエンコードされたAppレシートを 取得するロジックを変更します これまで URL方式のAppレシートを 利用していたかもしれません その場合 自動更新サブスクリプションについては このプロパティで置き換えてください その他のApp内課金では このような類似のプロパティを使用します それでは サーバを更新してApp Store サーバAPIを使用できるようにしましょう /verifyReceiptから /History または/SubscriptionStatus のURLに変更します リクエストの認証にはJWTを使用し オリジナルトランザクションIDを これ以降使用することになります 以上の2つの変更を行うと サーバ上で管理する エンタイトルメントロジックがなくなり 安全なJWS署名付き トランザクションを使用できて Appレシートを保存する必要がなくなります それで 古いバージョンの iOSに対応したAppであれば App StoreサーバAPIの 機能を利用できます 先ほど StoreKit 2とサーバAPIが サブスクリプションステータスを どのように判定するかを説明しました ベストプラクティスとして Appは起動時に必ず サブスクリプション登録者の ステータスを判定する必要があります ステータスが判定されると ローカルに保存され 必要に応じて更新されます ここで APIが返す5つのステータスと それぞれに必要なアクション および考慮すべきいくつかの可能性について 簡単に確認したいと思います なお 新規ユーザーには これらのステータスのいずれにも 該当しません そのため 新規ユーザーのステータスは Appで管理する必要があります 1つ目のステータスは「アクティブ」です このステータスの場合 有効期限が切れるまで ユーザーにサービスが提供されます ユーザーに複数のレベルで サービスを提供している場合 1つの可能性として プロモーションオファーを活用して App内でアップグレードオファー を表示することが考えられます なお このようなオファーは ユーザーの サブスクリプション履歴に合わせて カスタマイズする必要があります 次に サブスクリプションが完全に解約されると 「期限切れ」というステータスになります サービスを提供する必要はなく 現在提供している サブスクリプションを販売できます さらに プロモーションオファーや サブスクリプションオファーコード を活用して ウィンバックオファーを 提示することもできます サブスクリプションが有効期限から 60日以内に再開されると 85%の収益率に必要な 有料サービス日数の累積が再開されます 3つ目のステータスは 「支払いの再試行期間」です 支払い上の問題が起きることはよくあります クレジットカードの有効期限が切れたり ストアクレジットが消費されて いたりするかもしれません このステータスでは サブスクリプションが 自動更新される予定でしたが 支払い方法の問題により 支払いの再試行期間に 入ってしまったものです サブスクリプションの有効期限が切れて サービスが不要であれば ユーザーはサブスクリプションを 再登録する必要はなく 単に支払い上の問題を解決する必要があります App Storeは自動的に最大60日間 様々な形でユーザーとやり取りし 支払いの再試行と サブスクリプションの回復を試みます デベロッパの側にアクションは不要です とはいえ App内のメッセージ機能を使えば 支払い上の問題が発生している旨を ユーザーに直接通知し 問題解決のため ユーザーが 支払い情報のページに移動できる ディープリンクを記載した 効果的なコールトゥアクションを提供できます 次は「請求の猶予期間」です 支払いの再試行と関連しているものの このステータスは App Store Connectで App Storeの請求の猶予期間を 有効にしている場合にのみ サブスクリプション登録者に適用されます このステータスの場合は 猶予期間が終了する日まで 中断することなくサービスを提供します 猶予期間中に サブスクリプションが回復された場合 元の課金サイクルが維持されます そのため ユーザーは中断することなく サービスを利用でき Appのプロバイダは 請求可能な日数を失わずに済みます 支払いの再試行と同様 App内のメッセージ機能を使って 支払い上の問題について ユーザーに注意を促すことができます 5つ目のステータスは「無効」です これは ファミリー共有可能なサブスクリプション に適用されるステータスです この場合 ファミリーメンバーは もはやそのサービスやコンテンツを 利用する権利がないため アクセスが無効になります 同時に Appはユーザー再獲得のための オファーを販売できます 最後に App Storeサーバ通知の使用で考慮すべき 実装のアプローチをいくつか紹介します これは サポートされるイベントの一覧ですが かなりの数があり ビジネスモデルに該当しない イベントもあるかもしれません 多くのイベントはサブスクリプション ライフサイクルの一部ですが すべてのタイプのApp内課金に 適用されるものもあります サブスクリプションを提供していない場合 実装に向けたアプローチはより単純です より複雑なサブスクリプションを 提供しない場合は ここに挙げられている イベントの多くは不要になるからです とはいえ まず 実装の様々なフェーズを確認しましょう ここではフェーズを「開始」 「ライフサイクルへの対応」 「インサイトに基づいたアクションの実行」 の3つに分けて考えたいと思います 「開始」フェーズは ビジネスモデルを問わず またバージョン1の通知を 導入済みかどうかに関わらず バージョン2を採用する すべてのユーザーに適用されます 最初の手順は App Store Connectで バージョン2を有効にすることです この機能は 「App情報」の 「App Storeサーバ通知」で確認できます また 秋のアップデートでは URLを Sandbox用と本番環境用に それぞれ選択できるようになりました 該当するURLを追加して 受信するバージョンを選択します すでにバージョン1を受信している場合は 本番環境で有効にする前に Sandbox環境で バージョン2のみを有効にして 開発を行うことをお勧めします バージョン2が有効になったところで 優先順位付けを考えましょう Appのビジネスモデルや使用状況に応じて 最初に対応する通知を判断します そのためには Appのビジネスや ロードマップに最も当てはまる 重要かつ頻繁に発生するイベントに 焦点を当てる必要があります すべてのタイプのApp内課金に 適用されるイベントに 返金があります ユーザーへの返金が完了した トランザクションごとに 1つのREFUND通知が届きます これらのイベントをどのように処理するかは Appのポリシーやビジネスモデルによります サブスクリプションベースの ビジネスモデルの場合 この4つの通知はサブスクリプションの 新規登録や再登録から 更新の成功や失敗 および有効期限に至るまで サブスクリプションサイクルの 主要なイベントに適用されます この5つの通知タイプに 優先的に対応することで 受信する可能性のあるイベントの大半に 対応できます こうした「開始」フェーズが確かな基盤となり リターンを最大化できるようになります 次のフェーズでは すべての通知タイプに対応するよう設定します サブスクリプションベースの通知が わずかに残っていますが ほかの通知タイプは機能の導入に依存しています 確認してみましょう DID_CHANGE_RENEWAL_STATUS とRENEWAL_PREFの2つのタイプは サブスクリプションベースの Appすべてに適用されます これらは サービスレベルを キャンセルまたは変更している ユーザーを特定する上で重要です 残りの通知タイプについては Appの使用状況によって異なります App Store Connectで請求の 猶予期間を有効にしている場合は GRACE_PERIOD_EXPIRED が適用されます RENEWAL_EXTENDEDは App StoreサーバAPIを使って ユーザーのサブスクリプション更新日を 延長した場合に送信されます App内課金におけるファミリー共有を 有効にしている場合 REVOKEが適用されます OFFER REDEEMEDは サブスクリプションオファーコードや プロモーションオファーを 活用した場合に適用されます 自動更新サブスクリプションの 価格が引き上げられた場合は PRICE_INCREASEが送信されます そして REFUND_DECLINEDと CONSUMPTION_REQUESTですが これについては Joeが後ほど返金処理のパートで 詳しく説明します 最後に 「インサイトに基づいた アクションの実行」のフェーズです この時点までに Appに関連する すべてのイベントを受信し アクションを実行しているはずです これにより ユーザーの 全サブスクリプションの最新ステータスや 購入された消耗型/非消耗型の課金 および非自動更新サブスクリプションへの アクセスの変更について App側で把握できています サブスクリプションでは これから紹介する通知により 厳密に特定したステータスのユーザーに向けて 特定のプロアクティブなアクションを Appで実行できます これによりサブスクリプション登録者を 特定し エンゲージメントを高め 登録者の維持と過去の登録者の 再獲得を促すことができます 以下に 鍵となるイベントを特定して エンゲージメントを高めたり 積極的にApp内メッセージを活用したり カスタマイズされたサブスクリプション オファーを提示したりするための 通知タイプを紹介します 1つの例として ユーザーがサブスクリプションを キャンセルする場合を考えてみましょう このシナリオでは 登録者が11月25日に 月間サブスクリプションを購入したとします そして12月5日に サブスクリプションを キャンセルすることにしました 現在のサブスクリプション期間は 20日残っています この20日間は ユーザーがサブスクリプションを キャンセルしてから サブスクリプションの有効期限が切れて そのまま解約されるまでの 保存期間となります さて サブスクリプションが キャンセルされると 自動更新のステータスがfalseに設定され AUTO_RENEW_DISABLED をサブタイプとする DID_CHANGE_RENEWAL_STATUSの通知を 送信するようApp Storeが即時にトリガされ 保存期間の開始について リアルタイムでデベロッパに通知されます これにより Appはユーザーに合わせて カスタマイズされた App内メッセージを送信したり 有効期限が切れる前に 割引オファーを販売したりできます こうしたオファーはそれぞれの ユーザータイプに合わせてカスタマイズし オファーの対象となる基準を 設けることが重要です 私からは以上です それでは 同僚のManjeetを紹介します Manjeet:ありがとう Dave Manjeet Chawlaです App Storeのテクニカルプログラム マネージャです ここまで DaveがStoreKit 2と App StoreサーバAPIを使った App内課金の改善方法を説明しました では そのまったく同じAPIを 今度はカスタマーサポートの 観点から考えてみましょう これから App内課金で よくあるサポートシナリオを いくつか取り上げ それらのシナリオでStoreKit 2や App StoreサーバAPIを活用するための ベストプラクティスを紹介します しかし カスタマーサポートの話をする前に サポートの提供が顧客管理全体に 与える影響を理解しておきましょう 顧客獲得や顧客分析 およびカスタマーサポートのための 様々なCRMツールやシステムに加え 各種マーケティングチャネルを 活用しておられるかもしれません 加えて サポートを提供することで ユーザーの満足度と 製品へのエンゲージメントを維持し 全体的な顧客関係の 向上につなげることができます ユーザーから問い合わせがあった場合に デベロッパが効果的にサポートを提供し 問題を効率的に解決するためのツールが App Storeには用意されています これから あらゆるサポート窓口での 問い合わせ対応に役立つ 5つの新しいカスタマーサポートツールを 紹介します まず Look Up Order IDです 現在App内課金を購入すると ユーザーのApple IDに レシートが送信されます ユーザーは 「アカウント設定」の購入履歴で いつでもレシートを確認できます ユーザーから問い合わせがあった場合 Appのサポートチームは ユーザーに このレシートに記載されている注文IDを尋ね 新しいApp StoreサーバAPIを呼び出し その注文IDから該当するレシートの App内課金を確認できます また このAPIを使用して レシートの信頼性を確認したり そのレシート内のトランザクションを ユーザーに関連付けたりすることができます 同じAPIを使用して 購入で発生した問題を特定することもできます 例えば トランザクションに App Storeで返金済みまたは無効になった 課金が含まれている場合は 応答のrevocationDateと revocationReasonで 返金に関する詳細を確認できます このAPIを一度実装すると ユーザーから問い合わせがあった場合に 注文番号で過去の購入履歴を 検索できるようになります ベストプラクティスとして すべての App内課金のoriginal_transaction_idを ユーザーのアカウントデータベースに 保存してください そうすることで ユーザーから 問い合わせがあった際 このAPIを利用して アカウントデータベースから 簡単にユーザーの購入履歴を 検索して関連付けられます このAPIを電話やメール およびWebといった 既存のカスタマーサポート窓口に統合して 一貫したサポート体験を提供 することも可能です 次に Refund Lookupについて説明します WWDC20で発表されたように App内課金の返金が正常に処理されると その都度デベロッパのサーバに通知する 返金通知機能が App Storeに導入されました Refund Lookupは 新しいApp StoreサーバAPIで ユーザーに返金済みのトランザクションを すべて検索できます このAPIを使用して 返金されたトランザクションを いつでも迅速かつ簡単に検索できるので サーバの停止や定期メンテナンスに対応できます すべてのタイプのApp内課金における ユーザーの返金履歴を確認することもできます また このAPIを使用して 返金の急増や不審な活動を監視し 返金の原因となり得る コンテンツ配信の 問題に対応することができます ベストプラクティスとしては App内課金ごとに original_transaction_idを ユーザーのアカウントデータベースに 保存している場合 任意のoriginal_transaction_idで 過去の返金を検索できます また Refund LookupのAPIを使用して 返金につながる可能性のある コンテンツ配信の問題を トラブルシューティングできます ここからは 自動更新サブスクリプションについて 具体的に説明します 例えば サーバ停止や イベントのキャンセルが発生した場合です これは スポーツや生放送のテレビ番組 ビデオなどを視聴する ストリーミングベースのAppでは より頻繁に起こります サーバ停止やイベントのキャンセルについて ユーザーに納得してもらうには どうすればよいでしょうか 新しく用意された Renewal Extension Server APIを 使用すれば 現在有効な 有料サブスクリプションの更新日を延長し 登録者に一定期間無償でサービスを 提供できます このAPIは 一時的なサーバ障害への対応や サービスに不満があるユーザーへの 柔軟な対応などにも使用できます なお 実際のサブスクリプション期間に かかわりなく サブスクリプションの更新日は 年に2回まで かつ1回につき 最長90日間延長できます また 延長期間は 85%の収益率を得るために必要な 1年間の有料サービスの日数には含まれません ベストプラクティスとして 更新日を延長するサブスクリプションを 特定できるよう 対象の original_transaction_idを 保存しましょう Appのビジネスモデルに最適な 延長期間を判断し ユーザーのサブスクリプションを 延長する際に送信する App内のメッセージに記載します また ユーザーに提供できる延長は 年に2回までなので 延長するユーザーの対象資格について 基準を整備しておくとよいでしょう さらに 社内のビジネスチームや マーケティングチームと常に連携し コミュニケーションチャネル間で 一貫したメッセージを提供してください 別のシナリオを考えてみましょう ユーザーに対する補償として サブスクリプションに1回限りの 割引を提供するとします iOS 14で App Storeに サブスクリプションオファーコードが 導入されました 限定期間中に割引価格または無償で サブスクリプションを提供することで 登録者の獲得や維持 および再登録の促進に役立ちます この1回限り利用できる 一意のオファーコードは オンラインまたはオフラインの チャネルを使用して提供できます カスタマーサービスに関する問題が 発生した場合 ユーザーに対する補償として こうした1回限りのコードを 提供できます 加えて さらに低い価格で より多くの特典付きの長期プランなど 別のサブスクリプションオプションを 提示することもできます iOS 14/iPadOS 14以降のユーザーは 1回限りのオファー利用URLを介して App Storeでオファーコードを 利用できます なお StoreKitの presentCodeRedemptionSheet のAPIを実装している場合は App内でもコードを利用できます ベストプラクティスとして ユーザーが 情報に基づいた決定を下せるように App内のメッセージや オファーコードの説明をカスタマイズした上で コードをApp内で利用できるようにしましょう そして このオファーコードに関する案内を 電話やメールおよびWebといった 既存のカスタマーサポート窓口 あるいはApp内で使用するようにします 例えば Appのサポートチームが ライブチャットでユーザーに対応する際に 使用できます オファーコードをメールなどの デジタルマーケティングチャネルで 提供する場合 コードがあらかじめ入力された オファー利用URLが 各コードに関連付けられます 固有のURLを使用して ユーザーがメールから App Storeのオファー利用のフローに シームレスにアクセスできる ディープリンクを提供できます このURLは2つの値で構成されます 1つはIDです これはAppのIDで Appごとの静的な値です 2つ目の値はコードで サブスクリプション登録者の 一意の英数字から成る値を使って 動的に生成されるURLコードです URLがメールに埋め込まれる場合 ユーザーがそのURLをタップすると App Storeに移動し トランザクションを完了できます このフローで コードが サブスクリプション登録者に 表示されることはありません フローが完了し ユーザーがAppを再起動すると Appで実行が必要な 外部トランザクションの1つとなります 次に ユーザーが サブスクリプションの管理を 行うシナリオを考えましょう StoreKit 2では 新しい Manage Subscriptions APIが 導入されており 既存のサブスクリプション管理を App内で表示できるようになりました App内でサブスクリプションを管理することで ユーザーはAppを離れることなく サブスクリプションの アップグレード/ダウングレードや キャンセルを行うことができます また この機能により デベロッパはApp内でスムーズに サブスクリプションに関する一般的な 問題をサポートしたり ユーザーに代替オファーを提示できます さらには ユーザーのエンゲージメントが 低い場合などに サブスクリプションの管理ページが 表示される前に ユーザーにパーソナライズされた 割引オファーを提示したり ユーザーがサブスクリプションを キャンセルした理由について 出口調査を行ったりすることもできます では ベストプラクティスを紹介します StoreKit APIを使用することで ユーザーがAppを離れることなく サブスクリプションの管理や キャンセルを行える 一貫したApp体験を提供できます システム組み込みの管理UIを補完するために ブランド性を出したコンテキストベースの 体験を提供してください 例えば 人気の高いプレミアム価格帯を設定し ユーザーの好みや使用状況に応じて パーソナライズされた提案や 代替プランを提供できます また 各種チャネルで提供する 一連のカスタマーサポートと関連して サブスクリプション管理の 全体的な体験を検証しましょう それでは Manage Subscriptions UIの例を 見てみましょう 「アカウント設定」に ユーザーがサブスクリプションを 管理するためのボタンを追加できます ユーザーがこのボタンをタップすると App Storeに既存の サブスクリプションの管理ページが 表示されます ページには 現在有効なサブスクリプションと 更新オプションが表示されます これは ユーザーが App Storeの「アカウント設定」で 「サブスクリプションの管理」を開くと 表示される画面です この画面でサブスクリプションを確認したり サブスクリプションの アップグレード/ダウングレードや キャンセルを行ったりします ここでサブスクリプションの キャンセルを選択すると キャンセルの詳細と有効期限が記載された 確認画面が表示されます また このページでユーザーが 何らかのアクションを実行すると App Storeサーバ通知が デベロッパに送信され StoreKit 2のフレームワークを 実装している場合は Appに通知が届きます では 本日紹介した 新しいカスタマーサポートツールや APIを活用してサポートを提供することの メリットについて考えましょう App内課金をApp上で 状況に合わせてシームレスにサポートして 全体的なユーザー体験を 向上させることができるようになりました これは 全体的なリテンション向上や ユーザーの満足度向上につながります その結果 エンゲージメントが高まり 最終的には Appに対する ポジティブな評価やレビューが増えます ここからは 同僚のJoeが 返金処理について説明します Joe:ありがとう Manjeet 新しいカスタマーサポートツールの ベストプラクティスやユースケースについて 知ることができました 皆さん こんにちは Joe Maniです App Storeの プログラムマネージャをしています 返金はデリケートなトピックです App Storeでは 返金がAppに与える影響を デベロッパが特定するためのツールが 用意されています また ユーザー体験を向上させるために そうしたツールをどのように活用できるか も示しています これから こうしたツールを 活用するメリットを確認した上で 返金の処理について包括的に説明します この1年で 返金に影響する 2つの新しいツールがリリースされました まず beginRefundRequest のAPIを説明します App Storeには「問題を報告する」があり Appleサポートでは ユーザーが返金を リクエストするためのプロセスが 確立されています iOS 15ではApp Storeにおいて StoreKit 2のフレームワークに beginRefundRequest APIが 新たに導入され ユーザーがApp内課金の返金を リクエストできるようになりました beginRefundRequest APIを 実装することには 複数のメリットがあります 皆さんはすでに ユーザーから App内課金の返金リクエストを 受けた経験があると思います 新しいbeginRefundRequest APIを 使用すると ユーザーをリダイレクトすることなく 同じ機能を提供したり App内でサポートを提供したり することができます App内課金の潜在的な問題に気付いたら このAPIを使用して 問題のトラブルシューティングについて ユーザーをサポートし より迅速な解決を図ることができます iOS 15では App Storeに 2つの通知機能が追加され 返金リクエストが承認されたかどうかを 知ることができるようになりました 返金が承認されると Appに通知され App Storeからデベロッパのサーバに REFUND通知が届きます 返金が却下された場合は REFUND_DECLINED通知が デベロッパのサーバに届きます なお この機能を利用するには ユーザーがiOS 15以降を 使用している必要があります では ベストプラクティスについて説明します オリジナルトランザクションIDは 保存しましょう また 返金リクエストのほとんどは 購入から30日以内に行われます ユーザーがイライラして 返金をリクエストしている場合でも カスタマイズされたApp内メッセージにより ユーザーに合わせた体験を提供できます 購入済みのコンテンツ情報を ユーザーに表示することもできます 返金するトランザクションを ユーザーが選択すると Appが APIを呼び出すことで 返金の リクエストシートが表示され ユーザーは理由コードのリストから 返金理由を選択できます 理由コードは Appleの「問題を報告する」に 準拠しています 自動更新サブスクリプションの場合 返金が正常に完了すると サブスクリプションがキャンセルされるため ユーザーのApp利用を維持するための リテンション戦略を準備しましょう 以上 beginRefundRequestについて 確認しました 次に この後のプロセスと デベロッパが実行できる アクションについて説明します App Storeでは 新しいサーバAPIが導入され ユーザーの消耗型App内課金の 利用状況に関する情報を送信して 返金プロセスの情報をAppleに提供し プロセス改善を図れるようになりました 例えば ユーザーが返金をリクエストする前に アイテムを消費済みかどうかといった情報です 大まかな流れとして それぞれの返金リクエストは Appleの返金決定システムを経て 決定されます 返金決定システムには 問題の トランザクションに関する情報に加えて ユーザーの購入/返金履歴といった その他の要素が含まれています Appleの決定が出る前に App Storeからデベロッパのサーバに CONSUMPTION_REQUEST通知が 送信されます この通知を受けて デベロッパのサーバは 消費データを送り返します 消費データは 返金の判断に 影響を与える可能性があります 消費のペイロードはいくつかの フィールドで構成されていますが ここでは主要なフィールドを 3つ取り上げたいと思います 「Consumption」は App内課金が 完全/部分的に消費されたか またはまったく消費されなかったかを示します 例えば アイテム交換のプラットフォームがあるAppや App内課金がアカウント間で 譲渡されたような場合 それは消費されたものとみなされます コンテンツ配信型Appでは 障害が発生したり App内課金コンテンツを 配信できなかったりして ユーザーに返金する場合があります こうした配信できなかったコンテンツを シンプルに提供できるようになりました StoreKit 2に導入された appAccountTokenでは Appのユーザーアカウントに関連付けられた 標準的なUUID形式を使用します ユーザーアカウントで購入を開始したり コンテンツを消費したりするため 販売店を特定しやすくなります 大半の返金リクエストは購入から 30日以内に行われるので それに従いトランザクションの 消費データを保存することが推奨されます Appleからデータを要求された際に 該当するトランザクションを 見つけることができるよう 消耗型のApp内課金ごとに original_transaction_IDを 保存してください Appleがデベロッパからのデータを 判断材料にできるよう 消費リクエストの通知を受け取ってから 12時間以内に応答してください 最初のリクエストの後に変更があった場合は 12時間以内に最新の ペイロードを送信してください なお 要求された消費データを App Storeに送信する前に お客様の同意を得る必要があります 消費のペイロードでは すべてのフィールドへの入力が必須ではないため どのフィールドを未申告にするかについては Appleの文書を参照してください 本日のセッションのまとめとして 重要なアクションのチェックリストを 用意しました 各種機能の採用と実装にあたって まずApp Store Connectで URLを入力し Sandbox環境で バージョン2を有効にすることで App Storeサーバ通知を受信するよう サーバを設定し有効化しましょう カスタマーサポートツールについては 電話やメール WebやApp内のサポートといった 既存のサポート窓口に統合します Appについては iOS 15で StoreKit 2を使用するにあたって 新しいAPIのbeginRefundRequest isEligibleforIntroOffer およびshowManageSubcriptionsに 対応するのに必要なクライアントの 変更点を確認します 最後に Sandbox Apple IDを 最大限に活用し ストアフロントの変更や購入履歴の消去 さらには返金の処理や サブスクリプション更新頻度の調整など 各種アップデートをSandbox環境で 十分にテストしてください 以上 本日は StoreKit 2と App StoreサーバAPIを使った カスタマーサポートについて お話ししました ご視聴ありがとうございました
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。