Slide 1

Slide 1 text

The State of In-app Purchases on Android Sebastiano Gottardo

Slide 2

Slide 2 text

IS HIRING

Slide 3

Slide 3 text

“Sometimes all you need is a billion dollars”

Slide 4

Slide 4 text

How can we make money on Android?

Slide 5

Slide 5 text

In-app products Subscriptions Managed Products

Slide 6

Slide 6 text

Managed Products One-off payments Each app can offer different products Consumable and non-consumable

Slide 7

Slide 7 text

Subscriptions Recurring billing Multiple subscriptions (w/ upgrade/downgrade) Auto-renewed

Slide 8

Slide 8 text

Subscriptions Multiple billing periods Recurring payment Managed Products One-off payment Consumable Non-consumable Non-consumable In-app products

Slide 9

Slide 9 text

In-app products Product ID (SKU) Unique

Slide 10

Slide 10 text

Implementing in-app billing

Slide 11

Slide 11 text

29 March 2011 In-app Billing Launched on Android Market 10 December 2012 In-App Billing Version 3 12 June 2017 New Google Play Billing Library (DP) 19 September 2017 Google Play Billing Library 1.0 released

Slide 12

Slide 12 text

In-app billing — High level Basic requirement an Android device that has billing capabilities In-app Billing Service IInAppBillingService.aidl Libraries

Slide 13

Slide 13 text

In-App Billing Version 3 isBillingSupported() isBillingSupportedExtra…() 
 getSkuDetails() getBuyIntent() consumePurchase() getBuyIntentToReplaceSkus() getBuyIntentExtraParams() getPurchases() getPurchaseHistory()

Slide 14

Slide 14 text

✔ Simple to understand ✘ Synchronous! ✘ No type-safety ✘ Service connection In-App Billing Version 3

Slide 15

Slide 15 text

The Play Billing Library (PBL) Replaces… nothing Maintained by Google Offers convenient access to IAB APIs

Slide 16

Slide 16 text

PBL components PBL BillingClient BillingClientStateListener PurchasesUpdateListener

Slide 17

Slide 17 text

PBL components PBL BillingClient newBuilder() setListener(PurchasesUpdateListener) startConnection(ClientStateListener) querySkuDetailsAsync(…,listener) queryPurchases() queryPurchaseHistoryAsync(listener) consumeAsync(listener) launchBillingFlow()

Slide 18

Slide 18 text

PBL — The good and the meh ✔ Less chances of errors ✔ Comes with updated samples ✔ Proper support for multiple platforms ✔ Better (and updated) documentation ✘ Not open-source ✘ Not really streamlined

Slide 19

Slide 19 text

“I wish this library came out 4 months ago” Me, June 2017

Slide 20

Slide 20 text

anjlab/ android-inapp-billing-v3 Open-source and actively developed Good wrapper over bare service calls Handling of some edge cases A lightweight implementation of Android In-app Billing Version 3

Slide 21

Slide 21 text

in-app billing Testing

Slide 22

Slide 22 text

Why testing?

Slide 23

Slide 23 text

OH PLEASE

Slide 24

Slide 24 text

Testing in-app products Static responses Real purchases Fake (money, for real) purchases

Slide 25

Slide 25 text

Static responses Use reserved product IDs Response is automatic No need for the app to be on the store

Slide 26

Slide 26 text

Static responses android.test.purchased android.test.canceled android.test.refunded android.test.item_unavailable

Slide 27

Slide 27 text

Static responses … cannot be used with subscriptions

Slide 28

Slide 28 text

Real purchases Require a published app (alpha/beta/prod) The real deal, with real money Hideous setup

Slide 29

Slide 29 text

Real purchases 1. Your app is published (i.e., not in draft). 2. The APK must be published (either production, alpha or beta channels). 3. The APK you uploaded matches the one you’re testing with when it comes to version code, version name, and keystore signature. 4. When testing on the device, you’re using a different account than the one tied to the Play Console (i.e., not your developer account). 5. The instructions to wait 15 minutes are a bit too optimistic, as it can take up to 2 hours for changes to propagate from the Play Console. 6. Double check that the SKU you’re using in the app matches the one for the product that was configured in the Play Console. 7. Double check that you’re not trying to purchase an already owned product or an already active subscription. 8. Double check that you have activated your products in the Play Console: by default, products in the console are deactivated and you need to manually activate them. 9. If you’re using the alpha/beta channels, make sure that the account you’re testing with is part of the testing group (i.e., has clicked on “Become a tester” after following the opt-in URL). 10.If you use ABI flavors, like arm-v7, arm-v8, etc., make sure the APK you’re using for testing contains all the ABI libraries. 11.Make sure that, when retrieving the Intent using getBuyIntent, you’re passing the correct product type, i.e., inapp if you’re purchasing managed in-app products or subs if you’re purchasing subscriptions. 12.If you’re using the public key for enhanced security, make sure it matches the one on the Play Console because it might change over time (see here). 13.Check that Google Play Services are updated on the test device by going to the Google Play Services page on the Play Store.

Slide 30

Slide 30 text

Real purchases http://bit.ly/2EJqoXt

Slide 31

Slide 31 text

Testing setup

Slide 32

Slide 32 text

“Fake” purchases License testers No money circulates Constraints in duration and renewal

Slide 33

Slide 33 text

“Fake” purchases Production subscription period Test subscription renewal 1 week 5 minutes 1 month 5 minutes 3 months 10 minutes 6 months 15 minutes 1 year 30 minutes Max renewals per sub: 6 times

Slide 34

Slide 34 text

NYT’s Register Fake implementation of the billing service Configuration via JSON (+ companion app) Removes existing limitations Allows integration tests to be easily ran

Slide 35

Slide 35 text

NYT’s Register

Slide 36

Slide 36 text

NYT’s Register … not yet compatible with PBL ! PRs welcome "

Slide 37

Slide 37 text

A/B testing price points

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

No platform support Android does not offer support for price chances If done wrong, it’s disastrous for the user Complicated to handle … and yet

Slide 40

Slide 40 text

“There is something we can do”

Slide 41

Slide 41 text

“There is something we can do” Me, a few months ago

Slide 42

Slide 42 text

A/B testing infrastructure Create multiple products in the console Have meaningful product IDs Serve products via a custom configuration

Slide 43

Slide 43 text

A/B $$$ - The good and the meh ✔ Test different price points ✔ Shared configuration across platforms ✔ Shared logic (with tests) ✔ Flexible ✘ (Very) Complicated to achieve ✘ Can be abused (country lock, tests within tests)

Slide 44

Slide 44 text

Monitoring

Slide 45

Slide 45 text

Google Play Console

Slide 46

Slide 46 text

Order management

Slide 47

Slide 47 text

Order management

Slide 48

Slide 48 text

Revenues

Slide 49

Slide 49 text

Monitoring subscriptions How are your subscriptions performing over time? What are your top subscriptions? How do you acquire these subscriptions? How well do you retain these subscriptions? Why did users cancel these subscriptions?

Slide 50

Slide 50 text

Limitations

Slide 51

Slide 51 text

 still has the upper hand All-around control Reliable sandbox environment Better promotion tools

Slide 52

Slide 52 text

Subscriptions ! Promo codes not available No easy way of testing Discounts only with Web API

Slide 53

Slide 53 text

#

Slide 54

Slide 54 text

@rotxed