Payments¶
Setup¶
- Open the Platforms & Products page from Project Settings menu and add all the information about the Platforms where the game is available. It's required to validate the purchases.
- Open the Products tab of Platforms & Products page and fill in all the information about your game's products. In most cases, you need the main table. However, if you have a different product ID, Name, or Price for other platforms, you can use the override section for each of the platforms.
Products are global¶
You have single global list of products, like in Apple Store or Google Play. Each environment uses the same list.
Make changes with care
Make changes with care, because it could affect your current players.
Products versioning¶
If you add/delete products on the products page, users will see these changes even without deploy.
Make changes with care
Be specifically care when you delete products.
Where to find needed data for validation for specific platforms?
Google Play¶
For Android, we need a License key.
- Open Play Console and select the app you want to find the license key for.
- Go to the Monetization setup page (Monetize ► Monetization setup).
- Your license key is under «Licensing».
- To properly check if the test account made the payment, you need to give us access to service account.
- Create a service account.
- Link it to the google play dev account.
- In the dev console, on /api-access page go to the permissions.
- Give it needed permissions.
- Add service account email and private key to Balancy.
Problems with service account
If you have set up everything and validation still doesn't work, the problem is probably with the service account settings. This answer could help you.
iOS¶
For validating iOS payments, we need generated shared secret.
Amazon¶
- During Balancy initialization pass platform
Balancy.Main.Init(new Balancy.AppConfig { ApiGameId = YOUR_GAME_ID, PublicKey = YOUR_PUBLIC_KEY, Environment = Balancy.Constants.Environment.Development, Platform = Constants.Platform.AmazonStore, OnReadyCallback = responseData => { Debug.Log("Balancy Initialized: " + responseData.Success); } });
- Add platform on the Balancy platforms page and set amazon shared key.
Amazon settings
You can read Amazon's documentation about IAP, also check Unity's documentation.
Basic Usage¶
To get all available products user asynchronous method GetProducts
:
Payments.GetProducts(data =>
{
if (data.Success)
{
foreach (var product in data.Products)
{
Debug.Log("product: " + product.Name + " => " + product.ProductId);
}
}
});
To get specific product you can use:
-
Asynchronous
GetProduct
:2. SynchronousPayments.GetProductById("gold.pack.1", (item) => { if (item != null) { Debug.Log("product: " + item.Name + " => " + item.ProductId); } });
GetProduct
:var product = Payments.GetProductById("gold.pack.1");
Product could be null
If you use synchronous method, it can return
null
, if you didn't callGetProducts
before that. We'd recommend always to use async method. But if you decide to use sync version, at least, callGetProducts
once before that.
Restore Purchases¶
When a user reinstalls your application they should be granted any Non-Consumable products they already own. On platforms that support it (e.g. Google Play and Universal Windows Applications) Balancy automatically restores any products the user owns during the first initialization following reinstallation.
On iOS platform you need to manually call Balancy.Payments.RestorePurchases()
.
To receive callback on successful restoration, subscribe on event Balancy.Payments.onProductWasRestored
. Here you will be able to get product id.
Payments.onProductWasRestored += data =>
{
if (data.Success)
{
Debug.Log("Product restored: " + data.ProductId);
}
};
LiveOps Purchases¶
To get the list of all the payments the user made, call the following method (make sure to do that after OnSmartObjectsInitialized is invoked)
Balancy.LiveOps.Profile.GetPaymentsInfo();
Balancy Validation¶
//Single Offers
Balancy.LiveOps.GameOffers.PurchaseOffer(offerInfo, purchaseResponse =>
{
Debug.Log("Purchase status " + purchaseResponse.Success + " for " + purchaseResponse.ProductId);
});
//Group Offers
Balancy.LiveOps.GameOffers.PurchaseOffer(offerGroupInfo, storeItem, purchaseResponse =>
{
Debug.Log("Purchase status " + purchaseResponse.Success + " for " + purchaseResponse.ProductId);
});
//Store Items
Balancy.LiveOps.Store.PurchaseStoreItem(storeItem, purchaseResponse =>
{
Debug.Log("Purchase status " + purchaseResponse.Success + " for " + purchaseResponse.ProductId);
});
There are additional methods, which are available for StoreItem:
bool isFree = storeItem.IsFree();
bool isEnoughResources = storeItem.IsEnoughResources();
int watchedAdsCount = storeItem.GetWatchedAds();
int requiredAdsCount = storeItem.GetRequiredAdsToWatch();
If you use Ads as a price, use the following method after an Ad was watched for the specific StoreItem. When storeItem.IsEnoughResources()
to purchase the storeItem for Ads, invoke Balancy.LiveOps.Store.PurchaseStoreItem
method.
Balancy.LiveOps.Store.AdWasWatchedForStoreItem(storeItem);
Custom Validation¶
If you use your payment/Validation system, you need to confirm the purchase with Balancy. This information will only be used for future Segmentation and will be saved in the profile history if the purchase is valid.
//unityProduct is what you receive from Unity payments, it's a type of UnityEngine.Purchasing.Product
var paymentInfo = new PaymentInfo
{
Receipt = unityProduct.receipt,
Price = (float)unityProduct.metadata.localizedPrice,
Currency = unityProduct.metadata.isoCurrencyCode,
ProductId = unityProduct.definition.id,
OrderId = unityProduct.transactionID
};
//Offers
Balancy.LiveOps.GameOffers.OfferWasPurchased(offerInfo, paymentInfo, purchaseResponse =>
{
Debug.Log("Purchase status " + purchaseResponse.Success + " for " + purchaseResponse.ProductId);
});
//Group Offers
Balancy.LiveOps.GameOffers.OfferWasPurchased(offerGroupInfo, storeItem, paymentInfo, purchaseResponse =>
{
Debug.Log("Purchase status " + purchaseResponse.Success + " for " + purchaseResponse.ProductId);
});
//Store Items
Balancy.LiveOps.Store.ItemWasPurchased(storeItem, paymentInfo, purchaseResponse =>
{
Debug.Log("Purchase status " + purchaseResponse.Success + " for " + purchaseResponse.ProductId);
});
If you didn't migrate all the data to Balancy, but still want us to save payments history to use it in segmentation and conditions, it's best to use the method above Balancy.LiveOps.Store.ItemWasPurchased
, passing null
as StoreItem.
If you use payment system which Balancy is not supported (yet), you can bypass payment from your payments/validation system to Balancy without validation on our side:
Balancy.LiveOps.GameOffers.OfferWasPurchasedAndValidated(offerInfo, paymentInfo, Constants.Platform.Unknown, purchaseResponse =>
{
Debug.Log("Purchase status " + purchaseResponse.Success + " for " + purchaseResponse.ProductId);
});
Balancy.LiveOps.GameOffers.OfferWasPurchasedAndValidated(offerGroupInfo, storeItem, paymentInfo, Constants.Platform.Unknown, purchaseResponse =>
{
Debug.Log("Purchase status " + purchaseResponse.Success + " for " + purchaseResponse.ProductId);
});
paymentInfo
by yourself with information from purchase.
Custom Payments¶
You can also use the Balancy payment system without LiveOps features. Be aware, using those methods for payments won't save any history in player's progress, thus won't affect segmentation and any other conditions. If you want to use history of payments in your LiveOps, use one of the methods above.
// Get a list Of Products:
Balancy.Payments.GetProducts(productsResponse =>
{
Debug.Log("Products Received " + productsResponse.Success);
if (productsResponse.Success)
Debug.Log("Products Count: " + productsResponse.Products.Length);
});
// Make a purchase:
Balancy.Payments.PurchaseProduct(<product_id>, doneCallback =>
{
Debug.Log("Purchase was made " + doneCallback.Success);
});
Product id
You should use the product id from the base product. For example, if a product has id com.mygame.gold1, and you overrode it for Android with com.mygame.gold1.android, you have to pass com.mygame.gold1 to the purchase method.