Android In-App Billing        Demystified
Agenda• In-App Billing Overview• In-App Billing in Android• Android Market Billing Service• Android Billing Library• Admin...
Freemium
Digital goods
Digital content
Subscriptions
Virtual currency
IAB for the user...• Faster• Simpler• Contextual• “Harmless”• “Inexpensive”
IAB generates  more sales
Agenda• In-App Billing Overview• In-App Billing in Android• Android Market Billing Service• Android Billing Library• Admin...
Options• Android Market In-App Billing• PayPal Mobile Payments Library• Others• Any web payment processor• Custom implemen...
Android Market IAB• Android Market only• 30% of the sale price• Android 1.6 upwards• Only digital goods
PayPal Mobile Payments• Starts at 2.9% of  the sale price +  transaction fee• Android 1.5  upwards• Physical goods  allowed
Others• Paythru• Movend• Open Payments• And a long list of other dubious looking  websites
“All fees received by Developers for Productsdistributed via the Market must be processed by the             Markets Payme...
Agenda• In-App Billing Overview• In-App Billing in Android• Android Market Billing Service• Android Billing Library• Admin...
Pre-requisites• Services• AIDL• BroadcastReceiver• PendingIntent
Overviewapp                      Android  IAB                 Marketrequests                       Server
Messaging sequence
IAB requests• CHECK_BILLING_SUPPORTED• REQUEST_PURCHASE• GET_PURCHASE_INFORMATION• CONFIRM_NOTIFICATIONS• RESTORE_TRANSACT...
IAB requests• MarketBillingService interface defined in an  Android Interface Definition Language file  (IMarketBillingServic...
Binding to          MarketBillingServicetry {  boolean bindResult = mContext.bindService(    new Intent("com.android.vendi...
Request bundle           parameters•   Shared    •   BILLING_REQUEST: request type    •   API_VERSION: 1    •   PACKAGE_NA...
Request bundleprotected Bundle makeRequestBundle(String method) {  Bundle request = new Bundle();  request.putString(BILLI...
Making a requestBundle request = makeRequestBundle("REQUEST_PURCHASE");request.putString(ITEM_ID, mProductId);Bundle respo...
IAB responses• The IAB service responds to every request  with a synchronous response• Followed by 0..N asynchronous respo...
Synchronous responses• RESPONSE_CODE: status information and  error information about a request• REQUEST_ID: used to match...
Asynchronous      responses• Broadcast intents: • RESPONSE_CODE • IN_APP_NOTIFY • PURCHASE_STATE_CHANGED
Receiving async                  responses public void onReceive(Context context, Intent intent) {    String action = inte...
Check Billing Supported
Check Billing               SupportedParameters                      BasicSync response keys        RESPONSE_CODE         ...
Request Purchase
Request Purchase                                BasicParameters                    ITEM_ID                       DEVELOPER...
Get Purchase             Information                                BasicParameters                    NONCE              ...
Purchase State            Changed JSON{ "nonce" : 1836535032137741465,  "orders" :    { "notificationId" : "android.test.p...
Purchase States• Purchased (0)• Canceled (1)• Refunded (2)
Confirm Notifications                               BasicParameters                   NONCE                            NOTIF...
Unsolicited In-App       Notify• Purchase when app is running in  various devices• Refunds
Unsolicited In-App      Notify
Restore Transactions
Restore Transactions                                BasicParameters                              NONCE                    ...
Security Controls• Signed purchase data• In-App Notify Nonces
Purchase State   Changed Extras• inapp_signed_data: Signed JSON  string (unencrypted)• inapp_signature: Use the Android  M...
Agenda• In-App Billing Overview• In-App Billing in Android• Android Market Billing Service• Android Billing Library• Admin...
requestPurchase("com.example.item");
Android Billing Library • https://github.com/robotmedia/   AndroidBillingLibrary • Beta but... • “Better than starting fro...
Features• Full Android IAB Service  implementation• Auto-confirmations• Obfuscated purchases database• Implements security ...
Overview
AndroidManifest.xml    <!-- Add this permission to your manifest -->    <uses-permission android:name="com.android.vending...
Set Configuration	   public void onCreate() {	   	 super.onCreate();	   	 BillingController.setDebug(true);	   	 BillingCon...
Check Billing                Supported   @Override   public void onCreate(Bundle savedInstanceState) {    // ...    Billin...
Request PurchaseBillingController.requestPurchase(this, productId, true /*confirm*/);@Overridepublic void onPurchaseIntent...
Restore Transactionsif (!mBillingObserver.isTransactionsRestored()) {	 BillingController.restoreTransactions(this);	 Toast...
Suggestedimplementation
Agenda• In-App Billing Overview• In-App Billing in Android• Android Market Billing Service• Android Billing Library• Admin...
Purchase type• Managed per user account •   premium, digital content, unique virtual goods• Unmanaged •   subscriptions, v...
Managing In-App   Products
Public key
Reserved product ids•   android.test.purchased•   android.test.canceled•   android.test.refunded•   android.test.item_unav...
Test purchase process
Signed test responsesApplication ever   Draft uploaded &                                        Userbeen published?     un...
Agenda• In-App Billing Overview• In-App Billing in Android• Android Market Billing Service• Android Billing Library• Admin...
Best practices• Random nonces• Obfuscate purchase data• Embedding public key• Code obfuscation• Server-side signature vali...
Gracias!
Android In-App Billing @ Barcelona GTUG
Android In-App Billing @ Barcelona GTUG
Android In-App Billing @ Barcelona GTUG
Android In-App Billing @ Barcelona GTUG
Android In-App Billing @ Barcelona GTUG
Android In-App Billing @ Barcelona GTUG
Próxima SlideShare
Cargando en…5
×

Android In-App Billing @ Barcelona GTUG

3.040 visualizaciones

Publicado el

  • Sé el primero en comentar

Android In-App Billing @ Barcelona GTUG

  1. 1. Android In-App Billing Demystified
  2. 2. Agenda• In-App Billing Overview• In-App Billing in Android• Android Market Billing Service• Android Billing Library• Administering & Testing In-App Billing• Security Best Practices
  3. 3. Freemium
  4. 4. Digital goods
  5. 5. Digital content
  6. 6. Subscriptions
  7. 7. Virtual currency
  8. 8. IAB for the user...• Faster• Simpler• Contextual• “Harmless”• “Inexpensive”
  9. 9. IAB generates more sales
  10. 10. Agenda• In-App Billing Overview• In-App Billing in Android• Android Market Billing Service• Android Billing Library• Administering & Testing In-App Billing• Security Best Practices
  11. 11. Options• Android Market In-App Billing• PayPal Mobile Payments Library• Others• Any web payment processor• Custom implementation
  12. 12. Android Market IAB• Android Market only• 30% of the sale price• Android 1.6 upwards• Only digital goods
  13. 13. PayPal Mobile Payments• Starts at 2.9% of the sale price + transaction fee• Android 1.5 upwards• Physical goods allowed
  14. 14. Others• Paythru• Movend• Open Payments• And a long list of other dubious looking websites
  15. 15. “All fees received by Developers for Productsdistributed via the Market must be processed by the Markets Payment Processor.” http://www.android.com/us/developer-distribution-agreement.html
  16. 16. Agenda• In-App Billing Overview• In-App Billing in Android• Android Market Billing Service• Android Billing Library• Administering In-App Billing• Security Best Practices
  17. 17. Pre-requisites• Services• AIDL• BroadcastReceiver• PendingIntent
  18. 18. Overviewapp Android IAB Marketrequests Server
  19. 19. Messaging sequence
  20. 20. IAB requests• CHECK_BILLING_SUPPORTED• REQUEST_PURCHASE• GET_PURCHASE_INFORMATION• CONFIRM_NOTIFICATIONS• RESTORE_TRANSACTIONS
  21. 21. IAB requests• MarketBillingService interface defined in an Android Interface Definition Language file (IMarketBillingService.aidl)• IAB requests sent by single IPC method (sendBillingRequest()) of the interface• Request type and parameters are sent as a Bundle
  22. 22. Binding to MarketBillingServicetry {  boolean bindResult = mContext.bindService(    new Intent("com.android.vending.billing.MarketBillingService.BIND"), this,    Context.BIND_AUTO_CREATE);  if (bindResult) {    Log.i(TAG, "Service bind successful.");  } else {    Log.e(TAG, "Could not bind to the MarketBillingService.");  }} catch (SecurityException e) {  Log.e(TAG, "Security exception: " + e);}public void onServiceConnected(ComponentName name, IBinder service) {  Log.i(TAG, "MarketBillingService connected.");  mService = IMarketBillingService.Stub.asInterface(service);}
  23. 23. Request bundle parameters• Shared • BILLING_REQUEST: request type • API_VERSION: 1 • PACKAGE_NAME: app package• Specific • ITEM_ID, NONCE, NOTIFY_ID, DEVELOPER_PAYLOAD
  24. 24. Request bundleprotected Bundle makeRequestBundle(String method) {  Bundle request = new Bundle();  request.putString(BILLING_REQUEST, method);  request.putInt(API_VERSION, 1);  request.putString(PACKAGE_NAME, getPackageName());  return request;}
  25. 25. Making a requestBundle request = makeRequestBundle("REQUEST_PURCHASE");request.putString(ITEM_ID, mProductId);Bundle response = mService.sendBillingRequest(request);
  26. 26. IAB responses• The IAB service responds to every request with a synchronous response• Followed by 0..N asynchronous responses depending of the request type
  27. 27. Synchronous responses• RESPONSE_CODE: status information and error information about a request• REQUEST_ID: used to match asynchronous responses with requests• PURCHASE_INTENT: PendingIntent, which you use to launch the checkout activity. REQUEST_PURCHASE only.
  28. 28. Asynchronous responses• Broadcast intents: • RESPONSE_CODE • IN_APP_NOTIFY • PURCHASE_STATE_CHANGED
  29. 29. Receiving async responses public void onReceive(Context context, Intent intent) {    String action = intent.getAction();    if (ACTION_PURCHASE_STATE_CHANGED.equals(action)) {      String signedData = intent.getStringExtra(INAPP_SIGNED_DATA);      String signature = intent.getStringExtra(INAPP_SIGNATURE);      // Do something with the signedData and the signature.    } else if (ACTION_NOTIFY.equals(action)) {      String notifyId = intent.getStringExtra(NOTIFICATION_ID);      // Do something with the notifyId.    } else if (ACTION_RESPONSE_CODE.equals(action)) {      long requestId = intent.getLongExtra(INAPP_REQUEST_ID, -1);      int responseCodeIndex = intent.getIntExtra(INAPP_RESPONSE_CODE,        ResponseCode.RESULT_ERROR.ordinal());      // Do something with the requestId and the responseCodeIndex.    } else {      Log.w(TAG, "unexpected action: " + action);    }  }
  30. 30. Check Billing Supported
  31. 31. Check Billing SupportedParameters BasicSync response keys RESPONSE_CODE RESULT_OK RESULT_BILLING_UNAVAILABLEResponse codes RESULT_ERROR RESULT_DEVELOPER_ERRORAsync response RESPONSE_CODE
  32. 32. Request Purchase
  33. 33. Request Purchase BasicParameters ITEM_ID DEVELOPER_PAYLOAD RESPONSE_CODESync response keys PURCHASE_INTENT REQUEST_ID RESULT_OKResponse codes RESULT_ERROR RESULT_DEVELOPER_ERROR RESPONSE_CODEAsync response IN_APP_NOTIFY
  34. 34. Get Purchase Information BasicParameters NONCE NOTIFY_IDS RESPONSE_CODESync response keys REQUEST_ID RESULT_OKResponse codes RESULT_ERROR RESULT_DEVELOPER_ERROR RESPONSE_CODEAsync response PURCHASE_STATE_CHANGED
  35. 35. Purchase State Changed JSON{ "nonce" : 1836535032137741465, "orders" : { "notificationId" : "android.test.purchased", "orderId" : "transactionId.android.test.purchased", "packageName" : "com.example.dungeons", "productId" : "android.test.purchased", "developerPayload" : "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQ", "purchaseTime" : 1290114783411, "purchaseState" : 0 }}
  36. 36. Purchase States• Purchased (0)• Canceled (1)• Refunded (2)
  37. 37. Confirm Notifications BasicParameters NONCE NOTIFY_IDS RESPONSE_CODESync response keys REQUEST_ID RESULT_OKResponse codes RESULT_ERROR RESULT_DEVELOPER_ERRORAsync response RESPONSE_CODE
  38. 38. Unsolicited In-App Notify• Purchase when app is running in various devices• Refunds
  39. 39. Unsolicited In-App Notify
  40. 40. Restore Transactions
  41. 41. Restore Transactions BasicParameters NONCE RESPONSE_CODESync response keys REQUEST_ID RESULT_OKResponse codes RESULT_ERROR RESULT_DEVELOPER_ERROR RESPONSE_CODEAsync response PURCHASE_STATE_CHANGED
  42. 42. Security Controls• Signed purchase data• In-App Notify Nonces
  43. 43. Purchase State Changed Extras• inapp_signed_data: Signed JSON string (unencrypted)• inapp_signature: Use the Android Market public key to validate
  44. 44. Agenda• In-App Billing Overview• In-App Billing in Android• Android Market Billing Service• Android Billing Library• Administering & Testing In-App Billing• Security Best Practices
  45. 45. requestPurchase("com.example.item");
  46. 46. Android Billing Library • https://github.com/robotmedia/ AndroidBillingLibrary • Beta but... • “Better than starting from scratch”
  47. 47. Features• Full Android IAB Service implementation• Auto-confirmations• Obfuscated purchases database• Implements security best-practices• Half-decent unit testing coverage
  48. 48. Overview
  49. 49. AndroidManifest.xml <!-- Add this permission to your manifest --> <uses-permission android:name="com.android.vending.BILLING" /> <application> <!-- Add this service and receiver to your application --> <service android:name="net.robotmedia.billing.BillingService" /> <receiver android:name="net.robotmedia.billing.BillingReceiver"> <intent-filter> <action android:name="com.android.vending.billing.IN_APP_NOTIFY" /> <action android:name="com.android.vending.billing.RESPONSE_CODE" /> <actionandroid:name="com.android.vending.billing.PURCHASE_STATE_CHANGED" /> </intent-filter> </receiver> </application>
  50. 50. Set Configuration public void onCreate() { super.onCreate(); BillingController.setDebug(true); BillingController.setConfiguration(new BillingController.IConfiguration() { @Override public byte[] getObfuscationSalt() { return new byte[] {41, -90, -116, -41, 66, -53, 122, -110, -127, -96, -88, 77, 127 } @Override public String getPublicKey() { return "your public key here"; } }); }
  51. 51. Check Billing Supported @Override public void onCreate(Bundle savedInstanceState) { // ... BillingController.registerObserver(mBillingObserver); BillingController.checkBillingSupported(this); // ... } public void onBillingChecked(boolean supported) { if (!supported) { showDialog(DIALOG_BILLING_NOT_SUPPORTED_ID); } }
  52. 52. Request PurchaseBillingController.requestPurchase(this, productId, true /*confirm*/);@Overridepublic void onPurchaseIntent(String itemId, PendingIntent purchaseIntent) { BillingController.startPurchaseIntent(activity, purchaseIntent, null);}@Overridepublic void onRequestPurchaseResponse(String itemId, ResponseCode response) {}@Overridepublic void onPurchaseStateChanged(String itemId, PurchaseState state) {}
  53. 53. Restore Transactionsif (!mBillingObserver.isTransactionsRestored()) { BillingController.restoreTransactions(this); Toast.makeText(this, R.string.restoring_transactions,Toast.LENGTH_LONG).show();}@Overridepublic void onTransactionsRestored() { final SharedPreferences preferences =PreferenceManager.getDefaultSharedPreferences(activity); final Editor editor = preferences.edit(); editor.putBoolean(KEY_TRANSACTIONS_RESTORED, true); editor.commit();}
  54. 54. Suggestedimplementation
  55. 55. Agenda• In-App Billing Overview• In-App Billing in Android• Android Market Billing Service• Android Billing Library• Administering & Testing In-App Billing• Security Best Practices
  56. 56. Purchase type• Managed per user account • premium, digital content, unique virtual goods• Unmanaged • subscriptions, virtual currency, unlimited virtual goods
  57. 57. Managing In-App Products
  58. 58. Public key
  59. 59. Reserved product ids• android.test.purchased• android.test.canceled• android.test.refunded• android.test.item_unavailable
  60. 60. Test purchase process
  61. 61. Signed test responsesApplication ever Draft uploaded & Userbeen published? unpublished? * * Developer Yes No Test user Yes Yes *
  62. 62. Agenda• In-App Billing Overview• In-App Billing in Android• Android Market Billing Service• Android Billing Library• Administering & Testing In-App Billing• Security Best Practices
  63. 63. Best practices• Random nonces• Obfuscate purchase data• Embedding public key• Code obfuscation• Server-side signature validation
  64. 64. Gracias!

×