2단계. 상품 목록 조회
상품명, 가격, 통화 등 Google Play에 등록된 인앱 상품 정보를 실시간으로 조회합니다. 사용자에게 현재 판매할 수 있는 최신 상품 목록과 정확한 현지 가격을 표시할 때 사용합니다.
아래 과정을 따라 상품 정보를 조회합니다.
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 | 마켓 식별자입니다. Google Play 상품 조회 전용 요청이므로 Google만 지정합니다. |
호출 예시
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.Google
};
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 | 마켓 식별자입니다. 이 응답에서는 Google이 반환됩니다. |
응답 예시
// Success 분기에서 success.Data 예시
// success.Data.Stores[0].ProviderId = StoreProductProviderId.Google
// 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. Google Play 상품 상세 정보 조회 (플러그인)
상품 ID 목록을 바탕으로 Google 결제 플러그인의 QueryProductDetailsAsync()를 호출해 Google Play BillingClient에서 상품 상세 정보를 직접 조회합니다. 조회 결과는 상점 화면을 구성하거나, 이어지는 Hive Axyl 서버 상품 조회(FetchGoogleProductsAsync())의 입력 데이터로 사용합니다.
BillingClient 연결 필수
QueryProductDetailsAsync()를 호출하기 전에 반드시 StartConnectionAsync()로 BillingClient를 연결하세요. 연결 방법은 1단계. 연동 환경 구성을 참조하세요.
QueryProductDetailsAsync
Google Play에 등록된 상품의 상세 정보를 조회하려면 Google 결제 플러그인이 제공하는 QueryProductDetailsAsync()를 호출하세요. 소모성 상품은 ProductType.Inapp, 구독 상품은 ProductType.Subs를 지정합니다.
호출 파라미터
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
| productIds | IReadOnlyList<string> | Required | 조회할 상품 ID 목록입니다. 1단계에서 조회한 Product ID를 전달합니다. |
| productType | ProductType | Required | 상품 유형입니다. Inapp(소모성 상품) 또는 Subs(구독 상품)를 지정합니다. |
| ct | CancellationToken | Optional | 취소 토큰입니다. |
호출 예시
GooglePlayBillingServiceQueryProductDetailsResult의 성공 결과와 이 메서드에서 정의한 도메인별 결과(Outcome)는 아래 예시와 응답 상태에서 확인합니다. 요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요. Google Play Billing Library 9의 부분 실패(partial-failure) 모델을 지원하므로, 조회에 성공한 상품(ProductDetailsList)과 조회하지 못한 상품(UnfetchedProductList)이 함께 반환될 수 있습니다.
using System.Collections.Generic;
using System.Linq;
using Hive.Axyl.Core;
using Hive.Axyl.Payments.Addon.Google;
using System.Threading;
// Google 결제 플러그인 획득 (초기화 시 builder.AddPlayBilling()으로 등록 필요)
if (!HiveCore.TryResolve<IGooglePlayBillingPlugin>(out var googlePlugin))
{
Debug.LogError("Google Play Billing 플러그인이 등록되지 않았습니다.");
return;
}
// 1단계에서 조회한 소모성 상품 ID 목록
var productIds = new List<string> { "com.game.product1", "com.game.product2" };
GooglePlayBillingServiceQueryProductDetailsResult result =
await googlePlugin.QueryProductDetailsAsync(productIds, ProductType.Inapp, CancellationToken.None);
switch (result)
{
case GooglePlayBillingServiceQueryProductDetailsResult.Success success:
// 조회 성공한 상품 목록
foreach (GoogleProductDetails detail in success.Data.ProductDetailsList)
{
Debug.Log($"상품: {detail.ProductId}, 이름: {detail.Name}, 제목: {detail.Title}");
// 소모성 상품의 가격 정보
if (detail.OneTimePurchaseOfferDetails != null)
{
Debug.Log($" 가격: {detail.OneTimePurchaseOfferDetails.FormattedPrice}");
}
// 구독 상품의 오퍼 정보
if (detail.SubscriptionOfferDetails != null)
{
foreach (var offer in detail.SubscriptionOfferDetails)
{
Debug.Log($" 구독 오퍼 토큰: {offer.OfferToken}");
}
}
}
// 조회 실패한 상품 목록 (부분 실패)
if (success.Data.UnfetchedProductList.Count > 0)
{
var unfetchedIds = success.Data.UnfetchedProductList.Select(p => p.ProductId);
Debug.LogWarning($"조회 실패 상품: {string.Join(", ", unfetchedIds)}");
}
break;
case GooglePlayBillingServiceQueryProductDetailsResult.UnknownOutcome:
Debug.LogWarning("알 수 없는 조회 결과입니다.");
break;
case GooglePlayBillingServiceQueryProductDetailsResult.Failure failure:
Debug.LogError($"상품 상세 조회 실패: {failure}");
break;
default:
Debug.LogWarning($"처리되지 않은 결과: {result.GetType().Name}");
break;
}
응답 데이터
성공 시 GooglePlayBillingServiceQueryProductDetailsResult.Success의 Data(QueryProductDetailsResponse)에 결과가 담깁니다.
| 필드명 | 타입 | 설명 |
|---|---|---|
Data.ProductDetailsList | IReadOnlyList<GoogleProductDetails> | 조회에 성공한 상품 상세 정보 목록입니다. 조회된 상품이 없으면 빈 목록입니다. |
Data.UnfetchedProductList | IReadOnlyList<UnfetchedProduct> | 조회하지 못한 상품 목록입니다. 부분 실패가 없으면 빈 목록입니다. |
GoogleProductDetails
| 필드명 | 타입 | 설명 |
|---|---|---|
ProductId | string | 상품의 고유 식별자입니다. |
ProductType | ProductType | 상품 유형입니다. Inapp(소모성 상품) 또는 Subs(구독 상품)입니다. |
Title | string | 상품 제목입니다. |
Name | string | 상품 이름입니다. |
Description | string | 상품 설명입니다. |
OneTimePurchaseOfferDetails | OneTimePurchaseOfferDetails? | 일회성 구매(소모성/비소모성) 오퍼 정보입니다. 구독 상품이면 null입니다. |
OneTimePurchaseOfferDetailsList | IReadOnlyList<OneTimePurchaseOfferDetails> | 다중 일회성 오퍼 목록입니다. 단일 일회성 오퍼만 있거나 구독 상품이면 빈 목록입니다. |
SubscriptionOfferDetails | IReadOnlyList<SubscriptionOfferDetails> | 구독 오퍼 정보 목록입니다. 소모성 상품이면 빈 목록입니다. |
응답 상태
반환 객체 GooglePlayBillingServiceQueryProductDetailsResult는 아래 케이스 중 하나로 분기됩니다. switch 구문으로 처리하세요.
| 응답 케이스 | 설명 | 앱 클라이언트 대응 |
|---|---|---|
Success | 상품 상세 조회 성공. ProductDetailsList에 상품 정보, UnfetchedProductList에 실패 상품이 담깁니다. | 조회된 상품으로 상점 화면 구성 또는 FetchGoogleProductsAsync() 입력 데이터로 활용 |
UnknownOutcome | 알 수 없는 결과 | 재시도 또는 오류 안내 |
Failure | 공통 Failure입니다. 공통 오류 처리를 참조하세요. | 공통 오류 처리 기준에 따라 처리 |
3. 선택: Hive Axyl 서버 상품 상세 정보 조회
상품 ID 목록을 기반으로 상품명, 현지화된 가격, 통화, 상품 설명 등 Google Play에 등록한 상품의 상세 정보를 Hive Axyl 서버를 통해 서비스 표준 형식(Single Standard)으로 조회합니다. 위 2단계에서 Google 결제 플러그인의 QueryProductDetailsAsync()로 조회한 상품 정보를 입력값으로 사용합니다.
FetchGoogleProductsAsync
Google Play 상품 목록 조회를 구현하려면 Hive Axyl SDK가 제공하는 FetchGoogleProductsAsync()를 호출하세요. 위 2단계에서 Google 결제 플러그인(QueryProductDetailsAsync())으로 조회한 상품 정보를 전달하면, 서비스 표준 형식(Single Standard)으로 정제된 상품 목록을 반환합니다.
호출 파라미터
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
| request | ProductGoogle | Required | Google Play에서 조회한 상품 정보를 담은 요청 데이터입니다. |
| context | ApiCallContext | Optional | 호출 단위 설정 객체입니다. 멱등키·취소 토큰·요청 정책을 지정하며, 생략하면 기본값이 사용됩니다. |
ProductGoogle
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
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<ProductDetails> | Required | 스토어에서 조회한 상품 정보 목록입니다. 1개 이상 담아야 합니다. |
ProviderId | ProductGoogleProviderId (enum) | Required | 마켓 식별자입니다. Google Play 전용 요청이므로 Google만 지정합니다. |
ProductDetails
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Description | string | Optional | 상품 설명입니다. |
OneTimePurchaseOfferDetails | ProductGoogleOfferDetails | Optional | 일회성 구매 오퍼입니다. 값이 있으면 이 오퍼의 가격 정보를 사용합니다. |
OneTimePurchaseOfferDetailsList | IReadOnlyList<ProductGoogleOfferDetails> | Optional | 일회성 구매 오퍼 목록입니다. 할인 오퍼와 기본 오퍼를 함께 전달할 때 사용합니다. |
ProductId | string | Required | 상품의 고유 식별자(PID)입니다. 비어 있으면 요청이 거부됩니다. 예: com.game.product1 |
ProductType | int | Optional | 상품 유형입니다. 1은 소모성 상품, 2는 구독 상품입니다. |
SubscriptionOfferDetails | IReadOnlyList<ProductGoogleSubscriptionOffer> | Optional | 구독 오퍼 목록입니다. 가격 정보는 각 오퍼의 PricingPhases에 담깁니다. |
Title | string | Optional | 상품 제목입니다. 예: 1000 Gold |
ProductGoogleOfferDetails
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
FormattedPrice | string | Optional | Google Play가 표시용으로 형식화한 가격입니다. |
OfferId | string | Optional | 오퍼 ID입니다. 기본 오퍼에서는 null입니다. |
OfferToken | string | Optional | 오퍼 토큰입니다. 상품을 다시 조회할 때마다 새 값을 사용하세요. |
PreorderDetails | string | Optional | 사전 주문 오퍼 정보의 원시 JSON 문자열입니다. 플러그인 객체가 있으면 ToJson() 결과를 사용합니다. |
PriceAmount | decimal | Optional | 통화 단위의 가격입니다. PriceAmountMicros도 전달하면 마이크로 단위 값을 사용합니다. |
PriceAmountMicros | long | Optional | 마이크로 단위 가격입니다. 이 값을 전달하면 가격 기준으로 사용합니다. |
PriceCurrencyCode | string | Optional | 통화 코드입니다. ISO 4217 세 자리 형식을 사용합니다. |
RentalDetails | string | Optional | 대여 오퍼 정보의 원시 JSON 문자열입니다. 플러그인 객체가 있으면 ToJson() 결과를 사용합니다. |
입력 JSON을 직접 만들 때는 productId, oneTimePurchaseOfferDetails처럼 C# 속성 이름에 맞춘 키를 사용하세요. Google Play에서 조회한 상품과 오퍼 정보를 바꾸지 말고 전달하세요.
ProductGoogleSubscriptionOffer
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
BasePlanId | string | Optional | 기본 요금제 ID입니다. |
OfferId | string | Optional | 구독 오퍼 ID입니다. 기본 오퍼에서는 null입니다. |
OfferTags | IReadOnlyList<string> | Optional | 구독 오퍼 태그입니다. |
OfferToken | string | Optional | 구독 오퍼 토큰입니다. 상품을 다시 조회할 때마다 새 값을 사용하세요. |
PricingPhases | IReadOnlyList<ProductGooglePricingPhase> | Optional | 구독 가격 단계 목록입니다. |
ProductGooglePricingPhase
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
BillingCycleCount | int | Optional | 청구 주기 수입니다. 무한 반복 단계에서는 0입니다. |
BillingPeriod | string | Optional | ISO 8601 기간 형식의 청구 주기입니다. |
FormattedPrice | string | Optional | Google Play가 표시용으로 형식화한 가격입니다. |
PriceAmount | decimal | Optional | 통화 단위의 가격입니다. PriceAmountMicros도 전달하면 마이크로 단위 값을 사용합니다. |
PriceAmountMicros | long | Optional | 마이크로 단위 가격입니다. 이 값을 전달하면 가격 기준으로 사용합니다. |
PriceCurrencyCode | string | Optional | 통화 코드입니다. ISO 4217 세 자리 형식을 사용합니다. |
RecurrenceMode | int | Optional | 반복 방식입니다. 1은 무한 반복, 2는 유한 반복, 3은 한 번만 청구합니다. |
플러그인 결과 매핑
GoogleProductDetails와 ProductDetails는 이름이 비슷하지만 서로 다른 C# 타입이므로 직접 대입할 수 없습니다. 2단계의 ProductDetailsList를 아래 매퍼로 변환해 3단계 요청의 Products에 설정하세요. 모든 오퍼와 가격 단계를 매핑하며, 일회성 오퍼의 PreorderDetails와 RentalDetails만 원시 JSON 문자열로 바꿉니다.
using System.Collections.Generic;
using System.Linq;
using Hive.Axyl.Payments;
using Google = Hive.Axyl.Payments.Addon.Google;
internal static class GoogleProductMapper
{
public static IReadOnlyList<ProductDetails> Map(IReadOnlyList<Google.GoogleProductDetails> sources)
{
return sources.Select(Map).ToArray();
}
private static ProductDetails Map(Google.GoogleProductDetails source)
{
return new ProductDetails
{
Description = source.Description,
OneTimePurchaseOfferDetails = source.OneTimePurchaseOfferDetails is { } offer
? Map(offer)
: null,
OneTimePurchaseOfferDetailsList = source.OneTimePurchaseOfferDetailsList.Select(Map).ToArray(),
ProductId = source.ProductId,
ProductType = (int)source.ProductType,
SubscriptionOfferDetails = source.SubscriptionOfferDetails.Select(Map).ToArray(),
Title = source.Title
};
}
private static ProductGoogleOfferDetails Map(Google.OneTimePurchaseOfferDetails source)
{
return new ProductGoogleOfferDetails
{
FormattedPrice = source.FormattedPrice,
OfferId = source.OfferId,
OfferToken = source.OfferToken,
PreorderDetails = source.PreorderDetails?.ToJson(),
PriceAmount = source.PriceAmount,
PriceCurrencyCode = source.PriceCurrencyCode,
RentalDetails = source.RentalDetails?.ToJson()
};
}
private static ProductGoogleSubscriptionOffer Map(Google.SubscriptionOfferDetails source)
{
return new ProductGoogleSubscriptionOffer
{
BasePlanId = source.BasePlanId,
OfferId = source.OfferId,
OfferTags = source.OfferTags.ToArray(),
OfferToken = source.OfferToken,
PricingPhases = source.PricingPhases.Select(phase => new ProductGooglePricingPhase
{
BillingCycleCount = phase.BillingCycleCount,
BillingPeriod = phase.BillingPeriod,
FormattedPrice = phase.FormattedPrice,
PriceAmount = phase.PriceAmount,
PriceCurrencyCode = phase.PriceCurrencyCode,
RecurrenceMode = (int)phase.RecurrenceMode
}).ToArray()
};
}
}
호출 예시
PaymentsFetchGoogleProductsResult의 성공 결과와 이 메서드에서 정의한 도메인별 결과(Outcome)는 아래 예시와 응답 상태에서 확인합니다. 요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요.
using Hive.Axyl.Payments;
using Hive.Axyl.Core;
// payments: 초기화 시 등록된 IPaymentsService (자세한 획득은 [모듈 설치 및 초기화](../init.md) 참고)
IPaymentsService payments = HiveCore.Resolve<IPaymentsService>();
// QueryProductDetailsAsync() 성공 응답의 ProductDetailsList를 변환해 요청에 담습니다.
var request = new ProductGoogle
{
AppVersion = "1.0.0",
Country = "KR",
Currency = "KRW",
Language = "ko",
ProductType = "consumable",
ProviderId = ProductGoogleProviderId.Google,
Products = GoogleProductMapper.Map(productDetailsList)
};
PaymentsFetchGoogleProductsResult result = await payments.FetchGoogleProductsAsync(request);
switch (result)
{
case PaymentsFetchGoogleProductsResult.Success success:
// 표준 형식으로 정제된 상품 목록으로 상점 화면을 구성합니다.
foreach (var product in success.Data.Products)
{
Debug.Log($"{product.ProductId}: {product.Title} ({product.DisplayPrice})");
}
break;
// 요청 검증 실패 결과(Outcome) 처리
case PaymentsFetchGoogleProductsResult.PaymentBadRequest:
case PaymentsFetchGoogleProductsResult.PaymentInvalidParameter:
// 요청 필드와 필수값을 점검하세요.
break;
// 공통 Failure 처리
case PaymentsFetchGoogleProductsResult.Failure failure:
HiveError err = failure.Problem;
Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
break;
// 안전망: 처리하지 않은 결과 및 알 수 없는 신규 결과(UnknownOutcome)
default:
Debug.LogWarning($"처리되지 않은 결과: {result.GetType().Name}");
break;
}
응답 데이터
성공 시 PaymentsFetchGoogleProductsResult.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 | 마켓 식별자입니다. 이 응답에서는 Google이 반환됩니다. |
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 | 오퍼 토큰입니다. 요청에 보낸 값이 그대로 반환됩니다. Google Play가 조회할 때마다 새로 발급하므로 캐시하지 말고 다시 조회한 값을 사용하세요. |
Price | decimal | Optional | 통화 단위의 가격입니다. |
응답 예시
// Success 분기에서 success.Data 예시
// success.Data.ProviderId = ProductProviderId.Google
// success.Data.Currency = "KRW"
// success.Data.Products[0].ProductId = "com.game.product1"
// success.Data.Products[0].Title = "1000 Gold"
// success.Data.Products[0].Price = 1200
// success.Data.Products[0].DisplayPrice = "1,200 KRW"
// success.Data.Products[0].ProductType = "consumable"
응답 상태
아래 표에는 PaymentsFetchGoogleProductsResult의 성공 결과와 이 메서드에서 정의한 도메인별 결과(Outcome)를 정리했습니다. 요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요.
| 응답 케이스 | 설명 | 앱 클라이언트 대응 |
|---|---|---|
Success | 상품 목록 조회에 성공했습니다. Data에 표준 형식 상품 목록이 담깁니다. | 상품 목록으로 상점 화면 구성 |
PaymentBadRequest | 요청을 처리할 수 없습니다. | 요청 값과 호출 조건을 점검 |
PaymentInvalidParameter | 유효하지 않은 파라미터입니다. | 요청 필드 값을 점검 후 재요청 |
PaymentResourceNotFound | 결제 정보를 찾을 수 없습니다. | 영수증·주문 번호·결제 상태를 확인 |
UnknownOutcome | SDK가 알 수 없는 도메인별 결과입니다. | 실패로 처리하고 결과 코드를 기록 |
Failure | 공통 Failure입니다. 공통 오류 처리를 참조하세요. | 공통 오류 처리 기준에 따라 처리 |
다음 단계
상품을 구매합니다.