[Solved] Ask-to-buy, empty in_app array, and refreshing receipt (flow)

This is somewhat related to [Closed] When purchase consumable product, iOS receipt field "in_app" is empty - Unity Services - Unity Discussions

We have an issue where, if a purchase goes through Ask-to-buy on iOS, when ProcessPurchase finally gets called, the in_app array is empty.

@ap-unity replied “one suggestion that came up was to refresh the receipt if you get an empty in_app array”. It’s been a while, but I’m finally getting around to trying to implement just that :slight_smile:

The issue I’m having is this:

When ProcessPurchase is called for an item, the Product.receipt is in the form:

{“Store”:“AppleAppStore”,“TransactionID”:“1234…”,“Payload”:“MIITuwYJKoZI…”}

If I make a call to RefreshAppReceipt just after this, the receipt string returned is in the form:

“MIITuwYJKoZI…”

As in it’s just the Payload part, and not wrapped in JSON.

What’s the recommended flow steps here?

  • Validating the Product locally using CrossPlatformValidator only works for the JSON form of the receipt
  • Product’s receipt setter is internal so I can’t set it
  • Product’s constructor is also internal so I can’t create a new one

From what I can see, I can:

  • Check if the in_app array is empty, call RefreshAppReceipt, then use a Substring/Replace with the Product receipt in order to generate a JSON string receipt, then validate that locally (then server)
  • Don’t validate it locally, but send the Product receipt (with empty in_app array) and the refreshed receipt (Payload) to the server, then validate it remotely using the Payload from the refreshed receipt rather than the Payload extracted from the Product receipt

Both seem somewhat hacky/prone to failure. Is there a recommended way to use the receipt returned from RefreshAppReceipt, but with the Product returned from ProcessPurchase?

Thanks

@Nicolas1212 ,

Sorry for the delay in responding, but we do have some additional information.

Our IAP engineering team ran some tests and were able to confirm that Apple’s Ask-to-Buy purchases do not update the app receipt, so they cannot be verified correctly.

Our store implementation does correctly load the app receipt data, but the receipt does not contain information about the approved IAP transaction. For consumables, refreshing the app receipt also does not yield a receipt with the correct IAP data in it—we have previously recommended refreshing the receipt as a workaround, but it is now clear this does not work.

Although the app receipt does not contain the IAP transaction, the SKPaymentTransaction passed to paymentQueue:updatedTransactions does include a valid IAP receipt for the purchase. Unfortunately, this receipt is only accessible through the deprecated transactionReceipt field. This receipt is in a different format than the app receipt. It validates with Apple’s server-side validation, but it will not correctly validate with our local receipt validation.

Our next step is to open a bug with Apple, documenting the StoreKit behavior with the receipts we’ve collected.

2 Likes

Hi @ap-unity ,

Thanks for following up on this. Looking forward to when we can finally get this issue fixed :slight_smile:

Does this mean that the product.hasReceipt field will not be set correctly to true in case of an Ask-to-Buy purchase goes through?

@MariaAngelovaPD hasReceipt is just a getter, so I’m going to assume that it just checks if .receipt is null/empty. In this case, the receipt isn’t empty, the in_app array inside it is.

@Nicolas1212

I wanted to update you (and this forum thread for anyone finding it via searching) that this issue has (hopefully) been mitigated.

As of 1.16, the Transaction Receipt is available to validate receipts, if the App Receipt contains an empty in_app array.

“Sometimes consumable Ask to Buy purchases don’t show up in the App Receipt, in which case you cannot validate them using that receipt. However, iOS provides a Transaction Receipt that contains all purchases, including Ask to Buy. Access the most recent Transaction Receipt string for a given Product using IAppleExtensions.”

1 Like