Skip to main content

Myket In-App Purchase Guide for Unity

Unity
Sample project

For a complete, runnable Myket Unity in-app billing implementation, see the official sample project on GitHub.

The Myket In-App Billing (IAB) Unity Plugin is the official solution for integrating in-app purchases into Unity games and applications targeting Android.

Features​

  • Consumable & Non-Consumable In-App Purchases: Complete flow for standard products (such as coins, gems, or premium unlocks).
  • Inventory & Purchase Recovery: Query purchase history and product information.
  • Consumption Management: APIs for consuming single or multiple items in batch (consumeProduct and consumeProducts).
  • Event-Driven Architecture: C# events via IABEventManager for asynchronous callbacks.
  • Gradle Integration: Native dependency resolution through the Myket Maven repository using Unity custom Gradle templates (settingsTemplate.gradle and launcherTemplate.gradle).
  • ProGuard and R8 Rules: Keep rules for Android release builds.

Prerequisites​

  • Unity Editor: Unity 6 (6000.x) or Unity 2022 LTS with Android Build Support installed.
  • JDK: Java 17 compatible JDK.
  • Test Device: A physical Android device with the Myket Application installed and signed in.
  • Myket Developer Account: A registered developer account on the Myket Developers Portal with:
    • Your application registered with a matching Package Name.
    • In-app products created.
    • Your developer Public Key available.

[!NOTE] In-app billing requires the Myket store app to be installed and active on the device during testing. The plugin communicates with Myket's billing service via Android IPC (AIDL).

Project Structure​

Assets/
├── MyketIAB/ # Core Myket IAB C# Plugin
│ ├── MyketIAB.cs # Main native bridge API
│ ├── MyketIABEventManager.cs # Event dispatcher (C# Actions)
│ ├── MyketPurchase.cs # Purchase data model
│ ├── MyketSkuInfo.cs # SKU/Product metadata model
│ ├── AbstractManager.cs # Unity-Android message bridge base
│ ├── ActionExtensions.cs # Utility extensions for events
│ ├── SimpleJSON.cs # Lightweight JSON parser
│ └── Demo/ # Sample Demo Scene & UI
│ ├── IABTestScene.unity # Interactive demo scene
│ ├── IABTestUI.cs # OnGUI test interface
│ └── MyketIABEventListener.cs # Sample event listener implementation
└── Plugins/
└── Android/ # Android-specific build configuration
├── AndroidManifest.xml # Custom Android manifest
├── launcherTemplate.gradle # Application-level Gradle config & dependencies
├── settingsTemplate.gradle # Repository configuration (Myket Maven)
├── gradleTemplate.properties # Gradle JVM and build properties
└── proguard-user.txt # Proguard / R8 keep rules

Quick Start: Running the Sample​

Subscription support

The subscription flow in the sample does not mean Myket currently supports subscriptions. Myket does not currently support subscription products; do not use the subscription example for a real product.

  1. Clone the repository:

    git clone https://github.com/myketstore/billing-sample-unity.git
  2. Open in Unity:

    • Launch Unity Hub.
    • Click Add -> Add project from disk and select the repository root folder.
    • Open the project with your installed Unity version (e.g., Unity 6 or Unity 2022 LTS).
  3. Configure Package Name (Application ID):

    • Go to Edit > Project Settings > Player > Android tab.
    • Under Other Settings > Identification, change Package Name to match the application registered on your Myket Developer Console (e.g., com.yourcompany.yourapp).
  4. Set Your Public Key and SKUs:

    • Open Assets/MyketIAB/Demo/IABTestUI.cs.
    • Replace the key variable with your actual RSA Public Key from the Myket Developer Panel:
      var key = "YOUR_MYKET_PUBLIC_KEY";
      MyketIAB.init(key);
    • Update the skus array with your registered product IDs:
      string[] skus = {
      "your_product_sku_1",
      "your_product_sku_2"
      };
  5. Build and Run:

    • Open the demo scene: Assets/MyketIAB/Demo/IABTestScene.unity.
    • Connect your Android test device via USB (with Developer Mode and USB Debugging enabled).
    • Go to File > Build Settings..., ensure the platform is set to Android, and click Build and Run.

