SlideShare a Scribd company logo
Testing In App Billing
The easy way
@rharter
Ryan Harter
In App Billing
AIDL
• Copy Google’s IInAppBillingService.aidl
• Connect to Play Store via Service Connection
• Manually manage connection
• Communicate directly with IAB service
IInAppBillingService
Play Billing LibraryServiceConnection
Google Play
Library Code
Your Code
AIDL
MyApp
IInAppBillingService
Play Billing LibraryServiceConnection
Google Play
Library Code
Your Code
AIDL
MyApp
Third Party Libs
Play Billing Library
• Support library
• Wraps AIDL service binding
• Based on abstract BillingClient class
• Now official solution
IInAppBillingService
Play Billing LibraryServiceConnection
Google Play
Library Code
Your Code
AIDL
MyApp
Google Play
Library Code
Your Code
Play Billing Library
IInAppBillingServicePlay Billing Library
MyApp
ServiceConnection
Testing
Testing
Static SKUs
Test Accounts
Testing
Static SKUs
Test Accounts
Static SKUs
android.test.purchased
android.test.canceled
android.test.item_unavailable
Google Play
Library Code
Your Code
IInAppBillingServicePlay Billing Library
MyApp
ServiceConnection
Purchase com.sku.foo
Static SKUs
Google Play
Library Code
Your Code
IInAppBillingServicePlay Billing Library
MyApp
ServiceConnection
com.sku.foo
Static SKUs
Google Play
Library Code
Your Code
IInAppBillingServicePlay Billing Library
MyApp
ServiceConnection
com.sku.foo
android.test.purchased
Static SKUs
Google Play
Library Code
Your Code
IInAppBillingServicePlay Billing Library
MyApp
ServiceConnection
co
android.test.purchased
Static SKUs
Google Play
Library Code
Your Code
IInAppBillingServicePlay Billing Library
MyApp
ServiceConnection
co
android.test.purchased
Static SKUs
Google Play
Library Code
Your Code
IInAppBillingServicePlay Billing Library
MyApp
ServiceConnection
co
android.test.purchased
Success
Static SKUs
Google Play
Library Code
Your Code
IInAppBillingServicePlay Billing Library
MyApp
ServiceConnection
co
android.test.purchased
Success
Static SKUs
Google Play
Library Code
Your Code
IInAppBillingServicePlay Billing Library
MyApp
ServiceConnection
co
android.test.purchased
Success
Static SKUs
Google Play
Library Code
Your Code
Static SKUs
IInAppBillingServicePlay Billing LibraryServiceConnection
co
android.test.purchased
MyApp
Static SKUs - Problems
• No Inventory
• No Subscriptions
• No Consumption
• Not actual code (switcheroo)
Testing
Static SKUs
Test Accounts
Testing
Static SKUs
Test Accounts
Test Accounts
Test the actual purchase flow using real accounts.
Test Accounts
1. Add test user accounts in Google Play Console
Test Accounts
1. Add test user accounts in Google Play Console
2. Deploy your app on Google Play
Test Accounts
1. Add test user accounts in Google Play Console
2. Deploy your app on Google Play
3. Create products in the Google Play Console
Test Accounts
1. Add test user accounts in Google Play Console
2. Deploy your app on Google Play
3. Create products in the Google Play Console
4. Install Release build on a device
Test Accounts
1. Add test user accounts in Google Play Console
2. Deploy your app on Google Play
3. Create products in the Google Play Console
4. Install Release build on a device
5. Make a purchase with a test account
Test Accounts - Problems
• Must know test user accounts in advance
• Purchasable items must be published
• Must run on a device
• Must be signed with release keys
• Can’t manually manage subscription state
Test Accounts - Problems
• Must know test user accounts in advance
• Purchasable items must be published
• Must run on a device
• Must be signed with release keys
• Can’t manually manage subscription state
• Subscription testing is slow
Testing
Static SKUs
Test Accounts
Testing
Static SKUs Test Accounts
Early Development Release
Testing
Static SKUs Test Accounts
Early Development Release
???
???
Goals
• Easy integration with minimal code changes
• No debug code in production
• Allow easy inventory/transaction management
• Seamless user experience
Easily test in app purchases and subscriptions
BillingX
Easily test in app purchases and subscriptions
BillingStoreBillingX
Google Play
Library Code
Your Code
Play Billing Library
IInAppBillingServicePlay Billing Library
MyApp
BillingStoreBillingX
Google Play
Library Code
Your Code
Play Billing Library
IInAppBillingServicePlay Billing Library
MyApp
Release
BillingStore
Google Play
Library Code
Your Code
Play Billing Library
IInAppBillingServicePlay Billing Library
MyApp
BillingX
Debug Release
BillingX
Play Billing Library
BillingClient
BillingX
Play Billing Library
BillingClient
BillingClientImpl
BillingX
Play Billing Library
BillingClient
BillingClientImpl
BillingX
DebugBillingClient
Play Billing Library
BillingClient
BillingX
BillingClientImpl
BillingX
DebugBillingClient
My App
MyActivity
BillingX
class MyActivity : AppCompatActivity() {
private lateinit var billingClient: BillingClient
private val myPurchaseUpdatedListener: PurchasesUpdatedListener // = ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
billingClient = BillingClient
.newBuilder(this)
.setListener(myPurchaseUpdatedListener)
.build()
billingClient.startConnection(object : BillingClientStateListener {
// ...
})
}
}
BillingX
class MyActivity : AppCompatActivity() {
private lateinit var billingClient: BillingClient
private val myPurchaseUpdatedListener: PurchasesUpdatedListener // = ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
billingClient = BillingClient
.newBuilder(this)
.setListener(myPurchaseUpdatedListener)
.build()
billingClient.startConnection(object : BillingClientStateListener {
// ...
})
}
}
class MyActivity : AppCompatActivity() {
private lateinit var billingClient: BillingClient
private val myPurchaseUpdatedListener: PurchasesUpdatedListener // = ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
billingClient = BillingClientFactory
.createBillingClient(this, myPurchaseUpdatedListener)
billingClient.startConnection(object : BillingClientStateListener {
// ...
})
}
}
BillingX
class MyActivity : AppCompatActivity() {
private lateinit var billingClient: BillingClient
private val myPurchaseUpdatedListener: PurchasesUpdatedListener // = ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
billingClient = BillingClientFactory
.createBillingClient(this, myPurchaseUpdatedListener)
billingClient.startConnection(object : BillingClientStateListener {
// ...
})
}
}
BillingX
BillingX
src/release/java/BillingClientFactory.kt
object BillingClientFactory {
fun createBillingClient(activity: Activity,
updateListener: PurchasesUpdatedListener): BillingClient {
return BillingClient
.newBuilder(activity)
.setListener(updateListener)
.build()
}
}
src/debug/java/BillingClientFactory.kt
object BillingClientFactory {
fun createBillingClient(activity: Activity,
updateListener: PurchasesUpdatedListener): BillingClient {
return DebugBillingClient(activity, updateListener)
}
}
BillingX
build.gradle
BillingX
dependencies {
implementation 'com.android.billingclient:billing:1.0'
debugImplementation 'com.pixiteapps.billingx:billingx:0.8.0'
}
build.gradle
BillingX
dependencies {
releaseImplementation 'com.android.billingclient:billing:1.0'
debugImplementation 'com.pixiteapps.billingx:billingx:0.8.0'
}
Goals
• Easy integration with minimal code changes
• No debug code in production
• Allow easy inventory/transaction management
• Seamless user experience
Easily test in app purchases and subscriptions
Goals
✓Easy integration with minimal code changes
• No debug code in production
• Allow easy inventory/transaction management
• Seamless user experience
Easily test in app purchases and subscriptions
Goals
✓Easy integration with minimal code changes
✓No debug code in production
• Allow easy inventory/transaction management
• Seamless user experience
Easily test in app purchases and subscriptions
BillingStore
Google Play
Library Code
Your Code
BillingStore
IInAppBillingServicePlay Billing Library
MyApp
BillingX
Debug Release
BillingStore Google Play
Library Code
Your Code
BillingStore
IInAppBillingServicePlay Billing Library
MyApp
BillingX
Debug Release
BillingStore
interface BillingStore {
fun getSkuDetails(params: SkuDetailsParams): List<SkuDetails>
fun getPurchases(skuType: String): Purchase.PurchasesResult
fun addProduct(skuDetails: SkuDetails): BillingStore
fun removeProduct(sku: String): BillingStore
fun clearProducts(): BillingStore
fun addPurchase(purchase: Purchase): BillingStore
fun removePurchase(sku: String): BillingStore
fun clearPurchases(): BillingStore
}
BillingStore
interface BillingStore {
fun getSkuDetails(params: SkuDetailsParams): List<SkuDetails>
fun getPurchases(skuType: String): Purchase.PurchasesResult
fun addProduct(skuDetails: SkuDetails): BillingStore
fun removeProduct(sku: String): BillingStore
fun clearProducts(): BillingStore
fun addPurchase(purchase: Purchase): BillingStore
fun removePurchase(sku: String): BillingStore
fun clearPurchases(): BillingStore
}
BillingStore
interface BillingStore {
fun getSkuDetails(params: SkuDetailsParams): List<SkuDetails>
fun getPurchases(skuType: String): Purchase.PurchasesResult
fun addProduct(skuDetails: SkuDetails): BillingStore
fun removeProduct(sku: String): BillingStore
fun clearProducts(): BillingStore
fun addPurchase(purchase: Purchase): BillingStore
fun removePurchase(sku: String): BillingStore
fun clearPurchases(): BillingStore
}
BillingStore
interface BillingStore {
fun getSkuDetails(params: SkuDetailsParams): List<SkuDetails>
fun getPurchases(skuType: String): Purchase.PurchasesResult
fun addProduct(skuDetails: SkuDetails): BillingStore
fun removeProduct(sku: String): BillingStore
fun clearProducts(): BillingStore
fun addPurchase(purchase: Purchase): BillingStore
fun removePurchase(sku: String): BillingStore
fun clearPurchases(): BillingStore
}
BillingStore
class BillingClientFactory {
fun createBillingClient(activity: Activity,
updateListener: PurchasesUpdatedListener): BillingClient {
return DebugBillingClient(activity, updateListener)
}
}
BillingStore
class BillingClientFactory {
fun createBillingClient(activity: Activity,
updateListener: PurchasesUpdatedListener): BillingClient {
initializeData(activity)
return DebugBillingClient(activity, updateListener)
}
}
BillingStore
class BillingClientFactory {
fun createBillingClient(activity: Activity,
updateListener: PurchasesUpdatedListener): BillingClient {
initializeData(activity)
return DebugBillingClient(activity, updateListener)
}
private fun initializeData(context: Context) {
}
}
BillingStore
class BillingClientFactory {
fun createBillingClient(activity: Activity,
updateListener: PurchasesUpdatedListener): BillingClient {
initializeData(activity)
return DebugBillingClient(activity, updateListener)
}
private fun initializeData(context: Context) {
runOnce(context, "init_inventory") {
}
}
}
BillingStore
class BillingClientFactory {
fun createBillingClient(activity: Activity,
updateListener: PurchasesUpdatedListener): BillingClient {
initializeData(activity)
return DebugBillingClient(activity, updateListener)
}
private fun initializeData(context: Context) {
runOnce(context, "init_inventory") {
val store = BillingStore.defaultStore(context)
val inventory: List<SkuDetails> = loadInventory(context)
inventory.forEach { store.addProduct(it) }
}
}
}
BillingStore
class BillingClientFactory {
fun createBillingClient(activity: Activity,
updateListener: PurchasesUpdatedListener): BillingClient {
initializeData(activity)
return DebugBillingClient(activity, updateListener)
}
private fun initializeData(context: Context) {
runOnce(context, "init_inventory") {
val store = BillingStore.defaultStore(context)
val inventory: List<SkuDetails> = loadInventory(context)
inventory.forEach { store.addProduct(it) }
}
}
}
Google Play
Library Code
Your Code
BillingStore
IInAppBillingServicePlay Billing Library
MyApp
Debug Release
BillingStoreBillingStoreBillingStore
BillingX
BillingStoreBillingStoreBillingStore Google Play
Library Code
Your Code
BillingStore
IInAppBillingServicePlay Billing Library
MyApp
Debug Release
BillingX
BillingStore
BillingStoreBillingStoreBillingStore
BillingX
BillingStore
BillingStore BillingStore BillingStore
BillingX
BillingStoreSharedPrefsBillingStore BillingStore BillingStore
BillingStore
BillingX
BillingStoreSharedPrefsBillingStore BillingStoreRetrofitBillingStore BillingStore
BillingStore
BillingX
BillingStoreSharedPrefsBillingStore BillingStoreRetrofitBillingStore BillingStoreAmazonBillingStore
BillingStore
BillingX
AmazonBillingStoreRetrofitBillingStoreSharedPrefsBillingStoreBillingStoreBillingStoreBillingStore Google Play
Library Code
Your Code
BillingStore
IInAppBillingServicePlay Billing Library
MyApp
Debug Release
BillingX
Goals
✓Easy integration with minimal code changes
✓No debug code in production
• Allow easy inventory/transaction management
• Seamless user experience
Easily test in app purchases and subscriptions
Goals
✓Easy integration with minimal code changes
✓No debug code in production
✓Allow easy inventory/transaction management
• Seamless user experience
Easily test in app purchases and subscriptions
User Experience
User Experience
User Experience
Goals
✓Easy integration with minimal code changes
✓No debug code in production
✓Allow easy inventory/transaction management
• Seamless user experience
Easily test in app purchases and subscriptions
Goals
✓Easy integration with minimal code changes
✓No debug code in production
✓Allow easy inventory/transaction management
✓Seamless user experience
Easily test in app purchases and subscriptions
Testing In App Billing
The easy way
@rharter
Ryan Harter
https://github.com/pixiteapps/billingx

