すべての記事
Deep dive読了まで 7 分

無効化された購入通知により、返金が着地した瞬間に Google Play サーバーはアクセスを取り消せます

Google Play は、購入が返金、チャージバック、または無効化された瞬間に、無効化された購入通知をサーバーへプッシュできます。この通知は purchaseToken、orderId、productType、refundType を運び、意味することはただ一つ、アクセスを取り消せということです。その読み方と組み込み方を解説します。

夕暮れの開発者のワークスペース。反転された支払いを表示するスマートフォンが置かれ、Google Play の無効化された購入通知がサーバーに届く様子を表している

要点

  • 無効化された購入通知は、購入が返金、チャージバック、その他の理由で無効化された瞬間に Google Play が Cloud Pub/Sub トピックへプッシュする Real-time Developer Notification です。これはプッシュ信号であり、ポーリングして取得する必要はありません。
  • この通知はちょうど 4 つのフィールド、`purchaseToken`、`orderId`、`productType`、`refundType` を運びます。これだけでデータベース内の該当する購入を特定し、それに紐づくエンタイトルメントを取り消すのに十分です。
  • `productType` は無効化されたサブスクリプションで `1`、無効化された 1 回限りの購入で `2` です。`refundType` は全額返金で `1`、数量ベースの部分返金で `2` であり、後者は複数数量の 1 回限りの購入にのみ適用されます。
  • 無効化された購入通知は、顧客がすでに返金を受け取っていることを意味します。Google 自身のガイダンスは、購入者がもはやエンタイトルメントを保持すべきではないため、該当するコンテンツへのアクセスを取り消すことです。
  • 無効化された購入通知は、有効にするまでオフになっています。Play Console の Monetization setup で、サブスクリプションとすべての無効化された購入か、それに 1 回限りの製品イベントを加えたもののいずれかを選びます。どちらの選択肢にも無効化された購入が含まれます。
  • 無効化された購入通知は、証拠を求める 2 つの返金フローのいずれでもありません。これは事後の通知です。あなたの入力を受け付ける唯一のフローは、12 時間の期限がある Apple の CONSUMPTION_REQUEST と、24 時間の期限がある `orders.reviewrefund` による Google Play のチャージバックレビューです。
  • 2026 年 8 月 3 日から、Google はチャージバックの購入価格に銀行手数料を加えた額を開発者に転嫁します。無効化された購入通知は、チャージバックによる無効化が発生したことをサーバーが最初に知る手段であることが多いため、これを組み込むことで、もはや代金を受け取れない顧客への提供を停止できます。

Google Play での返金は、後になってレポートで発見するようなものである必要はありません。Google Play は、購入が無効化された瞬間に無効化された購入通知をサーバーへプッシュできます。それは購入者がセルフサービスで返金を受けた場合でも、サポート担当者が返金を認めた場合でも、銀行がチャージバックを強制した場合でも、あるいはあなた自身が取り消しフラグを立てて注文を返金した場合でも同じです。メッセージは非常に小さく、正確な購入を名指しし、たった一つの指示を運びます。エンタイトルメントを返上せよ、なぜなら代金はすでに失われているからです。

無効化された購入通知とは実際に何か

無効化された購入通知は、Google Play の Real-time Developer Notifications、すなわち RTDN の一種です。RTDN はプッシュチャネルです。Google はあなたが所有する Cloud Pub/Sub トピックへメッセージを発行し、バックエンドは次の定期ポーリングで気づくのではなく、イベントの直後にそれを受け取ります。これこそが、古いプル方式に対する無効化された購入通知の要点です。返金を数時間後ではなく、発生と同時に知ることができます。

プル方式は依然として存在し、依然として重要です。Voided Purchases API を使えば、サーバーは自分のスケジュールで、ある期間内に無効化された購入のリストを問い合わせられます。両者は補完的です。通知は一つの購入が切り替わった瞬間を伝え、API は一括での照合と、取りこぼしたメッセージが残したものの埋め戻しを可能にします。

それは Real-time Developer Notification の中に乗って届く

無効化された購入通知が単独で届くことはありません。それは DeveloperNotification ラッパーの中に収まっており、そのラッパーは Pub/Sub メッセージの data フィールドに単一の base64 エンコード文字列として届けられます。ハンドラーは何かを読み取る前に、その文字列を JSON にデコードします。ラッパーは常にアプリとイベント時刻を名指しし、Google が定義する 5 つのうちちょうど 1 つの通知オブジェクトを含みます。それらは相互排他的なので、voidedPurchaseNotification を運ぶメッセージがサブスクリプションや 1 回限りのイベントを同時に運ぶことはありません。

