Infinum Android Talks #18 - In-app billing by Ivan Marić

41
We're an independent design & development agency.

Transcript of Infinum Android Talks #18 - In-app billing by Ivan Marić

Page 1: Infinum Android Talks #18 - In-app billing by Ivan Marić

We're an independent design & development agency.

Page 2: Infinum Android Talks #18 - In-app billing by Ivan Marić

In-app billing

IVAN MARIĆ

Page 3: Infinum Android Talks #18 - In-app billing by Ivan Marić

Average people earn money doing things they don’t like. Rich people follow their passion.

- STEVE SIEBOLD

Page 4: Infinum Android Talks #18 - In-app billing by Ivan Marić

GOOGLE PLAY

Page 5: Infinum Android Talks #18 - In-app billing by Ivan Marić

MONETIZE

Premium - simple and convient

Freemium - durable and consumable digital goods

Subscription - continuing revenue stream

AdMob Ads - easy way to earn revenue

Page 6: Infinum Android Talks #18 - In-app billing by Ivan Marić

Total revenue by model

Page 7: Infinum Android Talks #18 - In-app billing by Ivan Marić

https://support.google.com/googleplay/android-developer/table/3539140?hl=en&rd=1

MERCHANT ACCOUNT

Google Play Developer Console - Financial reports

Not supported in all countries

Page 8: Infinum Android Talks #18 - In-app billing by Ivan Marić

IMPLEMENTATION

Page 9: Infinum Android Talks #18 - In-app billing by Ivan Marić

Sample project https://github.com/googlesamples/android-play-billing

Consumable good

SubscriptionDurable good

Page 10: Infinum Android Talks #18 - In-app billing by Ivan Marić

ADD AIDL FILE

IInAppBillingService.aidl

<sdk>/extras/google/play_billing/

src/main/aidl/com.android.vending.billing

IInAppBillingService.java

Page 11: Infinum Android Talks #18 - In-app billing by Ivan Marić

ANDROID MANIFEST

<uses-permission android:name="com.android.vending.BILLING" />

Upload to Alpha/Beta channel

Page 12: Infinum Android Talks #18 - In-app billing by Ivan Marić

Intent serviceIntent = new Intent( “com.android.vending.billing.InAppBillingService.BIND"); serviceIntent.setPackage(“com.android.vending”); context.bindService(serviceIntent,

serviceConnection, Context.BIND_AUTO_CREATE);

context.unbindService(serviceConnection);

Service connection

Page 13: Infinum Android Talks #18 - In-app billing by Ivan Marić

