j3k0 / cordova-plugin-purchase

In-App Purchase for Cordova on iOS, Android and Windows
https://purchase.cordova.fovea.cc
1.3k stars 537 forks source link

[IOS] Still no implementation for Auto-Renew Subscription free-trial periods #1041

Closed Seanmclem closed 4 years ago

Seanmclem commented 4 years ago
OSX 10.15.4
Cordova 7.0.1 // Phone Gap 3.19.2 etc.
Device: iPhone iOS 13.4.1
"@ionic-native/core": "^5.26.0",
"@ionic-native/in-app-purchase-2": "^5.26.0",
"@ionic/react": "^5.1.0",
"cc.fovea.cordova.purchase": "^10.1.1"

Expected behavior

Free-trial Promotional offers should work. Subscriptions are one of the few types of IAP, and free-trials are a very important part of subscriptions. Personally I can't really launch my otherwise completed app without it.

Observed behavior

The full price is charged for new subscribers. Is this only in sandbox? Would it work in production? The free trial period is listed on the products "discounts" array, but everything else relating to trials and promotions is null or false on the product and reciept. With the full price being charged. Issue opened 2 years ago. Another one, and more to name a few. None seem to fully address it from what I can tell

Lindsay-Needs-Sleep commented 4 years ago

Auto-renewing subscriptions with a free trial at the beginning have been working for us. (Haven't updated the plugin in awhile. On version 8.1.1).

If you are using a sandbox user, I believe you only get to see the popup with the free trial information the very first time you buy the subscription.
Subsequent purchases with the same sandbox account after the subscription has expired will go straight to being charged. (The same as it would be for a user.) (Mind you, I haven't tested this since 8.1.1 was new.)

Maybe you can try creating a new sandbox user and see if you get the free trial?

I also seem to recall that I wasn't able to determine if the user was going to receive the free trial or not. (Like it wasn't reflected in the price or something... been too long.) But I am hoping to update and do a bunch more testing in a few weeks.

If I remember, I will post an update with any relevant free trial info.

j3k0 commented 4 years ago

Introductory prices and discount offers are fully supported (iOS and Android). They're 2 different things:

Notice that the plugin is not responsible for what Apple/Google charges, it depends on your setup (which seems incorrect).

j3k0 commented 4 years ago

I also seem to recall that I wasn't able to determine if the user was going to receive the free trial or not. (Like it wasn't reflected in the price or something... been too long.) But I am hoping to update and do a bunch more testing in a few weeks.

You need a receipt validator that returns the ineligible_for_introprice array of product ids. For example, Fovea's https://billing.fovea.cc service is compatible with introductory prices and will do that for you.

j3k0 commented 4 years ago

The free trial period is listed on the products "discounts" array

For some reasons, Apple decided that it would be a good idea. Though you can access into price info in the introPrice* product fields (cf api documentation)

If it's only listed in the discount array, it means you created a discount offer and not an introductory price.

Lindsay-Needs-Sleep commented 4 years ago

@j3k0 Oh awesome!! Thank you for pointing me in the right direction! <3

Seanmclem commented 4 years ago

@j3k0 i use fovea and its setup correct as far as I can tell. Followed all instructions and everything else is working. I have the intro-offer/free-trail setup with Apple on the IAP in question. I'm calling the product transaction with store.order('my-id') and everything else about the transaction works. But it always charges full price with no trial eligibility.

What about my setup seems incorrect? Any specific configurations for this type of setup I might have missed?

I couldn't find anything about trials in the docs really besides a few property descriptions.

Seanmclem commented 4 years ago

@Lindsay-Needs-Sleep how can you confirm what the user ends up paying in a sandbox? For me, everything says the full price in the initial transaction/receipt. Including in fovea

Seanmclem commented 4 years ago

Introductory prices and discount offers are fully supported (iOS and Android). They're 2 different things:

  • introductory prices can only be used if no other purchases have been made
  • discount offers can only be used by subscribers, and require a bunch of server logic.

Notice that the plugin is not responsible for what Apple/Google charges, it depends on your setup (which seems incorrect).

So I can just use an intro offer for my subscription? From a new sandbox user, on their first transaction? I don't need to use a discount offer? Fovea doesnt cover server the side logic?

I guess I'm wondering which I should use.

Seanmclem commented 4 years ago

I got it working with an introductory price. I'll make a PR for the area(s) of the docs I felt are missing some info. Thanks!

simplenetworks commented 3 years ago

I got it working with an introductory price. I'll make a PR for the area(s) of the docs I felt are missing some info. Thanks!

Android works as expected while no luck with iOS and introductory price. Do you have any advice?

j3k0 commented 3 years ago

@simplenetworks Make sure you understand the ins and outs of introductory prices on iOS:

See https://developer.apple.com/app-store/subscriptions for details.

tljesse commented 3 years ago

@j3k0 You mentioned there is a bunch of server logic for discount offers (promotional offers in app store connect?). Is there any documentation for how to set those up for use? We tried using promotional offers for a free first two weeks and have now switched it to an introductory offer. We would still like to have access to the promotional offers if possible. Thanks for any help.

j3k0 commented 3 years ago

Sure, this is the demo server: https://github.com/j3k0/nodejs-suboffer-signature-server

Note, this code is initially from Apple, I modified and documented in order to have it work with the cordova plugin.

jonah-butler commented 2 years ago

@j3k0 when purchasing a product with a discount, what type of return should we expect from store.order(productID, orderData) - the orderData object containing the app user name, discount id, product key id, nonce, timestamp and cryptographic signature.

With your example above, I get a successful return from the store.order, but there is no indication in the return payload or within the native menus showing anything about a discounted price.

The order makes it all the way through to product.verify() where it hits my receipt validation server and lands in product.finish(), but still not seeing any data regarding the discounted price. I may be missing something pretty obvious.

Any tips or help would be appreciated!

UPDATE Turns out discounts are exclusively for in-app customers that have disabled auto-renew from a previous renewable subscription plan. Only they can redeem a discount. A two week free trial period (which is what I was trying to setup) with each auto-renewing subscription should just be setup as an Introductory Offer. Just had to dig a little more for that clarity.