Checking for Payment
If you plan to use Chrome Web Store Payments, you can use the Chrome Web Store Licensing API to determine whether the user has paid. The Licensing API is a simple REST-based API that lets you query the Chrome Web Store license server to find out whether a particular user has paid for a particular app.
Generally, you use the Licensing API in hosted apps. Although you can use the API in packaged apps and extensions, it's more difficult for them to use the license server securely.
Note: This page applies only if you use Chrome Web Store Payments. For information on other options, see Charging for your app in the Overview.
Overview of using the Licensing API
Using the Licensing API requires a user ID, an app ID, and an OAuth access token and token secret. The user ID is the OpenID URL for the user's Google Account. You can get the app ID and the OAuth access token and token secret from the Chrome Developer Dashboard after you upload your app for the first time.
Here's an overview of the process of writing code that uses the Licensing API:
- Get the app ID and OAuth access token from the Chrome Developer Dashboard.
- Add code to get the Google Account OpenID URL for the current user.
- Add code to make a signed OAuth request to the license server.
- Add code to handle the response from the license server.
Read the following sections for details about this process, with tips on testing your code.
Get access to the Licensing API
Before you can use the Licensing API for a particular app, you need to do some one-time preparation:
- Upload a ZIP file for your app to the Chrome Developer Dashboard. See Step 3 in Publishing Your App for details.
- In the edit page for your app, click the Change pricing button, choose This application uses Chrome Web Store Payments, and save.
- Get your app's ID, which you can do either as described in Step 5 of Publishing Your App or when you get an OAuth access token.
- Get an OAuth access token and token secret so that your app can use the Licensing API. For details, see the next section.
Getting an OAuth access token and token secret
You get the access token and access token secret for your app from a special page in the Chrome Developer Dashboard. Here's how.
-
Go to the Chrome Developer Dashboard. As the following screenshot shows, each app that you've uploaded and that uses Chrome Web Store Payments has an OAuth setup link that lets you get OAuth information for that app.
In this dashboard, two apps have an OAuth setup linkNote: If you don't see the OAuth setup link for your app, click the Edit link and use the Change pricing button to specify that your app uses Chrome Web Store Payments.
-
Click the OAuth setup link. You get a page with OAuth information for the Licensing API. At the bottom of that page is the information you need to make Licensing API requests with your app, including the app ID but not the access token and token secret. Here's an example of what you might see:
What the bottom of the OAuth window looks like before you generate a token -
Click the Generate new token button at the bottom of the page to generate the OAuth access token and token secret for your app.
What you see after generating a token -
Record the token and token secret in a safe place. The dashboard will not show them to you again.
Important: Keep your access token and token secret safe and private. (The screenshot shows sample values that won't work.) If you lose the token or token secret, you'll have to return to the dashboard and generate them again.
Make a signed OAuth request
To make a request with the Licensing API, you need the following:
- a user ID for the current user (an OpenID URL corresponding to a Google account)
- the app ID for your app
- the OAuth access token that gives your app access to the Licensing API
- the corresponding access token secret
- a consumer key ("anonymous")
- a consumer secret ("anonymous")
All of these except the user ID are constant for your app. When you have them all, you can create and send a signed OAuth request to the licensing server, signing it using the HMAC-SHA1 algorithm. Here's the request you send if you want the response in JSON format:
https://www.googleapis.com/chromewebstore/v1/licenses/appId/userID
If you want the response in ATOM format,
you add ?alt=atom
to the request:
https://www.googleapis.com/chromewebstore/v1/licenses/appId/userID?alt=atom
The next sections have further details on getting the user ID, creating the request, and sending the request.
Get the user ID
The user ID is an OpenID URL corresponding to a Google Account. See Identifying the user for instructions on getting the current user's ID using OpenID.
Create, sign, and send the request
You should use an OAuth library to help create and sign the request. The following Java example creates, signs, and sends a request, using the OAuth Signpost library and the standard URLConnection class.
public static final String APP_ID = "yourAppId"; private static final String TOKEN = "anOAuthToken"; private static final String TOKEN_SECRET = "anOAuthTokenSecret"; public static final String SERVER_URL = "https://www.googleapis.com/chromewebstore/v1/licenses/%s/%s"; public static final String CONSUMER_KEY = "anonymous"; public static final String CONSUMER_SECRET = CONSUMER_KEY; ... OAuthConsumer oauth = new DefaultOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET); oauth.setTokenWithSecret(TOKEN, TOKEN_SECRET); URLConnection http = new URL( String.format( SERVER_URL, APP_ID, URLEncoder.encode(user.getFederatedIdentity(), "UTF-8") ) ).openConnection(); oauth.sign(http); http.connect();
Handle the response
The response you get from the license server tells you three things:
whether the user has access to the app,
the level of access the user should have,
and how much longer the response is valid.
If you just want to know whether the user has access,
check the value of the result
field.
If you want to know whether the user should get
a free trial version of the app,
check the value of the accessLevel
field.
(If you're using ATOM, the field name is all lowercase:
accesslevel
.)
The response is valid for the number of seconds specified by the value of
the maxAgeSecs
field.
Once that time has passed,
you should query the license server again
to check whether the user's access has changed.
Note:
The max-age
directive of the response's Cache-Control HTTP header
has the same value
as the maxAgeSecs
field.
Use whichever one is most convenient.
Situation | result | accessLevel |
---|---|---|
The user has paid for the app. | YES |
FULL |
The user hasn't paid for the app, but should get a free trial version. | YES |
FREE_TRIAL |
The user has not paid for the app,
and shouldn't have access to the app.
Note: In this situation, your app should provide an easy way for the user to buy it, such as by providing a prominent link to its store listing. |
NO |
NONE |
Parse the JSON or ATOM data
Unless you specify otherwise, you get a JSON response back from the license server. Once unescaped, it looks something like this:
{ "kind": "chromewebstore#license", "id": "appId/userId", "appId": "appId", "userId": "userId", "result": "YES", "accessLevel": "FULL", "maxAgeSecs": "3600", }
If your GET request has ?alt=atom
,
you get ATOM data,
which looks something like this
after unescaping:
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005" xmlns:cws="http://schemas.google.com/chromewebstore/2010" gd:kind="chromewebstore#license"> <id>http://www.googleapis.com/chromewebstore/licenses/ appId/userId</id> <cws:appid>appId</cws:appid> <cws:userid>userId</cws:userid> <cws:result>YES</cws:result> <cws:accesslevel>FULL</cws:accesslevel> <cws:maxAgeSecs>3600</cws:maxAgeSecs> </entry>
Use your favorite JSON or XML parser
to get the value of the fields you're interested in.
The following example checks
both the result
and accessLevel
fields
of a JSON-formatted response from the license server.
JSONObject json = new JSONObject(body); Object result = json.get("result"); String license = "no"; if (result != null && result.equals("YES")) { Object accessLevel = json.get("accessLevel"); license = accessLevel != null && accessLevel.equals("FULL") ? "full" : "free-trial"; }
For more code, see the Samples.
Cache the results
To improve the performance of your app
and avoid running into rate limits,
don't make a license server request every time you load a resource.
Instead, make one request and then cache the results
for the number of seconds
specified by the maxAgeSecs
field
(or by the max-age
directive
of the Cache-Control HTTP header).
Test your implementation
While testing your app's interaction with the license server, you can use the OAuth Playground and special user IDs.
The OAuth Playground
If you have difficulties with your license server requests or responses, or if you just want to see for yourself what the responses look like, try the OAuth Playground. The Playground lets you send raw API requests, displaying the full request and the response returned by the server.
Note: When you use the OAuth Playground, click the execute button to send the request. Pressing Enter doesn't work.
Special user IDs for testing
Before releasing your app to the general public, you should have a few trusted testers try out the install/payment flow. You can do this by creating a version of your app that you publish only to a few accounts. For details, see Publishing to test accounts.
OAuth resources
You should use an existing OAuth library rather than implement your own. Here are a few libraries we've used:
- Java: OAuth Signpost
- Python: Python OAuth2
- PHP: OAuth for PHP
- Ruby: Signet
You can find more libraries at the OAuth Code page.
For a detailed explanation of using OAuth, see Authentication and Authorization for Google APIs.
What next?
Read Supplying Images.