Has anyone here ever implemented IAP subsciptions?

From what I can see there is an undocumented call in the GP IAP plugin:

plugin.purchaseSubscription()

and also a check to see if the store is able to process subscriptions:

plugin.canPurchaseSubscriptions

If I print canPurchaseSubscriptions it returns true, however if I pass the subscription identifier into loadProducts() it comes back as an invalid product. A regular IAP passed in at the same time comes back as a valid product.

I also don’t see how you would check if a subscription was still valid or not.  

The Amazon IAP plugin docs seem to imply that it can also handle subscriptions, but I haven’t got that working yet either.

If anyone has implemented subscriptions in a Corona app before, I’d be grateful for any help you could give.

I’ve been researching subscriptions this morning.  Obviously Apple and Google want to do things differently.  But generally speaking for manual subscriptions, they would seem to be purchased the same as a regular purchase and the store’s interface will initiate the workflow. It’s the developer’s responsibility to track when the purchase is made and when it will expire and if the subscriber purchases a new subscription before the other one ends, to extend the subscription. Your app would check to see if the subscription has expired and turn off features accordingly. If you have multiple tiers of subscriptions you have to compute the amount of time left on the previous subscription and add it to the length of the new subscription. It’s highly recommended you maintain all of this on a server.

For auto-renewing subscriptions, this server seems to be required for Google and recommended for Apple. When the subscription auto renews, the provider will contact your server and call a URL that will update the subscription information and then your app can verify against your server. Google does have a REST based API to check subscription statuses. I didn’t see something similar for Apple.

I need to talk to our engineers about what this mysterious subscription API is about in the Google IAP plugin. I didn’t see anything similar for Apple. I’m not sure why loadProducts() is calling your subscription invalid. As far as I know we are just returning data from the server. But I’ll need to check with our engineers.

I don’t see how there could be a magical API that does all of this work. We do need to identify if Google has a separate purchase API for subscriptions which might justify the purchaseSubscription() API call. But beyond that, it’s more up to you to track when they expire and offer UI options to let people purchase/renew them.

Rob

Did you ever get to the bottom of this @RobMiracle?

No, I did not. Let me re-engage engineering on it.

Honestly, our IAP should just work as is. These extra server setups are not Corona specific. The store.init() setups up your transaction listener and at least in the new iOS store, you can get purchases from outside of your app and they just show up as transactions in your function. You just handle them when you get them.

It’s up to you to manage turning off features when you detect a subscription is up. Apple and Google should be providing you enough information to make that happen.

Rob

So I had more of a look into this - specifically on Google Play. Unfortunately loadProducts() seems to only return actual products - not subscriptions.

We can probably get around this by making the subscription listing more dynamic (or serving it from our own database), but I can’t see a way to get the status of a subscription - i.e. is it still valid. Looking at the Google Play Developer docs it appears that subscriptions have their own section of the API, so if the Corona plug-in isn’t interacting with that end-point, I doubt we’ll get anything about subscriptions coming back.

I’ll do some sniffing on the iOS side next.

On Android when we call store.loadProducts() we get a product list back, the first element of the event object is…

“invalidProducts”:[“idOfTestSubscriptionProduct”]

We forced our app to offer it up anyway and when the Google Play store pops up it does offer the user a subscription.

Next step is to see what comes back when they complete the purchase - hopefully something usable. Also wondering how we can check of the status of the user’s subscription.

Got the callback from Google Play and it’s not good…

11-03 13:00:23.474 32615 32754 I Corona  : transactionCallback: Received event storeTransaction

11-03 13:00:23.474 32615 32754 I Corona  : event.transaction = table: 0xc6e03340

11-03 13:00:23.474 32615 32754 I Corona  : state: failed

11-03 13:00:23.474 32615 32754 I Corona  : errorType: -1008

11-03 13:00:23.474 32615 32754 I Corona  : errorString: IAB returned null purchaseData or dataSignature (response: -1008:Unknown error)

11-03 13:00:23.475 32615 32754 I Corona  : storeTransactionCallback event: {

11-03 13:00:23.475 32615 32754 I Corona  :   “name”:“storeTransaction”,

11-03 13:00:23.475 32615 32754 I Corona  :   “transaction”:{

11-03 13:00:23.475 32615 32754 I Corona  :     “state”:“failed”,

11-03 13:00:23.475 32615 32754 I Corona  :     “errorString”:“IAB returned null purchaseData or dataSignature (response: -1008:Unknown error)”,

11-03 13:00:23.475 32615 32754 I Corona  :     “isError”:true,

11-03 13:00:23.475 32615 32754 I Corona  :     “errorType”:-1008

11-03 13:00:23.475 32615 32754 I Corona  :   }

11-03 13:00:23.475 32615 32754 I Corona  : }

11-03 13:00:23.475 32615 32754 I Corona  : Transaction failed, type: -1008 IAB returned null purchaseData or dataSignature (response: -1008:Unknown error)

Looks like it’s not possible to handle subs @robmiracle ?

Just tested on iOS - doesn’t return the subscription products at all on store.loadProducts().

