Differentiation between initial purchase and free “re-purchase” in StoreKit / In-App Purchase

In the StoreKit manual:

If a user tries to purchase an unused product or a renewable subscription that they have already purchased, your application receives a normal transaction for this item, and not a recovery transaction. However, the user is not charging again for this product. Your application must process these transactions identically to the transactions of the original transaction.

This presents a huge problem in the application I'm working on. We licensed a large amount of content from the publisher for sale through an in-app purchase. They require that every time we sell part of this content (that is, the user pays us), our server calls the API on its servers to report the transaction. This is for accounting purposes and is ultimately used to determine how much we pay them at the end of the month, by our agreement with them.

I read some suggestions about SO and other places that you often call restoreCompletedTransactions and maintain a local understanding on the device of what the user has already purchased, so they are not allowed to purchase it again. This for me is similar to what should be implemented on the server side. However, the receipts we receive from Apple servers are exactly the same for purchase and re-purchase, as promised in the StoreKit manual.

If callbacks from StoreKit cannot be trusted as a valid accounting mechanism in such a situation (“you paid” or “you did not pay”), what other real-time transaction flow data is available? I don’t think that the publisher we work with will be happy if we tell them that we have to wait 45 days after the end of the month to receive the REAL paid dollar amount from iTunes Connect.

+4
source share
3 answers

I recently addressed the same issue. In my case, I wanted to implement accurate revenue tracking using mobile app tracking to track revenue generated from various customer acquisition campaigns.

Fortunately, there is a way to do this. It should be noted that SKPaymentTransactionStatePurchased vs. SKPaymentTransactionStateRestored depends solely on the initiating action, for example. Have you initiated a recovery or (re) purchase so that this does not work.

Instead, it checks for SKPaymentTransaction.originalTransaction , which will be != nil for recovery and re-purchase. The latter, unfortunately, is undefined ( docs ) behavior. I would consider that this is a fairly honest test.

Another option is to check the transaction-receive transaction using SKPaymentTransactionStatePurchased and verify that the original_transaction_id property in the returned confirmed receipt matches transaction_id .

+6
source

The bad news: In the current version of iOS (4.3.x) there is no way to distinguish between the purchase and re-purchase of non-expendable products.

To alleviate the situation, I would recommend two things:

First

After a successful purchase, save the product identifier purchased product in NSUserDefaults on the device. Then you can hide products already purchased from the user and, thus, handle the situation with a re-purchase.

NSUserDefaults copied by iTunes when a user synchronizes their device. Therefore, your saved purchase information is not lost when the user receives a new device.

Second

Save the receipt data with the device identifier on your server. Review the receipt product identifier and device identifier.

If you receive a different receipt with the same product identifier and a combination of device identifiers, then suppose you buy a repeat purchase. At the very least, this will allow you to cover most re-purchase cases.

Assuming a regular iPhone user switches his device every 1-2 years, you will at least cover most re-purchase cases, and perhaps Apple will fix this in the future.

+4
source

I have one solution,

  • Set up the product as a consumable. this will solve the problem - (They require that every time we sell part of this content (that is, the user pays us)).

  • Then you need to implement the logic in the product purchase option. This happens in such a way that, as soon as the user buys the product, it is necessary to choose the purchase option, otherwise the user can make a purchase and lose money again for the same product on the same device. you can use NSUserdefaults for this purpose.

thanks,

+1
source

Source: https://habr.com/ru/post/1347579/


All Articles