IAP Badger: a unified approach to in-app purchases

I’ve had a quick look and:

  • according to the docs, the Google IAP v3 store.purchase() function does not support subscriptions.
  • I can’t find anything specific in the docs about how Corona supports subscriptions on iOS (does anyone know more about this and can point me in the right direction???)

As IAP Badger is designed to be cross platform, across both Google/Apple/Amazon, I’d be kind of reluctant to add a feature that only applies to iOS devices to the main branch and plug-in for IAP Badger.

However, the beauty of Github (and the open-license IAP Badger is provided with) is that anyone can fork the code and add improvements of their own - and these improvements can always be re-introduced to the main branch  :slight_smile:

Simon

Thank you for your attention sir. :smiley:

For now I just develop in Android sir, and afaik that google iap is support subscription system, and idk how to do with subscription. I attach the screenshot in this post.

I don’t know much about android development. I just found corona is easier and I want to develop with corona for my android apps.

Please correct me if I’m wrong…

Thank you :slight_smile:

Azhar

Hi Azhar,

The problem isn’t with setting up a subscription in Google Play console - that definitely is possible - it’s whether Corona SDK then supports that functionality in your app.   If you check out the Gotcha’s section of this page, you’ll see that it explicitly says that Corona doesn’t currently support IAP subscriptions through Google Play.

And interestingly, although Corona doesn’t say subscriptions aren’t supported on iOS, I haven’t found anything specific about how to work with them either (such as how to check subscription dates).   If you look at the event.transaction description on this page (which explains the kind of information you get back from iTunes), although you get some information back about the date the transaction was made, there is no information about subscription expiration dates etc.

If anyone knows different, I’m happy to take a look at this.  I did leave a hook in the system to support subscriptions (though I never developed it further, because my own apps didn’t require it).

Simon :slight_smile:

PS - if anyone’s got any subscription code for iOS/Google/Amazon they’re willing to share, I’m also happy to take a look at that too (as long as it doesn’t involve running your own database on a webserver - which is a bit beyond the scope of IAP Badger).

Hello happymongoose,

I love the plugin so far, however I feel like I’m missing a step somewhere.

I’ve submitted my app along with the first in-app purchase for review on iTunes but my app got rejected because IAP Badger is showing purchase failed during purchase. Which of course it should, since the in-app purchase isn’t live yet because it has just been submitted for review along with the app.

How do I get past this step? IAP and app won’t get accepted because IAP is failing due to the IAP not being live yet.


Edit: Whoops, nevermind. This is an non-issue. Took a while but finally found out that the problem “Cannot connect to iTunes store” was caused by not having filled out the paid application agreement yet.

Hi everyone,

I’ve just posted an update to the Github version of IAP Badger.

The latest change will further simplify your code if you manually save purchase information.

You now don’t need to pass an inventory table at all, or give the  init function a filename or salt (as they won’t be used).  Neither do you have to pass a  onPurchase or  onRefund function in your product catalogue.

This reduces the minimal code for processing an in app purchase to:

