React Native - Subscriptions (Android)


IAB
In-app Billing
GP
Google Play
GPC
Google Play Console

  1. https://developer.android.com/google/play/billing/index.html
  2. https://developer.android.com/google/play/billing/billing_subscriptions.html

implement subscriptions in application

  1. https://github.com/idehub/react-native-billing

https://developer.android.com/google/play/billing/api.html#subs:

Unlike managed products, subscriptions cannot be consumed.

include license key in application build

https://developer.android.com/google/play/billing/billing_integrate.html#billing-security:

To help ensure the integrity of the transaction information that is sent to your application, Google Play signs the JSON string that contains the response data for a purchase order. Google Play uses the private key that is associated with your application in the Play Console to create this signature. The Play Console generates an RSA key pair for each application.

To find the public key portion of this key pair, open your application’s details in the Play Console, click ‘Services & APIs’, and review the field titled ‘Your License Key for This Application’.

When your application receives this signed response, you can use the public key portion of your RSA key pair to verify the signature.

GPC:

Licensing allows you to prevent unauthorized distribution of your app. It can also be used to verify in-app billing purchases.

  1. https://support.google.com/googleplay/android-developer/answer/186113?hl=en
  2. https://developer.android.com/google/play/billing/billing_admin.html#license_key
GPC
All applications<MY_APP>
Development tools (left menu) → Services & APIsLicensing & in-app billing

android/app/src/main/res/values/strings.xml:

  <resources>
      <string name="app_name">Хоккей</string>
+     <string name="RNB_GOOGLE_PLAY_LICENSE_KEY">YOUR_GOOGLE_PLAY_LICENSE_KEY_HERE</string>
  </resources>

declare IAB permission

https://developer.android.com/google/play/billing/billing_integrate.html#billing-permission:

In-app billing relies on the Google Play application, which handles all of the communication between your application and the Google Play server. To use the Google Play application, your application must request the proper permission.

If your application does not declare the In-app Billing permission, but attempts to send billing requests, Google Play refuses the requests and responds with an error.

android/app/src/main/AndroidManifest.xml:

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+ <uses-permission android:name="com.android.vending.BILLING" />
  <uses-feature android:name="android.hardware.camera" android:required="false"/>

add subscription in GPC

create signed APK

  1. https://facebook.github.io/react-native/docs/signed-apk-android.html

assemble production release with IAB permission as usual.

NOTE: you cannot upload APK with the same build number twice.

upload APK to alpha

https://developer.android.com/google/play/billing/billing_admin.html#billing-list-setup:

The link to the In-app Products page appears only if you have a Google payments merchant account and the app’s manifest includes the com.android.vending.BILLING permission.

NOTE: in fact In-app products page is available even when application with IAB permission is not uploaded but there are no MANAGED PRODUCTS and SUBSCRIPTIONS tabs to manage corresponding items in product list.

=> upload APK with IAB permission to alpha channel to be able to set up subscription (actually upload APK anywhere - alpha channel is just the safest option).

at the same time it’s not required to publish (rollout) application - you can both set up subscription and test it on real device without publishing (see testing with test subscriptions section).

GPC
All applications<MY_APP>
Release management (left menu) → App releasesAlpha (section) → MANAGE (button) → CREATE RELEASE (button)

New release to alpha

Confirm rollout to alpha: 3.15

add pricing template

  1. https://support.google.com/googleplay/android-developer/answer/138000?hl=en&ref_topic=3452890
GPC
Settings (left menu)
Pricing templates (left menu) → NEW PRICING TEMPLATE (button)

about Add applicable tax on top of price tax option:

Local tax is added in addition to set price in select countries. Local prices are generated using exchange rates and local pricing patterns. Tax is only added in countries with set tax rates.

=> EUR 2.09 (~ RUB 149) becomes EUR 2.49 (~ RUB 179).

set up subscription (add subscription item to product list)

  1. https://developer.android.com/google/play/billing/billing_admin.html#billing-form-add

NOTE: you can’t set up subscription until you upload APK with IAB permission (see upload APK to alpha section).

GPC
All applications<MY_APP>
Store presence (left menu) → In-app productsSubscriptions (tab) → + Create subscription (button)

test subscription on real device

  1. https://developer.android.com/google/play/billing/billing_testing.html#testing-subscriptions
  2. https://stackoverflow.com/a/22469253/3632318 (list of requirements)
  3. http://suda.pl/the-hell-of-testing-google-play-in-app-billing
  4. https://www.youtube.com/watch?v=XMrUBC4Xgl8

emulator (app):

InAppBilling is not available. InAppBilling will not work/test on an emulator, only a physical Android device.

testing with static responses

YOU DON’T NEED TO TOUCH GOOGLE PLAY CONSOLE AT ALL TO TEST WITH STATIC RESPONSES.

  1. https://developer.android.com/google/play/billing/billing_testing.html#billing-testing-static
  2. https://github.com/idehub/react-native-billing#testing-with-static-responses

You do not need to list the reserved products in your application’s product list. Google Play already knows about the reserved product IDs. Also, you do not need to upload your application to the Play Console to perform static response tests with the reserved product IDs. You can simply install your application on a device, log into the device, and make billing requests using the reserved product IDs.

UPDATE (2019-08-13)

I couldn’t manage to make static responses work - stick to testing with test or real subscriptions.

use reserved product ID

replace real product ID (com.iceperk.iceperkapp.sub.noads.monthly) with one of reserved ones:

set license key to null temporarily

  1. https://github.com/idehub/react-native-billing#testing-with-static-responses

use null license key when testing with static responses.

android/app/src/main/res/values/strings.xml:

  <resources>
      <string name="app_name">Хоккей</string>
