--- title: "Payment" slug: "game-gamepot3-purchase" updated: 2026-10-08T02:15:44Z published: 2026-10-08T02:15:44Z canonical: "guide.ncloud-docs.com/game-gamepot3-purchase" --- > ## Documentation Index > Fetch the complete documentation index at: https://guide.ncloud-docs.com/llms.txt > Use this file to discover all available pages before exploring further. # Payment Available in Classic and VPC ## Payment You can sell in-game items using the in-app payment feature provided by the GAMEPOT SDK. Before checking out, you need to set [Configuration by store](/docs/en/game-gamepot3-google-play-store) to match the applicable store. Also, if the item has not been added to **Dashboard** > **Payment** > **In-app**, an error "ProductID not found" will occur. ### Android This guide describes how to retrieve product information, request payments, and recover unprocessed payments on Android. #### (AOS) Import in-app information When checking out, you need to display payment information and local currency information on the page. You can use the functions below to get the current payment currency, name, etc. If the import fails, check your console settings. Kotlin: ``` import com.nbase.sdk.Store NBase.getProductItems() {products, e -> if (e != null) { Log.e("NBase", e.message) } else { // In-app item information Log.e("NBase", products) } } ``` Java: ``` NBase nBase = NBase.INSTANCE; nBase.getProductItems((products, e) -> { if (e != null) { Log.e("NBase", "getProductItems fail: " + e.getMessage()); } else { if (products != null) { Log.e("NBase", "getProductItems success: " + products.toString()); } } return null; }); ``` The following table describes the values passed to the product information retrieval callback. - **Callback** | Key | Type | Description | | --- | --- | --- | | id | String | productId | | productName | String | Product name | | title | String | Product title | | price | Float | Product price | | localizedPrice | Float | Localized price | | productId | String | Unique ID of the product | | productType | String | Product type | | productDescription | String | Product description | | currency | String | Currency unit | #### (AOS) Request payment You can request a payment using the productId from the imported in-app information. Kotlin: ``` import com.nbase.sdk.Store NBase.purchase (activity, Store.GOOGLE, productId, metadata, options) { purchase, e -> if (e != null) { Log.e("NBase", e.message) } else { Log.e("NBase", purchase) } } ``` Java: ``` import com.nbase.sdk.Store; NBase nBase = NBase.INSTANCE; nBase.purchase (activity, storeId, productId, metadata, options, (purchase, e) -> { if (e != null) { Log.e("NBase", "purchase fail: " + e.getMessage()); } else { if (purchase != null) { Log.e("NBase", "purchase success: " + purchase.toString()); } } return null; }); ``` The following table describes the parameters passed when making a payment request. - **Parameter** | Key | Type | Description | Required | | --- | --- | --- | --- | | activity | Activity | Current activity | O | | storeId | Store | Store ID (See the following table) | O | | productId | String | productId (dashboard → payment → in-app item) | O | | Metadata | String | Metadata | X | | options | String | Payment options feature | X | The following table describes the store values that can be passed to `storeId`. | Key | Description | | --- | --- | | Store.GOOGLE | Google Play Store | | Store.ONE | ONE Store | | Store.GALAXY | Galaxy Store | | Store.AMAZON | Amazon Store | | Store.HUAWEI | Huawei Store | The following table describes the values passed to the payment request callback. - **Callback** | Key | Type | Description | | --- | --- | --- | | id | String | ID | | orderId | String | Order ID | | storeId | String | Store ID | | productId | String | Product ID | | billingKey | String | Payment key | | signature | String | Signature | | originalJson | String | Source JSON | | developerPayload | String | Developer payload | | packageName | String | Package name | | isAcknowledged | bool | Confirmation status | | purchaseState | String | Purchase status | | purchaseTime | String | Purchase time | | quantity | String | Quantity | | recurringState | String | Recurring payment status | | currency | String | Currency | | country | String | Country | | paymentId | String | Payment ID | | price | Float | Pricing | | iapVersion | String | In-app payment version | | playerId | String | Player ID | | serverId | String | Server ID | | level | Int | Level | | userdata | String | User data | | Metadata | String | Metadata | | options | String | Options | | authCode | String | Authentication code | #### (AOS) Recover unprocessed payment It restores purchases that were completed but whose results were not delivered to the game. When you request restoration using `restorePurchase`, the restored purchase information is delivered one entry at a time to the listener registered via `setPurchaseRestoreListener`. Note It is available in nbasesdk 3.0.98 or later. - **Register recovery listener** Since the SDK begins the restore process immediately after login is complete, register the listener once before calling the login method. Recovery results automatically performed by the SDK during login and when returning to the app are also delivered to the same listener, and a successful transaction for the same purchase is delivered only once. Kotlin: ``` NBase.setPurchaseRestoreListener { purchase, e -> if (e != null) { // Recovery failure Log.e("NBase", "restore Failed: ${e.message}") } else { // Recovery success: Grant items using orderId and productId. Log.d("NBase", "restore Success: ${purchase?.get("orderId")} / ${purchase?.get("productId")}") } } ``` Java: ``` NBase nBase = NBase.INSTANCE; nBase.setPurchaseRestoreListener((purchase, e) -> { if (e != null) { // Recovery failure Log.e("NBase", "restore Failed: " + e.getMessage()); } else if (purchase != null) { // Recovery success: Grant items using orderId and productId. Log.d("NBase", "restore Success: " + purchase.get("orderId") + " / " + purchase.get("productId")); } return null; }); ``` This section describes the values passed to the recovery listener callback. - **Callback** | Key | Type | Description | | --- | --- | --- | | purchase | Map? | Restored payment information. Passed with the same key as the [Request payment](/docs/en/game-gamepot3-purchase#AOS%EA%B2%B0%EC%A0%9C%EC%9A%94%EC%B2%AD) callback. | | e | CoreException? | Error information when recovery fails. `null` upon success. | - **Request recovery** Call after initialization and login. Kotlin: ``` NBase.restorePurchase(activity) { success, e -> if (e != null) { Log.e("NBase", "restorePurchase Failed: ${e.message}") } else { Log.d("NBase", "restorePurchase Success") } } ``` Java: ``` NBase nBase = NBase.INSTANCE; nBase.restorePurchase(activity, (success, e) -> { if (e != null) { Log.e("NBase", "restorePurchase Failed: " + e.getMessage()); } else { Log.d("NBase", "restorePurchase Success"); } return null; }); ``` The following table describes the parameters passed when making a recovery request. - **Parameter** | Key | Type | Description | Required | | --- | --- | --- | --- | | activity | Activity | Current activity | O | | storeId | Store | Store for recovery. The store specified in the initialization settings if omitted. | X | The following table describes the values passed to the recovery request callback. - **Callback** | Key | Type | Description | | --- | --- | --- | | success | Boolean | Whether to initiate a recovery request. Recovered payment information is passed to the listener. | | e | CoreException? | Error information when request fails. `null` upon success. | - **Remove recovery listener** Remove a registered listener. Kotlin: ``` NBase.setPurchaseRestoreListener(null) ``` Java: ``` NBase.INSTANCE.setPurchaseRestoreListener(null); ``` ### iOS This section describes how to view product information and request payment on iOS. #### (iOS) Import in-app information When checking out, you need to display payment information and local currency information on the page. You can use the functions below to get the current payment currency, name, etc. If the import fails, check your console settings. Swift: ``` let products = NBase.getProductItems() ``` Objective-C: ``` [NBaseBridge.shared getProductItems:^(NSString * _Nullable result) { NSLog(@"getProductItems result: %@", result); }]; ``` The following table describes the values passed to the product information retrieval callback. - **Callback** | Key | Type | Description | | --- | --- | --- | | id | String | productId | | productId | String | Unique ID of the product | | productName | String | Product name | | productType | String | Product type | | currency | String | Currency | | price | Float64 | Product price | | localizedPrice | String | Localized price | | productDescription | String | Product description | #### (iOS) Request payment You can request a payment using the productId from the imported in-app information. Swift: ``` NBase.purchase (productId: productId, metadata: metadata, options: options) { result in switch result { case .success(let data): NBase.showToast(message: data?.encodeToJson() ?? "") case .failure(let error): NBase.showToast(message: error.errorDescription ?? "") } } ``` Objective-C: ``` [NBaseBridge.shared purchase:productId metadata:metadata options:options :^(NSDictionary * _Nullable result, NSError * _Nullable error) { if (error) { NSLog(@"purchase Error: %@", error.localizedDescription); } else { NSLog(@"purchase succeeded with result: %@", result); } }]; ``` The following table describes the parameters passed when making a payment request. - **Parameter** | Key | Type | Description | Required | | --- | --- | --- | --- | | productId | String | Product ID (Dashboard > Payment > In-app item) | O | | Metadata | String | Metadata | X | | options | String | Payment options feature | X | The following table describes the values passed to the payment request callback. - **Callback** | Key | Type | Description | | --- | --- | --- | | orderId | String | Order ID | | receipt | String | Receipt | | signature | String | Signature | | productId | String | Product ID | | storeId | String | Store ID | | country | String | Country | | quantity | Int | Quantity | | paymentId | String | Payment ID | | currency | String | Currency | | serverId | String | Server ID | | playerId | String | Player ID | | userdata | String | User data | | Metadata | String | Metadata | | options | String | Payment options | | authCode | String | Authentication code | | level | Int | Level | | price | Float64 | Pricing | ### Unity This section describes how to retrieve product information, request payment, and recover unprocessed Android payments in Unity. #### (Unity) Import in-app information When checking out, you need to display payment information and local currency information on the page. You can use the functions below to get the current payment currency, name, etc. If the import fails, check your console settings. ``` NBaseSDK.NBase.getProductItems((products, error) => { if (products != null && products.Count > 0) { // Go through the list of products. foreach (var product in products) { // It shows the information of each product as a toast message. // In the example, product.ToString() is called, // but in reality, you can display the specific properties (e.g., name, price, etc.). NBaseSDK.NBase.showToast(product.ToString()); } } else { // If the product list is empty, the user will be notified. NBaseSDK.NBase.showToast("The product list is empty."); } }); ``` The following table describes the values passed to the product information retrieval callback. - **Callback** | Key | Type | Description | | --- | --- | --- | | Products[].id | string | productId | | Products[].title | string | Product title | | Products[].productId | string | Unique ID of the product | | Products[].productType | string | Product type | | Products[].productName | string | Product name | | Products[].productDescription | string | Product description | | Products[].currency | string | Currency unit | | Products[].price | float | Product price | #### (Unity) Request payment You can request payment by productId in the imported in-app information. ``` NBaseSDK.NBase.purchase (Store.google.ToString(), productId, metadata, options, (purchase, error) => { if (error != null) { Debug.Log(error.Message.ToString()); return; } // Payment succeeded. }); ``` The following table describes the parameters passed when making a payment request. - **Parameter** | Key | Type | Description | Required | | --- | --- | --- | --- | | storeId | string | Store ID (See the following table) | O | | productId | string | productId (dashboard → payment → in-app item) | O | | Metadata | string | Metadata | X | | options | string | Payment options feature | X | The following table describes the store values that can be passed to `storeId`. | Key | Description | | --- | --- | | Store.google.ToString() | Google Play Store | | Store.one.ToString() | ONE Store | | Store.galaxy.ToString() | Galaxy Store | | Store.amazon.ToString() | Amazon Store | | Store.huawei.ToString() | Huawei Store | The following table describes the values passed to the payment request callback. - **Callback** | Key | Type | Description | | --- | --- | --- | | storeId | string | Store's unique ID | | paymentId | string | Payment ID | | iapVersion | string | In-app payment version | | productId | string | productId | | billingKey | string | Billing key | | signature | string | Signature | | originalJson | string | Source JSON | | orderId | string | Order ID | | developerPayload | string | Developer payload | | packageName | string | Package name | | isAcknowledged | bool | Confirmation status | | purchaseState | int | Purchase status | | purchaseTime | long | Purchase time | | price | float | Pricing | | quantity | int | Quantity | | currency | string | Currency unit | #### (Unity) Recover unprocessed payment It restores purchases that were completed but whose results were not delivered to the game. When you request restoration using `restorePurchase`, the restored purchase information is delivered one entry at a time to the listener registered via `setPurchaseRestoreListener`. Note It is available on Android devices running nbasesdk-unity-plugin 3.0.18 or later. - **Register recovery listener** Since the SDK begins the restore process immediately after login is complete, register the listener once before calling the login method. Recovery results automatically performed by the SDK during login and when returning to the app are also delivered to the same listener, and a successful transaction for the same purchase is delivered only once. ``` NBaseSDK.NBase.setPurchaseRestoreListener((purchase, error) => { if (error != null) { // Recovery failure Debug.Log("restore Failed: " + error.Message); return; } // Recovery success: Grant items using orderId and productId. Debug.Log("restore Success: " + purchase.orderId + " / " + purchase.productId); }); ``` This section describes the values passed to the recovery listener callback. - **Callback** | Key | Type | Description | | --- | --- | --- | | purchase | Purchase | Restored payment information. Same format as the callback of [Request payment](/docs/en/game-gamepot3-purchase#Unity%EA%B2%B0%EC%A0%9C%EC%9A%94%EC%B2%AD). | | error | Error | Error information when recovery fails. `null` upon success. | - **Request recovery** Call after initialization and login. ``` NBaseSDK.NBase.restorePurchase((success, error) => { if (error != null) { Debug.Log("restorePurchase Failed: " + error.Message); return; } Debug.Log("restorePurchase Success"); }); ``` The following table describes the values passed to the recovery request callback. - **Callback** | Key | Type | Description | | --- | --- | --- | | success | bool | Whether to initiate a recovery request. Restored payment information is sent to the listener. | | error | Error | Error information when request fails. `null` upon success. | - **Remove recovery listener** Remove a registered listener. ``` NBaseSDK.NBase.removePurchaseRestoreListener(); ``` ## Troubleshooting This section describes common errors that occur when trying to integrate payments and what to check. **Q. A ProductID not found error occurs.** A. Check if the applicable product ID is registered in **Dashboard** > **Payment** > **In-app**. **Q. The payment is not going through.** A. See [Configuration by store](/docs/en/game-gamepot3-google-play-store) and check if the settings applicable for the store have been completed. **Q. (Android) java.lang.NoClassDefFoundError: Failed resolution of: Lcom/android/billingclient/api/BillingClient;** A. Add the following code. ``` ``` **Q. (iOS) In-app information cannot be retrieved.** A. Make sure that the in-app product information and app environment (Production/Sandbox) are the same as those registered in Apple Connect.