ํ์ฌ ๋ฌธ์ :
์ ๋ํฐ ํ๊ฒฝ์์๋ ์ธ์ฑ ๊ฒฐ์ ํ ์คํธ ์ ๋จ
๋ชจ๋ฐ์ผ ํ๊ฒฝ์์๋ ๋ฒํผ์ ๋๋ฌ๋ ์๋ฌด ํ์ ์ด ์๋ธ
์ ๋ํฐ ํ๊ฒฝ์์๋ ๊ฒ์์ ์์ํ๋ฉด
IAP ์ด๊ธฐํ๊ฐ ์ฑ๊ณตํ๋ค๋ ๋ก๊ทธ๊ฐ ์ถ๋ ฅ๋์ง๋ง
๋ชจ๋ฐ์ผ ํ๊ฒฝ์ ์ด๊ธฐํ ์คํจ ๋ก๊ทธ๊ฐ ์ถ๋ ฅ๋จ
์ผ๋จ ๊ตฌ๊ธ ๋ผ์ด์ ์ค ์ฝ๋ ์ธํ ์ ์ด๋ ๊ฒ ํ์ด์
๊ตฌ๊ธ ๋ผ์ด์ ์ค ํค ๋ณต์ฌ ํด์ ๊ณต๋ฐฑ ์ ๊ฑฐ ํ๊ณ ํ์์ ์นธ์ ๋ฃ์์ด์
์ ๋ํฐ ๋์ฌ๋ณด๋์ ํ์ฌ ์ ๊ฐ ์ฌ์ฉ ์ค์ธ ํ๋ก์ ํธ๊ฐ ์๊ธธ๋
์ง์ ๋์ฌ๋ณด๋์ ์์ ์ค์ธ ํ๋ก์ ํธ ์ด๋ฆ์ ์ ๋ ฅํด์ ์ถ๊ฐ ํ๊ณ
๋ผ์ด์ ์ค ํค๋ฅผ ๋ฃ์์ต๋๋ค
์นดํ๋ก๊ทธ๋ ์ด๋ ๊ฒ ์งฐ์ต๋๋ค
IAPManager ์ค๋ธ์ ํธ์ IAPManager ์คํฌ๋ฆฝํธ ๋ฃ์์ต๋๋ค
์ด๊ฑฐ๋ IAPManager ์คํฌ๋ฆฝํธ ์ฝ๋์์
using UnityEngine;
using UnityEngine.Purchasing;
public class IAPManager : MonoBehaviour, IStoreListener
{
[Header("Product ID")]
public readonly string gold500_id = "com.games.srpg.gold500";
public readonly string gold1000_id = "com.games.srpg.gold1000";
[Header("Cache")]
private IStoreController storeController; // ๊ตฌ๋งค ๊ณผ์ ์ ์ ์ดํ๋ ํจ์ ์ ๊ณต์
private IExtensionProvider storeExtensionProvider; // ์ฌ๋ฌ ํ๋ซํผ์ ์ํ ํ์ฅ ์ฒ๋ฆฌ ์ ๊ณต์
private void Start()
{
InitUnityIAP(); // Start ๋ฌธ์์ ์ด๊ธฐํ ํ์
}
/* Unity IAP๋ฅผ ์ด๊ธฐํํ๋ ํจ์ */
private void InitUnityIAP()
{
ConfigurationBuilder builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
/* ๊ตฌ๊ธ ํ๋ ์ด ์ํ๋ค ์ถ๊ฐ */
builder.AddProduct(gold500_id, ProductType.Consumable);
builder.AddProduct(gold1000_id, ProductType.Consumable);
UnityPurchasing.Initialize(this, builder);
}
/* ๊ตฌ๋งคํ๋ ํจ์ */
public void Purchase(string productId)
{
Product product = storeController.products.WithID(productId); // ์ํ ์ ์
if (product != null && product.availableToPurchase) // ์ํ์ด ์กด์ฌํ๋ฉด์ ๊ตฌ๋งค ๊ฐ๋ฅํ๋ฉด
{
storeController.InitiatePurchase(product); // ๊ตฌ๋งค๊ฐ ๊ฐ๋ฅํ๋ฉด ์งํ
}
else // ์ํ์ด ์กด์ฌํ์ง ์๊ฑฐ๋ ๊ตฌ๋งค ๋ถ๊ฐ๋ฅํ๋ฉด
{
Debug.Log("์ํ์ด ์๊ฑฐ๋ ํ์ฌ ๊ตฌ๋งค๊ฐ ๋ถ๊ฐ๋ฅํฉ๋๋ค");
}
}
#region Interface
/* ์ด๊ธฐํ ์ฑ๊ณต ์ ์คํ๋๋ ํจ์ */
public void OnInitialized(IStoreController controller, IExtensionProvider extension)
{
Debug.Log("์ด๊ธฐํ์ ์ฑ๊ณตํ์ต๋๋ค");
storeController = controller;
storeExtensionProvider = extension;
}
/* ์ด๊ธฐํ ์คํจ ์ ์คํ๋๋ ํจ์ */
public void OnInitializeFailed(InitializationFailureReason error)
{
Debug.Log("์ด๊ธฐํ์ ์คํจํ์ต๋๋ค");
}
public void OnInitializeFailed(InitializationFailureReason error, string message)
{
Debug.Log($"์ด๊ธฐํ์ ์คํจํ์ต๋๋ค. ์ด์ : {error.ToString()}. ๋ฉ์์ง: {message}");
}
/* ๊ตฌ๋งค์ ์คํจํ์ ๋ ์คํ๋๋ ํจ์ */
public void OnPurchaseFailed(Product product, PurchaseFailureReason reason)
{
Debug.Log("๊ตฌ๋งค์ ์คํจํ์ต๋๋ค");
}
/* ๊ตฌ๋งค๋ฅผ ์ฒ๋ฆฌํ๋ ํจ์ */
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
{
Debug.Log("๊ตฌ๋งค์ ์ฑ๊ณตํ์ต๋๋ค");
if (args.purchasedProduct.definition.id == gold500_id)
{
/* test_id ๊ตฌ๋งค ์ฒ๋ฆฌ */
point.gold += 500;
}
else if (args.purchasedProduct.definition.id == gold1000_id)
{
point.gold += 1000;
}
return PurchaseProcessingResult.Complete;
}
#endregion
}
using System;
using System.Collections.Generic;
namespace UnityEngine.Purchasing
{
ย ย /// <summary>
ย ย /// Used by Applications to control Unity Purchasing.
ย ย /// </summary>
ย ย public interface IStoreController
ย ย {
ย ย ย ย /// <summary>
ย ย ย ย /// Gets the collection of products in the store.
ย ย ย ย /// </summary>
ย ย ย ย /// <value> The product collection. </value>
ย ย ย ย ProductCollection products { get; }
ย ย ย ย /// <summary>
ย ย ย ย /// Initiate a purchase from the controlled store.
ย ย ย ย /// </summary>
ย ย ย ย /// <param name="product"> The product to be purchased. </param>
ย ย ย ย /// <param name="payload"> The developer payload provided for certain stores that define such a concept (ex: Google Play). </param>
ย ย ย ย void InitiatePurchase(Product product, string payload);
ย ย ย ย /// <summary>
ย ย ย ย /// Initiate a purchase from the controlled store.
ย ย ย ย /// </summary>
ย ย ย ย /// <param name="productId"> The id of the product to be purchased. </param>
ย ย ย ย /// <param name="payload"> The developer payload provided for certain stores that define such a concept (ex: Google Play). </param>
ย ย ย ย void InitiatePurchase(string productId, string payload);
ย ย ย ย /// <summary>
ย ย ย ย /// Initiate a purchase from the controlled store.
ย ย ย ย /// </summary>
ย ย ย ย /// <param name="product"> The product to be purchased. </param>
ย ย ย ย void InitiatePurchase(Product product);
ย ย ย ย /// <summary>
ย ย ย ย /// Initiate a purchase from the controlled store
ย ย ย ย /// </summary>
ย ย ย ย /// <param name="productId"> The id of the product to be purchased. </param>
ย ย ย ย void InitiatePurchase(string productId);
ย ย ย ย /// <summary>
ย ย ย ย /// Fetch additional products from the controlled store.
ย ย ย ย /// </summary>
ย ย ย ย /// <param name="additionalProducts"> The set of product definitions to be fetched. </param>
ย ย ย ย /// <param name="successCallback"> The event triggered on a successful fetch. </param>
ย ย ย ย /// <param name="failCallback"> The event triggered on a failed fetch. </param>
ย ย ย ย [Obsolete]
ย ย ย ย void FetchAdditionalProducts(HashSet<ProductDefinition> additionalProducts, Action successCallback,
ย ย ย ย ย ย Action<InitializationFailureReason> failCallback);
ย ย ย ย /// <summary>
ย ย ย ย /// Fetch additional products from the controlled store.
ย ย ย ย /// </summary>
ย ย ย ย /// <param name="additionalProducts"> The set of product definitions to be fetched. </param>
ย ย ย ย /// <param name="successCallback"> The event triggered on a successful fetch. </param>
ย ย ย ย /// <param name="failCallback"> The event triggered on a failed fetch. Contains the FailureReason and an optional error message. </param>
ย ย ย ย void FetchAdditionalProducts(HashSet<ProductDefinition> additionalProducts, Action successCallback,
ย ย ย ย ย ย Action<InitializationFailureReason, string> failCallback);
ย ย ย ย /// <summary>
ย ย ย ย /// Where an Application returned ProcessingResult.Pending
ย ย ย ย /// from IStoreListener.ProcessPurchase(), Applications should call
ย ย ย ย /// this method when processing completes.
ย ย ย ย /// </summary>
ย ย ย ย /// <param name="product"> The product for which its pending purchase it to be confirmed. </param>
ย ย ย ย void ConfirmPendingPurchase(Product product);
ย ย }
}
์ด๊ฑด IStoreListener ์คํฌ๋ฆฝํธ
using System;
namespace UnityEngine.Purchasing
{
ย ย /// <summary>
ย ย /// Implemented by Application developers using Unity Purchasing.
ย ย /// </summary>
ย ย public interface IStoreListener
ย ย {
ย ย ย ย /// <summary>
ย ย ย ย /// Purchasing failed to initialise for a non recoverable reason.
ย ย ย ย /// </summary>
ย ย ย ย /// <param name="error"> The failure reason. </param>
ย ย ย ย [Obsolete]
ย ย ย ย void OnInitializeFailed(InitializationFailureReason error);
ย ย ย ย /// <summary>
ย ย ย ย /// Purchasing failed to initialise for a non recoverable reason.
ย ย ย ย /// </summary>
ย ย ย ย /// <param name="error"> The failure reason. </param>
ย ย ย ย /// <param name="message"> More detail on the error : for example the GoogleBillingResponseCode. </param>
ย ย ย ย void OnInitializeFailed(InitializationFailureReason error, string message);
ย ย ย ย /// <summary>
ย ย ย ย /// A purchase succeeded.
ย ย ย ย /// </summary>
ย ย ย ย /// <param name="purchaseEvent"> The <c>PurchaseEventArgs</c> for the purchase event. </param>
ย ย ย ย /// <returns> The result of the successful purchase </returns>
ย ย ย ย PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs purchaseEvent);
ย ย ย ย /// <summary>
ย ย ย ย /// A purchase failed with specified reason.
ย ย ย ย /// </summary>
ย ย ย ย /// <param name="product"> The product that was attempted to be purchased. </param>
ย ย ย ย /// <param name="failureReason"> The failure reason. </param>
ย ย ย ย [Obsolete("Use IDetailedStoreListener.OnPurchaseFailed for more detailed callback.", false)]
ย ย ย ย void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason);
ย ย ย ย /// <summary>
ย ย ย ย /// Purchasing initialized successfully.
ย ย ย ย ///
ย ย ย ย /// The <c>IStoreController</c> and <c>IExtensionProvider</c> are
ย ย ย ย /// available for accessing purchasing functionality.
ย ย ย ย /// </summary>
ย ย ย ย /// <param name="controller"> The <c>IStoreController</c> created during initialization. </param>
ย ย ย ย /// <param name="extensions"> The <c>IExtensionProvider</c> created during initialization. </param>
ย ย ย ย void OnInitialized(IStoreController controller, IExtensionProvider extensions);
ย ย }
}
์ด๊ฑด GooglePlayTangle ์คํฌ๋ฆฝํธ ์ฝ๋
// WARNING: Do not modify! Generated file.
namespace UnityEngine.Purchasing.Security {
public class GooglePlayTangle
{
private static byte[] data = System.Convert.FromBase64String("๊ธธ๊ฒ ๋์ด๋ ์์ด์ ์ซ์, ํน์ ๊ธฐํธ๋ค");
private static int[] order = new int[] { 12,3,13,8,9,9,8,10,11,10,11,11,12,13,14 };
private static int key = 160;
public static readonly bool IsPopulated = true;
public static byte[] Data() {
if (IsPopulated == false)
return null;
return Obfuscator.DeObfuscate(data, order, key);
}
}
}
๊ตฌ๊ธ์ ์ํ ๋ฑ๋ก๋ ์ ๋ถ ์ ํํ๊ฒ ๋ง์ณค์ต๋๋ค
์ฒ ์ ์ ํ๋ ธ๊ณ
๋ชจ๋ ํ์ฑํ ์ํจ ์ง ์ผ์ฃผ์ผ์ ์ง๋ฌ์ต๋๋ค
๋ง๋ ์ง 2~3์ฃผ๋ ์ง๋ฌ๋๋ฐ ๋ณ ์ง์ ๋ค ํด๋ ์๋๊ธธ๋
ํน์๋ ๋์น ์ ์ด ์๋์ง ๋ณด๊ณ ์
๋ชจ๋ ์ ๋ณด๋ฅผ ์ฌ๊ธฐ์ ์ฌ๋ฆฝ๋๋ค
์ถ๊ฐ๋ก ํ์ํ์ ์ ๋ณด๊ฐ ์๋ค๋ฉด ๋๊ธ ๋จ๊ฒจ์ฃผ์ธ์
๋ฐ๋ก ์ฌ๋ฆฌ๊ฒ ์ต๋๋ค
๋๊ธ 0