sckor/AnystoneStoreKit

What happens when the subscription date is here?

markrickert opened this issue · 7 comments

So, first, let me say that this library is SO much easier to implement than "the other one". Love how easy it is to understand what's going on! Thank you SO MUCH for putting this out there.

I'm implementing the ASTStoreController without the related ViewController since I already have the view written.

My question is regarding what happens when the subscription date approaches and then is here. Say the user opens my app and their 1-month term subscription has JUST passed and it has renewed with Apple. If I understand the documentation correctly for subscriptions, each subscription term generates a new receipt, thus invalidating the original receipt (and obviously, the expiration date for the original receipt will be in the past so expiryDateForProduct: will return a date in the past.)

How do I go about validating the new receipt data to make sure the new monthly term is valid? Any help would be appreciated.

Thanks again for the great library, and I hope to hear from you soon (trying to get this thing submitted and approved before Christmas, but that might not happen ಠ_ಠ ).

Hi Mark,

You're quite welcome - I'm glad you find it useful.

Gosh it's been a while since I wrote the AutoRenewables. The basic answer is that the kit should handle that automatically. If you query to see if an autorenewable product has been purchased, it will look at the last known expiry time. If the time has passed, it sends the last receipt up for validation. The result from that operation will either be that the sub is valid - in which case a new receipt is saved with the next expiry time. Otherwise, a receipt indicating that the sub has expired will be returned. In that case, it should invoke an expired callback. So basically, just ask if the product is purchased and the kit do the rest of the work.

At least that is how I remember it working. ;)

Sean.
PS: If you haven't submitted to Apple yet - you'll be cutting it pretty close. iTunes connect shuts down on the 22nd. I hate to say it, but it's unlikely you'll get a new app in before Christmas.

On 2011-12-14, at 5:50 PM, Mark Rickert wrote:

So, first, let me say that this library is SO much easier to implement than "the other one". Love how easy it is to understand what's going on! Thank you SO MUCH for putting this out there.

I'm implementing the ASTStoreController without the related ViewController since I already have the view written.

My question is regarding what happens when the subscription date approaches and then is here. Say the user opens my app and their 1-month term subscription has JUST passed and it has renewed with Apple. If I understand the documentation correctly for subscriptions, each subscription term generates a new receipt, thus invalidating the original receipt (and obviously, the expiration date for the original receipt will be in the past so expiryDateForProduct: will return a date in the past.)

How do I go about validating the new receipt data to make sure the new monthly term is valid? Any help would be appreciated.

Thanks again for the great library, and I hope to hear from you soon (trying to get this thing submitted and approved before Christmas, but that might not happen ಠ_ಠ ).


Reply to this email directly or view it on GitHub:
#11

Thanks for the quick reply. I'll try and step through the code in the morning to make sure the workflow I'll be using doesn't interrupt the user experience when the subscription period switches over.

I guess my question is about the difference between

// AutoRenewable - YES means active subscription, NO means subscription expired
- (BOOL)isProductPurchased:(NSString*)productIdentifier;

and

// AutoRenewable - Returns expiry date (may be expired) or nil (which means sub not active or has expired)
- (NSDate*)expiryDateForProduct:(NSString*)productIdentifier;

I would assume that the expiryDateForProduct: is a convenience method to allow me to display to the user WHEN their subscription actually expires.

Do I only need to call isProductPurchased: in order to validate the subscription or do I also need to manually check the expiry date against [NSDate date] and if expired, manually tell the library to re-check to see if it was renewed or if the user canceled their subscription?


I know about the shutdown and I've been having issues with Apple's Sandbox servers for a week (multiple calls to dev. support). It is what it is and if it gets in, well then great... but if not. I can live with it being before Jan. 10th.

Hi again Mark,

So, I took a look at what I'd done - like I said, it's been a while.

In general you shouldn't even need to run the isProductPurchased (though you may want to for your own reasons). On startup as it's reading the data in, for all of the subscriptions it will set the expiry date. As part of setting the expiry date, it will also create a timer that will fire near the expiry time. That timer will trigger a check to determine if the sub is still valid or not. Take a look at setExpiresDate in the familyData code and follow the chain of delegates if you're interested.

The expiryDateForProduct was meant so that you could display the expiry information to the user - you do not need to do the subscription expiry calculation yourself.

Cheers,

Sean.

On 2011-12-14, at 11:26 PM, Mark Rickert wrote:

Thanks for the quick reply. I'll try and step through the code in the morning to make sure the workflow I'll be using doesn't interrupt the user experience when the subscription period switches over.

I guess my question is about the difference between

// AutoRenewable - YES means active subscription, NO means subscription expired
- (BOOL)isProductPurchased:(NSString*)productIdentifier;

and

// AutoRenewable - Returns expiry date (may be expired) or nil (which means sub not active or has expired)
- (NSDate*)expiryDateForProduct:(NSString*)productIdentifier;

I would assume that the expiryDateForProduct: is a convenience method to allow me to display to the user WHEN their subscription actually expires.

Do I only need to call isProductPurchased: in order to validate the subscription or do I also need to manually check the expiry date against [NSDate date] and if expired, manually tell the library to re-check to see if it was renewed or if the user canceled their subscription?


I know about the shutdown and I've been having issues with Apple's Sandbox servers for a week (multiple calls to dev. support). It is what it is and if it gets in, well then great... but if not. I can live with it being before Jan. 10th.


Reply to this email directly or view it on GitHub:
#11 (comment)

Yeah, I followed the delegate chain earlier today and I'm pretty comfortable with what it's doing.

Like I said earlier, I'm not using the ViewController included in the library and I'm rolling my own. I've got a subscription "paywall" that I need to invoke if I detect that the subscription is invalid, so in my applicationWillEnterForeground: method in the app delegate I'm checking to see if the subscription family is valid (1 month, 6 months & 1 year terms).

I see the grace period in the subscription check. So I guess when the user launches the app and the subscription is invalid, it'll fire off the request to validate the new subscription term, but will still return that it's valid if within the grace period. Then HOPEFULLY, the next time the user opens the app, they should have the new valid receipts.

Again, thanks for the great library and the quick replies. It's much appreciated.

-Mark

After a little more investigation, I've discovered that Apple's subscription implementation is completely broken. The subscriptions are considered "consumables" and therefore don't get retuned back to the device when doing a restore transaction call. This completely prohibits me from implementing the rule from Apple: "subscriptions must be available on all the user's devices" without implementing some kind of username/password on my own servers to keep track of their account.

I've given up and am pursuing traditional in-app purchases.

I was pretty sure that it did replay as part of the restore
transactions. Did you check?

Sean.

Sent from my iPhone

On 2011-12-18, at 5:16 PM, Mark Rickert
reply@reply.github.com
wrote:

After a little more investigation, I've discovered that Apple's subscription implementation is completely broken. The subscriptions are considered "consumables" and therefore don't get retuned back to the device when doing a restore transaction call. This completely prohibits me from implementing the rule from Apple: "subscriptions must be available on all the user's devices" without implementing some kind of username/password on my own servers to keep track of their account.

I've given up and am pursuing traditional in-app purchases.


Reply to this email directly or view it on GitHub:
#11 (comment)

Yeah, spent about 12 hours trying to implement it. I finally decided that it wasn't worth it.