SDK

Implementation

With the Notificare's Monetize add-on you can easily sell virtual goods in Google Play. Our library will provide you all the mechanisms to quickly develop an engaging in-app store experience where you can sell digital products.

Please note that be able to test your products, you will need to upload at least an **Alpha** build of your app to Google Play. Please read [this guide](https://developer.android.com/google/play/billing/billing_testing.html) to learn how to test products in a sandbox environment.

To be able to use In-App Billing in your application, make you sure you add the following dependency to your app/build.gradle:

dependencies {
    implementation 're.notifica:notificare-billing:2.7.0' // make sure you always use the latest version
}

You will enable this feature in your app by invoking the following method from your Intent Receiver:

public class MyIntentReceiver extends DefaultIntentReceiver {

    @Override
    public void onReady() {

        //... more code
        Notificare.shared().enableBilling();

        //... more code
    }
    //... more code
}
class MyIntentReceiver: DefaultIntentReceiver() {
    override fun onReady() {

        //... more code
        Notificare.shared().enableBilling()

        //... more code
    }
    //... more code
}

After this point, our library will automatically load any products you've previously created.

To actually display them to the user in an activity or fragment you will need to implement the following:

public class ProductsActivity extends BaseActivity implements Notificare.OnBillingReadyListener, BillingManager.OnRefreshFinishedListener, BillingManager.OnPurchaseFinishedListener {

    //...more code

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      if (Notificare.shared().getBillingManager().handleActivityResult(requestCode, resultCode, data)) {
        // Billingmanager handled the result
        inProgress = true; // wait for purchase to finish before doing other calls
      }
    }
    @Override
    protected void onResume() {
      super.onResume();
      Notificare.shared().addBillingReadyListener(this);
    }
    @Override
    protected void onPause() {
      super.onPause();
      Notificare.shared().removeBillingReadyListener(this);
    }
    @Override
    public void onBillingReady() {
      if (!inProgress) {
        productListAdapter.clear();
        Notificare.shared().getBillingManager().refresh(this);
      }
    }
    @Override
    public void onPurchaseFinished(BillingResult billingResult, Purchase purchase) {
      inProgress = false;
      productListAdapter.clear();
      Notificare.shared().getBillingManager().refresh(this);
    }
    @Override
    public void onRefreshFinished() {
      productListAdapter.addAll(Notificare.shared().getBillingManager().getProducts());
    }
    @Override
    public void onRefreshFailed(NotificareError notificareError) {
      Toast.makeText(this, "billing refresh failed: " + notificareError.getMessage(), Toast.LENGTH_LONG).show();
    }

    //...more code
}
class ProductsActivity : BaseActivity(), OnBillingReadyListener, OnRefreshFinishedListener, OnPurchaseFinishedListener {

    //...more code

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (Notificare.shared().billingManager.handleActivityResult(requestCode, resultCode, data)) {
            // Billingmanager handled the result
            inProgress = true // wait for purchase to finish before doing other calls
        }
    }

    override fun onResume() {
        super.onResume()
        Notificare.shared().addBillingReadyListener(this)
    }

    override fun onPause() {
        super.onPause()
        Notificare.shared().removeBillingReadyListener(this)
    }

    override fun onBillingReady() {
        if (!inProgress) {
            productListAdapter.clear()
            Notificare.shared().billingManager.refresh(this)
        }
    }

    override fun onPurchaseFinished(billingResult: BillingResult?, purchase: Purchase?) {
        inProgress = false
        productListAdapter.clear()
        Notificare.shared().billingManager.refresh(this)
    }

    override fun onRefreshFinished() {
        productListAdapter.addAll(Notificare.shared().billingManager.products)
    }

    override fun onRefreshFailed(notificareError: NotificareError) {
        Toast.makeText(this, "billing refresh failed: " + notificareError.message, Toast.LENGTH_LONG).show()
    } 
    
    //...more code
}

In the code above, we are assuming that you will be consuming the products loaded in a ListView but you can basically present your products in any other way you may see fit.

To actually handle the purchase flow of one of your products, make sure you implement some like this:

//...more code

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_products);

    //...more code

    listView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            NotificareProduct item = productListAdapter.getItem(position);
            Notificare.shared().getBillingManager().launchPurchaseFlow(ProductsActivity.this, item, ProductsActivity.this);
        }
    });

    //...more code
}

//...more code
//...more code

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_products)

    //...more code

    listView.onItemClickListener =
        OnItemClickListener { parent: AdapterView<*>?, view: View?, position: Int, id: Long ->
            val item: NotificareProduct = productListAdapter.getItem(position)
            Notificare.shared().billingManager.launchPurchaseFlow(this, item, this)
        }

    //...more code
}

//...more code

This will be all you need to allow your user to buy any of your products.