+     <string name="RNB_GOOGLE_PLAY_LICENSE_KEY" />
  </resources>

however you cannot remove RNB_GOOGLE_PLAY_LICENSE_KEY property altogether - or else you’ll get String resource ID #0x0 error.

run application on real device

  1. React Native - Running on Real Device

troubleshooting

testing with test subscriptions

  1. https://developer.android.com/google/play/billing/billing_testing.html#test-purchases-sandbox

test subscriptions:

test subscriptions are not created separately - they are real subscriptions but with special characteristics and behaviour for license testers.

=> it’s required to create and publish a real subscription in GPC as described above (application itself may stay unpublished).

https://developer.android.com/google/play/billing/billing_admin.html#billing-form-add:

To be visible to a user during checkout, an item’s publishing state must be set to Active, and the item’s app must be published on Google Play.

If you’re using a test account, users can see active items within unpublished apps, as well.

https://developer.android.com/google/play/billing/billing_testing.html#billing-testing-test:

A test account can purchase an item in your product list only if the item is published.

add license testers (license test accounts, license tester accounts)

  1. https://developer.android.com/google/play/billing/billing_testing.html#setup
  2. https://developer.android.com/google/play/billing/billing_admin.html#billing-testing-setup
GPC
Settings (left menu)
Developer account (left menu) → Account detailsLicense Testing (section)

it’s not required that license test account is linked to a valid payment method (I could make a test purchase without any linked payment method).

if user is registered as both license and alpha tester, being a license tester has priority: he’ll be offered to purchase a test subscription only.

NOTE: license test account must be a primary account on real device!

https://developer.android.com/google/play/billing/billing_testing.html#billing-testing-test:

The only way to change the primary account on a device is to do a factory reset, making sure you log on with your primary account first.

set valid license key

see include license key in application build section.

uninstall existing application from real device

it’s necessary to uninstall application from device beforehand or else you’ll get one of these errors:

$ adb uninstall com.iceperkapp

NOTE: com.iceperkapp is both package name and applicationId from android/app/build.gradle.

set environment in application

test subscriptions can be purchased in both development and production environments - just don’t forget to forward ports in development environment.

run or install application on real device

  1. React Native - Running on Real Device

NOTE: application (being installed now) and APK (uploaded to GPC) must have the same version name and build number.

TODO: previous statement should be double-checked (and find its source).

troubleshooting

testing with real subscriptions

  1. https://developer.android.com/google/play/billing/billing_testing.html#transactions
  2. https://github.com/idehub/react-native-billing#testing-with-your-own-in-app-products

https://developer.android.com/google/play/billing/billing_testing.html#billing-testing-test:

You can do end-to-end testing of your app by publishing it to an alpha distribution channel. This allows you to publish the app to the Google Play Store, but limit its availability to just the testers you designate.

add alpha testers (alpha tester accounts)

release review summary when trying to publish release to alpha without testers:

This release will not be available to any users because you haven’t specified any testers for it yet.

https://developer.android.com/google/play/billing/billing_testing.html#transactions:

With alpha/beta test groups, real users (chosen by you) can install your app from Google Play and test your in-app products. They can make real purchases that result in actual charges to their accounts, using any of their normal payment methods in Google Play to make purchases. Note that if you include test license accounts in your alpha and beta distribution groups, those users will only be able to make test purchases.

=> license testers cannot make real purchases!

so I’ve removed myself from license testers (*.tap349@gmail.com email) and added to alpha testers instead (see below). also unlike for license test account it’s important that alpha tester account be linked to a valid payment method - so make sure to add payment info for this account before trying to make a purchase.

GPC
Settings (left menu)
Manage testers (left menu) → CREATE LIST (button)
GPC
All applications<MY_APP>
Release management (left menu) → App releasesAlpha (section) → MANAGE (button) → Manage testers (section)

it’s possible to add/remove alpha testers after release is published.

publish release to alpha

NOTE: publish release to alpha only if you’re planning to start Alpha Testing (either open or closed) - don’t publish if you will test application by installing and running it on real device with adb.

GPC
All applications<MY_APP>
Release management (left menu) → App releasesAlpha (section) → MANAGE (button) → EDIT RELEASE (button)

New release to alpha

Confirm rollout to alpha: 3.15

open opt-in URL in browser

GPC
All applications<MY_APP>
Release management (left menu) → App releasesAlpha (section) → MANAGE (button) → Manage testers (section) → Opt-in URL (input)

subscription error codes

  1. https://developer.android.com/google/play/billing/billing_reference.html
  2. https://github.com/idehub/react-native-billing/issues/17#issuecomment-228036758
  3. https://github.com/anjlab/android-inapp-billing-v3/blob/master/library/src/main/java/com/anjlab/android/iab/v3/Constants.java
  4. https://github.com/idehub/react-native-billing/blob/master/android/src/main/java/com/idehub/Billing/InAppBillingBridge.java

in both cases react-native-billing rejects promise with this error message:

Purchase or subscribe failed with error: <error_code>

publish release with subscription

update tax info (if necessary)

GPC
Settings (left menu)
Developer account (left menu) → Payment settingsSettings (section) → MANAGE SETTINGS (button)
Payments profile (section) → United States tax info (link) → UPDATE TAX INFO (link)

Tax form questions

Certificate of Foreign Status

rollout app to production

new app appeared in GP almost immediately (it took about 1 minute).

view financial reports

test subscriptions

test transactions are not shown in financial reports. IDK how to view them - currently I can track them through GP emails only (they are sent to license test account email each time subscription is renewed or cancelled).

real subscriptions

GPC
All applications<MY_APP>
Financial reports (left menu) → Subscriptions

statistics are collected with 2 days delay (there’re no data for the last 2 days).