We need to implement restore functionality for purchases on iOS. We offer subscriptions and consumables in our products, so all the restored purchases should be subscriptions (it looks like they are by looking at the product ids).
I have followed the documentation and added a method that triggers the purchase restore functionality for ios using the IAppleExtensions.
IStoreListener.ProcessPurchase(PurchaseEventArgs purchaseEvent) is successfully invoked, however it is invoked for a bunch of transactions that we cannot validate against our backend records using the transaction Id.
Also, recently purchased subscriptions doesn’t seem to be coming back.
Is the ProcessPurchase callback being invoked for previous purchases in any particular order? (i.e. most recent first)
Does unity IAP pick up sandbox payments properly ?
Does unity IAP pick up subscriptions on trial ?
NOTE: I Also noticed that ProcessPurchase was triggers as part of the initialisation process on iOS, however the documentations states that that shouldn’t be the case?
Apple bundles all receipts. ProcessPurchase is not called in any order. Not sure what you mean by “pick up payments”. But yes, if I understand correctly. What is your observation with subscriptions on trial? We are working on improved subscription support including trials as we move to StoreKit2 by the end of the year.
When I say pick up i basically ask whether ProcessPurchase will be invoked for sandbox payments/ subscription on trial.
The problem I am trying to resolve is, how can I detect what’s the latest/valid purchase from all these subscription purchase transactions ?
When i try to test the functionaity I :
buy a subscription product (sandbox)
delete the app
re-install
try to restore
At this point, none of the transaction ids that are being restored maps to the latest purchase.
Also it takes some time before unity IAP allows a subscription purchase to go through again (but i think that’s a problem with the nature of sandbox subscriptions that don’t last long)
I am getting wrong transactionIds on iOS. I am querying the transaction id that can be found in purchaseEvent.purchasedProduct.transactionID. Am i missing something ?
This is how you can find the originalTransactionIdentifier from an AppleInAppPurchaseReceipt. That receipt can be found in the purchaseProduct.receipt.
private void LogAppleReceiptValidationInfo(IPurchaseReceipt productReceipt)
{
var appleReceipt = productReceipt as AppleInAppPurchaseReceipt;
if (appleReceipt != null)
{
LogConsole($"Apple - Original Transaction: '{appleReceipt.originalTransactionIdentifier}', Expiration Date : '{appleReceipt.subscriptionExpirationDate}', Cancellation Date : '{appleReceipt.cancellationDate}', Quantity : '{appleReceipt.quantity}'");
}
}
The receipt you have is a string as a JSON hash, the same as the link you posted.
From that receipt (found in purchaseProduct.receipt), you can use the CrossPlatformValidator.Validate which will return an array of IPurchaseReceipt.
Alternatively, you can also use the AppleValidator.Validate to obtain an AppleReceipt which has inAppPurchaseReceipts containing an array of IPurchaseReceipt.
See both examples (Store-specific details and Parsing raw Apple receipts):
Thanks! I used cloud verification instead and managed to get the original transaction id.
When attempting to restore purchases (subscriptions in my case) do we need to call StoreController.ConfirmPendingPurchase for any result we get back?
I get some weird behaviour where, when i try to restore purchases and nothing comes back from Unity IAP, and then I try purchase the product, unity IAP fails the purchase with a reason Duplicate Transaction.
No, there is no need to call ConfirmPendingPurchase during restore. Basically treat it like a brand new purchase. You should see ProcessPurchase triggered for each product that is restored.
I got 2 subscriptions which must be verified on app start. I was able to test it on iOS only using Test Flight using my actual Apple ID account (not a sandbox user).
By some reason, each time starting the app I am forced to make the subscription purchase because these 2 subscription products just doesn’t have a receipt so I can’t verify, is subscription active or not.
Even knowing the fact it’s not related to purchase restore feature (because app wasn’t re-isntalled) but trying to restore purchases using appleStore.RestoreTransactions method, I receive only true as a result, but never receive
ProcessPurchase callback. Also, checking the subscriptions receipts after restore I can’t get any info, because receipts were not found.
Furthermore, once I see these logs trying to restore the purchase - by some reason there wre unfinished transaction
How to get the ProcessPurchase callback and make the things works as expected?
I am on Unity 2021.3 and IAP 4.5.1
UPDATE
Finally, I could make it work using Sandbox user login in AppStore app settings. However, there are still no callback after purchase restore request - if user without any subscription tries to restore purchased, I still will get true as a response. Sounds logically if that callback represents just a restore purchase request result, but in terms of app development it’s impossible to understand in right time does user has a purchase or not. If he has, I will get the process purchase callback what is fine, but if not, I need to check the receipt again after getting true in purchase restore request, but I need to do it in some delayed time, becuase can be the case that
process purchase callback can be delayed…