すべての記事
実践ガイド読了まで 9 分

返金通知を取りこぼすと、唯一異議を出せる返金を失いかねない。ただし両ストアとも、間に合えば取り戻せる

サーバーが返金通知を取りこぼすと、あなたの証拠を求める 2 つの返金フローは、あなた抜きで締め切られます。Apple と Google Play がどう再送するのか、取りこぼした返金通知をどこまでさかのぼって回収できるのか、そして回収できない穴はどこにあるのかを解説します。

夜のサーバーラック。安定した緑のランプが並ぶ中にひとつだけ琥珀色の警告灯が点き、手前のカートにノートパソコンが置かれている。返金通知の取りこぼしの裏にある、静かな障害のイメージ

要点

  • App Store Server Notifications V2 の配信に失敗すると、Apple は前回の試行から 1、12、24、48、72 時間後の計 5 回再送します。そのため 2 回目の再送が届くのは、最初の試行から約 13 時間後です。
  • Apple は CONSUMPTION_REQUEST を受信してから 12 時間以内の応答を求めています。最初の配信と 1 時間後の再送を逃したサーバーがリクエストに気づく頃には、その期限をおそらく過ぎています。
  • Apple の Get Notification History エンドポイントは、本番環境で過去 180 日分の V2 通知を 1 ページ 20 件で返します。onlyFailures フラグを使うと、サーバーに届かなかった通知と、まだ再送中の通知だけに絞り込めます。
  • Google Play がチャージバックの審査を届けるのは PendingRefundReviewNotification だけで、24 時間以内に orders.reviewrefund を呼ぶのに必要な pendingRefundToken もこの通知に含まれています。保留中の審査を一覧できる別の API は、Google のドキュメントにありません。
  • Google Cloud Pub/Sub は確認応答されていないメッセージをデフォルトで 7 日間、最大 31 日間保持します。また、有効期限を変更しない限り、サブスクライバーの活動が 31 日間ないサブスクリプションは削除されます。
  • Google Play の Voided Purchases API では、過去 30 日分の返金、取り消し、チャージバックを回収できます。クォータは 1 日 6,000 クエリ、任意の 30 秒間で 30 クエリです。ただし、一度も応答しなかったチャージバック審査は回収できません。
  • Apple のサンドボックスは各通知を 1 回だけ送り、再送しません。サンドボックスでしか動かしたことのない回収処理は、Apple の本番の再送スケジュールで一度も試されていないことになります。

返金通知の取りこぼしは、デベロッパーが口を出せる唯一の 2 つの返金判断を、静かに失ってしまう原因です。Apple の CONSUMPTION_REQUEST も Google Play のチャージバック審査も通知から始まり、どちらも短い期限で締め切られます。Apple は 12 時間、Google は 24 時間です。メッセージが届いたときにサーバーが落ちていたり、遅かったり、設定が間違っていたりしても、ストアは待ってくれません。手元にある情報だけで判断します。

良い知らせは、どちらのストアも最初の失敗でメッセージを捨てたりしないことです。Apple は再送し、問い合わせ可能な 180 日分の履歴を残します。Google は Pub/Sub 経由で配信し、確認応答されていないメッセージを数日間保持します。悪い知らせは、再送のタイミングが応答期限と噛み合わないこと、そして 2 つのフローのうち 1 つには回収用の API がまったくないことです。

各ストアは返金通知をどう届けるか

Apple は App Store Server Notifications を、App Store Connect で設定した HTTPS の URL に直接送ります。Google はサーバーを直接呼び出しません。リアルタイム デベロッパー通知を Google Cloud Pub/Sub のトピックに公開し、そのトピックのサブスクリプションがエンドポイントへプッシュするか、サーバーがプルするのを待ちます。

