Version: Unity 6.0 (6000.0)
언어 : 한국어
스토어 가이드
유니버설 Windows 플랫폼

iOS & Mac 앱 스토어

확장 기능

앱 영수증 읽기

앱 영수증은 기기의 로컬 스토리지에 저장되며 다음과 같이 읽을 수 있습니다.

var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
string receipt = builder.Configure<IAppleConfiguration>().appReceipt;

결제 제한 사항 확인

앱 내 구매가 장치 설정으로 제한되어 있을 수도 있으며 아래의 방법으로 확인할 수 있습니다.

var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
bool canMakePayments = builder.Configure<IAppleConfiguration>().canMakePayments;

거래 복구

Apple 플랫폼에서는 사용자가 이전 거래를 검색해서 가져오려면 비밀번호를 입력해야 하므로 애플리케이션에서 사용자에게 비밀번호를 입력할 수 있도록 버튼을 제공해야 합니다. 이 프로세스 중에 사용자가 이미 소유하고 있는 모든 항목에 대해 IStoreListenerProcessPurchase 메서드가 호출됩니다.

/// <summary>
/// Your IStoreListener implementation of OnInitialized.
/// </summary>
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
    extensions.GetExtension<IAppleExtensions> ().RestoreTransactions (result => {
        if (result) {
            // This does not mean anything was restored,
            // merely that the restoration process succeeded.
        } else {
            // Restoration failed.
        }
    });
}

앱 영수증 새로 고침

Apple은 서버에서 새 앱 영수증을 가져오는 메커니즘을 제공하며, 일반적으로 로컬 스토리지에 현재 캐시된 영수증이 없을 때 사용되는 SKReceiptRefreshRequest를 제공합니다.

이 경우 사용자가 비밀번호를 입력해야 한다는 점을 참고해야 합니다.

Unity IAP에서는 다음과 같은 방법으로 이 메서드를 사용할 수 있습니다.

/// <summary>
/// Your IStoreListener implementation of OnInitialized.
/// </summary>
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
    extensions.GetExtension<IAppleExtensions> ().RefreshAppReceipt (receipt => {
        // This handler is invoked if the request is successful.
        // Receipt will be the latest app receipt.
        Console.WriteLine(receipt);
    },
    () => {
        // This handler will be invoked if the request fails,
        // such as if the network is unavailable or the user
        // enters the wrong password.
    });
}

Ask to Buy

iOS 8에는 Ask to Buy라는 새로운 보호자 관리 기능이 도입되었습니다.

Ask to Buy는 보호자의 승인을 위해 구매를 연기하는 기능입니다. 이 경우 Unity IAP는 앱에 다음과 같은 알림을 전송합니다.

/// This is called when Unity IAP has finished initialising.
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
    extensions.GetExtension<IAppleExtensions>().RegisterPurchaseDeferredListener(product => {
        Console.WriteLine(product.definition.id);
    });
}

Sandbox 앱 스토어에서 ‘Ask-to-Buy’ 시뮬레이션 활성화

아래 샘플 클래스는 Sandbox 앱 스토어에서 Ask-to-Buy 시뮬레이션을 활성화하기 위해 IAppleExtensions에 액세스하는 방법을 보여 줍니다.

using UnityEngine;
using UnityEngine.Purchasing;

public class AppleSimulateAskToBuy : MonoBehaviour {
    public void SetSimulateAskToBuy(bool shouldSimulateAskToBuy) {
        if (Application.platform == RuntimePlatform.IPhonePlayer) {
            IAppleExtensions extensions = IAPButton.IAPButtonStoreManager.Instance.ExtensionProvider.GetExtension<IAppleExtensions>();
            extensions.simulateAskToBuy = shouldSimulateAskToBuy;
        }
    }
}

구매가 승인 또는 거절되면 스토어의 노멀 ProcessPurchase 또는 OnPurchaseFailed 리스너 메서드가 호출됩니다.

거래 영수증 소비성 Ask to Buy 구매 항목이 앱 영수증에 표시되지 않는 경우가 있으며, 이 경우 해당 영수증을 통해 구매 항목을 확인할 수 없습니다. 하지만 iOS는 Ask to Buy를 비롯한 모든 구매 항목이 포함된 거래 영수증을 제공합니다. IAppleExtensions를 사용하여 주어진 Product의 최신 거래 영수증 문자열에 액세스합니다.

참고: Mac 빌드에서는 거래 영수증을 사용할 수 없습니다. Mac 빌드에서 거래 영수증을 요청하면 빈 문자열이 생깁니다.

#if UNITY_PURCHASING

using System;
using UnityEngine;
using UnityEngine.Purchasing;

public class AskToBuy : MonoBehaviour, IStoreListener
{
    // Unity IAP objects
    private IStoreController m_Controller;
    private IAppleExtensions m_AppleExtensions;

