2단계. 상품 목록 조회
상품명, 가격, 통화 등 Apple App Store에 등록된 인앱 상품 정보를 실시간으로 조회합니다. 조회한 정보를 사용자에게 표시할 때 사용하세요.
아래 과정을 따라 상품 정보를 조회합니다.
1. 상품 ID 목록 조회
Hive Axyl 서버에 등록된 상품 ID 목록을 조회합니다. 이 목록은 Hive 콘솔에서 등록한 상품의 고유 식별값(Product ID)을 포함합니다.
ListStoreProductIdsAsync
Product ID 목록 조회를 구현하려면 Hive Axyl SDK가 제공하는 ListStoreProductIdsAsync()를 호출하세요. 앱에서 판매 중인 인앱 상품의 고유 식별자(Product ID) 목록을 마켓별로 반환합니다.
호출 파라미터
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
| request | StoreRequest | Required | 조회할 마켓과 앱 정보를 담은 요청 데이터입니다. |
| context | ApiCallContext | Optional | 호출 단위 설정 객체입니다. 멱등키·취소 토큰·요청 정책을 지정하며, 생략하면 기본값이 사용됩니다. |
StoreRequest
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
AppVersion | string | Optional | 앱의 현재 빌드 버전을 문자열로 전달합니다. 예: 1.0.0 |
Country | string | Required | 사용자의 국가 코드(ISO 3166-1 두 자리)를 전달합니다. 상품 필터링에 사용됩니다. 예: KR |
Language | string | Required | 상품 이름 등 현지화에 사용할 언어 코드(ISO 639-1 두 자리)를 전달합니다. 예: ko |
ProviderId | StoreRequestProviderId (enum) | Required | 마켓 식별자입니다. Apple App Store 상품 조회 전용 요청이므로 Apple만 지정합니다. |
호출 예시
PaymentsListStoreProductIdsResult의 성공 결과와 이 메서드에서 정의한 도메인별 결과(Outcome)는 아래 예시와 응답 상태에서 확인합니다. 요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요.
using Hive.Axyl.Payments;
using Hive.Axyl.Core;
// payments: 초기화 시 등록된 IPaymentsService (자세한 획득은 [모듈 설치 및 초기화](../init.md) 참고)
IPaymentsService payments = HiveCore.Resolve<IPaymentsService>();
// 조회할 마켓과 앱 정보를 담은 요청 객체를 생성합니다.
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:
// 마켓별 Product ID 목록을 확인합니다.
foreach (var store in success.Data.Stores)
{
Debug.Log($"{store.ProviderId}: 소모성 {store.Products.Count}개, 구독 {store.ProductSubscriptions.Count}개");
}
break;
case PaymentsListStoreProductIdsResult.PaymentBadRequest:
case PaymentsListStoreProductIdsResult.PaymentInvalidParameter:
Debug.LogError("요청 필드와 필수값을 확인하세요.");
break;
// 공통 Failure 처리
case PaymentsListStoreProductIdsResult.Failure failure:
HiveError err = failure.Problem;
Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
break;
// 안전망: 처리하지 않은 결과 및 알 수 없는 신규 결과(UnknownOutcome)
default:
Debug.LogWarning($"처리되지 않은 결과: {result.GetType().Name}");
break;
}
응답 데이터
성공 시 PaymentsListStoreProductIdsResult.Success의 Data(StoreResponseData)에 결과가 담깁니다.
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Data.Stores | IReadOnlyList<StoreProduct> | Required | 마켓별 상품 ID 정보 목록입니다. 조회 결과가 없으면 빈 목록입니다. |
Data.Meta | string | Optional | 응답 메타 정보입니다. 없으면 null입니다. |
StoreProduct
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
AppId | string | Optional | 앱 ID입니다. 예: com.game |
Products | IReadOnlyList<string> | Optional | 소모성 상품의 Product ID 목록입니다. |
ProductSubscriptions | IReadOnlyList<string> | Optional | 구독 상품의 Product ID 목록입니다. |
ProviderId | StoreProductProviderId (enum) | Required | 마켓 식별자입니다. 이 응답에서는 Apple이 반환됩니다. |
응답 예시
// Success 분기에서 success.Data 예시
// 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"]
응답 상태
아래 표에는 PaymentsListStoreProductIdsResult의 성공 결과와 이 메서드에서 정의한 도메인별 결과(Outcome)를 정리했습니다. 요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요.
| 응답 케이스 | 설명 | 앱 클라이언트 대응 |
|---|---|---|
Success | Product ID 목록 조회에 성공했습니다. Data에 마켓별 상품 ID 목록이 담깁니다. | 받은 Product ID로 스토어 상품 정보 조회 진행 |
PaymentBadRequest | 요청을 처리할 수 없습니다. | 요청 값과 호출 조건을 점검 |
PaymentInvalidParameter | 유효하지 않은 파라미터입니다. | 요청 필드를 점검 후 재요청 |
UnknownOutcome | SDK가 알 수 없는 도메인별 결과입니다. | 실패로 처리하고 결과 코드를 기록 |
Failure | 공통 Failure입니다. 공통 오류 처리를 참조하세요. | 공통 오류 처리 기준에 따라 처리 |
2. Apple App Store 상품 정보 조회 (플러그인)
상품 ID 목록을 사용하여 Apple 결제 플러그인(IAppleStoreKitPlugin)의 GetProductsAsync()를 호출합니다. Apple App Store에서 상품명, 가격, 통화 등 네이티브 상품 정보를 직접 조회합니다.
GetProductsAsync
호출 파라미터
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
| request | GetProductsRequest | Required | 상품 조회 요청 데이터 객체입니다. |
| ct | CancellationToken | Optional | 취소 토큰입니다. |
GetProductsRequest
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
ProductIds | IReadOnlyList<string> | Required | 조회할 상품 ID 목록입니다. ListStoreProductIdsAsync()에서 받은 Product ID를 전달합니다. |
호출 예시
AppleStoreKitServiceGetProductsResult의 성공 결과와 이 메서드에서 정의한 도메인별 결과(Outcome)는 아래 예시와 응답 상태에서 확인합니다. 요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요.
using Hive.Axyl.Core;
using Hive.Axyl.Payments.Addon.Apple;
using System.Threading;
// Apple StoreKit 플러그인 획득
if (!HiveCore.TryResolve<IAppleStoreKitPlugin>(out var applePlugin))
{
Debug.LogError("Apple StoreKit 플러그인이 등록되지 않았습니다.");
return;
}
// 1단계에서 받은 Product ID 목록으로 요청 생성
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("알 수 없는 결과입니다.");
break;
case AppleStoreKitServiceGetProductsResult.Failure failure:
Debug.LogError($"상품 조회 실패: {failure}");
break;
default:
Debug.LogWarning($"처리되지 않은 결과: {result.GetType().Name}");
break;
}
응답 데이터
성공 시 AppleStoreKitServiceGetProductsResult.Success의 Data(GetProductsResponse)에 결과가 담깁니다.
| 필드명 | 타입 | 설명 |
|---|---|---|
Data.Products | IReadOnlyList<AppleProduct> | Apple App Store에서 조회한 상품 정보 목록입니다. |
AppleProduct
| 필드명 | 타입 | 설명 |
|---|---|---|
Id | string | 상품의 고유 식별자(Product ID)입니다. |
DisplayName | string | 사용자 로캘에 맞게 현지화된 상품 이름입니다. |
Description | string | 사용자 로캘에 맞게 현지화된 상품 설명입니다. |
DisplayPrice | string | 현지화된 가격 표시 문자열입니다. (예: ₩1,200) |
Price | decimal | 숫자형 가격 값입니다. |
PriceLocale | string | 가격 로캘 식별자입니다. 3단계 요청의 PriceLocale에 그대로 전달합니다. (예: ko_KR@currency=KRW) |
ProductType | AppleProductType | 상품 유형입니다. 멤버는 Consumable, NonConsumable, AutoRenewable, NonRenewable입니다. |
Subscription | SubscriptionInfo? | 구독 상품인 경우 구독 정보입니다. 비구독 상품은 null입니다. |
응답 상태
반환 객체 AppleStoreKitServiceGetProductsResult는 아래 케이스 중 하나로 분기됩니다.
| 응답 케이스 | 설명 | 앱 클라이언트 대응 |
|---|---|---|
Success | 상품 조회 성공. Data.Products에 상품 정보가 담깁니다. | 조회한 상품 정보를 다음 단계(FetchAppleProductsAsync) 요청에 매핑 |
UnknownOutcome | 알 수 없는 결과 | 재시도 또는 오류 안내 |
Failure | 공통 Failure입니다. 공통 오류 처리를 참조하세요. | 공통 오류 처리 기준에 따라 처리 |
3. 상품 상세 정보 조회
상품 ID 목록을 바탕으로 상품명, 현지화된 가격, 통화, 상품 설명 등 Apple App Store에 등록된 상품의 상세 정보를 조회합니다. 조회한 정보를 사용자에게 표시할 때 사용하세요.
FetchAppleProductsAsync
Apple App Store 상품 목록 조회를 구현하려면 Hive Axyl SDK가 제공하는 FetchAppleProductsAsync()를 호출하세요. 스토어(Apple App Store)에서 조회한 상품 정보를 전달하면, 서비스 표준 형식(Single Standard)으로 정제된 상품 목록을 반환합니다.
호출 파라미터
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
| request | ProductApple | Required | App Store에서 조회한 상품 정보를 담은 요청 데이터입니다. |
| context | ApiCallContext | Optional | 호출 단위 설정 객체입니다. 멱등키·취소 토큰·요청 정책을 지정하며, 생략하면 기본값이 사용됩니다. |
ProductApple
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
AppVersion | string | Optional | 앱의 현재 빌드 버전을 문자열로 전달합니다. 예: 1.0.0 |
Country | string | Required | 사용자의 국가 코드(ISO 3166-1 두 자리)를 전달합니다. 예: KR |
Currency | string | Required | 결제 통화(ISO 4217 세 자리)를 전달합니다. 예: KRW |
Language | string | Required | 현지화에 사용할 언어 코드(ISO 639-1 두 자리)를 전달합니다. 예: ko |
ProductType | string | Required | 상품 유형입니다. subscription(구독), consumable(소모성) |
Products | IReadOnlyList<ProductAppleProducts> | Required | 스토어에서 조회한 상품 정보 목록입니다. 1개 이상 담아야 합니다. |
ProviderId | ProductAppleProviderId (enum) | Required | 마켓 식별자입니다. Apple App Store 전용 요청이므로 Apple만 지정합니다. |
ProductAppleProducts
Apple 결제 플러그인(IAppleStoreKitPlugin)의 GetProductsAsync()를 먼저 호출하여 Apple App Store에서 네이티브 상품 정보(AppleProduct)를 조회한 뒤, 그 결과를 아래 필드에 매핑하여 FetchAppleProductsAsync() 요청에 담습니다. StoreKit 2 원본 속성은 PascalCase이지만 SDK는 아래 C# 속성을 camelCase JSON 키(id, displayName, description, displayPrice, price, priceLocale, productType)로 직렬화합니다. 값은 변환하지 말고 그대로 전달하세요.
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Description | string | Optional | 상품의 상세 설명입니다. |
DisplayName | string | Optional | 상품명입니다. |
DisplayPrice | string | Optional | 통화 기호를 포함한 표시 가격입니다. |
Id | string | Required | 상품의 고유 식별자(PID)입니다. 비어 있으면 요청이 거부됩니다. 예: com.game.product1 |
Price | decimal | Optional | 원본 가격입니다. 소수점을 쓰는 통화를 포함해 조회한 값을 그대로 전달합니다. 예: 4.99 |
PriceLocale | string | Optional | 원본 가격 로캘입니다. 서버가 이 값에서 통화와 국가를 추출합니다. 예: ko_KR@currency=KRW |
ProductType | int | Optional | StoreKit 상품 유형 코드입니다. 0: 미지정, 1: 소모성, 2: 비소모성, 3: 자동 갱신 구독, 4: 비갱신 구독입니다. |
호출 예시
PaymentsFetchAppleProductsResult의 성공 결과와 이 메서드에서 정의한 도메인별 결과(Outcome)는 아래 예시와 응답 상태에서 확인합니다. 요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요.
using System.Collections.Generic;
using Hive.Axyl.Payments;
using Hive.Axyl.Core;
// payments: 초기화 시 등록된 IPaymentsService (자세한 획득은 [모듈 설치 및 초기화](../init.md) 참고)
IPaymentsService payments = HiveCore.Resolve<IPaymentsService>();
// App Store에서 조회한 상품 정보를 요청에 담습니다.
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:
// 표준 형식으로 정제된 상품 목록으로 상점 화면을 구성합니다.
foreach (var product in success.Data.Products)
{
Debug.Log($"{product.ProductId}: {product.Title} ({product.DisplayPrice})");
}
break;
// 요청 검증 실패 결과(Outcome) 처리
case PaymentsFetchAppleProductsResult.PaymentBadRequest:
case PaymentsFetchAppleProductsResult.PaymentInvalidParameter:
// 요청 필드와 필수값을 점검하세요.
break;
// 공통 Failure 처리
case PaymentsFetchAppleProductsResult.Failure failure:
HiveError err = failure.Problem;
Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
break;
// 안전망: 처리하지 않은 결과 및 알 수 없는 신규 결과(UnknownOutcome)
default:
Debug.LogWarning($"처리되지 않은 결과: {result.GetType().Name}");
break;
}
응답 데이터
성공 시 PaymentsFetchAppleProductsResult.Success의 Data(ProductResponseData)에 결과가 담깁니다.
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Data.AppVersion | string | Optional | 앱 버전입니다. |
Data.Country | string | Optional | 국가 정보입니다. |
Data.Currency | string | Optional | 통화입니다. |
Data.Language | string | Required | 언어입니다. |
Data.Products | IReadOnlyList<ProductProducts> | Optional | 표준 형식으로 정제된 상품 정보 목록입니다. |
Data.ProviderId | ProductProviderId (enum) | Required | 마켓 식별자입니다. 이 응답에서는 Apple이 반환됩니다. |
Data.Meta | string | Optional | 응답 메타 정보입니다. 없으면 null입니다. |
ProductProducts
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Currency | string | Optional | 통화입니다. 예: KRW |
Description | string | Optional | 상품 설명입니다. |
DisplayOriginalPrice | string | Optional | 화면 표시용 할인 전 가격입니다. 예: ₩1,100 |
DisplayPrice | string | Optional | 화면 표시용 가격입니다. 예: 1,200 KRW |
Offers | IReadOnlyList<ProductOffer> | Optional | 일회성 또는 구독 오퍼 목록입니다. 오퍼가 없으면 null입니다. |
OriginalPrice | decimal | Optional | 할인 전 가격입니다. 예: 1100 또는 11.00 |
Price | decimal | Optional | 가격입니다. 예: 1200 또는 9.99 |
ProductId | string | Optional | 상품의 고유 식별자(PID)입니다. |
ProductType | string | Optional | 상품 유형입니다. subscription(구독), consumable(소모성) |
Title | string | Optional | 상품 제목입니다. 예: 1000 Gold |
ProductOffer
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
BasePlanId | string | Optional | 구독 상품의 기본 요금제 ID입니다. 일회성 구매 오퍼에서는 null입니다. |
Currency | string | Optional | 통화 코드입니다. ISO 4217 세 자리 형식을 사용합니다. |
DisplayPrice | string | Optional | 화면에 표시할 가격입니다. |
OfferToken | string | Optional | 오퍼 토큰입니다. 요청에 보낸 값이 그대로 반환됩니다. |
Price | decimal | Optional | 통화 단위의 가격입니다. |
응답 예시
// Success 분기에서 success.Data 예시
// 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"
응답 상태
아래 표에는 PaymentsFetchAppleProductsResult의 성공 결과와 이 메서드에서 정의한 도메인별 결과(Outcome)를 정리했습니다. 요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요.
| 응답 케이스 | 설명 | 앱 클라이언트 대응 |
|---|---|---|
Success | 상품 목록 조회에 성공했습니다. Data에 표준 형식 상품 목록이 담깁니다. | 상품 목록으로 상점 화면 구성 |
PaymentBadRequest | 요청을 처리할 수 없습니다. | 요청 값과 호출 조건을 점검 |
PaymentInvalidParameter | 유효하지 않은 파라미터입니다. | 요청 필드 값을 점검 후 재요청 |
UnknownOutcome | SDK가 알 수 없는 도메인별 결과입니다. | 실패로 처리하고 결과 코드를 기록 |
Failure | 공통 Failure입니다. 공통 오류 처리를 참조하세요. | 공통 오류 처리 기준에 따라 처리 |
다음 단계
상품을 구매합니다.