技術系TIPS
PR

【Google】購入したアイテムの払い戻し(返金)の実行や確認

saratogax
記事内に商品プロモーションを含む場合があります

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

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

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

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

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

あわせて読みたい
【Google】アプリ内課金の導入と運用方法
【Google】アプリ内課金の導入と運用方法

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

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

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

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

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

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

Voided Purchases API – Google Play Developer API

2023 年 11 月に都度課金のアイテムについても、デベロッパー通知で通知されるようになりました。

詳細は下記の記事をご覧ください。

あわせて読みたい
【Google】無効(返金やチャージバック)となった購入の情報をリアルタイムに通知で取得する
【Google】無効(返金やチャージバック)となった購入の情報をリアルタイムに通知で取得する

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】定期購入のリアルタイムデベロッパー通知の種類とハンドリング

APIのレスポンス

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

{
    "voidedPurchases": [
        {
            "purchaseToken": "xxxxxxxxxx",
            "purchaseTimeMillis": "1629269273686",
            "voidedTimeMillis": "1629381456002",
            "orderId": "XXX.9999-9999-9999-99999",
            "voidedSource": 0,
            "voidedReason": 4,
            "kind": "androidpublisher#voidedPurchase"
        },
        ...
    ]
}

デフォルトでは最大 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 の詳細な仕様は以下を参考にしてください。

レスポンスにあるページングの項目が、リファレンスだと少し異なるようですね。動きを見ると、tokenPagination しか返ってこないので、リクエストパラメータとページングのレスポンスについては、冒頭で紹介した「Voided Purchases API」のページを参考にした方が良さそうです。

まとめ

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

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

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

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

ABOUT ME
saratoga
saratoga
フリーランスエンジニア
仕事にも趣味にも IT を駆使するフリーランスエンジニア。技術的な TIPS や日々の生活の中で深堀りしてみたくなったことを備忘録として残していきます。
記事URLをコピーしました