37

ユーザーアカウント/ログインを必要とせず、ユーザーがサブスクリプションを購入できるアプリを作成しています。Google Play Developer APIを使用して、ユーザーが購入済み/アクティブなサブスクリプションを持っているかどうかを確認したいと思います。すべてのドキュメントから、次の手順を収集しました。

それらは正しいですか、そしてあなたはそれらの2つの質問に答えることができますか?

  1. GoogleAPIコンソールでサービスアカウントを作成します。
  2. 私に与えられた秘密鍵を保存します(このサンプルコードが示唆しているように、私のコード/デバイスには確かにありません)
  3. Java用のGoogleAPIクライアントライブラリを使用して、秘密鍵を使用してJWTを作成し、署名します(どのように?ドキュメントはこれを教えてくれますが、それはJavaコードではありません...どうすればよいですか?)
  4. アクセストークンリクエストを作成し、APIへのアクセスを取得します
  5. アプリケーションは、ユーザーがサブスクリプションを持っているかどうかを確認するために、APIにGETリクエストを送信できるようになりました。
  6. アクセストークンの有効期限が切れたら、手順3に戻ります。

また、私はWebサービスを持っていますが、WebサービスやWebサービスプログラミングについては何も知りません...おそらくここで使用する必要があることを知っているだけです。

編集:これらの手順は正しくありませんでした。正しい手順については、以下の私の答えを参照してください。ただし、これはサービスアカウントの使用にのみ適用されることに注意してください(ユーザーにAPIアクセスを明示的に許可する必要がないため)

4

7 に答える 7

44

結局のところ、私の手順は正しくありませんでした。これを理解するのに数週間かかりましたが、他のどこにも文書化されていないようです。どういたしまして:

  1. GoogleAPIコンソールでWebアプリケーションアカウントを作成します。任意のWebサイトを「リダイレクトURI」として配置します。あなたが実際にそれを使用しないので、それは問題ではありません。アカウントを作成すると、クライアントIDとクライアントシークレットを取得します。

  2. コンピュータのブラウザで、に移動しhttps://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=[YOUR REDIRECT URI]&client_id=[YOUR CLIENT ID]、プロンプトが表示されたらアクセスを許可します。

  3. アドレスバーを見てください。最初に入力したURIの最後に、更新トークンがあります。1/....次のステップでこの「コード」が必要になるようです。更新トークンが期限切れになることはありません。

  4. に移動して、この「コード」を「更新トークン」に変換しhttps://accounts.google.com/o/oauth2/token?client_id=[YOUR CLIENT ID]&client_secret=[YOUR CLIENT SECRET]&code=[CODE FROM PREVIOUS STEP]&grant_type=authorization_code&redirect_uri=[YOUR REDIRECT URI]ます。結果の値をプログラムに直接保存できます。明示的に取り消されない限り、有効期限が切れることはありません。(このステップは@BrianWhiteによって挿入されました-コメントを参照してください)POSTを使用していることを確認してください。(Gintasによって挿入されました)

  5. コードで、BasicNameValuePairs 、、、を使用してHttpPostリクエストをに送信https://accounts.google.com/o/oauth2/tokenします。例については、こちらをご覧ください。おそらくAsyncTaskを使用して、別のスレッドでこれを行う必要があります。これにより、JSONObjectが返されます。"grant_type","refresh_token""client_id",[YOUR CLIENT ID]"client_secret",[YOUR CLIENT SECRET]"refresh_token",[YOUR REFRESH TOKEN]

  6. 返されたJSONObjectからアクセストークンを取得します。例については、こちらをご覧ください。文字列「access_token」を取得する必要があります。アクセストークンは1時間で期限切れになります。

  7. コードで、HttpGetリクエストをに送信しますhttps://www.googleapis.com/androidpublisher/v1/applications/[YOUR APP'S PACKAGE NAME]/subscriptions/[THE ID OF YOUR PUBLISHED SUBSCRIPTION FROM YOUR ANDROID DEVELOPER CONSOLE]/purchases/[THE PURCHASE TOKEN THE USER RECEIVES UPON PURCHASING THE SUBSCRIPTION]?accesstoken="[THE ACCESS TOKEN FROM STEP 4]"。例については、こちらをご覧ください。