項目App StoreGoogle Play
配信経路あなたの URL への HTTPS POSTCloud Pub/Sub トピック、プッシュまたはプル
成功とみなされる条件HTTP 200 から 206Pub/Sub メッセージの確認応答、またはプッシュ エンドポイントの成功コード
再送V2 は 5 回、前回の試行から 1、12、24、48、72 時間後確認応答されるか保持期間が終わるまで Pub/Sub が再配信
取りこぼしたメッセージの保存期間Get Notification History に 180 日サブスクリプションにデフォルト 7 日、最大 31 日
証拠を求められる返金CONSUMPTION_REQUEST、12 時間以内に応答PendingRefundReviewNotification、24 時間以内に応答
確定した返金のプル型バックアップGet Notification History、Get Refund HistoryVoided Purchases API、過去 30 日
サンドボックスやテストでの挙動1 回のみ、再送なしPlay Console の Send Test Message

Apple が失敗とみなすもの

Apple のドキュメントは明確です。200 から 206 のステータスを返せば配信は完了です。40x や 50x を返すと Apple は再送します。それ以外のコードも、すべて失敗として扱われます。各試行には sendAttemptResult が記録され、その値は実際の障害のチェックリストのようです。TIMED_OUT、TLS_ISSUE、CIRCULAR_REDIRECT、NO_RESPONSE、PREMATURE_CLOSE、UNSUCCESSFUL_HTTP_RESPONSE_CODE などがあります。TIMED_OUT について、Apple 自身はサーバーがメッセージをリクエスト内で同期処理していないか確認するよう勧めています。

Google が失敗とみなすもの

プッシュ サブスクリプションでは、エンドポイントが成功のレスポンスコードを返すことが確認応答になります。プル サブスクリプションでは、サーバーがプルした各メッセージに確認応答しなければ、Pub/Sub は再び配信します。確認応答の期限はデフォルトで 10 秒、最大で 600 秒です。Google の RTDN ガイドには、繰り返しておく価値のあるルールがもうひとつあります。通知は何かが変わったことを伝えるだけなので、購入の完全な状態は Google Play Developer API を呼んで取得する必要があります。

Apple の再送スケジュールが 12 時間の期限に合わない理由

Apple の再送間隔は、最初の試行からではなく、前回の試行から数えます。合計すると、サーバーが失敗し続ける 1 件の V2 通知は次のような経過をたどります。

試行前回の試行からの待ち時間最初の試行からの経過時間
最初の配信なし0
再送 11 時間1
再送 212 時間13
再送 324 時間37
再送 448 時間85
再送 572 時間157

Apple は CONSUMPTION_REQUEST を受信してから 12 時間以内に応答するよう求めています。最初の配信時と 1 時間後の再送時にサーバーが落ちていれば、次の試行が届くのは最初の配信から 13 時間後です。再送で初めて受信したリクエストに新たに 12 時間が与えられるのかどうか、Apple は明言していません。慎重に読むなら、最初の試行を期限の起点とみなすべきです。つまり、1 時間以上取りこぼしたリクエストは、再送だけでは救えません。

HTTP 400 を返した後も Apple は再送するか

ドキュメントによれば、再送します。Apple は再送のきっかけになるコードとして 40x と 50x を挙げています。2026 年 3 月、あるデベロッパーが Apple のフォーラムで、400 を返した後に再送が止まったようだと報告し、その後 1、2 日で配信が再開したと書き込みました。Apple は Feedback Assistant での報告を求めています。ドキュメントの挙動をルールとし、自分の監視をその裏付けとしてください。

Get Notification History で取りこぼした App Store 通知を回収する

Get Notification History は、指定した期間に Apple がサーバーへ送ろうとしたバージョン 2 の通知を返します。各レコードには署名付きペイロードがそのまま含まれるので、リアルタイムの通知と同じハンドラーに渡せます。各レコードには最大 6 件の sendAttempts 配列も含まれ、最初の試行と 5 回の再送にそれぞれ対応します。

  • startDate と endDate は必須で、startDate は本番環境では過去 180 日以内、サンドボックスでは過去 30 日以内でなければなりません。
  • onlyFailures を true にすると、サーバーに届いていない通知と、Apple がまだ再送中の通知だけを取得できます。
  • CONSUMPTION_REQUEST や REFUND などの notificationType を 1 つ指定するか、1 人の顧客の transactionId で絞り込めます。ただし、同じリクエストで両方は使えません。
  • 1 回の呼び出しで返るのは最大 20 件です。hasMore が true の間は paginationToken を付けて呼び出しを続け、毎回同じリクエストボディを送ってください。

