How we manage payments across multiple platforms in Vookmark 🤑💸

Ameer Hamja
5 min readJul 5, 2018

--

To monetize for Vookmark we used multiple payment methods native to each platform it was available on.

  1. Stripe (Web App)
  2. Google Play subscriptions (Android)
  3. Apple App Store subscriptions (iOS)
Payment Method

Stripe (Web App)

We used Stripe for subscriptions initated through the browser. You can read more about it here .

Stripe Payment

After you click the pay button, Stripe validates the payment information and provides an one time token. A sample one time token is shown here,

OneTimeToken:tok_1CNa3TJqROc2KRwhHAeaj7ad

Once you have this token from the Web UI, initiate background processing with this information and create a new user and subscription in Stripe.

customer = Stripe::Customer.create(
:email => UserEmail,
:source => StripeToken,
:plan => ‘yearly’
)

After the payment is a success, you get the below details of the customer through Stripe,

  1. CustomerID
  2. SubscriptionID
  3. Subscription StartDate
  4. Subscription EndDate
  5. TransactionID

When the subscription is a success, user will be upgraded to pro mode across all the platforms [Web, Android, iOS, iPad, Apple TV ].

When the subscription processing is a failure, reinitiate payment process from the one time token creation method.

Cancelling Subscription in Stripe:

Cancel Subscription Template

Vookmark allows you to cancel subscriptions.When the user clicks on the cancel subscription button, you initiate the cancel subscription with the below payload to Stripe etc.

customer = Stripe::Customer.retrieve(CustomerID)customer.subscriptions.retrieve(customer.subscriptions.data[0].id).delete

Once your subscription is cancelled, auto renewal will be stopped. But your Pro mode will be active across all the platforms [web, Android, iOS, iPad, Apple TV] till the end of current subscription period.

Google Play Store:

We used Google Play Store for subscriptions initiated through the Android app. You can read more about it here. When Google Play Store processes the payment successfully, the Android app gets an OrderID.

  1. PublicKey and PackageName are same for all Google Play Store Vookmark payments.
  2. For each and every payment we get an unique OrderID and JSON object.
  3. Use the below method to verify the OrderID.
require 'rubygems'
require 'openssl'
require 'base64'

base64_encoded_public_key = "YOUR KEY HERE"
data = "JSON_DATA_HERE"
sig = "SIGNATURE HERE"

key = OpenSSL::PKey::RSA.new(Base64.decode64(base64_encoded_public_key))

verified = key.verify( OpenSSL::Digest::SHA1.new, Base64.decode64(sig), data )

Once it is verified, user will be upgraded to Pro mode across all the platforms.

Trial Period:

To check the customer subscription state, we use a Cron Job. Cron will be run at end of the trial period and use following parameters to check the state of user,

  1. PackageName
  2. SubscriptionName
  3. CustomerID
  4. Access Token [https://developers.google.com/android-publisher/authorization]

With the above details, the below API call is made to check on the subscription state and updated in our database.

RestClient.get “https://www.googleapis.com/androidpublisher/v2/applications/#{package_name}/purchases/subscriptions/#{subscription_name}/tokens/#{customer_id}/?access_token=#{access_token}"

If we get the CancelReason node, then subscription for that particular user is cancelled.

Play Store Cancel Subscription State Response
  1. If the subscription was cancelled by the user, before the end of trial period, Pro mode will be deactivated for the user across all platforms.
  2. If the subscription was cancelled by user after the trial period, auto renewal will be stopped. However, Pro mode will be active across all the platforms until the current subscription date ends.

Apple App Store subscriptions (iOS):

We used Apple App Store for subscriptions initiated through the app. You can read more about it here. When Apple App Store processes the payment successfully, the app gets an ReceiptData object.

Use the below method to verify the ReceiptData,

payload = {“receipt-data” => “”, “password” => “”}
url = ‘https://buy.itunes.apple.com/verifyReceipt'
initheader = { ‘Content-Type’ => ‘application/json’ }
encoded = JSON.generate(payload)
details = RestClient.post(url, encoded, initheader)
result = JSON.parse(details)

3. If result[“status”] == 0 it is a valid ReceiptData.

4. Get the customer payment details from the result node.

5. The user is then upgraded to Pro mode across all the platforms.

Trial Period:

To check the status of a customer’s subscription, we use a Cron Job. Cron will be run at end of the trial period. Use the following parameters to check the state of user,

  • ReceiptData and Password
payload = {“receipt-data” => “”, “password” => “”}
url = ‘https://buy.itunes.apple.com/verifyReceipt'
initheader = { ‘Content-Type’ => ‘application/json’ }
encoded = JSON.generate(payload)
details = RestClient.post(url, encoded, initheader)
result = JSON.parse(details)

If we get the expiration_intent node, then subscription for that particular user is cancelled.

App Store Cancel Subscription State
  1. If the subscription was cancelled by the user, before the end of trial period, Pro mode will be deactivated for the user across all platforms.
  2. If the subscription was cancelled by user after the trial period, auto renewal will be stopped. However, Pro mode will be active across all the platforms until the current subscription date ends.

Cancel Subscription for Play Store and App Store:

At end of the subscription period, check the cancel subscription state of a customer using the Cron Job.

  1. If the subscription was cancelled by the user auto renewal will be stopped. Then Pro mode will be deactivated across all the platforms.
  2. If the subscription was not cancelled, they can continue in Pro mode across all the platforms

Thus we integrated native payment modes across multiple platforms for provide a seamless payment experience for our users.

Happy Vookmarking ! 😎

Happy Earning! 🤑

--

--