Finish pending store transactions? - iphone

How can someone finish or remove any pending store transaction?
A client tested an app IAP with a test user, the purchase didn't finish, and the user expired, he cannot login with the user anymore, and now the system is always trying to make him log in with the old user, and when trying to re-purchase the IAP the transaction gets cancelled because of the previous one.
The only way I know for solving this is restoring the system, but that's a pain.

Tell the client to log out of this user account in Settings -> Store -> Apple ID.
Then the app should prompt for a new username when you attempt a purchase.

Related

IOS buy, erase phone, detect previously purchased

I got most of IAP purchase working, using user defaults etc
But supposing a user buys an app, then erases or updates to a new phone.
Then reinstalls the app.
How do I detect that the user has previously purchased the app?
That is what restore functionality is for. See the Restore section of:
https://developer.apple.com/documentation/storekit/in-app_purchase/offering_completing_and_restoring_in-app_purchases
There are three ways:
If you store some purchase indicator in the app keychain, it will be present when the app is re-installed. If you are doing subscriptions also include an expiration date you can check if a subscription is possibly out of date.
If you send the app receipt up to Apple, it will always give you back the most current purchase data - which includes any prior purchases. So on first launch, always send the receipt up to Apple to see if you might want to automatically restore a purchase made previously. Note that sometimes an application receipt will not be present immediately after install (although it should always be there), which is why you also need to allow for option 3.
There is also a SKPaymentQueue’s restoreCompletedTransactions() call you can make to basically replay previous purchase transactions. This is something you should wire to a button somewhere in your UI - Apple requires that. It's not something you want to automatically call as it can prompt for the user to enter their iTunes account password, so you should not rely on this method to restore purchases automatically, but it is good to have in place as a backup for the user.

How to start a download upon this StoreKit message?

On a fresh app install, when I try to re-purchase an item to re-download it my app sends a purchase request to Store Kit.
Then I get SKPaymentTransactionStatePurchasing, and Store Kit prompts the user to confirm the purchase.
Then Store Kit responds with this message on iOS 7: "You've already purchased this in-App Purchase but it hasn't been downloaded.".
Then, Store Kit fails with SKPaymentTransactionStateFailed and error is
Previously StoreKit would just let the user re-download the content instead. But now it fails with error code 2 "Cannot connect to iTunes Store". If I do a complete restore then Store Kit allows to download content, but this particular item still fails. Also note the test device has WiFi and stable internet connection and StoreKit was able to resolve that the item is purchased. So this error is bogus.
Is this a new change in iOS 7? How can I let the user re-download a single item without forcing to re-download all?
According to this Technical Note, the problem occurs if there is a purchase transaction that was not finished. I tripple-checked that I call finish transaction and it happens after I get the error. So the transaction does get closed.
You have some unfinished transactions in the payment queue. To finish them check the paymentQueue.transactions array right after adding your observer with addTransactionObserver: method. If it contains some transactions handle them the way you do in your paymentQueue:updatedTransactions: method.
If you don't, paymentQueue:updatedTransactions: is not called for them because they were already in the queue when you have registered the observer.
By the way, make sure you call finishTransaction: for all of your transactions even if they have failed. Otherwise they will stay in the payment queue and cause this issue.
Same problem here.. we launched a new update for our app after iOS 7 release. We have many users now complaining that they are either unable to restore previous purchases. Other users are complaining that their purchase is successful, however the IAP package does not unlock with no error message.. we are a bit baffled here.
I had same problem ! After checking for hours! I just restarted the I pad (iOS7), and now again its working.
I fixed this by signing out the test account from the App Store via Settings app -> App Store -> Sign Out. Then I removed the test account from iTunes Connect, then I rebooted the device.
I was in a similar situation; resolved by restarting my iPhone. Specifically, I had non-consumable purchase hosted on Apple's Server. Installed app to iphone5, made purchase. Deleted App, reinstalled in another build, and upon restore, ITunesStore server didn't respond with my hosted-contact productIdentifier. Purchasing the item again produces "already purchased" error, without an option to download. I found this site, http://support.nimblebit.com/customer/portal/articles/672080-problem-making-in-app-purchase-ios-os-x; restarted my device, and restore now recognizes the previous purchase.

In-App Purchase Auto-renewable Subscriptions