返金に関しては、注意点がひとつあります。Apple によれば、履歴のレコードは現在ではなく、通知が最初に送られた時点の購入状態を反映しています。つまり、回収した REFUND は過去の事実です。アクセス権を取り消す前に、トランザクションやサブスクリプションのステータス エンドポイントで現在の状態を確認してください。

V1 の通知はこの方法では回収できない

Get Notification History が対象とするのはバージョン 2 だけです。Apple は V1 の通知を、前回の試行から 6、24、48 時間後の 3 回再送しますが、すべて失敗すると再生できる履歴は残りません。V1 のままのアプリを V2 に移行すべき理由が、またひとつ増えます。

取りこぼした Google Play の返金通知を回収する

Google のセーフティネットは Pub/Sub そのものです。サブスクリプションが存在する限り、誰も確認応答しなかったメッセージは保持期間中そこに残ります。デフォルトは 7 日で、引き上げれば最大 31 日です。エンドポイントが復旧すれば配信も再開します。ただし、この仕組みを静かに無効にしてしまう設定が 2 つあります。

  • デッドレター トピックは、配信の失敗が設定回数に達したメッセージをサブスクリプションから移します。デフォルトは 5 回で、デフォルトの即時再配信の再試行ポリシーでは、5 回の試行はすぐに使い切ってしまうことがあります。使っている場合は、デッドレター トピックを 2 つ目の受信トレイのように見張ってください。
  • 開いている接続、実行中のプル、成功したプッシュなど、サブスクライバーの活動がないサブスクリプションは、デフォルトで 31 日後に期限切れになります。1 か月壊れたままのエンドポイントは、サブスクリプションそのものと、そこで待っていたすべてのメッセージを失う可能性があります。

無効化された返金には 30 日のバックアップがある

すでに発生した返金については、Voided Purchases API がプル型のバックアップです。過去 30 日分の無効化された購入を 1 ページ最大 1,000 件で一覧でき、クォータはアプリごとに 1 日 6,000 クエリ、任意の 30 秒間で 30 クエリです。type 1 を渡すと、買い切りアイテムに加えてサブスクリプションも含まれます。毎日実行すれば、通知パイプラインが取りこぼした返金を拾えるので、利用権と収益の数字を正しく保てます。

チャージバック審査にはバックアップがない

PendingRefundReviewNotification は事情が異なります。この通知には orders.reviewrefund に渡す必要のある pendingRefundToken が含まれており、受信から 24 時間以内に返金に関する希望と利用状況の証拠を送らなければなりません。Google は最初の呼び出しだけを記録し、それ以降は無視します。保留中の審査を一覧するエンドポイントは Google のドキュメントに記載されていないため、その Pub/Sub メッセージが失われれば、そのチャージバックに対する証拠も一緒に失われます。

返金通知の取りこぼしが金銭面で意味すること

すでに確定した返金の通知を取りこぼした場合のコストは、帳簿上の手間です。後で Voided Purchases API や Get Notification History で見つけ、ポリシーに従ってアクセス権を取り消せば、レポートも追いつきます。面倒ですが、安く済みます。

異議を出せる 2 つのフローで通知を取りこぼすと、実際にお金を失います。ストアがあなたの証拠なしで判断するからです。Apple では、あなたの消費データなしで返金の判断が下されることを意味します。Google Play では、2026 年 8 月 3 日以降の注文の場合、チャージバックに負けると購入価格から Play のサービス手数料を引いた額に加え、購入者の銀行が課すチャージバック手数料を負担します。Google が負担するのは自社のサービス手数料だけです。