More Related Content

KEY
In-App Purchase
KEY
Android in-app billing @ Google DevFest Barcelona 2012
PDF
Android In-app Billing @ Droidcon Murcia
KEY
Android In-App Billing @ Droidcon 2011
PPT
[Android] Google Play in app billing
PDF
Infinum Android Talks #18 - In-app billing by Ivan Marić
PDF
App Store Subscriptions - Condensed Edition
KEY
Android In-App Billing @ Barcelona GTUG
In-App Purchase
Android in-app billing @ Google DevFest Barcelona 2012
Android In-app Billing @ Droidcon Murcia
Android In-App Billing @ Droidcon 2011
[Android] Google Play in app billing
Infinum Android Talks #18 - In-app billing by Ivan Marić
App Store Subscriptions - Condensed Edition
Android In-App Billing @ Barcelona GTUG

Similar to Testing In App Billing (20)

PPTX
Monetize your app_with_google_subscriptions_v3_services_intuit
PDF
In App Purchase - Transcript.pdf
PDF
June2013 Meetup : In-App Billing by Soham & Senthil
PDF
Payments in Mobile Apps
PDF
Reverse engineering Java et contournement du mécanisme de paiement inapp Android
PPTX
Mobile payments at Droidcon Eastern Europe
PDF
Mobi: "In-app Payments by Google & Apple"
PDF
Product Teardown - Flobiz - MyBillBook
PDF
In-app purchases for BlackBerry 10
PDF
Present and future of mCommerce in Spain
PDF
Mobile Payment
PDF
Samsung IAP SDK
PPTX
Bootstrapping an App for Launch
PDF
Legal Engineering for Game Point in Mobile App
PDF
Easy Mobile Payments
PDF
Adding power to your Android distribution: Eight app stores or more in 30 min...
PPTX
Windows 8 Camp Ottawa - 2012-04-14 - Introducing the Windows store
PDF
best Mobile App Development Companies in Bangalore.pdf
PDF
Business Utility Application
PDF
InReceipts Plug N Play Client & REST APIs for billing softwares v1.0
Monetize your app_with_google_subscriptions_v3_services_intuit
In App Purchase - Transcript.pdf
June2013 Meetup : In-App Billing by Soham & Senthil
Payments in Mobile Apps
Reverse engineering Java et contournement du mécanisme de paiement inapp Android
Mobile payments at Droidcon Eastern Europe
Mobi: "In-app Payments by Google & Apple"
Product Teardown - Flobiz - MyBillBook
In-app purchases for BlackBerry 10
Present and future of mCommerce in Spain
Mobile Payment
Samsung IAP SDK
Bootstrapping an App for Launch
Legal Engineering for Game Point in Mobile App
Easy Mobile Payments
Adding power to your Android distribution: Eight app stores or more in 30 min...
Windows 8 Camp Ottawa - 2012-04-14 - Introducing the Windows store
best Mobile App Development Companies in Bangalore.pdf
Business Utility Application
InReceipts Plug N Play Client & REST APIs for billing softwares v1.0
Ad

