
-
アプリ内課金のためのApp Store Server APIの詳細
App Store Server API、App Store Server Notifications、App Store Server Libraryの最新アップデートを紹介します。これらのテクノロジーを使用すると、カスタマーの購入データをサーバ上で直接管理し、優れたアプリ内課金体験を提供できます。appAccountToken、署名認証、署名付きトランザクションと更新情報の新しいフィールド、および新しいAPIのアップデートについて解説します。また、サーバ上でプロモーションオファーの署名を作成する方法や、Send Consumption Informationエンドポイントを使用する方法についても説明します。
関連する章
リソース
- Advanced Commerce API
- App Store Server API
- App Store Server Notifications
- Set App Account Token
- Simplifying your implementation by using the App Store Server Library
- Submit feedback
関連ビデオ
WWDC25
WWDC24
-
このビデオを検索
こんにちは Riyazです App Store Serverチームのエンジニアです このセッションでは アプリ内課金のためのApp Store Server APIについて詳しく解説します アプリサーバの責務の 合理化と強化のために設計された 最新のアップデートの詳細を紹介します まず アプリサーバが担う主な責務を いくつか見てみましょう このセッションでは 3つの重要な責務に焦点を当てます
最初はアプリ内課金の管理です このタスクでは アプリの コンテンツとサービスをシームレスに 配信するための トランザクションデータと カスタマーアカウントの 関連付けが必要です
次はリクエストへの署名です このタスクでは App Storeに対する サーバのリクエストを認可するための 署名の生成が必要です
最後は返金決定プロセスへの関与です サーバから 購入に関する消費データを共有することで App Storeが十分な情報に基づいて 返金の決定を下せるようになります これらは アプリサーバが担う 多くの重要な責務の一部です 次に App Store Server APIの 新しいアップデートが これらの責務の遂行を どのように向上させるのかを確認します 内容が多岐にわたるため さっそく始めましょう 最初に紹介するのは トランザクションIDのアップデートです これにより アプリ内課金をより適切に管理できます 次に 署名生成機能の 向上について確認します サーバでのリクエストへの署名が 簡単になっています 最後に取り上げる機能強化は 返金プロセスへの関与を容易にします
アプリ内課金の管理から 詳しく見ていきましょう アプリ内課金の管理でまず必要なのは システム上でカスタマーアカウントを 効果的に処理することです
通常は システム上で各カスタマーに 一意のアカウントIDを割り当てて アカウントと App Storeのトランザクションの間に 明確なリンクを確立します この関連付けは 適切なコンテンツを 配信したり ユーザー体験を パーソナライズしたりする上で不可欠です App Storeは 3つの主要なデータ構造を 通じて アプリ内課金データを提供します AppTransaction、 JWSTransaction、 JWSRenewalInfoです
JWSTransactionから見ていきましょう 他の型については後で説明します
カスタマーがアプリ内課金を購入すると App Storeは署名済み トランザクションオブジェクトを提供します サーバ上でこの署名済みトランザクションを 表すのがJWSTransactionですが その検証と デコードは App Store Serverライブラリを 使用することで効果的に行えます
これは デコードされた signedTransactionInfoのサンプルです
最初のいくつかのフィールドに含まれるのは アプリに関連する重要な情報と アプリ内プロダクトのタイプです それに続くフィールドは 購入に関するメタデータであり 数量、価格、通貨などです カスタマーがオファーを 利用する場合 JWSTransactionにはofferType、 offerIdentifier、offerDiscountTypeの 各フィールドが含まれます 新たに追加されたofferPeriodフィールドは 利用されるオファーの期間を ISO 8601に準拠した形式で示します このフィールドは JWSRenewalInfoにも含まれており サブスクリプションの 次回の更新時に適用される オファーの期間を知ることができます
その後に続くのがトランザクションIDです transactionIdは トランザクションの一意の識別子であり アプリ内課金、復元、 サブスクリプションの更新で使用されます この例のIDが表しているのは サブスクリプションの更新の トランザクションIDです
originalTransactionIdは 元の購入のトランザクションIDです サブスクリプションが更新されても 変わらないため 自動更新サブスクリプションの 正確な特定に役立ちます
最後のappAccountTokenは カスタマーがアプリ内課金を購入した際に StoreKitを使用して アプリが設定するUUIDです このフィールドにより システム上で 購入をカスタマーアカウントに 関連付けできます サブスクリプションの更新時に appAccountTokenを簡単に取得できるよう このフィールドは JWSRenewalInfoにも含まれているため カスタマーアカウントを その人の 最新のサブスクリプション更新の トランザクションに シームレスに関連付けできます その仕組みを見てみましょう まず サーバ上でUUIDを生成し その値を カスタマーアカウントに関連付けます 次に その値をアプリ内課金時に StoreKitでビルドされたアプリに渡して appAccountTokenを設定します 特定のカスタマーアカウントでの アプリ内課金のすべてに 同じappAccountToken値を 使用することをおすすめします App Store Serverは JWSTransactionとJWSRenewalInfoで 同じappAccountToken値を返します 以前は アプリ内で購入が行われた時に appAccountTokenを 設定できましたが 購入がアプリ外で行われる場合もあります オファーコードを利用する場合や App Storeのプロモーションで 購入する場合です これらのケースでappAccountTokenを より柔軟に設定できるよう 新しいサーバエンドポイントを用意しました Set App Account Tokenエンドポイントを 使用すると トランザクションで 新規のappAccountTokenを設定したり 既存のものを更新したりできます このエンドポイントは すべてのプロダクトタイプに使えます 具体的な例としては まず 過去の1回限りの購入です これには消耗型/非消耗型の プロダクトと 非自動更新サブスクリプションが含まれます そして 各自動更新サブスクリプションの 最新の購入です 自動更新サブスクリプションでは このエンドポイントを使用して設定した appAccountTokenが アップグレードやダウングレードを含む 将来の更新に引き継がれます
Set App Account Tokenエンドポイントが 便利なのは オファーコードの利用などで カスタマーがアプリ外で トランザクションを完了する場合です 以前は このタイプの購入に対して appAccountTokenフィールドを 設定する方法はありませんでした StoreKitが使用されないためです さらに appAccountTokenとカスタマーアカウントの 関連付けの不整合を修正できます 例えば アカウントの所有権が システムで変更された場合などの 不整合を修正できます では App Store Server APIの一部である このエンドポイントの詳細を見てみましょう
これは Set App Account Token エンドポイントの使用例です パスにoriginalTransactionIdを指定します この値により appAccountTokenを設定するのが 1回限りの購入トランザクションか サブスクリプションかが識別されます
リクエストの本文では appAccountTokenに 適切なUUID値を設定します Set App Account Tokenエンドポイントで 指定したappAccountTokenは そのトランザクションに以前設定された appAccountTokenを上書きします appAccountTokenは transactionIdや originalTransactionIdなどの その他のトランザクションIDとともに カスタマーアカウントを App Storeトランザクションに 関連付ける方法を提供します これらのIDの概要を見てみましょう transactionIdとoriginalTransactionIdの ソースはApp Storeですが appAccountTokenの生成と App Storeトランザクションとの関連付けは デベロッパの役割です transactionIdは 個々の購入イベントを 識別するのに役立ちます originalTransactionIdの用途は 1つのサブスクリプショングループ内の 自動更新サブスクリプションの ライフサイクルの管理や サブスクリプションステータスの確認です appAccountTokenは カスタマーの アカウント情報をアプリ内課金に 関連付けるのに役立ちます アプリがファミリー共有対応の場合も ファミリー共有のトランザクションには appAccountTokenを利用できません transactionIdとoriginalTransactionIdは 両方とも JWSTransactionとJWSRenewalInfoに 存在します appAccountTokenを利用できるのは 購入時に設定した場合だけです StoreKitか 新しいSet App Account Token エンドポイントで設定します
カスタマーがアプリをダウンロードすると StoreKitでAppTransaction オブジェクトが使用可能になります これは アプリのダウンロードに関する 重要な情報を表します transactionId、originalTransactionId、 appAccountTokenは アプリ内課金に固有であるため AppTransactionオブジェクトには 含まれません しかし アプリのインストール時に コンテンツをアンロックする場合など ダウンロードの一意な識別が 重要な場合もあります このユースケースに対応するために AppTransactionオブジェクトに appTransactionIdという 新しいフィールドを追加しました appTransactionIdは 各Apple Accountで アプリごとに割り当てられる グローバル一意識別子です ファミリー共有の場合 各メンバーに一意の appTransactionIdが割り当てられます 設計上 appTransactionIdは特定の Apple Accountとアプリに固定されており 再ダウンロード、返金、再購入、ストア フロントの変更で変わることはありません appTransactionIdは カスタマーがアプリ内で購入した アプリ内課金にも付与されるため App Storeでのすべてのトランザクションに カスタマーアカウントを より柔軟に関連付けることができます その仕組みを見てみましょう これは appTransactionIdを使用して カスタマーアカウントをApp Storeの トランザクションに関連付ける方法の例です まず カスタマーが アプリをダウンロードしたら システム内のカスタマーアカウントを AppTransactionオブジェクト内の appTransactionIdに関連付けます サーバ上のAppTransactionオブジェクトの 取得方法の 1つとして アプリからこの情報を送信できます カスタマーがアプリ内課金を購入すると JWSTransactionとJWSRenewalInfoに 同じappTransactionIdが付与されます そのため 一度関連付けると App Storeトランザクションオブジェクト すべてで再利用できます appTransactionIdは すべての App Storeトランザクションオブジェクトに 存在するため 高価値のユースケースが アプリで実現されます 例えば 2つの異なる サブスクリプション購入が 同一の カスタマーアカウントのものか識別できます アプリが2つのサブスクリプション プロダクトをサポートしているとしましょう 月次請求のスポーツニュースレターと 試合の生中継を観戦するための 年間シーズンサブスクリプションです カスタマーアカウントがこの両方にアクセス できるか どうすれば判断できるでしょうか
transactionIdとoriginalTransactionIdは 各サブスクリプションで異なる一方 appTransactionIdは同じです このフィールドを活用して アプリ内課金の 復元などのアプリ内のカスタマイズを 起動時に適用できます またappTransactionIdは 一般的な App Store Server APIエンドポイントの トランザクションIDとしても使用できます Get Transaction Historyや Get All Subscription Statusesなどです 次に紹介するのは サーバエンドポイントを使用して AppTransactionオブジェクトを取得する 新しいエンドポイントです 新しいエンドポイント Get App Transaction Infoは アプリのダウンロード情報を デバイスに依存せずに サーバー上で直接取得できる 史上初の機能を提供します アプリのバージョン、プラットフォーム、 環境など アプリのダウンロードに関する 重要情報を AppTransaction オブジェクトを使って確認できます これによりビジネスモデルの変化が アプリのパフォーマンスに 及ぼす影響を把握できます なお このエンドポイントでは デバイス検証などのデバイス関連の詳細は 返されません それらで使うのは 従来通り アプリから取得される AppTransactionオブジェクトです 次は App Store Server APIの 一部であるエンドポイントを紹介します
これはGet App Transaction Info エンドポイントの使用例です 任意のトランザクションID すなわちoriginalTransactionId、 transactionId、appTransactionIdを パスに指定できます 応答には JWS signedAppTransactionInfoが 含まれます signedAppTransactionInfoをデコードする 方法の1つとして App Store Serverライブラリを使用できます Get App Transaction Infoエンドポイントは 年内に提供開始されます 次に appTransactionIdを 先ほど紹介した他のトランザクションIDと 比較してみましょう appTransactionIdは App Storeが生成します transactionIdや originalTransactionIdの場合と同様です
appTransactionIdを使用すると アプリのダウンロードを一意に識別して そのダウンロードにカスタマーの その後の購入を関連付けられます appTransactionIdは すべてのApp Store トランザクションオブジェクトで同じです ファミリー共有対応のアプリでは appTransactionIdを ファミリー共有の トランザクションに使用できます すべてのニーズにワンストップで対応する IDソリューションであるappTransactionIdの 使用をおすすめします アプリ内課金の管理や サーバ上でのカスタマーアカウントとの 関連付けが容易になります 次は リクエストへの署名に関する いくつかの重要な機能強化を紹介します まず サーバでJWS文字列を作成します JWSはJSON Web Signatureの略です 次に App Store Connectから ダウンロードした秘密鍵を 使用して このJWS文字列に署名します
次に この署名文字列を StoreKitでビルドしたアプリに送信して 署名を必要とする関数を呼び出します
すると StoreKitがその署名済みの 署名文字列をApp Store Serverに送信します 以前は ユースケースに応じて App Store Serverで要求される 様々な形式で署名が行われていました 今回 すべてのユースケースで リクエストへの 署名が統一され JWSの署名形式が 使用されるようになりました つまりこの形式を 署名を必要とする StoreKitの呼び出しで使えるようになります 例えば プロモーションオファーの署名を 生成する関数の呼び出しなどで使えます JWSの署名形式を使用して プロモーション オファーに署名できるようになりました この新しい署名方法を 以前のプロモーションオファーへの署名の 代わりに使用できます お試しオファーを より柔軟に提供できるように 最近 新しく JWSのお試しオファー署名を導入しました この機能を使用すると お試しオファーの利用資格を トランザクションごとやカスタマーごとに カスタマイズできます これにより カスタマーがApp Storeで 利用できるお試しオファーの数を より細かく制御できます Advanced Commerce APIで 署名済みの JWSのアプリ内リクエストも送信できます 詳細については デベロッパ向けドキュメントをご覧ください ここからは サーバでのJWSによる プロモーションオファー署名の作成方法を 説明します StoreKitで プロモーションオファーの署名を 使用して アプリの既存の登録者や 解約した登録者を維持できます App Store Serverライブラリを プロモーションオファーの 署名の作成に使用している例がこちらです この例ではJavaを使用しています まず PromotionalOfferV2SignatureCreator クラスをインスタンス化します アプリのkey(秘密鍵)、keyId、 issuerId、bundleIdを使用します key、keyId、issuerIdは App Store Connectで確認できます
これらの値は署名に使用され これにより プロモーションオファーが デベロッパの同意なしに 利用されるのを防止できます
次にtransactionIdを指定します カスタマーに属する 任意のトランザクションIDを 指定できます appTransactionIdなどです
transactionIdを指定するのは オファーを 特定のカスタマーに限定する場合です そうでない場合は省略できます
次に productIdとofferIdを指定します このIDで表されるオファーを App Store Connectで 事前に構成してあります
最後に productId、 offerId、transactionIdを createSignature関数に渡します ご覧の通り 新しい署名は 古いバージョンよりシンプルです 入力項目が少ないためです 統一されたJWS署名による 署名形式を使用することにより 様々なユースケースで リクエストへの署名を簡素化できます オファーを提供した後に カスタマーが返品して 返金をリクエストする場合があります 支払い上の問題や誤購入など こちらの制御が及ばない理由で 行われることもあります そのような場合に 返金決定プロセスに関与する方法について 説明します まずメリットをいくつか紹介します デベロッパが返金決定への関与を 検討すべきなのは カスタマーのプロダクト消費を 把握しているからです 例えば アプリで消耗型プロダクトを サポートしている場合は カスタマーの消費可能な残高は デベロッパがサーバ上で管理します デベロッパの関与は 返金リクエスト後の 顧客満足度の向上にも寄与します
カスタマーが返金をリクエストすると CONSUMPTION_REQUEST通知が App Storeからサーバに送信されます 返金決定プロセスに情報を提供するには この通知に応答します この応答にはSend Consumption Information エンドポイントを使用します
ここで紹介したいのが 機能強化された 新しい Send Consumption Information V2 エンドポイントです
その中核となるのは統合の簡素化であり 必要な入力項目の数が 以前のバージョンに比べて 大幅に削減されています 新しいエンドポイントは 返金の案分設定もサポートしているため プロダクトが部分的に消費されている ケースに より適切に対応できます 以前のバージョンでサポートされていた プロダクトは 消耗型と 自動更新サブスクリプションのみでしたが サポート対象が すべてのプロダクトタイプに拡張され 非消耗型と非自動更新サブスクリプションも 対象になりました
旧バージョンのエンドポイントを 使用している場合は 非推奨になりますが リクエストは引き続き受け付けられます Send Consumption Information エンドポイントをまだ使用していない場合は App Store Serverライブラリの 最新のV2を使用することをおすすめします 次に Send Consumption Information V2 エンドポイントの使用方法を説明します カスタマーが 消耗型プロダクトの購入に対する 返金をリクエストして CONSUMPTION_REQUEST通知が サーバに送信されてきたとします Send Consumption Information V2 エンドポイントで その通知に応答する方法の例がこちらです
パスにtransactionIdを指定します このIDは CONSUMPTION_REQUEST通知に 記載されています
新しいエンドポイントには 入力フィールドが合計5つあります 旧バージョンの12個から減りました 5つの入力フィールドのうち 3つが必須フィールドで 2つは省略可能です フィールドを大幅に減らしたのは 返金の決定への関与を容易にするためです customerConsentedフィールドをtrueに 設定するのは 返金リクエストに関連する 消費データをApp Storeに送信することに カスタマーが同意した場合です 対象には ConsumptionRequestV2の 本文で指定したすべてのデータが含まれます カスタマーの同意がない場合は CONSUMPTION_REQUEST通知に 応答しないでください このフィールドをfalseに設定して エンドポイントを呼び出すと リクエストは拒否されます sampleContentProvidedを使用して プロダクトの購入前にサンプルコンテンツを ユーザーに提供したかどうかを指定します deliveryStatusでは コンテンツがカスタマーに 正常に配信された場合はDELIVEREDを それ以外の場合は 該当する UNDELIVEREDステータスを指定します
必要に応じて 返金設定を指定することもできます 返金の案分設定も 新たに選択できるようになりました GRANT_PRORATED値を使用します 従来通り 全額返金と返金なしも選択できます 返金設定を指定しない場合は このフィールドを設定しないでください consumptionPercentageは プロダクトの消費量を ミリパーセント単位で指定します
25,000という値は 消耗型プロダクトが 25%消費されたことを表します Send Consumption Information V2 エンドポイントは 年内に提供開始されます 次は 最新のV2エンドポイントの 新しいオプションである 返金の案分設定の詳細を説明します 返金の案分設定の使用を検討するのは カスタマーが部分的に消費できる プロダクトが関連する場合です
返金の案分設定を使用すると 消費量を指定できるため App Storeから 適切な金額が返金されるようになります
消耗型、非消耗型、 非自動更新サブスクリプションの プロダクトタイプで 返金の案分設定を行う場合は consumptionPercentageを指定する 必要があります App Storeが適切な返金を 正確に行えるようにするためです 自動更新サブスクリプションの consumptionPercentageは App Storeにより計算されます 計算にはカスタマーのサブスクリプションの 残り期間が使用されます デベロッパが提出する消費データは App Storeで使用され 全額返金か、 案分返金か、返金拒否かの 決定に活用されます 決定の結果は REFUND通知か REFUND_DECLINED通知で知らされます REFUND_DECLINED通知を 受け取った場合は対応不要ですが REFUND通知を受け取った場合 デベロッパには 適切な措置を講じる責任があります これはREFUND通知の例です 新しいrefundPercentageフィールドで App Storeでどれだけの返金が認められたか 把握できるようになりました この例では75%の返金が認められており それに応じて 消費されたプロダクトに対し 適切な措置を実施できます
このフィールドを使う際 財務と会計のすべての目的に関して 信頼できる情報源となるのは App Store Connectであることを 忘れないでください また 無効化の種類を把握するために 参照できるのが 新しいrevocationTypeフィールドです 値はREFUND_FULL、REFUND_PRORATED、 FAMILY_REVOKEのいずれかです これは消耗型プロダクトの返金なので REFUND_FULLか REFUND_PRORATEDになります REFUND_FULLか FAMILY_REVOKEの場合は サーバ上のコンテンツへのアクセスを すぐに無効化します REFUND_PRORATEDの場合は 返金された分のコンテンツを無効化します 次に 案分返金の返金通知を サーバで処理する方法を説明します プロダクトが消耗型、非消耗型、 非自動更新サブスクリプションの場合は カスタマーのアカウントで無効化する コンテンツの割合を refundPercentageフィールドを 使用して計算します 例えば カスタマーが 仮想通貨を購入した場合は 返金された金額に応じて 残高を減らすことができます 自動更新サブスクリプションでは 案分返金を全額返金と同じように処理します 現在のサブスクリプションステータスを 確認し 適切な措置を行いましょう ぜひ 新しいSend Consumption Information V2エンドポイントを使用して 返金決定プロセスに関与してください かつてないほど使いやすく パワフルになっています 本日は多くの内容を説明しました 簡単にまとめましょう 各種のトランザクションIDを確認し ワンストップのトランザクションIDである appTransactionIdを紹介しました 次に 統一されたJWSによる署名の 署名形式を確認しました 最後に 返金の決定に 簡単に関与できる仕組みを説明しました 最後に 次のステップについてお話しします オープンソースのApp Store Server ライブラリにこれまで貢献されてきた皆様に 感謝いたします 未参加の方は ぜひGitHubページにアクセスして App Storeコミュニティへの 貢献とサポートの方法をご確認ください 新機能に関する 皆さんのご意見をお待ちしています フィードバックアシスタントで 機能に関する ご要望やご意見を App Store Serverチームまでお寄せください StoreKitに追加された アップデートの詳細については WWDC25の「What's new in StoreKit and In-App Purchase」をご覧ください WWDC24のセッション 「Explore App Store server APIs for In-App Purchase」でも App Store Serverの詳細を学べます ありがとうございました またお会いしましょう
-