Verify application subscriptions with Ruby on Rails API
A complete guide to learn how to verify subscriptions from the AppStore and PlayStore across a Ruby on Rails REST API, using candy_check gem. As well as how to handle all authorizations and configurations for the AppStore and PlayStore.
In times were paper revues were common, many people had a subscription to receive their favorite newspaper, magazine or tabloid. Subscription of this kind seems less and less common nowadays. However, people still subscribe to a lot of services in their daily lives, phone, internet, video games, insurance, even delivery options!
The subscription method also applies when creating applications. For example, an application with daily, weekly or monthly new content. This subscription, allows a regular income, that permits maintaining the service, such as a newspaper application.
Apps on the AppStore and PlayStore should exist with an API in the middle, to work as an interface between applications and the database, to enable managing the same data for both. This is allow a cross-platform user.
Usually, applications deal directly with the AppStore or PlayStore to handle everything related to a subscription. However, if you have a cross-platform user you need to check their subscription from the API. For example: to verify the receipt/purchase token or the end date of subscription.
Dealing with subscriptions on the PlayStore and AppStore across an API could require a huge amount of work - configure the API to receive different types of responses from each platform, set up services for iOS and Android App. Luckily, there are some tools that help achieve this a lot easier.
This article will walk through a Ruby on Rails (RoR) gem, candy_check.
In the following article we will intend to resolve these points:
- Present candy_check gem and basic configurations;
- Explain how to configure AppStore and mainly PlayStore;
- How to manage .p12 certificate file from Google API developer when deploying.
Candy check a useful gem
Among all possibilities to verify subscriptions with a RoR API, candy_check gem seems like one of the best options. Some advantages:
- Saving time configuring controllers for both platforms;
- Only one gem to deal with two different services;
The gem documentation explains in details how to use it, however, an example which presents an encapsulation in a controller is always a welcome.
In this controller, there is one endpoint for each service. The general structure is the same:
- calling a method to deal with the gem and retrieve information from the AppStore or PlayStore,
- validating the response - with classes of candy_check gem,
- and processing data in check_service_receipt(receipt) to be able to extract logics needed depending on the products you configured - here we can check subscription validity and change user status for example.
There are two endpoints because the used parameters, methods, and classes are not exactly the same.
Now we are going to look at the classes which handle candy_check methods. But before a word about configuration parameters. They are stored, in local, in .env, and retrieved across secrets.rb, to keep these parameters confidential and ease any change from services. See the example below:
Secret parameters are defined depending on environment and refer to environment variables. For the development environment, these variables are stored in the file .env.
The .env file should be added to the gitignore, to learn more about it check here.
Now we can call this variable by:
The configuration for the AppStore is very simple, only two parameters are required:
- appstore_environment: :sandbox or :production,
- appstore_secret: secret key to access to the AppStore API (see below to learn more about it).
Here is an example on how to use the gem:
You can remark two steps in this method:
- Set up configuration parameters for Verifier class from candy_check gem;
- Use the configured class to retrieve subscription information.
It is as simple as that.
To learn more about what the gem simplifies, check this documentation.
For the PlayStore, things are a bit harder. There are some extra parameters to configure:
- playstore_application_name: application name on PlayStore;
- playstore_application_version: actual version;
- playstore_issuer: coming from Google Developers API (ex: app-api@api-546844648–8768.iam.gserviceaccount.com)
- playstore_key_file: certificate file *.p12 coming from Google Developers API;
- playstore_key_secret: secret key to access to certificate file *.p12 - usually is notasecret;
- playstore_cache_file: path to cache file;
- playstore_package: package name one the PlayStore.
The next part will explain where and how to find these parameters. Pieces of code below will show how to use them.
You can notice the two same steps, as in AppStore class, in the first method purchase_verifier:
- Set up the configuration parameter for Verifier class from candy_check gem (using playstore_verifier method);
- Use the configured class to retrieve subscription information.
However, the Verifier class needs more information and needs to be booted. This verifier.boot! automatically minimizes the amount of work: generates authentication to use Google Developers API and allows us to retrieve information from the PlayStore. This helps reduce the amount of work in the above methods.
Conclusion on gem presentation
In few lines and with few parameters this gem allows you to retrieve information to verify subscriptions easily (which is fantastic), but now we need to generate and access to all of the parameters listed. The steps are simple, but if it is your first time the following part will surely save you a lot of time.
For the AppStore, you only need to set up your subscription product and use your appstore_secret_key. Therefore, we will focus on PlayStore API configuration. To find your appstore_secret_key go to iTune Connect and after signing in, follow steps below:
Configure PlayStore API
All possible ways for the configuration are listed and explained in detail following this link.
If you are doing it for the first time follow only the steps bellow:
- Go to this link and sign in with the owner account;
- Accept Terms of service;
- Click on Create new project;
Now, an API project is generated and linked to your Google Play Console. In case you would like to use an existing one check out this link.
Next step, create a service account to access the API from a build server without providing your personal user credentials:
- Go back to: API Access Place for Google Play;
- Under Service Accounts, click Create Service Account;
- Follow the instructions on the page to create your service account (Look specifically at the image below and for the key type select P12);
- Once you’ve created the service account on the Google Developers Console, click Done. The API Access page automatically refreshes, and your service account will be listed.
- Click Grant Access to provide the service account the necessary rights to perform actions (this is very import, the service account must have access to the bills category).
Now you have all information and configuration to use PlayStore API:
- playstore_issuer: from the service account with necessaries right on PlayStore API (ex: app-api@api-546844648–8768.iam.gserviceaccount.com)
- The P12 file, do not lose it, because you can not generate it newly;
- Secret code to access to p12 certificate file.
A solution to manage certificate file from Google API
Certificate file contains information to access your services. So it is important not to share it. Do not upload it to your git repository and do not forget to put the path in the gitignore.
In this article we use AWS (Amazon Web Service) to deploy the project if your not using AWS the idea is the same:
- Create a private S3 bucket with the file;
- When deploying add automatically the file on your server;
- Use environment parameters to set the path to this file on the server;
Create a private S3 bucket
Sign up to AWS account where the app is deploy:
- Create a new bucket with a name: certificate-bucket;
- Verify Access right to the new bucket, should be Not public*;
- Upload you certificate file to the bucket recently created;
At this point, you have your certificate file upload and only AWS account users can access it.
A snippet to upload a file in the app
In the example, we used Elastic Beanstalk to manage our server. If you never heard about it you could start with this link. Using this way to deploy, permit to add a snippet of code that will be executed when deploying. This snippets should be added to the folder /.ebextensions/ of the project. Here’s the one we used:
We simply use the cp (copy - paste) command from aws s3, give paths of S3 bucket and target path on our server.
Set environment params
Last step is to set up environment parameters on the server. The path should be the same as the target path on the snippet code:
PLAYSTORE_KEY_FILE = /tmp/your_certificate_file.p12
This article explained a complete way to verify subscriptions across a Ruby and Rails API and server on AWS. In the case your API does not use RoR or AWS, you can apply the same logic and structure. I hope the post was helpful!