Question

I am working on an Android app (implemented with mono/Xamarin) that allows for non-consumable In-App purchases (the user only has to buy the feature once and then they have access to it across all their devices forever). I am trying to use the Xamarin.InAppBilling component to accomplish this.

According to the documentation for the Xamarin.InAppBilling component (http://components.xamarin.com/view/xamarin.inappbilling), these events exist for my use:

Xamarin.InAppBilling defines the following events that you can monitor and respond to:

OnConnected - Raised when the component attaches to Google Play.

OnDisconnected - Raised when the component detaches from Google Play.

OnInAppBillingError - Raised when an error occurs inside the component.

OnProductPurchasedError - Raised when there is an error purchasing a product or subscription. >

OnProductPurchase - Raised when a product is successfully purchased.

OnPurchaseConsumedError - Raised when there is an error consuming a purchase.

OnPurchaseConsumed - Raised when a purchase is successfully consumed.

I see the OnConnected, OnDisconnected, and OnInAppBillingError events defined as part of the Xamarin.InAppBilling.InAppBillingServiceConnection class.

In the assembly browser, I've found the other events defined as part of the Xamarin.InAppBilling.InAppBillingHandler class but I'm not sure the best way to access these as they aren't available via the IInAppBillingHandler interface. It would make sense to access them via the property Xamarin.InAppBilling.InAppBillingServiceConnection.BillingHandler but that property returns an instance cast as IInAppBillingHandler and not the InAppBillingHandler class.

My questions:

Should I expect this code to work as the in-line comments note it should?

// When activity starts...
_serviceConnection = new InAppBillingServiceConnection (CurrentContext, publicKey);
_serviceConnection.OnConnected += () =>
{
     var bh = _serviceConnection.BillingHandler as InAppBillingHandler;
     bh.OnProductPurchased += (sku) => {
        // This code should run when call to BuyProduct is successful
        var purchasedProductId = sku;
     };

     bh.OnProductPurchasedError += (int responseCode, string sku) => {
         // This code should run when call to BuyProduct is NOT successful 
         var p = sku;
         Toast.MakeText(this, "KP - purchase error: " + p, ToastLength.Long).Show();
     };

};


// When "Buy" button is clicked.  Expect OnProductPurchasedError or OnProductPurchased to be called as a result of a call to this
_serviceConnection.BillingHandler.BuyProduct(_selectedProduct);

I did a test by modifying the sample code included with the component by adding my code above and The OnProductPurchasedError event seems to be raised frequently (often right before the Google Play UI says the purchase was successful). I'm not seeing the OnProductPurchased event handler get called even when the Google Play UI indicates a successful transaction. Sometimes this event gets called before the Google Play UI is shown which allows the user to input the form of payment.

My expectation is that the event handler hooked into OnProductPurchased will get called whenever a purchase is successfully completed. However, that does not seem to be happening and I can't find any documentation for these events (other than what I've pasted here). Also, the response code passed to the OnProductPurchasedError event handler is always 0.

As I've done the research to post this question, my current theory is that these events are don't work as I expect and that the documentation is incorrect.

Note: I'm using android.test.purchased as the product ID. I am consuming the purchase before re-testing which I assume resets it to the non-purchased state.

Has anyone successfully utilized these events?

Was it helpful?

Solution

I know this is a bit late to answer, but hopefully it helps someone else!

It seems you might be missing passing back the activity result from your activity to the BillingHandler.

protected override void OnActivityResult (int requestCode, Result resultCode, Intent data)
{
    // Ask the open service connection's billing handler to process this request
    service.BillingHandler.HandleActivityResult (requestCode, resultCode, data);
}

This will cause the BillingHandler to consume the result and fire the appropriate events :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top