How to detect refunded IAPs from receipts?

Hello all,


I've been looking at various other threads trying to decipher this, but there don't seem to be clear answers.


My question is the following: if I want to develop an app with In-App Purchases, but I want to know when those IAPs were refunded, how can I do that? My plan was to keep receipts server-side, and to keep checking with Apple's servers until the refund period ends (how long that is exactly is another matter).


However, it's not clear from the documentation how I can tell by a receipt, that an IAP was refunded. I read here about the cancellation_time field:


https://developer.apple.com/library/ios/technotes/tn2413/_index.html#//apple_ref/doc/uid/DTS40016228-CH1-RECEIPTURL


however, I have a few questions.


  1. The link mentions that "This field is set when a customer contacts Apple customer support for a refund and the transaction is canceled." Does this happen if a user in the EU cancels an IAP with no questions asked, within the first 14-day window after purchase?
  2. According to the link, cancellation_date might appear in various places, depending on circumstances I don't fully understand: "
    cancellation_date
    is not automatically added to your app's receipt when set. It appears in the
    latest_receipt
    section of your app's receipt when the receipt is updated (for instance, when a new payment transaction occurs or when you restore purchases using SKPaymentQueue’s restoreCompletedTransactions), when your app calls SKReceiptRefreshRequest to refresh it, or when your app performs receipt validation with the App Store (
    https://buy.itunes.apple.com/verifyReceipt
    ). Note: If your app validates its receipt with the App Store and your subscriptions are still valid, then
    cancellation_date
    will appear in the
    latest_receipt
    section of the returned receipt. If your subscriptions are expired,
    cancellation_date
    will appear in its
    latest_receipt_info
    section." Is there a series of steps a server can take, using a receipt, to be certain whether an IAP has been refunded?
  3. How long do we need to keep checking for refunds? Can users refund their IAPs after the initial 14-day grace period (in Europe, at least)?


Thanks in advance.

Alexander

Accepted Reply

You will want to see this reference:

https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html



The cancellation_date field will be set if the user cancels the purchase. But it is set only in receipts that issue after the user cancels the purchase - not before (because of causality - cause must precede effect). If you have an old style receipt (iOS6 - transaction.transactionReceipt) and you send that old style receipt to the Apple servers for decoding then the Apple servers will append to that receipt the latest_receipt_info field and that added field, not in the receipt, will contain a cancellation_date if appropriate. But if you have a new receipt (iOS7 and later - from [[NSBundle mainBundle] appStoreReceiptURL]) then Apple servers do not update that receipt, they just decode it. So if a user makes a purchase then their receipt will not have a cancellation_date in it. If they subsequently cancel the purchase then their old receipts will not magically transform. You will need to refersh their receipt to discover whether or not there is a cancellation_date.


So the answer to your questions are 1: yes. 2: refresh the receipt or call restoreCompletedTransactions or rely on finding a deprecated transaction.transactionReceipt at your peril. 3: Forever and yes or ignore the problem because after all there are very few refunds

Replies

You will want to see this reference:

https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html



The cancellation_date field will be set if the user cancels the purchase. But it is set only in receipts that issue after the user cancels the purchase - not before (because of causality - cause must precede effect). If you have an old style receipt (iOS6 - transaction.transactionReceipt) and you send that old style receipt to the Apple servers for decoding then the Apple servers will append to that receipt the latest_receipt_info field and that added field, not in the receipt, will contain a cancellation_date if appropriate. But if you have a new receipt (iOS7 and later - from [[NSBundle mainBundle] appStoreReceiptURL]) then Apple servers do not update that receipt, they just decode it. So if a user makes a purchase then their receipt will not have a cancellation_date in it. If they subsequently cancel the purchase then their old receipts will not magically transform. You will need to refersh their receipt to discover whether or not there is a cancellation_date.


So the answer to your questions are 1: yes. 2: refresh the receipt or call restoreCompletedTransactions or rely on finding a deprecated transaction.transactionReceipt at your peril. 3: Forever and yes or ignore the problem because after all there are very few refunds

Thank you very much for your answer! That's great.


As for refunds, let me know if I'm mistaken, but I think I can't ignore the problem. The reason is that even though in general people might not request refunds that often, in my case, I think they might use the refund to keep the content permanently for free.


I also want to unlock content on another platform when people make the IAP in the App Store, which means that people can buy the content on the App Store, refund it immediately, and keep the content in the other platform.


So, to be clear, you're saying that there's no time when we can stop checking for refunds. The scenario I'm describing above is always possible.


Am I right to assume, though, that after the 14-day grace period (wherever that holds), people will have to convince Apple support to give them a refund, and thus only at least quasi-legitimate refund requests will go through? So, checking for these first 14 days might be practically enough.

Please do the experiment for us....tell us how many of your users ask for a refund in the first 14 days (as per European law, I believe that Apple cannot refuse a refund in that time period) and how many do it after that time period. And, if you can, tell us how many users who ask for a refund, and then realize they lose the content, actually miss it and repurchase the item. I suspect the answer will be few and fewer thereby eliminating the need to check - but I could be wrong.

Thanks for the answer!


Well, if I don't check for refunds on the server side, the users will keep the content in the other platform I mentioned, so I'm not sure how bugged they will be 🙂


The question remains, though: people who ask Apple directly for a refund, will have to convince Apple they have a legitimate reason for it, right? So that should be rare.

Not sure about this but I recall a European law provision that requires refunds for software no-questions-asked if requested within 15 days. I recall Apple adding a provision into its user contracts that addressed this provision and essentially eliminated it. With the above exception, refunds from Apple require a good explanation (e.g. It doesn't work on my 3GS or my 3 year old bought it).

Thanks.

Can this solution be used for consumable product?

No. Unless you are refering to this 'solution':


"ignore the problem because after all there are very few refunds"

Up until today I would have agreed, that there are very few refunds. However, today I had a large number of refunds -- equivalent to about 10+ days worth of in-app purchase sales. These were mostly for consumables, which, no-doubt, had already been consumed.


So for example, on a normal day I might see 10 in-app purchases and today I suddenly saw 120 refunds. Something along those lines.


I found a few other threads here talking about that some people will commit fraud this way -- basically:

1) Buy the IAP

2) Use the IAP in the app or game (especially effective if it's a consumable)

3) Go get a refund from Apple

4) ... and thereby keeping what they didn't pay for.


I've found others have had similar things from time to time -- occasionally having very outsized refund amounts.


What bothers me is that, if what you say is true -- that you can refund for any reason within 14 days, there is no reason for these users to refund again and again.


If I could reverse their purchases in some way when they get refunded, they would probably only do it once.


Anyway, thanks for the information on receipts and cancellation date checking. I will look into it.

Keep in mind two things that limit the loss here: 1) I suspect (aka hope and expect) that a user who asks Apple for more than one or two refunds will be rejected. 2) what you are losing is not the cash value of the refund since the dishonest user most likely would not have made the purchase if they weren't anticipating the cancellation. You are losing the cost of providing the consumable. You are suffering a loss only if that is a real cost.