PURCHASE
Purchase flow
Purchasing flow is a multistage process, which involves payment collection, purchase validation and consumption.
Starting purchasing flow
Use one of the snippets below to launch a purchasing flow depending on whether you use Unity InApp Purchasing or not:
- Unity IAP
- Without Unity IAP
_storeController.InitiatePurchase(product);
// ...
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs purchaseEvent)
{
// handle the purchased item here
return PurchaseProcessingResult.Complete;
}
storeClient.PurchaseProduct(productId, (product, error) =>
{
if (error != null)
{
// handle error
return;
}
var receipt = product.ToReceipt();
// handle the purchased product here (e.g. validate or consume)..
});
Advanced Settings
Use a more complete XsollaStoreClient.PurchaseProduct() variant for extended functionality:
XsollaStoreClient.PurchaseProduct(
string productId,
XsollaStoreClientPurchaseArgs args,
Action<XsollaStoreClientPurchasedProduct, XsollaStoreClientError> completionHandler
)
Developer Payload
Use the example below to set your custom developer payload for a purchasing flow:
var args = new XsollaStoreClientPurchaseArgs() {
developerPayload = "<your-custom-developer-payload>"
};
XsollaStoreClient.PurchaseProduct(
productId, args, completionHandler: (product, err) =>
{
// Handle the result.
}
);
External ID
Allows providing your own custom unique ID for a transaction.
You need to enable external ID support in your Publisher Account beforehand or purchasing will fail.
Use the example below to set the external ID for a purchasing flow:
var args = new XsollaStoreClientPurchaseArgs() {
externalId = "<your-custom-unique-external-id"
};
XsollaStoreClient.PurchaseProduct(
productId, args, completionHandler: (product, err) =>
{
// Handle the result.
}
);
External Transaction Token
Attaches an external transaction token to the launched purchasing flow, so it carries through to your order for reporting back to the platform. The setter is shared across platforms; what it's used for depends on the target:
| Platform | Supported | Used for |
|---|---|---|
| Android | ✅ | Google Play external transaction token, for User Choice Billing / alternative billing reporting — see Reporting External Transactions to Google Play |
| iOS | ❌ | — |
| Windows | ❌ | — |
| macOS | ❌ | — |
| Web | ❌ | — |
Setting externalTransactionToken on a platform not listed as supported above fails the purchase call with an error, rather than dropping the value silently. Also don't confuse it with externalId above: that's Xsolla's own merchant reconciliation ID, not a platform token.
Use the example below to attach the token for a purchasing flow:
var args = new XsollaStoreClientPurchaseArgs() {
externalTransactionToken = "<google-play-external-transaction-token>"
};
XsollaStoreClient.PurchaseProduct(
productId, args, completionHandler: (product, err) =>
{
// Handle the result.
}
);
Forcing a Payment Method
Allows selecting a specific payment method for a purchasing flow.
Payment method IDs can be found in your Publisher Account.
var args = new XsollaStoreClientPurchaseArgs() {
paymentMethodId = <payment-id>
};
XsollaStoreClient.PurchaseProduct(
productId, args, completionHandler: (product, err) =>
{
// Handle the result.
}
);
Handling user cancellation
When a player cancels a purchase, handle it separately from actual errors.
- Unity IAP
- Without Unity IAP
public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
{
if (failureReason == PurchaseFailureReason.UserCancelled)
{
// User cancelled the purchase — don't show an error
return;
}
// Handle other failure reasons
}
// Or (newer API)
public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription)
{
if (failureDescription.reason == PurchaseFailureReason.UserCancelled)
{
// User cancelled the purchase — don't show an error
return;
}
// Handle other failure reasons
}
void OnPurchase(XsollaStoreClientPurchasedProduct product, XsollaStoreClientError error)
{
if (error?.code == XsollaStoreClientPurchaseErrorCode.Cancelled)
{
// User cancelled the purchase — don't show an error
return;
}
if (error != null)
{
// Handle other errors
return;
}
// Handle successful purchase
}
Validating purchases (recommended)
Although validation is NOT a mandatory step, yet it's highly recommended to minimize the chance of fraud and any other malevolent intents.
For instructions on how to validate your purchases, see Purchase Validation guide.
Consuming purchased goods
The very final step in the chain of purchasing flow stages is to award the purchased goods to the user and mark these goods as "awarded". The process also known as purchase consumption.
Use the code below to do just that:
- Unity IAP
- Without Unity IAP
_storeController.InitiatePurchase(product);
// ....
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs purchaseEvent)
{
// handle purchased item
return PurchaseProcessingResult.Pending;
}
// ....
_storeController.ConfirmPendingPurchase(product);
storeClient.ConsumeProduct(item.sku, item.quantity, item.transactionId, error => {
if (error != null)
{
return;
}
// handle purchased item
});
It's highly recommended to perform at least some form of validation before consuming the purchased goods.