ラッパーフィールド保持する内容
version通知スキーマのバージョン。例えば 1.0
packageNameイベントが属するアプリ。例えば com.acme.app
eventTimeMillisイベントが発生した時刻。エポックからのミリ秒
5 つの通知オブジェクトのうち 1 つoneTimeProductNotificationsubscriptionNotificationvoidedPurchaseNotificationpendingRefundReviewNotification、または testNotification。メッセージごとに 1 つだけ存在する

それが運ぶ 4 つのフィールド

ラッパーを取り除けば、無効化された購入通知そのものは 4 つのフィールドです。これは意図的に切り詰められています。正しい購入を見つけてエンタイトルメントを調整することだけが必要なら、この 4 つで十分であり、行動するためにどの API も呼び戻す必要はない、というのが Google の立場です。

フィールドそれが何か使い方
purchaseToken商品が購入されたときにデバイスへ渡されたトークンあなたの主キー。付与時に保存した購入レコードと照合する
orderId購入者に表示される注文 ID。例えば GS.0000-0000-0000サポートと照合のための人間が読める第 2 のキー
productType無効化された商品がサブスクリプションか 1 回限りの購入か正しい取り消しパスへ振り分ける
refundType無効化が全額返金か数量ベースの部分返金かすべてを取り消すか、返金された数量だけを取り消すかを決める

productType は何が無効化されたかを伝える

productType は小さな整数で、どの取り消しパスを取るかを決めます。サブスクリプションの無効化は継続的なアクセスを巻き戻す必要があり、1 回限りの購入の無効化は単一のエンタイトルメントを取り除くだけです。

`productType` の値定数意味
1PRODUCT_TYPE_SUBSCRIPTIONサブスクリプション購入が無効化された
2PRODUCT_TYPE_ONE_TIME1 回限りの購入が無効化された

refundType はどれだけが返金されたかを伝える

refundType は、きれいな全額の取り消しと部分的なものを区別します。部分的なケースは限定的です。それは複数数量の 1 回限りの購入で、数量の一部だけが(全部ではなく)返金されたときにのみ現れます。

`refundType` の値定数意味
1REFUND_TYPE_FULL_REFUND購入が全額無効化された
2REFUND_TYPE_QUANTITY_BASED_PARTIAL_REFUND複数数量の購入の一部が無効化された

まず有効にすること。さもないと決して届かない

無効化された購入通知はデフォルトでは流れません。RTDN は Play Console で一度有効にし、あなたが管理する Pub/Sub トピックに向けます。そのスイッチは Monetize、続いて Monetization setup の下、ページ上部の Real-time developer notifications セクションにあります。Enable real-time notifications にチェックを入れ、projects/{project_id}/topics/{topic_name} の形式で完全なトピック名を貼り付け、信頼する前に Send Test Message で配管が機能することを確認してください。

コンテンツの切り替えこそ、人々が無効化された購入を見落とす場所です。どちらの選択肢にもそれらは含まれているので、サブスクリプションを維持したまま返金を誤ってオプトアウトすることはできません。

  • サブスクリプションとすべての無効化された購入の通知を受け取る。サブスクリプションイベントとすべての無効化された購入を受け取りますが、1 回限りの製品購入イベントは受け取りません。
  • サブスクリプションと 1 回限りの製品のすべての通知を受け取る。上記に加えて、ONE_TIME_PRODUCT_PURCHASEDONE_TIME_PRODUCT_CANCELED などの 1 回限りの製品イベントを受け取ります。
紙のレシートの隣に裏返しに置かれたクレジットカード。無効化された Google Play の購入を象徴している

それが金銭的にあなたにいくらの損失をもたらすか

無効化は、通知があなたに届く頃にはすでに計上済みの損失です。販売価格は失われており、その顧客に提供するために費やしたものも同様です。彼らが画像を生成し、あなたのモデルに対して呼び出しを実行し、ストレージを使い、あるいは第三者への支払いを発生させていたなら、それらのコストは実際の金銭で支払われており、返金では戻ってきません。通知はそのいずれも回収できません。通知にできるのは、ここから先の出血を止めることであり、それこそが素早く対処すべき唯一の理由です。

出血が最もひどいのはサブスクリプションとチャージバックです。取り消しそこねたサブスクリプションは、もはや支払っていない顧客のために、月を追うごとに提供コストをかけ続けます。そしてチャージバックは最も高くつく種類の無効化です。2026 年 8 月 3 日から、Google のドキュメントは、チャージバックが購入価格に銀行手数料を加えた額を開発者に転嫁すると述べています。無効化された購入通知は、チャージバックが完了したことをあなた自身のシステムが最初に耳にする場所であることが多いため、その場で取り消すハンドラーこそが、失われた売上を失われた売上プラス数週間の無料サービスに変えないための鍵です。

無効化された購入通知の処理方法、ステップごとに

