ios IAP receipt field

Using corona build 2016.3012 and testing IAP. The receipt field in the documentation states the value would be JSON receipt data.  What I’m seeing appears to be a string of hexadecimal numbers preceded by a <

Anything changed with the API?

There have been no API updates for our Apple, Google or Amazon IAP libraries in some time.  Now I’m not sure what all three of them provide the receipt as JSON.

Rob

The docs for ios iap do say it will be json with the fields which we’d use to confirm the order through external means.  Not sure what I’m seeing now though.  I seem to remember in the distant past it was json but we weren’t using it then so I don’t have any code which tried to use it.

There have been no API updates for our Apple, Google or Amazon IAP libraries in some time.  Now I’m not sure what all three of them provide the receipt as JSON.

Rob

The docs for ios iap do say it will be json with the fields which we’d use to confirm the order through external means.  Not sure what I’m seeing now though.  I seem to remember in the distant past it was json but we weren’t using it then so I don’t have any code which tried to use it.

Rich: I am having the same problem. Did you ever get it resolved? I am getting what appears to be a Hex receipt and not json. When I try to validate it with an external verifier I get:

"error":{ "verificationError":"2", "storeError":"status was: 21002" }

Which is:

21002 The data in the receipt-data property was malformed or missing.
  1. strip spaces, < and >,

  2. convert the hex values to ascii

  3. encode the whole thing as base64

This might help - https://github.com/SatheeshJM/Auto-Renewable-In-App-Purchase-Validation-using-Corona-SDK/blob/ca8f5db8546df916c511c687b385a186899d45aa/validate.lua#L80-L98

Wow! Thank you! Two days fighting with this. I owe you one. Sphere Game’s answer should be marked as the correct answer.

And for those using Gamespark to validate iOS.

Steps 1 and 2 mentioned by Sphere where done with code from the URL Sphere provided.

Step 3 was done with code from http://lua-users.org/wiki/BaseSixtyFour

-- base64 encoding local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' local encodeBase64 = function(data) return ((data:gsub('.', function(x) local r,b='',x:byte() for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)\>0 and '1' or '0') end return r; end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x) if (#x \< 6) then return '' end local c=0 for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end return b:sub(c+1,c+1) end)..({ '', '==', '=' })[#data%3+1]) end local requestBuilder = gs.getRequestBuilder() local iOSRequest = requestBuilder.createIOSBuyGoodsRequest() local receipt = transaction.receipt --remove unwanted characters receipt = receipt:sub(2,-2) receipt = receipt:gsub(" ","") --Convert to ascii local ascii = "" local l = receipt:len() for i=1,l,2 do local hex = receipt:sub(i,i+1) local dec = tonumber(hex, 16) if dec then local char = string.char(dec) ascii = ascii..char end end --Encode to base 64 local b64encode = encodeBase64(ascii) iOSRequest:setReceipt(b64encode) iOSRequest:send(function(response) --- Response end)

I’m testing IAPs on iOS and was thrown for a loop with this.

@Rob perhaps the docs should be updated to say that you will receive a receipt in hex format that will need to be manipulated if you want to get the relevant information?

@Everyone else, do you know which version of the receipt needs to be sent to Apple for validation - hex or base64 ?

Thanks!

At the bottom of each documentation page is a link where  you can report issues. It’s best if you fill out that form so we can track it with our documentation team.

Thanks

Rob

Vince_: I believe that Apple expects base64 as a value of a JSON key:

From this link: https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html

Send the Receipt Data to the App Store

On your server, create a JSON object with the following keys:

Key

Value

receipt-data

The base64 encoded receipt data.

password

Only used for receipts that contain auto-renewable subscriptions. Your app’s shared secret (a hexadecimal string).

@Rob, thank you I’ll submit an issue.

@agramonte, thank you that was a big help!

Rich: I am having the same problem. Did you ever get it resolved? I am getting what appears to be a Hex receipt and not json. When I try to validate it with an external verifier I get:

"error":{ "verificationError":"2", "storeError":"status was: 21002" }

Which is:

21002 The data in the receipt-data property was malformed or missing.
  1. strip spaces, < and >,

  2. convert the hex values to ascii

  3. encode the whole thing as base64

This might help - https://github.com/SatheeshJM/Auto-Renewable-In-App-Purchase-Validation-using-Corona-SDK/blob/ca8f5db8546df916c511c687b385a186899d45aa/validate.lua#L80-L98

Wow! Thank you! Two days fighting with this. I owe you one. Sphere Game’s answer should be marked as the correct answer.

And for those using Gamespark to validate iOS.

Steps 1 and 2 mentioned by Sphere where done with code from the URL Sphere provided.

Step 3 was done with code from http://lua-users.org/wiki/BaseSixtyFour

-- base64 encoding local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' local encodeBase64 = function(data) return ((data:gsub('.', function(x) local r,b='',x:byte() for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)\>0 and '1' or '0') end return r; end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x) if (#x \< 6) then return '' end local c=0 for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end return b:sub(c+1,c+1) end)..({ '', '==', '=' })[#data%3+1]) end local requestBuilder = gs.getRequestBuilder() local iOSRequest = requestBuilder.createIOSBuyGoodsRequest() local receipt = transaction.receipt --remove unwanted characters receipt = receipt:sub(2,-2) receipt = receipt:gsub(" ","") --Convert to ascii local ascii = "" local l = receipt:len() for i=1,l,2 do local hex = receipt:sub(i,i+1) local dec = tonumber(hex, 16) if dec then local char = string.char(dec) ascii = ascii..char end end --Encode to base 64 local b64encode = encodeBase64(ascii) iOSRequest:setReceipt(b64encode) iOSRequest:send(function(response) --- Response end)

I’m testing IAPs on iOS and was thrown for a loop with this.

@Rob perhaps the docs should be updated to say that you will receive a receipt in hex format that will need to be manipulated if you want to get the relevant information?

@Everyone else, do you know which version of the receipt needs to be sent to Apple for validation - hex or base64 ?

Thanks!

At the bottom of each documentation page is a link where  you can report issues. It’s best if you fill out that form so we can track it with our documentation team.

Thanks

Rob

Vince_: I believe that Apple expects base64 as a value of a JSON key:

From this link: https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html

Send the Receipt Data to the App Store

On your server, create a JSON object with the following keys:

Key

Value

receipt-data

The base64 encoded receipt data.

password

Only used for receipts that contain auto-renewable subscriptions. Your app’s shared secret (a hexadecimal string).

@Rob, thank you I’ll submit an issue.

@agramonte, thank you that was a big help!