Unity Integration Guide
Environment Requirements
- Supports Unity version 2019.4 and above
Preparation
- Create an app as described in Getting Ready, configure app parameters, and bind the API domain name
- Configure the package name and signature as described in TapSDK Quick Start
Obtaining the SDK
For versions before Unity 2020.3.15, it is recommended to upgrade the Gradle version to avoid build errors later. Refer to the Gradle Upgrade Steps Document.
The following introduces two methods to import the SDK: via Unity Package Manager or by modifying the Packages/manifest.json configuration file. Choose either one based on your project needs:
1. Import via Package Manager Visual Interface
Since the TapTap IAP relies on EDM4U (External Dependency Manager for Unity) to handle Android-related dependencies, the steps to import dependencies are install the EDM4U library first, then install the TapTap IAP.
Installing EDM4U
Below are two methods to install EDM4U, either through OpenUPM installation or manual download and installation:
- Method 1: Install EDM4U via OpenUPM
EDM4U can be downloaded via OpenUPM. Developers can register to use OpenUPM through Edit > Project Settings > Package Manager.

- Method 2: Manual Download and Installation
Developers can download the UPM package from Google APIs for Unity and install it by installing from a local disk.
Installing TapTap IAP
The TapTap IAP can be installed via NPMJS. Developers can register to use NPMJS through Edit > Project Settings > Package Manager.

After configuration, you can install TapTapSDK IAP 4.10.1 in Window > Package Manager > My Registries.
If TapTap Payments Global V2 is not in the installation directory, try re-registering NPMJS in Edit > Project Settings > Package Manager.

