web-dev-qa-db-ja.com

サーバー側でAndroidアプリの購入を確認する方法(アプリ課金v3でのGoogle Play)

シンプルなアプリがあります(アカウントでユーザーログインする必要があります)。有料ユーザー向けに、より多くのニュースコンテンツなど、いくつかのプレミアム機能を提供しています。

ユーザーがサーバーデータベースでこのアイテムを購入したかどうかを記録する必要があります。ユーザーのデバイスにデータコンテンツを提供する場合、ユーザーのステータスを確認し、有料ユーザーに異なるコンテンツを提供できます。

Googleが提供する公式のTrivialdriveサンプルを確認しましたが、サーバー側の検証用のサンプルコードは提供していません。ここに質問があります。

  1. サンプルでは、​​アプリの公開キーを使用して購入を確認していますが、見栄えはよくありません。ユーザーのログイン資格情報と組み合わせて確認プロセスをサーバーに移動して、ユーザーの購入が完了したかどうかを確認し、データベースを更新できると思います。
  2. また、 purchase API を使用してクエリを実行できます。ユーザーのpurchaseTokenをサーバーに渡す必要があります。

ユーザーの購入を確認し、データベースでユーザーのステータスをマークするためにどの方法を使用する必要があるのか​​わかりません。

そして、ユーザーがGoogle Playからこのアイテムを購入した場合、状況があるのではないかと心配していますが、何らかの理由で、ちょうどその時にアプリがサーバーへの検証を開始したとき、ネットワーク接続ダウンしている、または自分のサーバーがダウンしている、ユーザーはGoogle Playでお金を支払っただけですが、サーバーに購入を記録しませんでしたか?私は何をすべきか、どうすればこの状況に対処できますか。

76
virsir

探しているのは、ユーザーがアカウントでプレミアム機能を有効にしているかどうかを確認する方法だと思うので、ここから始めます。

ユーザーにプレミアム機能があるかどうかを示す何らかのフラグがデータベースにあることを確認し、アカウント情報をリクエストするときにAPI応答ペイロードにそれを含めます。このフラグは、「プレミアム機能」の主要な権限になります。

ユーザーがアプリ内購入を行う場合、詳細(トークン、注文ID、製品ID)をクライアント(アプリ)でローカルにキャッシュしてから、APIに送信します。

APIは、検証のためにpurchaseTokenGoogle Play Developer API に送信する必要があります。

ここからいくつかのことが起こります:

  1. 領収書は有効です。APIは200 Okステータスコードでクライアントに応答します
  2. 領収書が無効です。APIはクライアントに400 Bad Requestステータスコードで応答します
  3. Google Play APIがダウンしています。APIは502 Bad Gatewayステータスコードで応答します

1.または2.(2xxまたは4xxステータスコード)の場合、クライアントは購入の詳細のキャッシュをクリアします。これは、APIが受信したことをAPIが示しているため、購入の詳細が不要になったためです。

検証が成功したら(ケース1)、ユーザーのpremiumフラグをtrueに設定する必要があります。

3(5xxステータスコード)またはネットワークタイムアウトの場合、クライアントはAPIから2xxまたは4xxステータスコードを受信するまで試行を続ける必要があります。

要件に応じて、数秒待ってから再度送信するか、アプリが再度起動されるか、購入の詳細がアプリのキャッシュにある場合はバックグラウンドから外れたときに、APIに詳細を送信することができます。

このアプローチでは、ネットワークのタイムアウト、サーバーの使用不可などを処理する必要があります。

考慮する必要がある質問がいくつかあります。

購入後すぐに何が起こるべきですか?アプリは、プレミアムコンテンツを提供する前に検証が成功するまで待機する必要がありますか、それとも一時的にアクセスを許可し、検証が失敗した場合にそれを削除する必要がありますか?

プレミアム機能への暫定的なアクセスを許可すると、大多数のユーザーのプロセスがスムーズになりますが、APIがpurchaseTokenを検証する間、多数の不正ユーザーにもアクセスが許可されます。

別の言い方をすれば、購入は不正であると証明されるまで有効です。有効であると証明されるまで不正ですか?

サブスクリプション期間が更新されるときにユーザーがまだ有効なサブスクリプションを持っているかどうかを識別するために、purchaseTokenで再検証をスケジュールして、返されたexpiryTimeMillisで実行する必要があります。 結果

expiryTimeMillisが過去にある場合、premiumフラグをfalseに設定できます。将来の場合は、新しいexpiryTimeMillisに合わせて再度スケジュールを設定します。

