Skip to content
Stove
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.



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.

text
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.).

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.



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}.



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 InitializeLoginSetCharacter.
    • We recommend calling deep-link handling after character setup is complete.

  • Read the received Deep Link data
    • On Android, read the data from the Intent received in Activity.onNewIntent or onCreate.
    • 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.

  • 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-QWA1
    Manual pop-up invocation {packageName}://stovelink/popup/manual?popupnotice_param={location}
    e.g., com.stove.mvp.google://stovelink/popup/manual?popupnotice_param=1
    Load 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%2F
    Cash 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, the pin parameter 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 the VIEW/DEFAULT/BROWSABLE categories along with the android:launchMode="singleTask" attribute, and the <data android:scheme="${applicationId}"/> data scheme.

  • 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 the CFBundleURLTypes array and the CFBundleURLSchemes item.

Development


Android Implementation


  • Register the AndroidManifest.xml Intent Filter
    • Add a deep-link-receiving intent-filter to the main Activity along with the android: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>
    

  • Handle MainActivity onCreate / onNewIntent
    • Register the Intent received in onCreate and onNewIntent with StoveDeepLinkManager.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.

  • Using the StoveDeepLinkManager class

  • 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.).

kotlin
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 > CFBundleURLSchemes in Info.plist so 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>
    

  • Handle AppDelegate application:openURL:options:
    • In the application:openURL:options: callback where the iOS system passes the deep-link URL, register the URL with SGSDeepLinkManager. Then delegate to the STOVE SDK's application:openURL:options: so SDK-internal handling also proceeds.
    • For how to define a URL Scheme, refer to the Apple official guide.

  • 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.

objectivec
#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.deepLinkActivated event. For the Unity official guide, refer to the deep-linking manual.

  • Android build
    • Apply the AndroidManifest.xml Intent Filter from the Android Implementation section above equally to Unity Plugins/Android or a custom manifest template.

  • iOS build
    • Apply the Info.plist URL Types > URL Schemes setting from the iOS Implementation section above equally in Xcode Post-Process (or PlayerSettings).

  • Call DeepLinkManager and execute the SDK Method
    • Parse the URL received from Application.deepLinkActivated in 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.

Unreal Implementation


  • Add the StoveDeepLink files
    • Download and unzip StoveDeepLink.zip, then add the following files to the Unreal project.
      • StoveDeepLink_APL.xml

      • StoveLinkBridge.h / StoveLinkBridge.cpp
      • StoveDeepLinkGameHandler.h / StoveDeepLinkGameHandler.cpp

  • Android — Register APL.xml in Build.cs
    • Add StoveDeepLink_APL.xml via AdditionalPropertiesForReceipt in the Android branch of the project's Build.cs.
    csharp
    if (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"));
    }
    

  • 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::FOnOpenURLwithOptions to the engine code. For details, refer to the engine-code addition guide.

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.cpp to the project, and call RegisterStoveDeepLinkBridge() only once at game start to register the iOS deep-link response listener.
    • The recommended call time is GameInstance::Init() or StartupModule(). It must be registered before application:openURL:options: in the iOS lifecycle for deep-link responses to be received correctly.

Register the listener only once
FIOSCoreDelegates::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.

cpp
// StoveLinkBridge.h
#pragma once
// Register iOS deep-link reception (call once at game start)
void RegisterStoveDeepLinkBridge();
cpp
// 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
}
cpp
// 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 > CFBundleURLSchemes in Info.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>
    

  • 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. StoveDeepLinkGameHandler is 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();
    

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 pin parameter and call the SDK coupon-registration API. It registers correctly only when user login and character setup are complete.

  • 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.

  • Specific-URL loading handling (stovelink/popup/load?url={url})
    • Show the external URL passed via the url parameter as a WebView pop-up. The URL must be passed URL-encoded.

  • 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 / StoveDeepLinkGameHandler are 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 pin in stovelink/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.

  • 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 with setData/setURL, and handle them all at once in the main-page-entry callback.

  • 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.AddStatic approach, so calling it multiple times accumulates that many listeners and the same deep link is handled repeatedly. Guard RegisterStoveDeepLinkBridge() to be called only once in the game boot sequence. Android needs no separate guard because setData overwrites each time.



Need to contact us directly? stove.developers@smilegate.com