private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { billingService = IInAppBillingService.Stub.asInterface(service); int r = billingService.isBillingSupported(3, packageName, itemType); if (r == 0) { // Billing supported return; } }};

Service connection

Page 14: Infinum Android Talks #18 - In-app billing by Ivan Marić

private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { billingService = IInAppBillingService.Stub.asInterface(service); int r = billingService.isBillingSupported(3, packageName, "inapp"); if (r == 0) { // Billing supported return; } }};

Service connection

Page 15: Infinum Android Talks #18 - In-app billing by Ivan Marić

private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { billingService = IInAppBillingService.Stub.asInterface(service); int r = billingService.isBillingSupported(5, packageName, "subs"); if (r == 0) { // Billing supported return; } }};

Service connection

Page 16: Infinum Android Talks #18 - In-app billing by Ivan Marić

Response

Page 17: Infinum Android Talks #18 - In-app billing by Ivan Marić

GET DETAILS

Information about the item

Localised

Items are immutable

Page 18: Infinum Android Talks #18 - In-app billing by Ivan Marić

// Split the sku list in blocks of no more than 20 elements. Bundle querySkus = new Bundle(); querySkus.putStringArrayList("ITEM_ID_LIST", skuPartList);

Bundle skuDetails = billingService.getSkuDetails( 3, packageName, itemType, querySkus);

Page 19: Infinum Android Talks #18 - In-app billing by Ivan Marić

Bundle skuDetails = billingService.getSkuDetails( 3, packageName, itemType, querySkus);

Page 20: Infinum Android Talks #18 - In-app billing by Ivan Marić

GET PURCHASES

User owned items

Use for restore

Page 21: Infinum Android Talks #18 - In-app billing by Ivan Marić

Bundle ownedItems = billingService.getPurchases( 3, packageName, itemType, continueToken);

Page 22: Infinum Android Talks #18 - In-app billing by Ivan Marić

BUY INTENT

Get PendingIntent to launch the purchase flow

Purchase flow is handle by Google Play

Response for purchase order received in onActivityResult

Page 23: Infinum Android Talks #18 - In-app billing by Ivan Marić

Bundle buyIntent = billingService.getBuyIntent( 3, packageName, sku, itemType, payload);

PendingIntent intent = buyIntent.getParcelable("BUY_INTENT"); activity.startIntentSenderForResult(intent.getIntentSender(), requestCode, new Intent(), 0, 0, 0);

Page 24: Infinum Android Talks #18 - In-app billing by Ivan Marić

Bundle buyIntent = billingService.getBuyIntentToReplaceSkus( 5, packageName, oldSku, sku, "subs", payload);

PendingIntent intent = buyIntent.getParcelable("BUY_INTENT"); activity.startIntentSenderForResult(intent.getIntentSender(), requestCode, new Intent(), 0, 0, 0);

Subscription upgrade/downgrade

Page 25: Infinum Android Talks #18 - In-app billing by Ivan Marić
Page 26: Infinum Android Talks #18 - In-app billing by Ivan Marić

CONSUME ITEM

Purchased item is owned by the user forever

Can not purchase an item more than once

Remove item from the owner to purchase again

Page 27: Infinum Android Talks #18 - In-app billing by Ivan Marić

// Don’t call this on UI thread billingService.consumePurchase(3, packageName, token);

Page 28: Infinum Android Talks #18 - In-app billing by Ivan Marić

TESTING

Page 29: Infinum Android Talks #18 - In-app billing by Ivan Marić

STATIC TEST

Used for testing response models

Verify signatures

android.test.purchased, android.test.canceled,

android.test.refunded, android.test.item_unavailable

Page 30: Infinum Android Talks #18 - In-app billing by Ivan Marić

REAL TEST

Setup test accounts in Google Developer Console

Real purchase without money transaction

All subscriptions last one day

Missing orderId property

Page 31: Infinum Android Talks #18 - In-app billing by Ivan Marić

SECURITY

Page 32: Infinum Android Talks #18 - In-app billing by Ivan Marić

SIGNED RESPONSES

Verify purchase JSON response

Licence key as public key portion

Best practice to do this on a server side

Page 33: Infinum Android Talks #18 - In-app billing by Ivan Marić

GOOGLE PLAY DEVELOPER API

Use www.googleapis.com for checking purchase status

Manage subscriptions

Page 34: Infinum Android Talks #18 - In-app billing by Ivan Marić

https://www.reddit.com/r/Piracy/comments/3eo8sj/antipiracy_measures_on_android_custom_roms/

HACKER APPS

Rooted devices

Change the behaviour of the system and apps

Page 35: Infinum Android Talks #18 - In-app billing by Ivan Marić

PROTECT YOUR CONTENT

Do not provide content with .apk

Encrypt content with device specific key

Recoverable data

Page 36: Infinum Android Talks #18 - In-app billing by Ivan Marić

DOCUMENTATION

Page 37: Infinum Android Talks #18 - In-app billing by Ivan Marić

http://developer.android.com/google/play/billing/index.html

GOOGLE SERVICE

Overview

Version 3 API

Security and Design

Testing In-app Billing

Administering In-app Billing

Page 38: Infinum Android Talks #18 - In-app billing by Ivan Marić

http://developer.android.com/training/in-app-billing/index.html

TRAINING

Preparing Your App

Establishing Products for Sale

Purchasing Products

Testing Your App

Page 39: Infinum Android Talks #18 - In-app billing by Ivan Marić

WATCH OUT FOR

Developer payload

Calling consume request on Main thread

Subscription downgrade/upgrade (v3 / v5)

AIDL file (https://github.com/googlesamples/android-play-billing/issues/3)

Limitations http://stackoverflow.com/questions/13717091/android-error-while-

retrieving-information-from-server-rpcs-5aec-0-in-google

Page 40: Infinum Android Talks #18 - In-app billing by Ivan Marić

HTTP://BLOG.GOFORYT.COM/VALIDATING-ANDROID-APP-PURCHASES-LARAVEL/

Page 41: Infinum Android Talks #18 - In-app billing by Ivan Marić

Any questions? [email protected] IVAN MARIĆ

Visit infinum.co or find us on social networks:

infinum.co infinumco infinumco infinum