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

顧客のレシートにある App Store の注文 ID を見れば、何を買ったのか、Apple がすでに返金したのかがわかる

Apple の Look Up Order ID エンドポイントは、顧客の App Store レシートにある注文 ID を、返金日と返金理由を含む署名付きトランザクションに変換します。返金メールへの使い方、できないこと、Google Play の注文 ID との違いを解説します。

受信トレイを表示したノートパソコンと購入レシートを表示した iPhone が置かれたサポートデスク。App Store の注文 ID から返金対応が始まる

要点

  • Apple は顧客がアプリ内課金をするたびに注文 ID 付きのメールレシートを送り、顧客は App Store の購入履歴でも注文 ID を確認できる。
  • Apple の App Store Server API のエンドポイント Look Up Order ID(GET /inApps/v1/lookup/{orderId})は、有効な注文 ID に対して 1 件以上の署名付きトランザクションを返すため、サポートは推測せずに productId と purchaseDate を確認できる。
  • デコードした App Store のトランザクションには revocationDate と revocationReason が含まれるため、注文 ID を調べれば Apple がすでに返金したかどうかがわかる。理由 1 は、アプリ内の実際の、または認識された問題を理由に Apple が返金したことを意味する。
  • 注文 ID が自分のアプリで無効な場合、Look Up Order ID は OrderLookupStatus 1 を返し、signedTransactions 配列を含まない。これはレシートの誤りか、別のアプリの購入であることを示す。
  • Look Up Order ID は Apple のサンドボックス環境では利用できず、本番環境のレート制限はアプリごとに毎秒 10 リクエストで、1 時間単位で適用される。
  • 開発者は App Store の返金を行えない。返金は reportaproblem.apple.com で Apple が判断し、開発者が証拠を出せる唯一の場面は 12 時間以内に CONSUMPTION_REQUEST へ応答することだ。
  • Google Play は一回限りの購入ごと、定期購入の更新ごとに注文 ID 付きのメールを送り、開発者は Play Console でその注文 ID を検索して直接返金できる。Play Console は返金を取り消せないとしている。

iPhone の顧客から届いた返金メールに返信する前に、Apple のレシートにある App Store の注文 ID を送ってもらいましょう。その文字列を Apple の Look Up Order ID エンドポイントに渡せば、どの商品をいつ買ったのか、Apple がすでに返金したのかがわかります。注文 ID がなければ、スクリーンショットとメールアドレスをデータベースと突き合わせ、当たることを祈るしかありません。注文 ID があれば、相手が支払い中の顧客なのか、Apple がすでに返金した顧客なのか、別のアプリのレシートを持っている人なのかが数秒でわかります。

App Store の注文 ID はどこにあるのか

Apple のドキュメントは具体的です。顧客がアプリで 1 回以上のアプリ内課金をすると、App Store はメールでレシートを送り、そのレシートに注文 ID が記載されています。顧客は App Store の購入履歴でも注文 ID を確認できます。Apple の購入履歴ページは reportaproblem.apple.com と、App Store アプリの「App と購入履歴」にあり、初期表示は直近 90 日で、それより前の購入はフィルタで表示できます。

つまり、鍵はすでに顧客の手元にあります。サポートフォームで尋ねるだけです。

メールアドレスだけでは足りない理由

Apple は顧客の Apple アカウントのメールアドレスを開発者と共有しません。サポート窓口に届いたメールのアドレスは、支払ったアカウントとまったく無関係かもしれません。購入時に appAccountToken を設定していれば、トランザクションを自社のユーザー ID に結び付けられますが、それは開発者側からしかできません。注文 ID は顧客側から、ワンタップで転送できるレシートから届きます。

Look Up Order ID が返すもの

Look Up Order ID は App Store Server API の一部で、バージョン 1.1.0 から利用できます。署名済みの JWT を付けて GET https://api.storekit.apple.com/inApps/v1/lookup/{orderId} を呼び出します。Apple によると、レスポンスは顧客がアプリをインストール、削除、再インストールしたかどうかに関係なく、顧客のアプリ内課金の履歴に基づきます。