Sounds like a native approach is required.

Hello,

Im trying to use this library for android https://github.com/anjlab/android-inapp-billing-v3, and i need some help to override the “onActivityResult” like:

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (!bp.handleActivityResult(requestCode, resultCode, data)) { super.onActivityResult(requestCode, resultCode, data); } }

How can i do from CoronaActivity?

I’ve been researching subscriptions this morning.  Obviously Apple and Google want to do things differently.  But generally speaking for manual subscriptions, they would seem to be purchased the same as a regular purchase and the store’s interface will initiate the workflow. It’s the developer’s responsibility to track when the purchase is made and when it will expire and if the subscriber purchases a new subscription before the other one ends, to extend the subscription. Your app would check to see if the subscription has expired and turn off features accordingly. If you have multiple tiers of subscriptions you have to compute the amount of time left on the previous subscription and add it to the length of the new subscription. It’s highly recommended you maintain all of this on a server.

For auto-renewing subscriptions, this server seems to be required for Google and recommended for Apple. When the subscription auto renews, the provider will contact your server and call a URL that will update the subscription information and then your app can verify against your server. Google does have a REST based API to check subscription statuses. I didn’t see something similar for Apple.

I need to talk to our engineers about what this mysterious subscription API is about in the Google IAP plugin. I didn’t see anything similar for Apple. I’m not sure why loadProducts() is calling your subscription invalid. As far as I know we are just returning data from the server. But I’ll need to check with our engineers.

I don’t see how there could be a magical API that does all of this work. We do need to identify if Google has a separate purchase API for subscriptions which might justify the purchaseSubscription() API call. But beyond that, it’s more up to you to track when they expire and offer UI options to let people purchase/renew them.

Rob

Did you ever get to the bottom of this @RobMiracle?

No, I did not. Let me re-engage engineering on it.

Honestly, our IAP should just work as is. These extra server setups are not Corona specific. The store.init() setups up your transaction listener and at least in the new iOS store, you can get purchases from outside of your app and they just show up as transactions in your function. You just handle them when you get them.

It’s up to you to manage turning off features when you detect a subscription is up. Apple and Google should be providing you enough information to make that happen.

Rob

So I had more of a look into this - specifically on Google Play. Unfortunately loadProducts() seems to only return actual products - not subscriptions.

We can probably get around this by making the subscription listing more dynamic (or serving it from our own database), but I can’t see a way to get the status of a subscription - i.e. is it still valid. Looking at the Google Play Developer docs it appears that subscriptions have their own section of the API, so if the Corona plug-in isn’t interacting with that end-point, I doubt we’ll get anything about subscriptions coming back.

I’ll do some sniffing on the iOS side next.

On Android when we call store.loadProducts() we get a product list back, the first element of the event object is…

“invalidProducts”:[“idOfTestSubscriptionProduct”]

We forced our app to offer it up anyway and when the Google Play store pops up it does offer the user a subscription.

Next step is to see what comes back when they complete the purchase - hopefully something usable. Also wondering how we can check of the status of the user’s subscription.

Got the callback from Google Play and it’s not good…

11-03 13:00:23.474 32615 32754 I Corona  : transactionCallback: Received event storeTransaction

11-03 13:00:23.474 32615 32754 I Corona  : event.transaction = table: 0xc6e03340

11-03 13:00:23.474 32615 32754 I Corona  : state: failed

11-03 13:00:23.474 32615 32754 I Corona  : errorType: -1008

11-03 13:00:23.474 32615 32754 I Corona  : errorString: IAB returned null purchaseData or dataSignature (response: -1008:Unknown error)

11-03 13:00:23.475 32615 32754 I Corona  : storeTransactionCallback event: {

11-03 13:00:23.475 32615 32754 I Corona  :   “name”:“storeTransaction”,

11-03 13:00:23.475 32615 32754 I Corona  :   “transaction”:{

11-03 13:00:23.475 32615 32754 I Corona  :     “state”:“failed”,

11-03 13:00:23.475 32615 32754 I Corona  :     “errorString”:“IAB returned null purchaseData or dataSignature (response: -1008:Unknown error)”,

11-03 13:00:23.475 32615 32754 I Corona  :     “isError”:true,

11-03 13:00:23.475 32615 32754 I Corona  :     “errorType”:-1008

11-03 13:00:23.475 32615 32754 I Corona  :   }

11-03 13:00:23.475 32615 32754 I Corona  : }

11-03 13:00:23.475 32615 32754 I Corona  : Transaction failed, type: -1008 IAB returned null purchaseData or dataSignature (response: -1008:Unknown error)

Looks like it’s not possible to handle subs @robmiracle ?

Just tested on iOS - doesn’t return the subscription products at all on store.loadProducts().

Sounds like a native approach is required.

Hello,

Im trying to use this library for android https://github.com/anjlab/android-inapp-billing-v3, and i need some help to override the “onActivityResult” like:

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (!bp.handleActivityResult(requestCode, resultCode, data)) { super.onActivityResult(requestCode, resultCode, data); } }

How can i do from CoronaActivity?