Skip to main content

Android Subscription

Overview

AndroidのSubscription(定期購入)についてまとめているセクション。
Google Play の課金システムは、Android アプリでデジタル商品とデジタル コンテンツを販売するためのサービス。
1 回だけの購入で収益を上げることも、サービスを定期購入できるようにすることも可能。
Google Play では、Android アプリとサーバー バックエンドの両方と統合するための API 一式を用意しており、ユーザーは安全性が高く使い慣れた Google Play で購入できる。

サブスクリプションライフサイクル

サブスクリプションライフサイクル

PurchaseTokenとorderId違い

Google Play の課金では purchaseTokenorderId は役割が異なる2つの識別子である。

項目purchaseTokenorderId
役割購入状態を識別するためのトークン決済トランザクションの注文ID
主な用途サーバーAPIでサブスクリプション状態を取得する際のキー返金処理・サポート対応・会計処理
取得場所アプリの購入結果 (BillingClient)Google Play の注文履歴 / APIレスポンス
一意性1つの購入ライフサイクルに対して一意決済ごとに発行される
サブスク継続時基本的に変わらない更新ごとに suffix が増える

purchaseToken

purchaseTokenGoogle Play Developer API で購入状態を確認するためのキーであり、 サーバー側でサブスクリプションを識別する際の最も重要な識別子となる。

例:サブスクリプション状態取得API

GET /androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{purchaseToken}

サーバーでは通常この purchaseToken をデータベースに保存し、ユーザーのサブスクリプション状態を管理する。

orderId

orderIdGoogle Play の決済トランザクションIDであり、 Google Play Console やユーザーのレシートで表示される注文番号に相当する。

GPA.1234-5678-9012-34567

この ID は主に次の用途で利用される。

  • 返金処理
  • カスタマーサポート対応
  • 会計・売上管理

サブスクリプション更新時の挙動

サブスクリプションの場合、purchaseTokenorderId の挙動は次のように異なる。

例:月額サブスクリプション

初回購入
purchaseToken: token_A
orderId: GPA.1234-5678-9012-34567..0

1回目の自動更新
purchaseToken: token_A
orderId: GPA.1234-5678-9012-34567..1

2回目の自動更新
purchaseToken: token_A
orderId: GPA.1234-5678-9012-34567..2

このように

  • purchaseToken → サブスクリプション全体を識別するID
  • orderId → 各決済トランザクションを識別するID

という役割の違いがある。

実装上の推奨

バックエンドでは次のような設計が一般的。

subscriptions
purchase_token (unique)
user_id
product_id
payments
order_id
purchase_token
price
purchased_at

つまり

  • サブスクリプション管理 → purchaseToken
  • 決済履歴管理 → orderId

として扱うのが推奨される。

PurchaseTokenとorderIdの変更タイミング

  1. 説明: Google Play の自動更新購読では、自動更新をキャンセルして再購入すると新しい購入として扱われ、新しい purchaseToken と orderId が発行される。
  2. 明示: purchaseToken はサーバー API での状態確認のキーであり、ユニーク性が保証される。orderId は人間向け表示や返金処理で使われるが、複数回の再購入で異なる値が付与される。
  3. 注意: 自動更新が通常通り継続される場合、purchaseToken は変わらず、orderId も継続される(ただしプラットフォームの仕様によって部分的に異なる場合がある)。
  4. 補足: 開発者はユーザーの購読を識別する際、purchaseToken をキーとして扱い、orderId は補助的な用途(トランザクション参照など)に用いるのが推奨される。
  5. 例:
    • 初回購入 → purchaseToken_A, orderId_1
    • 自動更新継続 → purchaseToken_A のまま
    • キャンセル後に再購入 → purchaseToken_B, orderId_2(新規扱い)

Grace Period(猶予期間)

Account Hold(アカウントの一時停止)

Google Play サブスクリプション特有の状態であり、Grace Periodが終了した後に遷移するステータス。

  • ユーザーの定期購入が支払い失敗 → Grace Period 終了したあとに遷移するステータス。
  • この状態ではユーザーのアクセス権(entitlement)が一時的に無効化され、サービス利用が止まる。

新規購入

caution

3日以内に新規定期購入を承認しない場合、自動的にユーザーに払い戻しがされ、Google Play は購入を取り消す

アップグレード/ダウングレード

Google Playでは、ユーザーがサブスクリプションのプランを変更(アップグレード / ダウングレード)した場合、支払いの調整(按分)や残存期間の扱いがプラン変更の種類によって異なる。

即時アップグレード(Immediate Upgrade)

