Hi after updating the IAP package to 2.3.0 from 1.23.1 (Unity 2018.4.23). GooglePlayReceipt transactionId is not matching with PurchasedProduct transactionId.
Validation code
public bool Validate(PurchaseEventArgs e, out IPurchaseReceipt productReceipt)
{
var receipt = e.purchasedProduct.receipt;
var productId = e.purchasedProduct.definition.storeSpecificId;
var transactionId = e.purchasedProduct.transactionID;
productReceipt = null;
try
{
var purchaseReceipts = _crossPlatformValidator.Validate(receipt);
foreach (var purchaseReceipt in purchaseReceipts)
{
if (purchaseReceipt.productID == productId && purchaseReceipt.transactionID == transactionId)
{
productReceipt = purchaseReceipt;
break;
}
}
}
catch (IAPSecurityException)
{
return false;
}
return true;
}
I can second to this issue, while the unity IAP API gave us an interface with the purchasedProduct as an event (via the
PurchaseEventArgs param) we could match the e.purchasedProduct.transactionId with the receipt.transactionId easily, now those two are diffrent on the android platform (e.purchasedProduct.TransactionId is now being provided as the GoogleBilling v3 purchase token as @JeffDUnity3D stated, while the receipt transactionId stayed in the old format (GPA.xxxxx)).
Please note that this behaviour is clearly wrong on the android side of thinks since the iOS side of things we can still exactly match thee.purchasedProduct.transactionId with the receipts TransactionId
Hi Jeff, Yes I’m aware of that change, but the current implementation is very counterintuitive. A field value must return the same value for all implementations. And also without casting interface to GooglePlayReceipt, it’s impossible to compare.
I do your suggestion as a temporary workaround however this shouldn’t be recommended/suggested way.
For reference, this is my current implementation
if (purchaseReceipt.productID == productId
&& ((purchaseReceipt as GooglePlayReceipt)?.purchaseToken == transactionId
|| (purchaseReceipt as AppleReceipt)?.transactionID == transactionID))
{
productReceipt = purchaseReceipt;
break;
}
What are you using it for? Just checking, if you are not using it then you of course don’t need to store it. And what do you mean by legacy changes? IAP does indeed now use the purchaseToken. Google has not been consistent in this area, and we are hoping for improvements in the upcoming Google Billing Libraries 4 and 5.
For my game, for online co-op sessions (allowing a party to quit and resume their game later), I’m storing some sort of unique ID from Unity’s IAP info after the player purchases a one-time IAP, so my servers know which player is which when resuming.
At first, I thought receipts would be unique, but no.
TransactionID seems to be consistent between sessions and devices at least.
If TransactionID changes later in the future, I’ll handle it, but I can see the Google purchaseToken is used for now. And Apple transactionIDs seem consistent.
Trying my hardest to not bother the user about creating a special account for my game, as I’d have to create my own account system! Just requiring them to sign into Google Play or Game Center, then linking to their purchase, is good enough if I can help it.