Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
The Android flavor of The Open Code Project for In App Purchasing.
branch: master

This branch is 456 commits behind soomla:master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
SoomlaAndroidExample
SoomlaAndroidStore
SoomlaAndroidStoreTest
.gitignore
.gitmodules
.travis.yml
CNAME
MIT-LICENSE
README.md
buildstuff.sh

README.md

This project is a part of The SOOMLA Project which is a series of open source initiatives with a joint goal to help mobile game developers get better stores and more in-app purchases.

Haven't you ever wanted an in-app purchase one liner that looks like this ?!

    StoreController.getInstance().buyGoogleMarketItem("[Product id here]");

android-store

Feb 7th, 2013 - We've just released v2.0 of android-store. The major change is a key-value storage (above SQLite) instead of the previous tables. We've also added code that migrates old data and removes the old database (StorageManager.migrateOldData). When you upgrade your code make sure data is transferred from the old database.

The android-store is our first open code initiative as part of The SOOMLA Project. It is a Java API that simplifies Google Play's in-app purchasing API and complements it with storage, security and event handling. The project also includes a sample app for reference.

If you also want to create a storefront you can do that using our Store Designer.

Check out our Wiki for more information about the project and how to use it better.

Getting Started

  1. Clone android-store. Copy all files from android-store/SoomlaAndroidStore subfolders to their equivalent folders in your Android project:

    git clone git@github.com:soomla/android-store.git

  2. Make the following changes to your AndroidManifest.xml:

    Add SoomlaApp as the main Application by placing it in the application tag:

      <application ...
                   android:name="com.soomla.store.SoomlaApp">

    Add the following permission:

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

    Add the following code into your application element:

      <service android:name="com.soomla.billing.BillingService" />
    
      <receiver android:name="com.soomla.billing.BillingReceiver">
          <intent-filter>
              <action android:name="com.android.vending.billing.IN_APP_NOTIFY" />
              <action android:name="com.android.vending.billing.RESPONSE_CODE" />
              <action android:name="com.android.vending.billing.PURCHASE_STATE_CHANGED" />
          </intent-filter>
      </receiver>
  3. Change the value of StoreConfig.SOOM_SEC to a secret of you choice. Do this now! You can't change this value after you publish your game!

  4. Create your own implementation of IStoreAssets in order to describe your specific game's assets (example). Initialize StoreController with the class you just created:

       StoreController.getInstance().initialize(new YourStoreAssetsImplementation(),
                                           "[YOUR PUBLIC KEY FROM GOOGLE PLAY]",
                                           "[YOUR CUSTOM GAME SECRET HERE]");

    The custom secret is your encryption secret for data saved in the DB. This secret is NOT the secret from step 3 (select a different value).

    Initialize StoreController ONLY ONCE when your application loads.

  5. Now that you have StoreController loaded, just decide when you want to show/hide your store's UI to the user and let StoreController know about it:

    When you show the store call:

      StoreController.getInstance().storeOpening([your application context], [a handler you just created]);

    When you hide the store call:

      StoreController.getInstance().storeClosing();

And that's it ! You have storage and in-app purchasing capabilities... ALL-IN-ONE.

What's next? In App Purchasing.

android-store provides you with VirtualCurrencyPacks. VirtualCurrencyPack is a representation of a "bag" of currency units that you want to let your users purchase in Google Play. You define VirtualCurrencyPacks in your game specific assets file which is your implementation of IStoreAssets (example). After you do that you can call StoreController to make actual purchases and android-store will take care of the rest.

Example:

Lets say you have a VirtualCurrencyPack you call TEN_COINS_PACK and a VirtualCurrency you call COIN_CURRENCY:

VirtualCurrencyPack TEN_COINS_PACK = new VirtualCurrencyPack(
        "10 Coins",                // name
        "A pack of 10 coins",      // description
        "10_coins",                // item id
        "com.soomla.ten_coin_pack",// product id in Google Market
        1.99,                      // actual price in $$
        10,                        // number of currency units in the pack
        COIN_CURRENCY);            // the associated currency

Now you can use StoreController to call Google Play's in-app purchasing mechanism:

StoreController.getInstance().buyGoogleMarketItem(TEN_COINS_PACK.getProductId());

And that's it! android-store knows how to contact Google Play for you and redirect the user to the purchasing mechanism. Don't forget to define your IStoreEventHandler in order to get the events of successful or failed purchases (see Event Handling).

Storage & Meta-Data

When you initialize StoreController, it automatically initializes two other classes: StorageManager and StoreInfo. StorageManager is the father of all storage related instances in your game. Use it to access tha balances of virtual currencies and virtual goods (usually, using their itemIds). StoreInfo is the mother of all meta data information about your specific game. It is initialized with your implementation of IStoreAssets and you can use it to retrieve information about your specific game.

The on-device storage is encrypted and kept in a SQLite database. SOOMLA is preparing a cloud-based storage service that will allow this SQLite to be synced to a cloud-based repository that you'll define.

Example Usages

  • Add 10 coins to the virtual currency with itemId "currency_coin":

    VirtualCurrency coin = StoreInfo.getVirtualCurrencyByItemId("currency_coin");
    StorageManager.getVirtualCurrencyStorage().add(coin, 10);
  • Remove 10 virtual goods with itemId "green_hat":

    VirtualGood greenHat = StoreInfo.getVirtualGoodByItemId("green_hat");
    StorageManager.getVirtualGoodsStorage().remove(greenHat, 10);
  • Get the current balance of green hats (virtual goods with itemId "green_hat"):

    VirtualGood greenHat = StoreInfo.getVirtualGoodByItemId("green_hat");
    int greenHatsBalance = StorageManager.getVirtualGoodsStorage().getBalance(greenHat);

Security

If you want to protect your application from 'bad people' (and who doesn't?!), you might want to follow some guidelines:

  • SOOMLA keeps the game's data in an encrypted database. In order to encrypt your data, SOOMLA generates a private key out of several parts of information. The Custom Secret is one of them. SOOMLA recommends that you provide this value when initializing StoreController and before you release your game. BE CAREFUL: You can change this value once! If you try to change it again, old data from the database will become unavailable.
  • Following Google's recommendation, SOOMLA also recommends that you split your public key and construct it on runtime or even use bit manipulation on it in order to hide it. The key itself is not secret information but if someone replaces it, your application might get fake messages that might harm it.

Event Handling

For event handling, we use Square's great open-source project otto. In ordered to be notified of store related events, you can register for specific events and create your game-specific behaviour to handle them.

Your behaviour is an addition to the default behaviour implemented by SOOMLA. You don't replace SOOMLA's behaviour.

In order to register for events:

  1. In the class that should receive the event create a function with the annotation '@Subscribe'. Example:

    @Subscribe public void onMarketPurchase(MarketPurchaseEvent marketPurchaseEvent) {
        ...
    }
  2. You'll also have to register your class in the event bus (and unregister when needed):

    BusProvider.getInstance().register(this);
    BusProvider.getInstance().unregister(this);

If your class is an Activity, register in 'onResume' and unregister in 'onPause'

You can find a full event handler example here.

List of events

Full documentation and explanation of otto

Contribution

We want you!

Fork -> Clone -> Implement -> Test -> Pull-Request. We have great RESPECT for contributors.

SOOMLA, Elsewhere ...

License

MIT License. Copyright (c) 2012 SOOMLA. http://project.soom.la

Something went wrong with that request. Please try again.