フィールドまたは挙動Apple のドキュメントの記載サポートでの使い方
OrderLookupStatus 0有効な注文 ID。レスポンスには 1 件以上の署名付きトランザクションの配列が含まれる1 件ずつデコードして購入内容を確認する
OrderLookupStatus 1レスポンスに signedTransactions 配列が含まれないその注文 ID は自分のアプリでは無効と判断する。正しいレシートを依頼する
productId と purchaseDateApple がカスタマーサポートに使うフィールドとして挙げている何をいつ購入したかを確認する
revocationDateApp Store がトランザクションを返金した、またはファミリー共有から取り消した日時値があれば、Apple はすでに顧客に返金している
revocationReason0:誤購入などその他の理由による返金。1:アプリ内の実際の、または認識された問題による返金1 はサポートチケットではなくプロダクトのシグナル
appAccountToken購入時に設定した UUID(設定している場合)注文を自社のユーザー記録と照合する
price と currencyApple は収益の照合に使わないよう明記している金額は App Store Connect のレポートを使う
サンドボックスこのエンドポイントはサンドボックス環境では利用できない本番環境の注文 ID でのみテストする
レート制限アプリごとに毎秒 10 リクエスト、1 時間単位で適用。超過すると Retry-After ヘッダー付きの HTTP 429サポート窓口には十分。一括スキャンには向かない

自分のアプリの有効なレシートか?

OrderLookupStatus が最初に答えるのがこの問いです。1 は、その注文 ID が自分のアプリの購入に該当しなかったことを意味します。よくあるのは入力ミス、別のアプリのレシート、そもそも App Store のものではないレシートです。1 のときは、返金も、クレジットの付与も、復元も一切しないでください。顧客にレシートをもう一度確認してもらいましょう。

Apple はこの購入をすでに返金したか?

デコードした各トランザクションの revocationDate を確認します。値があれば、Apple はすでにその購入を返金したか、ファミリー共有から取り消しており、顧客はお金を受け取っています。同じトランザクションについて App Store Server Notifications から REFUND が届いているはずなので、サーバーが実際にアクセスを取り消したかを安く確かめる方法にもなります。

印刷した App Store のレシートとノートパソコンのトランザクション行を見比べ、返金依頼に返信する前に App Store の注文 ID を確認する開発者

App Store で注文 ID にできないこと

注文 ID で返金はできません。開発者には App Store の返金ボタンがありません。返金を判断するのは Apple で、Apple のサポート記事は顧客を reportaproblem.apple.com に案内します。顧客はそこで「I'd like to」、次に「Request a refund」を選び、理由を選んで、該当する項目を選択します。Apple はまた、保留中の請求は顧客がメールのレシートを受け取るまで返金を申請できないとしています。

開発者が意見を言える唯一の場は Apple の CONSUMPTION_REQUEST です。顧客が Apple に返金を申請すると、Apple がこの通知を送ることがあり、開発者は 12 時間以内に Send Consumption Information で応答します。注文 ID の照会はサポート用のツールで、この期限を開くことも延ばすこともありません。

照会を省いた返金メールのコスト

注文 ID を見ないサポートは、お金が静かに漏れる場所です。よくあるパターンは 3 つあります。

  • 返金に上乗せされる好意。Apple が返金し、顧客がさらに開発者にもメールを送り、サポートが無料クレジットや 1 か月分を付与してしまう。付与したクレジットはすべて、開発者が支払う計算資源、API 呼び出し、ストレージで動きます。しかも相手はすでに返金を受けたアカウントです。
  • 取り消されないままのアクセス。REFUND の処理が失敗していると、返金済みの顧客が使用量を生み続けます。照会結果に revocationDate があるのにデータベースではまだ有効なら、それは値札の付いたバグ報告です。
  • アカウント違いの対応。注文 ID が別人のものなのに、転送されたメールのアカウントを復元したりクレジットを付与したりすると、購入していない人に有料サービスを提供することになります。

どれも紛争や期限がなくても損失を生みます。事実を確認しないまま返したサポートの回答にすぎません。チケットごとに API を 1 回呼べば、推測は不要になります。

revocationReason が 1 なら、自分が何か間違えたということ?

必ずしもそうではありません。Apple によると、理由 1 はアプリ内の実際の、または認識された問題を理由に返金したことを意味します。「認識された」という言葉の意味は大きいのです。それでも、あるリリースの後に特定の商品で理由 1 の返金がまとまって発生したなら、それは Apple がくれる最も明確なプロダクトのフィードバックです。数えておきましょう。

Google Play の注文 ID との違い

