Правильно ли я делаю шаги для проверки подписки пользователя на Android в приложении?

Я делаю приложение, которое не требует учетной записи пользователя/логин, и позволяет пользователю приобрести подписку. Я хочу использовать API разработчика Google Play, чтобы проверить, имеет ли пользователь приобретенную/активную подписку. Из всей документации я собрал следующие шаги.

они правильные, а не могли бы вы ответить на два вопроса в них?

  1. создать Учетная Запись Службы в API Google Приставка.
  2. сохраните закрытый ключ, который мне предоставлен (где? конечно, не в моем коде/на устройстве, как этот пример кода напрашивается)
  3. использовать клиентская библиотека Google APIs для Java чтобы создать и подписать JWT с помощью закрытого ключа (как? доктора дают мне это, но это не Java-код... Что мне с ним делать?)
  4. создайте запрос маркера доступа и получите доступ к API
  5. приложение теперь может отправить GET запрос к API, чтобы узнать, является ли или нет пользователь имеет подписку
  6. по истечении срока действия маркера доступа вернитесь к шагу 3.

кроме того, у меня есть веб-служба, хотя я ничего не знаю о веб-службах или программировании веб-служб... Я знаю достаточно, чтобы знать, что, вероятно, необходимо использовать здесь.

EDIT: эти шаги были неправильными. См. мой ответ ниже для правильный шаг. Однако обратите внимание, что это относится только к использованию учетной записи службы (потому что я не хотел требовать от пользователя явного разрешения доступа к API)

7 ответов


как оказалось, мои шаги были неправильными. Мне потребовались недели, чтобы понять это, и это, похоже, нигде не документировано. Добро пожаловать:

  1. создать Веб-Приложения


пользователи .NET: Я надеюсь, что этот ответ избавит кого-то от тонны горя.

Как отметил @Christophe Fondacci в 2015 году, принятое решение отлично сработало несколько лет назад. Теперь это 2017 год, и процесс намного проще и быстрее.

мой вариант использования-проверить подписки в приложении, Где мое мобильное приложение отправляет информацию о покупке подписки на мой сервер RESTful, который, в свою очередь, связывается с Google для проверки подписки покупка.

стратегия заключается в создании учетной записи службы, которая будет работать от вашего имени.

  1. войдите в свой Google Play Dev Консоли и нажмите приложение, которое вы настраиваете.
  2. посетить настройки ->доступ к API
  3. под Учетные Записи Служб, ударил Создать Учетную Запись Службы.
  4. С января 2017 года диалог с указаниями по настройке появится учетная запись службы. Диалоговое окно приведет вас к консоли Google API; оттуда,

    A) Нажмите Кнопку Создать Учетную Запись Службы

    B) создайте имя учетной записи службы, которое имеет смысл. Поскольку мы заинтересованы в доступе к службам Android Publisher, я выбрал "publisher".

    C) для роли, просто выберите что - то-вы можете изменить это позже.

    D) выберите "предоставить новый закрытый ключ" и выберите P12 для .Net реализации. Не потеряйте этот файл!

5) Теперь вы закончили с #4, вы увидите свою новую учетную запись службы в списке; нажмите "предоставить доступ", чтобы включить его.

6) Нажмите на ссылку "Посмотреть разрешения". Вы должны изменить разрешения на основе ваших потребностей и API.

чтобы проверить покупки в приложении, посетите Cog - >изменить разрешения и включите глобальные разрешения "Visiblity" и "управление заказами".

OK на данный момент у вас есть настроил все на конце Google. Теперь, чтобы настроить сервер на серверный материал. Я рекомендую создать консольное приложение .Net для проверки вашей реализации, а затем выгрузить его, где это необходимо.

1) добавьте клиентскую библиотеку Android Publisher из Nuget

PM> Install-Package Google.Apis.AndroidPublisher.v2

2) добавьте файл P12 в корневой каталог проекта

3) Измените свойства P12, чтобы " действие сборки "было" содержимое "и" копировать в выходной каталог "на"копировать, если новее".

4) реализовать что-то подобное это для проверки вашего доступа и тонкой настройки.

using System.Threading.Tasks;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Services;
using Google.Apis.Auth.OAuth2;
using Google.Apis.AndroidPublisher.v2;
...
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();
}

удачи, надеюсь, это кому-то поможет.