于 2012-09-25T20:40:19.657 に答える
24

.NETユーザー:この回答が誰かの悲しみを大幅に軽減することを願っています。

@Christophe Fondacciが2015年に述べたように、受け入れられたソリューションは数年前にうまく機能しました。

今では2017年 2020年とプロセスははるかに簡単で高速です。

私のユースケースは、アプリ内サブスクリプションを検証することです。ここで、モバイルアプリはサブスクリプション購入情報をRESTfulサーバーに送信し、RESTfulサーバーはGoogleに連絡してサブスクリプション購入を検証します。

戦略は、あなたに代わって機能するサービスアカウントを作成することです。

  1. Google Play Dev Consoleにサインインし、設定しているアプリをクリックします。

  2. [設定] ->[ APIアクセス]にアクセスします

  3. [サービスアカウント]で、[サービスアカウントの作成]ボタンをクリックします。

  4. 2017年1月の時点で、サービスアカウントの設定方法を示すダイアログが表示されます。ダイアログが表示され、GoogleAPIコンソールが表示されます。そこから、

    A)[サービスアカウントの作成]をクリックします

    B)意味のあるサービスアカウント名を作成します。Android Publisher Servicesにアクセスすることに興味があるので、「publisher」を選択しました。

C)役割については、何かを選択するだけです。これは後で変更できます。

D)「新しい秘密鍵の提供」を選択し、.Net実装の場合はP12を選択します。このファイルをなくさないでください!

  1. これで#4が完了し、新しいサービスアカウントが一覧表示されます。[アクセスを許可]をクリックして有効にします。

  2. 「権限の表示」へのリンクをタップします。ニーズとAPIに基づいて権限を変更する必要があります。

アプリ内購入を検証するには、[歯車]-> [権限の変更]にアクセスし、グローバルな[表示]および[注文の管理]権限を有効にします。

この時点で、Google側ですべてを構成しました。次に、サーバーをサーバーにセットアップします。.Netコンソールアプリを作成して実装をテストし、必要に応じてオフロードすることをお勧めします。

  1. NugetからAndroidパブリッシャークライアントライブラリを追加します[1]
    PM> Install-Package Google.Apis.AndroidPublisher.v3
  1. P12ファイルをプロジェクトルートに追加します

  2. 「ビルドアクション」が「コンテンツ」になり、「出力ディレクトリにコピー」が「新しい場合はコピー」になるように、P12プロパティを変更します。

  3. このようなものを実装して、アクセスをテストし、微調整します[1]

    using System.Threading.Tasks;
    using System.Security.Cryptography.X509Certificates;
    using Google.Apis.Services;
    using Google.Apis.Auth.OAuth2;
    using Google.Apis.AndroidPublisher.v3;
    ...
    public Task<SubscriptionPurchase> GetSubscriptionPurchase(string packageName, string productId, string purchaseToken)
    {
        var certificate = new X509Certificate2(
                        "{{your p12 file name}}",
                        "{{ your p12 secret }}",
                        X509KeyStorageFlags.Exportable
                    );
        var credentials = new ServiceAccountCredential(
                new ServiceAccountCredential.Initializer("{{ your service account email }}")
                {
                    Scopes = new[] { AndroidPublisherService.Scope.Androidpublisher }
                }.FromCertificate(certificate));
    
        var service = new AndroidPublisherService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credentials,
            ApplicationName = "my server app name",
        });
        return service.Purchases.Subscriptions.Get(packageName, productId, purchaseToken).ExecuteAsync();
    }

頑張ってください、これが誰かを助けることを願っています。

出典:

サーバー間アプリケーションでのOAuth2.0の使用

.Net Client Library for Google.Apis.AndroidPublisher.v3 [1]


1  2020年4月11日更新-Google.Apis.AndroidPublisher.v2EOLを実行し、Google.Apis.AndroidPublisher.v3を使用します。
于 2017-01-04T00:21:28.750 に答える
10