Google Play は逆の仕組みです。Google の課金ドキュメントによると、ユーザーは一回限りのアイテムの購入ごと、定期購入の初回購入時、そして定期的な自動更新ごとに、固有の注文 ID が記載されたメールを受け取ります。開発者はその注文 ID を使って Play Console で返金を管理できます。注文管理で注文 ID またはユーザーの完全なメールアドレスで検索し、自分で返金します。

質問App Store の注文 IDGoogle Play の注文 ID
顧客がどこで見つけるかメールのレシートと App Store の購入履歴購入ごと、更新ごとのメールのレシート
どう調べるかApp Store Server API の Look Up Order IDPlay Console の注文管理で検索
そこから返金できるかできない。Apple が判断するできる。全額返金、アプリ内アイテムと定期購入は一部返金も可能
返金の証拠提出期限CONSUMPTION_REQUEST、12 時間、Apple が判断するorders.reviewrefund によるチャージバック審査、24 時間
返金は取り消せるか開発者には取り消せないできない。Play Console は返金を取り消せないとしている

Google Play では、ボタンを押すのが開発者自身なので、注文 ID がさらに重要になります。Play Console によると、最新の定期購入の注文を返金すると定期購入はただちに削除され、今後の更新もキャンセルされます。一方、それより前の注文の返金は返金のみで、定期購入は有効なままです。一部返金は 2018 年 3 月以降の注文のみが対象で、有料アプリは一部返金できません。

返金サポートの流れの最初に注文 ID を置く

  • サポートフォームで注文 ID を尋ね、「Apple または Google Play のレシートメールに記載されています」と 1 行のヒントを添える。
  • iOS では Look Up Order ID を呼び出し、すべてのトランザクションをデコードして、productId、purchaseDate、revocationDate、revocationReason を 1 つの画面でサポートに表示する。
  • OrderLookupStatus が 1 なら手を止め、正しいレシートを依頼する。何も付与しない。
  • revocationDate に値があれば、サーバーでアクセスがすでに取り消されていることを確認してチケットを閉じる。上乗せの好意はなし。
  • 値がなく、顧客が返金を求めているなら reportaproblem.apple.com を案内し、12 時間の期限に備えて CONSUMPTION_REQUEST のハンドラーを準備しておく。RefundHalt は、Apple が求める消費データでその要求に応答します。
  • Android では、返金する前に Play Console で正確な注文を見つけ、返金のみか、返金して取り消すかを意図して選ぶ。

よくある質問

開発者として App Store の注文 ID を調べるには?
署名済みの JWT を付けて App Store Server API のエンドポイント Look Up Order ID、つまり GET https://api.storekit.apple.com/inApps/v1/lookup/{orderId} を呼び出します。有効な注文 ID なら OrderLookupStatus 0 と 1 件以上の署名付きトランザクションが返り、デコードすれば productId、purchaseDate、返金の詳細を確認できます。このエンドポイントはサンドボックスでは利用できません。
顧客は App Store の注文 ID をどこで確認できますか?
アプリ内課金のたびに Apple が送るメールのレシートと、reportaproblem.apple.com または App Store アプリの「App と購入履歴」にある App Store の購入履歴です。購入履歴の初期表示は直近 90 日で、それより前の購入はフィルタで表示できます。
注文 ID を使って App Store の購入を返金できますか?
できません。開発者は App Store の返金を行えません。顧客が reportaproblem.apple.com で返金を申請すると、Apple が判断します。開発者ができるのは、Apple の CONSUMPTION_REQUEST に 12 時間以内に Send Consumption Information で応答することです。
Apple がすでに購入を返金したかどうかは、どうすればわかりますか?
注文 ID を照会し、デコードした各トランザクションの revocationDate を確認します。値があれば、Apple はその購入を返金したか、ファミリー共有から取り消しています。revocationReason の 0 は誤購入などその他の理由、1 はアプリ内の実際の、または認識された問題を意味します。
OrderLookupStatus 1 とはどういう意味ですか?
その注文 ID が自分のアプリでは無効で、レスポンスに signedTransactions 配列がないことを意味します。多くの場合、顧客が別のアプリのレシートを送った、ID を打ち間違えた、または App Store 以外のレシートを送ったケースです。何かを付与する前に、正しいレシートを依頼してください。

出典と参考資料

RefundHalt

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

続きを読む

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

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