Recently uploaded (20)

PPTX
L1 - Introduction to python Backend.pptx
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PPTX
ai tools demonstartion for schools and inter college
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PPTX
assetexplorer- product-overview - presentation
PDF
System and Network Administraation Chapter 3
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Digital Strategies for Manufacturing Companies
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Designing Intelligence for the Shop Floor.pdf
PPTX
Embracing Complexity in Serverless! GOTO Serverless Bengaluru
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Understanding Forklifts - TECH EHS Solution
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
L1 - Introduction to python Backend.pptx
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
ai tools demonstartion for schools and inter college
Upgrade and Innovation Strategies for SAP ERP Customers
Softaken Excel to vCard Converter Software.pdf
Navsoft: AI-Powered Business Solutions & Custom Software Development
assetexplorer- product-overview - presentation
System and Network Administraation Chapter 3
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
2025 Textile ERP Trends: SAP, Odoo & Oracle
Design an Analysis of Algorithms I-SECS-1021-03
Digital Strategies for Manufacturing Companies
How to Choose the Right IT Partner for Your Business in Malaysia
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Designing Intelligence for the Shop Floor.pdf
Embracing Complexity in Serverless! GOTO Serverless Bengaluru
Design an Analysis of Algorithms II-SECS-1021-03
Understanding Forklifts - TECH EHS Solution
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Ad

Testing In App Billing