robotmedia / RMStore

A lightweight iOS library for In-App Purchases
Apache License 2.0
2.43k stars 450 forks source link

App Store update, IAP no longer works #154

Open ddaddy opened 9 years ago

ddaddy commented 9 years ago

Has anyone else had an updated app suddenly stop awarding IAP's?

I've update my app many times, and this last update absolutely nothing was changed regarding IAP's and yet when the App Store update was released, no IAP's are awarded. Neither 'Restore Purchases' nor buying awards the IAP.

I've tested the previous build, and it works fine. I've gone through my commits with a fine tooth comb, and nothing should affect this.

I can't properly debug the App Store version because iOS 9 and Xcode 7 have since been released and everything seems to work flawlessly when running and debugging my code from Xcode.

Looking at the device console, I left in an NSLog that lists the purchasedProductIdentifiers and I can see my IAP is listed.

The only point I can see an issue, is if calling the RMStoreKeychainPersistence too many times in quick succession with [_persistence purchasedProductIdentifiers] could cause the issue?

I really don't know whether uploading a new build that works from Xcode is going to have the same problem once released onto the App Store.

Anyone else had similar experiences?

georgbachmann commented 9 years ago

I had the same problem. I was not using RMStoreKeychainPersistence but only receipt verification... We had one or two customers complaining about lost IAPs in the past after each update, but after the last update there were hundreds of customers complaining. It seems as if my app receipt wasn't there any more or maybe it was not valid any more... I don't know since I didn't have logging for that.

Does anybody know if there is any way how this can be debugged?

For the future I will not use receipt verification any more as it 1. can't be testen and 2. seems to be very unreliable...

ddaddy commented 9 years ago

That sounds very similar. I had a couple of users complain and just brushed it off as user error, then another update later and everyone (Even me) has the same problem. I guess all I can do I submit a new build and hope for the best.

georgbachmann commented 9 years ago

Do you know the reason in your case? Was the receipt missing? Or was it invalid?

georgbachmann commented 9 years ago

I'll going to make an update and would like to refresh the receipt for users with the problem... but the question is: "How to detect those users"...?!?

ddaddy commented 9 years ago

No idea. I don't use receipt validation at all. Just used RMStoreKeychainPersistence which seems to still report that it's been purchased. I wonder if there's an issue with calling it too frequently or too early

ddaddy commented 9 years ago

I pushed an update to the App Store and got an expedited review, and all is working again! That was very very strange.

matthieurouif commented 9 years ago

It seem we have the same problem. Any more info on this?

georgbachmann commented 9 years ago

It seems as if receipt validation fails.... I did an expedit review and just ignored the validation (i know that's bad... but as it's hard to test it was the only way we saw) and just checked for the IAP identifier. And now I am saving the information if PRO user or not in the KeyChain

ddaddy commented 9 years ago

@matthieurouiff were you using receipt validation? I'm wondering if it's more a general App Store problem with an update as I didn't change anything but my next update worked.

matthieurouif commented 9 years ago

Thanks. I don't think we don't do receipt validation but I am checking this right now. Same as you, we didn't change anything on the in-app side on our last release

georgbachmann commented 9 years ago

I also didn't change anything in my IAP code... So I guess it was an update problem from the store... But as it's just impossible to test the exact reason we were just not brave enough to just resubmit :) we collected quite a few 1star reviews and therefore wanted to solve the problem as quick as possible :)

matthieurouif commented 9 years ago

@georgbachmann have you made an update already?

georgbachmann commented 9 years ago

@matthieurouif yes... expedit review... was through in about 2h or so... after the update the problem was gone...

ddaddy commented 9 years ago

I was able to recreate my issue by exporting the previous build from Xcode for adhoc, the. Using Xcode to install it on my device. I did the same with a new build and it worked so I was confident with the submission.

ddaddy commented 9 years ago

Something I've noticed since my update that fixed the IAP. I regularly have to restore purchases. Like maybe once every couple of days. It's as if the keychain store is randomly broken.

formvoltron commented 9 years ago

Did you guys resolve this. This sounds pretty scary. My app uses RMStore. No negative reviews related to missing IAP, but it would be good to get to the bottom of this. Have you googled around looking for other broken IAP related things with IOS9?

