IAP Game Unreal Developer Guide - ONE-store/inapp-sdk GitHub Wiki

< ์ฐธ๊ณ  >

๋ณธ ๋ฌธ์„œ๋Š” ์›์Šคํ† ์–ด ์ธ์•ฑ SDK v16(API v4)์— ๋Œ€ํ•œ ๊ฐ€์ด๋“œ ๋ฌธ์„œ์ž…๋‹ˆ๋‹ค. ์ตœ์‹  ์›์Šคํ† ์–ด ์ธ์•ฑ SDK v17(API v5)์— ๋Œ€ํ•œ ๊ฐ€์ด๋“œ ๋ฌธ์„œ๋Š” ์›์Šคํ† ์–ด ๊ฐœ๋ฐœ์ž์„ผํ„ฐ์—์„œ ์ œ๊ณต๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ตœ์‹  ์ธ์•ฑ SDK v17 ๊ฐ€์ด๋“œ ๋ฌธ์„œ ๋งํฌ : https://dev.onestore.co.kr/devpoc/reference/view/IAP_v17


ํ•ด๋‹น ๋‚ด์šฉ์€ Unreal์„ ์‚ฌ์šฉํ•˜๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ์—์„œ IAP SDK ์ ์šฉ์„ ๋•๊ธฐ ์œ„ํ•œ ์„ค๋ช…์„œ์ด๋‹ค. ์ด๋ฅผ ์œ„ํ•ด OnestoreIapHelper ํด๋ž˜์Šค(์ดํ•˜ OIAPhelper)๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

1. OIAPhelper ์†Œ๊ฐœ


OIAPhelper๋Š” IAP SDK ๋‚ด ๊ฒฐ์ œ ๊ด€๋ จ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ์‘๋‹ต ๊ฒฐ๊ณผ๋ฅผ native ๋ ˆ๋ฒจ๋กœ ๋ณด๋‚ด๋Š” ์—ญํ• ์„ ํ•˜๋Š” ์ƒ˜ํ”Œ ๊ฐ€์ด๋“œ ์ฝ”๋“œ์ด๋‹ค. OIAPhelper๋‚ด์— ์ •์˜๋œ native ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์‘๋‹ต ๊ฒฐ๊ณผ๊ฐ€ ์ „๋‹ฌ๋˜๊ธฐ ๋•Œ๋ฌธ์—, OIAPhelper ๋‚ด์— ์ •์˜๋œ native ๋ฉ”์„œ๋“œ๋“ค์€ ์—”์ง„(ํ˜น์€ ๊ทธ ์™ธ native ๋ ˆ๋ฒจ)๋‹จ์— ๋ฐ˜๋“œ์‹œ ๊ตฌํ˜„ ํ•ด์•ผ ํ•œ๋‹ค.

Folder File Name Description
UE4/src OnestoreIapHelper.java IAP SDK ๊ฒฐ์ œ API์™€ ์—ฐ๋™ํ•˜๊ธฐ ์œ„ํ•œ ์ƒ˜ํ”Œ ๊ฐ€์ด๋“œ ์ฝ”๋“œ

ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋Š” native ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ


2. OIAPhelper ์ ์šฉ


IAP SDK(.jar)์—์„œ ์ œ๊ณตํ•˜๋Š” API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด OIAPhelper๋ฅผ ์—”์ง„๊ณผ ์—ฐ๋™์‹œ์ผœ์•ผ ํ•œ๋‹ค.

1)์ตœ์‹  IAP SDK(.jar)๋ฅผ ์ž‘์—… ํ”„๋กœ์ ํŠธ libs ํด๋”์— ๋ณต์‚ฌ

2)OnestoreIapHelper.java ํŒŒ์ผ์„ ์•„๋ž˜ ์—”์ง„ ํด๋”์— ๋ณต์‚ฌ (GameActivity.java๊ฐ€ ์กด์žฌํ•˜๋Š” ํด๋”)

\Engine\Build\Android\Java\src\com\epicgames\ue4\

3)GameActivity.java ์ˆ˜์ •

import ์„ ์–ธ

import com.epicgames.ue4.OnestoreIapHelper;

