Solved

Unity Server side receipt validation


Badge +1

So I’m trying to verify purchase’s made on client devices. I’ve made a simple flow with screen shots and notations to more clearly explain my problem.

But simply put: How do I request a receipt/transaction token be validated by revanueCat from Unity C#, and receive the response.
 

 

icon

Best answer by jazmine 8 October 2021, 23:01

View original

12 replies

Badge +1

I’m willing to offer payment for support in setting this up properly!

Userlevel 4
Badge +8

Hey @MaximillianChronoscope! Using the .purchasePackage or .restoreTransactions functions in the SDK will automatically validate the device receipt. There isn’t a standalone receipt validation endpoint in the SDK, it’s  a little more abstracted then that so the whole purchase process is handled by RevenueCat. 

Badge +1

How do I receive this info from inside unity? If i can get this information to my server i should be able to accomplish what I’m after.

​​​​​​@ryan I’m using .purchaseProduct(). Am will this validate it as well? My issue is though that clients can still bypass this and simply send a request to my server, so i need my server to be able to basically receive a transactionID or token or something from the client, and then have my server request this information below, using that transactionID. to make sure the player did in fact make a purchase.

 

Badge +1

This is what the code looks like on my client when a player makes a purchase.

        Purchases purchases = GetComponent<Purchases>();
        purchases.PurchaseProduct(productID, (productIdentifier, purchaserInfo, userCancelled, error) =>
        {
            if (!userCancelled)
            {
                if (error != null)
                {
                    LogError(error);
                }
                else
                {

                    //On successful purchase, how do i get a token or transactionID on the client                      so i can send to my server, so my server can request that same event data                          from revanueCat using aforementioned ID / token

                    purchases.SyncPurchases();
                }
            }
            else
            {
                Debug.Log("Subtester: User cancelled, don't show an error");
            }
        });

Userlevel 2
Badge +6

Hey @MaximillianChronoscope ,

 

We don't expose the transaction ID from our SDK at this time. If you're interested in getting this for your transactions, we do include the value in our webhooks: https://docs.revenuecat.com/docs/webhooks. Webhook events will be sent to your server. 

Badge +1

I’ll have 10+ servers running, with users able to connect to any one each time they login to my app (game). So i can’t just send the information to one location, i need each server to request to receive this information. Can i get more support than a webpage link? How can the client send some sort of idintifying information to my server so that my game server knows which transaction to look for in order to verify it?

I’ve looked through the 13 API functions on that page, and none of them seem to do what I’m looking for.

Badge +1

Is it possible to have a quick conversation with anyone in support so I can quickly find out whether what I’m trying to do is even possible with this product otherwise I unfortunately need to move on to something else.

Userlevel 2
Badge +6

Hey @MaximillianChronoscope ,

I don’t think there is a way for your servers to request specific transaction IDs. RevenueCat handles all of the receipt validation on our end and we use an entitlement system to unlock access as shown in our documentation here: https://docs.revenuecat.com/docs/entitlements

We don’t offer live support , but can you describe the full use-case in which you are trying to account for? I can then see if there is a workaround with RevenueCat that can support your needs :slight_smile: .

Badge +1

@jazmine So currently the client makes a purchase on either of the app stores, this receipt gets locally validated with unity’s IAP services. I currently also have it syncing with RevenueCat. The Client then sends this information to the server, currently it’s just sending the productID, as this tells the server what in game content to reward the user with. The issue with this is that the user can use a hack/jailbroken device to just send the request and bypass the purchase and validation all together. So i need a way for my server to make a request (I was originally hoping a PHP request?) to reveneue cat, that would search for a valid transaction from the player for what particular product. And if it finds a valid transaction that hasnt been used before, it successfully rewards the content, otherwise it will send an error to the client.

But in my case there will be 10’s of servers set up, globally, with users being able to pick which one they connect to each time they login to my app. So a webhook to one server when “NON_RENEWING_PURCHASE” is called unfortunately won’t work for me unless i can somehow send that information with each transaction (as the client does keep track of which server the user is connected to)

I was thinking of using something like this, but i do not know how to get the particular user on my server, as on my client i can set the App User ID once the user logs in, on my server there could be 100’s or 1000’s of users logged on.

```csharp
                    foreach (Purchases.Transaction transaction in purchaserInfo.NonSubscriptionTransactions)
                    {
                        if(transaction.ProductId == ""/*productID sent by the client*/)
                        {
                            if (SearchDatabaseForUsedTransactionID(transaction.RevenueCatId) == false)
                            {
                                //this transaction hasn't been used for a reward yet, reward it now
                                //add transaction to the database so it cannot be used for rewards a second time
                                //provide content to user
                                break; //stop searching
                            }
                            else
                            {
                                //this transaction has been used for a reward already.
                                //send error to client, could be malicious intent to use for duplicate reward, or some other issue.
                            }
                        }
                    }
```

Userlevel 2
Badge +6

Hey @MaximillianChronoscope , 

Thank you for providing this information about your use case! One way you could achieve a workaround for the solution you are looking for is by calling our Get Subscribers endpoint. Within the purchaserInfo object, you will see all the purchases this user has made. Each of these purchases has been validated with Apple or Google on our end. Our validation is as secure as Apple/Google makes it. 

I hope this helps!

Badge +1

@jazmine awesome okay i was looking at that! One thing though, currently all of my purchases are consumables/not subscriptions. If the player were to purchase the same product twice, (which is likely in my case) how can i check to make sure that they arn’t being granted more than they paid for, only only counting it the first time?

Badge +1

I was able to successfully get the information i needed into my game using “Get Subscribers” thank you for your assistance! Look forward to using your company’s services!

Reply