Currency (IAP)
Integration Guide
Every project may have multiple custom currencies. For example "diamonds" and/or "cash". Aside from these typical game currencies, projects wishing to sell NFTs must integrate a specific currency. The internal name for this currency is "rgn-coin". When the "rgn-coin" is presented in the UI it can have any currency name, for example, "gems".
The "rgn-coin" may only be sold using in-app purchases. For more information on why this approach is used, please refer to the Currency GDG.
Other typical currencies can be added and used in an expected manner - as rewards to the user's account, or sold for in-app purchases.
To sell "rgn-coin" or other custom currency via in-app purchases you need to follow the below process:
- 1.Get the products list from AppStore (iOS) or PlayMarket (Android)
- 2.Get the registered products list from RGN SDK:
- 1.
RGN.Modules.Currency.CurrencyModule.GetInAppPurchaseCurrencyDataAsync
for custom coin currency packs - 2.
RGN.Modules.Currency.CurrencyModule.GetRGNCoinEconomyAsync
for "rgn-coin" packs. Important: you need to sell the "rgn-coin" for exact same tiers as it is specified in the response from this method.
- 3.When the user tries to purchase the coins start the in-app purchase process by using one of the available Unity plugins.
- 4.When the user purchases the coins and the callback for a successful purchase is triggered, you need to verify the receipt locally.
- 5.After successful receipt verification, you need to trigger the RGNCurrency API:
- 1.For custom currencies call the
RGN.Modules.Currency.CurrencyModule.PurchaseCurrencyProductAsync
method. - 2.For "rgn-coin" purchases call the
RGN.Modules.Currency.CurrencyModule.PurchaseRGNCoinAsync
mehtod.
- 6.In case the operation is successfully updated coin currencies balance will be returned in the response.
string id; //IAP identifier
string currencyName; //reward currency name i.e. coin
float price; //price of IAP
int quantity; //reward currency ammount
string type;
string promotionalSticker;
The
GetInAppPurchaseCurrencyDataAsync()
needs to be called only once. You can cache the value CurrencyProductsData
for later use in the PurchaseCurrencyProductAsync
method:using RGN.Modules.Currency;
namespace SomeNamespace
{
internal sealed class RetrieveCurrencyData
{
internal CurrencyProductsData ProductsData { get; private set; }
public async void RetrieveCurrencyDataOnceAsync()
{
ProductsData =
await CurrencyModule.I.GetInAppPurchaseCurrencyDataAsync();
}
}
}
The
CurrencyProductsData
contains two fields: products
and offers
The
products
is a list of RGNStoreProduct
classes:public class CurrencyProduct
{
public string id;
public string currencyName;
public float price;
public int quantity;
public string type;
public string promotionalSticker;
}
The
offers
is a list of CurrencyOffer
classes:public class CurrencyOffer
{
public string productId;
public string offeredProductId;
public double remainingTime;
public float offeringPrice;
public string promotionalMessage;
}
- 1.Call Unity IAP package purchase API and let the user buy the IAP (it is handled by native UI)
- 2.Validate the purchase receipt locally
- 3.On
OnSuccessfullPurchase
event call RGN'sPurchaseCurrencyProductAsync(productId)
:
using System.Collections.Generic;
using RGN.Modules.Currency;
namespace SomeNamespace
{
internal sealed class PurchaseCustomCoin
{
// This is a callback method for IAP plugin after successful
// receipt validation:
public async void HandleSuccessfulPurchaseAsync(string productId)
{
List<Currency> userCurrencyData =
await CurrencyModule.I.PurchaseCurrencyProductAsync(productId);
}
}
}
Here the
productId
is the id that you received in the CurrencyProduct
data.Purchasing
rgn-coin
works a bit differently, it has its own API called PurchaseRGNCoinAsync(string iapUUID)
To process in-app purchases you can use the Unity Purchasing plugin by adding
"com.unity.purchasing": "4.9.3",
to projects manifest.json file.using RGN.Modules.Currency;
using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.Purchasing.Security;
namespace SomeNamespace
{
internal sealed class PurchaseRGNCoin
{
public async void HandleSuccessfulPurchaseAsync()
{
// You can also retrieve the ecomony data
// once the app starts and cache it
RGNCoinEconomy rgnCoinEconomy =
await CurrencyModule.I.GetRGNCoinEconomyAsync();
// TODO: select the right product from the list:
// The list contains multiple 'rgn-coin' product packs
// Every pack has different amount of 'rgn-coin's and
// is sold using different price tier from the store
string iapUUID = rgnCoinEconomy.products[0].uid;
// TODO: before you call this method, you need
// to go to the in-app purchase process
//
// After the in-app purchase successfully finishes
// you need to validate the receipt locally
// in the ProcessPurchase() callback and then
// you can call following method:
// TODO: get it from the iap plugin callback
string iapTransactionId = string.Empty;
// TODO: get it from the iap plugin callback
string iapReceipt = string.Empty;
System.Collections.Generic.List<Currency> purchaseResponse =
await CurrencyModule.I.PurchaseRGNCoinAsync(
iapUUID,
iapTransactionId,
iapReceipt);
}
private PurchaseProcessingResult ProcessPurchase(
PurchaseEventArgs purchaseEvent)
{
bool validPurchase = true; // Presume valid for platforms with no R.V.
// Unity IAP's validation logic is only included on these platforms.
// Prepare the validator with the secrets we prepared in the Editor
// obfuscation window.
var validator =
new UnityEngine.Purchasing.Security.CrossPlatformValidator(
GooglePlayTangle.Data(),
AppleTangle.Data(),
Application.identifier);
try
{
// On Google Play, result has a single product ID.
// On Apple stores, receipts contain multiple products.
var result = validator.Validate(
purchaseEvent.purchasedProduct.receipt);
// For informational purposes, we list the receipt(s)
Debug.Log("Receipt is valid. Contents:");
foreach (IPurchaseReceipt productReceipt in result)
{
Debug.Log(productReceipt.productID);
Debug.Log(productReceipt.purchaseDate);
Debug.Log(productReceipt.transactionID);
}
}
catch (IAPSecurityException)
{
Debug.Log("Invalid receipt, not unlocking content");
validPurchase = false;
}
if (validPurchase)
{
Debug.Log(
$"Product {purchaseEvent.purchasedProduct.definition.id} " +
"purchased");
string transactionId = purchaseEvent.purchasedProduct.transactionID;
string receipt = purchaseEvent.purchasedProduct.receipt;
// TODO: call here the
// await CurrencyModule.I.PurchaseRGNCoinAsync() method
}
else
{
Debug.Log("Something happened when trying to purchase product " +
purchaseEvent.purchasedProduct.definition.id);
}
return PurchaseProcessingResult.Complete;
}
public class GooglePlayTangle
{
private static byte[] data = System.Convert.FromBase64String("abc");
private static int[] order = new int[] { 10, 11 };
private static int key = 12;
public static readonly bool IsPopulated = true;
public static byte[] Data()
{
if (IsPopulated == false)
return null;
return Obfuscator.DeObfuscate(data, order, key);
}
}
public class AppleTangle
{
private static byte[] data = System.Convert.FromBase64String("abc");
private static int[] order = new int[] { 10, 11 };
private static int key = 12;
public static readonly bool IsPopulated = true;
public static byte[] Data()
{
if (IsPopulated == false)
return null;
return Obfuscator.DeObfuscate(data, order, key);
}
}
}
}
You can get
isoCurrenyCode
and localizedPrice
from Unity IAP product's metadata. More details for Browsing Product Metadata.For now, you'll have to set
isoCurrenyCode & localizedPrice in USD and 0.99, 1.99 or 2.99