[Unity3D] Unity In App Purchasing / In App Billing - iOS & Android
우선, 유니티에서 Window -> Services 합니다.
그러고 나면 Inspector 옆에 Services라는 텝이 생기는데
Select Organization 하고 Create 해줍니다.
그러면 유니티에서 제공하는 Service들이 보일 것입니다.
그 중에, OFF상태인 In-App Purchasing 텝을 클릭합니다.
우측상단에 있는 토글을 눌러 OFF되어있던 상태를 ON으로 만들어줍니다.
그리고 13세 이하 어린이에게 지도감독이 필요한 지 여부를 선택하고 Save Changes 합니다.
이제, 프로젝트에 In-App Purchasing이 활성화 된 모습을 보실 수 있을 것입니다.
여기서 잊지말고 Import 버튼을 꼬옥 눌러줍니다!
프로젝트 뷰에 Unity IAP 플러그인이 제대로 임포트 된 모습입니다.
이제 기본 세팅이 다 되었습니다. 그렇다면 코딩을 해볼까요?
아래와 같이 Script를 작성합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | using System; using UnityEngine; using UnityEngine.Purchasing; public class InAppPurchaser : MonoBehaviour, IStoreListener { private static IStoreController storeController; private static IExtensionProvider extensionProvider; #region 상품ID // 상품ID는 구글 개발자 콘솔에 등록한 상품ID와 동일하게 해주세요. public const string productId1 = "gem1"; public const string productId2 = "gem2"; public const string productId3 = "gem3"; public const string productId4 = "gem4"; public const string productId5 = "gem5"; #endregion void Start() { InitializePurchasing(); } private bool IsInitialized() { return (storeController != null && extensionProvider != null); } public void InitializePurchasing() { if (IsInitialized()) return; var module = StandardPurchasingModule.Instance(); ConfigurationBuilder builder = ConfigurationBuilder.Instance(module); builder.AddProduct(productId1, ProductType.Consumable, new IDs { { productId1, AppleAppStore.Name }, { productId1, GooglePlay.Name }, }); builder.AddProduct(productId2, ProductType.Consumable, new IDs { { productId2, AppleAppStore.Name }, { productId2, GooglePlay.Name }, } ); builder.AddProduct(productId3, ProductType.Consumable, new IDs { { productId3, AppleAppStore.Name }, { productId3, GooglePlay.Name }, }); builder.AddProduct(productId4, ProductType.Consumable, new IDs { { productId4, AppleAppStore.Name }, { productId4, GooglePlay.Name }, }); builder.AddProduct(productId5, ProductType.Consumable, new IDs { { productId5, AppleAppStore.Name }, { productId5, GooglePlay.Name }, }); UnityPurchasing.Initialize(this, builder); } public void BuyProductID(string productId) { try { if (IsInitialized()) { Product p = storeController.products.WithID(productId); if (p != null && p.availableToPurchase) { Debug.Log(string.Format("Purchasing product asychronously: '{0}'", p.definition.id)); storeController.InitiatePurchase(p); } else { Debug.Log("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase"); } } else { Debug.Log("BuyProductID FAIL. Not initialized."); } } catch (Exception e) { Debug.Log("BuyProductID: FAIL. Exception during purchase. " + e); } } public void RestorePurchase() { if (!IsInitialized()) { Debug.Log("RestorePurchases FAIL. Not initialized."); return; } if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.OSXPlayer) { Debug.Log("RestorePurchases started ..."); var apple = extensionProvider.GetExtension<IAppleExtensions>(); apple.RestoreTransactions ( (result) => { Debug.Log("RestorePurchases continuing: " + result + ". If no further messages, no purchases available to restore."); } ); } else { Debug.Log("RestorePurchases FAIL. Not supported on this platform. Current = " + Application.platform); } } public void OnInitialized(IStoreController sc, IExtensionProvider ep) { Debug.Log("OnInitialized : PASS"); storeController = sc; extensionProvider = ep; } public void OnInitializeFailed(InitializationFailureReason reason) { Debug.Log("OnInitializeFailed InitializationFailureReason:" + reason); } public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) { Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id)); switch (args.purchasedProduct.definition.id) { case productId1: // ex) gem 10개 지급 break; case productId2: // ex) gem 50개 지급 break; case productId3: // ex) gem 100개 지급 break; case productId4: // ex) gem 300개 지급 break; case productId5: // ex) gem 500개 지급 break; } return PurchaseProcessingResult.Complete; } public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) { Debug.Log(string.Format("OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: {1}", product.definition.storeSpecificId, failureReason)); } } | cs |
결제를 진행해야하는 부분에서
위의 BuyProductID 함수의 파라미터로 상품ID를 넣고 콜(구매요청)하면
product가 initialize된 후 ProcessPurchase로 결과가 넘어오는데
args.purchasedProduct.definition.id로 구매요청된 상품ID를 판별하여
상품에 맞는 보상을 지급해주면 됩니다. 참 쉽죠?
유니티 5.3버전 이전에는(유니티가 자체 IAP를 지원하기 전) Android와 iOS 각각 따로 결제시스템을 만들어야했는데
지금은 Android와 iOS를 동시에 지원해주기 때문에 정말 편하답니다~
결제된 정보는 구글 Payments 판매자 센터에서 확인하실 수 있습니다. (https://wallet.google.com/merchant)
출처: http://minhyeokism.tistory.com/47 [programmer-dominic.kim]