구매 복구
통신 오류나 비정상 종료로 결제는 완료됐지만 상품을 받지 못한 미지급 건을 다시 조회해, 누락된 상품을 지급합니다. 이로써 결제 관련 불만을 줄이고 사용자의 구매 자산을 보호합니다.
아래 과정을 따라 미지급 구매를 복구합니다.
1. 미지급 영수증 재조회
Google 결제 플러그인의 QueryPurchasesAsync()를 호출하여 Google Play에서 미지급 상품의 구매 영수증을 다시 획득합니다. Google Play는 별도의 복원(Restore) 흐름이 없으며, QueryPurchasesAsync()가 미완료 구매를 포함한 사용자의 구매 내역을 반환하므로 이 메서드가 복원의 역할을 합니다.
BillingClient 연결 필수
QueryPurchasesAsync()를 호출하기 전에 반드시 StartConnectionAsync()로 BillingClient를 연결하세요. 연결 방법은 1단계. 연동 환경 구성을 참조하세요.
QueryPurchasesAsync
미지급 영수증 재조회를 구현하려면 Google 결제 플러그인이 제공하는 QueryPurchasesAsync()를 호출하세요. 소모성 상품과 구독 상품 각각에 대해 호출하여 미완료 구매 건을 조회합니다.
호출 파라미터
| 필드명 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
| productType | ProductType | Required | 조회할 상품 유형입니다. Inapp(소모성 상품) 또는 Subs(구독 상품)를 지정합니다. |
| ct | CancellationToken | Optional | 취소 토큰입니다. |
호출 예시
GooglePlayBillingServiceQueryPurchasesResult의 성공 결과와 이 메서드에서 정의한 도메인별 결과(Outcome)는 아래 예시와 응답 상태에서 확인합니다. 요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요.
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;
}
// 소모성 상품과 구독 상품의 미완료 구매 조회
foreach (ProductType productType in new[]
{
ProductType.Inapp,
ProductType.Subs
})
{
GooglePlayBillingServiceQueryPurchasesResult result =
await googlePlugin.QueryPurchasesAsync(productType, CancellationToken.None);
switch (result)
{
case GooglePlayBillingServiceQueryPurchasesResult.Success success:
foreach (GooglePurchase purchase in success.Data.Purchases)
{
if (purchase.PurchaseState == PurchaseState.Purchased && !purchase.IsAcknowledged)
{
// 미지급(미소모) 구매 건 발견. 구매 토큰을 보관하고 후속 처리 진행
string orderId = purchase.OrderId;
Debug.Log($"미지급 구매({productType}) — 상품: {string.Join(", ", purchase.Products)}, 주문: {orderId}");
}
}
break;
case GooglePlayBillingServiceQueryPurchasesResult.UnknownOutcome:
Debug.LogWarning("알 수 없는 조회 결과입니다.");
break;
case GooglePlayBillingServiceQueryPurchasesResult.Failure failure:
Debug.LogError($"미지급 구매 조회 실패: {failure}");
break;
default:
Debug.LogWarning($"처리되지 않은 결과: {result.GetType().Name}");
break;
}
}
응답 데이터
성공 시 GooglePlayBillingServiceQueryPurchasesResult.Success의 Data(QueryPurchasesResponse)에 결과가 담깁니다.
| 필드명 | 타입 | 설명 |
|---|---|---|
Data.Purchases | IReadOnlyList<GooglePurchase> | 사용자의 구매 목록입니다. 미소모(미지급) 구매 건을 포함합니다. |
GooglePurchase
| 필드명 | 타입 | 설명 |
|---|---|---|
OrderId | string? | 마켓 주문번호입니다. (예: GPA.3389-9543-8198-17604) |
PurchaseToken | string | 구매 영수증(purchaseToken)입니다. |
Products | IReadOnlyList<string> | 구매한 상품 ID 목록입니다. |
PurchaseState | PurchaseState | 구매 상태입니다. Purchased(완료) 또는 Pending(보류)입니다. |
PurchaseTime | DateTimeOffset | 구매 시각입니다. |
Quantity | int | 구매 수량입니다. |
IsAcknowledged | bool | 구매 확인(acknowledge) 완료 여부입니다. |
IsAutoRenewing | bool | 자동 갱신 여부입니다. 구독 상품에서 사용됩니다. |
Signature | string | 구매 서명 데이터입니다. |
OriginalJson | string | Google Play가 반환한 원본 구매 JSON 데이터입니다. |
응답 상태
반환 객체 GooglePlayBillingServiceQueryPurchasesResult는 아래 케이스 중 하나로 분기됩니다. switch 구문으로 처리하세요.
| 응답 케이스 | 설명 | 앱 클라이언트 대응 |
|---|---|---|
Success | 구매 목록 조회 성공. Data.Purchases에 미완료 구매 건이 담깁니다. | 각 미지급 건의 PurchaseToken을 앱 서버에 전달해 영수증 검증 진행 후 상품 지급 |
UnknownOutcome | 알 수 없는 결과 | 재시도 또는 오류 안내 |
Failure | 공통 Failure입니다. 공통 오류 처리를 참조하세요. | 공통 오류 처리 기준에 따라 처리 |
재조회로 획득한 미지급 구매도 신규 구매와 같은 영수증 형식을 사용합니다. GooglePurchase.PurchaseToken을 3단계. 상품 구매의 결제 결과 데이터 저장 요청 AxylReceipt로 전달하고, RequestType은 2(구매 복원)로 설정합니다.
2. 영수증 검증 및 상품 지급
다시 획득한 영수증을 가지고 아래 과정을 다시 진행합니다.
- 영수증 정보를 준비해 앱 서버에 전달합니다. 앱 서버가 보내는 영수증 검증 요청의
requestType도2(구매 복원)로 설정합니다. - 앱 서버가 Hive Axyl Server API로 영수증을 검증합니다.
- 검증이 완료되면 상품을 지급하고 거래 완료 처리를 합니다.