Skip to content

Instantly share code, notes, and snippets.

@derrek
Last active August 17, 2022 19:34
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save derrek/763ef95c71491833ae3c1e4acad6785e to your computer and use it in GitHub Desktop.
Save derrek/763ef95c71491833ae3c1e4acad6785e to your computer and use it in GitHub Desktop.
Google Play/Android Receipt Validation/Verification/Lookup with Ruby

This document outlines setting up google's ruby gem, google-api-client, to verify payloads(receipts) sent to a server from google play in app purchases made via an android app.
This document was written using version 0.9.13.

First you'll need 'owner' access to the google play developer's console that contains the mobile app you wish to verify receipts from.

  • Go to https://play.google.com/apps/publish
  • Click on the mobile app you'd like to set up
  • Click "Settings" on the left click "API access"
  • Below "LINKED PROJECT" link the google play account

Next setup an api account

  • Go to http://console.developers.google.com
  • From the left menu select "Credentials"
  • From the center click "Create credentials"
  • From the drop down select "OAuth client ID"
  • From the "Application Type" list select "Web Application"
  • Note your the "client id" and "client secret"

Now manually "login" with your oauth information (this video outlines the steps below https://www.youtube.com/watch?v=hfWe1gPCnzc)

  • go to https://developers.google.com/oauthplayground/
  • Click the "cog" icon on the righ
  • Check "User your own OAuth credentials"
  • Select "Access Type" of "Offline"
  • Enter the client id and client secret created from the previos step
  • Under scopes on the left select "Google Play Developer API v2" and then
  • click "Authorize APIs'
  • click "Allow'
  • click "Exchange authorization code for tokens'
  • note the "refresh token" and "access token"

Add your secrets.yml something similar to below

google_oauth_defaults: &google_oauth_defaults
  google_oauth_client_id: <%= ENV["GOOGLE_OAUTH_CLIENT_ID"] %>
  google_oauth_client_secret: <%= ENV["GOOGLE_OAUTH_CLIENT_SECRET"] %>
  google_oauth_refresh_token: <%= ENV["GOOGLE_OAUTH_REFRESH_TOKEN"] %>
  google_oauth_access_token: <%= ENV["GOOGLE_OAUTH_ACCESS_TOKEN"] %>

production:
  <<: *google_oauth_defaults

This example assumes rails and uses rails application secrets. You can, of course, swap that out to suite your needs.

require 'google/apis/androidpublisher_v2'

class GooglePlayReceiptVerifier
  attr_accessor :receipt_data
  
  def initialize(receipt_data)
    self.receipt_data = receipt_data
  end
  
  def package_name
    receipt_data&.fetch("packageName", nil)
  end

  def product_id
    receipt_data&.fetch("productId", nil)
  end

  def purchase_token
    receipt_data&.fetch("purchaseToken", nil)
  end
  
  def verify
    secrets = Rails.application.secrets
    
    auth_client = Signet::OAuth2::Client.new(
      scope: [Google::Apis::AndroidpublisherV2::AUTH_ANDROIDPUBLISHER],
      authorization_uri: "https://accounts.google.com/o/oauth2/auth",
      token_credential_uri: "https://accounts.google.com/o/oauth2/token",
      client_id: secrets.google_oauth_client_id,
      client_secret: secrets.google_oauth_client_secret,
      refresh_token: secrets.google_oauth_refresh_token,
      access_token: secrets.google_oauth_access_token
    )

    aps = Google::Apis::AndroidpublisherV2::AndroidPublisherService.new
    aps.authorization = auth_client

    is_verified = false

    aps.get_purchase_product(
        package_name,
        product_id,
        purchase_token,  
    ) do |result, err|
      if result
        # this is a bit simplified - you may opt to do something
        # with the result like store it or return it to the caller
        is_verified = true
      end
      if err
        # you may wish to do something with err like return it to the caller or store it
        # err.to_s
      end
    end
    
    return is_verified
  end
end
@gmcnaughton
Copy link

Thanks so much for the walkthrough and the code!

Out of curiosity, when creating oauth credentials, why use "Web Application" as the application type instead of "Service Account"?

@jeremymarc
Copy link

thanks!

@famictech2000
Copy link

How can you tell if its a PROD purchase vs a TEST purchase?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment