This how-to implements the Google Play Store purchase flow in your game: initiating a purchase, then redeeming it with LootLocker to grant rewards to the Player.
Prerequisites
Section titled “Prerequisites”- Unity, Unreal, or Godot SDK installed and configured in your project (not required for REST). Unity also requires the In-App Purchasing package.
- An active Player session (see Authentication).
- Google Play Store IAP settings configured and a Catalog Listing configured for Google Play Store IAP.
Set Up the IAP Manager
Section titled “Set Up the IAP Manager”Create an IAPManager script that inherits from IDetailedStoreListener to handle all purchase callbacks: initializing Unity IAP, registering your Google Play products (as Consumable or NonConsumable), triggering a purchase, and redeeming a completed purchase with LootLocker.
using Unity.Services.Core;using Unity.Services.Core.Environments;using UnityEngine;using UnityEngine.Purchasing;using UnityEngine.Purchasing.Extension;
public class IAPManager : MonoBehaviour, IDetailedStoreListener{ public IStoreController controller; private IExtensionProvider extensions;
public async void Awake() { try { var options = new InitializationOptions() .SetEnvironmentName("production");
await UnityServices.InitializeAsync(options); } catch (Exception exception) { Debug.Log(exception); }
// Create IAP configuration for Google Play Store var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance(AppStore.GooglePlay));
// Register your products (replace with your actual product IDs from Google Play Console) builder.AddProduct("com.company.game.coins100", ProductType.Consumable); builder.AddProduct("com.company.game.coins500", ProductType.Consumable);
// Initialize the purchasing system UnityPurchasing.Initialize(this, builder); }
/// <summary> /// Called when a user clicks the purchase button /// </summary> public void OnPurchaseClicked(string productId) { Purchase(productId); }
/// <summary> /// Initiates a purchase for the given product ID /// </summary> public void Purchase(string productId) { var product = controller.products.WithID(productId);
if (product is { availableToPurchase: true }) { controller.InitiatePurchase(product); } else { Debug.Log($"Product {productId} is not available for purchase"); } }
/// <summary> /// Called when Unity IAP is ready to make purchases /// </summary> public void OnInitialized(IStoreController controller, IExtensionProvider extensions) { this.controller = controller; this.extensions = extensions; }
/// <summary> /// Called when Unity IAP encounters an unrecoverable initialization error /// </summary> public void OnInitializeFailed(InitializationFailureReason error) { Debug.Log($"IAP initialization failed: {error}"); }
/// <summary> /// Called when a purchase completes successfully /// </summary> public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e) { string productID = e.purchasedProduct.definition.id; string purchaseToken = e.purchasedProduct.transactionID;
LootLockerSDKManager.RedeemGooglePlayStorePurchaseForPlayer(productID, purchaseToken, (result) => { if (!result.success) { Debug.Log("Redeem Purchase unsuccessful!"); return; } });
return PurchaseProcessingResult.Complete; }
/// <summary> /// Called when a purchase fails /// </summary> public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription) { Debug.Log($"Purchase failed: {failureDescription.reason}"); }
public void OnInitializeFailed(InitializationFailureReason error, string message) { Debug.Log("IAP Error: " + message); }}Coming soon — this sample hasn't been written yet.
Coming soon — this sample hasn't been written yet.
Coming soon — this sample hasn't been written yet.
Redeem a Purchase for a Character Class
Section titled “Redeem a Purchase for a Character Class”You can also redeem a purchase to reward a specific Character Class the player owns instead of the player directly — the flow is the same, but you call RedeemGooglePlayStorePurchaseForClass instead.
public void RedeemPurchase(Product product){ string productID = product.definition.id; string purchaseToken = product.transactionID; int classID = 123; LootLockerSDKManager.RedeemGooglePlayStorePurchaseForClass(productID, purchaseToken, classID, (result) => { if (!result.success) { Debug.Log("Redeem Purchase unsuccessful!"); return; }
});}Coming soon — this sample hasn't been written yet.
curl --location --request POST 'https://api.lootlocker.io/game/redeem/store/google' \--header 'x-session-token: {{session_token}}' \--header 'Content-Type: application/json' \--data-raw '{ "sandboxed": true, "transaction_id": "2000000316432499", "character_id": 123}'On a successful purchase, a 204 No Content response is returned.
Conclusion
Section titled “Conclusion”You now have the full Google Play Store purchase flow implemented: initiating a purchase using Google Play Billing, validating it through LootLocker, and granting rewards to Players and Character Classes.