高価格のプランへ即座に移行する場合。

  • ユーザーは直ちに新しいプランの料金を支払う
  • 前のプランの未使用期間分はGoogleが自動で按分精算し、新しい課金額に充当する
  • 次の請求サイクルは、新しいプランの請求日に基づいてリセットされる
    • 1ヶ月プラン($10/月)に加入 → 15日後、1年プラン($100/年)にアップグレード
    • ユーザーは即座に$100を支払うが、未使用の$5($10/月の半分)が払い戻され、$95が請求される
tip

アップグレード(高額プランへ)は、即時適用 & 未使用分は按分されて新プランの料金に充当される
ユーザーが無駄な支払いを避けるなら「即時アップグレード」を選ぶのがベスト
ダウングレードはすぐに適用されないので、注意が必要

期限終了時のアップグレード・ダウングレード(When the current plan expires)

現在の請求期間が終了した後に、新しいプランに変更。

  • 現在のプランの期間が終了するまでは、新しいプランに移行しない
  • 新しいプランの料金は、次回の請求時に適用
  • 未使用の金額の払い戻しはなし
    • 1ヶ月プラン($10/月)に加入 → 満了後、1年プラン($100/年)へ変更
    • 既存のプランが終了するまでは変更なし、次の請求から$100の1年プランが適用される

ダウングレード(Downgrade to a lower plan)

低価格のプランに移行する場合。

  • 通常、現在の請求期間の終了時に新しいプランが適用される
  • 即時ダウングレードは行われず、按分調整もされない
  • 未使用の料金の払い戻しは行われない
    • 1年プラン($100/年)から1ヶ月プラン($10/月)に変更
    • 1年プランの有効期間が終了するまで変更されず、次の請求時に1ヶ月プランが適用⸻
note

なぜ即時ダウングレードがないのか?
これはユーザーが短期間だけ高額プランを使って、すぐに低額プランへ変更し、払い戻しを狙うという不正行為を防ぐため。
もし即時ダウングレードで按分計算があった場合、次のような悪用が考えられる。

悪用例。

  1. ユーザーが1年プラン($100)に加入
  2. 2日後に1ヶ月プラン($10)にダウングレード
  3. 残りの約 $99が払い戻される(← これができると不正に使われる可能性がある)
  4. 1ヶ月プランに変更後、またすぐに高額プランに切り替える

このような不正な支払い調整を防ぐため、Googleはダウングレードを次の請求サイクルで適用される仕様にしている。

了解です。 Android(Google Play Billing)で注文にメタデータを付けて識別したい、という意図ですね。以下に詳しく整理します。

🎯 Google Play課金における「注文識別」の基本

Google Playの購入には主に以下の情報が関連します:

項目 説明 purchaseToken 注文を一意に識別するトークン(重要) orderId GPA.〜形式の注文ID(人間向け、返金時に使用) productId 商品ID(SKU) packageName アプリのパッケージ名 developerPayload (旧)開発者が自由に設定できる文字列(非推奨)

✅ 現在利用可能な「メタデータ的手段」

  1. developerPayload(旧方式/非推奨)※過去のIn-app Billing v3などで使用 • 自由な文字列(JSONなど)を付与可能だった。 • 例:ユーザーIDやセッションIDを含める。 • 現在はセキュリティ上の理由で無効化/非推奨。

  2. 自前のDBに購入直前の情報を記録+purchaseToken連携(推奨)

フロー例:

  1. ユーザーが「購入する」ボタンを押す直前に、自前サーバーに 「ユーザーID」「商品ID」「意図したコンテキスト(例:どの画面から購入したか)」などのメタ情報 を記録。
  2. Google Play Billingで購入処理を行い、クライアントで purchaseToken を取得。
  3. サーバーへ purchaseToken を送信し、ステップ1の情報と紐付けて保存。
  4. 以後、注文関連処理はすべて purchaseToken ベースで処理。

補足: • サーバーで定期的に Google Play の API を使って purchaseToken の状態確認を行うことで、正確な購入状況も管理可能。 • メタデータを注文情報と紐付けたい場合は自前で管理するしかないというのがGoogleの設計です。

🔐 注意点 • purchaseToken は基本的に1注文に対して一意。 • orderId はリフレッシュ購入などで再利用されるケースがあるため、厳密な識別には不向きな場合もある。 • purchaseToken はサーバーで安全に保管すべき。

🛠 まとめ

やりたいこと 方法 購入に任意の情報を紐付けたい ✅ 自前サーバーに保存+purchaseTokenで紐付け 注文に直接メタデータを持たせたい ❌ できない(developerPayloadは非推奨) Google公式でのサポート手段 ✅ purchaseTokenを通じた管理、Verify Purchase API

Resource