Skip to content

인앱 결제

앱인토스 유니티 SDK를 사용하면 C# 코드만으로 인앱 결제를 연동할 수 있어요.

Unity SDK의 인앱 결제 API는 앱인토스 WebView SDK IAP 객체와 같은 주문·상품 지급 완료 모델을 사용해요. 함수명만 Unity C# 환경에 맞게 IAP.getPendingOrders() 대신 AIT.IAPGetPendingOrders()처럼 제공돼요.


결제 플로우

정상 플로우

  1. IAPGetProductItemList() — 상품 목록 조회
  2. IAPCreateOneTimePurchaseOrder() — 구매 주문 생성
    • ProcessProductGrant 콜백에서 상품 지급 또는 권한 부여 후 true 반환
    • SDK가 자동으로 IAPCompleteProductGrant를 호출해서 주문을 완료 처리해요

참고하세요

결제 성공 후 30초 내에 ProcessProductGrant 콜백이 호출되지 않거나 해당 콜백의 결과가 true가 아닌 경우, {appName}에 문제가 생겼어요. 환불을 신청해 주세요 페이지가 노출될 수 있어요.

복구 플로우

앱 크래시나 네트워크 끊김 등으로 ProcessProductGrant 콜백이 호출되지 않은 경우에 사용해요.

  1. IAPGetPendingOrders() — 미결 주문 조회
  2. 각 주문에 대해 상품 지급 또는 권한 부여 수행
  3. IAPCompleteProductGrant() — 상품 지급 완료 처리

API

API설명
AIT.IAPGetProductItemList()등록된 상품 목록을 조회해요
AIT.IAPCreateOneTimePurchaseOrder()일회성 구매 주문을 생성해요
AIT.IAPGetPendingOrders()결제는 완료됐지만 상품이 아직 지급되지 않은 미결 주문을 조회해요
AIT.IAPGetCompletedOrRefundedOrders()상품 지급이 완료됐거나 환불된 주문을 조회해요
AIT.IAPCompleteProductGrant()미결 주문의 상품 지급 또는 권한 부여 완료를 처리해요

주문 조회 API 구분

AIT.IAPGetPendingOrders()AIT.IAPGetCompletedOrRefundedOrders()는 용도가 달라요.

API언제 사용하나요
AIT.IAPGetPendingOrders()결제는 완료됐지만 상품이 아직 지급되지 않은 주문을 복구할 때 사용해요. 앱 시작 시 미결 주문을 확인하고, 상품 지급 후 AIT.IAPCompleteProductGrant()를 호출해 주세요.
AIT.IAPGetCompletedOrRefundedOrders()상품 지급까지 완료된 주문이나 환불된 주문 이력을 확인할 때 사용해요. 미결 주문은 이 결과에 포함되지 않아요.

결제 완료 이벤트를 받지 못했거나 주문 상태를 서버에서 확인해야 하는 경우에는 주문 상태 조회 API를 함께 사용할 수 있어요. 이 API를 사용하려면 토스 로그인 연동이 필요해요.


샘플 코드

상품 목록 조회

csharp
using AppsInToss;
using UnityEngine;

public class IAPExample : MonoBehaviour
{
    async void Start()
    {
        try
        {
            var result = await AIT.IAPGetProductItemList();
            foreach (var product in result.Products)
            {
                Debug.Log($"{product.DisplayName} ({product.Sku}) - {product.DisplayAmount}");
            }
        }
        catch (AITException ex)
        {
            Debug.LogError($"상품 조회 실패: {ex.ErrorCode} - {ex.Message}");
        }
    }
}

구매 주문 생성

csharp
using System;
using AppsInToss;
using UnityEngine;

public class IAPPurchase : MonoBehaviour
{
    private Action _purchaseDisposer;

