Our company is receiving many reports of in-app purchases and in-app purchase restores not doing anything. Most reports mention that no action occurs within the app when the purchase completes, or when the restore button is tapped.
All of our sandbox and live app testing shows that the IAP feature is working flawlessly. Further, the vast majority of our users report no issues with the feature. Still, it's odd that such a large number of users are reporting a problem.
We recently had to rebuild our .xcodeproj file from scratch, after losing the prior copy, but all of the other files remained unchanged. Could this have somehow caused the problem?
Per the debug information provided with our reports, the issue appears to affect nearly every device and every iOS version. The only common thread is that it's affecting the versions of our app produced after we rebuilt the Xcode project file.
This is more of a high-level question to see if others are facing or have faced this issue. Because of this, and because the code appears to working fine, no code has been provided, but please let me know if specific code examples would be useful.
Per comment below, here is some relevant code relating to the restore process:
- (void)restoreCompletedTransactions {
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
NSString *product_identifier = transaction.originalTransaction.payment.productIdentifier;
if(product_identifier == nil)
product_identifier = #"PRODUCT_IDENTIFIER";
[self provideContentForProductIdentifier:product_identifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
There is an issue on App purchase restoring from iOS 9.0.
Use this bunch of code for restoring.
- (void)restoreCompletedTransactions {
[[SKPaymentQueue defaultQueue] addTransactionObserver:[yourclass sharedHelper]]; // Yourclass can be self, or can be where did you initialise your helper.
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
Related
When I first developed an inapp purchase solution for an iOS app, one of the annoying things was that calling [[SKPaymentQueue defaultQueue] restoreCompletedTransactions] would ask the user to verify their Apple ID every time, popping up the dreaded password dialog. I was testing this against iOS 8 & 9.
Skip forward a few years and now I have noticed that on iOS 12.1, calling [[SKPaymentQueue defaultQueue] restoreCompletedTransactions] doesn't show that dialog unless the user has signed out of their Apple account under Settings.
So I'm wondering, what version of iOS stopped showing this dialog on every call to that function?
I wish I had a pile of iOS test devices with all the old versions, but unfortunately I only have devices running iOS 12 so I can't test this out myself.
The reason I want to know is because being able to call that method without invoking the stupid dialog means I can potentially use it as a background method of checking what purchases a user has made on starting/resuming the app.
Once I know which iOS version stopped asking for Apple ID verification on every call to restore, I can add some conditional logic to only do this on or above that iOS version.
I have an app where non-consumable inapp purchases allow content packages to be downloaded to the device.
Users often use my app across their iOS devices and so currently they have to manually sync the purchased content between devices using the "Restore purchases" button.
However, if I can call restoreCompletedTransactions in the background to obtain a list of their owned non-consumable purchases, I can diff that against the content packages already downloaded to their device and therefore automatically restore content packages for purchases they've made on other devices.
This is something I've been able to do on Android for ages and users ask why the app can't do the same on iOS.
(BTW I know the way of doing this recommended by Apple is to store the receipt of purchase from Apple on my server and use this to verify re-downloading of content, but for various reasons this was not possible)
This question already has answers here:
restoreCompletedTransactions broken?
(7 answers)
Closed 8 years ago.
I have recently released my first app after 2.5 years of development (a roguelike) and I am now having difficulty restoring a nonconsumable purchase:
I have a "restore purchases" button that calls this method just fine:
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
Then a prompt pops up requesting my user name and password, so I enter my test account information.
However, that is all that happens. The app doesn't crash as xcode shows it still running fine, but this method never gets called:
-(void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions;
I am able to make consumable purchases and even the non-consumable purchase can be made normally, but when I delete the app from my device, reinstall and try to restore, the paymentQueue: updatedTransactions: function above never gets called while everything else seems to be called normally.
Can anyone identify my error?
Are you calling [[SKPaymentQueue defaultQueue] addTransactionObserver:myObject] to tell the defaultQueue that you are to be notified of transaction updates/events? I just recently had a similar problem occur to me, and it took a couple of days and multiple tutorials to find the error. Hope this helps!
Note that Store Kit testing does not work in the Simulator. You don't say whether this is happening in the Simulator or on a device, but my experience is that testing in the Simulator won't cut it. (It's unclear to me whether this is a deliberate policy on Apple's part or a Simulator bug.)
I have an app with working In App purchases, it was approved by Apple and it is now in Appstore. A few days ago I submitted a new version of the app with one new consumable purchase, implemented as others were.
I'm using MKStoreKit and this method to buy a feature:
// ... showing loading window
[[MKStoreManager sharedManager] buyFeature:feature
onComplete:^(NSString* purchasedFeature,NSData* purchasedReceipt, NSArray* availableDownloads) {
// ... some handler and close loading
onCancelled:^ {
// ... another handler and close loading
}];
In Sandbox mode this method ends either in onComplete block, either onCancelled block, getting all correct identifiers (with new purchase too). However, due to Apple's reviewer's answer my loading is never closed. Also, they say that new purchase is now in Developer Action Needed Status, but can not edit it now, and I can not delete it (even if I check Cleared For Sale for NO).
May the problem be in the new purchase product or is it something else? I'm totally confused...
What can I do? Anyone encountered such a problem? I can not reproduce the error in Sandbox since it is working fine, so is there any way I can get the same result as in the Apple Review Team?
that was a strange bug on Apple servers caused by this new In App. I don't know why, but I could not delete it. Also, it had broken all In Apps but only while Apple Review testing, as I've said, all was fine in Sandbox mode. The solution was to write to Apple's support, and after a while they fixed it, I deleted this In App and everything started to work as is should.
Apple states that all apps using in-app purchases have to put this
[[SKPaymentQueue defaultQueue] addTransactionObserver:self.observer];
at the beginning of the app to handle for any successful sale that for some reason the device has not received the confirmation to release the content.
I am trying to test this, trying to call the phone when it is about to finish the transaction, quitting the application or stopping Xcode before the transaction finish, but for some reason, even when I quit Xcode, iOS appears to continue handle the transaction and the app never receives the SKPaymentTransactionStateRestored. The app always receive the SKPaymentTransactionStatePurchased and appears to be fail proof (perhaps the new iOS 4 handles that better than the 3.2 when StoreKit was released).
My question is: do you guys know any situation I can create here to generate the failure and receive the SKPaymentTransactionStateRestored when the app starts? I need to test if the app is working well for this kind of situation.
thanks
SKPaymentTransactionStateRestored is only for when you call restoreCompletedTransactions (so a user can restore their in-app purchases on a new device). If you quit the app without calling finishTransaction:, the transaction stays in the queue and you will get SKPaymentTransactionStatePurchased again.
i get a timeout error (-1001) when trying to make an in app purchase. this began happening suddenly after in-app-purchase had been working fine for a while. what happens now is that i see my inventory, complete with prices retreived from apple, but after i attempt a purchase and the following code is executed:
SKPayment *payment = [SKPayment
paymentWithProductIdentifier: product.productIdentifier];
[[SKPaymentQueue defaultQueue] addPayment: payment];
all i get is a timeout error.
i created a test project with nothing but the storefront supplied by a reliable third party (urban airship) which i'd been using successfully with some alterations in my app. i got the same in app purchase timeout error, which strongly suggests some kind of issue on apple's end (it seems that either my device or my app id have gotten blackballed somehow -- perhaps after i'd uninstalled the app a bunch of times to reset its state -- at least with the sandbox servers). so now the question is what to do about it. any help would be appreciated.
problem solved: it was after all an apple issue. apparently the new app store agreement had gummed up the works. i had to install something via the app store on the device, after which the in-app-purchase was a-okay again. thanks all for your help.