あなたが私のようで、 PHPでこれを実行したい場合、これを実行する手順は次のとおりです... Kalinaの回答のおかげで、それがどのように機能するかを理解するのに3日しかかかりませんでした:)。

ここに行きます:

  1. Google Developers Console https://console.developers.google.com/にアクセスして、 Webアプリを作成します。'developers.google.com/oauthplayground'を「リダイレクトURI」として配置します。手順2で使用します。アカウントを作成すると、クライアントIDとクライアントシークレットが取得されます。Google Play AndroidDeveloperAPIが追加されていることを確認してください。

  2. Googleoauth2プレイグラウンドhttps://developers.google.com/oauthplayground/にアクセスします。この素晴らしいツールは、今後数日間のあなたの親友です。次に、設定に移動します。[独自のOAuthクレデンシャルを使用する]が設定されていることを確認してください。その場合にのみ、以下のフォームにクライアントIDクライアントシークレットを入力できます。

  3. Google oauth2プレイグラウンドで、手順1に進みます。APIを選択して承認し、入力フィールドhttps://www.googleapis.com/auth/androidpublisherにスコープを入力します。リストにGooglePlayAndroid Developer APIが見つかりませんでした。しばらくすると、追加される可能性があります。AUTORIZEAPISを押します。次の認証を行います。

  4. Google oauth2プレイグラウンドで、ステップ2に進みます。トークンの認証コードを交換します。すべてがうまくいけば、/4で始まる認証コードが表示されます。うまくいかなかった場合は、右側のエラーメッセージを確認してください。ここで、「アクセストークンの更新」を押します。更新トークンをコピーします...それは/1で始まります...

  5. これで、いつでもアクセストークンを取得できます。方法は次のとおりです。

    $url ="https://accounts.google.com/o/oauth2/token";
    $fields = array(
       "client_id"=>"{your client id}",
       "client_secret"=>"{your client secret}",
       "refresh_token"=>"{your refresh token 1/.....}",
       "grant_type"=>"refresh_token"
    );
    
    $ch = curl_init($url);
    
    //set the url, number of POST vars, POST data
    curl_setopt($ch, CURLOPT_POST,count($fields));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    //execute post
    $lResponse_json = curl_exec($ch);
    
    //close connection
    curl_close($ch);
    

これで、アクセストークンができました...JSONは次のようになります。

"access_token" : "{the access token}",  "token_type" : "Bearer",  "expires_in" : 3600

最後に、あなたはグーグルに何かを尋ねる準備ができています!これを行う方法は次のとおりです。

$lAccessToken = "{The access token you got in}" ;
$lPackageNameStr = "{your apps package name com.something.something}";
$lURLStr =  "https://www.googleapis.com/androidpublisher/v1.1/applications/$lPackageNameStr/subscriptions/$pProductIdStr/purchases/$pReceiptStr";

$curl = curl_init($lURLStr);

curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
$curlheader[0] = "Authorization: Bearer " . $lAccessToken;
curl_setopt($curl, CURLOPT_HTTPHEADER, $curlheader);

$json_response = curl_exec($curl);
curl_close($curl);

$responseObj = json_decode($json_response,true);

返されるJSONには、サブスクリプションが有効なときの、 initiationTimestampMsecvalidUntilTimestampMsecの2つのタイムスタンプが含まれます。どちらも1970年1月1日の日付に追加するミリ秒の数です。

于 2014-02-10T13:03:57.543 に答える
6

2012年にはわかりませんが、2015年には、これらの手順を手動で実行しないでください。ドキュメントを見つけるのに非常に苦労したので、誰かに役立つ場合に備えてここに投稿します。

  1. セキュリティ上の理由から、サーバーからのアプリ内購入のみをクエリする必要があります。そうしないと、購入プロセスの両端を信頼できなくなります。

