How to track In-App Refund in ios app [duplicate] - ios

Situation:
- User makes an IAP and is awarded some content, we store the users device id to ensure they can access this content whenever they want.
- User decided they do not like the content, so they call Apple and get a refund.
- User can still access the content, even though they have been refunded for their IAP
Problem:
We don't want the user to be able to access this content anymore. This could become a loophole that they would take advantage of. (unlock content, then get refunded and keep their access to said content)
Question:
Is there any way for us to check if a user has been refunded for an IAP with either their transactionId, transactionReceipt, or any other information we may have?
For Reference, I've read the StoreKitGuide, it did not mention this case.

No. There is no way to revoke access to content if they have been refunded. I believe this is by design. It is the same with App Store refunds; if someone buys an app and then asks Apple for a refund, Apple does not stop the user from continuing to use the app.

No. you cannot stop user to access. Apple does not stop user to use that feature after refund

Below a recent answer from the overbearing Apple!!!
At April 11
Hello Joe,
Thanks for your quick reply at first.
I think there were some misunderstandings. We understand that you must protect the user information. And we do not require any user info. We do not require any user's information---- iTunes account, User Name, email address and other information about himself/herself.
We require only one data----- transaction id (named "transactionIdentify" in your code), for example "1000000033409668" (this transaction id is a record at March 13).
A user buys a product from IAP, you will generate a "transaction id" and send it to us. This transaction id is stored in our database then. Now he/she gets refunds from you, so please send the transaction id to us. Let us know which one in the game canceled the IAP.
When a refund occurs, we think you should provide the transaction id to us. With these data, we could make a more fair service for all players. If you do not do it, more and more players will use your refund mechanism to get game items without real payment. You and we will lose money then. We think it is very important.
Regards,
Baibo
At April 12
Hello Baibo,
Thank you for following up with me regarding the refund transaction data.
We will not be able to provide you with the refund transaction data you have requested as it is not a feature or benefit provided to you per the contracts you have agreed to.
To view your paid applications contract and review your membership benefits, please access the contracts, tax and banking module within iTunes Connect:
http://itunesconnect.apple.com
If you are not happy with large refunds, you may want to consider adjusting the price of your in-app purchases as we will not be able to provide you with the refund transaction data in the future.

According to an answer one of my users received from Apple, refunding an app means they will no longer receive updates to the app, but doesn't remove the app from the device. IAP appears to work the same.
I am wondering if there is not a way by using restoreCompletedTransactions to check for the iAP purchase, but this would pop up a request for the user's iTunes password, so its use is limited.

Related

Linking Apple ID to an multiple account/user on my server

Background:
I am trying to implement In-app purchasing for my iOS app. The app allows the user to be able to log in to multiple accounts and register multiple accounts. Each registration will require the user to pay a subscription fee (unless a free plan is selected). When the registration is complete the account will be linked to the Apple ID that paid for the subscription.
Question:
If already have done a registration with my current Apple ID(Account A) with a $0.99 subscription every month and then do another registration with the same Apple ID(Account B) with a $1.99 subscription every month. Both accounts have purchased a subscription with the same Subscription Groups. In that case will that Apple ID just be paying for the subscription of Account B since it would be considered an upgrade from Account A.
I can make it so that when an account is created with an Apple ID that have been used, we link the new account with that Apple ID and disable the older one. This would however provides a bad user experience and only ever one account will work with one Apple ID and probably isn't the solution I want.
I did try to set the ApplicationUsername for SKPayment object in hopes that it will appear on the other side when the notification API is hit by Apple but it don't seem to use it for that and is used to detect fraudulent activity.
I am trying to find some documentation on handling this case but to no avail. I'm not too sure how to get around this issue and have a feeling that my app's implementation is not aligned with how Apple expects us to implement it. Maybe I have misunderstood some documentation but any insight to this would be greatly appreciated.

Apple In-App Purchase: How apple use the applicationusername to Detecting Irregular Activity?

In apple's document, it says developer can use the applicationusername to Detecting Irregular Activity,but i don't know how to use it.The document just says hash a userId,but how can i detect the irrgular activity? Does the apple's server have a server API to notify me ?
Here the link:
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/RequestPayment.html#//apple_ref/doc/uid/TP40008267-CH4-SW6
Let's day your app uses an account system so each user has an identifier (email, username etc) which we refer as appId here and the app store login as appleId
Scenario:
Say user purchased a subscription with a trial period (txn123) with appId usr123 having appleId appl123
Later she unsubscribed the subscription.
After few months she changed the AppleID for some reason.
Again she wants to purchase the subscription.
She will login into the app using same appId, usr123.
As she already has used trial with that appId, your app will recognise her, and will show buy button to her.
When she will click on the Buy button, Apple UI will show that she is eligible for Trial, and will be charged after 7 days.
If you had passed the applicationUserName field in the payment(payment object) in the both the transaction user makes, apple will recognise that and may take a remedial action (like actually charging the user instead of offering a second trial period).
At this point I am not sure, how Apple is going to inform your app/ecosystem about this irregular activity. I have not tested this scenario myself as yet, will update the answer once I have done so.
Several things may happen:
Apple declines the second purchase because it detects the irregular activity of the same user purchasing the trial period again. But how would Apple know if the user is intentionally trying to make the purchase now after trial has expired. Anyways, apple can say that this user seems to be associated with some other apple id also which has made a purchase in the past, thus not allowing the transaction with the pair.
Apple may actually charge the user, since they are trying to buy after a trial but in this case Apple will be offering a Apple Id user without a trial period in their name.
Apple may allow the transaction with trial period offering and may resolve this through other/offline channel.

