Step 2. Get the product list
Retrieve in real time the in-app product information registered in the Apple App Store, such as product names, prices, and currencies. Use it when you display the retrieved information to users.
Follow the process below to retrieve product information.
1. Get the product ID list
Retrieve the list of product IDs registered on the Hive Axyl server. This list contains the unique identifiers (Product IDs) of the products you registered in the Hive Console.
ListStoreProductIdsAsync
To implement Product ID list retrieval, call ListStoreProductIdsAsync() provided by the Hive Axyl SDK. It returns, by market, the list of unique identifiers (Product IDs) of the in-app products that the app sells.
Call parameters
| Field name | Type | Required | Description |
|---|---|---|---|
| request | StoreRequest | Required | Request data that contains the market to query and the app information. |
| context | ApiCallContext | Optional | Per-call settings object that specifies the idempotency key, cancellation token, and request policy. If omitted, the default values are used. |
StoreRequest
| Field name | Type | Required | Description |
|---|---|---|---|
AppVersion | string | Optional | Pass the app's current build version as a string. Example: 1.0.0 |
Country | string | Required | Pass the user's country code (two-letter ISO 3166-1 code). Used for product filtering. Example: KR |
Language | string | Required | Pass the language code (two-letter ISO 639-1 code) to use for localization, such as product names. Example: ko |
ProviderId | StoreRequestProviderId (enum) | Required | Market identifier. Because this request is only for retrieving Apple App Store products, specify only Apple. |
Call example
Check the success result of PaymentsListStoreProductIdsResult and the domain-specific results (Outcome) defined by this method in the example below and in the response status. For the result model and handling principles of common failures (Failure) that prevent the request from being performed, see Common error handling.
using Hive.Axyl.Payments;
using Hive.Axyl.Core;
// payments: IPaymentsService registered during initialization (for how to retrieve it, see [Install and initialize the module](../init.md))
IPaymentsService payments = HiveCore.Resolve<IPaymentsService>();
// Create a request object that contains the market to query and the app information.
var request = new StoreRequest
{
AppVersion = "1.0.0",
Country = "KR",
Language = "ko",
ProviderId = StoreRequestProviderId.Apple
};
PaymentsListStoreProductIdsResult result = await payments.ListStoreProductIdsAsync(request);
switch (result)
{
case PaymentsListStoreProductIdsResult.Success success:
// Check the Product ID list for each market.
foreach (var store in success.Data.Stores)
{
Debug.Log($"{store.ProviderId}: {store.Products.Count} consumable(s), {store.ProductSubscriptions.Count} subscription(s)");
}
break;
case PaymentsListStoreProductIdsResult.PaymentBadRequest:
case PaymentsListStoreProductIdsResult.PaymentInvalidParameter:
Debug.LogError("Check the request fields and required values.");
break;
// Handle common Failure
case PaymentsListStoreProductIdsResult.Failure failure:
HiveError err = failure.Problem;
Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
break;
// Safety net: unhandled results and unknown new results (UnknownOutcome)
default:
Debug.LogWarning($"Unhandled result: {result.GetType().Name}");
break;
}
Response data
On success, the result is contained in Data (StoreResponseData) of PaymentsListStoreProductIdsResult.Success.
| Field name | Type | Required | Description |
|---|---|---|---|
Data.Stores | IReadOnlyList<StoreProduct> | Required | List of product ID information by market. If there are no results, this is an empty list. |
Data.Meta | string | Optional | Response meta information. null if there is none. |
StoreProduct
| Field name | Type | Required | Description |
|---|---|---|---|
AppId | string | Optional | App ID. Example: com.game |
Products | IReadOnlyList<string> | Optional | List of Product IDs of consumable products. |
ProductSubscriptions | IReadOnlyList<string> | Optional | List of Product IDs of subscription products. |
ProviderId | StoreProductProviderId (enum) | Required | Market identifier. This response returns Apple. |
Response example
// Example of success.Data in the Success branch
// success.Data.Stores[0].ProviderId = StoreProductProviderId.Apple
// success.Data.Stores[0].AppId = "com.game"
// success.Data.Stores[0].Products = ["com.game.product1", "com.game.product2"]
// success.Data.Stores[0].ProductSubscriptions = ["com.game.subscription1", "com.game.subscription2"]
Response status
The following table summarizes the success result of PaymentsListStoreProductIdsResult and the domain-specific results (Outcome) defined by this method. For the result model and handling principles of common failures (Failure) that prevent the request from being performed, see Common error handling.
| Response case | Description | App client handling |
|---|---|---|
Success | The Product ID list was retrieved successfully. Data contains the product ID list for each market. | Proceed to retrieve store product information with the received Product IDs |
PaymentBadRequest | The request cannot be processed. | Check the request values and call conditions |
PaymentInvalidParameter | The parameters are invalid. | Check the request fields and send the request again |
UnknownOutcome | A domain-specific result that the SDK does not recognize. | Treat it as a failure and log the result code |
Failure | Common Failure. See Common error handling. | Handle it according to the common error handling guidelines |
2. Get Apple App Store product information (plugin)
Use the product ID list to call GetProductsAsync() of the Apple payment plugin (IAppleStoreKitPlugin). It retrieves native product information, such as product names, prices, and currencies, directly from the Apple App Store.
GetProductsAsync
Call parameters
| Field name | Type | Required | Description |
|---|---|---|---|
| request | GetProductsRequest | Required | Product retrieval request data object. |
| ct | CancellationToken | Optional | Cancellation token. |
GetProductsRequest
| Field name | Type | Required | Description |
|---|---|---|---|
ProductIds | IReadOnlyList<string> | Required | List of product IDs to retrieve. Pass the Product IDs you received from ListStoreProductIdsAsync(). |
Call example
Check the success result of AppleStoreKitServiceGetProductsResult and the domain-specific results (Outcome) defined by this method in the example below and in the response status. For the result model and handling principles of common failures (Failure) that prevent the request from being performed, see Common error handling.
using Hive.Axyl.Core;
using Hive.Axyl.Payments.Addon.Apple;
using System.Threading;
// Retrieve the Apple StoreKit plugin
if (!HiveCore.TryResolve<IAppleStoreKitPlugin>(out var applePlugin))
{
Debug.LogError("The Apple StoreKit plugin is not registered.");
return;
}
// Create a request with the Product ID list received in step 1
var request = new GetProductsRequest
{
ProductIds = new[] { "com.game.product1", "com.game.product2" }
};
AppleStoreKitServiceGetProductsResult result =
await applePlugin.GetProductsAsync(request, CancellationToken.None);
switch (result)
{
case AppleStoreKitServiceGetProductsResult.Success success:
foreach (AppleProduct product in success.Data.Products)
{
Debug.Log($"{product.Id}: {product.DisplayName} — {product.DisplayPrice}");
}
break;
case AppleStoreKitServiceGetProductsResult.UnknownOutcome:
Debug.LogWarning("Unknown result.");
break;
case AppleStoreKitServiceGetProductsResult.Failure failure:
Debug.LogError($"Failed to get products: {failure}");
break;
default:
Debug.LogWarning($"Unhandled result: {result.GetType().Name}");
break;
}
Response data
On success, the result is contained in Data (GetProductsResponse) of AppleStoreKitServiceGetProductsResult.Success.
| Field name | Type | Description |
|---|---|---|
Data.Products | IReadOnlyList<AppleProduct> | List of product information retrieved from the Apple App Store. |
AppleProduct
| Field name | Type | Description |
|---|---|---|
Id | string | Unique identifier of the product (Product ID). |
DisplayName | string | Product name localized for the user's locale. |
Description | string | Product description localized for the user's locale. |
DisplayPrice | string | Localized price display string. (Example: ₩1,200) |
Price | decimal | Numeric price value. |
PriceLocale | string | Price locale identifier. Pass it as is to PriceLocale in the step 3 request. (Example: ko_KR@currency=KRW) |
ProductType | AppleProductType | Product type. The members are Consumable, NonConsumable, AutoRenewable, and NonRenewable. |
Subscription | SubscriptionInfo? | Subscription information for a subscription product. null for non-subscription products. |
Response status
The returned object AppleStoreKitServiceGetProductsResult branches into one of the following cases.
| Response case | Description | App client handling |
|---|---|---|
Success | Product retrieval succeeded. Data.Products contains the product information. | Map the retrieved product information to the request of the next step (FetchAppleProductsAsync) |
UnknownOutcome | Unknown result | Retry or show an error message |
Failure | Common Failure. See Common error handling. | Handle it according to the common error handling guidelines |
3. Get product details
Based on the product ID list, retrieve the details of the products registered in the Apple App Store, such as product names, localized prices, currencies, and product descriptions. Use it when you display the retrieved information to users.
FetchAppleProductsAsync
To implement Apple App Store product list retrieval, call FetchAppleProductsAsync() provided by the Hive Axyl SDK. When you pass the product information retrieved from the store (Apple App Store), it returns a product list refined into the service's standard format (Single Standard).
Call parameters
| Field name | Type | Required | Description |
|---|---|---|---|
| request | ProductApple | Required | Request data that contains the product information retrieved from the App Store. |
| context | ApiCallContext | Optional | Per-call settings object that specifies the idempotency key, cancellation token, and request policy. If omitted, the default values are used. |
ProductApple
| Field name | Type | Required | Description |
|---|---|---|---|
AppVersion | string | Optional | Pass the app's current build version as a string. Example: 1.0.0 |
Country | string | Required | Pass the user's country code (two-letter ISO 3166-1 code). Example: KR |
Currency | string | Required | Pass the payment currency (three-letter ISO 4217 code). Example: KRW |
Language | string | Required | Pass the language code (two-letter ISO 639-1 code) to use for localization. Example: ko |
ProductType | string | Required | Product type. subscription (subscription product), consumable (consumable product) |
Products | IReadOnlyList<ProductAppleProducts> | Required | List of product information retrieved from the store. Must contain at least one item. |
ProviderId | ProductAppleProviderId (enum) | Required | Market identifier. Because this request is only for the Apple App Store, specify only Apple. |
ProductAppleProducts
First call GetProductsAsync() of the Apple payment plugin (IAppleStoreKitPlugin) to retrieve native product information (AppleProduct) from the Apple App Store, and then map the result to the following fields and include them in the FetchAppleProductsAsync() request. The original StoreKit 2 properties are PascalCase, but the SDK serializes the following C# properties to camelCase JSON keys (id, displayName, description, displayPrice, price, priceLocale, productType). Pass the values as is without converting them.
| Field name | Type | Required | Description |
|---|---|---|---|
Description | string | Optional | Detailed description of the product. |
DisplayName | string | Optional | Product name. |
DisplayPrice | string | Optional | Display price including the currency symbol. |
Id | string | Required | Unique identifier of the product (PID). If it is empty, the request is rejected. Example: com.game.product1 |
Price | decimal | Optional | Original price. Pass the retrieved value as is, including for currencies that use decimal places. Example: 4.99 |
PriceLocale | string | Optional | Original price locale. The server extracts the currency and country from this value. Example: ko_KR@currency=KRW |
ProductType | int | Optional | StoreKit product type code. 0: unspecified, 1: consumable, 2: non-consumable, 3: auto-renewable subscription, 4: non-renewing subscription. |
Call example
Check the success result of PaymentsFetchAppleProductsResult and the domain-specific results (Outcome) defined by this method in the example below and in the response status. For the result model and handling principles of common failures (Failure) that prevent the request from being performed, see Common error handling.
using System.Collections.Generic;
using Hive.Axyl.Payments;
using Hive.Axyl.Core;
// payments: IPaymentsService registered during initialization (for how to retrieve it, see [Install and initialize the module](../init.md))
IPaymentsService payments = HiveCore.Resolve<IPaymentsService>();
// Put the product information retrieved from the App Store in the request.
var request = new ProductApple
{
AppVersion = "1.0.0",
Country = "KR",
Currency = "KRW",
Language = "ko",
ProductType = "consumable",
ProviderId = ProductAppleProviderId.Apple,
Products = new List<ProductAppleProducts>
{
new ProductAppleProducts
{
Id = "com.game.product1",
DisplayName = "소모성 상품 27",
Description = "소모성 상품 설명",
DisplayPrice = "₩1,200",
Price = 1200m,
PriceLocale = "ko_KR@currency=KRW",
ProductType = 1
}
}
};
PaymentsFetchAppleProductsResult result = await payments.FetchAppleProductsAsync(request);
switch (result)
{
case PaymentsFetchAppleProductsResult.Success success:
// Build the in-app store screen with the product list refined into the standard format.
foreach (var product in success.Data.Products)
{
Debug.Log($"{product.ProductId}: {product.Title} ({product.DisplayPrice})");
}
break;
// Handle request validation failure results (Outcome)
case PaymentsFetchAppleProductsResult.PaymentBadRequest:
case PaymentsFetchAppleProductsResult.PaymentInvalidParameter:
// Check the request fields and required values.
break;
// Handle common Failure
case PaymentsFetchAppleProductsResult.Failure failure:
HiveError err = failure.Problem;
Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
break;
// Safety net: unhandled results and unknown new results (UnknownOutcome)
default:
Debug.LogWarning($"Unhandled result: {result.GetType().Name}");
break;
}
Response data
On success, the result is contained in Data (ProductResponseData) of PaymentsFetchAppleProductsResult.Success.
| Field name | Type | Required | Description |
|---|---|---|---|
Data.AppVersion | string | Optional | App version. |
Data.Country | string | Optional | Country information. |
Data.Currency | string | Optional | Currency. |
Data.Language | string | Required | Language. |
Data.Products | IReadOnlyList<ProductProducts> | Optional | List of product information refined into the standard format. |
Data.ProviderId | ProductProviderId (enum) | Required | Market identifier. This response returns Apple. |
Data.Meta | string | Optional | Response meta information. null if there is none. |
ProductProducts
| Field name | Type | Required | Description |
|---|---|---|---|
Currency | string | Optional | Currency. Example: KRW |
Description | string | Optional | Product description. |
DisplayOriginalPrice | string | Optional | Pre-discount price for display. Example: ₩1,100 |
DisplayPrice | string | Optional | Price for display. Example: 1,200 KRW |
Offers | IReadOnlyList<ProductOffer> | Optional | List of one-time or subscription offers. null if there are no offers. |
OriginalPrice | decimal | Optional | Pre-discount price. Example: 1100 or 11.00 |
Price | decimal | Optional | Price. Example: 1200 or 9.99 |
ProductId | string | Optional | Unique identifier of the product (PID). |
ProductType | string | Optional | Product type. subscription (subscription product), consumable (consumable product) |
Title | string | Optional | Product title. Example: 1000 Gold |
ProductOffer
| Field name | Type | Required | Description |
|---|---|---|---|
BasePlanId | string | Optional | Base plan ID of the subscription product. null for one-time purchase offers. |
Currency | string | Optional | Currency code. Uses the ISO 4217 three-letter format. |
DisplayPrice | string | Optional | Price to display on the screen. |
OfferToken | string | Optional | Offer token. The value sent in the request is returned as is. |
Price | decimal | Optional | Price in the currency unit. |
Response example
// Example of success.Data in the Success branch
// success.Data.ProviderId = ProductProviderId.Apple
// success.Data.Currency = "KRW"
// success.Data.Products[0].ProductId = "com.game.product1"
// success.Data.Products[0].Title = "소모성 상품 27"
// success.Data.Products[0].Price = 1200
// success.Data.Products[0].DisplayPrice = "1,200 KRW"
// success.Data.Products[0].ProductType = "consumable"
Response status
The following table summarizes the success result of PaymentsFetchAppleProductsResult and the domain-specific results (Outcome) defined by this method. For the result model and handling principles of common failures (Failure) that prevent the request from being performed, see Common error handling.
| Response case | Description | App client handling |
|---|---|---|
Success | The product list was retrieved successfully. Data contains the product list in the standard format. | Build the in-app store screen with the product list |
PaymentBadRequest | The request cannot be processed. | Check the request values and call conditions |
PaymentInvalidParameter | The parameters are invalid. | Check the request field values and send the request again |
UnknownOutcome | A domain-specific result that the SDK does not recognize. | Treat it as a failure and log the result code |
Failure | Common Failure. See Common error handling. | Handle it according to the common error handling guidelines |