OIAPhelper ๊ด€๋ จ ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€
  // Onestore manager objects
 private OnestoreIapHelper mOnestoreIapHelper = null;
 
 // Onestore In-App-Purchase functionality
 public void AndroidThunkJava_OnestoreIapSetupService(boolean isDebugMode) {
     Log.debug("[JAVA] - AndroidThunkJava_OnestoreIapSetupService. DebugMode : " + isDebugMode);

     if(mOnestoreIapHelper == null){
         mOnestoreIapHelper = new OnestoreIapHelper(this, isDebugMode);
     }
 }
 
 public void AndroidThunkJava_OnestoreIapRequestPurchase(final String appId, final String pId, final String pName, final String tId, final String bpInfo)   {
     if (mOnestoreIapHelper == null) {
        Log.debug("[JAVA] - OneStoreIapHelper is invalid");
             return;
     }
     mOnestoreIapHelper.requestPurchase(appId, pId, pName, tId, bpInfo);
 }
 
 public void AndroidThunkJava_OnestoreIapReceiptVerify(final String appId, final String txId, final String receiptSignData)
 {
     if (mOnestoreIapHelper == null) {
         Log.debug("[JAVA] - OneStoreIapHelper is invalid");
         return;
     }       
     mOnestoreIapHelper.doReceiptVerification(appId, txId, receiptSignData);
 }

public void AndroidThunkJava_OnestoreIapCmdPurchaseHistory(final String appId, final String pId)
{
     if (mOnestoreIapHelper == null) {
        Log.debug("[JAVA] - OneStoreIapHelper is invalid");
             return;
      }
      mOnestoreIapHelper.doCmdPurchaseHistory(appId, pId);
 }
 
 public void AndroidThunkJava_OnestoreIapCmdProductInfo(final String appId)
 {
     if (mOnestoreIapHelper == null) {
         Log.debug("[JAVA] - OneStoreIapHelper is invalid");
         return;
     }
     mOnestoreIapHelper.doCmdProductInfo(appId);
 }
 
 public void AndroidThunkJava_OnestoreIapCmdCheckPurchasability(final String appId, final String pId)
 {
     if (mOnestoreIapHelper == null) {
         Log.debug("[JAVA] - OneStoreIapHelper is invalid");
         return;
     }
     mOnestoreIapHelper.doCmdCheckPurchasability(appId, pId);
 }
 
 public void AndroidThunkJava_OnestoreIapCmdChangeProduct_withDrawSubscription(final String appId, final String pId)
 {
     if (mOnestoreIapHelper == null) {
         Log.debug("[JAVA] - OneStoreIapHelper is invalid");
         return;
     }       
     mOnestoreIapHelper.doCmdChangeProduct_withDrawSubscription(appId, pId);
 }
 
 public void AndroidThunkJava_OnestoreIapCmdChangeProduct_descentPoints(final String appId, final String pId)
 {
     if (mOnestoreIapHelper == null) {
         Log.debug("[JAVA] - OneStoreIapHelper is invalid");
         return;
     }
     mOnestoreIapHelper.doCmdChangeProduct_descentPoints(appId, pId);
 }
 
 public void AndroidThunkJava_OnestoreIapCmdPurchaseHistory_bg(final String appId, final String pId)
 {
     if (mOnestoreIapHelper == null) {
         Log.debug("[JAVA] - OneStoreIapHelper is invalid");
         return;
     }
     mOnestoreIapHelper.doCmdPurchaseHistory_bg(appId, pId);
 }
 
public void AndroidThunkJava_OnestoreIapCmdProductInfo_bg(final String appId)
 {
     if (mOnestoreIapHelper == null) {
                Log.debug("[JAVA] - OneStoreIapHelper is invalid");
         return;
     }
      mOnestoreIapHelper.doCmdProductInfo_bg(appId);
}

 public void AndroidThunkJava_OnestoreIapCmdCheckPurchasability_bg(final String appId, final String pId)
 {
     if (mOnestoreIapHelper == null) {
         Log.debug("[JAVA] - OneStoreIapHelper is invalid");
         return;
     }
     mOnestoreIapHelper.doCmdCheckPurchasability_bg(appId, pId);
 }
 
 public void AndroidThunkJava_OnestoreIapCmdChangeProduct_withDrawSubscription_bg(final String appId, final String pId)
 {
     if (mOnestoreIapHelper == null) {
         Log.debug("[JAVA] - OneStoreIapHelper is invalid");
         return;
     }
     mOnestoreIapHelper.doCmdChangeProduct_withDrawSubscription_bg(appId, pId);
 }
 
 public void AndroidThunkJava_OnestoreIapCmdChangeProduct_descentPoints_bg(final String appId, final String pId)
 {
     if (mOnestoreIapHelper == null) {
         Log.debug("[JAVA] - OneStoreIapHelper is invalid");
         return;
     }
}       