メッセージを検証し重複を排除する

  • Pub/Sub メッセージが Google から来ており、あなたが構成したトピックを対象としていることを確認し、次に base64 の data フィールドをデコードして DeveloperNotification の JSON を取得します。
  • Pub/Sub の messageId を使って重複を破棄します。Google は同じ通知が複数回配信されうると警告しているので、再送を正常なものとして扱い、ハンドラーを冪等にしてください。
  • メッセージを安全に記録した後にのみ確認応答します。そうすればハンドラー途中のクラッシュでイベントを失うことはありません。

購入を検索する

  • purchaseToken を、最初にエンタイトルメントを付与したときに保存した購入と照合します。サポートの検索や手動照合には orderId をフォールバックとして使います。
  • productType を読んでサブスクリプションか 1 回限りの取り消しパスを選び、refundType を読んで全額取り消しか部分取り消しかを決めます。

取り消して記録する

  • エンタイトルメントを取り除きます。全額返金の場合は、その商品へのアクセスを遮断します。数量ベースの部分返金の場合は、付与した数量を返金された分だけ減らし、残りはそのままにします。
  • 何をいつ行ったかを、purchaseTokenorderId をキーにして書き留めます。その記録こそが、後でサポートチケットに答えることを可能にし、Voided Purchases API があなた自身の状態に対してきれいに照合することを可能にします。

それが他の返金シグナルの中でどこに位置するか

無効化された購入通知は通知であって、交渉ではありません。それはすでに決定された結果を伝えます。混同しやすいシグナルと並べて見る価値があります。なぜなら、そのうちの一部だけが、あなた側の言い分を求めてくるからです。

シグナル方向あなたの入力を受け付けるか
無効化された購入通知 (RTDN)Google がサーバーへプッシュいいえ。すでに起きた無効化を報告する
Voided Purchases APIサーバーが Google からプルいいえ。過去の無効化の読み取り専用リスト
pendingRefundReviewNotification (RTDN)Google がサーバーへプッシュはい、間接的に。チャージバックを示し、あなたは 24 時間以内に orders.reviewrefund を通じて異議を申し立てる
Apple CONSUMPTION_REQUESTApple がサーバーへ問い合わせはい。12 時間以内に Send Consumption Information で応答する

覚えておくべき要点は単純です。両ストアを通じて、開発者が発言権を持つ返金フローはちょうど 2 つ、Apple の CONSUMPTION_REQUEST と Google Play のチャージバックレビューだけです。無効化された購入通知はそのどちらでもありません。それがあなたに届く頃には決定はすでに済んでおり、あなたの手に残された唯一のものは、どれだけ速く取り消すかだけです。

よくある質問

Google Play での無効化された購入通知は何を意味しますか?
それは購入が返金、チャージバック、その他の理由で無効化され、顧客が返金を受け取ったことを意味します。Google のガイダンスは、購入者がもはやエンタイトルメントを保持すべきではないため、該当するコンテンツへのアクセスを取り消すことです。通知は `purchaseToken` と `orderId` を通じて正確な購入を名指しします。
Google Play の無効化された購入通知にはどのようなフィールドが含まれますか?
4 つです。`purchaseToken`、`orderId`、`productType`、`refundType`。`productType` はサブスクリプションで `1`、1 回限りの購入で `2` です。`refundType` は全額返金で `1`、複数数量の購入における数量ベースの部分返金で `2` です。
無効化された購入通知はどうすれば有効にできますか?
Play Console で Monetize、続いて Monetization setup を開き、Real-time developer notifications セクションで Enable real-time notifications にチェックを入れ、Cloud Pub/Sub のトピック名を入力します。コンテンツの両方の選択肢、すなわちサブスクリプションとすべての無効化された購入、およびそれに 1 回限りの製品イベントを加えたものは、いずれも無効化された購入を含みます。
無効化された購入通知と Voided Purchases API の違いは何ですか?
通知は、購入が無効化された瞬間に Cloud Pub/Sub を通じてリアルタイムで届けられるプッシュ信号です。Voided Purchases API は、ある期間の無効化を一覧するためにサーバーが自分のスケジュールで問い合わせるプル方式です。即座に反応するには通知を、照合と埋め戻しには API を使ってください。
無効化された購入通知で返金に異議を申し立てられますか?
いいえ。それはすでに下された決定の事後通知です。あなたの入力を受け付ける唯一の Google Play フローは `orders.reviewrefund` を通じたチャージバックレビューで、回答期限は 24 時間です。Apple では 12 時間の期限がある CONSUMPTION_REQUEST がそれにあたります。

出典と参考資料

RefundHalt

App Store と Google Play の返金を自動処理

続きを読む

次の返金リクエストは、すでに向かってきています。

異議を申し立てられなかった返金について、もう 1 通のサポートメールを読む時間で RefundHalt を設定できます。