--Load IAP Badger local iap = require("iap\_badger") --Create the catalogue local catalogue = {     --Information about the product on the app stores     products = {             --removeAds is the product identifier.         removeAds = {                 --A list of product names or identifiers specific to apple's App Store or Google Play.                 productNames = { apple="remove\_ads", google="REMOVE\_BANNER", amazon="Banner\_Remove"},                 --The product type                 productType = "non-consumable"         }     } } --This table contains all of the options we need to specify in this example program. local iapOptions = { catalogue=catalogue } --Initialise IAP badger iap.init(iapOptions) --Called when the relevant app store has completed the purchase --Make a record of the purchase using whatever method you like local function purchaseListener(product )     print "Purchase made" end iap.purchase("removeAds", purchaseListener)

The above code will correctly handle an IAP for a product called “removeAds” across iOS, Google Play and Amazon.

Obviously, if you take this route, it’s your responsibility to then store a reference to that purchase somewhere - but from the examples people have posted on the forums, I think that’s what lots of people do anyway.

Hopefully, this will also help people new to IAP get their head around what’s going on.

Let me know if you encounter any issues - if I haven’t heard of any problems within a couple of weeks, I’ll update the plug-in as well.

Simon :slight_smile:

No one has reported any issues, so the plug-in version of IAP Badger has now been updated and should be hitting a Corona server near you soon.

This means that if you don’t want/need IAP Badger to save records of your in-app purchases, you don’t have to - simplifying your code.  I’ve also updated the docs at http://happymongoose.co.uk/iapbadger.php to explain this (although I haven’t updated the tutorial).

Regards,

Simon

@happymongoose,

This has got to the #1 most used library/module.  I know I really appreciate you having written and shared this, plus all the maintenance.

Thanks!

Thanks roaminggamer!

I’m happy to see my code out in the world helping people :slight_smile:

The real irony here is - I’m no longer developing apps (I couldn’t make it financially viable, though I do still have apps out on the app store etc.)  IAP Badger was my swan song, really - I wanted to give something back to the community.

Simon 

So what do you do Simon?

Thank you for the library.

I am also considering moving totally to apps (not games), because games has become true lottery and Big guys playground.

I now run a behaviour consultancy service for primary schools (supporting kids who have behaviour issues, teachers with classroom management, that sort of thing).  We also have a website where we’re starting to offer digital products (some free, some paid) that’s growing in popularity, so I still have links to the programming side.

[It may sound like an odd transition - but I originally started as a programmer, moved to primary school teaching, then jumped back into coding for a while].

Having spent some time over the last twelve months learning about promoting digital learning products through the web, with hindsight, I think I should have spent 50% of my time on the coding, and 50% on copywriting and promotion.  If no one knows about your app, no one’s going to download it.  I should have taken more active steps to increase discoverability than relying on SEO, ASO etc.

You live and learn  :slight_smile:

Simon

These days I think without Apple feature + a great game one has no chance getting more than few thousand installs.

Especially developers outside US, GB, Australia…

Good luck and thanks!

Good luck too Ivan!

Not quite sure why but I am having issue doing restore for Android. The app simply hangs. Purchase works fine. For iOS, both restore and purchase work fine. Any advice?

Hi there,

There could be a couple of things going on here.

After receiving the  iap.restore call, IAP Badger asks Google Play, “is there anything to restore for this user?”  If there isn’t, Google Play just doesn’t reply.  Silence.  Nothing.  Not even a shake of the head.

If you’re using the example code from the website (with the spinner etc.), then your app will wait until a given timeout period, after which it will assume that no message is coming and give up.  At this point, IAP Badger calls the timeout listener specified in **iap.restore() **to say, “there’s nothing to restore here.”

(If you don’t specify a listener, it will default to a text box telling the user the process failed.)

The second thing to bear in mind is that Google Play will only tell you about any non-consumable products that should be restored (eg. remove ads, unlock game).  Their servers won’t tell you about any consumables the user has purchased (eg. extra coins).

So what may be going on is, if your app doesn’t have any non-consumable products to restore, the app is sitting there waiting for a message that is never going to come from Google Play.

A quick way to check this is to lower the amount of time IAP Badger waits for a message for debugging purposes.  This is the cancelTime parameter you pass to iap.restore()  (see this page).  Reduce it to three or four seconds for testing purposes and see what messages you get.  (In your release, you have to account for users around the world who may have very slow connections).

If this doesn’t give you any insight into what’s happening, then the most likely problem is something to do with:

  • your setup on Google Play’s console
  • the test users you are using to test your IAPs.  (Remember that you cannot use your developer Google account to test IAPs on your device.)

Kind regards,

Simon

Hi Simon

Thanks for the reply. It is not timeout issue as the entire app hangs when the restore function is being called. Using your example code, it means the spinner does not even spin. After a while, there will be a system dialog box, stating the app is not responding.  I am pretty sure the setup is correct and I am using a valid test user as I can purchase a non-consumable product.

Regards

Hi Marcus,

Sorry - I didn’t get a notification that you’d replied to my message (I’ll check my spam settings).

Could you run an  adb logcat Corona:v *:s  to see if you’re getting any native error messages from the device after you call the restore function?

(For more info on Android debugging, check out this page; you’ll also need to go into your device and set it up as a developer machine from Settings - and enable USB debugging, if you haven’t done so already).

Kind regards,

Simon

I did not see any native error message popping out. I have actually commented most of the codes in your restore function leaving only store.restore() and the app still hangs.

This is an odd one - because the code works with iOS, it’s a pure lua build and your purchase works.  I feel like there is something else going on with the setup.

Here are a few things to check/answer next:

  • Are you able to test on a different Android device?
  • Could you try building your app on a different Corona daily build?
  • Does the code run in debug mode on your Android device? (ie. when it’s not actually attempting to contact the store and IAP Badger fakes all the callbacks).  The answer to this should be yes, because it works on iOS, but checking will make sure nothing is slipping through the net.

It would also be helpful if you could post a copy of your catalogue (blank out your Apple/Google product identifiers), and show me how you are calling iap.purchase and iap.restore.

Kind regards,

Simon :slight_smile:

Another way at getting to the bottom of this would be to compile one of the example projects/code accompanying IAP Badger, sign them with your Google Play certificates and insert your Google Play identifiers.

I’d use example code 2 from this page.

The example code has been tested and executes without any problems.  So if the example project works on your device, using your certificate and product IDs, the issue is with the code or setup somewhere in your app.  If it doesn’t work, something more specific to your device and build is happening (probably).

Simon