VALIDATION
Purchase Validation
Each purchase should be validated before awarding it to the end-user. This assists in preventing unauthorized purchases and ensures the integrity of your in-app economy. Validating purchases is a critical security measure to prevent fraud, protect your revenue, and ensure fair user experiences.
Essentially, that are two distinct validation approaches readily available.
Server-side Validationβ
The most secure and reliable way to validate purchases is by using server-to-server (S2S) communication, with the client completely removed from the validation process. This minimizes security risks and ensures that entitlements are only granted based on verified data received directly from Xsolla.
With Xsolla, server-side validation is implemented through a webhook-based model:
- Once a user completes a purchase through your app, Xsolla services automatically trigger a webhook event to your backend.
- This webhook contains all the necessary purchase data, including the Xsolla
order ID, enabling your server to validate and process the purchase asynchronously. - Your backend can then use this data to update the userβs entitlements, balance, inventory, etc., without requiring any additional input from the client.
This flow ensures that the client has no role in deciding the outcome of a purchase β all validation logic lives on the server, using trusted data that originates from Xsolla itself.
For more information about how webhooks work, see here.
Client-side Validationβ
Provides means of validating a purchase on the user's device without a need for a backend (server). It's better than nothing, but has its own drawbacks, i.e. anything that runs on the client can potentially be exploited.
- Unity IAP
- Without Unity IAP
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
{
var product = purchaseEvent.purchasedProduct;
var validator = extensions.GetExtension<IXsollaPurchasingStoreExtension>().GetValidator();
validator.ValidatePurchase(product.receipt, (success, error) =>
{
if (error == null && success)
{
// Purchase is Valid, handle the purchased item..
}
else
{
// Purchase is NOT valid or there was an error performing validation..
}
});
}
void MyOnPurchaseCallback(XsollaStoreClientPurchasedProduct product, XsollaStoreClientError error)
{
_storeClient.ValidatePurchase(product.ToReceipt(), (success, error) =>
{
if (error == null && success)
{
// Purchase is Valid, handle the purchased item..
}
else
{
// Purchase is NOT valid or there was an error performing validation..
}
});
}