技術 約4分で読めます

Google Play課金のサーバー検証APIを使うためのサービスアカウント設定

前回の記事「Flutter WebView + Google Play 課金実装ガイド」でFlutter側の課金処理は動いた。次はサーバー側でレシートを検証したい。

不正購入を防ぐためには、クライアントから送られてきた購入トークンをGoogle Play Developer APIで検証する必要がある。

必要なもの

  • Google Cloud Console のサービスアカウント(JSON鍵ファイル)
  • Google Play Console でそのサービスアカウントへの権限付与

手順

1. Google Cloud Console でサービスアカウント作成

  1. Google Cloud Console を開く
  2. プロジェクトを作成(または既存を選択)
  3. APIとサービス → ライブラリ で「Google Play Android Developer API」を検索して有効化
  4. IAMと管理 → サービスアカウント → 作成
    • 名前は play-verification とか適当に
    • ロールは不要(Play Console側で権限付与するため)
  5. 作成したアカウントのタブ → 鍵を追加 → JSON
  6. ダウンロードされる .json ファイルを保存

重要: API有効化は必須。有効化前にJSON作っても使えない。

2. Play Console でサービスアカウントを招待

昔は Play Console に「APIアクセス」という専用メニューがあったが、現在は廃止されている。代わりに「ユーザーと権限」から設定する。

  1. Google Play Console を開く
  2. 左メニュー → ユーザーと権限
  3. 新しいユーザーを招待
  4. メールアドレス欄にサービスアカウントのメールアドレスを入力
    • 形式: xxxx@project-id.iam.gserviceaccount.com
    • JSON鍵ファイルの client_email に書いてある
  5. 権限を付与(両方必要):
    • 売上データの表示 ← 「Purchases API へのアクセス」が含まれる
    • 注文と定期購入の管理 ← 検証にも必要

3. サーバー側での使い方(PHP例)

// google/apiclient ライブラリを使う場合
$client = new Google_Client();
$client->setAuthConfig('/path/to/service-account.json');
$client->addScope('https://www.googleapis.com/auth/androidpublisher');

$service = new Google_Service_AndroidPublisher($client);
$purchase = $service->purchases_products->get(
    'com.your.package',  // パッケージ名
    'product_id',        // 商品ID
    'purchaseToken'      // Flutterから送られてきたトークン
);

// $purchase->purchaseState === 0 なら購入済み

ハマりポイント

「APIアクセス」メニューが見つからない

Play Console のUIが変わって「APIアクセス」は廃止された。「リンクされたサービス」でもない。「ユーザーと権限」からサービスアカウントを招待する形式に変わっている。

API有効化前にJSON作成した

同じプロジェクトで「Google Play Android Developer API」を有効化すれば、既存のJSONはそのまま使える。作り直し不要。

権限がわからない

以下の両方が必要:

  • 売上データの表示 ← 「Purchases API へのアクセス」が含まれる
  • 注文と定期購入の管理 ← これも検証に必要

権限反映に時間がかかる

これが一番厄介。Play Consoleで権限を変更したり、APIを有効化した後、実際にAPIが通るようになるまで最大24時間かかることがある

設定直後に401/403エラーが出ても、設定が合っていれば「Google側のキャッシュ更新待ち」の可能性が高い。数時間〜一晩寝かせると急に通ることがよくある。

エラーコードで判別:

  • 400 (Bad Request): 確実に設定ミス。リクエストの形式やパラメータが間違っている。待っても直らない。
  • 401 (Unauthorized): 厄介なやつ。設定ミスの可能性もあるが、設定が正しくてもCloud側への反映待ちで出ることがある。判別が難しい。
  • 403 (Forbidden): 認証は通っているが権限がない状態。設定が合っていれば「反映待ち」。これなら待つのが正解。
  • 404 (Not Found): パッケージ名のミス。本番とデバッグでパッケージ名を変えている場合に起きやすい。

401の罠: 一般的に「401は設定ミス」と言われるが、今回の検証で作りたてのサービスアカウントだと設定が正しくても401が出るケースを確認した。Play Consoleの権限反映(403が出がち)より前の段階で、Google Cloud側でのサービスアカウント作成やAPI有効化の情報が認証サーバーに行き渡っていない状態だったと思われる。設定を何度見直しても間違いがない場合は、数時間〜一晩待つと急に通ることがある。

テストに必要な追加設定

サービスアカウントとは別に、課金テストを行う実機のGoogleアカウントを「ライセンステスト」に登録する必要がある。

場所: Play Console → 設定 → ライセンステスト

ここに登録されていないと、テストカード(Succeed/Fail)が出ず、実際のクレジットカード決済画面になる。

また、アプリが「ドラフト」状態では課金テストできない。内部テスト(Internal Testing)やクローズドテストのトラックにAPK/AABをアップロードし、ステータスが「公開中」になっている必要がある。