Myket In-App Purchase Guide for Unreal Engine
For the complete plugin and runnable Myket billing sample project for Unreal Engine, see the official sample repository on GitHub.
The Myket In-App Billing SDK provides integration for Myket In-App Billing (IAB) on Android in Unreal Engine (compatible with UE 5.0 and newer).
The plugin provides native C++ APIs (via a GameInstanceSubsystem) and visual Blueprint nodes, supporting in-app products, inventory queries, consumption workflows, and diagnostics.
Features
- Full In-App Billing Support: Support for one-time purchases, including consumable items (such as coins, gems, energy) and non-consumable entitlements (such as premium unlocks or ad removal).
- Inventory & Catalog Queries: Query user-owned active purchases and SKU metadata (title, localized price, description).
- Single & Batch Consumption: Built-in methods for consuming individual items (
ConsumeProduct/ConsumePurchase) or multiple products at once. - C++ Subsystem & Visual Blueprints: Integration via
UMyketBillingSubsystemand Myket | Billing library nodes. - Procedural Sample UI (UMG/Slate): An interactive test widget created procedurally for billing verification.
- Live On-Screen Log Console: Displays timestamped event logs directly on the device screen for troubleshooting.
- Play-in-Editor (PIE) Support: Test UI interactions and Blueprint logic in the editor without crashes or requiring a physical device.
Prerequisites
- A registered developer account on the Myket Developer Portal.
- An application registered in your Myket developer console with a reserved package name.
- Your app's RSA Public Key copied from the Myket developer console.
- Products (SKUs) defined in your application console on Myket.
- Android build and packaging tools configured in Unreal Engine (Android SDK, NDK, and Java 17 JDK).
- A physical Android device with the Myket app installed and logged into a developer or test account.
Project Structure
Unreal/
├── Config/ # Unreal project settings
│ ├── DefaultEngine.ini # GameMode & Android packaging settings
│ ├── DefaultGame.ini # Project metadata
│ └── DefaultInput.ini # Input configuration (touch / mouse)
├── Plugins/
│ └── MyketBilling/ # Standalone Payment SDK Plugin
│ ├── Java/ # Android Java bridge (MyketBillingBridge.java)
│ ├── Source/MyketBilling/ # C++ Subsystem, JNI bridge, and Test UI
│ ├── MyketBilling_UPL.xml # Unreal Plugin Language manifest & Gradle config
│ ├── MyketBilling.Build.cs # Build rules
│ ├── MyketBilling.uplugin # Plugin descriptor
│ └── README.md # Dedicated SDK integration guide
├── Source/
│ ├── MyketSample/ # Example project game module
│ │ ├── MyketSampleGameMode.h/.cpp # Automatically displays the test UI on start
│ │ ├── MyketSampleModule.h/.cpp
│ │ └── MyketSample.Build.cs
│ ├── MyketSample.Target.cs
│ └── MyketSampleEditor.Target.cs
├── MyketSample.uproject # Unreal Engine project file
└── README.md
Quick Start: Running the Sample
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. In Unreal Editor (Play-in-Editor / PIE)
- Clone the repository:
git clone https://github.com/myketstore/billing-sample-unrealengine.git
- Open
MyketSample.uprojectin a compatible version of Unreal Engine. - Click Play in the editor toolbar.
MyketSampleGameModewill automatically display the Test Panel on your screen. Non-Android platforms run on a safe stub that responds with informational messages, allowing you to test UI interactions and Blueprint flow without crashes.
2. On an Android Device
- Connect your Android device via USB (with Developer Mode and USB Debugging enabled).
- Ensure the Myket app is installed and signed in.
- In Unreal Engine: go to Platforms → Android → Package Project (or use Quick Launch to deploy directly).
- Launch the application on your phone.
- Tap Initialize IAB, then tap any purchase or query button to test live transactions with Myket.
Integrating into an Existing Project
To add Myket In-App Billing to your existing Unreal project:
1. Copy Plugin Directory
Copy Plugins/MyketBilling from the sample repository into your project's Plugins/ directory (create the directory if it does not exist).
2. Enable Plugin in .uproject
Open your .uproject file in a text editor and add the plugin:
{
"Plugins": [
{
"Name": "MyketBilling",
"Enabled": true
}
]
}
If your file already has a Plugins array, append the entry to the existing array.
3. Add Module Dependency in Build.cs
In your game module's [ProjectName].Build.cs file, add MyketBilling to PublicDependencyModuleNames:
PublicDependencyModuleNames.AddRange(new string[] {
"Core",
"CoreUObject",
"Engine",
"InputCore",
"MyketBilling"
});
4. Configure Android Project Settings
In Project Settings > Platforms > Android:
- Set Android Package Name to match the application registered on the Myket Developer Console.
- Set Target SDK Version to 30 or higher.
- The plugin's UPL file (
MyketBilling_UPL.xml) automatically injects the Myket Maven repository, billing client dependencies,BILLINGpermissions, and package visibility declarations (<queries>) into your Android build.
API & Code Integration Guide
The plugin provides UMyketBillingSubsystem at the GameInstance level, managing the global billing lifecycle.
1. C++ Integration
Initialization & Event Binding
In your game mode, player controller, or shop manager:
#include "MyketBillingSubsystem.h"
#include "Kismet/GameplayStatics.h"
void AMyGameMode::InitBilling()
{
UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(this);
if (!GameInstance) return;
UMyketBillingSubsystem* Billing = GameInstance->GetSubsystem<UMyketBillingSubsystem>();
if (!Billing) return;
// Bind event delegates
Billing->OnBillingSupported.AddDynamic(this, &AMyGameMode::HandleBillingSupported);
Billing->OnBillingNotSupported.AddDynamic(this, &AMyGameMode::HandleBillingNotSupported);
Billing->OnPurchaseFinished.AddDynamic(this, &AMyGameMode::HandlePurchaseFinished);
Billing->OnConsumeFinished.AddDynamic(this, &AMyGameMode::HandleConsumeFinished);
Billing->OnQueryInventoryFinished.AddDynamic(this, &AMyGameMode::HandleInventoryFinished);
// Initialize with your Base64 public key
Billing->Init(TEXT("YOUR_MYKET_BASE64_PUBLIC_KEY"));
}
Querying Inventory
After receiving OnBillingSupported:
void AMyGameMode::HandleBillingSupported()
{
UMyketBillingSubsystem* Billing = GetGameInstance()->GetSubsystem<UMyketBillingSubsystem>();
if (Billing)
{
TArray<FString> Skus = { TEXT("gem_pack_100"), TEXT("premium_upgrade") };
Billing->QueryInventory(Skus);
}
}
Launching a Purchase
void AMyGameMode::BuyProduct(FString Sku)
{
UMyketBillingSubsystem* Billing = GetGameInstance()->GetSubsystem<UMyketBillingSubsystem>();
if (Billing)
{
FString DeveloperPayload = TEXT("unique_order_payload_123");
Billing->PurchaseProduct(Sku, DeveloperPayload);
}
}
The developerPayload string must not exceed 800 characters.
Handling Purchase and Consumption
void AMyGameMode::HandlePurchaseFinished(const FMyketPurchase& Purchase, const FMyketResult& Result)
{
if (Result.bIsSuccess)
{
// If consumable item (coins, energy, gems):
if (Purchase.ProductId == TEXT("gem_pack_100"))
{
UMyketBillingSubsystem* Billing = GetGameInstance()->GetSubsystem<UMyketBillingSubsystem>();
if (Billing)
{
Billing->ConsumeProduct(Purchase.ProductId);
}
}
else
{
// Non-consumable entitlement (e.g. ad removal)
UnlockFeature();
}
}
else
{
UE_LOG(LogTemp, Error, TEXT("Purchase failed: %s"), *Result.Message);
}
}
void AMyGameMode::HandleConsumeFinished(const FMyketPurchase& Purchase, const FMyketResult& Result)
{
if (Result.bIsSuccess)
{
UE_LOG(LogTemp, Log, TEXT("Product consumed successfully: %s"), *Purchase.ProductId);
// Credit gems or coins to the player
}
}
Never consume non-consumable products. Consuming an item permanently removes it from the user's active inventory on Myket.
2. Blueprint Integration
All subsystem methods and events are exposed to Blueprints:
- Use Get Myket Billing Subsystem to retrieve the subsystem.
- Bind to delegates:
On Billing SupportedOn Billing Not SupportedOn Query Inventory FinishedOn Purchase FinishedOn Consume Finished
- Call Init with your Myket public key.
- Call Purchase Product to initiate payment, and Consume Product or Consume Purchase for consumables.
Sample UI Features (UMyketTestWidget)
The procedural Slate/UMG widget includes full test actions:
- Initialize IAB: Initializes the billing helper with the configured public key.
- Query Inventory: Queries catalog details and user purchases for sample SKUs.
- Query SkuDetails: Queries metadata (title, price, description) for products.
- Query Purchases: Retrieves currently owned active purchases.
- Purchase Product Test1 / Test2: Purchases test items
test1andtest2. - Consume Purchase Test1 / Test2: Consumes test items so they can be purchased again.
- Consume Multiple Purchases: Batch consumes multiple purchases simultaneously.
- Test Unavailable Item: Verifies error handling for non-existent SKUs (
unavailable). - Custom SKU Field: Allows entering any arbitrary SKU and testing purchase/consumption without recompiling.
- Live On-Screen Log Console: Displays real-time timestamped event logs directly on screen without needing ADB.
Security & Best Practices
- Test on Physical Android Devices: Live transactions must be verified on a real device with Myket installed. Play-in-Editor provides a simulated stub for UI testing.
- Server-Side Validation: Send
Purchase.OriginalJsonandPurchase.Signatureto your backend to verify authenticity with your RSA public key. - Prevent Duplicate Delivery: Store
Purchase.PurchaseTokenin your database to ensure each transaction is fulfilled only once.