4)AndroidJNI.h ๋ฐ Android.cpp ์ˆ˜์ • Native ์˜์—ญ์—์„œ Java ์˜์—ญ(GameActivity.java ํด๋ž˜์Šค)์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด AndroidJNI.h ํŒŒ์ผ ๋ฐ AndroidJNI.cpp ํŒŒ์ผ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค. ํ•ด๋‹น ํŒŒ์ผ์€ ์•„๋ž˜ ๊ฒฝ๋กœ์— ์œ„์น˜ํ•œ๋‹ค. (UE4 4.12 ๊ธฐ์ค€)

\Engine\Source\Runtime\Launch\Private\Android\AndroidJNI.cpp \Engine\Source\Runtime\Launch\Public\Android\AndroidJNI.h

< AndroidJNI.h >

  class FJavaWrapper{
   public:
   ... 
   // In app purchase functionality for Onestore
   static jmethodID AndroidThunkJava_OnestoreIapSetupService;
   static jmethodID AndroidThunkJava_OnestoreIapRequestPurchase;
   static jmethodID AndroidThunkJava_OnestoreIapReceiptVerify;
   
   static jmethodID AndroidThunkJava_OnestoreIapCmdPurchaseHistory;
   static jmethodID AndroidThunkJava_OnestoreIapCmdProductInfo;
   static jmethodID AndroidThunkJava_OnestoreIapCmdCheckPurchasability;
   static jmethodID AndroidThunkJava_OnestoreIapCmdChangeProduct_withDrawSubscription;
   static jmethodID AndroidThunkJava_OnestoreIapCmdChangeProduct_descentPoints;

   static jmethodID AndroidThunkJava_OnestoreIapCmdPurchaseHistory_bg;
   static jmethodID AndroidThunkJava_OnestoreIapCmdProductInfo_bg;
   static jmethodID AndroidThunkJava_OnestoreIapCmdCheckPurchasability_bg;
   static jmethodID AndroidThunkJava_OnestoreIapCmdChangeProduct_withDrawSubscription_bg;
   static jmethodID AndroidThunkJava_OnestoreIapCmdChangeProduct_descentPoints_bg;
   ...

< Android.cpp >
//Declare all the static members of the class defs 

...

// In app purchase functionality for Onestore
jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapSetupService;
jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapRequestPurchase;
jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapReceiptVerify;

jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapCmdPurchaseHistory;
jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapCmdProductInfo;
jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapCmdCheckPurchasability;
jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapCmdChangeProduct_withDrawSubscription;
jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapCmdChangeProduct_descentPoints;

jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapCmdPurchaseHistory_bg;
jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapCmdProductInfo_bg;
jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapCmdCheckPurchasability_bg;
jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapCmdChangeProduct_withDrawSubscription_bg;
jmethodID FJavaWrapper::AndroidThunkJava_OnestoreIapCmdChangeProduct_descentPoints_bg;
void FJavaWrapper::FindClassesAndMethods(JNIEnv* Env)
{

...

// Onestore IAP method id
    AndroidThunkJava_OnestoreIapSetupService = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapSetupService", "(Z)V", bIsOptional);
    AndroidThunkJava_OnestoreIapRequestPurchase = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapRequestPurchase", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", bIsOptional);
    AndroidThunkJava_OnestoreIapReceiptVerify = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapReceiptVerify", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",bIsOptional);

    AndroidThunkJava_OnestoreIapCmdPurchaseHistory = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapCmdPurchaseHistory", "(Ljava/lang/String;Ljava/lang/String;)V",bIsOptional);
    AndroidThunkJava_OnestoreIapCmdProductInfo = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapCmdProductInfo", "(Ljava/lang/String;)V",bIsOptional);
    AndroidThunkJava_OnestoreIapCmdCheckPurchasability = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapCmdCheckPurchasability", "(Ljava/lang/String;Ljava/lang/String;)V",bIsOptional);
    AndroidThunkJava_OnestoreIapCmdChangeProduct_withDrawSubscription = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapCmdChangeProduct_withDrawSubscription", "(Ljava/lang/String;Ljava/lang/String;)V",bIsOptional);
    AndroidThunkJava_OnestoreIapCmdChangeProduct_descentPoints = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapCmdChangeProduct_descentPoints", "(Ljava/lang/String;Ljava/lang/String;)V",bIsOptional);

    AndroidThunkJava_OnestoreIapCmdPurchaseHistory_bg = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapCmdPurchaseHistory_bg", "(Ljava/lang/String;Ljava/lang/String;)V",bIsOptional);
    AndroidThunkJava_OnestoreIapCmdProductInfo_bg = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapCmdProductInfo_bg", "(Ljava/lang/String;)V",bIsOptional);
    AndroidThunkJava_OnestoreIapCmdCheckPurchasability_bg = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapCmdCheckPurchasability_bg", "(Ljava/lang/String;Ljava/lang/String;)V",bIsOptional);
    AndroidThunkJava_OnestoreIapCmdChangeProduct_withDrawSubscription_bg = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapCmdChangeProduct_withDrawSubscription_bg", "(Ljava/lang/String;Ljava/lang/String;)V",bIsOptional);
    AndroidThunkJava_OnestoreIapCmdChangeProduct_descentPoints_bg = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_OnestoreIapCmdChangeProduct_descentPoints_bg", "(Ljava/lang/String;Ljava/lang/String;)V",bIsOptional);

์ƒ๊ธฐ ์ž‘์—…์„ ํ†ตํ•ด Native ์˜์—ญ์—์„œ๋Š” JavaWrapper ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„ํ•จ์ˆ˜์ธ FindClassesAndMethods ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด GameActivity์— ์ž‘์„ฑํ•ด๋†“์€ ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ฒฐ์ œ๊ฐ€ ํ•„์š”ํ•œ ์‹œ์ ์— ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

5)native ๋ฉ”์„œ๋“œ ๊ตฌํ˜„ ๊ฒฐ์ œ ์‘๋‹ต์— ๋Œ€ํ•œ ์ฝœ๋ฐฑ์€ OnestoreIapHelper.java๋‚ด์— ์ •์˜๋œ native ๋ฉ”์„œ๋“œ๋กœ ์ „๋‹ฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— native ์˜์—ญ์— ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋“ค์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. ๋ณดํ†ต ๊ฒฐ์ œ ์‘๋‹ต์— ๋”ฐ๋ฅธ ์ „์ž์˜์ˆ˜์ฆ ์ •๋ณด์˜ ๊ฒ€์ฆ(์„œ๋ฒ„ to ์„œ๋ฒ„)๊ณผ ์ด์— ๋”ฐ๋ฅธ ์•„์ดํ…œ ์ง€๊ธ‰๋“ฑ์˜ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋œ๋‹ค.

6)์•ˆ๋“œ๋กœ์ด๋“œ ์„ธํŒ… IAP SDK์™€ ์ •์ƒ์ ์œผ๋กœ ์—ฐ๋™ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฐ˜๋“œ์‹œ ์•ˆ๋“œ๋กœ์ด๋“œ Manifest ์„ค์ •์„ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์–ธ๋ฆฌ์–ผ ์—”์ง„์˜ ํ”„๋กœ์ ํŠธ ์„ค์ • ๋ฉ”๋‰ด์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

enter image description here

์ถ”๊ฐ€ ์ •๋ณด๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด 3๊ฐ€์ง€์ด๋‹ค. Meta-data ์„ค์ •์€ 'Extra Settings for section..' ํ•ญ๋ชฉ์— ์ถ”๊ฐ€ํ•˜๊ณ , Permission ์„ค์ •์€ 'Extra Permissions..' ํ•ญ๋ชฉ์— ์ถ”๊ฐ€ํ•œ๋‹ค.

Meta-data

<meta-data 
    android:name="iap:api_version"
    android:value="4" />

Permission

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

์•ˆ๋“œ๋กœ์ด๋“œ ์ธ์•ฑ๊ฒฐ์ œ ์„œ๋น„์Šค์˜ manifest ํŒŒ์ผ์˜ ์˜ˆ
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.skplanet.iapexample"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="23" />

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        
        <meta-data
            android:name="iap:api_version"
            android:value="4" />
        
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" 
            android:theme="@android:style/Theme.Holo.Light">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

3. ์ธ์•ฑ๊ฒฐ์ œ ๊ตฌํ˜„

์ดˆ๊ธฐํ™”


// Onestore manager objects
private OnestoreIapHelper mOnestoreIapHelper = null;
    
// Onestore In-App-Purchase functionality
public void AndroidThunkJava_OnestoreIapSetupService(boolean isDebugMode) {
        Log.debug("[JAVA] - AndroidThunkJava_OnestoreIapSetupService. DebugMode : " + isDebugMode);

        if(mOnestoreIapHelper == null){
            mOnestoreIapHelper = new OnestoreIapHelper(this, isDebugMode);
        }
}

๊ฒฐ์ œ(Payment) ์ฒ˜๋ฆฌ


