Library for in-app purchases (Android In-App Billing v.3)


    Checkout (“cash desk”, “cash register”) is a library for making in-app purchases based on Android In-App Billing v.3 . The main goal is to reduce the developer’s time spent on introducing payments into Android applications. The project was inspired by the Volley library , and was designed to be as easy to use, fast and flexible as possible.


    ▌Preparation


    There are several ways to connect a library to a project:
    • Download the source code from the github repository and copy it to your project
    • For Maven users, use the following dependency:
      org.solovyev.androidcheckoutx.x.x
    • For Gradle users, use the following dependency:
      compile 'org.solovyev.android:checkout:x.x.x@aar'
      
    • Download the desired archive from the repository


    The library requires com.android.vending.BILLINGpermission.
    If you connected the library as a dependency (for example, in Maven or Gradle), then nothing else needs to be done. Otherwise, add the following line to AndroidManifest.xml:


    ▌Use


    The library contains 3 main classes: Billing , Checkout and Inventory .

    The class Billingprocesses purchase requests (see IInAppBillingService.aidl methods ) and controls the connection to the Google Play service. This class is best used as a singleton, so that all requests are lined up in the same queue and use the same cache. For example, an application class might look like this:

    public class MyApplication extends Application {
        /**
         * For better performance billing class should be used as singleton
         */
        @Nonnull
        private final Billing billing = new Billing(this, new Billing.Configuration() {
            @Nonnull
            @Override
            public String getPublicKey() {
                return "Your public key, don't forget to encrypt it somehow";
            }
            @Nullable
            @Override
            public Cache getCache() {
                return Billing.newCache();
            }
        });
        /**
         * Application wide {@link org.solovyev.android.checkout.Checkout} instance (can be used anywhere in the app).
         * This instance contains all available products in the app.
         */
        @Nonnull
        private final Checkout checkout = Checkout.forApplication(billing, Products.create().add(IN_APP, asList("product")));
        @Nonnull
        private static MyApplication instance;
        public MyApplication() {
            instance = this;
        }
        @Override
        public void onCreate() {
            super.onCreate();
            billing.connect();
        }
        public static MyApplication get() {
            return instance;
        }
        @Nonnull
        public Checkout getCheckout() {
            return checkout;
        }
        //...
    }
    

    A class Billingcan be used to execute queries directly, but more often it is more convenient to use an intermediary - a class Checkout. The latter adds to each request a tag by which the request can be canceled, which can be useful, for example, in Activity. Checkoutallows you to download the current state of purchases through the method Checkout#loadInventory(). Also Checkout, or rather its heir ActivityCheckout, provides access to PurchaseFlow, which in turn carries out the actions necessary for the purchase. The class code Activity, which displays the shopping list, and which allows you to make purchases, is presented below:

    public class MyActivity extends Activity {
        @Nonnull
        private final ActivityCheckout checkout = Checkout.forActivity(this, MyApplication.get().getCheckout());
        @Nonnull
        private Inventory inventory;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            checkout.start();
            // you only need this if this activity starts purchase process
            checkout.createPurchaseFlow(new PurchaseListener());
            // you only need this if this activity needs information about purchases/SKUs
            inventory = checkout.loadInventory();
            inventory.whenLoaded(new InventoryLoadedListener())
        }
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            checkout.onActivityResult(requestCode, resultCode, data);
        }
        @Override
        protected void onDestroy() {
            checkout.stop();
            super.onDestroy();
        }
        //...
    }
    


    ▌ Source code, examples


    The source code is available in my github repository . There you will find the source code of the test application (the application itself can be installed from Google Play ). Everything is licensed under the Apache License, Version 2.0 .

    ▌ Conclusion


    The library has something to work on (for example, there is not enough test coverage, and it would be nice to have a migration procedure from one popular library ). But in general, she can already be used in production, which I do in my Say it right application ! .
    Questions and suggestions are welcome in the comments to the article, as well as in the bug tracker on the github.

    UPD There is a test application for the library on Google Play. In order to make test payments you need to join this Google+ group.

    Also popular now: