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

Post on 16-Apr-2017

129 Views

Category:

Software

4 Downloads

Preview:

Click to see full reader

Transcript

We're an independent design & development agency.

In-app billing

IVAN MARIĆ

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

- STEVE SIEBOLD

GOOGLE PLAY

MONETIZE

Premium - simple and convient

Freemium - durable and consumable digital goods

Subscription - continuing revenue stream

AdMob Ads - easy way to earn revenue

Total revenue by model

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

IMPLEMENTATION

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

Consumable good

SubscriptionDurable good

ADD AIDL FILE

IInAppBillingService.aidl

<sdk>/extras/google/play_billing/

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

IInAppBillingService.java

ANDROID MANIFEST

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

Upload to Alpha/Beta channel

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

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

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

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

Response

GET DETAILS

Information about the item

Localised

Items are immutable

// 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);

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

GET PURCHASES

User owned items

Use for restore

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

BUY INTENT

Get PendingIntent to launch the purchase flow

Purchase flow is handle by Google Play

Response for purchase order received in onActivityResult

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);

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

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

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

TESTING

STATIC TEST

Used for testing response models

Verify signatures

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

android.test.refunded, android.test.item_unavailable

REAL TEST

Setup test accounts in Google Developer Console

Real purchase without money transaction

All subscriptions last one day

Missing orderId property

SECURITY

SIGNED RESPONSES

Verify purchase JSON response

Licence key as public key portion

Best practice to do this on a server side

GOOGLE PLAY DEVELOPER API

Use www.googleapis.com for checking purchase status

Manage subscriptions

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

PROTECT YOUR CONTENT

Do not provide content with .apk

Encrypt content with device specific key

Recoverable data

DOCUMENTATION

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

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

TRAINING

Preparing Your App

Establishing Products for Sale

Purchasing Products

Testing Your App

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

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

Any questions? IVAN.MARIC@INFINUM.CO IVAN MARIĆ

Visit infinum.co or find us on social networks:

infinum.co infinumco infinumco infinum

top related