- Last Updated
Deep Link
Understanding
A deep link is a feature that receives a specific address or value from outside, runs the game (app), and moves the user to a specific screen in-game.
It's used in various user-inflow scenarios such as coupon registration, event participation, cash-shop entry, and invoking a specific pop-up.
The STOVE platform provides a feature to easily create and manage deep links in Partners, and the SDK delivers received deep-link data to the game
to support follow-up actions (calling the coupon-registration API, moving screens, etc.).
A deep link handles the flow from external entry (web, message, QR, etc.) → running the mobile app → entering a specific screen in-game, all with a single URL.
Application Environment and Operating Scope
| Item | Details |
|---|---|
| Applicable platform | Mobile (Android / iOS). On PC, it moves to a representative-URL-based web page. |
| Supported engines | Android (Java/Kotlin), iOS (Objective-C/Swift), Unity, Unreal. |
| Deep-link type | General (no coupon), coupon-type (linked to a coupon issued in the Partners Billing Center). |
| Validity period | 90 days by default. Configurable by use (up to 999 days) or set to no expiration. |
| Recommended execution time | The game main page after SDK initialization, login, and character setup are complete. |
Basic Deep-Link Execution Flow
The User → Partners → Billing → SDK → Game areas operate integrated in sequence.
| Area | Role |
|---|---|
| User | After clicking the deep link, enters the game and checks the reward. |
| Partners | Creates and manages coupons and deep links in the Partners GM Center. |
| Billing | Handles coupon creation and coupon-API execution. |
| SDK | Parses received deep-link data, and handles coupon-API calls and responses. |
| Game | Checks and executes the deep link, passes world/character info to the SDK, and handles reward payout. |
How the URI Scheme Works
A URI Scheme is a value the game (app) must define to run the designated game (app) when a specific link is clicked on mobile.
Format: myapp://open/community
- myapp : a unique value by which the OS identifies the app
- //open/community : the screen path of the mobile app you want to run via the URI Scheme
- Operation flow
- Click a hyperlink (e.g.,
myapp://open/community) on a web page or in the game (app). - The OS checks the passed URI Scheme and searches for an app that can run it.
- If an app is designated for that URI Scheme, it runs the app while passing along the URI.
- As the app runs, it references the content in the URI and performs a specific function (coupon registration, pop-up invocation, screen movement, etc.).
- Click a hyperlink (e.g.,
Integration Guide
Integration Preparation
The following items must be prepared before registering a deep link.
| Item | Description |
|---|---|
| Package name / Bundle ID | Pre-register the per-environment package name / Bundle ID in the Partners Launching > Mobile Market Info menu. |
| Define the URI Scheme | Decide the URI Scheme format the game (app) will use. |
| Coupon issuance (coupon-type deep link) | Issue the coupon first in the Partners Billing Center before registering a coupon-type deep link. |
Coupon-type deep links require coupon issuance in the Partners Billing Center before registration.
Step 1. Register the Deep Link
Create the deep link in the Partners GM Center, the STOVE back-office site. Registration is completed through 5 steps.
- Move to the deep-link management page
- It's located in the Partners deep-link management menu; click the New Link button to enter the registration screen.
- For a registered deep link, you can check the ID, type (general/coupon), link name, URL, status, validity period, and registration date together.
- Enter basic info
- Specify the type, link name, validity period, and representative URL of the deep link to create.
Item Description Link type Choose general or coupon type. Link name A name identifiable when looked up in Partners. Within 100 characters. Link validity period 90 days by default. Enter a number in days (up to 999 days) or choose 'no expiration'. Representative URL The default path moved to when the deep-link URL is accessed in an environment where the mobile app can't run (e.g., PC desktop).
- Enter per-OS link info
- Register the mobile-app link info. At least one of Android or iOS is required.
- For Android, enter the package name and URL; for iOS, enter the App ID, package name, and URL. The package name is auto-filled with the value registered in the Partners Mobile Market Info menu; if not registered, it appears blank.
- In the URL, enter the URL Scheme info of the screen to show when the game (app) runs. e.g.,
com.stove.mvp.google://stovelink/coupon.
- Enter coupon info (when using a coupon-type deep link)
- Enter the coupon info to use in the coupon-type deep link. This area isn't shown when a general deep link is selected.
- In coupon and round selection, choose the coupon to create a deep link for among the issued coupons. A coupon that already has a deep link issued can't be created again.
- The number of URLs generated automatically creates deep-link URLs equal to the number of selected coupons.
- Set the landing page and complete registration
- Set the landing page shown when the deep-link URL is accessed, then complete registration.
- Set the language selection, game name (up to 60 characters per language), app icon (100x100px), landing button and guide (default/custom), and preview items. When setting additional languages, any missing info is replaced with the default-language info.
- When registering a coupon-type deep link, a CSV file is provided; the first column is 'Deep-link URL' and the second is 'Short URL'.
The coupon number is included in the deep-link URL in the form
p={coupon number}.
Step 2. Execute the Deep Link
When a user clicks the deep-link URL on mobile, the deep link executes via a landing screen.
Behavior can differ depending on the OS type, version, browser type, and user action.
- Per-OS deep-link execution behavior
OS App install state Path-movement method Auto-execution On clicking the landing-page install button Android Not installed Enter URL in Samsung/Chrome browser X Move to store Enter URL in Naver browser O (move to store) - Click the link in another app O (move to store) - Installed Enter URL in Samsung/Chrome browser X Move to app Enter URL in Naver browser O (move to app) - Click the link in another app O (move to app) - iOS 13 and above Not installed Enter URL in Safari/Chrome browser X Move to store Installed Enter URL in Safari/Chrome browser X Move to app Below iOS 13 Not installed Enter URL in Safari/Chrome browser O (move to store) - Installed Enter URL in Safari/Chrome browser O (move to app) -
On iOS 13 and above, for enhanced security, deep-link auto-execution is blocked at the browser onLoad stage.
In this case, it operates by prompting the user to click the execution button directly via the landing-page screen.
Step 3. SDK–Game Communication
This is the communication flow between the SDK and the game after the game is run via the deep-link URL.
The recommended time for deep-link execution is the game main page after character setup is complete.
- Run the game (app)
- Via the deep-link URL, the OS runs the game app while passing along the URI data.
- Complete SDK login and character setup
- Complete SDK initialization and user authentication in the order
Initialize→Login→SetCharacter. - We recommend calling deep-link handling after character setup is complete.
- Complete SDK initialization and user authentication in the order
- Read the received Deep Link data
- On Android, read the data from the Intent received in
Activity.onNewIntentoronCreate. - On iOS, receive the NSURL via the
application:openURL:options:method. - On Unity, handle the URL received via a native plugin in the game code.
- On Android, read the data from the Intent received in
- Run (handle) Stove Link
- Execute the Stove SDK Method according to the received Deep Link URI value.
- Call examples for frequently used features (coupon registration, manual pop-up, loading a specific URL, cash shop) are below, and you can extend the sample code (
DeepLinkManager) as needed to call the SDK's various feature APIs.
- Stove Link call formats
Feature Deep-link format Coupon registration {packageName}://stovelink/coupon?pin={couponCode}
e.g.,com.stove.mvp.google://stovelink/coupon?pin=B1A4-1424-1241-QWA1Manual pop-up invocation {packageName}://stovelink/popup/manual?popupnotice_param={location}
e.g.,com.stove.mvp.google://stovelink/popup/manual?popupnotice_param=1Load a specific URL {packageName}://stovelink/popup/load?url={url}
e.g.,com.stove.mvp.google://stovelink/popup/load?url=https%3A%2F%2Fwww.onstove.com%2FCash shop {packageName}://cashshop
e.g.,com.stove.mvp.google://cashshop
URI Scheme Setup
There's the method of registering the URI Scheme info when registering a deep link in Partners, and
the iOS/Android app-setup method of directly defining the URI Scheme the game (app) will use.
- Partners settings
- Enter the URL Scheme info when registering a deep link in Partners.
- For example, if you set
com.stove.epic7.googleqa2://stovelink/coupon, thepinparameter and value are auto-generated by the designated coupon info.
- Android URI Scheme setup
- Add an Intent Filter to the MainActivity settings in
AndroidManifest.xml. Register an intent-filter block including theVIEW/DEFAULT/BROWSABLEcategories along with theandroid:launchMode="singleTask"attribute, and the<data android:scheme="${applicationId}"/>data scheme.
- Add an Intent Filter to the MainActivity settings in
- iOS URI Scheme setup
- Add the Bundle identifier value to URL Types > URL Schemes in
Info.plist. e.g.,com.stove.mvp.ios. - You can use either the Xcode UI or editing the Info.plist XML, and register the
CFBundleTypeRole(Editor) within theCFBundleURLTypesarray and theCFBundleURLSchemesitem.
- Add the Bundle identifier value to URL Types > URL Schemes in
Development
Android Implementation
- Register the AndroidManifest.xml Intent Filter
- Add a deep-link-receiving
intent-filterto the main Activity along with theandroid:launchMode="singleTask"attribute. The game app's package name is automatically placed where${applicationId}is.
xml<manifest> <application> <activity android:name="com.stove.mvp.MainActivity" android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:launchMode="singleTask" android:screenOrientation="fullSensor"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="${applicationId}"/> </intent-filter> </activity> </application> </manifest> - Add a deep-link-receiving
- Handle MainActivity onCreate / onNewIntent
- Register the Intent received in
onCreateandonNewIntentwithStoveDeepLinkManager.setData(intent). Handling it in both methods supports both cold start (app not running → launched via deep link) and hot start (deep link received while the app is running). - For directly parsing the received Intent data, refer to the Android official guide.
- Register the Intent received in
- Using the StoveDeepLinkManager class
- The sample class is provided on the SDK forum and is an area the CP company (developer) can manage and modify directly. As URI patterns grow, extend this class to add handling logic.
- StoveDeepLinkManager.kt · StoveDeepLinkManager.java
- Call parseStoveDeepLink and execute the Stove SDK Method
- Call
StoveDeepLinkManager.parseStoveLink(activity)at the game main page after SDK login and character setup are complete. The SDK parses the registered URI and executes the corresponding feature (coupon registration, pop-up invocation, etc.).
- Call
class MainActivity : AppCompatActivity() {
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
StoveDeepLinkManager.setData(intent)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
StoveDeepLinkManager.setData(intent)
}
fun parseStoveDeepLink(activity: Activity) {
StoveDeepLinkManager.parseStoveLink(activity)
}
}
iOS Implementation
- Register Info.plist URL Types > URL Schemes
- Add the game's Bundle Identifier value to
CFBundleURLTypes > CFBundleURLSchemesinInfo.plistso the app runs via deep link. (e.g.,com.stove.mvp.ios) - You can either register it in the Xcode UI or edit the Info.plist XML directly.
xml<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLSchemes</key> <array> <string>com.stove.mvp.ios</string> </array> </dict> </array> </plist> - Add the game's Bundle Identifier value to
- Handle AppDelegate
application:openURL:options:- In the
application:openURL:options:callback where the iOS system passes the deep-link URL, register the URL withSGSDeepLinkManager. Then delegate to the STOVE SDK'sapplication:openURL:options:so SDK-internal handling also proceeds. - For how to define a URL Scheme, refer to the Apple official guide.
- In the
- Using the SGSDeepLinkManager class
- The sample class is provided on the SDK forum and is an area the CP company can manage and modify directly. When extending URI patterns, modify this class to add handling logic.
- SGSDeepLinkManager.h · SGSDeepLinkManager.m
- Call parseStoveLink and execute the Stove SDK Method
- Calling
[[SGSDeepLinkManager sharedInstance] parseStoveLink]at the game main page after SDK login and character setup are complete makes the SDK parse the registered URI and execute the corresponding feature.
- Calling
#import "SGSDeepLinkManager.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
[[SGSDeepLinkManager sharedInstance] setURL:url];
return [SGSApplicationDelegate application:app openURL:url options:options];
}
- (void)parseStoveLink {
[[SGSDeepLinkManager sharedInstance] parseStoveLink];
}
@end
Unity Implementation
Unity doesn't provide a separate STOVE-specific helper class. Use Unity's standard deep-link handling flow as-is, and apply the Manifest/Info.plist settings from the Android/iOS sections above equally to the Android/iOS build outputs.
- Unity standard deep-link handling
- Receive and handle the URL string via Unity's built-in
Application.deepLinkActivatedevent. For the Unity official guide, refer to the deep-linking manual.
- Receive and handle the URL string via Unity's built-in
- Android build
- Apply the
AndroidManifest.xml Intent Filterfrom the Android Implementation section above equally to Unity Plugins/Android or a custom manifest template.
- Apply the
- iOS build
- Apply the
Info.plist URL Types > URL Schemessetting from the iOS Implementation section above equally in Xcode Post-Process (or PlayerSettings).
- Apply the
- Call DeepLinkManager and execute the SDK Method
- Parse the URL received from
Application.deepLinkActivatedin the game-side manager and map it to STOVE SDK APIs (coupon registration, pop-up invocation, cash-shop entry, etc.). For URI formats and mapping targets, refer to the Deep-Link Call Handling section.
- Parse the URL received from
Unreal Implementation
- Add the StoveDeepLink files
- Download and unzip StoveDeepLink.zip, then add the following files to the Unreal project.
StoveDeepLink_APL.xmlStoveLinkBridge.h/StoveLinkBridge.cppStoveDeepLinkGameHandler.h/StoveDeepLinkGameHandler.cpp
- Download and unzip StoveDeepLink.zip, then add the following files to the Unreal project.
- Android — Register APL.xml in Build.cs
- Add
StoveDeepLink_APL.xmlviaAdditionalPropertiesForReceiptin the Android branch of the project'sBuild.cs.
csharpif (Target.Platform == UnrealTargetPlatform.Android) { PrivateDependencyModuleNames.AddRange(new string[] { "Launch" }); string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath); // ... /* Add StoveDeepLink_APL */ AdditionalPropertiesForReceipt.Add("AndroidPlugin", Path.Combine(PluginPath, "StoveDeepLink_APL.xml")); } - Add
- Android — Register URI Schemes
- In the Unreal Editor's Project Settings, register a game-package-based intent-filter in the Android URI Schemes item.
xml<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="{packageName}" android:host="{game-studio integration HOST}" /> </intent-filter>
- iOS — Add engine code
- The Unreal engine doesn't handle deep-link responses by default, so you must add
FIOSCoreDelegates::FOnOpenURLwithOptionsto the engine code. For details, refer to the engine-code addition guide.
- The Unreal engine doesn't handle deep-link responses by default, so you must add
Engine-code modification is required
It works only in a custom engine build environment; a standard engine built without modification can't receive iOS deep-link responses.
- iOS — Register the DeepLink receive listener
- Add
StoveLinkBridge.h/StoveLinkBridge.cppto the project, and callRegisterStoveDeepLinkBridge()only once at game start to register the iOS deep-link response listener. - The recommended call time is
GameInstance::Init()orStartupModule(). It must be registered beforeapplication:openURL:options:in the iOS lifecycle for deep-link responses to be received correctly.
- Add
Register the listener only onceFIOSCoreDelegates::OnOpenURLwithOptions.AddStatic is an "add-registration" approach, so calling it multiple times causes that many duplicate executions. You must guard it to be called only once in the game boot sequence.
// StoveLinkBridge.h
#pragma once
// Register iOS deep-link reception (call once at game start)
void RegisterStoveDeepLinkBridge();
// StoveLinkBridge.cpp
#include "StoveLinkBridge.h"
#include "CoreMinimal.h"
#if PLATFORM_IOS
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#include "IOS/IOSAppDelegate.h"
#include "Async/Async.h"
#include "StoveDeepLinkGameHandler.h"
#endif
#if PLATFORM_IOS
static void OnOpenURLwithOptions(UIApplication* application, NSURL* url, NSDictionary* options)
{
if (!url) return;
NSString* abs = [url absoluteString];
if (!abs) return;
const FString UrlString = UTF8_TO_TCHAR([abs UTF8String]);
AsyncTask(ENamedThreads::GameThread, [UrlString]()
{
StoveDeepLinkGameHandler::CacheIfStoveLink(UrlString);
});
}
#endif
void RegisterStoveDeepLinkBridge()
{
#if PLATFORM_IOS
FIOSCoreDelegates::OnOpenURLwithOptions.AddStatic(&OnOpenURLwithOptions);
#endif
}
// Register once in GameInstance
#include "StoveSDKGameInstance.h"
#include "StoveLinkBridge.h"
void UStoveSDKGameInstance::Init()
{
Super::Init();
#if PLATFORM_IOS
RegisterStoveDeepLinkBridge();
#endif
}
- iOS — Register the URL Scheme
- Add the game's BundleID to
CFBundleURLTypes > CFBundleURLSchemesinInfo.plist. (e.g.,$(PRODUCT_BUNDLE_IDENTIFIER))
xml<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLSchemes</key> <array> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> </array> </dict> </array> - Add the game's BundleID to
- Call StoveDeepLinkGameHandler::HandleDeepLink_OnGameThread
- Calling it at the game main page after SDK login and character setup are complete dispatches the cached deep link to the SDK feature.
StoveDeepLinkGameHandleris an area the CP company can manage and modify directly, so you can freely change it when extending URI patterns.
cpp#include "StoveDeepLinkGameHandler.h" // Deep-link usage call StoveDeepLinkGameHandler::HandleDeepLink_OnGameThread(); - Calling it at the game main page after SDK login and character setup are complete dispatches the cached deep link to the SDK feature.
Deep-Link Call Handling
When parseStoveLink (Android: StoveDeepLinkManager.parseStoveLink, iOS: [SGSDeepLinkManager parseStoveLink], Unreal: StoveDeepLinkGameHandler::HandleDeepLink_OnGameThread) is called, the SDK features below are executed per received URI path.
- Coupon-registration handling (
stovelink/coupon?pin={couponCode})- Extract the coupon code from the
pinparameter and call the SDK coupon-registration API. It registers correctly only when user login and character setup are complete.
- Extract the coupon code from the
- Manual pop-up invocation handling (
stovelink/popup/manual?popupnotice_param={location})- Show the manual pop-up for the location ID specified by
popupnotice_param. A pop-up pre-registered in Partners must exist for it to show correctly.
- Show the manual pop-up for the location ID specified by
- Specific-URL loading handling (
stovelink/popup/load?url={url})- Show the external URL passed via the
urlparameter as a WebView pop-up. The URL must be passed URL-encoded.
- Show the external URL passed via the
- Cash-shop entry handling (
{packageName}://cashshop)- Move to the in-game cash-shop screen. It works only when mapped to the game-side routing.
- Extending DeepLinkManager — adding new URI patterns
StoveDeepLinkManager/SGSDeepLinkManager/StoveDeepLinkGameHandlerare areas the CP company can manage and modify directly. To add a new URI pattern (e.g., event page, friend invitation, etc.), extend that class's dispatch logic to map the new URI to a game/SDK API.
Exception Handling
- Handling receipt of an invalid URI format
- If a required parameter is missing (e.g., no
pininstovelink/coupon) or an unknown path comes in, either ignore it via branching in the DeepLinkManager or show the user a notice message. URI validation logic is implemented in the CP company's manager class (StoveDeepLinkManager/SGSDeepLinkManager/StoveDeepLinkGameHandler), not the SDK.
- If a required parameter is missing (e.g., no
- Queuing deep links while SDK login/character setup is incomplete
- Deep links are received at app launch, but call the actual handling (
parseStoveLink/HandleDeepLink_OnGameThread) at the game main page after SDK login and character setup are complete. Store URIs received before that in the manager withsetData/setURL, and handle them all at once in the main-page-entry callback.
- Deep links are received at app launch, but call the actual handling (
- Handling auto-execution blocking on iOS 13 and above
- From iOS 13, security policy blocks deep-link auto-execution at the browser onLoad stage. The STOVE landing page automatically prompts the user to click the execution button, so no additional game-side implementation is needed. However, if your structure triggers the deep link from your own web page, be sure to provide a user-click UI.
- Preventing duplicate deep-link calls (Unreal iOS)
- Unreal iOS uses the
FIOSCoreDelegates::OnOpenURLwithOptions.AddStaticapproach, so calling it multiple times accumulates that many listeners and the same deep link is handled repeatedly. GuardRegisterStoveDeepLinkBridge()to be called only once in the game boot sequence. Android needs no separate guard becausesetDataoverwrites each time.
- Unreal iOS uses the