サーバー側で(どうしても必要な場合は、アプリから同じコードを使用できると思います)、google-api-services-androidpublisherプロジェクトにクライアントライブラリを含めます(https://developers.google.com/api-client-library/を参照)。 java / apis / androidpublisher / v1

前述のように、P12ファイルを含むサービスアカウントが必要です(クライアントライブラリはP12ファイルのみを受け入れます)。

次に、次のコードが認証され、購入情報を適切に取得します。

    HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = new JacksonFactory();

    List<String> scopes = new ArrayList<String>();
    scopes.add(AndroidPublisherScopes.ANDROIDPUBLISHER);

    Credential credential = new GoogleCredential.Builder().setTransport(httpTransport).setJsonFactory(jsonFactory)
            .setServiceAccountId(googleServiceAccountId)
            .setServiceAccountPrivateKeyFromP12File(new File(googleServicePrivateKeyPath))
            .setServiceAccountScopes(scopes).build();
    AndroidPublisher publisher = new AndroidPublisher.Builder(httpTransport, jsonFactory, credential).build();
    AndroidPublisher.Purchases purchases = publisher.purchases();
    final Get request = purchases.get(packageName, productId, token);
    final SubscriptionPurchase purchase = request.execute();

    // Do whatever you want with the purchase bean

Javaクライアント認証に関する情報は、 https ://developers.google.com/identity/protocols/OAuth2ServiceAccountにあります。

于 2015-11-13T00:10:53.347 に答える
2

あなたの質問を誤解するかもしれませんが、Androidアプリのアプリ内課金を機能させるために参照しているリンクを使用している理由はわかりません。このページはもっと役に立ちます:

http://developer.android.com/guide/google/play/billing/index.html

含まれているデモアプリケーションを試すことができます(ダンジョン-http://developer.android.com/guide/google/play/billing/billing_integrate.html#billing-download)。サブスクリプションではなく製品(1回限りの購入)を使用しますが、必要なものをテストするために変更できるはずです。

重要なのは、サンプルで提供されているrestoreTransactionsメソッドで、GooglePlayアカウントにアプリのサブスクリプションがあるかどうかを確認することだと思います。

@Override
public void onRestoreTransactionsResponse(RestoreTransactions request, int responseCode) {
    if (responseCode == BillingVars.OK) {                        
        // Update the shared preferences so that we don't perform a RestoreTransactions again.
        // This is also where you could save any existing subscriptions/purchases the user may have.
        SharedPreferences prefs = getSharedPreferences(my_prefs_file, Context.MODE_PRIVATE);
        SharedPreferences.Editor edit = prefs.edit();
        edit.putBoolean(DB_INITIALIZED, true);
        edit.commit();
    } else {
        Log.e(TAG, "RestoreTransactions error: " + responseCode);
    }
}
于 2012-09-14T18:49:20.943 に答える
2

承認された投稿の最終ステップ(#7)で問題が発生している場合は、?access_token=代わりに機能することがわかりました?accessToken=

スタックオーバーフローがひどすぎると、スレッドに直接コメントを付けることができません...

于 2017-07-26T03:41:11.523 に答える
1

アプリが呼び出すことができるWebサービスがあるので、秘密鍵をサーバーに安全に保存することをお勧めします。アプリ内のものをできるだけ多くサービスコールに移動することを検討する必要があります。このリンクを参照してください。アプリ内サブスクリプションを実装しましたが、APIのこの部分がリリースされる前でした。私は自分で登録とセキュリティ検証を行う必要がありましたが、サブスクリプション要求/検証を保存する責任はまだあるようですが、このAPIはOAuthを使用してそのほとんどを実行しているようです。

既存のライブラリを使用してJWTに署名することについて説明している場合、Javaライブラリ、Pythonライブラリ、およびPHPライブラリへのリンクを提供しているように見えます。これは、Webサービスまたはサーバーコンポーネントが何で記述されているかによって異なります(私の場合はC#です。そのため、署名された購入を確認するためにRSACryptoServiceProvider)を使用しています。彼らは実際のデータ転送にJSONオブジェクトを使用しています。

于 2012-09-23T14:19:45.810 に答える