Tracking Monetization: Receipt Verification

Tracking monetization in our SDK requires you to call the Transaction method and pass in the necessary parameters.

The Transaction method looks like this:

UnityAnalytics.Transaction(string productId, decimal price, string currency, string receipt, string signature);

example:

UnityAnalytics.Transaction("PRODUCT_ID", 0.99m, "USD", null, null);

We currently support both iOS and Android platforms and also support receipt verification.
With receipt verification, you’ll have the ability to differentiate fraud and real transactions on your dashboard.
We’ve had a lot of questions regarding the receipt verification and how to do it when using popular In-App-Purchase plugins like Prime31 or Unibill.

So we’ve come up with the following receipt guide:

  • For iOS

  • “receipt” parameter

  • If you leave this as null, this transaction will show up in Unverified Revenue

  • If you are writing a Native iOS plugin

  • For iOS 6 and below, send the raw SKPaymentTransaction’s transactionReceipt. (SKPaymentTransaction | Apple Developer Documentation)

  • For iOS 7 and above, send the base64 encoded value of the App Receipt from the app bundle. (Validating receipts with the App Store | Apple Developer Documentation)

  • If you are using Unibill plugin

  • Pass in PurchasableItem’s “receipt” property as the receipt. (Outline Games)

  • If you are using Prime31 plugin

  • Pass in StoreKitTransaction’s “base64EncodedTransactionReceipt” property as the receipt.

  • “signature” parameter

  • Pass in null since this is not used.

  • For Android

  • Make sure you have entered your Google Public Key on your dashboard under Integration > Advanced Integration > Monetization

  • You can get your Google Public Key under Google Play Developer console > All applications > Services & APIs > Your License Key For This Application

  • “receipt” parameter

  • If you leave this as null, this transaction will show up as Unverified Revenue

  • If you are writing a Native Android plugin

  • Pass in the the purchase data for the order, which is a String in JSON format that is mapped to the INAPP_PURCHASE_DATA key in the response Intent. (See: Sistema di fatturazione di Google Play  |  Google Play's billing system  |  Android Developers)

  • If you are using Unibill plugin

  • Parse the PurchasableItem’s “receipt” property as JSON, and pass in the value of the “json” property. (Outline Games)

  • If you are using Prime31 plugin

  • Pass in GooglePurchase “originalJson” property

  • “signature” parameter

  • If you leave this as null, this transaction will show up as Unverified Revenue

  • If you are writing a Native Android plugin

  • Pass in the the signature, which is mapped to the INAPP_DATA_SIGNATURE key in the response Intent. (See: Sistema di fatturazione di Google Play  |  Google Play's billing system  |  Android Developers)

  • If you are using Unibill plugin

  • Parse the PurchasableItem’s “receipt” property as JSON, and pass in the value of the “signature” property. (Outline Games)

  • If you are using Prime31 plugin

  • Pass in GooglePurchase “signature” property.

4 Likes

Well I was doing just this but after querying why I didn’t get any verified transactions I was told by Angelo Ferro that the receipt could not be base 64 encoded and I had to decode it myself before passing it to you.

The receipt can’t be Base64 encoded. It needs to be decoded first before being passed as a parameter, here is some sample code to decode it:
byte[ ] data = System.Convert.FromBase64String(“IOS_RECEIPT_GOES_HERE”);
string receipt = System.Text.Encoding.UTF8.GetString(data);

Hi @andymads ,

We recently made a change to our backend infrastructure to accept Base64 encoding for Prime31 transactions. The original instructions I sent you were correct at the time, but we wanted to simplify the receipt verification process by accepting Base64 encoded transactions (so no need to decode it!) :slight_smile:

Either way, for Prime31 transactions on iOS, whether you send it decoded or encoded, our backend will still process it correctly. Please let us know if you have any questions :slight_smile:

Thanks!
-Angelo

How is the data handled if a duplicate receipt is sent for multiple transactions? Is it treated as just one (under both total revenue and verified)?

Currently, we don’t validate for duplicate receipt, but we do checks based on the timestamp of the receipt and when the transaction event was triggered. Both timestamps have to be within 1 hour.

Good to know. Time to leave Flurry and save time verifying all those fucking receipt that no-one implements in the same way.
I will surely try this service on next game.

Thanks Kent for the further details!

Hi, Im trying to set my Google Api Key but always I recieved “There was an error updating your project.”

Any guess??

Hi @Splipic - We apologize for the error message when you attempted entering your Google API Key. Please try this again as the error is now fixed. Let us know if you need any assistance.

It work thank you, the Google Api Key is the Base64-encoded RSA public key right?

Hey, I was just implementing this and I was wondering if you think it’s worthwhile and/or possible to track refunds? How would I go about doing this? I was thinking of just tracking a negative purchase value… but I wasn’t sure if that was a good idea or not.

Hi @Splipic , Yes that is the correct Google API key, as described in Google’s documentation. Our receipt verification for Google Play apps works by base64-decoding the key and using it to verify the signature in the receipt.

Is there currently a way to check the response of verified or unverified - or is that a future API? Is it foolproof enough to disable future IAP for a user with unverified transactions - assuming they have a tampered version of the app?

My instinct says no, but isn’t that the point of monitoring if the transactions are verified?

Hi @eezSZI ,

Currently there is no returned value on a Transaction method so determining if an in app purchase was verified or unverified is not possible. Our goal is to accurately display your transaction histories, by separating your verified transaction from fraudulent ones, and not to prevent fraudulent transactions from occurring.

@mpinol fair enough. Thanks!

1 Like

Hello, I’m using Unity 5.2.1p2 and build games for windows, android, ios and web. Does purchase verification exist now only for android and ios? Did you plan to integrate it for windows store/phone 8.1/10 and for facebook?

Hi @vladrybak ,

Yes, we currently only support purchase verification for Android and iOS. Windows store is certainly on our roadmap but I cannot give you any real information about when it will be available. I do not believe Facebook has a purchase verification system in place, if you have any information on this you could link me that would be greatly appreciated, but I will look into the possibility of adding Facebook to our future plans as well.

Hi everyone,

We are using Unibill in Unity 5.1.1p2 and everything seems to work properly, excepted that we do not see the transactions in Unity Analytics. Even though the transactions are processed in iTunes Connect.

Any guess?

Hi @fpomerleau ,

Would you mind opening a support ticket here with your script so we can take a look?

Hi @kentunity

can we filter our test devices with purchase data or it will mix the test data and real data.