Testing IAP edge cases in iOS (eg: missing credit card info, etc.) - ios

We currently have an app in the app store that uses IAP to disable ads and add a few features.
However, we've noticed that some users have problems buying the IAP. After scrutiny it seems most of it comes down to not having an active internet connection on the moment of purchase. About a dozen cases however could not be tracked down and resolved.
One of these:
tap buy IAP
Credit Card security code was not yet filled in
purchase fails
user is automatically moved to his App Store account to fill in the missing code
user fills in code and confirms buying the IAP
user goes back to the app
purchase is still failed (!)
Conclusion: user paid and did not yet receive the IAP.
(of course this can be resolved by tapping the IAP again and downloading for free, but that's not ideal)
We're looking to test a solution to such edge cases.
However test accounts usually do not require valid CC info. Thus..
Question: How do I test such cases?

I have been using prepaid credit cards to test and make sure it goes through.

Related

Testing iOS subscriptions upgrade/downgrade on sandbox

At the moment, we have one auto-renewable subscription on our live app, and we want to add two more, where the only difference is the price and the subscription time. To accomplish that, we created a "subscription group" and everything is set up on the apple side:
and the app is currently reading all the packs from the store and allow the user to buy them.
Our issue is that we can't fully test the upgrade/downgrade feature when trying to buy another subscription level on sandbox (iOS 14.5). If we buy the lowest pack first, and then try to buy a superior pack, a popup should appear saying that we want to modify our current subscription plan to another one and that it will start on XX/XX/2021 as seen here (image from a tutorial):
This is not the behaviour we are seeing on our app (on sandbox). When we try to buy a superior plan the app shows the normal purchase popup:
and it proceeds to buy the pack normally without showing the popup warning that we are changing our current plan.
This causes some concerns, as it implies that the user is buying two subscriptions. They are on the same subscription group, so it should be impossible, but still brings concerns... Did anyone experienced the same issue? Is this the normal behaviour in sandbox?

Should in-app purchases be present after logging out of iTunes?

I am developing an iOS app. It will have non-consumable in-app purchases.
Q1. Let's say that a user is logged in on their iPad or iPhone to "iTunes & App Store" with "account1", then purchases the in-app purchase, and then logs out of "iTunes & App Store". Then they return to the app.
Should their in-app purchase still be present? Not will it, but should it?
If not, my questions are answered. On the other hand, let's say it should be present. Then I have a follow-up question.
Q2. After following all the above-mentioned steps, the same user logs in to "iTunes & App Store" with a different account, "account2". Should the in-app purchases they made with "account1" still be present while logged in as "account2"?
If you can enhance your own clear and succinct answer with an official statement from Apple, that would be awesome and much more likely to be marked as the solution! If not, thanks in advance for your personal thoughts, ideas, and opinions regarding the best user experience... if Apple doesn't have a clear position on this, then whoever makes the best case will have their answer marked as the solution.
Certainly an unusual case for two users to enter their App Store credentials on the same device. That said, the closest I can see to Apple having something to say about this is:
"Non-consumable products. Items that remain available to the user
indefinitely on all of the user’s devices. They’re made available to
all of the user’s devices. Examples include content, such as books and
game levels, and additional app functionality."
If you take this literally, and if you consider the device still being the same user's even if they have logged out, then I suppose you should make sure you award the non-consumable to the new user as well.
In my experience, many apps store locally when an IAP has been purchased so if the app has not been deleted, any user will see the unlocked content. Your app won't necessarily know that a new iTunes user is using the app, so it would be hard to detect that a new user was using it and revoke the content.
Additionally if you didn't want two users to potentially share a purchase, it would make more sense, in my opinion, to make the purchase a consumable and enforce some sort of log-in mechanism in your app such that it is credited to an individual authenticated account.
Purchases are literally stored in a file in the app bundle on the device. The path or url to the file can be accessed using appStoreReceiptURL. This documentation states:
In OS X, if the appStoreReceiptURL method is not available (on older systems), you can fall back to a hardcoded path. The receipt’s path is /Contents/_MASReceipt/receipt inside the app bundle.
While this is quote specifically mentions OS X, the same is true for iOS with the exception that the result is a localised app url. To support this further, the documentation for NsBundle (which is what appStoreReceiptURL returns) states:
An NSBundle object helps you access the code and resources in a bundle directory on disk.
So with this understanding, we can conclude that purchases are not stateless. They remain within the context of the app. If a user signs out of iTunes, the file isn't deleted.
If an app listens to the SKPaymentQueue, new transactions will come in from time-to-time, particularly when a user buys an auto-renewing subscription. If the user is signed out of iTunes they will receive a request to sign in with the account they originally subscribed with in order for the app receive and save the new receipt. But I digress.
By retaining the purchase state in the app, it allows the purchases to be used without an internet connection. Since an offline device can't authenticate with Apple, keeping the purchase state anywhere else would break this functionality. So yeah, it should be present.
As for Q2, the receipt for account1 is replaced with account2 once a transaction for account2 is received. However until account2 has their made first transaction account1's receipt will still be on disk. This can be used as an exploit to share purchases between users and AFAIK, no good solution exists without using your own user accounts. There are a bunch of stack posts describing this problem.
Should it happen? I wish it didn't, but it seems it is an unintended consequence of the stateful design of the purchase receipts.

How do I do a "combined" subscription model in iOS app?

We have a print magazine and we're going to release an app with subscription model, sort of kiosk app but with extended functionality.
Well, what we want is to solve the following cases:
Case 1 (complex)
User buys a print issue and discovers a promo code in it. This code should allow user to download free digital copy of this issue from our app.
User launches the app, opens a dialog box where he can enter the promo code.
Voila! User gets his free digital copy of purchased print issue.
Digital issue always remains in his list of purchased issues and is a valid purchased issue with all App Store options available for them (restore, etc.)
Case 2 (simple)
User does not have a print issue. He launches the app and buys the same digital issue using IAP.
So, both issues are the same (i.e. "blablabla magazine", November, 2014) but 1st was downloaded using a promo code, and 2nd was purchased with IAP, and they both should have the same properties and "weight" for App Store.
Problem is I don't know if this model will be approved by Apple. Or, if they do, how do I develop this? AFAIK, list of purchased and non-purchased items is provided by App Store and there's no way to intervene this process.
I didn't find any samples of using 3d party promo codes in iOS apps. Can anyone provide a solution for this, please?
Thanks
To keep a record of the promo code usage, I think the simpliest way to do it is to require an account. Once the user is logged with his account, you can tell a server that the promo code have been used with that account. If the user delete/reinstall your app, you will be able to restore all his promo codes from his account.
For your issue with IAP and promo codes, here is the App Store Review Guidelines
See the 11.16 section:
Apps may enable additional approved features or functionality when
used in combination with specific approved physical products (such as
a toy) as long as the additional features and functionality are either
completely dependent on such hardware (for example an App that is used
to control a telescope) or also available through the App without the
physical products, such as by way of reward for achievement or by use
of IAP
So basically, what you want to do shouldn't be rejected.
But by experience when you do something that borderline with Apple's money (possibility to "undercut" IAP), you should expect a review failure, whatever the guidelines review says.
Keep in mind that the guidelines can be interpreted in your advantage, or in you disadvantage.

Apple App Store - bypass listed purchase price?

Is there a way to offer a purchase free of charge for in-app purchases? I'd like to give a free download as a promotional item and not charge the normal price that is listed in iTunes.
You have to code for this in your app. In my app all purchases are registered on parse.com and sync'd between user's devices. I can add a purchase to the class on parse.com for a user and then they get the IAP for free when the data sync's to their device.
Apple don't have any mechanism for this like they do with app purchases unfortunately. The best way I've found is a custom URL scheme, so you can generated a code/string of your custom URL type ://myApp/123456promoCodeFooBar12999 etc, then your app, in response can connect to your server and check this code off against your database (confirming that it has not been used before, and can't be used again on a diff device) before unlocking the feature. This circumvents needing to get UUID's off people etc (which you can't do in code anymore to check against anyway), you just need an email address, send link, user clicks in it, your app opens and away you go :)
edit addition 28 Feb 2014..
an alternate approach might be to submit an separate paid version of the application in which all upgrades are unlocked because they are paid for upfront at purchase time. You may choose to keep this off the iTunes shelf but occasionally put it up, perhaps at a prohibitively high price, $1000 etc, because you can get the normal promo codes off Apple for this one to give to journalists etc, just explain what you are doing to them in your cover letter and I'm sure they'll be more than happy to play ball

Is it possible to detect when a user has re-purchased a non-consumable IAP for free?

When a user of an iOS app purchases a non-consumable item, then installs that app on a new device, it is possible for them to again go through the standard purchasing logic for that item. The app store will ask them if they wish to spend $0.99 on the item, but if they click "Yes", it will inform that they already own that item, and ask if they wish to download it for free.
I would like to track new purchases in my analytics, and not have them conflated with re-purchased items that a user receives for free. Unfortunately, it seems that this behavior is indistinguishable from a genuinely new purchase, (to the client app). Apple seems to say as much: "Note: If the user attempts to purchase a product that’s already been purchased, rather than using your app’s restoration interface, the App Store creates a regular transaction instead of a restore transaction. The user isn’t charged again for the product. Treat these transactions the exact same way you treated the original transactions."
In discussing this issue, most posts (and Apple's documentation) say that I should offer a 'Restore Transactions' button to the users. I do offer this button, but it is always possible for users to circumvent this logic, and go through the traditional purchasing route. This is where my tracking will become inaccurate.
Do I have any options? Thanks!
I am pretty sure you don't have any options for tracking a new purchase versus downloading a previous purchase for free when a user does an in app purchase. I have looked into this for the same reason of analytics and I could not find a way to do it. IAP is set up to make sure that you honor purchases made by the same iTunes account on other devices.
If your users are required to have an account specific to your app to make a purchase you could use that to know if they already have made the purchase or not. But requiring an account for purchase can lower your conversion rate.

Resources