アプリ内課金

【Googleアプリ内課金】返金対象など無効になった購入を特定する

実店舗でもネットショッピングでも、決済が発生すれば返金対応に追われる可能性があります。

それは、iPhone や Android のアプリ内課金も例外ではありません。

課金によってポイントを付与したのに、いつの間にかユーザとプラットフォーム側(Apple, Google など)の間で返金手続きがされているケースも。

iOS の場合は「REFUND」の返金通知が対応されているのですぐに検知することができますが、Android の場合はどうでしょうか。

今回は Google のアプリ内課金の返金(無効)になった決済について紹介していきます。

【2021年版】Googleアプリ内課金の導入と運用方法(GooglePlayBilling)2020 年の 10 月から 11 月にかけて、Google Play Billing の公式ドキュメントページが大幅に更新されました。...

ユーザが取り消した購入の注文リスト

結論から言うと、2021 年 9 月現在、Google で購入が無効になった情報は通知されません。

具体的には都度課金の場合で、サブスクの場合は「SUBSCRIPTION_REVOKED」のデベロッパー通知を受け取ることで判断が可能となっています。

では、どうすれば都度課金も無効な購入情報が入手できるのでしょうか。

その答えは、GooglePlay に用意されている Voided Purchases API になります。

Google Play Voided Purchases API からは、ユーザーが取り消した購入に関連付けられている注文のリストが提供されます。このリストの情報を基に、ユーザーがそれらの注文から商品にアクセスできないようにする取り消しシステムを実装できます。

Voided Purchases API – Google Play Developer API

Voided Purchases API

この API では、都度課金とサブスク両方の購入取消リストを取得することができます。

よくあるのは以下の理由でのキャンセルですね。

・ユーザが注文をキャンセルする
・デベロッパーが注文のキャンセルまたは払い戻しを行う
・Google が注文のキャンセルまたは払い戻しを行う

デベロッパー(アプリ開発側)や Google がキャンセルすることは稀ですが、ユーザのキャンセルは日々発生しています。

システムの問題で決済の不整合が生じるケースもあるかもしれませんが、ユーザからの一方的な払い戻し要求も多い認識です。

・通信状況が悪く間違って再購入してしまった
・課金して得られたものが期待外れだった
・課金しすぎてしまった

理由は様々ですが、ユーザまたはデベロッパーのどちらかが不利益を被る状態になるのは避けたいところですね。

APIの仕様

では、Voided Purchases API の仕様です。

[GET]
https://www.googleapis.com/androidpublisher/v3/applications/{{your_package_name}}/purchases/voidedpurchases?access_token={{your_auth_token}}

your_package_name の部分にはアプリのパッケージ名を、your_auth_token にはアクセストークンを設定します。
(アクセストークンはリクエストヘッダの Authorization に Bearer で埋め込む方がいいでしょうか)

リクエストには以下のパラメータを指定することもできますが、取り消しの情報は過去 30 日分までしか取得できないので注意が必要です。

・startTime
・endTime
・maxResults
・token
・type

この中で気を付けておきたいのが「type」ですね。

サブスクは 1 つの purchaseToken に複数の orderId が紐付くので、この両方の値で購入データを特定できるようにしておく必要があります。

サブスクはリアルタイムデベロッパー通知で判断できるので、この API では都度課金のみのリストを取得するという方法もアリかもしれません。
(デフォルトは type = 0 で都度課金のみのデータとなります)

【Googleサブスク】リアルタイムデベロッパー通知の種類とハンドリング「Google(Androidサブスク)のレシート検証について」で書いたように、Google Play Billing のサブスクリプシ...

APIのレスポンス

実際に、Voided Purchases API を叩いてみたら、以下のレスポンスが返ってきました。
(一部省略します)

デフォルトでは最大 1000 件のデータが返されますが、それ以上のデータが存在する場合は pageInfo や tokenPagination を頼りに残りのデータを取得するために API を何度か実行する必要があります。
(ページ情報がない場合は pageInfo や tokenPagination はレスポンスされません)

また、参考データとして voidedSource と voidedReason は保持しておきたいですね。

voidedSource

0: User
1: Developer
2: Google

voidedReason

0: Other
1: Remorse
2: Not_received
3: Defective
4: Accidental_purchase
5: Fraud
6: Friendly_fraud
7: Chargeback

API の詳細な仕様は以下を参考にしてください。

まとめ

Google のアプリ内課金における返金(無効)データについて紹介してきました。

・Voided Purchases API を活用する
・無効な購入情報を保存しておく
・取り消された理由を分析する
・運営側、ユーザ側がストレスのないサービス提供に繋げる

スムーズな決済処理を提供したつもりでも、何かの都合で決済取消が生じてしまうケースはあります。

どちらかが不利益を被るのは良くないので、なるべく迅速に誠実に対応を心掛けていきたいですね。