    public AskToBuy ()
    {
        var builder = ConfigurationBuilder.Instance (StandardPurchasingModule.Instance ());
        builder.AddProduct ("100_gold_coins", ProductType.Consumable, new IDs {
            { "100_gold_coins_google", GooglePlay.Name },
            { "100_gold_coins_mac", MacAppStore.Name }
        });

        UnityPurchasing.Initialize (this, builder);
    }

    /// <summary>
    /// This will be called when Unity IAP has finished initialising.
    /// </summary>
    public void OnInitialized (IStoreController controller, IExtensionProvider extensions)
    {
        m_Controller = controller;
        m_AppleExtensions = extensions.GetExtension<IAppleExtensions> ();

        // On Apple platforms we need to handle deferred purchases caused by Apple's Ask to Buy feature.
        // On non-Apple platforms this will have no effect; OnDeferred will never be called.
        m_AppleExtensions.RegisterPurchaseDeferredListener (OnDeferred);
    }

    /// <summary>
    /// This will be called when a purchase completes.
    /// </summary>
    public PurchaseProcessingResult ProcessPurchase (PurchaseEventArgs e)
    {
        if (Application.platform == RuntimePlatform.IPhonePlayer ||
            Application.platform == RuntimePlatform.tvOS) {
            string transactionReceipt = m_AppleExtensions.GetTransactionReceiptForProduct (e.purchasedProduct);
            Console.WriteLine (transactionReceipt);
            // Send transaction receipt to server for validation
        }    
        return PurchaseProcessingResult.Complete;
    }

    /// <summary>
    /// Called when Unity IAP encounters an unrecoverable initialization error.
    ///
    /// Note that this will not be called if Internet is unavailable; Unity IAP
    /// will attempt initialization until it becomes available.
    /// </summary>
    public void OnInitializeFailed (InitializationFailureReason error)
    {
    }

    /// <summary>
    /// Called when a purchase fails.
    /// </summary>
    public void OnPurchaseFailed (Product i, PurchaseFailureReason p)
    {
    }

    /// <summary>
    /// iOS Specific.
    /// This is called as part of Apple's 'Ask to buy' functionality,
    /// when a purchase is requested by a minor and referred to a parent
    /// for approval.
    ///
    /// When the purchase is approved or rejected, the normal purchase events
    /// will fire.
    /// </summary>
    /// <param name="item">Item.</param>
    private void OnDeferred (Product item)
    {
        Debug.Log ("Purchase deferred: " + item.definition.id);
    }
}

#endif // UNITY_PURCHASING

앱 영수증과 달리 거래 영수증은 로컬에서 확인할 수 없습니다. 대신 확인을 위해 영수증 문자열을 원격 서버로 전송해야 합니다. 이미 원격 서버를 사용하여 앱 영수증을 확인하는 경우 동일한 Apple 엔드포인트로 거래 영수증을 전송하여 JSON 리스폰스를 수신합니다.

JSON 리스폰스 예제:

{
    "receipt": {
        "original_purchase_date_pst": "2017-11-15 15:25:20 America/Los_Angeles",
        "purchase_date_ms": "1510788320209",
        "unique_identifier": "0ea7808637555b2c633eb07aa1cb0894c821a6f9",
        "original_transaction_id": "1000000352597239",
        "bvrs": "0",
        "transaction_id": "1000000352597239",
        "quantity": "1",
        "unique_vendor_identifier": "01B57C2E-9E91-42FF-9B0D-4983175D6694",
        "item_id": "1141751870",
        "original_purchase_date": "2017-11-15 23:25:20 Etc/GMT",
        "product_id": "100.gold.coins",
        "purchase_date": "2017-11-15 23:25:20 Etc/GMT",
        "is_trial_period": "false",
        "purchase_date_pst": "2017-11-15 15:25:20 America/Los_Angeles",
        "bid": "com.unity3d.unityiap.demo",
        "original_purchase_date_ms": "1510788320209"
    },
    "status": 0
}

Apple 프로모션 구매 인터셉트 Apple을 사용하면 앱의 제품 페이지를 통해 게임 내 구매를 홍보할 수 있습니다. 기존 인앱 구매와 달리 Apple 프로모션 구매는 iOS와 tvOS의 앱 스토어에서 직접 시작됩니다. 그런 다음 앱 스토어 앱을 실행하여 거래를 완료하거나 앱이 설치되어 있지 않은 경우 앱을 다운로드하라는 메시지가 표시됩니다.

IAppleConfiguration SetApplePromotionalPurchaseInterceptor 콜백 메서드는 Apple 프로모션 구매를 인터셉트합니다. 구매를 Apple에 전송하기 전에 이 콜백을 사용하여 보호자 승인 절차를 표시하거나 분석 이벤트를 전송하거나 다른 함수를 수행할 수 있습니다. 콜백은 사용자가 구매하려고 시도한 Product를 사용합니다. 프로모션 구매를 계속하려면 IAppleExtensions.ContinuePromotionalPurchases()를 호출해야 합니다. 그러면 대기열 결제가 시작됩니다.

