Share via


앱 내 제품의 큰 카탈로그를 관리하는 방법(HTML)

[ 이 문서는 Windows 런타임 앱을 작성하는 Windows에서 8.x 및 Windows Phone 8.x 개발자를 대상으로 합니다. Windows 10용으로 개발하는 경우에는 최신 설명서를 참조하세요.]

Windows 8.1 및 Windows Phone 8.1에서는 개발자 계정당 200개 제품 목록이라는 스토어 제한을 넘어서 확장되는 앱 내 제품 카탈로그를 제공하는 앱에 대한 새로운 솔루션을 제공합니다. 이 솔루션을 사용하여 카탈로그 내에서 각각 수백 개의 제품을 나타낼 수 있는 특정 기준 가격에 대한 소수의 제품 항목을 만들 수 있습니다.

이 접근 권한 값을 사용하기 위해 스토어에 나열된 앱 내 제품과 관련된 앱 정의 판매를 구매하는 새로운 RequestProductPurchaseAsync 메서드 오버로드를 제공했습니다. 호출하는 동안 앱은 판매와 제품 연결을 지정할 뿐만 아니라 큰 카탈로그 판매 세부 정보를 포함하는 ProductPurchaseDisplayProperties 개체도 전달해야 합니다. 이러한 세부 정보를 제공하지 않으면 나열된 제품에 대한 세부 정보가 대신 사용됩니다.

스토어는 결과 PurchaseResults에서 구매 요청의 OfferId만 사용합니다. 이 프로세스는 스토어에 앱 내 제품을 나열할 때 원래 제공된 정보를 직접 수정하지 않습니다.

알아야 할 사항

기술

사전 요구 사항

  • 이 항목에서는 스토어에 나열되는 단일 앱 내 제품을 사용하여 여러 가지 앱 내 제품을 표현하는 스토어 지원에 대해 설명합니다. 앱 내 제품에 익숙하지 않은 경우 라이선스 정보 및 스토어에 앱 내 제품을 제대로 나열하는 방법을 알아보려면 앱에서 바로 제품 구매 사용을 검토하세요.

  • 또한 이 항목에서는 MSDN 코드 갤러리에서 사용할 수 있는 체험 앱 및 앱에서 바로 구매 샘플에 제공된 코드 예제를 참조합니다. 이 샘플은 Windows 런타임 앱에 제공된 다양한 화폐화 옵션을 실습할 수 있는 좋은 방법입니다.

  • 새 앱 내 제품을 처음 코딩하고 테스트할 때는 CurrentApp 개체 대신 CurrentAppSimulator 개체를 사용해야 합니다. 이렇게 하면 라이브 서버를 호출하는 대신 라이선스 서버에 대한 호출을 시뮬레이션하여 라이선스 논리를 확인할 수 있습니다. 이렇게 하려면 %userprofile%\AppData\local\packages\<package name>\LocalState\Microsoft\Windows Store\ApiData에 있는 "WindowsStoreProxy.xml" 파일을 사용자 지정해야 합니다. 처음으로 앱이 실행될 때 Microsoft Visual Studio 시뮬레이터에서 이 파일을 만들거나 런타임에 사용자 지정 파일을 로드할 수도 있습니다. 자세한 내용은 CurrentAppSimulator 설명서를 참조하세요.

앱 내 제품을 위한 구매 요청 만들기

큰 카탈로그 내에서 특정 제품을 위한 구매 요청은 앱 내에서의 다른 모든 구매 요청과 거의 동일한 방식으로 처리됩니다. 앱은 새로운 RequestProductPurchaseAsync 메서드 오버로드를 호출할 때 OfferId와 앱 내 제품 이름으로 채워진 ProductPurchaseDisplayProperties 개체를 모두 제공합니다.

function purchaseAndFulfillOfferAsProduct() {
    var offerId = "1234";
    var displayPropertiesName = "MusicOffer1";
    var displayProperties = new ProductPurchaseDisplayProperties(displayPropertiesName);

    currentApp.requestProductPurchaseAsync("product1", offerId, displayProperties).done(
        function (purchaseResults) {
            if (purchaseResults.status === ProductPurchaseStatus.succeeded) {
                grantFeatureLocally("product1", purchaseResults.transactionId);
                fulfillProduct1("product1", purchaseResults.transactionId, purchaseResults.offerId);
            } else if (purchaseResults.status === ProductPurchaseStatus.notFulfilled) {
                if (isNotLocallyFulfilled("product1", purchaseResults.transactionId)) {
                    grantFeatureLocally("product1", purchaseResults.transactionId);
                }
                fulfillProduct1("product1", purchaseResults.transactionId, purchaseResults.offerId);
            } else if (purchaseResults.status === ProductPurchaseStatus.notPurchased) {
                log("Product 1 was not purchased.", "sample", "status");
            }
        },
        function () {
            log("Unable to buy product 1.", "sample", "error");
        });
}

앱 내 제품의 이행 보고

판매가 로컬에서 이행되는 즉시 앱은 제품 이행을 스토어에 보고해야 합니다. 큰 카탈로그 시나리오에서 앱이 판매 이행을 보고하지 않을 경우 사용자는 동일한 스토어 제품 목록을 사용하여 앱 내 제품을 구매할 수 없습니다.

앞에서 설명한 대로 스토어는 제공된 판매 정보만 사용하여 PurchaseResults를 채우며, 큰 카탈로그 판매와 스토어 제품 목록 간에 영구 연결을 만들지 않습니다. 따라서 제품에 대한 사용자 자격을 추적하고 제품 관련 컨텍스트(예제: 구매할 항목의 이름 또는 항목에 대한 세부 정보)를 RequestProductPurchaseAsync 작업 외부의 사용자에게 제공해야 합니다.

다음 코드에서는 이행 호출과 특정 판매 정보가 삽입되는 UI 메시지 패턴을 보여줍니다. 특정 제품 정보가 없을 경우 예제에서는 제품 ListingInformation의 정보를 사용합니다.

function fulfillProduct1(productId, transactionId, offerId) {
    var displayPropertiesName = document.getElementById("displayPropertiesName").value;
    if (displayPropertiesName === "") {
        displayPropertiesName = product1ListingName;
    }
    var offerIdMsg = " with offer id " + offerId;
    if (!offerId) {
        offerIdMsg = " with no offer id";
    }

    currentApp.reportConsumableFulfillmentAsync(productId, transactionId).done(
        function (result) {
            switch (result) {
                case FulfillmentResult.succeeded:
                    log("You bought and fulfilled " + displayPropertiesName  + offerIdMsg, "sample", "status");
                    break;
                case FulfillmentResult.nothingToFulfill:
                    log("There is no purchased product 1 to fulfill.", "sample", "status");
                    break;
                case FulfillmentResult.purchasePending:
                    log("You bought product 1. The purchase is pending so we cannot fulfill the product.", "sample", "status");
                    break;
                case FulfillmentResult.purchaseReverted:
                    log("You bought product 1. But your purchase has been reverted.", "sample", "status");
                    // Since the user's purchase was revoked, they got their money back.
                    // You may want to revoke the user's access to the consumable content that was granted.
                    break;
                case FulfillmentResult.serverError:
                    log("You bought product 1. There was an error when fulfilling.", "sample", "status");
                    break;
            }
        },
        function (error) {
            log("You bought Product 1. There was an error when attempting to fulfill.", "sample", "error");
        });
}

관련 항목

체험 앱 및 앱에서 바로 구매 샘플

앱에서 바로 제품 구매 사용

앱에서 바로 소모성 제품 구매 사용

앱 설명

RequestProductPurchaseAsync

ProductPurchaseDisplayProperties