最後に、ユーザーがプレミアムアクセス権を持っているかどうかを確認するために、アプリはAPIにアプリの起動時またはバックグラウンドから外れたときにユーザーの詳細を照会する必要があります。

126
Marc Greenstock

PHP用Google APIクライアントライブラリ の完全な使用例:

  1. Google Projectを設定し、Google PlayにアクセスしてサービスアカウントMarcの回答はこちら https://stackoverflow.com/a/35138885/1046909 .

  2. ライブラリをインストールします: https://developers.google.com/api-client-library/php/start/installation

  3. これで、次の方法で領収書を確認できます。

    $client = new \Google_Client();
    $client->setAuthConfig('/path/to/service/account/credentials.json');
    $client->addScope('https://www.googleapis.com/auth/androidpublisher');
    $service = new \Google_Service_AndroidPublisher($client);
    $purchase = $service->purchases_subscriptions->get($packageName, $productId, $token);
    

    その後、$ purchaseはGoogle_Service_AndroidPublisher_SubscriptionPurchaseのインスタンスです

    $purchase->getAutoRenewing();
    $purchase->getCancelReason();
    ...
    
14
MingalevME

Purchases.subscriptions:get サーバー側を使用して試すことができます。 packageName、subscriptionId、tokenをパラメーターとして受け取り、 authorization が必要です。

ユーザーのサブスクリプション購入が有効かどうかを確認し、有効期限を返します。

成功した場合、このメソッドは応答本文で Purchases.subscriptionsリソース を返します。

12
random

これに関するドキュメントは、実際には重要なドキュメントがほとんどリンクされておらず、見つけるのが非常に難しいままで、ほとんど取るに足らないものと混同し、奇妙に冗長です。これは、Java、Python、.Net、NodeJSなどのGoogle APIクライアントライブラリを実行できる最も一般的なサーバープラットフォームでうまく機能するはずです。注:以下に示すように、Python apiクライアントのみをテストしました。

必要な手順:

  1. Google PlayコンソールのAPIアクセスリンクからAPIプロジェクトを作成します

  2. 生成されるJSON秘密鍵を新しいサービスアカウントsaveに作成します。このファイルをサーバーに持って行く必要があります。

  3. Playコンソールの[サービスアカウント]セクションで[完了]を押して更新し、サービスアカウントへのアクセスを許可します

  4. https://developers.google.com/api-client-library から、サーバープラットフォーム用のGoogle APIクライアントライブラリを取得します

  5. 特定のプラットフォームのクライアントライブラリを使用して、サービスインターフェイスを構築し、購入確認の結果を直接読み取ります。

あなたは、not承認スコープに煩わされる必要はありません。カスタムリクエストの呼び出し、アクセストークンの更新などを行います。APIクライアントライブラリがすべてを処理します。サブスクリプションを確認するpythonライブラリの使用例を次に示します。

まず、次のように、pipenvにGoogle APIクライアントをインストールします。

$ pipenv install google-api-python-client

次に、サービスアカウントを認証するためにプライベートキーjsonファイルを使用して、APIクライアント資格情報を設定できます。

credentials = service_account.Credentials.from_service_account_file("service_account.json")

ライブラリを使用して、サブスクリプション購入または製品購入を直接確認できるようになりました。

#Build the "service" interface to the API you want
service = googleapiclient.discovery.build("androidpublisher", "v3", credentials=credentials)

#Use the token your API got from the app to verify the purchase
result = service.purchases().subscriptions().get(packageName="your.app.package.id", subscriptionId="sku.name", token="token-from-app").execute()
#result is a python object that looks like this ->
# {'kind': 'androidpublisher#subscriptionPurchase', 'startTimeMillis': '1534326259450', 'expiryTimeMillis': '1534328356187', 'autoRenewing': False, 'priceCurrencyCode': 'INR', 'priceAmountMicros': '70000000', 'countryCode': 'IN', 'developerPayload': '', 'cancelReason': 1, 'orderId': 'GPA.1234-4567-1234-1234..5', 'purchaseType': 0}

Play開発者APIのプラットフォームサービスインターフェースのドキュメントは、簡単に見つけることができる方法でリンクされていません。一部のユーザーは、見つけるのが難しい難しい私が見つけた人気のあるプラットフォームへのリンクは次のとおりです。

Python | Java | 。NET | PHP | NodeJS(Github TS) | Go(Github JSON)

8
Dhiraj Gupta