콘텐츠로 이동

구매 복구

통신 오류나 비정상 종료로 결제는 완료됐지만 상품을 받지 못한 미지급 건을 다시 조회해, 누락된 상품을 지급합니다. 이로써 결제 관련 불만을 줄이고 사용자의 구매 자산을 보호합니다.

아래 과정을 따라 미완료 거래를 복구합니다.

1. 미완료 거래 복구

Method

RestorePurchasesAsync

구매 복구를 구현하려면 Hive Axyl SDK가 제공하는 RestorePurchasesAsync()를 호출하세요. 결제는 완료했지만 상품을 아직 지급하지 않은 구매 목록을 반환합니다.

호출 파라미터

필드명 타입 필수 여부 설명
request PurchaseRestoreRequest Required 구매 복구 요청 데이터입니다.
context ApiCallContext Optional 호출 단위 설정 객체입니다. 멱등키·취소 토큰·요청 정책을 지정하며, 생략하면 기본값이 사용됩니다.

PurchaseRestoreRequest

필드명 타입 필수 여부 설명
ProviderId PurchaseRestoreRequestProviderId Required 마켓 식별자입니다. Steam 구매 복구 전용 요청이므로 Steam만 지정합니다.
AppVersion string Optional 앱 버전입니다.
Country string Required 국가 코드(ISO 3166-1 두 자리)입니다. 예: KR
Language string Required 언어 코드(ISO 639-1 두 자리)입니다. 예: ko
ServerId string Optional Hive 콘솔 앱 서버를 따라 앱 정보 > 앱 서버에서 앱 서버를 등록한 뒤 앱 서버 탭에서 확인하는 서버 ID입니다. 지정하면 해당 서버의 주문만 반환하고, 생략하면 모든 주문을 반환합니다.

호출 예시

PaymentsRestorePurchasesResult의 성공 결과와 이 메서드에서 정의한 도메인별 결과(Outcome)는 아래 예시와 응답 상태에서 확인합니다. 요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요.

using Hive.Axyl.Payments;
using Hive.Axyl.Core;

// payments: 초기화 시 등록된 IPaymentsService (자세한 획득은 [모듈 설치 및 초기화](../init.md) 참고)
IPaymentsService payments = HiveCore.Resolve<IPaymentsService>();

var request = new PurchaseRestoreRequest
{
    ProviderId = PurchaseRestoreRequestProviderId.Steam,
    Country = "KR",
    Language = "ko",
    ServerId = "server01"
};

PaymentsRestorePurchasesResult result = await payments.RestorePurchasesAsync(request);

switch (result)
{
    case PaymentsRestorePurchasesResult.Success success:
        // 복구 가능한 구매 목록 처리
        if (success.Data.Restores is { } restores)
        {
            foreach (var restore in restores)
            {
                Debug.Log($"orderId: {restore.OrderId}, productId: {restore.ProductId}");
            }
        }
        break;

    case PaymentsRestorePurchasesResult.PaymentBadRequest:
        // 요청을 처리할 수 없습니다. 요청 값과 호출 조건 확인
        break;

    case PaymentsRestorePurchasesResult.PaymentInvalidParameter:
        // 유효하지 않은 파라미터입니다. 요청 값 확인
        break;

    // 공통 Failure 처리
    case PaymentsRestorePurchasesResult.Failure failure:
        HiveError err = failure.Problem;
        Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
        break;

    // 안전망: 처리하지 않은 결과 및 알 수 없는 신규 결과(UnknownOutcome)
    default:
        Debug.LogWarning($"처리되지 않은 결과: {result.GetType().Name}");
        break;
}

응답 데이터

성공 시 PaymentsRestorePurchasesResult.Success의 Data(PurchaseRestoreResponseData)에 결과가 담깁니다.

필드명 타입 필수 여부 설명
Data.Restores IReadOnlyList<RestorePurchase>? Optional 복구 가능한 구매 목록입니다.
Data.Meta string? Optional 응답 메타 정보입니다.

RestorePurchase