formvoltron commented 9 years ago

By the way, I'd say after 1 + years no update and no response on this sort of level of issue... I'm looking for an alternative to RMStore.

ddaddy commented 9 years ago

Not sure where you got 1+ years from? I started this topic 17 days ago.

I'm still none the wiser what happened and every now and then I have to restore purchases.

formvoltron commented 9 years ago

sorry for the confusing message. I meant the last version bump. But actually it was December last year and I guess nothing has changed with IAP so nothing to update with the library.

Still, it would be good to know what is going on here.

matthieurouif commented 9 years ago

We shipped an update, hopefully it will solve the problem for everyone.

Some other news, one of our users was able to make things work again with this easy solution that I'd like to share with you: "I have my device on Automatic update of time and date - so I set it on manual and set the date to yesterday. Went back to Replay app and hit restore..."

georgbachmann commented 9 years ago

@matthieurouif could you share with us where the problem was? Would be great to know what caused all the problems...

formvoltron commented 9 years ago

@matthieurouif I really hope I don't have to tell my users to try that solution. I guess it is good to have some possible solution though. Thank you for sharing.

On Mon, Oct 12, 2015 at 6:12 PM, Georg Bachmann notifications@github.com wrote:

@matthieurouif https://github.com/matthieurouif could you share with us where the problem was? Would be great to know what caused all the problems...

— Reply to this email directly or view it on GitHub https://github.com/robotmedia/RMStore/issues/154#issuecomment-147448869.

matthieurouif commented 9 years ago

We haven't identify the problem. I just gave a fix that seems to be working and I ship an update since you guys sayed it fixed the problem. I'll tell you if it really fix the problem once the app is on the store

ddaddy commented 9 years ago

Probably totally unrelated but I've noticed my banking app randomly ask me for my pincode, whereas it should (and 90% of the time does) just let me use touchId.

So I'm wondering if this could be an iOS bug with the keychain, as I still have to refresh purchases every now and then.

sipersso commented 8 years ago

I am also getting this issue. Did you find a solution? I have a non consumable in app purchase and I only check the app receipt if the user has purchased the premium features. Haven't made any changes, but all of a sudden users start complaining about in app purchases being lost. The app receipt seems to be lost and the users have to restore their purchase.

sipersso commented 8 years ago

To add to this issue, I just noticed that my update was released on the 4th of november and according to my analytics framework, most users lost their receipt on the 12th of november. More than one week after the update! Could this issue have something to do with iOS updates?

ddaddy commented 8 years ago

I'm still none the wiser on this. I don't even use the receipt, just the keychain and yet I have to restore my purchase almost weekly.

sipersso commented 8 years ago

@ddaddy That sounds disturbing! I am not even using the transaction persistence, just checking the receipt. I have no clue why this is happening.

Now I am implementing my own fallback solution storing if a purchase has been made in user defaults and automating the refresh when needed, but it has already caused quite a few negative reviews.

formvoltron commented 8 years ago

So annoying... I'll never get this release out. But thank you for sharing the issue. Strange that there isn't more chatter about it on stack overflow or apple's dev boards. Maybe there is. I haven't looked for it.

On Mon, Nov 16, 2015 at 10:47 PM, sipersso notifications@github.com wrote:

@ddaddy https://github.com/ddaddy That sounds disturbing! I am not even using the transaction persistence, just checking the receipt. I have no clue why this is happening.

Now I am implementing my own fallback solution storing if a purchase has been made in user defaults and automating the refresh when needed, but it has already caused quite a few negative reviews.

— Reply to this email directly or view it on GitHub https://github.com/robotmedia/RMStore/issues/154#issuecomment-157198008.

GabrielCartier commented 8 years ago

Have you guys got any news on this?

I have recently published an app and we have been getting complaints of users getting charged and not getting the products. It seems like a common step to reproduce is when the users are prompted to update their credit card information and taken out of the app in the process. They are then taking back in the app and the process is completed.

I am almost certain that the block success will never be called in this case as when I did the test myself, I have seen an error from the addPayment:success:failure call (the failure displays a HUD).

