Apple が判断を下した後に 3 種類の App Store 返金通知が届き、REFUND_REVERSED は売上を返してくれる
Apple は App Store Server Notifications V2 を通じて 4 種類の返金メッセージを送りますが、ほとんどのアプリは 2 種類しか処理していません。REFUND は権利の取り消しを指示し、REFUND_DECLINED は売上をそのまま保持することを意味し、REFUND_REVERSED は売上を返したうえで、あなたが取り上げたものを復元するよう求めます。それぞれに何が必要かを説明します。

要点
- Apple は App Store Server Notifications V2 を通じて返金に関する 4 種類のメッセージを送ります。CONSUMPTION_REQUEST はあなたの証拠を求め、REFUND、REFUND_DECLINED、REFUND_REVERSED は Apple がすでに判断を下した後に結果を報告します。
- REFUND 通知は、App Store がその取引を返金したことを意味します。revocationDate と revocationReason を伴い、その 1 件の取引に紐づく権利を取り消す合図であって、その製品のすべての購入を取り消すものではありません。
- revocationReason には 2 つの値があります。1 はあなたの製品の問題により返金が認められたことを意味し、0 は別の理由で認められたことを意味します。値が 1 の場合は、記録して傾向を追う価値のある品質シグナルです。
- REFUND_DECLINED は、Apple が顧客の返金を却下したことを意味します。あなたは売上を保持し、何も変更しませんが、これが安全なのは、判断が最終になる前にアクセスを取り消していなかった場合に限られます。
- REFUND_REVERSED は、Apple が以前に認めた返金を取り消したことを意味し、通常は顧客がその返金に異議を申し立てた後に起こります。取引から取り消し用のフィールドが消え、Apple 自身の指示は、コンテンツを取り消していたなら復元する必要がある、というものです。
- 4 種類の通知すべてに HTTP 200 で応答してください。サーバーがダウンして 1 件取りこぼした場合でも、Get Refund History エンドポイントを使えば取引 id で返金済み取引を照会して突き合わせられます。
- 過去のサブスクリプション期間に対する返金が、必ずしもアクセスを終了すべきことを意味するわけではありません。より新しい有料期間がまだ有効なら、古い取引で取り消すと、支払いが継続中の顧客を締め出してしまいます。
Apple はあなたの返金について判断を下しても、それで話が終わるわけではありません。結果が確定すると、App Store はあなたのサーバーに 3 種類の App Store 返金通知のいずれかを送り、それぞれが異なる対応を求めます。REFUND はお金が失われたのでアクセスを引き上げるべきだと告げます。REFUND_DECLINED は顧客が申請に敗れたので売上を保持すると告げます。REFUND_REVERSED は Apple がすでに認めた返金を取り消したので、その売上は再びあなたのものになり、取り上げたものを何であれ返す必要があると告げます。ほとんどのアプリは最初の 1 つだけを組み込み、残りの 2 つを静かに無視します。こうして、支払いをした顧客が、支払ったはずのものから締め出されてしまうのです。
この 3 つは CONSUMPTION_REQUEST とは別物で、後者は返信を求める唯一の返金メッセージです。判断後の通知は議論を求めていません。求めているのは HTTP 200 と、顧客のアクセスに対する正しい変更です。以下では、それぞれの意味、事実を運ぶ正確なフィールド、そして誤って処理したときにお金がどこから漏れるかを説明します。
4 種類の返金通知と、返信を求めるのはどれか
App Store Server Notifications V2 は単一のフィードです。1 つの URL に向けるだけで、Apple はあらゆる通知タイプをそこへ送るので、処理するしないにかかわらず、あなたはすでに 4 種類の返金メッセージすべてを受け取っています。そのうち 4 つのタイプが返金に関わり、質問なのはそのうち 1 つだけです。
| 通知 | Apple が伝えていること | あなたの対応 | 返信の要否 |
|---|---|---|---|
| CONSUMPTION_REQUEST | 顧客が返金を申請し、Apple があなたのデータを求めている | 12 時間以内に Send Consumption Information | 要、実データ |
| REFUND | App Store がその取引を返金した | その取引の権利を取り消す | 不要、HTTP 200 |
| REFUND_DECLINED | App Store が返金を却下した | アクセスを保持し、何も変更しない | 不要、HTTP 200 |
| REFUND_REVERSED | Apple が認めた返金を取り消した | 取り消したコンテンツを復元する | 不要、HTTP 200 |
REFUND 通知が実際に伝えていること
REFUND は、App Store が顧客への取引の返金に成功したときに発火します。あらゆる購入タイプに適用されます。消耗型、非消耗型、自動更新サブスクリプション、そして非更新サブスクリプションです。通知内部の署名済み取引は、返金前には持っていなかった 2 つのフィールドを今や伴っており、その 2 つのフィールドがすべてを物語ります。
revocationDate と revocationReason が事実を運ぶ
revocationDate は、App Store がその取引を返金または取り消した UNIX 時間で、ミリ秒単位です。revocationReason は返金の分類を伝え、ちょうど 2 つの値を取ります。
| revocationReason | Apple の意味 | そこから読み取るべきこと |
|---|---|---|
| 1 | 製品の問題により返金が認められた | 品質または配信のシグナル。記録し、傾向を追い、特定の製品や特定のビルドにパターンがないか探す |
| 0 | 別の理由で返金が認められた | 通常の返金。権利を取り消して先へ進む |
取引に revocationDate が存在すること自体が目印です。後で取引を取得して revocationDate があれば、通知の有無にかかわらず、その購入は返金済みです。理由も併せて読み、特定のリリースで押し寄せる値 1 の返金の波が、ノイズとして見過ごされないようにしてください。
製品単位ではなく取引単位で取り消す
ここでの落とし穴は取り消しすぎることです。1 件の REFUND が指すのは 1 件の取引です。その製品 id について顧客がこれまで行ったすべての購入を無効化せよ、とは言っていません。Apple 自身のガイダンスは、何かを断ち切る前に顧客がまだ保持しているアクセスを確認すること、というものです。権利は重なり合うからです。典型例はサブスクリプションです。返金は先月の更新に対して発生し、今月の更新は有効で全額支払い済み、という状況です。製品単位で取り消せば、すでに終わった期間に対する返金のために、支払いを継続中の顧客を締め出してしまいます。
REFUND_DECLINED はすでに勝っている合図なので、覆さないこと
REFUND_DECLINED は、App Store が顧客の返金申請を却下したときに届きます。顧客が申請し、Apple がノーと言い、あなたは売上を保持します。一見すると何もすることはなく、それが要点です。この通知が浮き彫りにする間違いは別のもので、アクセスを早すぎるタイミングで取り消すことです。
もしあなたのコードが、Apple が裁定する前に CONSUMPTION_REQUEST に反応して顧客のアクセスを引き上げてしまうと、REFUND_DECLINED はその判断が破綻する瞬間になります。Apple はあなたのお金を残し、あなたは返金を却下された顧客を締め出したのです。その顧客は今や使えない製品に支払い、サポートチケットを開き、そのことを覚えています。修正は機能ではなくルールです。REFUND で取り消し、申請では決して取り消さない。REFUND_DECLINED は、早すぎる取り消しが誤った判断だったことを Apple が確認しているにすぎません。
REFUND_REVERSED はあなたにお金を返してくれる通知
REFUND_REVERSED はほとんど誰も処理しないものであり、あなたにお金を返すものです。Apple は、以前に認めた返金を取り消すときにこれを送り、通常は顧客がその返金に異議を申し立てた後です。REFUND が取引に追加した取り消し用のフィールドが再び削除され、その購入は再び支払い済みとして読み取れます。Apple は開発者の仕事を一行で示しています。関連する返金の結果としてアプリがコンテンツやサービスを取り消していたなら、復元する必要がある、というものです。消耗型から自動更新サブスクリプションまで、あらゆる購入タイプに適用されます。
数週間後に起こる問題
開発者が Apple 自身のフォーラムで挙げる本当の疑問はタイミングです。REFUND_REVERSED は、最初の REFUND から数週間後、サブスクリプション期間が失効してからずっと経ってから届くことがあります。そのときアクセスを復元するのか、という点です。その取引が実際に付与するものを、その取引が対象とする範囲に限定して復元してください。消耗型または非消耗型なら、ロック解除を再びオンにします。すでに経過したサブスクリプション期間については、新しい時間を配っているのではなく、記録を訂正して顧客の履歴を正確にし、まだ有効な権利を再び有効化しているのです。その特定の取引を復元すれば、あなたの重複ロジックが今どれが有効かを判断します。