2. Modify the Packages/manifest.json File
"dependencies": {
"com.taptap.sdk.iap": "4.10.1", // Add TapTap IAP
"com.unity.purchasing": "3.1.0", // Required dependency for TapTap IAP
"com.google.external-dependency-manager": "1.2.179", // Required dependency for TapTap IAP
"com.taptap.sdk.core": "4.10.1",
...
...
},
// Add Registries
"scopedRegistries": [
{
"name": "taptap",
"url": "https://registry.npmjs.org",
"scopes": ["com.tapsdk"]
},
{
"name": "openupm",
"url": "https://package.openupm.com",
"scopes": ["com.google"]
}
]
Handling Android Dependency Failures
EDM4U automatically monitors Android dependencies introduced by the TapTap IAP. However, in certain cases, automatic dependency resolution may fail. Developers can force dependency resolution by using Assets > External Dependency Manager > Android Resolver > Force Resolve. Before testing, ensure that the dependency for com.taptap.android.payment:unity is added to the mainTemplate.gradle file. If EDM4U does not automatically add this dependency, developers can handle it manually.
SDK Guide
We have implemented a new store within the Unity IAP framework to reduce integration costs for apps that already have in-app purchases on Google Play or the App Store. If this is your first time dealing with in-app purchases, we will briefly explain Unity's in-app purchase process. Developers can also refer to Unity's official documentation for detailed information about in-app purchases.
Initialize Unity Gaming Services
Call UnityServices.InitializeAsync() to initialize Unity Gaming Services at once. This method returns a Task object, through which developers can obtain initialization status information.
using System;
using Unity.Services.Core;
using Unity.Services.Core.Environments;
using UnityEngine;
public class InitializeUnityServices : MonoBehaviour
{
public string environment = "production";
async void Start()
{
try
{
var options = new InitializationOptions()
.SetEnvironmentName(environment);
await UnityServices.InitializeAsync(options);
}
catch (Exception exception)
{
// An error occurred during services initialization.
}
}
}
Initialize IAP
Ensure that you add TapPurchasingModule during IAP initialization and set the correct clientId and clientToken.
using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.Purchasing.Extension;
using TapSDK.IAP;
public class MyIAPManager : IStoreListener {
private IStoreController controller;
private IExtensionProvider extensions;
public MyIAPManager () {
var builder = ConfigurationBuilder.Instance(TapPurchasingModule.Instance);
builder.Configure<ITapTapStoreConfiguration>().SetClientId("Your Client ID Here");
builder.Configure<ITapTapStoreConfiguration>().SetClientToken("Your Client Token Here");
builder.Configure<ITapTapStoreConfiguration>().SetRegionCode(1); // 0: CN, 1: GLOBAL
builder.Configure<ITapTapStoreConfiguration>().SetEnableLog(true); // Enable the log. It's recommended to turn it on for Debug and off for Release, with it being off by default.
builder.AddProduct("100_gold_coins", ProductType.Consumable);
UnityPurchasing.Initialize (this, builder);
}
/// <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.
///
/// Note that this will not be called if Internet is unavailable; Unity IAP
/// will attempt initialization until it becomes available.
/// </summary>
public void OnInitializeFailed (InitializationFailureReason error)
{
}
public void OnInitializeFailed(InitializationFailureReason error, string str)
{
}
/// <summary>
/// Called when a purchase completes.
///
/// May be called at any time after OnInitialized().
/// </summary>
public PurchaseProcessingResult ProcessPurchase (PurchaseEventArgs e)
{
return PurchaseProcessingResult.Complete;
}
/// <summary>
/// Called when a purchase fails.
/// </summary>
public void OnPurchaseFailed (Product i, PurchaseFailureReason p)
{
}
}
Initiate the Purchase Flow
Once IAP is successfully initialized, you can initiate the purchase flow by calling IStoreController.InitiatePurchase.
// Example method called when the user taps a 'buy' button
// to start the purchase process.
public void OnPurchaseClicked(string productId) {
controller.InitiatePurchase(productId, "developerPayload, e.g. user_id or order_id");
}
Handling Purchase Results
If an order remains unpaid for more than 30 minutes, its status is set to “Timed Out and Closed”. No callback notification is sent in this case.
When a purchase is completed, the store listener's ProcessPurchase(PurchaseEventArgs e) callback is invoked. You can obtain and process the order information in this callback:
e.purchasedProduct.definition.id: Product IDe.purchasedProduct.transactionID: TapTap order ID (orderId)e.purchasedProduct.receipt: Purchase credential (purchaseToken)
Your application should fulfill every purchase, for example by unlocking local content or sending the purchase receipt to your server to update the server-side game model.
This process returns a result indicating whether your application has finished processing the purchase:
| Result | Description |
|---|---|
| PurchaseProcessingResult.Complete | The application has completed processing the purchase, and it should not be notified again. |
| PurchaseProcessingResult.Pending | The application is still processing the purchase. Unless the IStoreController's ConfirmPendingPurchase function is called, ProcessPurchase will be called again the next time the application starts. |
Note that ProcessPurchase may be called at any time after initialization succeeds. If the application crashes while the ProcessPurchase handler is running, it will be called again the next time Unity IAP is initialized. You may therefore want to implement your own additional deduplication logic.
Reliability
Unity IAP requires purchases to be explicitly confirmed to ensure reliable completion in the event of network interruptions or application crashes. Any purchases completed while the application is offline will be sent to the application the next time it initializes.
Completing Purchases Immediately
When PurchaseProcessingResult.Complete is returned, Unity IAP completes the transaction immediately, as shown below.
If you are selling consumable products and fulfilling orders from a server—for example, providing in-game currency in an online game—you must not return PurchaseProcessingResult.Complete.
Otherwise, the consumable purchase may be lost if the application is uninstalled before the purchase is saved to the cloud.

Saving Purchases to the Cloud
If you want to save consumable purchase transactions to the cloud, you must return PurchaseProcessingResult.Pending and call ConfirmPendingPurchase only after the purchase has been saved successfully.
When Pending is returned, Unity IAP keeps the transaction open in the underlying store until it is confirmed as processed. This ensures that the consumable purchase transaction is not lost even if the user reinstalls the application while the consumable purchase is pending.

Restore Unfinished Orders
After Unity IAP initializes, the SDK automatically queries unfinished orders from the TapTap server. These are orders that the user has paid for but that the game has not yet verified. Developers do not need to call an additional restore-purchases API. This feature handles orders left unfinished because the application was exited, crashed, or encountered a network error.
The unfinished orders returned by the query are passed to ProcessPurchase(PurchaseEventArgs e). You can obtain and process the order information in this callback.
Note: The current version restores unfinished orders from the TapTap server, not the user's complete purchase history.
Debugging
Currently, we only provide the library implementation for Android. Please perform functional debugging in the Android environment (other platforms will be gradually supplemented).