콜백을 설정하지 않으면 홍보 구매가 즉시 진행되고 그 결과로 ProcessPurchase를 호출합니다.

참고: 다른 플랫폼에서 이 API를 호출하면 아무런 영향을 미치지 않습니다.

private IAppleExtensions m_AppleExtensions;

public void Awake() {
    var module = StandardPurchasingModule.Instance();
    var builder = ConfigurationBuilder.Instance(module);
        // On iOS and tvOS we can intercept promotional purchases that come directly from
        // the App Store.
        // On other platforms this will have no effect; OnPromotionalPurchase will never be
        // called.
    builder.Configure<IAppleConfiguration>().
     SetApplePromotionalPurchaseInterceptorCallback(OnPromotionalPurchase);
    Debug.Log("Setting Apple promotional purchase interceptor callback");
}

public void OnInitialized(IStoreController controller, IExtensionProvider extensions) {
    m_AppleExtensions = extensions.GetExtension<IAppleExtensions>();
    foreach (var item in controller.products.all) {
        if (item.availableToPurchase) {                
            // Set all these products to be visible in the user's App Store
            m_AppleExtensions.SetStorePromotionVisibility(item, AppleStorePromotionVisibility.Show);
        }
    }
}

private void OnPromotionalPurchase(Product item) {
    Debug.Log("Attempted promotional purchase: " + item.definition.id);
    // Promotional purchase has been detected. 
    // Handle this event by, e.g. presenting a parental gate.
    // Here, for demonstration purposes only, we will wait five seconds before continuing 
    // the purchase.
    StartCoroutine(ContinuePromotionalPurchases());
}

private IEnumerator ContinuePromotionalPurchases() {
    Debug.Log("Continuing promotional purchases in 5 seconds");
    yield return new WaitForSeconds(5);
    Debug.Log("Continuing promotional purchases now");
    m_AppleExtensions.ContinuePromotionalPurchases (); // iOS and tvOS only
}

테스트

Apple 스토어에서 테스트를 진행하려면 iTunes Connect에서 생성할 수 있는 iTunes Connect 테스트 계정을 사용해야 합니다.

iOS 기기나 노트북에서 앱 스토어 로그아웃을 한 후 애플리케이션을 실행하고 구매나 거래 복원 시도를 하면 로그인 화면이 나타납니다.

NoProductsAvailable로 인해 초기화 실패를 수신하면 다음 체크리스트를 확인하십시오.

  • iTunes Connect 제품 식별자가 Unity IAP에 제공된 제품 식별자와 정확하게 일치해야 합니다.
  • iTunes Connect 애플리케이션에 대해 애플리케이션 내 구매가 활성화되어 있어야 합니다.
  • 해당 상품이 iTunes Connect에서 판매 중이어야 합니다.
  • iTunes Connect 제품을 새로 생성한 경우 구매가 가능하려면 몇 시간이 소요될 수 있습니다.
  • 최신 iTunes Connect 개발자 약관에 동의하고 유효한 계좌 정보를 등록해야 합니다.

Mac 앱 스토어

데스크톱 Mac 빌드를 빌드하는 경우 Unity의 빌드 설정 내에서 Mac App Store validation을 선택해야 합니다.

앱을 빌드한 후에는 info.plist 파일에 번들 식별자와 버전 문자열을 업데이트해야 합니다. .app 파일을 오른쪽 클릭하고 show package contents를 클릭하고, info.plist 파일을 찾아 CFBundleIdentifier 문자열을 애플리케이션의 번들 식별자로 업데이트합니다.

그런 다음 애플리케이션에 서명하고 패키징하고 설치해야 합니다. OSX 터미널에서 다음 커맨드를 실행해야 합니다.

codesign -f --deep -s "3rd Party Mac Developer Application: " your.app/Contents/Plugins/unitypurchasing.bundle
codesign -f --deep -s "3rd Party Mac Developer Application: " your.app
productbuild --component your.app /Applications --sign "3rd Party Mac Developer Installer: " your.pkg

번들에 서명하려면 먼저 Contents.meta 파일이 your.app/Contents/Plugins/unitypurchasing.bundle/Contents.meta에 존재하는 경우 제거해야 할 수 있습니다.

패키지를 올바르게 설치하려면 새로 생성된 패키지를 실행하기 전에 언패키지된 .app 파일을 삭제해야 합니다.

그런 다음 Applications 폴더에서 앱을 실행해야 합니다. 이 작업을 처음 수행하면 iTunes 계정 세부 정보를 입력하라는 메시지가 표시됩니다. 이 경우 iTunes Connect 테스트 사용자 계정 로그인을 입력해야 합니다. 그러면 샌드박스 환경에서 구매를 테스트할 수 있습니다.


  • 2018–05–30
  • 2017.3에 Ask to Buy, 거래 영수증, 영수증 인터셉트 추가함 NewIn20173
스토어 가이드
유니버설 Windows 플랫폼