The only possible solution I have found is to actually add an observer on the delegate for any transactions call to see if the success notification is actually received. I may have found a way to test it better, I'll post on it later.

Maybe the error is not directly related to the issue in this topic, if it ain't I'll create another issue.

catlan commented 8 years ago

Any news?

iMobCoding commented 8 years ago

Any news please? Any solution? I also get emails about charged purchases but users not credited...

formvoltron commented 8 years ago

I wonder if this is new behavior or these spurious errors have been with the platform since the beginning?

On Fri, Mar 18, 2016 at 4:14 AM, Dusan Lazarevic notifications@github.com wrote:

Any news please? Any solution? I also get emails about charged purchases but users not credited...

— You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/robotmedia/RMStore/issues/154#issuecomment-198199860

creynaud commented 8 years ago

We are using RMStoreKeychainPersistence in our yoga app, and got support requests from users who said the yoga sessions they had purchased got locked again. This issue affects only a minority of users (~5 every 1000 users). Asking them to go "Restore purchases" in the app settings solved the issue.

I wonder if this has something to do with this spurious bug that Apple has to fix in the Keychain: https://forums.developer.apple.com/thread/4743

I can't think of a workaround so far, except keeping track of in-app purchases somewhere else (maybe NSUserDefaults, which makes it easy to hack).

georgbachmann commented 8 years ago

I also went ahead and kept track in user defaults as fallback. But what I did so that you can't easily hack it it take the Device-ID + Salt and Hash that.. So I can compare the stored value to an expected one...

iMobCoding commented 8 years ago

Ok but I am not using non-consumable purchases at all, only consumable. So I can't tell users to restore purchases. And even with consumable, users complain about lost money without credits...

catlan commented 8 years ago

With the current state, I would recommend migrating to your own solution.

There seems to be confirmed bug fixes that haven't been merged in over half a year like https://github.com/robotmedia/RMStore/pull/150 and this serious open issue without any real hints. Also while hunting down this crash I lost trust in the code base.

But to bring some productivity to the discussion, when using RMStoreKeychainPersistence:

I added some logging which can be attach to a report problem email, which gave a good clue.(https://github.com/catlan/RMStore/commit/9668bf7b4ce66f03a080f5bb91320d8608efd7bb and https://github.com/catlan/RMStore/commit/a78ce35f110dceb46b9d5b3264f6213773779339)

RMStoreKeychainPersistence is not able to find the item. And the restore fails because item with the same unique attributes is already in the keychain.

The unique attributes for kSecClassGenericPassword are kSecAttrService and kSecAttrAccount. In RMStoreKeychainPersistence, kSecAttrAccount https://github.com/catlan/RMStore/blob/a78ce35f110dceb46b9d5b3264f6213773779339/RMStore/Optional/RMStoreKeychainPersistence.m#L36 is set to data instead of a string, and as such gets ignored.

So the keychain item for effected users seems to have lost kSecAttrGeneric attribute. Which explains why SecItemCopyMatching returns errSecItemNotFound. And SecItemAdd fails with errSecDuplicateItem.

I'm curious on how the kSecAttrGeneric attribute got missing.

About fixing the issue. I suggest to move to a new key - fixing the wrong data type and querying for a non unique attribute issue. Maybe with a run once upgrade process in the RMStoreKeychainPersistence initialiser. Fixing the items with the missing kSecAttrGeneric attribute is a double-edged sword. One could search for only the kSecAttrService attribute, but because it uses only the bundle ID it could return false positive. So if one impl a fix for this, I would suggest to require a NSUserDefaults key for it. It only makes sense for consumables I think, customers with non-consumables can just use restore when the fix is in place. So the developer could audit their code, see if no other keychain item with the bundle ID is used.

Seoras commented 8 years ago

I've seen a crash reported in popAddPaymentParametersForIdentifier line 674 of RMStore.m due to the passed parameter being a null string. Neither didFailTransaction nor finishTransaction, which are the only 2 places it's called, check if SKPaymentTransaction payment is non-null. Some more defensive coding here might go some way to mitigating problems like this one, which I suspect are many and not one.