Unity IAP: How to differentiate between restored purchase and regular purchase?

In both case PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) function gets called. But I want shiny animation to play on new purchases, and “silently” restore the old ones (no animation). Is there any way to tell in the PurchaseProcessingResult function if it’s a new purchase or a restored one?

No, there is currently no way to differentiate both cases inside ProcessPurchase, and there will be no notion of restoration or regular purchase in PurchaseEventArgs.

However, products restoration happen during the first initialization following reinstallation, so you can use that. For example, you can check when ProcessPurchase is called whether the user is currently browsing your app’s in-game store. If that is the case, then you can assume this was a regular purchase. Otherwise, it is probably a restoration.

Another way would be to store all productIds owned by this user on your own server, and check after any transaction whether the product was already owned.

Same here. I suppose we should store receipts on server to check duplicates.