简体   繁体   中英

Android verify IAP subscription server side with Ruby

I have been googling and searching and this is killing me. I am just trying to setup our RoR server to be able to query the google play purchases API to validate if a subscription has been renewed and I cannot seem to find an actual solution. I have been through all of the google documentation. It appears I need a service account as described here

https://developers.google.com/accounts/docs/OAuth2ServiceAccount

But then I found this python article on how they actually want us to use the web server application flow

http://milancermak.wordpress.com/2012/08/24/server-side-verification-of-google-play-subsc/

I don't really care at this point, I just need to get the server to successfully talk to the Google API to validate/renew subscriptions. I have found 0 articles on how this flow works. Has anyone gotten this working??

For anyone who stumbled on this, this was the craziest thing I have ever had to deal with but I managed to figure it out and do it right. I want to thank the following articles for helping me slowly but surely get to the bottom of this. I will add the most frustriating part of this is the steps I am going to list below, I am not 100% convinced they are all necessary because the only error I ever got during this was "403 Insufficient Permissions" so all I can really do here is tell you EVERYTHING I did and hope it works for you.

This article got everything working but was using the web access approach and stating that the service account wouldn't work

http://milancermak.wordpress.com/2012/08/24/server-side-verification-of-google-play-subsc/

This was a great implementation on the above article for Ruby

https://gist.github.com/cornflakesuperstar/5632813

This was a great article on how to get the key so that you could store it as an environment variable for Heroku

http://ar.zu.my/how-to-store-private-key-files-in-heroku/

This was a good article on how to setup the service account (note I am not the account owner of our services so I was flying blind on telling him how to do this. This article worked)

https://developers.google.com/console/help/#activatingapis

This was the article on how you need to authorize the auto generated email from above

How can I authorize with OAuth 2.0 for google's predictive API in Ruby?

The official Google Implementation for the API is here

https://developers.google.com/android-publisher/api-ref/purchases/subscriptions/get

After countless late nights since I posted this article I was able to get this working WITH A SERVICE ACCOUNT with the following steps

  1. I had our developer console admin generate me the service account information as described in the above developer article
  2. I had our admin add the email account and allow it permission as described in the above stack overflow article
  3. I followed the article on how to make the key a string that could be stored as a string

After tons of trial and error, miraculously got a "200" out of the API. Here is my code

ISSUER = '45366745684568-afdasfasdfasdfasdfasdf@developer.gserviceaccount.com'  # From service account
APP_NAME = '<appname>'  # This value didn't seem to matter.  I think it is for logging
APP_VERSION = '1.0'     # This value didn't seem to matter.  I think it is for logging

  class SomeClass < ActiveRecord::Base
   def self.google_api_client
    @@google_client ||= Google::APIClient.new(
      application_name:    APP_NAME,
      application_version: APP_VERSION
    ).tap do |client|

      # Load the key downloaded from the Google Developer Console
      if ENV['GOOGLE_API_KEY'].nil?
        puts "Be sure that you have ENV['GOOGLE_API_KEY'] defined in your environment."
        return
      end
      key = OpenSSL::PKey::RSA.new ENV['GOOGLE_API_KEY'], 'notasecret'

      # Initialize the connection
      client.authorization = Signet::OAuth2::Client.new(
        :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
        :audience => 'https://accounts.google.com/o/oauth2/token',
        :scope => 'https://www.googleapis.com/auth/androidpublisher',
        :issuer => ISSUER,
        :signing_key => key)
      client.authorization.fetch_access_token!
    end
  end

  def self.test_server(package_name, subscription_id, token)
    # Get the client
    client = self.google_api_client

    # Discover the subscriptions API
    publisher = client.discovered_api('androidpublisher', 'v2')

    # Make the API call
    result = client.execute(
      :api_method => publisher.purchases.subscriptions.get,
      :parameters => {'packageName' => package_name, 'subscriptionId' => subscription_id, 'token' => token}
    )
  end
end

Once I did all of the steps above I was still struggling (same 403 error). I realized the thing that was burning me was the 'scope' was not properly set to ' https://www.googleapis.com/auth/androidpublisher '. I hope this really helps someone. This was tearing me apart and now it works perfect.

Thanks all of the mentioned articles for your help.

Here's a rails gist that verifies whether a Google Play subscription is currently active using the latest google-api-client gem: https://gist.github.com/jkotchoff/e60fdf048ec443272045

That gist also includes documentation about how to create an OAuth token for which can be used offline.

ie.

  1. visit http://console.developers.google.com
  2. API Manager
  3. Credentials
  4. Create Credentials (OAuth client ID)
  5. Application type: Web Application
  6. Authorised redirect URIs: https://developers.google.com/oauthplayground
    • the resultant client ID / client secret is for your access token
  7. visit: https://developers.google.com/oauthplayground/
  8. Click the settings icon to show the OAuth 2.0 configuration
  9. Tick 'Use your own OAuth credentials'
  10. Enter the OAuth Client ID and OAuth Client secret that you have just created
  11. Check the entry for 'Calendar API v3' in the scopes field and click 'Authorize APIs'
  12. Click 'Allow'
  13. Click 'Exchange authorization code for tokens'
    • now you have a Refresh token and Access token for your client id / secret

Note, this gist has recently been upgraded to use version 0.9.x of the google-api-client gem. For an implementation that uses the deprecated v0.8.x of that gem, refer: https://gist.github.com/jkotchoff/e60fdf048ec443272045/e3e2c867633900d9d6f53de2de13aa0a0a16bb03

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM