Apple StoreKit 결제 Add-on
iOS와 macOS에서 Apple의 인앱 결제 기능인 StoreKit 2의 Product, Transaction, AppStore API를 감싸는 Add-on입니다. 상품 조회, 구매, 거래 조회, 거래 완료, App Store 동기화를 실행하고, StoreKit 2가 반환한 상품과 거래 필드를 가공하지 않고 그대로 전달합니다. 거래의 서명 검증 결과도 성공과 실패 두 값으로 줄이지 않고 검증 상태와 오류 원인을 함께 전달합니다.
구매로 받은 거래는 Payments 모듈로 Hive Axyl 서버에 기록한 뒤, 앱 서버가 Hive Axyl Server API로 영수증을 검증합니다. 두 단계 모두 영수증 값으로 AppleTransaction.JwsRepresentation을 사용합니다. 값을 넣는 방법은 AxylReceipt 규칙을, 검증 흐름은 영수증 검증을 참조하세요.
모듈 정보
- 패키지:
com.com2usplatform.hiveaxyl.payments.addon.apple - 인터페이스:
IAppleStoreKitPlugin - 네임스페이스:
Hive.Axyl.Payments.Addon.Apple - 등록 메서드:
AddStoreKit() - 지원 플랫폼: iOS, macOS
- 최소 사양: iOS 17+, macOS 15+, Unity 6000.0+
등록과 획득
HiveBootstrap.Initialize의 등록 단계에서 Payments 모듈과 함께 등록한 뒤 HiveCore.TryResolve<T>()로 가져옵니다.
using Hive.Axyl.Core;
using Hive.Axyl.Core.Unity; // HiveBootstrap
using Hive.Axyl.Payments;
using Hive.Axyl.Payments.Addon.Apple;
HiveBootstrap.Initialize(config, builder =>
{
builder.AddPayments()
.AddStoreKit();
});
if (HiveCore.TryResolve<IAppleStoreKitPlugin>(out var storeKit))
{
// iOS · macOS 빌드에서만 실행되는 코드
}
Unity 에디터에서는 등록되지 않습니다
이 Add-on은 iOS 또는 macOS로 빌드한 플레이어에서만 등록됩니다. Unity 에디터에서는 플랫폼이 맞아도 등록되지 않으므로, HiveCore.Resolve<T>()를 쓰면 RegistrationNotFoundException이 발생합니다. 반드시 TryResolve<T>()로 확인한 뒤 사용하세요.
패키지 설치와 등록 절차는 Hive Axyl Apple 결제 플러그인 설치를 참조하세요.
메서드 요약
모든 메서드는 마지막 파라미터로 CancellationToken ct = default를 받으며, request가 null이면 ArgumentNullException이 발생합니다. 호출 규약은 호출 컨텍스트를 참조하세요.
이 Add-on이 제공하는 메서드는 아래와 같습니다.
- GetProductsAsync(): 상품 ID로 StoreKit 상품 정보 조회
- PurchaseAsync(): 상품 구매 시작
- StartTransactionObserverAsync():
Transaction.updates구독 시작 - StopTransactionObserverAsync():
Transaction.updates구독 중지 - GetCurrentEntitlementsAsync(): 사용자가 현재 이용 권한을 가진 거래 조회
- GetAllTransactionsAsync(): 사용자의 전체 거래 내역 조회
- GetUnfinishedTransactionsAsync(): 아직 완료하지 않은 거래 조회
- FinishTransactionAsync(): 거래 완료
- SyncAsync(): App Store 동기화를 통한 구매 복원
- GetStorefrontAsync(): 현재 App Store storefront 조회
메서드
GetProductsAsync
Product.products(for:)를 호출해 요청한 상품 ID에 해당하는 상품을 조회합니다. 일치하는 상품이 없어도 오류가 아니라 빈 목록으로 성공합니다.
결과 케이스 — AppleStoreKitServiceGetProductsResult
| 결과 케이스 | 와이어 코드 | 설명 |
|---|---|---|
Success | — | 조회에 성공했습니다. 일치하는 상품이 없으면 Data.Products가 비어 있습니다. |
UnknownOutcome | UNKNOWN | 이 SDK 버전이 알지 못하는 새 결과입니다. |
Failure | FAILURE | 호출을 마치지 못했습니다. Problem의 HiveError로 원인을 확인합니다. |
발생 예외
ArgumentNullException:request가null인 경우ArgumentException:request.ProductIds가null이거나 비어 있는 경우
구현 절차는 Apple App Store 상품 정보 조회를 참조하세요.
PurchaseAsync
Product.purchase(options:)로 구매를 시작합니다. 성공하면 서명 검증 여부와 관계없이 구매로 생성된 거래를 반환합니다. 앱 사용자가 결제 화면을 닫으면 UserCanceled로, 보호자 승인이 필요한 Ask to Buy나 Strong Customer Authentication(SCA) 때문에 구매가 보류되면 Pending으로 분기합니다.
- 요청: PurchaseRequest
- 응답: PurchaseResponse
결과 케이스 — AppleStoreKitServicePurchaseResult
| 결과 케이스 | 와이어 코드 | 설명 |
|---|---|---|
Success | — | 구매 거래를 받았습니다. 지급하기 전에 Data.Transaction.VerificationStatus를 확인합니다. |
UserCanceled | user_canceled | 앱 사용자가 StoreKit 결제 화면이나 로그인 대화 상자를 닫았습니다. |
Pending | pending | Ask to Buy나 SCA 때문에 구매가 보류됐습니다. 거래는 나중에 StartTransactionObserverAsync()로 시작한 구독의 TransactionUpdated 이벤트로 전달됩니다. |
UnknownOutcome | UNKNOWN | 이 SDK 버전이 알지 못하는 새 결과입니다. |
Failure | FAILURE | 호출을 마치지 못했습니다. Problem의 HiveError로 원인을 확인합니다. |
UserCanceled는 IUserCanceledOutcome을 구현합니다.
사용자 취소와 코드 취소는 다릅니다
앱 사용자가 결제 화면을 닫으면 UserCanceled입니다. 반면 CancellationToken으로 코드가 취소하면 Cancelled 코드를 담은 Failure가 됩니다.
호출 예시
using Hive.Axyl.Core;
using Hive.Axyl.Payments.Addon.Apple;
var request = new PurchaseRequest
{
ProductId = "{productId}",
Options = new PurchaseOptions
{
AppAccountToken = accountUuid, // Player ID로 만든 AccountUuid
},
};
var result = await storeKit.PurchaseAsync(request);
switch (result)
{
case AppleStoreKitServicePurchaseResult.Success success:
AppleTransaction transaction = success.Data.Transaction;
AppleVerificationStatus status = transaction.VerificationStatus; // 지급하기 전에 확인
string receipt = transaction.JwsRepresentation; // Payments 모듈의 AxylReceipt
break;
case AppleStoreKitServicePurchaseResult.UserCanceled:
// 앱 사용자가 결제 화면을 닫았습니다.
break;
case AppleStoreKitServicePurchaseResult.Pending:
// 구매가 보류됐습니다. 거래는 StartTransactionObserverAsync로 시작한 구독의 TransactionUpdated 이벤트로 전달됩니다.
break;
case AppleStoreKitServicePurchaseResult.Failure failure:
HiveError error = failure.Problem;
break;
default:
// 처리하지 않은 결과와 UnknownOutcome
break;
}
구매한 거래는 JwsRepresentation을 AxylReceipt로 삼아 RecordStorePurchaseAsync()로 결제 결과를 저장합니다.
Payments 모듈에도 PurchaseRequest가 있습니다
Hive.Axyl.Payments 네임스페이스에도 같은 이름의 PurchaseRequest가 있습니다. 한 파일에서 두 네임스페이스를 함께 가져온 뒤 PurchaseRequest를 그대로 쓰면 어느 타입인지 모호해 컴파일 오류가 발생합니다. 두 타입을 한 파일에서 함께 쓰려면 using ApplePurchaseRequest = Hive.Axyl.Payments.Addon.Apple.PurchaseRequest;와 using PaymentsPurchaseRequest = Hive.Axyl.Payments.PurchaseRequest;처럼 두 타입에 각각 별칭을 지정하세요.
구현 절차는 Apple App Store 결제 요청을 참조하세요.
StartTransactionObserverAsync
StoreKit의 Transaction.updates 비동기 스트림 구독을 시작합니다. 스트림으로 도착하는 거래는 TransactionUpdated 이벤트로 전달됩니다.
결과 케이스 — AppleStoreKitServiceStartTransactionObserverResult
| 결과 케이스 | 와이어 코드 | 설명 |
|---|---|---|
Success | — | 구독을 시작했습니다. |
AlreadyStarted | already_started | Transaction.updates 구독이 이미 실행 중입니다. |
UnknownOutcome | UNKNOWN | 이 SDK 버전이 알지 못하는 새 결과입니다. |
Failure | FAILURE | 호출을 마치지 못했습니다. Problem의 HiveError로 원인을 확인합니다. |
StopTransactionObserverAsync
Transaction.updates 구독을 중지합니다. 구독 중이 아닐 때 호출해도 오류가 아닙니다.
결과 케이스 — AppleStoreKitServiceStopTransactionObserverResult
| 결과 케이스 | 와이어 코드 | 설명 |
|---|---|---|
Success | — | 구독을 중지했습니다. |
UnknownOutcome | UNKNOWN | 이 SDK 버전이 알지 못하는 새 결과입니다. |
Failure | FAILURE | 호출을 마치지 못했습니다. Problem의 HiveError로 원인을 확인합니다. |
GetCurrentEntitlementsAsync
Transaction.currentEntitlements를 끝까지 읽어 사용자가 현재 이용 권한을 가진 거래를 반환합니다. 서명 검증 여부와 관계없이 모든 거래를 그대로 반환하며, 이용 권한이 없으면 오류가 아니라 빈 목록으로 성공합니다.
결과 케이스 — AppleStoreKitServiceGetCurrentEntitlementsResult
| 결과 케이스 | 와이어 코드 | 설명 |
|---|---|---|
Success | — | 조회에 성공했습니다. |
UnknownOutcome | UNKNOWN | 이 SDK 버전이 알지 못하는 새 결과입니다. |
Failure | FAILURE | 호출을 마치지 못했습니다. Problem의 HiveError로 원인을 확인합니다. |
구현 절차는 현재 자격 조회를 참조하세요.
GetAllTransactionsAsync
Transaction.all을 끝까지 읽어 사용자의 전체 거래 내역을 반환합니다. 결과 목록이 클 수 있습니다.
결과 케이스 — AppleStoreKitServiceGetAllTransactionsResult
| 결과 케이스 | 와이어 코드 | 설명 |
|---|---|---|
Success | — | 조회에 성공했습니다. |
UnknownOutcome | UNKNOWN | 이 SDK 버전이 알지 못하는 새 결과입니다. |
Failure | FAILURE | 호출을 마치지 못했습니다. Problem의 HiveError로 원인을 확인합니다. |
GetUnfinishedTransactionsAsync
Transaction.unfinished를 끝까지 읽어 아직 완료하지 않은 거래를 반환합니다.
결과 케이스 — AppleStoreKitServiceGetUnfinishedTransactionsResult
| 결과 케이스 | 와이어 코드 | 설명 |
|---|---|---|
Success | — | 조회에 성공했습니다. |
UnknownOutcome | UNKNOWN | 이 SDK 버전이 알지 못하는 새 결과입니다. |
Failure | FAILURE | 호출을 마치지 못했습니다. Problem의 HiveError로 원인을 확인합니다. |
구현 절차는 미완료 트랜잭션 조회를 참조하세요.
FinishTransactionAsync
Transaction.finish()로 거래를 완료합니다. 이미 완료한 거래에 다시 호출해도 오류가 아니며, 거래 ID와 일치하는 거래가 없으면 TransactionNotFound로 분기합니다.
결과 케이스 — AppleStoreKitServiceFinishTransactionResult
| 결과 케이스 | 와이어 코드 | 설명 |
|---|---|---|
Success | — | 거래를 완료했습니다. |
TransactionNotFound | transaction_not_found | 지정한 거래 ID와 일치하는 거래가 없습니다. |
UnknownOutcome | UNKNOWN | 이 SDK 버전이 알지 못하는 새 결과입니다. |
Failure | FAILURE | 호출을 마치지 못했습니다. Problem의 HiveError로 원인을 확인합니다. |
구현 절차는 Apple 거래 완료 처리를 참조하세요.
SyncAsync
AppStore.sync()로 App Store와 동기화해 구매를 복원합니다. OS가 Apple ID 재인증 대화 상자를 표시할 수 있으며, 앱 사용자가 이 대화 상자를 닫으면 UserCanceled로 분기합니다.
- 요청: SyncRequest
- 응답: SyncResponse
결과 케이스 — AppleStoreKitServiceSyncResult
| 결과 케이스 | 와이어 코드 | 설명 |
|---|---|---|
Success | — | 동기화에 성공했습니다. |
UserCanceled | user_canceled | 앱 사용자가 StoreKit 대화 상자를 닫았습니다. |
UnknownOutcome | UNKNOWN | 이 SDK 버전이 알지 못하는 새 결과입니다. |
Failure | FAILURE | 호출을 마치지 못했습니다. Problem의 HiveError로 원인을 확인합니다. |
UserCanceled는 IUserCanceledOutcome을 구현합니다.
구현 절차는 구매 동기화를 참조하세요.
GetStorefrontAsync
Storefront.current로 현재 App Store storefront를 조회합니다. StoreKit 2는 별도의 초기화 설정이 필요하지 않습니다.
결과 케이스 — AppleStoreKitServiceGetStorefrontResult
| 결과 케이스 | 와이어 코드 | 설명 |
|---|---|---|
Success | — | 조회에 성공했습니다. |
UnknownOutcome | UNKNOWN | 이 SDK 버전이 알지 못하는 새 결과입니다. |
Failure | FAILURE | 호출을 마치지 못했습니다. Problem의 HiveError로 원인을 확인합니다. |
이벤트
TransactionUpdated
StoreKit의 Transaction.updates 스트림으로 거래가 전달될 때마다 발생합니다. StartTransactionObserverAsync()로 구독하는 동안에만 발생하며, StopTransactionObserverAsync()로 중지합니다. 엔진 메인 스레드에서 호출되므로 핸들러 안에서 엔진 API를 사용해도 됩니다.
| 파라미터 | 타입 | 설명 |
|---|---|---|
| — | AppleTransaction | 스트림으로 전달된 거래입니다. |
앱은 전달된 거래마다 VerificationStatus를 확인한 뒤, 앱 서버에 영수증 검증을 요청하거나 FinishTransactionAsync()로 거래를 완료합니다. 상품을 지급할 거래는 앱 서버의 영수증 검증과 상품 지급이 끝난 뒤에 완료하세요. PurchaseAsync()가 Pending으로 끝난 구매의 결과도 이 이벤트로 전달됩니다.
데이터 타입
AppleProduct
StoreKit의 원본 Product 정보입니다.
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Id | string | Required | 상품 식별자인 Product.id입니다. |
DisplayName | string | Required | Product.displayName입니다. |
Description | string | Required | Product.description입니다. |
DisplayPrice | string | Required | 현지화된 표시 가격 문자열인 Product.displayPrice입니다. |
Price | decimal | Required | Product.price를 정밀도 손실 없이 담은 가격입니다. |
PriceLocale | string | Required | Product.priceFormatStyle의 로케일 식별자입니다. |
ProductType | AppleProductType | Required | Product.type입니다. |
Subscription | SubscriptionInfo? | Optional | 자동 갱신 구독에만 있는 Product.subscription입니다. |
IsFamilyShareable | bool | Required | Product.isFamilyShareable입니다. |
AppleTransaction
StoreKit의 원본 Transaction 정보입니다. 모든 필드를 가공하지 않고 전달하므로 필드의 의미는 앱이 해석합니다. 거래가 유효한지는 앱 서버가 Hive Axyl Server API로 JwsRepresentation을 검증한 결과로 최종 판단합니다.
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Id | ulong | Required | StoreKit 거래 식별자인 Transaction.id입니다. 민감 정보이므로 SDK 로그에는 마지막 4자리만 표시됩니다. |
OriginalId | ulong | Required | 원래 거래의 ID인 Transaction.originalID입니다. |
ProductId | string | Required | Transaction.productID입니다. |
ProductType | AppleProductType | Required | Transaction.productType입니다. |
PurchaseDate | DateTimeOffset | Required | Transaction.purchaseDate입니다. 민감 정보이므로 SDK 로그에 기록되지 않습니다. |
OriginalPurchaseDate | DateTimeOffset | Required | Transaction.originalPurchaseDate입니다. 민감 정보이므로 SDK 로그에 기록되지 않습니다. |
ExpirationDate | DateTimeOffset? | Optional | 자동 갱신 구독에만 있는 Transaction.expirationDate입니다. 만료 시각이 없으면 값이 없습니다. |
RevocationDate | DateTimeOffset? | Optional | 거래가 취소된 경우에만 있는 Transaction.revocationDate입니다. |
RevocationReason | AppleRevocationReason | Required | Transaction.revocationReason입니다. RevocationDate가 있을 때만 유효하며, 취소되지 않은 거래에서는 Unspecified입니다. |
WebOrderLineItemId | string? | Optional | 자동 갱신 구독에만 있는 Transaction.webOrderLineItemID입니다. |
SubscriptionGroupId | string? | Optional | 자동 갱신 구독에만 있는 Transaction.subscriptionGroupID입니다. |
AppAccountToken | string? | Optional | 앱이 지정한 UUID인 Transaction.appAccountToken입니다. 민감 정보이므로 SDK 로그에 기록되지 않습니다. |
Quantity | int | Required | Transaction.purchasedQuantity입니다. |
TransactionReason | AppleTransactionReason | Required | Transaction.reason입니다. |
SignedDate | DateTimeOffset | Required | Apple이 JWS에 서명한 시각인 Transaction.signedDate입니다. |
Environment | AppleEnvironment | Required | Transaction.environment입니다. |
OwnershipType | AppleOwnershipType | Required | Transaction.ownershipType입니다. |
JwsRepresentation | string | Required | Apple이 서명한 JWS 문자열인 Transaction.jwsRepresentation입니다. 서버 검증의 기준이 되는 값으로, Payments 모듈 요청의 AxylReceipt와 앱 서버가 보내는 영수증 검증 요청의 axylReceipt에 변형하지 않고 넣습니다. 민감 정보이므로 SDK 로그에 기록되지 않습니다. |
VerificationStatus | AppleVerificationStatus | Required | 이 거래의 VerificationResult 분기입니다. |
VerificationError | AppleVerificationError | Required | 서명 검증 오류 원인입니다. VerificationStatus가 Unverified일 때만 유효합니다. |
BundleId | string | Required | 거래에 연결된 번들 식별자인 Transaction.bundleID입니다. |
AppBundleId | string? | Optional | iOS 16 이상에서 제공되는 Transaction.appBundleID입니다. |
IsUpgraded | bool | Required | 구독 업그레이드로 대체됐는지 나타내는 Transaction.isUpgraded입니다. |
OfferType | AppleOfferType | Required | Transaction.offerType입니다. 적용된 오퍼가 없으면 Unspecified입니다. |
OfferId | string? | Optional | Transaction.offerID입니다. |
OfferPaymentModeStringRepresentation | string? | Optional | Transaction.offerPaymentModeStringRepresentation의 원본 문자열입니다. |
OfferPeriod | string? | Optional | ISO 8601 기간 문자열인 Transaction.offerPeriod입니다. |
Price | decimal? | Optional | 구매 시점의 Transaction.price를 정밀도 손실 없이 담은 가격입니다. |
Currency | string? | Optional | ISO 4217 통화 코드인 Transaction.currency입니다. |
StorefrontCountryCode | string | Required | 구매 시점 storefront의 countryCode입니다. |
DeviceVerification | string | Required | Base64로 인코딩된 Transaction.deviceVerification 값입니다. |
DeviceVerificationNonce | string | Required | UUID인 Transaction.deviceVerificationNonce입니다. |
AppTransactionId | string? | Optional | iOS 17 이상에서 제공되는 Transaction.appTransactionID입니다. |
SignedRenewalInfo | string? | Optional | 자동 갱신 구독의 갱신 정보 JWS입니다. 민감 정보이므로 SDK 로그에 기록되지 않습니다. |
FinishTransactionRequest
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
TransactionId | ulong | Required | 완료할 거래의 Transaction.id입니다. 민감 정보이므로 SDK 로그에는 마지막 4자리만 표시됩니다. |
FinishTransactionResponse
필드가 없습니다.
GetAllTransactionsRequest
필드가 없습니다. 빈 인스턴스를 전달하세요.
GetAllTransactionsResponse
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Transactions | IReadOnlyList<AppleTransaction> | Required | Transaction.all에서 읽은 사용자의 전체 거래 목록입니다. 거래 내역이 없으면 빈 목록입니다. |
GetCurrentEntitlementsRequest
필드가 없습니다. 빈 인스턴스를 전달하세요.
GetCurrentEntitlementsResponse
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Transactions | IReadOnlyList<AppleTransaction> | Required | Transaction.currentEntitlements에서 읽은, 사용자가 현재 이용 권한을 가진 거래 목록입니다. 이용 권한이 없으면 빈 목록입니다. |
GetProductsRequest
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
ProductIds | IReadOnlyList<string> | Required | Product.products(for:)로 조회할 상품 ID 목록입니다. null이거나 비어 있으면 ArgumentException이 발생합니다. |
GetProductsResponse
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Products | IReadOnlyList<AppleProduct> | Required | 요청한 ID에 해당하는 상품 목록입니다. 순서는 보장되지 않으며, 일치하는 상품이 없으면 빈 목록입니다. |
GetStorefrontRequest
필드가 없습니다. 빈 인스턴스를 전달하세요.
GetStorefrontResponse
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
CountryCode | string | Required | ISO 3166-1 alpha-3 지역 코드인 Storefront.countryCode입니다. |
Identifier | string | Required | App Store storefront 식별자인 Storefront.id입니다. |
GetUnfinishedTransactionsRequest
필드가 없습니다. 빈 인스턴스를 전달하세요.
GetUnfinishedTransactionsResponse
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Transactions | IReadOnlyList<AppleTransaction> | Required | Transaction.unfinished에서 읽은, 아직 완료하지 않은 거래 목록입니다. 없으면 빈 목록입니다. |
Offer
StoreKit의 원본 Product.SubscriptionOffer 정보입니다.
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Id | string? | Optional | SubscriptionOffer.id입니다. introductory offer에서는 null입니다. |
Type | AppleOfferType | Required | SubscriptionOffer.type입니다. |
Price | decimal | Required | SubscriptionOffer.price를 정밀도 손실 없이 담은 가격입니다. |
DisplayPrice | string | Required | SubscriptionOffer.displayPrice입니다. |
Period | Period | Required | SubscriptionOffer.period입니다. |
PeriodCount | int | Required | SubscriptionOffer.periodCount입니다. |
PaymentMode | ApplePaymentMode | Required | SubscriptionOffer.paymentMode입니다. |
Period
StoreKit의 Product.SubscriptionPeriod 정보입니다.
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Value | int | Required | SubscriptionPeriod.value입니다. |
Unit | ApplePeriodUnit | Required | SubscriptionPeriod.unit입니다. |
PurchaseOptions
Product.purchase(options:)에 전달하는 Product.PurchaseOption 값입니다. appAccountToken과 quantity만 지원하며, promotionalOffer와 simulatesAskToBuyInSandbox는 지원하지 않습니다.
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
AppAccountToken | string? | Optional | 앱이 지정하는 UUID인 Product.PurchaseOption.appAccountToken입니다. Payments 모듈 요청과 영수증 검증 요청에 보내는 AccountUuid와 같은 값을 넣어야 영수증 검증 응답의 계정 식별자 비교 결과가 일치로 나옵니다. 민감 정보이므로 SDK 로그에 기록되지 않습니다. |
Quantity | int? | Optional | 소모성 상품의 구매 수량인 Product.PurchaseOption.quantity입니다. |
PurchaseRequest
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
ProductId | string | Required | 구매할 상품 ID입니다. |
Options | PurchaseOptions? | Optional | 구매 옵션입니다. |
PurchaseResponse
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
Transaction | AppleTransaction | Required | 구매로 생성된 거래입니다. StoreKit VerificationResult로 감싼 원본 거래이므로 지급하기 전에 VerificationStatus를 확인하세요. |
StartTransactionObserverRequest
필드가 없습니다. 빈 인스턴스를 전달하세요.
StartTransactionObserverResponse
필드가 없습니다.
StopTransactionObserverRequest
필드가 없습니다. 빈 인스턴스를 전달하세요.
StopTransactionObserverResponse
필드가 없습니다.
SubscriptionInfo
StoreKit의 원본 Product.SubscriptionInfo 정보입니다.
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
SubscriptionGroupId | string | Required | SubscriptionInfo.subscriptionGroupID입니다. |
SubscriptionPeriod | Period | Required | SubscriptionInfo.subscriptionPeriod입니다. |
IntroductoryOffer | Offer? | Optional | introductory offer가 설정된 경우에만 있는 SubscriptionInfo.introductoryOffer입니다. |
PromotionalOffers | IReadOnlyList<Offer> | Required | SubscriptionInfo.promotionalOffers 원본 목록입니다. 오퍼 선택과 서명 생성은 앱이 담당합니다. |
SyncRequest
필드가 없습니다. 빈 인스턴스를 전달하세요.
SyncResponse
필드가 없습니다.
열거형
Add-on 열거형은 C# 멤버 이름으로 지정합니다. 표의 '값'은 직렬화에 사용하는 정수입니다.
AppleEnvironment
Transaction.environment입니다. System.Environment와 이름이 겹치지 않도록 Apple 접두사가 붙습니다.
| C# 멤버 | 값 | 설명 |
|---|---|---|
Unspecified | 0 | 환경이 지정되지 않은 기본값입니다. |
Production | 1 | 운영 App Store 환경에서 처리된 거래입니다. |
Sandbox | 2 | 샌드박스 테스트 환경에서 처리된 거래입니다. |
Xcode | 3 | Xcode에서 실행한 로컬 StoreKit 구성 파일로 생성된 거래입니다. |
AppleOfferType
Transaction.offerType 또는 Product.SubscriptionOffer.type입니다.
| C# 멤버 | 값 | 설명 |
|---|---|---|
Unspecified | 0 | 적용된 오퍼가 없습니다. |
Introductory | 1 | 구독 그룹에서 introductory offer를 받은 적 없는 고객에게 제공하는 오퍼입니다. |
Promotional | 2 | 서명된 오퍼로 기존 구독자나 이탈한 구독자에게 제공하는 오퍼입니다. |
Code | 3 | 구독 오퍼 코드로 사용한 오퍼입니다. 거래에만 적용됩니다. |
WinBack | 4 | 이전 구독자의 재구독을 유도하는 오퍼입니다. 거래에서는 iOS 18 이상에서 제공됩니다. |
AppleOwnershipType
Transaction.ownershipType입니다.
| C# 멤버 | 값 | 설명 |
|---|---|---|
Unspecified | 0 | 소유 유형이 지정되지 않은 기본값입니다. |
Purchased | 1 | 현재 사용자가 상품을 구매했습니다. |
FamilyShared | 2 | 가족 공유로 상품에 접근합니다. |
ApplePaymentMode
Product.SubscriptionOffer.PaymentMode입니다.
| C# 멤버 | 값 | 설명 |
|---|---|---|
Unspecified | 0 | 결제 방식이 지정되지 않은 기본값입니다. |
PayAsYouGo | 1 | 오퍼의 청구 기간마다 결제합니다. |
PayUpFront | 2 | 오퍼 전체 기간의 금액을 한 번에 결제합니다. |
FreeTrial | 3 | 오퍼 기간을 무료로 제공합니다. |
ApplePeriodUnit
Product.SubscriptionPeriod.Unit입니다.
| C# 멤버 | 값 | 설명 |
|---|---|---|
Unspecified | 0 | 기간 단위가 지정되지 않은 기본값입니다. |
Day | 1 | 일 단위입니다. |
Week | 2 | 주 단위입니다. |
Month | 3 | 월 단위입니다. |
Year | 4 | 연 단위입니다. |
AppleProductType
Product.ProductType 또는 Transaction.productType입니다.
| C# 멤버 | 값 | 설명 |
|---|---|---|
Unspecified | 0 | 상품 유형이 지정되지 않은 기본값입니다. StoreKit은 이 값을 반환하지 않습니다. |
Consumable | 1 | 사용하면 소진되고 다시 구매할 수 있는 소모성 상품입니다. |
NonConsumable | 2 | 한 번 구매하면 계속 보유하는 비소모성 상품입니다. |
AutoRenewable | 3 | 사용자가 취소할 때까지 자동으로 갱신되는 구독입니다. |
NonRenewable | 4 | 정해진 기간만 이용하고 자동으로 갱신되지 않는 구독입니다. |
AppleRevocationReason
Transaction.revocationReason입니다.
| C# 멤버 | 값 | 설명 |
|---|---|---|
Unspecified | 0 | 거래가 취소되지 않았습니다. |
DeveloperIssue | 1 | 앱의 문제로 App Store가 환불했습니다. |
Other | 2 | 고객 지원 요청 같은 다른 사유로 App Store가 환불했습니다. |
AppleTransactionReason
Transaction.reason입니다.
| C# 멤버 | 값 | 설명 |
|---|---|---|
Unspecified | 0 | 거래 사유가 지정되지 않은 기본값입니다. |
Purchase | 1 | 사용자가 직접 구매한 거래입니다. |
Renewal | 2 | 구독이 자동으로 갱신된 거래입니다. |
AppleVerificationError
VerificationStatus가 Unverified일 때 StoreKit이 알려 준 VerificationResult.VerificationError 원인입니다. 원인을 바꾸거나 줄이지 않고 그대로 전달합니다.
| C# 멤버 | 값 | 설명 |
|---|---|---|
Unspecified | 0 | 검증 오류가 없습니다. VerificationStatus가 Unverified가 아닐 때의 값입니다. |
InvalidSignature | 1 | JWS 서명이 예상 값과 일치하지 않습니다. |
RevokedCertificate | 2 | JWS에 서명한 인증서가 폐기됐습니다. |
InvalidDeviceVerification | 3 | JWS의 기기 검증 값이 이 기기에 기대한 값과 일치하지 않습니다. |
InvalidCertificateChain | 4 | JWS에 서명한 인증서 체인이 유효하지 않습니다. |
InvalidEncoding | 5 | JWS가 StoreKit이 기대한 형식으로 인코딩되지 않아 디코딩할 수 없습니다. |
MissingRequiredProperties | 6 | 검증에 필요한 속성이 JWS에 없습니다. |
AppleVerificationStatus
VerificationResult<Transaction>의 분기입니다.
| C# 멤버 | 값 | 설명 |
|---|---|---|
Unspecified | 0 | 검증 상태가 지정되지 않은 기본값입니다. |
Verified | 1 | StoreKit이 거래 JWS 서명을 검증했습니다. VerificationError는 적용되지 않습니다. |
Unverified | 2 | StoreKit이 거래 JWS 서명을 검증하지 못했습니다. VerificationError에서 원인을 확인합니다. |