Windows.ApplicationModel.Store 네임스페이스를 사용하는 앱 내 구매 및 평가판
Windows.ApplicationModel.Store 네임스페이스의 멤버를 사용하여 앱 내 구매 및 평가판 기능을 UWP(유니버설 Windows 플랫폼) 앱에 추가하여 앱으로 수익을 창출할 수 있습니다. 이러한 API는 앱의 라이선스 정보에 대한 액세스도 제공합니다.
이 섹션의 문서에서는 몇 가지 일반적인 시나리오에 대해 Windows.ApplicationModel.Store 네임스페이스의 멤버를 사용하기 위한 자세한 지침 및 코드 예시를 제공합니다. UWP 앱의 앱 내 구매와 관련된 기본 개념에 대한 개요는 앱 내 구매 및 평가판을 참조하세요. Windows.ApplicationModel.Store 네임스페이스를 사용하여 평가판 및 앱 내 구매를 구현하는 방법을 보여 주는 전체 샘플은 Store 샘플을 참조하세요.
중요
Windows.ApplicationModel.Store 네임스페이스는 새 기능에서 더 이상 업데이트되지 않습니다. 프로젝트가 Visual Studio에서 Windows 10 Anniversary Edition(10.0, 빌드 14393) 이상 릴리스를 대상으로 하는 경우(즉, Windows 10 버전 1607 이상을 대상으로 함) 대신 Windows.Services.Store 네임스페이스를 사용하는 것이 좋습니다. 자세한 정보는 앱 내 구매 및 평가판을 참조하세요. Windows.ApplicationModel.Store 네임스페이스는 데스크톱 브리지를 사용하는 Windows 데스크톱 애플리케이션 또는 파트너 센터에서 개발 샌드박스를 사용하는 앱 또는 게임(예: Xbox Live와 통합되는 모든 게임)에서 지원되지 않습니다. 해당 제품은 Windows.Services.Store 네임스페이스를 사용하여 앱 내 구매 및 평가판을 구현해야 합니다.
CurrentApp 및 CurrentAppSimulator 클래스 시작하기
Windows.ApplicationModel.Store 네임스페이스에 대한 기본 진입점은 CurrentApp 클래스입니다. 이 클래스는 현재 앱과 사용 가능한 추가 기능에 대한 정보 가져오기, 현재 앱 또는 추가 기능에 대한 라이선스 정보 가져오기, 현재 사용자를 위한 앱 또는 추가 기능 구매하기, 기타 작업에 사용할 수 있는 고정 속성 및 메서드를 제공합니다.
CurrentApp 클래스는 Microsoft Store에서 해당 데이터를 가져오므로 개발자 계정이 있어야 하며 앱을 Store에 게시해야 앱에서 이 클래스를 성공적으로 사용할 수 있습니다. Store에 앱을 제출하기 전에 이 클래스의 시뮬레이션된 버전인 CurrentAppSimulator로 코드를 테스트할 수 있습니다. 앱을 테스트한 후 Microsoft Store에 제출하기 전에 CurrentAppSimulator 인스턴스를 CurrentApp으로 바꾸어야 합니다. 앱이 CurrentAppSimulator를 사용하는 경우 인증에 실패합니다.
CurrentAppSimulator를 사용하는 경우, 앱 라이선스 및 앱 내 제품의 초기 상태가 WindowsStoreProxy.xml 개발 컴퓨터의 로컬 파일에 설명되어 있습니다. 이 파일에 대한 자세한 정보는 CurrentAppSimulator에서 WindowsStoreProxy.xml 파일 사용하기를 참조하세요.
CurrentApp 및 CurrentAppSimulator를 사용하여 수행할 수 있는 일반적인 작업에 대한 자세한 정보는 다음의 문서를 참조하세요.
항목 | 설명 |
---|---|
평가판의 기능 제외 또는 제한 | 고객이 평가판 기간 동안 앱을 무료로 사용할 수 있도록 하는 경우 평가판 기간 동안 일부 기능을 제외하거나 제한하여 고객이 앱의 정식 버전으로 업그레이드하도록 유도할 수 있습니다. |
앱 내 제품 구매 사용하기 | 앱이 무료인지 여부에 관계없이 앱 내에서 바로 콘텐츠, 다른 앱 또는 새로운 앱 기능(게임의 다음 단계 잠금 해제 등)을 판매할 수 있습니다. 여기서 앱에서 이러한 제품을 사용하도록 설정하는 방법을 볼 수 있습니다. |
앱 내 소모성 제품 구매 사용하기 | Store 상거래 플랫폼을 통해 소모성 앱 내 제품(다시 구입, 사용 및 구매할 수 있는 항목)을 제안하여 강력하고 신뢰할 수 있는 구매 환경을 고객에게 제공합니다. 이는 특정 파워업을 구매하는 데 사용할 수 있는 게임 내 통화(금, 동전 등)에 특히 유용합니다. |
앱 내 구매 제품의 큰 카탈로그 관리하기 | 앱에서 큰 앱 내 제품 카탈로그를 제공하는 경우 필요에 따라 이 항목에 설명된 프로세스를 따라 카탈로그를 관리할 수 있습니다. |
확인 메일을 사용하여 제품 구매 검증하기 | 제품 구매를 성공적으로 이행한 각 Microsoft Store 거래에서 고객에게 나열된 제품 및 통화 비용에 대한 정보를 제공하는 거래 영수증을 선택적으로 반환할 수 있습니다. 이 정보에는 사용자가 앱을 구매했거나 Microsoft Store에서 앱 내 구매 제품을 구매했는지 앱이 확인해야 하는 경우 액세스할 수 있습니다. |
CurrentAppSimulator에서 WindowsStoreProxy.xml 파일 사용하기
CurrentAppSimulator를 사용하는 경우, 앱 라이선스 및 앱 내 제품의 초기 상태가 WindowsStoreProxy.xml 개발 컴퓨터의 로컬 파일에 설명되어 있습니다. 예를 들어 라이선스를 구입하거나 앱 내 구매를 처리하여 앱 상태를 변경하는 CurrentAppSimulator 메서드는 메모리에서 CurrentAppSimulator4 개체의 상태만 업데이트합니다. WindowsStoreProxy.xml의 내용은 변경되지 않습니다. 앱이 다시 시작되면 라이선스 상태는 WindowsStoreProxy.xml에 설명된 내용으로 되돌려집니다.
WindowsStoreProxy.xml 파일은 기본적으로 %UserProfile%\AppData\Local\Packages\<app package folder>\LocalState\Microsoft\Windows Store\ApiData에 생성됩니다. 이 파일을 편집하여 CurrentAppSimulator 속성에서 시뮬레이션하려는 시나리오를 정의할 수 있습니다.
이 파일의 값을 수정할 수 있지만 CurrentAppSimulator가 대신 사용할 수 있도록 고유한 WindowsStoreProxy.xml 파일(Visual Studio 프로젝트의 데이터 폴더)을 만드는 것이 좋습니다. 트랜잭션을 시뮬레이션할 때 ReloadSimulatorAsync를 호출하여 파일을 로드합니다. ReloadSimulatorAsync를 호출하여 고유한 WindowsStoreProxy.xml 파일을 로드하지 않으면 CurrentAppSimulator는 기본 WindowsStoreProxy.xml 파일을 만들거나 로드(덮어쓰지 않음)합니다.
참고
CurrentAppSimulator는 ReloadSimulatorAsync가 완료되기 전에는 완전히 초기화되지 않습니다. 또한 ReloadSimulatorAsync는 비동기 메서드이므로 다른 스레드에서 초기화되는 동안 한 스레드에서 CurrentAppSimulator를 쿼리하는 경합 상태를 방지하기 위해 주의해야 합니다. 한 가지 방법은 플래그를 사용하여 초기화가 완료되었음을 나타내는 것입니다. Microsoft Store에서 설치된 앱은 CurrentAppSimulator 대신 CurrentApp을 사용해야 하며, 이 경우 ReloadSimulatorAsync가 호출되지 않으므로 방금 언급한 경합 상태가 적용되지 않습니다. 따라서 두 사례(비동기적 및 동기적)에서 모두 작동하도록 코드를 설계해야 합니다.
예시
이 예시는 WindowsStoreProxy.xml 파일(UTF-16 인코딩)로, 2015년 1월 19일 05:00(UTC)에 만료되는 평가판 모드의 앱을 설명합니다.
<?xml version="1.0" encoding="UTF-16"?>
<CurrentApp>
<ListingInformation>
<App>
<AppId>00001111-aaaa-2222-bbbb-3333cccc4444</AppId>
<LinkUri>http://apps.windows.microsoft.com/app/00001111-aaaa-2222-bbbb-3333cccc4444</LinkUri>
<CurrentMarket>en-US</CurrentMarket>
<AgeRating>3</AgeRating>
<MarketData xml:lang="en-us">
<Name>App with a trial license</Name>
<Description>Sample app for demonstrating trial license management</Description>
<Price>4.99</Price>
<CurrencySymbol>$</CurrencySymbol>
</MarketData>
</App>
</ListingInformation>
<LicenseInformation>
<App>
<IsActive>true</IsActive>
<IsTrial>true</IsTrial>
<ExpirationDate>2015-01-19T05:00:00.00Z</ExpirationDate>
</App>
</LicenseInformation>
<Simulation SimulationMode="Automatic">
<DefaultResponse MethodName="LoadListingInformationAsync_GetResult" HResult="E_FAIL"/>
</Simulation>
</CurrentApp>
다음 예시는 구매한 앱을 설명하는 WindowsStoreProxy.xml 파일(UTF-16 인코딩)이며, 2015년 1월 19일 UTC(05:00)에 만료되며 앱 내 구매가 가능한 기능을 포함합니다.
<?xml version="1.0" encoding="utf-16" ?>
<CurrentApp>
<ListingInformation>
<App>
<AppId>11112222-bbbb-3333-cccc-4444dddd5555</AppId>
<LinkUri>http://apps.windows.microsoft.com/app/11112222-bbbb-3333-cccc-4444dddd5555</LinkUri>
<CurrentMarket>en-us</CurrentMarket>
<AgeRating>3</AgeRating>
<MarketData xml:lang="en-us">
<Name>App with several in-app products</Name>
<Description>Sample app for demonstrating an expiring in-app product and a consumable in-app product</Description>
<Price>5.99</Price>
<CurrencySymbol>$</CurrencySymbol>
</MarketData>
</App>
<Product ProductId="feature1" LicenseDuration="10" ProductType="Durable">
<MarketData xml:lang="en-us">
<Name>Expiring Item</Name>
<Price>1.99</Price>
<CurrencySymbol>$</CurrencySymbol>
</MarketData>
</Product>
<Product ProductId="consumable1" LicenseDuration="0" ProductType="Consumable">
<MarketData xml:lang="en-us">
<Name>Consumable Item</Name>
<Price>2.99</Price>
<CurrencySymbol>$</CurrencySymbol>
</MarketData>
</Product>
</ListingInformation>
<LicenseInformation>
<App>
<IsActive>true</IsActive>
<IsTrial>false</IsTrial>
</App>
<Product ProductId="feature1">
<IsActive>true</IsActive>
<ExpirationDate>2015-01-19T00:00:00.00Z</ExpirationDate>
</Product>
</LicenseInformation>
<ConsumableInformation>
<Product ProductId="consumable1" TransactionId="00000001-0000-0000-0000-000000000000" Status="Active"/>
</ConsumableInformation>
</CurrentApp>
스키마
이 섹션에서는 WindowsStoreProxy.xml 파일의 구조를 정의하는 XSD 파일을 나열합니다. WindowsStoreProxy.xml 파일로 작업할 때 이 스키마를 Visual Studio의 XML 편집기에서 적용하려면 다음을 수행합니다.
- Visual Studio에서 WindowsStoreProxy.xml 파일을 엽니다.
- XML 메뉴에서 스키마 만들기를 클릭합니다. 그러면 XML 파일의 내용을 기반으로 임시 WindowsStoreProxy.xsd 파일이 생성됩니다.
- 해당 .xsd 파일의 내용을 아래의 스키마로 바꿉니다.
- 여러 앱 프로젝트에 적용할 수 있는 위치에 파일을 저장합니다.
- Visual Studio에서 WindowsStoreProxy.xml 파일로 전환합니다.
- XML 메뉴에서 스키마를 클릭한 다음 WindowsStoreProxy.xsd 파일 목록에서 행을 찾습니다. 파일의 위치가 원하는 위치가 아니면(예: 임시 파일이 계속 표시되는 경우) 추가를 클릭합니다. 오른쪽 파일로 이동한 다음 확인을 클릭합니다. 이제 목록에 해당 파일이 표시됩니다. 확인 표시가 해당 스키마에 대한 사용 열에 나타나는지 확인합니다.
이 작업을 완료하면 스키마가 WindowsStoreProxy.xml를 편집한 내용에 적용됩니다. 자세한 정보는 사용할 XML 스키마를 선택하는 방법을 참조하세요.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xs:element name="CurrentApp" type="CurrentAppDefinition"></xs:element>
<xs:complexType name="CurrentAppDefinition">
<xs:sequence>
<xs:element name="ListingInformation" type="ListingDefinition" minOccurs="1" maxOccurs="1"/>
<xs:element name="LicenseInformation" type="LicenseDefinition" minOccurs="1" maxOccurs="1"/>
<xs:element name="ConsumableInformation" type="ConsumableDefinition" minOccurs="0" maxOccurs="1"/>
<xs:element name="Simulation" type="SimulationDefinition" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="ResponseCodes">
<xs:restriction base="xs:string">
<xs:enumeration value="S_OK">
<xs:annotation>
<xs:documentation>0x00000000</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="E_INVALIDARG">
<xs:annotation>
<xs:documentation>0x80070057</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="E_CANCELLED">
<xs:annotation>
<xs:documentation>0x800704C7</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="E_FAIL">
<xs:annotation>
<xs:documentation>0x80004005</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="E_OUTOFMEMORY">
<xs:annotation>
<xs:documentation>0x8007000E</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="ERROR_ALREADY_EXISTS">
<xs:annotation>
<xs:documentation>0x800700B7</xs:documentation>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ConsumableStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="Active"/>
<xs:enumeration value="PurchaseReverted"/>
<xs:enumeration value="PurchasePending"/>
<xs:enumeration value="ServerError"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="StoreMethodName">
<xs:restriction base="xs:string">
<xs:enumeration value="RequestAppPurchaseAsync_GetResult" id="RPPA"/>
<xs:enumeration value="RequestProductPurchaseAsync_GetResult" id="RFPA"/>
<xs:enumeration value="LoadListingInformationAsync_GetResult" id="LLIA"/>
<xs:enumeration value="ReportConsumableFulfillmentAsync_GetResult" id="RPFA"/>
<xs:enumeration value="LoadListingInformationByKeywordsAsync_GetResult" id="LLIKA"/>
<xs:enumeration value="LoadListingInformationByProductIdAsync_GetResult" id="LLIPA"/>
<xs:enumeration value="GetUnfulfilledConsumablesAsync_GetResult" id="GUC"/>
<xs:enumeration value="GetAppReceiptAsync_GetResult" id="GARA"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="SimulationMode">
<xs:restriction base="xs:string">
<xs:enumeration value="Interactive"/>
<xs:enumeration value="Automatic"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="ListingDefinition">
<xs:sequence>
<xs:element name="App" type="AppListingDefinition"/>
<xs:element name="Product" type="ProductListingDefinition" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ConsumableDefinition">
<xs:sequence>
<xs:element name="Product" type="ConsumableProductDefinition" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AppListingDefinition">
<xs:sequence>
<xs:element name="AppId" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="LinkUri" type="xs:anyURI" minOccurs="1" maxOccurs="1"/>
<xs:element name="CurrentMarket" type="xs:language" minOccurs="1" maxOccurs="1"/>
<xs:element name="AgeRating" type="xs:unsignedInt" minOccurs="1" maxOccurs="1"/>
<xs:element name="MarketData" type="MarketSpecificAppData" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MarketSpecificAppData">
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="Description" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="Price" type="xs:float" minOccurs="1" maxOccurs="1"/>
<xs:element name="CurrencySymbol" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="CurrencyCode" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:attribute ref="xml:lang" use="required"/>
</xs:complexType>
<xs:complexType name="MarketSpecificProductData">
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="Price" type="xs:float" minOccurs="1" maxOccurs="1"/>
<xs:element name="CurrencySymbol" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="CurrencyCode" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="Tag" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="Keywords" type="KeywordDefinition" minOccurs="0" maxOccurs="1"/>
<xs:element name="ImageUri" type="xs:anyURI" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:attribute ref="xml:lang" use="required"/>
</xs:complexType>
<xs:complexType name="ProductListingDefinition">
<xs:sequence>
<xs:element name="MarketData" type="MarketSpecificProductData" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="ProductId" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="100"/>
<xs:pattern value="[^,]*"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="LicenseDuration" type="xs:integer" use="optional"/>
<xs:attribute name="ProductType" type="xs:string" use="optional"/>
</xs:complexType>
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="ConsumableProductDefinition">
<xs:attribute name="ProductId" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="100"/>
<xs:pattern value="[^,]*"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="TransactionId" type="guid" use="required"/>
<xs:attribute name="Status" type="ConsumableStatus" use="required"/>
<xs:attribute name="OfferId" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="LicenseDefinition">
<xs:sequence>
<xs:element name="App" type="AppLicenseDefinition"/>
<xs:element name="Product" type="ProductLicenseDefinition" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AppLicenseDefinition">
<xs:sequence>
<xs:element name="IsActive" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
<xs:element name="IsTrial" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
<xs:element name="ExpirationDate" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ProductLicenseDefinition">
<xs:sequence>
<xs:element name="IsActive" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
<xs:element name="ExpirationDate" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:attribute name="ProductId" type="xs:string" use="required"/>
<xs:attribute name="OfferId" type="xs:string" use="optional"/>
</xs:complexType>
<xs:complexType name="SimulationDefinition" >
<xs:sequence>
<xs:element name="DefaultResponse" type="DefaultResponseDefinition" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="SimulationMode" type="SimulationMode" use="optional"/>
</xs:complexType>
<xs:complexType name="DefaultResponseDefinition">
<xs:attribute name="MethodName" type="StoreMethodName" use="required"/>
<xs:attribute name="HResult" type="ResponseCodes" use="required"/>
</xs:complexType>
<xs:complexType name="KeywordDefinition">
<xs:sequence>
<xs:element name="Keyword" type="xs:string" minOccurs="0" maxOccurs="10"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
요소 및 특성 설명
이 섹션에서는 WindowsStoreProxy.xml 파일의 요소와 특성에 대해 설명합니다.
이 파일의 루트 요소는 현재 앱을 나타내는 CurrentApp 요소입니다. 이 요소에는 다음의 자식 요소가 포함됩니다.
요소 | 필수 | 수량 | 설명 |
---|---|---|---|
ListingInformation | 예 | 1 | 앱 목록의 데이터를 포함합니다. |
LicenseInformation | 예 | 1 | 이 앱에 사용할 수 있는 라이선스와 지속성 추가 기능에 대해 설명합니다. |
ConsumableInformation | 아니요 | 0 또는 1 | 이 앱에 사용할 수 있는 소모성 추가 기능에 대해 설명합니다. |
Simulation | 아니요 | 0 또는 1 | 테스트 중에 앱에서 다양한 CurrentAppSimulator 메서드를 호출하는 방법을 설명합니다. |
ListingInformation 요소
이 요소에는 앱 목록의 데이터가 포함됩니다. ListingInformation은 CurrentApp 요소의 필수 자식입니다.
ListingInformation은 다음의 자식 요소를 포함합니다.
요소 | 필수 | 수량 | 설명 |
---|---|---|---|
App | 예 | 1 | 앱에 대한 데이터를 제공합니다. |
제품 | 아니요 | 0 이상 | 앱에 대한 추가 기능을 설명합니다. |
앱 요소(ListingInformation의 자식)
이 요소는 앱의 라이선스를 설명합니다. App은 ListingInformation 요소의 필수 자식입니다.
App은 다음의 자식 요소를 포함합니다.
요소 | 필수 | 수량 | 설명 |
---|---|---|---|
AppId | 예 | 1 | Store에서 앱을 식별하는 GUID입니다. 테스트하기 위해 아무 GUID나 입력할 수 있습니다. |
LinkUri | 예 | 1 | Store에 있는 목록 페이지의 URI입니다. 이는 테스트를 위한 유효한 URI입니다. |
CurrentMarket | 예 | 1 | 고객의 국가/지역입니다. |
AgeRating | 예 | 1 | 앱의 최소 연령 등급을 나타내는 정수입니다. 앱을 제출할 때 파트너 센터에서 지정하는 값과 같습니다. Store에서 사용하는 값은 3, 7, 12 및 16입니다. 이러한 등급에 대한 자세한 정보는 연령별 등급을 참조하세요. |
MarketData | 예 | 1개 이상 | 지정된 국가/지역의 앱에 대한 정보를 포함합니다. 앱이 나열된 각 국가/지역에 대한 MarketData 요소를 포함해야 합니다. |
MarketData 요소(앱의 자식)
이 요소는 지정된 국가/지역의 앱에 대한 정보를 제공합니다. 앱이 나열된 각 국가/지역에 대한 MarketData 요소를 포함해야 합니다. MarketData는 App 요소의 필수 자식입니다.
MarketData는 다음과 같은 자식 요소를 포함합니다.
요소 | 필수 | 수량 | 설명 |
---|---|---|---|
Name | 예 | 1 | 이 국가/지역에서의 앱의 이름입니다. |
Description | 예 | 1 | 이 국가/지역의 앱에 대한 설명입니다. |
Price | 예 | 1 | 이 국가/지역에서의 앱의 가격입니다. |
CurrencySymbol | 예 | 1 | 이 국가/지역에서 사용되는 통화 기호입니다. |
CurrencyCode | 아니요 | 0 또는 1 | 이 국가/지역에서 사용되는 통화 코드입니다. |
MarketData에는 다음과 같은 특성이 있습니다.
특성 | 필수 | 설명 |
---|---|---|
xml:lang | 예 | 시장 데이터 정보가 적용되는 국가/지역을 지정합니다. |
Product 요소(ListingInformation의 자식)
이 요소는 앱에 대한 추가 기능을 설명합니다. Product는 ListingInformation 요소의 선택적 자식이며 하나 이상의 MarketData 요소를 포함합니다.
Product에는 다음과 같은 특성이 있습니다.
특성 | 필수 | 설명 |
---|---|---|
ProductId | 예 | 앱에서 추가 기능을 식별하는 데 사용하는 문자열을 포함합니다. |
LicenseDuration | 아니요 | 항목을 구매한 후 라이선스가 유효한 기간(일)을 나타냅니다. 제품 구매에서 만든 새 라이선스의 만료 날짜는 구매 날짜와 라이선스 기간입니다. 이 특성은 ProductType 특성이 Durable인 경우에만 사용되며, 이 특성은 소모성 추가 기능에 대해 무시됩니다. |
ProductType | 아니요 | 앱 내 제품의 지속성을 식별하는 값을 포함합니다. 지원되는 값은 Durable(기본값) 및 Consumable입니다. 지속성 형식의 경우 LicenseInformation의 Product 요소에 의해 추가 정보가 설명되며, 소모성 형식의 경우 ConsumableInformation의 Product 요소에 의해 추가 정보가 설명됩니다. |
MarketData 요소(제품의 자식)
이 요소는 지정된 국가/지역의 추가 기능에 대한 정보를 제공합니다. 추가 기능이 나열된 각 국가/지역에 대한 MarketData 요소를 포함해야 합니다. MarketData는 Product 요소의 필수 자식입니다.
MarketData는 다음과 같은 자식 요소를 포함합니다.
요소 | 필수 | 수량 | 설명 |
---|---|---|---|
Name | 예 | 1 | 이 국가/지역에서의 추가 기능의 이름입니다. |
Price | 예 | 1 | 이 국가/지역에서의 추가 기능의 가격입니다. |
CurrencySymbol | 예 | 1 | 이 국가/지역에서 사용되는 통화 기호입니다. |
CurrencyCode | 아니요 | 0 또는 1 | 이 국가/지역에서 사용되는 통화 코드입니다. |
Description | 아니요 | 0 또는 1 | 이 국가/지역의 추가 기능에 대한 설명입니다. |
Tag | 아니요 | 0 또는 1 | 추가 기능에 대한 사용자 지정 개발자 데이터(태그라고도 함)입니다. |
Keywords | 아니요 | 0 또는 1 | 추가 기능에 대한 키워드를 포함하는 최대 10개의 Keyword 요소를 포함합니다. |
ImageUri | 아니요 | 0 또는 1 | 추가 기능 목록에 있는 이미지의 URI입니다. |
MarketData에는 다음과 같은 특성이 있습니다.
특성 | 필수 | 설명 |
---|---|---|
xml:lang | 예 | 시장 데이터 정보가 적용되는 국가/지역을 지정합니다. |
LicenseInformation 요소
이 요소는 이 앱에 사용할 수 있는 라이선스와 지속성 앱 내 제품에 대해 설명합니다. LicenseInformation은 CurrentApp 요소의 필수 자식입니다.
LicenseInformation 요소는 다음의 자식 요소를 포함합니다.
요소 | 필수 | 수량 | 설명 |
---|---|---|---|
App | 예 | 1 | 앱의 라이선스에 대해 설명합니다. |
Product | 아니요 | 0 이상 | 앱의 지속성 추가 기능의 라이선스의 상태를 설명합니다. |
다음의 테이블은 App 및 Product 요소 아래의 값을 결합하여 몇 가지 일반적인 조건을 시뮬레이션하는 방법을 보여 줍니다.
시뮬레이션 조건 | IsActive | IsTrial | ExpirationDate |
---|---|---|---|
정식 라이선스 | true | false | 없습니다. 실제로 있으며 이후 날짜를 지정할 수도 있지만 XML 파일에서 요소를 생략하는 것이 좋습니다. 존재하며 과거의 날짜를 지정하는 경우 IsActive는 무시되고 false로 간주됩니다. |
평가판 기간 내 | true | true | <미래의 datetime> 이 요소는 IsTrial이 true이기 때문에 있어야 합니다. 원하는 남은 평가판 기간을 가져오기 위해 어느 정도로 먼 미래에 설정할지 알려면 현재 UTC(협정 세계시)를 보여 주는 웹 사이트를 방문할 수 있습니다. |
만료된 평가판 | false | true | <과거의 datetime> 이 요소는 IsTrial이 true이기 때문에 있어야 합니다. UTC에서 "과거"가 언제인지 알기 위해 현재 UTC(협정 세계시)를 보여주는 웹 사이트를 방문할 수 있습니다. |
잘못됨 | false | false | <임의 값 또는 생략> |
앱 요소(LicenseInformation의 자식)
이 요소는 앱의 라이선스를 설명합니다. App은 LicenseInformation 요소의 필수 자식입니다.
App은 다음의 자식 요소를 포함합니다.
요소 | 필수 | 수량 | 설명 |
---|---|---|---|
IsActive | 예 | 1 | 이 앱의 현재 라이선스 상태를 설명합니다. true 값은 라이선스가 유효하다는 것을 나타내며, false는 잘못된 라이선스를 나타냅니다. 일반적으로 이 값은 앱에 평가판 모드가 있는지 여부에 관계없이 true입니다. 잘못된 라이선스가 있는 경우 앱의 동작 방식을 테스트하려면 이 값을 false로 설정합니다. |
IsTrial | 예 | 1 | 이 앱의 현재 평가판 상태를 설명합니다. true 값은 평가판 기간 동안 앱이 사용되고 있음을 나타내며, false는 앱이 구입되었거나 평가판 기간이 만료되었기 때문에 앱이 평가판에 있지 않음을 나타냅니다. |
ExpirationDate | 아니요 | 0 또는 1 | 이 앱의 평가 기간이 만료되는 날짜(UTC(협정 세계시 기준)입니다. 날짜는 yyyy-mm-ddThh:mm:ss.ssZ로 표현되어야 합니다. 예를 들어 2015년 1월 19일 05:00은 2015-01-19T05:00:00.00Z로 지정됩니다. 이 요소는 IsTrial이 true인 경우 필요합니다. 그렇지 않으면 필요하지 않습니다. |
Product 요소(LicenseInformation의 자식)
이 요소는 앱의 지속성 추가 기능의 라이선스의 상태를 설명합니다. Product는 LicenseInformation 요소의 선택적 자식입니다.
Product는 다음과 같은 자식 요소를 포함합니다.
요소 | 필수 | 수량 | 설명 |
---|---|---|---|
IsActive | 예 | 1 | 이 추가 기능의 현재 라이선스 상태를 설명합니다. true 값은 추가 기능을 사용할 수 있음을 나타내며, false는 추가 기능을 사용할 수 없거나 구입하지 않음을 나타냅니다. |
ExpirationDate | 아니요 | 0 또는 1 | 추가 기능이 만료되는 날짜(UTC(협정 세계시) 기준)입니다. 날짜는 yyyy-mm-ddThh:mm:ss.ssZ로 표현되어야 합니다. 예를 들어 2015년 1월 19일 05:00은 2015-01-19T05:00:00.00Z로 지정됩니다. 이 요소가 있는 경우 추가 기능에 만료 날짜가 있습니다. 없는 경우 추가 기능은 만료되지 않습니다. |
Product에는 다음과 같은 특성이 있습니다.
특성 | 필수 | 설명 |
---|---|---|
ProductId | 예 | 앱에서 추가 기능을 식별하는 데 사용하는 문자열을 포함합니다. |
OfferId | 아니요 | 추가 기능이 속한 범주를 식별하기 위해 앱에서 사용하는 문자열을 포함합니다. 이렇게 하면 앱 내 제품의 대규모 카탈로그 관리하기에 설명된 대로 큰 항목 카탈로그를 지원합니다. |
Simulation 요소
이 요소는 테스트 중에 앱에서 다양한 CurrentAppSimulator 메서드를 호출하는 방법을 설명합니다. Simulation은 CurrentApp 요소의 선택적 자식이며 0개 이상의 DefaultResponse 요소를 포함합니다.
Simulation에는 다음과 같은 특성이 있습니다.
특성 | 필수 | 설명 |
---|---|---|
SimulationMode | 아니요 | 값은 Interactive 또는 Automatic일 수 있습니다. 이 특성을 Automatic으로 설정하면 메서드는 지정된 HRESULT 오류 코드를 자동으로 반환합니다. 자동화된 테스트 사례를 실행할 때 사용할 수 있습니다. |
DefaultResponse 요소
이 요소는 CurrentAppSimulator 메서드가 반환하는 기본 오류 코드를 설명합니다. DefaultResponse는 Simulation 요소의 선택적 자식입니다.
DefaultResponse에는 다음과 같은 특성이 있습니다.
특성 | 필수 | 설명 |
---|---|---|
MethodName | 예 | 스키마의 StoreMethodName 형식에 대해 표시된 열거형 값 중 하나에 이 특성을 할당합니다. 이러한 각 열거형 값은 테스트 중에 앱에서 오류 코드 반환 값을 시뮬레이션하려는 CurrentAppSimulator 메서드를 나타냅니다. 예를 들어, RequestAppPurchaseAsync_GetResult 값은 RequestAppPurchaseAsync 메서드의 오류 코드 반환 값을 시뮬레이트하려고 했음을 나타냅니다. |
HResult | 예 | 이 특성을 스키마의 ResponseCodes 형식에 대해 표시된 열거형 값 중 하나에 할당합니다. 이러한 각 열거형 값은 이 DefaultResponse 요소의 MethodName 특성에 할당된 메서드에 대해 반환하려는 오류 코드를 나타냅니다. |
ConsumableInformation 요소
이 요소는 이 앱에 사용할 수 있는 소모성 추가 기능을 설명합니다. ConsumableInformation은 CurrentApp 요소의 선택적 자식이며 0개 이상의 Product 요소를 포함할 수 있습니다.
Product 요소(ConsumableInformation의 자식)
이 요소는 소모성 추가 기능을 설명합니다. Product는 ConsumableInformation 요소의 선택적 자식입니다.
Product에는 다음과 같은 특성이 있습니다.
특성 | 필수 | 설명 |
---|---|---|
ProductId | 예 | 앱에서 소모성 추가 기능을 식별하는 데 사용하는 문자열을 포함합니다. |
TransactionId | 예 | 처리 프로세스를 통해 소모품의 구매 트랜잭션을 추적하기 위해 앱에서 사용하는 GUID(문자열)를 포함합니다. 앱 내 소모성 제품 구매 사용하기를 확인합니다. |
상태 | 예 | 소모품의 처리 상태를 나타내기 위해 앱에서 사용하는 문자열을 포함합니다. 값은 Active, PurchaseReverted, PurchasePending 또는 ServerError일 수 있습니다. |
OfferId | 아니요 | 소모품이 속한 범주를 식별하기 위해 앱에서 사용하는 문자열을 포함합니다. 이렇게 하면 앱 내 제품의 대규모 카탈로그 관리하기에 설명된 대로 큰 항목 카탈로그를 지원합니다. |