public void AndroidThunkJava_OnestoreIapRequestPurchase(final String appId, final String pId, final String pName, final String tId, final String bpInfo)	{
		if (mOnestoreIapHelper == null) {
			Log.debug("[JAVA] - OneStoreIapHelper is invalid");
            return;
		}

        mOnestoreIapHelper.requestPurchase(appId, pId, pName, tId, bpInfo);
}

// Callback
public native void nativeOnPaymentComplete(String resultString);
public native void nativeOnPaymentError(String reqId, String errCode, String errMsg);

์ฟผ๋ฆฌ(Query) ์ฒ˜๋ฆฌ


public void AndroidThunkJava_OnestoreIapCmdPurchaseHistory(final String appId, final String pId)
{
		if (mOnestoreIapHelper == null) {
			Log.debug("[JAVA] - OneStoreIapHelper is invalid");
            return;
		}
        
        mOnestoreIapHelper.doCmdPurchaseHistory(appId, pId);
        //mOnestoreIapHelper.doCmdPurchaseHistory_bg(appId, pId);
}
    
public void AndroidThunkJava_OnestoreIapCmdProductInfo(final String appId)
{
        if (mOnestoreIapHelper == null) {
            Log.debug("[JAVA] - OneStoreIapHelper is invalid");
            return;
        }
        
        mOnestoreIapHelper.doCmdProductInfo(appId);
        //mOnestoreIapHelper.doCmdProductInfo_bg(appId);
}
    
public void AndroidThunkJava_OnestoreIapCmdCheckPurchasability(final String appId, final String pId)
{ 
        if (mOnestoreIapHelper == null) {
            Log.debug("[JAVA] - OneStoreIapHelper is invalid");
            return;
        }
       
        mOnestoreIapHelper.doCmdCheckPurchasability(appId, pId);
        //mOnestoreIapHelper.doCmdCheckPurchasability_bg(appId, pId);
}
    
public void AndroidThunkJava_OnestoreIapCmdChangeProduct_withDrawSubscription(final String appId, final String pId)
    {
        if (mOnestoreIapHelper == null) {
            Log.debug("[JAVA] - OneStoreIapHelper is invalid");
            return;
        }
        
        mOnestoreIapHelper.doCmdChangeProduct_withDrawSubscription(appId, pId);
        //mOnestoreIapHelper.doCmdChangeProduct_withDrawSubscription_bg(appId, pId);
}
    
public void AndroidThunkJava_OnestoreIapCmdChangeProduct_descentPoints(final String appId, final String pId)
{      
        if (mOnestoreIapHelper == null) {
            Log.debug("[JAVA] - OneStoreIapHelper is invalid");
            return;
        }
        
        mOnestoreIapHelper.doCmdChangeProduct_descentPoints(appId, pId);
        //mOnestoreIapHelper.doCmdChangeProduct_descentPoints_bg(appId, pId);
}

// Callback
public native void nativeOnCommandComplete(String resultString);
public native void nativeOnCommandError(String reqId, String errCode, String errMsg);

์ „์ž์˜์ˆ˜์ฆ๊ฒ€์ฆ ์ฒ˜๋ฆฌ


๊ฒฐ์ œ ๊ฒฐ๊ณผ ์˜์ˆ˜์ฆ์— ๋Œ€ํ•œ ๊ฒ€์ฆ ๊ธฐ๋Šฅ์„ ํ•œ๋‹ค. ๋ณ„๋„์˜ ๊ฐœ๋ฐœ์„œ๋ฒ„๊ฐ€ ์—†์„ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•˜๊ธธ ๊ถŒ์žฅํ•œ๋‹ค. ๊ฐ€๊ธ‰์  ๊ฐœ๋ฐœ์„œ๋ฒ„์—์„œ Server API๋ฅผ ํ†ตํ•ด ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค. (https://github.com/ONE-store/inapp-sdk/wiki/IAP-Reference-Server-API)

public void AndroidThunkJava_OnestoreIapReceiptVerify(final String appId, final String txId, final String receiptSignData)
{
        if (mOnestoreIapHelper == null) {
            Log.debug("[JAVA] - OneStoreIapHelper is invalid");
            return;
        }
        
        mOnestoreIapHelper.doReceiptVerification(appId, txId, receiptSignData);
}

// Callback
public native void nativeOnVerifyReceiptComplete(String resultString);
public native void nativeOnVerifyReceiptError(String errCode);
โš ๏ธ **GitHub.com Fallback** โš ๏ธ