필드명 타입 필수 여부 설명
Currency string Optional 통화 코드입니다.
GameServerPriceVerifyKey string Optional 앱 서버 결제 금액 검증 키입니다.
IapPayload string Optional 앱 서버로 전달할 추가 페이로드입니다.
OrderId string Optional 주문 ID입니다.
PaidDateTime string Optional 결제 완료 시각입니다(yyyy-MM-dd HH:mm:ss).
PaidDateTimeMs long Optional 결제 완료 시각입니다(Unix epoch 밀리초 단위).
Price decimal Optional 결제 금액입니다.
ProductId string Optional 상품 ID(market_pid)입니다.
ProviderId RestorePurchaseProviderId Required 결제 수단 식별자입니다. 이 응답에서는 Steam이 반환됩니다.
PurchaseDateTime long Optional 구매 일시입니다(Unix epoch 밀리초 단위).
Quantity int Optional 구매 수량입니다.
StartedDateTime string Optional 결제 시작 시각입니다(yyyy-MM-dd HH:mm:ss).
StartedDateTimeMs long Optional 결제 시작 시각입니다(Unix epoch 밀리초 단위).
StoreTransactionId string Optional Steam 스토어 거래 ID(transid)입니다. 주문 ID와 다를 수 있습니다.
AxylReceipt string Optional 서버가 발급한 변조 검증용 봉인 영수증입니다. Steam은 이 값이 항상 내려오므로, 앱 서버에 전달하는 영수증 정보의 axylReceipt와 구매 완료 처리 요청의 AxylReceipt로 그대로 사용합니다.

응답 예시

// Success 분기에서 success.Data 예시
// success.Data.Restores[0].OrderId = "1000000012345"
// success.Data.Restores[0].ProductId = "com.example.gem.100"
// success.Data.Restores[0].ProviderId = RestorePurchaseProviderId.Steam
// success.Data.Restores[0].Price = 9900.0
// success.Data.Restores[0].Currency = "KRW"
// success.Data.Restores[0].Quantity = 1
// success.Data.Restores[0].PurchaseDateTime = 1717200000000
// success.Data.Restores[0].StoreTransactionId = "421799706624185538"

응답 상태

아래 표에는 PaymentsRestorePurchasesResult의 성공 결과와 이 메서드에서 정의한 도메인별 결과(Outcome)를 정리했습니다. 요청 수행이 불가능한 공통 실패(Failure)의 결과 모델과 처리 원칙은 공통 오류 처리를 참조하세요.

응답 케이스 설명 앱 클라이언트 대응
Success 복구 가능한 구매 목록이 반환되었습니다. 각 구매 건의 AxylReceipt를 앱 서버에 전달해 영수증 검증 진행 후 상품 지급
PaymentBadRequest 요청을 처리할 수 없습니다. 요청 값과 호출 조건을 점검
PaymentInvalidParameter 유효하지 않은 파라미터입니다(예: 필수값 누락). 필수 필드 값 확인 후 수정
PaymentResourceNotFound 결제 정보를 찾을 수 없습니다. 영수증·주문 번호·결제 상태를 확인
UnknownOutcome SDK가 알 수 없는 도메인별 결과입니다. 실패로 처리하고 결과 코드를 기록
Failure 공통 Failure입니다. 공통 오류 처리를 참조하세요. 공통 오류 처리 기준에 따라 처리

2. 영수증 검증 및 상품 지급

다시 획득한 영수증 AxylReceipt를 가지고 아래 과정을 다시 진행합니다. 복구한 구매는 이미 Steam 승인을 확인한 주문이므로 영수증 정보 준비 단계부터 시작하세요.

  1. 영수증 정보를 준비해 앱 서버에 전달합니다. 앱 서버가 보내는 영수증 검증 요청의 requestType은 2(구매 복원)로 설정합니다.
  2. 앱 서버가 Hive Axyl Server API로 영수증을 검증합니다.
  3. 검증이 완료되면 상품을 지급하고 구매 완료 처리를 합니다.