    public void Purchase(string sku)
    {
        _purchaseDisposer?.Invoke();

        var options = new IapCreateOneTimePurchaseOrderOptionsOptions
        {
            Sku = sku,
            ProcessProductGrant = (data) =>
            {
                // 상품 지급 또는 권한 부여 처리
                Debug.Log($"상품 지급: {data}");
                bool grantSuccess = GrantProduct(data);

                // true를 반환하면 SDK가 자동으로 IAPCompleteProductGrant를 호출해요
                return grantSuccess;
            }
        };

        _purchaseDisposer = AIT.IAPCreateOneTimePurchaseOrder(
            options: options,
            onEvent: (result) =>
            {
                Debug.Log($"구매 완료: orderId={result.Data?.OrderId}, amount={result.Data?.DisplayAmount}");
            },
            onError: (error) =>
            {
                Debug.LogError($"구매 실패: {error.ErrorCode} - {error.Message}");
            }
        );
    }

    private bool GrantProduct(object data)
    {
        // 실제 게임 내 상품 지급 로직을 구현해요
        return true;
    }

    private void OnDestroy()
    {
        _purchaseDisposer?.Invoke();
    }
}

미결 주문 복구

앱 크래시 등으로 상품 지급이 완료되지 않은 주문을 복구하는 예제예요.

csharp
using AppsInToss;
using UnityEngine;

public class IAPRecovery : MonoBehaviour
{
    async void Start()
    {
        await RecoverPendingOrders();
    }

    private async System.Threading.Tasks.Task RecoverPendingOrders()
    {
        try
        {
            // 미결 주문 조회
            var result = await AIT.IAPGetPendingOrders();

            if (result.Orders == null || result.Orders.Length == 0)
            {
                Debug.Log("복구할 주문이 없어요");
                return;
            }

            foreach (var order in result.Orders)
            {
                // 상품 지급
                GrantProduct(order.Sku);

                // 지급 완료 처리
                var args = new IAPCompleteProductGrantArgs_0
                {
                    Params = new IAPCompleteProductGrantArgs_0Params
                    {
                        OrderId = order.OrderId
                    }
                };

                bool success = await AIT.IAPCompleteProductGrant(args);
                Debug.Log($"주문 {order.OrderId} 복구 {(success ? "성공" : "실패")}");
            }
        }
        catch (AITException ex)
        {
            Debug.LogError($"주문 복구 실패: {ex.ErrorCode} - {ex.Message}");
        }
    }

    private void GrantProduct(string sku)
    {
        // SKU에 따른 상품 지급 로직
        Debug.Log($"상품 지급: {sku}");
    }
}

완료·환불 주문 조회

이미 상품 지급이 완료된 주문이나 환불된 주문 이력을 확인하는 예제예요. 미결 주문 복구에는 사용하지 않아요.

csharp
using AppsInToss;
using UnityEngine;

public class IAPOrderHistory : MonoBehaviour
{
    async void Start()
    {
        await FetchCompletedOrRefundedOrders();
    }

    private async System.Threading.Tasks.Task FetchCompletedOrRefundedOrders()
    {
        try
        {
            var result = await AIT.IAPGetCompletedOrRefundedOrders();

            if (result.Orders == null || result.Orders.Length == 0)
            {
                Debug.Log("조회된 완료·환불 주문이 없어요");
                return;
            }

            foreach (var order in result.Orders)
            {
                Debug.Log($"주문 상태: orderId={order.OrderId}, sku={order.Sku}, status={order.Status}");
            }
        }
        catch (AITException ex)
        {
            Debug.LogError($"완료·환불 주문 조회 실패: {ex.ErrorCode} - {ex.Message}");
        }
    }
}

주의사항

TIP

  • 인앱 결제 상품은 반드시 ProcessProductGrant 콜백에서 상품 지급 또는 권한 부여를 처리하고 true를 반환해야 해요.
  • false를 반환하거나 콜백이 호출되지 않으면 주문이 미결 상태로 남아요.
  • 앱 시작 시 IAPGetPendingOrders()로 미결 주문을 확인하는 것을 권장해요.
  • 실제 결제는 샌드박스 앱에서 테스트할 수 없어요. 토스 앱에서 QR 코드를 통해 테스트해 주세요.