in-app originalPurchase

Hi All,


I'm wondering if there is a way to find out if the purchase is being made for the first time or if its being repurchased (for whatevr reason)


The reason I need t know this is becauseI'm using Fabrics Answers to track in-app purchases. In my case it tags it twice if the user repurchases the same one-time in-app purchase. Of course Apple doesnt recharge them and thats as expected, but I need to check to ensure I only track it if its a first time purchase.


I saw somewhere that there is a flag, something like originalPurchaseDate. Can someone point me in the right direction. Is that flag empty when its the first time or nil? An example of a check against it would be ideal.


Cheers

Ace

Accepted Reply

As noted within the thread above, the correct answer is to compare the updatedTransaction's value for transaction.transactionId to the receipt's value for transaction_Id. IF they differ it is not the original transaction but a repurchase for free.

Replies

You will want to follow this guide:

https://developer.apple.com/library/prerelease/ios/releasenotes/General/ValidateAppStoreReceipt/Introduction.html#//apple_ref/doc/uid/TP40010573-CH105-SW1


You will find that decoding the receipt on the device is difficult. You will be able to send the receipt to the Apple servers and get back the decoded receipt. That can be done directly from the device or it can be done through your servers. Sending directly from the device is subject to various hacks and is therefore not 'best practice' - but it will work for your purposes.


You will want to compare the value in the decoded receipt for original_purchase_date to the value for purchase_date - if they differ it is not an original purchase.


Unfortunately you cannot just rely upon the property transaction.originalTransaction.transactionDate in updatedTransactions because that property is not defined for a purchase, only for a restoreCompletedTransactions.

Hi


I finally got around doing all this and got the receipt an in-app purchases


For both my in-app purchases the dates are the same.


"original_purchase_date" : "2015-10-02 03:56:31 Etc\/GMT",

"purchase_date" : "2015-10-02 03:56:31 Etc\/GMT"

I assumed I may have bought the purchase once in my sandbox so I purchased them again and requested the receipt again using the functions below. The receipt still shows matching dates when it should show todays date in the purchase_date field. I was wondering if you can shed any light on this.


func requestReceipt() {

print("request a receipt")

let request = SKReceiptRefreshRequest(receiptProperties: nil)

request.delegate = self

request.start()

}


func requestDidFinish(request: SKRequest) {

print("request did finish")

let fileExists = NSFileManager.defaultManager().fileExistsAtPath(receiptURL!.path!)

if fileExists {

print("Appstore Receipt now exists")

return

}

print("something went wrong while obtaining the receipt, maybe the user did not successfully enter their credentials")

}

It's been awhile.


I assume you recently made a purchase (actually a second purchase of a non-consumable which you made 'for free' - everything is different for autorenewable subscriptions) and then grabbed the receipt and sent that 'new' receipt to the server. The Swift code above is irrelevant and actually suggests that all you did was refresh the old receipt. What you want to do is get the receipt from within updatedTransactions (after a purchase or a repurchase-for-free) and send that to the Apple server.


I recall the purchase_date being different from the original_purchase_date where both fields were in the in_app array of receipts.

You are saying that the original_purchase_date is correct (i.e. it seems to be back in October) but that the purchase_date is not the date that the app made a second purchase of the same item - is that correct? Can you show what the app store sent back so we can all see?

Yea its been a while. Thanks for the response. Your assumptions are all correct except I'm not sure if I grabbed the "new" receipt.


I did the above code hoping that I can get an updated "new" receipt. The above code is a part of my validateReceipt() that I execute on app launch.

There are other dates on teh receipt. If all you want to do is differentiate a purchase from a repurchase you can do that at the time of repurchase/purchase. I suggest you go back to your last post and edit out your Id then respond on Skype - I think I sent you a contact request on Skype.

I was waiting for you to add me before doing that.


Lets discuss the rest on Skype. I messaged you but you appear offline.

Hey,


Continuing our previous discussion. I'm trying to compare the original_purchase_date from my receipt to todaysDate. Heres where I'm right now


let todaysDate = NSDate()

print(todaysDate) ----> 2015-11-22 17:09:31 +0000

"original_purchase_date" : "2015-10-02 03:27:48 Etc\/GMT",

Technically I want convert original_purchase_date into an dateFormat of NSDate() and compare them to see if they are within 1 minute.


But I'm not really savvy with NSDate stuff

On a side note, PDK and I discovered that on the receipt, original_purchase_date and purchase_date are equal. This would have been expected if the purchase happened on the same day. But we repurchased the same item and the purchase_date still shows the original date.


See example below. I was wondering if any Apple staff can shed some light on this. Is it a mistake on the sandbox receipt or did the meaning of purchase_date change?


"in_app" : [

{

"product_id" : "chronic.iap.proversion",

"quantity" : "1",

"transaction_id" : "1000000174182587",

"purchase_date_ms" : "1443756468000",

"original_purchase_date_pst" : "2015-10-01 20:27:48 America\/Los_Angeles",

"purchase_date_pst" : "2015-10-01 20:27:48 America\/Los_Angeles",

"original_purchase_date_ms" : "1443756468000",

"is_trial_period" : "false",

"original_purchase_date" : "2015-10-02 03:27:48 Etc\/GMT",

"original_transaction_id" : "1000000174182587",

"purchase_date" : "2015-10-02 03:27:48 Etc\/GMT"

}

Isn't the OPD critical for restores?

You can use this type of code (in Objective C - I don't do Swift):


    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
    double timeOriginalPurchase = [[dateFormat dateFromString:[[purchaseInfoDict objectForKey:@"original_purchase_date"] stringByReplacingOccurrencesOfString:@"Etc/" withString:@""]] timeIntervalSinceReferenceDate];

Oh, and you want to capture the time you first issued the purchase request (start a timer) and the time you finally got back the verified receipt (stop the timer). The time difference between those two times must be greater than the time difference between the original_purchase_date (it must be after the timer started) and the receipt_creation_date (it must be betfore the timer stopped) for the purchase to be an actual purchase and not a repurchase for free. You need this because of the possibility that the system asks for credit card information or some other delay that might be more than 1 minute - and usually this time will be much shorter so you have a more stringent test.

oh boy this sounds super complicated and not worth the hassle in my opinion. I'm actually surprised a

Apple doesn't have a .Repurchased state. or why the purchased_date within the receipt isn't updated upon repurchase.


any Apple staff to shed some light on this? Or any other devs that dealt with it?

I just went back to the 2014 archives on this subject and realized the correct answer.


In updatedTransactions you grab the transaction.transactionId for the latest transaction. (I don't think you can grab the originalTransaction.transaction.transactionId out of updatedTransactions if it is not a restore.) Then you examine the receipt for the IAP's "transaction_id". If they match then it is an original purchase. You actually need to do this for non-renewing subscriptions to avoid granting repeat subscriptions.


No need for the NSDate stuff.

As noted within the thread above, the correct answer is to compare the updatedTransaction's value for transaction.transactionId to the receipt's value for transaction_Id. IF they differ it is not the original transaction but a repurchase for free.

Appreciate the feedback. Take a look at the receipt snippet above. The transaction_id == original_transaction_id


Going back to our discussion, not sure if I'm doing something wrong or its because I'm in sandbox environment.

would love if someone can confirm they are indeed different in production