Does Apple communicate with App Provider/Devs before providing refund to a customer for In-app purchases iOS?

If I am the App provider & developer, one thing I did understand about the refund process is that the user can directly ask Apple for a refund. Now my question is whether Apple asks the App provider/Devs for whether the refund should be made or does it decide on its own? If it does, then does my content still remain available to the user? I read another question that Apple doesn't notify the App of a refund. Also if I am not concerned with the refund process,because providing the content is my responsibility, how will I know if a product has been refunded or not so I may stop this to the user who has?

Refund the previously purchased non-renewing subscription, not the current one. Possible?

I'm implementing an iOS app with non-renewing subscription. Not much relevant information was available online; so I seek your guidance.
A use case which worries me the most is when a user purchased the subscription once and then immediately after purchase it again to extend the duration of service (see such scenario here). What if that user were to refund the first purchase, leaving the second one intact? Is this even possible in practice, or am I just too paranoid?
Assuming the above case is possible, my app will run into a problem because, as far as I know, verifyReceipt only returns the latest, good receipt (watch Managing Subscriptions with In-App Purchase in WWDC'12).
I find nowhere Apple provides relevant information about refunding policies.
(Auto-renewable subscription seems to rule out this case as a renewing action is taken care by iTunes automagically and it seems not possible to extend this type of subscription until iTunes allows it.)
verifyReceipt will not only return the latest good receipt, it will also tell you if the receipt you submitted for verification is good. So if you're concerned that a user may have cancelled* a transaction, then submit every receipt you're questioning.
*But what do you mean by "cancel" the first purchase? Do you mean when they tap "cancel" instead of "buy?" Well then the transaction won't go through and you won't even get a receipt.
Or do you mean when they request a refund? I don't know any other way they can cancel a purchase.
Edit:
If you're referring to refunds, there's no way for a developer to tell if a user has been issued a refund. The assumption is that Apple expects you to continue to deliver services to that user regardless of the fact that they received a refund. Your receipts will probably all verify correctly regardless of the status of a refund.

Differentiating between initial buy and free "re-buy" in StoreKit/In-App Purchase

From the StoreKit guide:
If the user attempts to purchase a nonconsumable product or a renewable subscription they have already purchased, your application receives a regular transaction for that item, not a restore transaction. However, the user is not charged again for that product. Your application should treat these transactions identically to those of the original transaction.
This presents a huge problem in an app I am working on. We have licensed a large body of content from a publisher for sale through in-app purchase. They require that every time we sell a piece of this content (i.e. user pays us), our server calls an API on their servers to report the transaction. This is for accounting purposes and ultimately used to determine how much we pay them at the end of the month, per our agreement with them.
I have read several suggestions on SO and elsewhere about calling restoreCompletedTransactions rather frequently and maintaining a local understanding, on the device, of what the user has already purchased so they cannot be allowed to purchase it again. This to me seems like something that should be able to be implemented on the server side. However, the receipts that we are getting back from the Apple servers are exactly the same for a buy and a re-buy, as promised by the StoreKit guide.
If payment callbacks from StoreKit cannot be trusted as a valid accounting mechanism in this kind of situation ("you got paid" vs. "you didn't get paid"), what other real-time insights into transaction traffic are available? I don't think the publisher we are working with is going to be happy if we tell them we have to wait 45 days after the end of the month to get the REAL paid dollar amount out of iTunes Connect.
I have recently looked into the same problem. In my case, I wanted to implement accurate revenue tracking using Mobile App Tracking to track revenue generated from different customer acquisition campaigns.
Fortunately enough, there is a way to do it. It should be noted that SKPaymentTransactionStatePurchased vs. SKPaymentTransactionStateRestored solely depends on the initating action, e.g. whether you initiated a restore or a (re-)purchase, so that doesn't work.
What does work instead is checking for SKPaymentTransaction.originalTransaction which will be != nil for restores and re-purchases. The latter is unfortunately undefined behavior (docs). I'd consider a null check fair enough though.
Another option is to validate the transaction-receipt of transactions with SKPaymentTransactionStatePurchased and check that the original_transaction_id property in the returned, validated receipt matches the transaction_id.
The bad news is: In the current iOS version (4.3.x) there's no way to distinguish between a buy and a re-buy of non-consumable products.
To ease the situation I would recommend two things:
First
After a successful purchase, store the product identifier of the purchased product in the NSUserDefaults on the device. You can then hide the already purchased products from the user and thus handle a re-buy situation.
The NSUserDefaults are backed up by iTunes when the user synchronizes his device. So your stored purchase information is not lost when the user gets a new device.
Second
Store the receipt data together with the device ID on your server. Analyze the receipt's product identifier and the device ID.
If you receive another receipt with the same product identifier and device ID combination, then assume a re-buy. At least this would allow you to cover most of the re-buy cases.
Assuming that an ordinary iPhone user switches his device every 1-2 years, you will at least cover most of the re-buy cases and maybe apple will fix this in the future.
I have one solution,
Configure the product as consumable.
this will solve the problem - (They require that every time we sell a piece of this content (i.e. user pays us)).
Next you need to implement a logic in product buy option. It is in a way that once the user purchase a product the buy option need to remove otherwise the user may happendly go purchase and lost is cash once again for same product in same device.
you can use NSUserdefaults for this purpose.
thanks,

Resources