I have an app that sells Virtual Phone Numbers. When an user subscribes, we deliver a new virtual number and the user can manage this number within the app. After that, the user can receive calls but not necesarily through the app. I mean, after the initial purchase the user does not need to open the app to use the service but I need a way to check the subscription status monthly. My question is, can I set up a cron in the server to check the next receipts even the user wont open the app anymore?
Is it possible to sell a subscription service that is not delivered through the app? Thanks.
Take a look at this service that manages IAP and push notifications..
http://urbanairship.com/
IF your service is eligible for auto-renewable subscriptions you can use that ( this is tricky because they reject this if the app dosen't give content. see more here: http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/RenewableSubscriptions/RenewableSubscriptions.html )
I've not done this myself, but the gist I get from the store docs is that you will verify the receipt and get an updated transaction if the subscription has been renewed. So presumably on your server you have some indication of when the original subscription was purchased and the time, so you would check before it expires and get the new transition.
I'd suggest maybe using push notification if this were to fail, to engage the user to update/renew.
You can use the Auto-renewable subscription from apple to serve your users.
When user buy the subscription first time store the receipt in the server.
Maintain the expiry date of the subscription per user in the server DB.
Run the cron job and check for the "Active Status" of the subscription via apple APIs http://tinyurl.com/ay2labm
Depending on the status you can extend the service to your users.
http://tinyurl.com/aeh9f84

Unexpected behaviour with iAP on iOS

I make a fresh install of my App on my iOS device. (I had deleted it, signed off from the GC account).
After the App launch, 'paymentQueue: updatedTransactions:' gets called. It has one transaction with transactionState' == SKPaymentTransactionStatePurchased. (It's the only iAP my App has, in fact).
And then the GC Sandbox Login ViewController is presented.
Why does the iAP object get the Bought State, if I haven't logged in neither with an iTunes account or GC account?
I am not login on Game Center, that's for sure. But I'm not so sure about being being logged in with an iTunes Store Sandbox account. (Does that even exist?) If so, how do I log off?
I want to be able to test my App's 'Restore' button, but as the function already gets called, and the item is shown as bought, I can't... Why does even the function get called when I add the observer to the SKPaymentQueue? To check unfinished transactions? But it shouldn't do so as I'm not supposed to be logged into an iTunes Account...
Please, tell me any ideas you have, this is making me go crazy.
It sounds like you might be failing to call [SKPaymentQueue finishTransaction:] after your transaction is processed - the IAP system will keep attempting to deliver the transaction on every startup until you do that. So just add that call when you're done processing the transaction and you should be all set.

How to redownload an in-App purchase application programmatically

I am able to implement in-App purchase successfully. I am also able to purchase a product through in - App purchase.I am storing purchase information in NSUserDefaluts.So if next time user tries to purchase same product again i am able to handle it locally.My problem is if a user deletes the application from the device,How do i handle the re-downloading of the application without charging for the same product again.I know that if an application has been deleted from the device having in App purchase it has to be downloaded again.Can anybody show a sample code for the same?
Thanks
Aditya
Hi
Thanks for a prompt reply.I have implemented the same as you have suggested.What i'm wondering is if i delete my app and install it again , i am asked to purchase it again.Do i have to pay again for the upgrade or is it handled from the apple server(i.e if i upgrade the same product again am i charged again?).Is there a way to know it was upgraded without asking to upgrade again?
The StoreKit api takes care of this and gives you, on request, a list of identifiers of the purchased items. Once you got those, it's up to you to re-download the products again(if not already bundled inside the app).
Excerpt from the StoreKit API help:
-(void)restoreCompletedTransactions
Asks the payment queue to restore previously completed purchases.
Your application calls this method to restore transactions that were previously finished so that you can process them again. For example, your application would use this to allow a user to unlock previously purchased content onto a new device.
When you create a new product to be sold in your store, you choose whether that product can be restored or not. See the In App Purchase Programming Guide for more information.
The payment queue will deliver a new transaction for each previously completed transaction that can be restored. Each transaction includes a copy of the original transaction.
////Comments pseudo code////
// Reinstall App:
// Restore already purchased transactions...
// Does the NSUserDefaults have the Purchase History??? -
// YES: Load the Table View of Items remaining for sale, Else -
// NO: Get the restoreCompletedTransactions list from Apple
// and create a container to hold previous transaction purchases.
// Fresh new App install:
// When a user makes the first IAP. Add it to the container and NSUserDefaults
// This container will be added to the NSUserDefaults when at least one purchase has been made.