Hello,
Recently we upgraded Unity IAP’s version to 1.23.3, and when we released the app, some small amount of Android users have problem when purchasing consumable items. We validate receipts with our backend server, but recently our server rejected the receipt because some of the fields were missing, and somehow it contained some old information. Details below.
This is the correct receipt which was processed successfully.
{
"Store":"GooglePlay",
"TransactionID":"GPA.****-****-****-*****",
"Payload":"{
\"json\":\"{
\\\"orderId\\\":\\\"GPA.****-****-****-*****\\\",
\\\"packageName\\\":\\\"com.package.name\\\",
\\\"productId\\\":\\\"com.package.name.item1\\\",
\\\"purchaseTime\\\":1594811344959,
\\\"purchaseState\\\":0,
\\\"developerPayload\\\":\\\"{\\\\\\\"developerPayload\\\\\\\":\\\\\\\"XXXXXX==\\\\\\\\n\\\\\\\",\\\\\\\"is_free_trial\\\\\\\":false,\\\\\\\"has_introductory_price_trial\\\\\\\":false,\\\\\\\"is_updated\\\\\\\":false,\\\\\\\"accountId\\\\\\\":\\\\\\\"\\\\\\\"}\\\",
\\\"purchaseToken\\\":\\\"thisisPurchaseToken-abCdeF123456.....\\\"}\",
\"signature\":\"thisisthesignature1234456.....==\",
\"skuDetails\":\"{
\\\"skuDetailsToken\\\":\\\"SkUToKeNSkUToKeN....\\\",
\\\"productId\\\":\\\"com.package.name.item1\\\",
\\\"type\\\":\\\"inapp\\\",
\\\"price\\\":\\\"¥1,234\\\",
\\\"price_amount_micros\\\":1234000000,
\\\"price_currency_code\\\":\\\"JPY\\\",
\\\"title\\\":\\\"product title\\\",
\\\"description\\\":\\\"product description\\\"
}\",
\"isPurchaseHistorySupported\":true,
\"isOwned\":true
}"
}
After the user successfully purchased an item with the receipt above, on the other day the user tried to purchase another same item, but the receipt sent to the server was like this:
(Ignore the different number of backslashes at the payload value; somehow our error reporting tool stripped one level of escaping)
{
"Store": "GooglePlay",
"TransactionID": "thisisPurchaseToken-abCdeF123456.....",
"Payload": "{
"json":"{
\"productId\":\"com.package.name.item1\",
\"purchaseToken\":\"thisisPurchaseToken-abCdeF123456.....\",
\"purchaseTime\":1594811344959,
\"developerPayload\":\"{\\\"developerPayload\\\":\\\"XXXXXX==\\\\n\\\",\\\"is_free_trial\\\":false,\\\"has_introductory_price_trial\\\":false,\\\"is_updated\\\":false,\\\"accountId\\\":\\\"\\\"}\"}",
"signature": "thisisthesignature1234456.....==",
"skuDetails": "{
\"skuDetailsToken\":\"SkUToKeNSkUToKeN....\",
\"productId\":\"com.package.name.item1\",
\"type\":\"inapp\",
\"price\":\"¥1,234\",
\"price_amount_micros\":1234000000,
\"price_currency_code\":\"JPY\",
\"title\":\"product title\",
\"description\":\"product description\
"}",
"isPurchaseHistorySupported":true,
"isOwned": true
}"
}
There are some strange things here:
- The user was trying to initiate a new purchase, but somehow the returned receipt has an old and consumed purchaseToken included, so Google Play Store’s purchases.product.get API responded it with consumptionState = 1.
- There’s no orderId (GPA-***) inside the payload, and Unity inserted purchaseToken instead of the orderId
- Some fields are missing in the Payload: orderId, packageName, and purchaseState.
Any help would be appreciated.