Uploading Android apps to all the existing Android appstores is a painful process and AppDF project was designed to make it easier. But what is even more difficult for the developers is supporting different in-purchase APIs of different appstores. There are five different In-App Purchase APIs already and this number is increasing. We are going to create an open source library that will wrap appstore in-app purchase APIs of all the stores and provide an easy way for the developers to develop their apps/games in a way that one APK will work in all the stores and automatically use right in-app purchase API under each store. Plus we are going to develop an open in-app billing API that stores could implement to support all the built APK files using this library.
-
Clone the library
git clone https://github.com/onepf/OpenIAB.git
and add /library as a Library Project. Or download the latest released jar from https://github.com/onepf/OpenIAB/releases and attach it to the project. -
Map Google Play SKU ids to Yandex/Amazon/etc SKUs like this: https://github.com/onepf/OpenIAB/blob/master/samples/trivialdrive/src/org/onepf/trivialdrive/MainActivity.java#L109
-
Instantiate
new OpenIabHelper
and callhelper.startSetup()
. When setup is done callhelper.queryInventory()
helper = new OpenIabHelper(this, storeKeys); helper.startSetup(new IabHelper.OnIabSetupFinishedListener() { public void onIabSetupFinished(IabResult result) { if (!result.isSuccess()) { complain("Problem setting up in-app billing: " + result); return; } Log.d(TAG, "Setup successful. Querying inventory."); helper.queryInventoryAsync(mGotInventoryListener); } });
-
Handle the results of
helper.queryInventory()
in an inventory listener and update UI to show what was purchased https://github.com/onepf/OpenIAB/blob/master/samples/trivialdrive/src/org/onepf/trivialdrive/MainActivity.java#L210 -
When the user requests purchase of an item, call
helper.launchPurchaseFlow()
https://github.com/onepf/OpenIAB/blob/master/samples/trivialdrive/src/org/onepf/trivialdrive/MainActivity.java#282 and handle the results with the listener https://github.com/onepf/OpenIAB/blob/master/samples/trivialdrive/src/org/onepf/trivialdrive/MainActivity.java#L384 -
If the user has purchased a consumable item, call
helper.consume()
to exclude it from the inventory. If the item is not consumed, a store supposes it as non-consumable item and doesn't allow to purchase it one more time. Also it will be returned byhelper.queryInventory()
next time https://github.com/onepf/OpenIAB/blob/master/samples/trivialdrive/src/org/onepf/trivialdrive/MainActivity.java#L403 -
Specify keys for different stores like this: https://github.com/onepf/OpenIAB/blob/master/samples/trivialdrive/src/org/onepf/trivialdrive/MainActivity.java#L164
-
Add the required permissions to the AndroidManifest.xml
<!--all stores--> <uses-permission android:name="android.permission.INTERNET"/> <!--Google Play--> <uses-permission android:name="com.android.vending.BILLING" /> <!--Amazon--> <uses-permission android:name="com.sec.android.iap.permission.BILLING" /> <!--Samsung Apps--> <uses-permission android:name="com.sec.android.iap.permission.BILLING" /> <!--Open Store--> <uses-permission android:name="org.onepf.openiab.permission.BILLING" /> <!--T-Store and Fortumo--> <uses-permission android:name="android.permission.RECEIVE_SMS"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!--T-Store--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="com.tmoney.vending.INBILLING" /> <permission android:name="com.tmoney.vending.INBILLING" /> <!--Fortumo--> <uses-permission android:name="android.permission.SEND_SMS" />
-
Edit your proguard config file
# T-Store -keep class com.skplanet.dodo.**{*;} -keep class com.skplanet.internal.dodo.**{*;} -keep class com.skplanet.internal.dodo.dev.**{*;} -keep class com.skplanet.internal.dodo.util.**{*;} -keep class com.skplanet.pmss.secure.**{*;} -keep public class android.net.http.SslError -keep public class android.webkit.WebViewClient -keep class com.tmoney.aidl.**{*;} -dontwarn android.webkit.WebView -dontwarn android.net.http.SslError -dontwarn android.webkit.WebViewClient -keepattributes Signature -dontshrink # AMAZON -dontwarn com.amazon.** -keep class com.amazon.** {*;} -keepattributes *Annotation* -dontoptimize # GOOGLE -keep class com.android.vending.billing.** # SAMSUNG -keep class com.sec.android.iap.**
-
Add the corresponding billing permission
<uses-permission android:name="com.android.vending.BILLING" />>
-
Provide a public key
Map<String, String> storeKeys = new HashMap<String, String>(); storeKeys.put(OpenIabHelper.NAME_GOOGLE, googleBase64EncodedPublicKey); OpenIabHelper.Options options = new OpenIabHelper.Options(); options.storeKeys = storeKeys; mHelper = new OpenIabHelper(this, options); //or mHelper = new OpenIabHelper(this, storeKeys);
otherwise verify purchases on your server side.
-
In the proguard configuration file
# GOOGLE -keep class com.android.vending.billing.**
-
In the AndroidManifest.xml add the corresponding billing permission
<uses-permission android:name="com.sec.android.iap.permission.BILLING" />
and declare the receiver
<receiver android:name="com.amazon.inapp.purchasing.ResponseReceiver"> <intent-filter> <action android:name="com.amazon.inapp.purchasing.NOTIFY" android:permission="com.amazon.inapp.purchasing.Permission.NOTIFY" /> </intent-filter> </receiver>
-
Map the SKUs if required. Remember, the SKUs must be unique across your Amazon developer account.
OpenIabHelper.mapSku(SKU_PREMIUM, OpenIabHelper.NAME_AMAZON, "org.onepf.trivialdrive.amazon.premium"); OpenIabHelper.mapSku(SKU_GAS, OpenIabHelper.NAME_AMAZON, "org.onepf.trivialdrive.amazon.gas"); OpenIabHelper.mapSku(SKU_INFINITE_GAS, OpenIabHelper.NAME_AMAZON, "org.onepf.trivialdrive.amazon.infinite_gas");
-
In the proguard configuration file add
# AMAZON -dontwarn com.amazon.** -keep class com.amazon.** {*;} -keepattributes *Annotation* -dontoptimize
-
Make sure that FortumoInApp-android-9.1.2-o.jar is attached to the project.
-
In the AndroidManifest.xml add the following permissions
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
and declare the Fortumo SDK objects
<!-- Declare these objects, this is part of Fortumo SDK, and should not be called directly --> <receiver android:name="mp.MpSMSReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver> <service android:name="mp.MpService"/> <service android:name="mp.StatusUpdateService"/> <activity android:name="mp.MpActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:configChanges="orientation|keyboardHidden|screenSize"/>
-
In the code setup an Options object
OpenIabHelper.Options options = new OpenIabHelper.Options(); //set supportFortumo flag to true options.supportFortumo = true; //or List<Appstore> storeList = new ArrayList<Appstore>(); storeList.add(new FortumoStore(this)); //by the way, you can add other stores object to the list options.availableStores = storeList; mHelper = new OpenIabHelper(this, options);
-
Add inapps_products.xml (contains data about all in-app products in terms similar to Google Play) and fortumo_inapps_details.xml (contains data about your Fortumo services) files to the assets folder.
XSD for inapps_products.xml https://github.com/onepf/AppDF/blob/xsd-for-inapps/specification/inapp-description.xsd
XSD for fortumo_inapps_details.xml https://github.com/onepf/AppDF/blob/xsd-for-inapps/specification/fortumo-products-description.xsd
You can find the sample here https://github.com/onepf/OpenIAB/tree/master/samples/trivialdrive/assets.
-
In the AndroidManifest.xml add the corresponding billing permission
<uses-permission android:name="com.sec.android.iap.permission.BILLING" />
-
Map the SKUs if required. Remember, Samsung Apps describes an item it terms of Item Group ID and Item ID.
//format "group_id/item_id" OpenIabHelper.mapSku(SKU_PREMIUM, OpenIabHelper.NAME_SAMSUNG, "100000100696/000001003746"); OpenIabHelper.mapSku(SKU_GAS, OpenIabHelper.NAME_SAMSUNG, "100000100696/000001003744"); OpenIabHelper.mapSku(SKU_INFINITE_GAS, OpenIabHelper.NAME_SAMSUNG, "100000100696/000001003747");
-
Instantiate
new OpenIabHelper
using an Activity instance. Activity context is required to callstartActivityForResult()
for SamsungAccount Activity. -
In the proguard configuration add
# SAMSUNG -keep class com.sec.android.iap.**
-
Add the corresponding billing permission
<uses-permission android:name="org.onepf.openiab.permission.BILLING" />
-
Provide a public key
Map<String, String> storeKeys = new HashMap<String, String>(); storeKeys.put(OpenIabHelper.OPEN_STORE_NAME, openStorePublicKey); OpenIabHelper.Options options = new OpenIabHelper.Options(); options.storeKeys = storeKeys; mHelper = new OpenIabHelper(this, options); //or mHelper = new OpenIabHelper(this, storeKeys);
otherwise verify purchases on your server side.
-
Map the SKUs if required
OpenIabHelper.mapSku(SKU_PREMIUM, OpenIabHelper.OPEN_STORE_NAME, "org.onepf.trivialdrive.openstorename.premium"); OpenIabHelper.mapSku(SKU_GAS, OpenIabHelper.OPEN_STORE_NAME, "org.onepf.trivialdrive.openstorename.gas"); OpenIabHelper.mapSku(SKU_INFINITE_GAS, OpenIabHelper.OPEN_STORE_NAME, "org.onepf.trivialdrive.openstorename.infinite_gas");
-
In the AndroidManifest.xml add the following permissions
<uses-permission android:name="android.permission.RECEIVE_SMS"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="com.tmoney.vending.INBILLING" /> <permission android:name="com.tmoney.vending.INBILLING" />
and specify the API version
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <meta-data android:name="iap:api_version" android:value="13"/>
-
Map the SKUs, if required
OpenIabHelper.mapSku(SKU_PREMIUM, OpenIabHelper.NAME_TSTORE, "tstore_sku_premium"); OpenIabHelper.mapSku(SKU_GAS, OpenIabHelper.NAME_TSTORE, "tstore_sku_gas"); OpenIabHelper.mapSku(SKU_INFINITE_GAS, OpenIabHelper.NAME_TSTORE, "tstore_sku_infinite_gas");
-
In the proguard config add
# TStore -keep class com.skplanet.dodo.**{*;} -keep class com.skplanet.internal.dodo.**{*;} -keep class com.skplanet.internal.dodo.dev.**{*;} -keep class com.skplanet.internal.dodo.util.**{*;} -keep class com.skplanet.pmss.secure.**{*;} -keep public class android.net.http.SslError -keep public class android.webkit.WebViewClient -keep class com.tmoney.aidl.**{*;} -dontwarn android.webkit.WebView -dontwarn android.net.http.SslError -dontwarn android.webkit.WebViewClient -keepattributes Signature -dontshrink
There is also Unity engine plugin that will simplify integration for C#/JavaScript developers. No need to write any java code.
- An Android app developer integrates OpenIAB library in his/her Android code
- An Android app developer implements in-app purchases using OpenIAB API (which is very close to Google Play IAB API, just few changes in source code will be needed)
- OpenIAB Lib detects which appstore installed the app
- OpenIAB Lib redirects in-app purchase calls to the corresponding appstore IAB API (OpenIAB Lib wrapps IAB APIs of severall apstores)
- All In-App Billing logic is handled by the corresponding appstore, OpenIAB has no code to process in-app purchases and has no UI, it just wrapps In-App Billing APIs of different stores in one library
We have just started. We are creating a sample game that supports in-app billing of all existing appstores that support in-app purchasing. In the same time, we are designing Open In-App Billing API that appstores can use to easily integrate in-app billing functionality.
- As close to Google Play In-app Billing API as possible - we optimize the OpenIAB library by the following parameter "lines on code you need to change in an app that already works in Google Play to make it working in all the appstores"
- No middle man
- Modular architecture - adding new appstore should be just adding one more class imeplementing a fixed interface
- One APK file to work in all appstores - but OpenIAB should have an option to build separate APK files for appstores for developers who want to create APK without any overhead
- No additional functionality - OpenIAB does not make in-app billing easier to use, we just make it working in all the appstores with single code
OpenIAB is an open source library that wraps the already existing IAB APIs as well as an open API that appstores could implement. It is important to understand that all payments are processes directly by each store and there is no a middle man staying between the app developers and the appstores. OpenIAB will not do payments for the appstores. It is just an API how the apps communicate with appstores to request in-app billing. There is a common open API all the stores can use instead of each new store implement their own API and developers have to integrate all these different APIs in their apps.
The following Android application stores support in-app billing today:
If you know about other Android appstores that support in-app purchasing please let us know.
We are working on integrating their IAB APIs in one OpenIAB library. Here is information about Appstore IAB feature support:
Google Play | Amazon AppStore | Samsung Apps | SK-Telecom T-Store | |
---|---|---|---|---|
Link to IAB API description | Google IAB API | Amazon IAB API | Samsung IAB API | T-Store IAB API |
Processing code | Appstore | Appstore | Lib | Lib |
Subscription | Yes | Yes | No | Yes |
Consumable goods | Yes | Yes | Yes | Yes |
Non-consumable goods | Yes | Yes | No | Yes |
- If you are an Android app developer check the list of open tasks, check if any of these tasks is interesting for you, send a message to OpenIAB mailing list how you want to help. Fork OpenIAB on GitHub.
- If you are an appstore and already support In-App Billing then most probably we are already working on supporting your API in OpenIAB library, and your help is very welcome since you know your API better than anyone else! Just contact us by joining OpenIAB mailing list.
- If you are an appstore and do not support In-App Billing yet but plan to support it then we will be glad working with your on creating a common OpenIAB API and API. Join OpenIAB mailing list to be involved in OpenIAB API development.
Source code of the OpenIAB library and the samples is available under the terms of the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
The OpenIAB API specification and the related texts are available under the terms of the Creative Commons Attribution 2.5 license: http://creativecommons.org/licenses/by/2.5/