Integrating into Your Own Project​

To add Myket In-App Billing to an existing Unity project:

1. Import Plugin Assets​

Copy the Assets/MyketIAB/ directory from the sample into your project's Assets/ directory.

2. Configure Custom Gradle Templates​

In Unity, go to Project Settings > Player > Android tab > Publishing Settings, and enable:

  • Custom Launcher Gradle Template (or Custom Main Gradle Template)
  • Custom Gradle Settings Template
  • Custom Proguard File

A. Add Myket Maven Repository (settingsTemplate.gradle)​

Add https://maven.myket.ir to the repository list in Assets/Plugins/Android/settingsTemplate.gradle:

dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
google()
mavenCentral()
maven { url 'https://maven.myket.ir' }
flatDir {
dirs "${project(':unityLibrary').projectDir}/libs"
}
}
}

B. Add Billing Dependency (launcherTemplate.gradle)​

Add the Myket Unity billing library under dependencies in Assets/Plugins/Android/launcherTemplate.gradle:

dependencies {
implementation project(':unityLibrary')
implementation 'ir.myket:billing-unity:2.2'
}

Ensure Java 17 compatibility is set under the android block:

android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
// ...
}

And configure manifest placeholders in defaultConfig:

defaultConfig {
manifestPlaceholders += [
marketApplicationId: "ir.mservices.market",
marketBindAddress: "ir.mservices.market.InAppBillingService.BIND",
marketPermission: "ir.mservices.market.BILLING"
]
}

3. Configure ProGuard / R8 Rules​

To prevent code obfuscation from breaking the native Android-to-Unity reflection bridge, ensure the following rules are present in Assets/Plugins/Android/proguard-user.txt:

-keep class ir.myket.billingclient.** { *; }
-keep interface ir.myket.billingclient.** { *; }
-keep class com.android.vending.billing.** { *; }
-keep interface com.android.vending.billing.** { *; }

Code Examples & API Guide​

Initialization (init)​

Initialize the billing client by passing your Base64-encoded RSA public key from the Myket Developer Portal early in your game lifecycle (e.g., Awake or Start):

using MyketPlugin;

string myketPublicKey = "YOUR_MYKET_PUBLIC_KEY";
MyketIAB.init(myketPublicKey);

Event Handling​

Subscribe to IABEventManager events to handle responses asynchronously. Always subscribe in OnEnable and unsubscribe in OnDisable:

using System.Collections.Generic;
using UnityEngine;
using MyketPlugin;