しかも、購入内容を提供するために使ったお金は、紛争が始まる前にすでに出ていっています。

  • コンピューティング: 購入者がすでに使った生成、レンダリング、モデル応答のそれぞれにかかった GPU とサーバーの時間。
  • API 呼び出し: 送信した瞬間に課金される外部サービスへのリクエスト。多くは呼び出しごとの課金です。
  • ストレージ: 購入者が作成したファイルやメディア。今もホスティング料金に乗っています。
  • 支払い: その売上について、クリエイター、アフィリエイト、パートナーにすでに支払ったレベニューシェア。

返金が通れば、どれも戻ってきません。その 12 時間または 24 時間のうちに送る証拠が唯一の打つ手であり、通知の取りこぼしはそれを奪います。

頼りになる回収の手順

  • まず確認応答する。生のペイロードを保存し、成功コードを返してから、キューで処理します。
  • 数分おきに onlyFailures を付けて Apple の Get Notification History で CONSUMPTION_REQUEST をポーリングし、障害で失うのを 12 時間の期限のうち数分に抑えます。
  • 毎日、onlyFailures を付けて過去数日分のすべてのタイプを Get Notification History で洗い出し、見つかったものを再生します。
  • Google Play のアプリごとに、毎日 type 1 で Voided Purchases API を呼び、記録済みの返金と突き合わせます。
  • Pub/Sub では、メッセージの保持期間を 7 日以上にし、デッドレター トピックがあればアラートを設定し、未配信のメッセージがたまったときにもアラートを出します。
  • 本番環境でも経路全体をテストします。Apple のサンドボックスは各通知を 1 回だけ送って再送しませんが、Request a Test Notification と Get Test Notification Status を組み合わせれば、サーバーがどう応答したかを正確に確認できます。
早朝の光の中、机の上で上向きに置かれたスマートフォンの横にコーヒーマグとノートがある。取りこぼした返金通知を確かめる毎日のチェックの、落ち着いた始まり

RefundHalt は両ストアの通知をあなたに代わって受け取り、CONSUMPTION_REQUEST とチャージバック審査に期限内に自動で応答します。時計を見張るのは、もうあなたの役目ではありません。

よくある質問

失敗した App Store のサーバー通知を、Apple はどのくらいの期間再送し続けますか?
バージョン 2 では約 6 日半です。Apple は前回の試行から 1、12、24、48、72 時間後の 5 回再送するため、最後の再送は最初の配信から 157 時間後になります。バージョン 1 の通知は、前回の試行から 6、24、48 時間後の 3 回再送されます。
取りこぼした App Store のサーバー通知は、どこまでさかのぼって回収できますか?
本番環境では 180 日です。Apple の Get Notification History エンドポイントは、過去 180 日分、サンドボックスでは過去 30 日分のバージョン 2 通知を 1 回の呼び出しで 20 件ずつ返します。onlyFailures フラグを使えば、サーバーに届かなかった通知だけに絞り込めます。
サーバーが HTTP 400 を返した場合、Apple は通知を再送しますか?
Apple のドキュメントによれば、再送します。サーバーが 40x または 50x のステータスを返すと Apple は再送し、200 から 206 を成功として扱います。それ以外のステータスも失敗とみなされます。
取りこぼした Google Play のチャージバック審査は回収できますか?
Pub/Sub のメッセージがまだ残っている間だけ可能です。orders.reviewrefund に必要な pendingRefundToken は PendingRefundReviewNotification で届き、保留中の審査を一覧する API は Google のドキュメントにありません。そのため、デフォルトで 7 日間保持されるサブスクリプションの未確認応答メッセージが、唯一のコピーです。
サーバーが取りこぼした Google Play の返金はどうやって見つけますか?
Voided Purchases API を呼び出します。返金、取り消し、チャージバックを含む過去 30 日分の無効化された購入を、1 ページ最大 1,000 件、アプリごとに 1 日 6,000 クエリのクォータで返します。type 1 を渡すとサブスクリプションも含まれます。

出典と参考資料

RefundHalt

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

続きを読む

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

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