The AppInfo
class stores client and Xiaomi credentials needed for client-to-server communication and authentication.
Key: | Type: | Description: |
---|---|---|
appID | строка | Xiaomi app ID |
appKey | строка | Xiaomi app key |
clientID | строка | Unity client ID |
clientKey | строка | Unity client key |
debug | bool | Toggle debug mode |
Xiaomi requires login through the ILoginListener
for all apps publishing to the Mi Game Center.
Key: | Type: | Description: |
---|---|---|
OnInitialized () | void | Called when initialization succeeds |
OnInitializedFailed (string message) | void | Called when initialization fails |
OnLogin () | void | Called when login succeeds |
OnLoginFailed (string message) | void | Called when login fails |
Unity IAP uses the StoreService
class internally to initialize the Unity Channel SDK.
Key: | Type: | Description: |
---|---|---|
static Initialize (AppInfo appInfo, ILoginListener loginListener) | void | Initialize the Unity Channel SDK |
static Login (AppInfo appInfo, ILoginListener loginListener) | void | Login to the Xiaomi account |
A successful login to Unity Channel returns the UserInfo
class. The data returned is for informational purposes.
Key: | Type: | Description: |
---|---|---|
channel | строка | Indicates which channel you are using (currently, it is only “XIAOMI”) |
userID | строка | Channel’s unique user ID |
userLoginToken | строка | Validate the user login (see Server-side initialization section of Xiaomi IAP integration guide) |
Unity IAP uses the IPurchaseListener
interface internally to handle purchasing activities.
Implement the IPurchaseListener
class to handle states of the purchase flow:
using UnityEngine.ChannelPurchase;
......
private class ExamplePurchaseListener : IPurchaseListener{
public void OnPurchase (PurchaseInfo purchaseInfo){
Debug.Log ("Purchase Succeed: " + purchaseInfo.gameOrderId);
}
public void OnPurchaseFailed (string message, PurchaseInfo purchaseInfo){
Debug.Log ("Purchase Failed: " + message);
}
public void OnPurchaseRepeated(string productCode){
Debug.Log ("Purchase Repeated");
}
public void OnReceiptValidate (ReceiptInfo receiptInfo){
Debug.Log ("Validate Succeed");
}
public void OnReceiptValidateFailed (string gameOrderId, string message){
Debug.Log ("Validate Failed");
}
public void OnPurchaseConfirm (string gameOrderId){
Debug.Log ("Confirm Succeed");
}
public void OnPurchaseConfirmFailed (string gameOrderId, string message){
Debug.Log ("Confirm Failed");
}
}
Key: | Type: | Description: |
---|---|---|
OnPurchase () | void | Called when purchase succeeds |
OnPurchaseFailed (string message, PurchaseInfo purchaseInfo) | void | Called when purchase fails |
OnPurchaseRepeated (string productCode) | void | Called when non-consumable Products are re-purchased |
OnReceiptValidation (ReceiptInfo receiptInfo) | void | Called when PurchaseService.ValidateReceipt (...) succeeds |
OnReceiptValidationFailed (string gameOrderID, string message) | void | Called when PurchaseService.ValidateReceipt (...) fails |
OnPurchaseConfirm (string gameOrderId) | void | Deprecated |
OnPurchaseConfirm (string gameOrderId, string message) | void | Deprecated |
Unity IAP uses the PurchaseService
class internally to initiate purchasing activities.
With the purchase listener implemented, call the PurchaseService.Purchase
method to execute a purchase transaction:
using UnityEngine.ChannelPurchase;
......
var myPurchaseListener = new ExamplePurchaseListener ();
PurchaseService.Purchase ("Product ID", "Game Order ID", myPurchaseListener);
Product IDs are listed in the Xiaomi developer portal. If your app runs in debug mode, Product IDs also export to the MiGameProductCatalog.prop file. Game Order ID can be null; the Unity Channel SDK will generate its UUID.
Key: | Type: | Description: |
---|---|---|
static Purchase (string productCode, string gameOrderId, IPurchaseListener productListener) | void | Purchase Products |
static ValidateReceipt (string gameOrderId, IPurchaseListener purchaseListener) | void | Validate purchase |
static ConfirmPurchase () | void | Deprecated (use ValidateReceipt (...) instead) |
After a purchase, validate it by calling the PurchaseService.ValidateReceipt
method:
PurchaseService.ValidateReceipt(gameOrderId, myPurchaseListener);
If gameOrderId
is valid, myPurchaseListener
receives ReceiptInfo
containing signData
and signature
, which Unity Channel uses to validate the purchase.
Key: | Type: | Description: |
---|---|---|
productCode | строка | A Product’s unique ID (you can also configure this directly in the Xiaomi dev portal) |
gameOrderId | строка | The order’s purchase ID |
orderQueryToken | строка | Used to validate purchases |
Validation usually occurs on the game server, however you can also validate the signData
client-side.
Key: | Type: | Description: |
---|---|---|
gameOrderId | строка | The order’s purchase ID |
signData | строка | A JSON string containing details of the purchase |
signature | строка | signData’s signature |
Before continuing, please review documentation on Unity IAP receipt validation. Also see the UnityEngine.Purchasing Scripting API.
The IUnityChannelConfiguration
and IUnityChannelExtensions
interfaces offer extended functionality for unpacking app store receipts.
Perform local receipt validation by using the Unity IAP CrossPlatformValidator
class (detailed in the Receipt validation documentation) and the IUnityChannelExtensions.ValidateReceipt
method (detailed below) at the time of purchase.
Before implementing validation, enable receipt obfuscation for Xiaomi:
To automatically fetch the required receipt data from Unity Channel during purchase, set IUnityChannelConfiguration.fetchReceiptPayloadOnPurchase
to true
when initializing Unity IAP. This calls IUnityChannelExtensions.ValidateReceipt
internally after a successful purchase (ideally when the PurchaseEventArgs
’ purchasedProduct.receipt
field triggers the IStoreListener.ProcessPurchase
success callback).
Note: Setting the fetchReceiptPayloadOnPurchase
flag to true incurs a network request to fetch the cryptographic receipt data after a successful purchase. If this second network request fails for any reason, the ProcessPurchase
success callback receives a Product with an invalid receipt.
Passing purchasedProduct.receipt
data through the CrossPlatformValidator.Validate
API returns an IPurchaseReceipt
, which is the fully validated receipt. If the result is empty, the validation failed. See the example below:
CrossPlatformValidator validator = new CrossPlatformValidator (GooglePlayTangle.Data(), AppleTangle.Data(), UnityChannelTangle.Data(), Application.identifier);
var result = validator.Validate(purchasedProduct.receipt);
Key: | Type: | Description: |
---|---|---|
fetchReceiptPayloadOnPurchase | bool | Automates Unity Channel receipt data collection during purchase |
Use the IUnityChannelExtensions
interface to confirm purchases and validate receipts. The callbacks for the above methods return a bool indicating success, a ‘signData’ string, and a ‘signature’ string (see section on ChannelPurchase.ReceiptInfo).
Note: ValidateReceipt ()
is vulnerable to man-in-the-middle attacks; use the Client RSA Public Key for added security (see the App Store Settings section of the Xiaomi IAP integration guide).
Key: | Type: | Description: |
---|---|---|
ConfirmPurchase (string transactionID, Action<bool, string, string>, callback) |
void | Collects purchase status for a prior purchase (used to review purchase history, especially for game interruption or network timeouts) |
ValidateReceipt (string transactionID, Action<bool, string, string>, callback) |
void | Validates the receipt for a given transactionID |
The UnifiedReceipt
class contains store-specific transaction data that Unity IAP can interpret. See the example below on how to unpack a unified receipt string:
var unifiedReceipt = JsonUtility.FromJson<UnifiedReceipt>(purchEvtArg.purchasedProduct.receipt)
Key: | Type: | Description: |
---|---|---|
Payload | строка | Unity IAP’s wrapper for receipts that come back in different formats for different stores |
Store | строка | The store on which the purchase occurred |
TransactionID | строка | The unique transaction ID |
Use the UnityChannelPurchaseReceipt
to further unpack a unified receipt into a Unity Channel receipt. See the example below:
var ucReceipt = JsonUtility.FromJson<UnityChannelPurchaseReceipt>(unifiedReceipt.Payload)
Use this additional Unity Channel receipt data for informational purposes.
Key: | Type: | Description: |
---|---|---|
productID | строка | The unique ID of the purchased Product |
transactionID | строка | The unique transaction ID |
orderQueryToken | строка | The order query token |
To check if the Xiaomi app store is the active store in your game at runtime, use the boolean value provided by the following code snippet:
var module = StandardPurchasingModule.Instance();
bool m_IsUnityChannelSelected =
Application.platform == RuntimePlatform.Android &&
module.androidStore == AndroidStore.XiaomiMiPay;