public class BillingManager : MonoBehaviour
{
void OnEnable()
{
IABEventManager.billingSupportedEvent += OnBillingSupported;
IABEventManager.billingNotSupportedEvent += OnBillingNotSupported;
IABEventManager.queryInventorySucceededEvent += OnQueryInventorySucceeded;
IABEventManager.queryInventoryFailedEvent += OnQueryInventoryFailed;
IABEventManager.purchaseSucceededEvent += OnPurchaseSucceeded;
IABEventManager.purchaseFailedEvent += OnPurchaseFailed;
IABEventManager.consumePurchaseSucceededEvent += OnConsumeSucceeded;
IABEventManager.consumePurchaseFailedEvent += OnConsumeFailed;
}

void OnDisable()
{
IABEventManager.billingSupportedEvent -= OnBillingSupported;
IABEventManager.billingNotSupportedEvent -= OnBillingNotSupported;
IABEventManager.queryInventorySucceededEvent -= OnQueryInventorySucceeded;
IABEventManager.queryInventoryFailedEvent -= OnQueryInventoryFailed;
IABEventManager.purchaseSucceededEvent -= OnPurchaseSucceeded;
IABEventManager.purchaseFailedEvent -= OnPurchaseFailed;
IABEventManager.consumePurchaseSucceededEvent -= OnConsumeSucceeded;
IABEventManager.consumePurchaseFailedEvent -= OnConsumeFailed;
}

void OnBillingSupported()
{
Debug.Log("Myket Billing is connected and ready.");
// Proceed to query inventory or enable shop buttons
}

void OnBillingNotSupported(string error)
{
Debug.LogError("Myket Billing not supported: " + error);
}

void OnPurchaseSucceeded(MyketPurchase purchase)
{
Debug.Log($"Purchased product: {purchase.ProductId}, Token: {purchase.PurchaseToken}");

// If consumable (e.g., coins, gems), consume it:
if (purchase.ProductId == "gem_pack_100")
{
MyketIAB.consumeProduct(purchase.ProductId);
}
else
{
// Non-consumable feature unlock
UnlockFeature();
}
}

void OnPurchaseFailed(string error)
{
Debug.LogError("Purchase failed: " + error);
}

void OnConsumeSucceeded(MyketPurchase purchase)
{
Debug.Log($"Product consumed successfully: {purchase.ProductId}");
// Grant virtual currency or reward to the player
}

void OnConsumeFailed(string error)
{
Debug.LogError("Failed to consume product: " + error);
}

void OnQueryInventorySucceeded(List<MyketPurchase> purchases, List<MyketSkuInfo> skus)
{
Debug.Log("Inventory queried successfully.");
// Recover pending consumable purchases or verify non-consumable ownership
}

void OnQueryInventoryFailed(string error)
{
Debug.LogError("Failed to query inventory: " + error);
}
}

Querying SKUs and Purchases​

Fetch product details (title, price, description) and check previously completed purchases:

// Query SKU details along with user purchase state
string[] productIds = new string[] { "gem_pack_100", "monthly_pass" };
MyketIAB.queryInventory(productIds);

// Or query only SKU information
MyketIAB.querySkuDetails(productIds);

// Query only current user purchases
MyketIAB.queryPurchases();

Purchasing Products​

Initiate a purchase flow for a product:

// Simple purchase
MyketIAB.purchaseProduct("gem_pack_100");

// Purchase with developer payload (optional security string for tracking)
MyketIAB.purchaseProduct("gem_pack_100", "unique_user_payload_123");
tip

The developerPayload string must not exceed 800 characters.

Consuming Purchases​

Consumable items (e.g., in-game coins, energy) must be consumed so the user can purchase them again:

// Consume a single product by SKU
MyketIAB.consumeProduct("gem_pack_100");

// Consume multiple products at once
MyketIAB.consumeProducts(new string[] { "gem_pack_100", "gem_pack_200" });
danger

Never consume non-consumable products. Consuming an item permanently removes it from the user's active inventory on Myket.

Debugging & Troubleshooting​

Enable Verbose Logging​

Enable high-detail debug logs during development to trace communication between Unity and the Myket billing service:

#if DEVELOPMENT_BUILD || UNITY_EDITOR
MyketIAB.enableLogging(true);
#endif
warning

High-detail logs output sensitive billing and payload information to Android Logcat. Disable detailed logging before exporting production / release builds.

Common Issues & Checklist​

IssueCauseSolution
billingNotSupportedEvent firesMyket application is not installed on deviceInstall the Myket app on the Android test device and log in.
"Item Unavailable" errorSKU not registered or application not published on portalVerify that the SKU ID in code matches the developer portal and the APK package name is registered.
Signature verification failedIncorrect Public KeyEnsure your RSA Public Key in MyketIAB.init() matches the key in the Myket Developer Panel under App Settings.
Crash or ClassNotFoundException in release buildProGuard/R8 stripped native classesVerify that rules from Assets/Plugins/Android/proguard-user.txt are included in your custom ProGuard file.
Gradle build failure: ir.myket:billing-unity not foundMissing Maven repositoryConfirm maven { url 'https://maven.myket.ir' } is declared in settingsTemplate.gradle.