I have deleted my sandbox user from my iTunes account and got stuck in an endless loop IAP transaction. I cant finish my previous transaction now. My question is that ,
How to clear the SKPaymentQueue?
How to break that endless loop?
I cant create that same sandbox user again as iTunes account prompts me that the userid has already been taken.
P.S I have placed [[SKPaymentQueue defaultQueue] finishTransaction:transaction] in SKPaymentTransactionStatePurchased, SKPaymentTransactionStateFailed and SKPaymentTransactionStateRestored but no luck :(
Kindly help, What should i do now?
Related
I am working on a mobile app using Ionic (with Cordova purchase plugin) but this question is more general. We are using In App Purchases (IAP) and are currently getting an error when we try to finish the consumable purchase. Our current flow is like this:
Get list of our Products from Apple and render on our IAP page
User clicks consumable IAP they want and it fire off a message to StoreKit initiating the purchase
We get a response with a consumable IAP object with the state set to approved.
We initiate the verification procedure with a callback to our own server where we hit apple up to verify the purchase and then log it on our database and send the app a 200 response (not sure if we need to send back the IAP object here with receipt from our server or we just work with the one already inside the app?)
We try finish the purchase where we get an error saying (InAppPurchase[objc]: Cannot finish transaction)
My question is assuming this is the correct flow what does the finish method do? Looking in the source code of the Cordova Purchase Plugin wrapper I can see it sets the state of the object to finished but I am assuming (I couldn't find the code where this happens) it also talks to Apple so that Apple marks the purchase as finished on their side? If we manually set the state to finished the IAP error goes away but the consumable can still not be purchased multiple times which means to me that Apple also need to close it. Is this a correct assumption? Any other tips to getting this to work would also be appreciated.
I'm not sure how cordova handles IAP, but on the apple side, the transaction needs to be finished by calling finishTransaction. It would appear thats the step thats not working.
One thing that might happen due to the delay in going to the server to validate is that the original transaction object has expired, and calling finishTransaction with it does nothing. At this point you might be able to search for your transaction in: [[SKPaymentQueue defaultQueue] transactions]
If you can grab it from there then call finishTransaction then it should work. Not sure how you do this with cordova but I hope this helps.
I have been testing In App Purchases and can only assume that there are transactions stuck in the queue.
I have called [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; but every time I start the app it asks me to login to iTunes.
I have checked within -(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{ but even if I place an NSLog in the first line, this is NOT being called. Thus I don't believe this is being called.
I have also called NSLog(#"PAYMENTQUEUE:%#",[[SKPaymentQueue defaultQueue] transactions]); which shows null.
Can someone advise why I would constantly be asked to login to iTunes every time I start the app all of a sudden? As I say, I can only assume it is a transaction, but how can I track it down?
Your device has been infected with the "endless loop" for failing to have called finishTransaction. It will reoccur every week like clockwork. Check out the IAP Developer's Forum for more info. The queue is empty because you need to log in as the 'infected' user.
Just in case anyone comes across this later on with the same issue. I left the device and stopped trying to sort it out. I deleted the app too.
Around half an hour later I was prompted to logon to the iTunes sandbox store (remember there was no app on anymore).
I logged in, and this scenario occurred another time.
After that all seemed to go quiet.
I have tried installing the app again today (12 hours later) and the issue has gone away.
I can only assume something got jammed up?
In-app purchases are working correctly with my app. I'm even using my own server to validate transaction receipts.
However, I seem to be having an issue with the SKPaymentQueue TransactionObserver and/or DefaultQueue.
An iTunes prompt, for an old test account, will appear whenever I make the following call -
SKPaymentQueue *currentQueue = [SKPaymentQueue defaultQueue];
I cannot figure out how to stop this old test account from appearing whenever I need to make a purchase or restore transactions.
Someone has recommended the following code, which would appear to finish all old transactions, but it doesn't resolve my issue.
SKPaymentQueue* currentQueue = [SKPaymentQueue defaultQueue];
[currentQueue.transactions enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[currentQueue finishTransaction:(SKPaymentTransaction *)obj];
}];
I've also tried removing the app, deleting the old test account from the device and also iTunesConnect. The old user prompt still appears!
Any help would be greatly appreciated, thanks.
are they sandbox transactions or production transactions?
sandbox transactions are a big mess, sometime i find old transactions in the queue, and the lifecycle of sandbox transactions is not totally coherent with production transactions's lifecycle
I just solved the same problem in my code. The issue was because I was not removing the transaction observer when the app would quit.
add this to your app delegate:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self.storeManager];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self.storeManager];
}
I also needed to restart my devices to make sure they were completely clear. Then when you do a restore all purchases the system should be back to normal.
I had a customer how contacted me since my app was just what he needed, and the In App Purchase did not work. After seeing the price and all, when he pressed the "Purchase" button, nothing happened. No app crash, just nothing. Just waiting with no response.
We had a dialogue and he tried many things: deleted the app, downloaded a fresh copy, reset his phone, but the purchase did not go through. He has no restrictions activated.
So I became curious. How many potential customers experience this problem?
Since I went from the Paid model over to the try-before-buy and the In App Purchase, my sales has reduced dramatically. I was disappointed: "do they not like my app after they have tried it?"
After my customer contacted me, and I could not find any bugs in my code, I uploaded a "debug-version" which logs the following info to a web server/database:
- the time and date when the purchase button is pressed.
- the time and date when payment is successful and contents is provided.
along with a generated UUID key.
Today is the first day with the debug version (which logs into a simple web app I made for the purpose), and 50 % of all tries have failed: they have no time and date for successful payment, after the purchase button was pressed.
Here are the lines of code being called after the "Purchase" button has been pressed:
SKPayment *payment = [SKPayment paymentWithProduct:proUpgradeProduct];
[[SKPaymentQueue defaultQueue] addPayment:payment];
Has anybody experienced the same?
Any suggestion about how to move forward?
I have an in-app purchase which is Apple hosted. However I can't figure out how to download the content associated with it.
I could get the downloadable objects and request the download start:
[[SKPaymentQueue defaultQueue] startDownloads:currentTransaction.downloads];
that's when I get lost: what should I do after that?
I have taken a look at Apple doc and didn't find anything that could possibly help me.
Thx
Implement an SKPaymentTransactionObserver. The observer will be notified when the payment queue changes status. For example, paymentQueue:updatedDownloads: will be called with an array of SKDownloads whose downloadState indicates the status change for a download. If you want to know about completed downloads, look for downloadState == SKDownloadStateFinished.
See http://developer.apple.com/library/ios/#documentation/StoreKit/Reference/SKPaymentTransactionObserver_Protocol/Reference/Reference.html
I could solve my problem. Calling the
[[SKPaymentQueue defaultQueue] startDownloads:currentTransaction.downloads];
then
(void)paymentQueue:(SKPaymentQueue *)queue updatedDownloads:(NSArray *)downloads
is constantly called back. I guess I had forgotten some delegates or something like that. Besides that, I deleted the app from my device and re-compiled it again from Xcode. Then it worked like a charm =) Thanks