これを正しく行うことのお金の在りか
これらの通知の一つひとつは実際の数字に対応しており、誤って処理したときの代償は販売価格だけではありません。
REFUND:返金済みの顧客にサービスを提供し続けるコストを止める
REFUND が届いた瞬間に販売価格は失われます。それでも制御できるのは、提供を続けるコストです。返金済みの権利が生きたままである時間が 1 時間増えるごとに、顧客がもう支払っていないもの、すなわちコンピュート、モデルの API 呼び出し、ストレージ、そして利用に紐づくクリエイターやパートナーへの支払いに、あなたはお金を使い続けます。REFUND で速やかに取り消せば、そのメーターが止まります。この通知を無視するのは、ストアがすでに埋め合わせをした相手のために製品を出資することを意味します。
REFUND_DECLINED:勝利を、善意の返金に変えないこと
早すぎるタイミングで取り消し、その後に返金が却下されると、帳簿上は売上を保持しつつ、実際には失っています。支払った顧客は製品を使えず、あなたはサポートのやり取りを引き受け、しばしば穴埋めのための任意の返金まで抱えます。これは、そもそも危うくなかった 1 件の売上に二度支払うことです。REFUND_DECLINED を正しく扱うのに費用はかからず、だからこそ REFUND まではアクセスに手を付けないことが、採用できる最も安いルールなのです。
REFUND_REVERSED:最悪の組み合わせは、お金とアクセスの両方が失われること
REFUND_REVERSED を無視すれば、あり得るなかで最悪の結末に至ります。あなたは支払いを受けているのに、顧客は何も持っていません。彼らは返金を取り消すためにすでに一度銀行に連絡しており、今や課金される製品から締め出された人は、二度目に銀行へ連絡する可能性が高いのです。その次の異議はカードのチャージバックになり得ます。それは銀行の最終決定であり、その売上がかつてもたらした以上の費用がかかります。REFUND_REVERSED が届いた瞬間にアクセスを復元することは、返金フロー全体で最も安い保険です。
何を組み込むか
モデルさえ正しければ、処理は小さなものです。権利を取引 id でキー付けし、あらゆる通知が 1 件の購入を指すようにします。CONSUMPTION_REQUEST では 12 時間以内にデータを送ります。REFUND ではその取引を取り消します。REFUND_DECLINED では何もしません。REFUND_REVERSED では復元します。いずれにも素早く HTTP 200 を返し、アクセスの変更は自分の時間で行います。
通知が残す隙間には、Get Refund History エンドポイントを使ってください。障害でサーバーがダウンして REFUND を取りこぼした場合は、取引 id に対して App Store Server API の返金照会を /inApps/v2/refund/lookup/{transactionId} で呼び出し、revocationDate と revocationReason を伴う署名済み取引を読み戻します。1 件ずつ取引を突き合わせ、顧客の返金済み購入をページ送りするので、取りこぼした webhook が、永久に誤設定された権利になることはありません。
これこそ RefundHalt があなたのために動かす部分です。4 種類すべてを待ち受け、REFUND で取り消し、REFUND_DECLINED ではアクセスに手を付けず、REFUND_REVERSED では自動で復元し、そのいずれも正確な取引にキー付けされています。取り消された返金が、支払い中の顧客を締め出したままキューで待たされることはなく、却下された返金が、あとで巻き戻すことになる取り消しを引き起こすこともありません。
よくある質問
- REFUND と REFUND_REVERSED の違いは何ですか?
- REFUND は App Store が取引を返金したことを意味し、その権利を取り消すべきです。一方 REFUND_REVERSED は Apple が認めた返金を取り消したことを意味し、取り消したコンテンツを復元すべきです。この 2 つは対になっています。購入はまず REFUND に進み、その後、顧客の異議が覆れば REFUND_REVERSED に進み得ます。アクセスの変更を取引 id でキー付けし、各通知が正しい購入に作用するようにしてください。
- REFUND 通知に対して何かを送り返す必要はありますか?
- いいえ。REFUND、REFUND_DECLINED、REFUND_REVERSED には、本文のない HTTP 200 で応答します。データの送信を求めるのは CONSUMPTION_REQUEST だけで、それは 12 時間以内に Send Consumption Information エンドポイントを通じて行います。ほかの 3 つは、Apple が判断を報告しているのであって、質問しているのではありません。
- REFUND_DECLINED 通知を受け取ったら何をすべきですか?
- 何も変えません。顧客の返金は却下され、あなたは売上を保持するからです。REFUND_DECLINED が作業を生む唯一のケースは、Apple が裁定する前にアクセスを早すぎるタイミングで取り消していた場合です。CONSUMPTION_REQUEST ではなく REFUND で取り消せば、REFUND_DECLINED はアクセスが正しくそのまま残されていたことの確認になります。
- REFUND_REVERSED が返金の数週間後に届いたとき、アクセスを復元すべきですか?
- はい、その特定の取引が付与する権利を復元してください。Apple は、関連する返金のためにアプリがコンテンツを取り消していたなら復元する必要がある、と述べています。消耗型または非消耗型なら、ロック解除を再びオンにします。すでに失効したサブスクリプション期間については、新しい時間を付与するのではなく記録を訂正しているので、今どれが有効かは引き続きあなたの重複ロジックが判断します。
- サーバーが取りこぼした返金通知をどうやって拾えばよいですか?
- App Store Server API の Get Refund History エンドポイントを使ってください。これは /inApps/v2/refund/lookup/{transactionId} で、取引 id により顧客の返金済み取引を照会します。revocationDate と revocationReason を伴う署名済み取引を返すので、障害の後でも、すでに発火した通知を待たずにアクセスを突き合わせられます。1 回の呼び出しで 1 つの取引 id を扱い、その顧客の返金済み購入をページ送りします。
出典と参考資料
RefundHalt
App Store と Google Play の返金を自動処理
続きを読む
Apple の返金リクエストにはすべて理由が付くようになり、consumptionRequestReason がそれを読み取る手段です
WWDC24 以降、すべての Apple CONSUMPTION_REQUEST は consumptionRequestReason、つまり顧客自身が述べた返金希望の理由を含んでいます。値は UNINTENDED_PURCHASE から LEGAL まで五つあり、それぞれが 12 時間の対応枠の中で返すべき内容を変えるはずです。ここではその一つひとつの読み方を説明します。
Google Play のチャージバック審査はあなたに 24 時間の反撃機会を与える。何を送るべきかを解説
銀行が Google Play の請求を取り消すと、Google はあなたのサーバーに PendingRefundReviewNotification を送り、24 時間のカウントダウンを始めます。ReviewRefund API を通じて返金の希望と実際の消費の証拠で応答しなければ、この紛争はあなた抜きで決着します。ここでは、その流れ全体をフィールドごとに解説します。