источники:

использование OAuth 2.0 для серверных приложений

клиентская библиотека .Net для Google.Апис.AndroidPublisher.П2


Если вы похожи на меня, и хочу сделать это в PHP, вот процедура, как это сделать... Благодаря ответу Калины мне потребовалось всего три дня, чтобы понять, как это работает :).

вот:

  1. перейдите в консоль разработчиков googlehttps://console.developers.google.com/ и создать веб-приложение. Put 'developers.google.com/oauthplayground" как "перенаправить URI"; вы будете использовать его на Шаге 2. Вы получите клиента идентификатор и секрет клиента при создании счета. Убедитесь, что у вас есть Google Play Android разработчик API добавил.

  2. перейти на площадку Google oauth2 https://developers.google.com/oauthplayground/. Этот отличный инструмент - ваш лучший друг в течение следующих нескольких дней. Теперь перейдите в настройки: убедитесь, что используйте свои собственные учетные данные OAuth установлен. Только тогда вы можете заполнить свой идентификатор клиента и клиент секрет в форме ниже.

  3. на Google OAuth2 площадка переходите к шагу 1 выберите & авторизовать API заполните область в поле ввода https://www.googleapis.com/auth/androidpublisher. Я не смог найти Google Play Android Developer API в списке, возможно, они добавят некоторое время спустя. Хит АВТОРИЗАЦИЯ API. Сделать разрешение, что следует.

  4. на Google OAuth2 площадка переходите к Шагу 2 код авторизации Exchange для токенов. Если все прошло хорошо вы увидите код авторизации начиная с /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

наконец-то вы готовы спросить google что-то! Вот как это сделать:

$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 будет содержать две метки времени,initiationTimestampMsec и validUntilTimestampMsec время действия подписки. Оба номера millisecs, чтобы добавить к дате 1/1/1970!


я не знаю в 2012 году, но в 2015 году вы не должны делать ни одного из этих шагов вручную. Мне было очень трудно найти документацию, поэтому я размещаю здесь, если это кому-то поможет.

  1. вы должны запрашивать только покупки в приложении с вашего сервера по соображениям безопасности, поскольку в противном случае вы не можете доверять ни одному из 2 концов процесса покупки.

теперь на стороне сервера (я думаю, вы все еще можете использовать тот же код из вашего приложения, если вы абсолютно необходимо), включите 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


Я могу неправильно понять ваш вопрос, но я не вижу причин для вас использовать ссылки, на которые вы ссылаетесь, чтобы получить биллинг в приложении для работы приложения Android. Эта страница намного полезнее:

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

вы можете попробовать демо-приложение, которое они включают (подземелья -- http://developer.android.com/guide/google/play/billing/billing_integrate.html#billing-download) - ... Что использует продукты (одноразовые покупки), а не подписки, но вы должны иметь возможность изменять, чтобы проверить, что вы хотите.

Я думаю, что ключом для вас будет метод restoreTransactions, который они предоставляют в примере, чтобы узнать, есть ли у учетной записи Google Play подписки на ваше приложение:

@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);
    }
}

поскольку у вас есть веб-служба, которую может вызвать ваше приложение, я бы рекомендовал безопасно хранить ваш закрытый ключ на вашем сервере. Вы должны смотреть на перемещение как можно большего количества материалов в приложении для обслуживания вызовов, как это возможно, см. этой ссылке. Я реализовал подписку в приложении, но это было до того, как эта часть API вышла. Я должен был сделать свою собственную регистрацию и проверку безопасности, но похоже, что этот API делает большую часть этого для вас, используя OAuth, хотя похоже, что вы все еще ответственный за хранение запроса/проверки подписки.

где речь идет о подписании вашего JWT с существующей библиотекой, они, похоже, предоставляют вам ссылки на библиотеку java, библиотеку Python и библиотеку PHP - это зависит от того, что ваш веб-сервис или серверный компонент написан (мой C#, поэтому я использую RSACryptoServiceProvider) для проверки подписанных покупок. Они используют объекты JSON для фактической передачи данных.


Если у кого-то возникли проблемы с принятым заключительным шагом сообщений (#7), я нашел ?access_token= работать вместо ?accessToken=

слишком плохое переполнение стека не позволит мне сделать этот комментарий непосредственно к потоку...