/// Called when the available items have been pulled from ChilliConnect. /// Builds the Unity purchasing system using the available items /// /// @param request /// Information about the request, including the URL endpoint. /// @param response /// Response from the request. Holds the information on all purchaseable items /// private void OnAvailableItemsFetched(GetRealMoneyPurchaseDefinitionsRequest request, GetRealMoneyPurchaseDefinitionsResponse response) { var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); Debug.Log("Available items fetched:"); //Initialise Unity purchasing with the product ids available on ChilliConnect foreach (var item in response.Items) { Debug.Log(string.Format("Product: {0}", item.Key)); builder.AddProduct(item.Key, ProductType.Consumable, new IDs { { item.GoogleId, GooglePlay.Name }, { item.IosId, AppleAppStore.Name } }); m_availableItems.Add(new Item(GetPlatformProductId(item), item.Key)); } builder.Configure <IGooglePlayConfiguration>().SetPublicKey("ADD YOUR GOOGLE PUBLIC KEY"); // Expect a response either in OnInitialized or OnInitializeFailed. UnityPurchasing.Initialize(this, builder); }
public void InitializePurchasing() { // If we have already connected to Purchasing ... if (IsInitialized()) { // ... we are done here. return; } // Create a builder, first passing in a suite of Unity provided stores. var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); InAppProductList.Instance.InitialiseProductList(); // Add Consumable foreach (KeyValuePair <string, InAppProductList.ProductInfo> product in InAppProductList.Instance.ConsumableList) { AddProduct(builder, product.Value, ProductType.Consumable); } // Continue adding the non-consumable product. foreach (KeyValuePair <string, InAppProductList.ProductInfo> product in InAppProductList.Instance.NonConsumableList) { AddProduct(builder, product.Value, ProductType.NonConsumable); } // Adding subscription foreach (KeyValuePair <string, InAppProductList.ProductInfo> product in InAppProductList.Instance.SubscriptionList) { AddProduct(builder, product.Value, ProductType.Subscription); } // Kick off the remainder of the set-up with an asynchrounous call, passing the configuration // and this class' instance. Expect a response either in OnInitialized or OnInitializeFailed. UnityPurchasing.Initialize(this, builder); }
public void Awake() { var module = StandardPurchasingModule.Instance(); module.useMockBillingSystem = true; // Microsoft // The FakeStore supports: no-ui (always succeeding), basic ui (purchase pass/fail), and // developer ui (initialization, purchase, failure code setting). These correspond to // the FakeStoreUIMode Enum values passed into StandardPurchasingModule.useFakeStoreUIMode. module.useFakeStoreUIMode = FakeStoreUIMode.StandardUser; var builder = ConfigurationBuilder.Instance(module); builder.Configure <IGooglePlayConfiguration>().SetPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2O/9/H7jYjOsLFT/uSy3ZEk5KaNg1xx60RN7yWJaoQZ7qMeLy4hsVB3IpgMXgiYFiKELkBaUEkObiPDlCxcHnWVlhnzJBvTfeCPrYNVOOSJFZrXdotp5L0iS2NVHjnllM+HA1M0W2eSNjdYzdLmZl1bxTpXa4th+dVli9lZu7B7C2ly79i/hGTmvaClzPBNyX+Rtj7Bmo336zh2lYbRdpD5glozUq+10u91PMDPH+jqhx10eyZpiapr8dFqXl5diMiobknw9CgcjxqMTVBQHK6hS0qYKPmUDONquJn280fBs1PTeA6NMG03gb9FLESKFclcuEZtvM8ZwMMRxSLA9GwIDAQAB"); builder.AddProduct("coins", ProductType.Consumable, new IDs { { "com.unity3d.unityiap.unityiapdemo.100goldcoins.v2.c", GooglePlay.Name }, { "com.unity3d.unityiap.unityiapdemo.100goldcoins.6", AppleAppStore.Name }, { "com.unity3d.unityiap.unityiapdemo.100goldcoins.mac", MacAppStore.Name }, { "com.unity3d.unityiap.unityiapdemo.100goldcoins.win8", WinRT.Name } }); builder.AddProduct("sword", ProductType.NonConsumable, new IDs { { "com.unity3d.unityiap.unityiapdemo.sword.c", GooglePlay.Name }, { "com.unity3d.unityiap.unityiapdemo.sword.6", AppleAppStore.Name }, { "com.unity3d.unityiap.unityiapdemo.sword.mac", MacAppStore.Name }, { "com.unity3d.unityiap.unityiapdemo.sword", WindowsPhone8.Name } }); builder.AddProduct("subscription", ProductType.Subscription, new IDs { { "com.unity3d.unityiap.unityiapdemo.subscription", GooglePlay.Name, AppleAppStore.Name } }); // Now we're ready to initialize Unity IAP. UnityPurchasing.Initialize(this, builder); }
// ========================================================================== // /* public - [Do] Function * 외부 객체가 호출 */ public static void DoInit(Action <TENUM, bool> onPurchased) { if (_bInit) { return; } int iLen = PrimitiveHelper.GetEnumMax <TENUM>(); if (iLen == 0) { Debug.LogWarning("Unity IAP : 상품을 등록해주세요!"); return; } StandardPurchasingModule pModule = StandardPurchasingModule.Instance(); ConfigurationBuilder pBuilder = ConfigurationBuilder.Instance(pModule); TENUM[] eEnum = PrimitiveHelper.DoGetEnumType <TENUM>(); for (int i = 0; i < iLen; i++) { string strProductID = eEnum[i].ToString(); Debug.Log(strProductID); pBuilder.AddProduct(strProductID, ProductType.Consumable, new IDs { { strProductID, AppleAppStore.Name }, { strProductID, GooglePlay.Name } }); } IStoreListener pStoreListener = new SCUnityIAPService <TENUM>(); UnityPurchasing.Initialize(pStoreListener, pBuilder); _EVENT_OnPurchased = onPurchased; }
public void InitializePurchasing() { if (IsInitialized()) { return; } var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); //Our products, with their consumable types builder.AddProduct(PURCHASE_GETCURRENCY_SMALL, ProductType.Consumable); // Consumable purchase = something you can purchase over and over builder.AddProduct(PURCHASE_GETCURRENCY_MEDIUM, ProductType.Consumable); builder.AddProduct(PURCHASE_GETCURRENCY_BIG, ProductType.Consumable); builder.AddProduct(PURCHASE_GETNOADS, ProductType.NonConsumable); // Non-consumable purchase = something you can purchase only once //Below is a builder for a subscription product, which we aren't planning to use atm. I'll leave it here for refence or if we need for some reason. /*builder.AddProduct(kProductIDSubscription, ProductType.Subscription, new IDs(){ * { kProductNameGooglePlaySubscription, GooglePlay.Name }, * });*/ UnityPurchasing.Initialize(this, builder); }
public void InitializePurchasing() { // If we have already connected to Purchasing ... if (IsInitialized()) { // ... we are done here. return; } var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); builder.AddProduct(PRODUCT_DIAMOND1, ProductType.Consumable); builder.AddProduct(PRODUCT_DIAMOND2, ProductType.Consumable); builder.AddProduct(PRODUCT_DIAMOND3, ProductType.Consumable); builder.AddProduct(PRODUCT_UNLOCK, ProductType.Consumable); builder.AddProduct(PRODUCT_NO_ADS, ProductType.NonConsumable); // Kick off the remainder of the set-up with an asynchrounous call, passing the configuration // and this class' instance. Expect a response either in OnInitialized or OnInitializeFailed. UnityPurchasing.Initialize(this, builder); }
public void InitializePurchasing(MarketPurchase[] items, EventHandler <EventArgs> ready) { _onReady = ready; _items = items; if (_storeController == null) { if (IsInitialized()) { return; } } var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); foreach (MarketPurchase item in _items) { builder.AddProduct(item.Name, ProductType.Consumable, new IDs() { { item.Name, GooglePlay.Name } }); } UnityPurchasing.Initialize(this, builder); }
public void InitializePurchasing() { // If we have already connected to Purchasing ... if (IsInitialized()) { // ... we are done here. return; } // Create a builder, first passing in a suite of Unity provided stores. var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); builder.AddProduct(PRODUCT_100_CREDITS, ProductType.Consumable); builder.AddProduct(PRODUCT_200_CREDITS, ProductType.Consumable); builder.AddProduct(PRODUCT_400_CREDITS, ProductType.Consumable); builder.AddProduct(PRODUCT_1000_CREDITS, ProductType.Consumable); builder.AddProduct(PRODUCT_2000_CREDITS, ProductType.Consumable); builder.AddProduct(PRODUCT_5000_CREDITS, ProductType.Consumable); builder.AddProduct(PRODUCT_10000_CREDITS, ProductType.Consumable); builder.AddProduct(PRODUCT_NO_ADS, ProductType.NonConsumable); UnityPurchasing.Initialize(this, builder); }
public void InitializePurchasing() { // If we have already connected to Purchasing ... if (IsInitialized()) { // ... we are done here. return; } // Create a builder, first passing in a suite of Unity provided stores. var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); // Add a product to sell / restore by way of its identifier, associating the general identifier // with its store-specific identifiers. builder.AddProduct(forestProjectilePackID, ProductType.NonConsumable); builder.AddProduct(thousandCoins, ProductType.Consumable); builder.AddProduct(fiveThousandCoins, ProductType.Consumable); builder.AddProduct(tenThousandCoins, ProductType.Consumable); builder.AddProduct(removeAds, ProductType.NonConsumable); // Kick off the remainder of the set-up with an asynchrounous call, passing the configuration // and this class' instance. Expect a response either in OnInitialized or OnInitializeFailed. UnityPurchasing.Initialize(this, builder); }
public void InitializePurchasing() { // If we have already connected to Purchasing ... if (IsInitialized()) { // ... we are done here. return; } // Create a builder, first passing in a suite of Unity provided stores. var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); builder.AddProduct(PRODUCT_100_BISCUITS, ProductType.Consumable); builder.AddProduct(PRODUCT_250_BISCUITS, ProductType.Consumable); builder.AddProduct(PRODUCT_400_BISCUITS, ProductType.Consumable); builder.AddProduct(PRODUCT_STARTER_PACK, ProductType.NonConsumable); // Kick off the remainder of the set-up with an asynchrounous call, passing the configuration // and this class' instance. Expect a response either in OnInitialized or OnInitializeFailed. UnityPurchasing.Initialize(this, builder); }
/// <summary> /// Initializes the in-app purchasing service. /// </summary> public static void InitializePurchasing() { #if EM_UIAP if (IsInitialized() || sIsInitializing) { return; } // Start initializing. sIsInitializing = true; // Create a builder, first passing in a suite of Unity provided stores. sBuilder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); // Add products foreach (IAPProduct pd in EM_Settings.InAppPurchasing.Products) { if (pd.StoreSpecificIds != null && pd.StoreSpecificIds.Length > 0) { // Add store-specific id if any IDs storeIDs = new IDs(); foreach (IAPProduct.StoreSpecificId sId in pd.StoreSpecificIds) { storeIDs.Add(sId.id, new string[] { GetStoreName(sId.store) }); } // Add product with store-specific ids sBuilder.AddProduct(pd.Id, GetProductType(pd.Type), storeIDs); } else { // Add product using store-independent id sBuilder.AddProduct(pd.Id, GetProductType(pd.Type)); } } // Intercepting Apple promotional purchases if needed. if (Application.platform == RuntimePlatform.IPhonePlayer) { if (EM_Settings.InAppPurchasing.InterceptApplePromotionalPurchases) { sBuilder.Configure <IAppleConfiguration>().SetApplePromotionalPurchaseInterceptorCallback(OnApplePromotionalPurchase); } } // If current store is Amazon and sandbox testing is enable: // write a product description to the SD card in the appropriate location. if (Application.platform == RuntimePlatform.Android) { if (EM_Settings.InAppPurchasing.TargetAndroidStore == IAPAndroidStore.AmazonAppStore && EM_Settings.InAppPurchasing.EnableAmazonSandboxTesting) { sBuilder.Configure <IAmazonConfiguration>().WriteSandboxJSON(sBuilder.products); } } // Kick off the remainder of the set-up with an asynchrounous call, passing the configuration // and this class' instance. Expect a response either in OnInitialized or OnInitializeFailed. UnityPurchasing.Initialize(sStoreListener, sBuilder); #else Debug.Log("InitializePurchasing FAILED: IAP module is not enabled."); #endif }
void InitializeValidator() { if (IsCurrentStoreSupportedByValidator()) { #if !UNITY_EDITOR var appleTangleData = m_UseAppleStoreKitTestCertificate ? AppleStoreKitTestTangle.Data() : AppleTangle.Data(); m_Validator = new CrossPlatformValidator(GooglePlayTangle.Data(), appleTangleData, Application.identifier); #endif } else { var warningMsg = $"The cross-platform validator is not implemented for the currently selected store: {StandardPurchasingModule.Instance().appStore}. \n" + "Build the project for Android, iOS, macOS, or tvOS and use the Google Play Store or Apple App Store. See README for more information."; Debug.LogWarning(warningMsg); } }
public void Awake() { var module = StandardPurchasingModule.Instance(); // The FakeStore supports: no-ui (always succeeding), basic ui (purchase pass/fail), and // developer ui (initialization, purchase, failure code setting). These correspond to // the FakeStoreUIMode Enum values passed into StandardPurchasingModule.useFakeStoreUIMode. module.useFakeStoreUIMode = FakeStoreUIMode.StandardUser; var builder = ConfigurationBuilder.Instance(module); // This enables the Microsoft IAP simulator for local testing. // You would remove this before building your release package. builder.Configure <IMicrosoftConfiguration>().useMockBillingSystem = true; builder.Configure <IGooglePlayConfiguration>().SetPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2O/9/H7jYjOsLFT/uSy3ZEk5KaNg1xx60RN7yWJaoQZ7qMeLy4hsVB3IpgMXgiYFiKELkBaUEkObiPDlCxcHnWVlhnzJBvTfeCPrYNVOOSJFZrXdotp5L0iS2NVHjnllM+HA1M0W2eSNjdYzdLmZl1bxTpXa4th+dVli9lZu7B7C2ly79i/hGTmvaClzPBNyX+Rtj7Bmo336zh2lYbRdpD5glozUq+10u91PMDPH+jqhx10eyZpiapr8dFqXl5diMiobknw9CgcjxqMTVBQHK6hS0qYKPmUDONquJn280fBs1PTeA6NMG03gb9FLESKFclcuEZtvM8ZwMMRxSLA9GwIDAQAB"); m_IsGooglePlayStoreSelected = Application.platform == RuntimePlatform.Android && module.androidStore == AndroidStore.GooglePlay; // CloudMoolah Configuration setings // All games must set the configuration. the configuration need to apply on the CloudMoolah Portal. // CloudMoolah APP Key builder.Configure <IMoolahConfiguration>().appKey = "d93f4564c41d463ed3d3cd207594ee1b"; // CloudMoolah Hash Key builder.Configure <IMoolahConfiguration>().hashKey = "cc"; // This enables the CloudMoolah test mode for local testing. // You would remove this, or set to CloudMoolahMode.Production, before building your release package. builder.Configure <IMoolahConfiguration>().SetMode(CloudMoolahMode.AlwaysSucceed); // This records whether we are using Cloud Moolah IAP. // Cloud Moolah requires logging in to access your Digital Wallet, so: // A) IAPDemo (this) displays the Cloud Moolah GUI button for Cloud Moolah m_IsCloudMoolahStoreSelected = Application.platform == RuntimePlatform.Android && module.androidStore == AndroidStore.CloudMoolah; // Define our products. // In this case our products have the same identifier across all the App stores, // except on the Mac App store where product IDs cannot be reused across both Mac and // iOS stores. // So on the Mac App store our products have different identifiers, // and we tell Unity IAP this by using the IDs class. builder.AddProduct("100.gold.coins", ProductType.Consumable, new IDs { { "100.gold.coins.mac", MacAppStore.Name }, { "000000596586", TizenStore.Name }, { "com.ff", MoolahAppStore.Name }, }); builder.AddProduct("500.gold.coins", ProductType.Consumable, new IDs { { "500.gold.coins.mac", MacAppStore.Name }, { "000000596581", TizenStore.Name }, { "com.ee", MoolahAppStore.Name }, }); builder.AddProduct("sword", ProductType.NonConsumable, new IDs { { "sword.mac", MacAppStore.Name }, { "000000596583", TizenStore.Name }, }); builder.AddProduct("subscription", ProductType.Subscription, new IDs { { "subscription.mac", MacAppStore.Name } }); // Write Amazon's JSON description of our products to storage when using Amazon's local sandbox. // This should be removed from a production build. builder.Configure <IAmazonConfiguration>().WriteSandboxJSON(builder.products); // This enables simulated purchase success for Samsung IAP. // You would remove this, or set to SamsungAppsMode.Production, before building your release package. builder.Configure <ISamsungAppsConfiguration>().SetMode(SamsungAppsMode.AlwaysSucceed); // This records whether we are using Samsung IAP. Currently ISamsungAppsExtensions.RestoreTransactions // displays a blocking Android Activity, so: // A) Unity IAP does not automatically restore purchases on Samsung Galaxy Apps // B) IAPDemo (this) displays the "Restore" GUI button for Samsung Galaxy Apps m_IsSamsungAppsStoreSelected = Application.platform == RuntimePlatform.Android && module.androidStore == AndroidStore.SamsungApps; // This selects the GroupId that was created in the Tizen Store for this set of products // An empty or non-matching GroupId here will result in no products available for purchase builder.Configure <ITizenStoreConfiguration>().SetGroupId("100000085616"); #if RECEIPT_VALIDATION validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), Application.bundleIdentifier); #endif // Now we're ready to initialize Unity IAP. UnityPurchasing.Initialize(this, builder); }
public void InitializePurchasing() { if (IsInitialized()) { return; } Debug.Log("!!!!!!!! InitializePurchasing"); var module = StandardPurchasingModule.Instance(); ConfigurationBuilder builder = ConfigurationBuilder.Instance(module); Debug.Log("!!!!!!!! CommonData.PURCHASE_ID_ARRAY[0]" + CommonData.PURCHASE_ID_ARRAY[0]); Debug.Log("!!!!!!!! CommonData.PURCHASE_ID_ARRAY[1]" + CommonData.PURCHASE_ID_ARRAY[1]); Debug.Log("!!!!!!!! CommonData.PURCHASE_ID_ARRAY[2]" + CommonData.PURCHASE_ID_ARRAY[2]); Debug.Log("!!!!!!!! CommonData.PURCHASE_ID_ARRAY[3]" + CommonData.PURCHASE_ID_ARRAY[3]); Debug.Log("!!!!!!!! CommonData.PURCHASE_ID_ARRAY[4]" + CommonData.PURCHASE_ID_ARRAY[4]); builder.AddProduct(CommonData.PURCHASE_ID_ARRAY[0], ProductType.Consumable, new IDs { { CommonData.PURCHASE_ID_ARRAY[0], AppleAppStore.Name }, { CommonData.PURCHASE_ID_ARRAY[0], GooglePlay.Name }, }); builder.AddProduct(CommonData.PURCHASE_ID_ARRAY[1], ProductType.Consumable, new IDs { { CommonData.PURCHASE_ID_ARRAY[1], AppleAppStore.Name }, { CommonData.PURCHASE_ID_ARRAY[1], GooglePlay.Name }, } ); builder.AddProduct(CommonData.PURCHASE_ID_ARRAY[2], ProductType.Consumable, new IDs { { CommonData.PURCHASE_ID_ARRAY[2], AppleAppStore.Name }, { CommonData.PURCHASE_ID_ARRAY[2], GooglePlay.Name }, }); builder.AddProduct(CommonData.PURCHASE_ID_ARRAY[3], ProductType.Consumable, new IDs { { CommonData.PURCHASE_ID_ARRAY[3], AppleAppStore.Name }, { CommonData.PURCHASE_ID_ARRAY[3], GooglePlay.Name }, }); builder.AddProduct(CommonData.PURCHASE_ID_ARRAY[4], ProductType.Consumable, new IDs { { CommonData.PURCHASE_ID_ARRAY[4], AppleAppStore.Name }, { CommonData.PURCHASE_ID_ARRAY[4], GooglePlay.Name }, }); builder.AddProduct(CommonData.PURCHASE_ID_ARRAY[5], ProductType.Consumable, new IDs { { CommonData.PURCHASE_ID_ARRAY[5], AppleAppStore.Name }, { CommonData.PURCHASE_ID_ARRAY[5], GooglePlay.Name }, }); builder.AddProduct(CommonData.PURCHASE_ID_ARRAY[6], ProductType.Consumable, new IDs { { CommonData.PURCHASE_ID_ARRAY[6], AppleAppStore.Name }, { CommonData.PURCHASE_ID_ARRAY[6], GooglePlay.Name }, }); /////////////////////////////////////////////////////////////////////////////////////// builder.AddProduct(CommonData.PURCHASE_DDONG_ARRAY[0], ProductType.Consumable, new IDs { { CommonData.PURCHASE_DDONG_ARRAY[0], AppleAppStore.Name }, { CommonData.PURCHASE_DDONG_ARRAY[0], GooglePlay.Name }, }); builder.AddProduct(CommonData.PURCHASE_DDONG_ARRAY[1], ProductType.Consumable, new IDs { { CommonData.PURCHASE_DDONG_ARRAY[1], AppleAppStore.Name }, { CommonData.PURCHASE_DDONG_ARRAY[1], GooglePlay.Name }, } ); builder.AddProduct(CommonData.PURCHASE_DDONG_ARRAY[2], ProductType.Consumable, new IDs { { CommonData.PURCHASE_DDONG_ARRAY[2], AppleAppStore.Name }, { CommonData.PURCHASE_DDONG_ARRAY[2], GooglePlay.Name }, }); builder.AddProduct(CommonData.PURCHASE_DDONG_ARRAY[3], ProductType.Consumable, new IDs { { CommonData.PURCHASE_DDONG_ARRAY[3], AppleAppStore.Name }, { CommonData.PURCHASE_DDONG_ARRAY[3], GooglePlay.Name }, }); builder.AddProduct(CommonData.PURCHASE_DDONG_ARRAY[4], ProductType.Consumable, new IDs { { CommonData.PURCHASE_DDONG_ARRAY[4], AppleAppStore.Name }, { CommonData.PURCHASE_DDONG_ARRAY[4], GooglePlay.Name }, }); builder.AddProduct(CommonData.PURCHASE_DDONG_ARRAY[5], ProductType.Consumable, new IDs { { CommonData.PURCHASE_DDONG_ARRAY[5], AppleAppStore.Name }, { CommonData.PURCHASE_DDONG_ARRAY[5], GooglePlay.Name }, }); builder.AddProduct(CommonData.PURCHASE_DDONG_ARRAY[6], ProductType.Consumable, new IDs { { CommonData.PURCHASE_DDONG_ARRAY[6], AppleAppStore.Name }, { CommonData.PURCHASE_DDONG_ARRAY[6], GooglePlay.Name }, }); UnityPurchasing.Initialize(this, builder); }
public void Awake() { var module = StandardPurchasingModule.Instance(); // The FakeStore supports: no-ui (always succeeding), basic ui (purchase pass/fail), and // developer ui (initialization, purchase, failure code setting). These correspond to // the FakeStoreUIMode Enum values passed into StandardPurchasingModule.useFakeStoreUIMode. module.useFakeStoreUIMode = FakeStoreUIMode.StandardUser; var builder = ConfigurationBuilder.Instance(module); // This enables the Microsoft IAP simulator for local testing. // You would remove this before building your release package. builder.Configure <IMicrosoftConfiguration>().useMockBillingSystem = true; m_IsGooglePlayStoreSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.GooglePlay; // CloudMoolah Configuration setings // All games must set the configuration. the configuration need to apply on the CloudMoolah Portal. // CloudMoolah APP Key builder.Configure <IMoolahConfiguration>().appKey = "d93f4564c41d463ed3d3cd207594ee1b"; // CloudMoolah Hash Key builder.Configure <IMoolahConfiguration>().hashKey = "cc"; // This enables the CloudMoolah test mode for local testing. // You would remove this, or set to CloudMoolahMode.Production, before building your release package. builder.Configure <IMoolahConfiguration>().SetMode(CloudMoolahMode.AlwaysSucceed); // This records whether we are using Cloud Moolah IAP. // Cloud Moolah requires logging in to access your Digital Wallet, so: // A) IAPDemo (this) displays the Cloud Moolah GUI button for Cloud Moolah m_IsCloudMoolahStoreSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.CloudMoolah; // UnityChannel, provides access to Xiaomi MiPay. // Products are required to be set in the IAP Catalog window. The file "MiProductCatalog.prop" // is required to be generated into the project's // Assets/Plugins/Android/assets folder, based off the contents of the // IAP Catalog window, for MiPay. m_IsUnityChannelSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.XiaomiMiPay; // UnityChannel supports receipt validation through a backend fetch. builder.Configure <IUnityChannelConfiguration>().fetchReceiptPayloadOnPurchase = m_FetchReceiptPayloadOnPurchase; // Define our products. // Either use the Unity IAP Catalog, or manually use the ConfigurationBuilder.AddProduct API. // Use IDs from both the Unity IAP Catalog and hardcoded IDs via the ConfigurationBuilder.AddProduct API. // Use the products defined in the IAP Catalog GUI. // E.g. Menu: "Window" > "Unity IAP" > "IAP Catalog", then add products, then click "App Store Export". var catalog = ProductCatalog.LoadDefaultCatalog(); foreach (var product in catalog.allProducts) { if (product.allStoreIDs.Count > 0) { var ids = new IDs(); foreach (var storeID in product.allStoreIDs) { ids.Add(storeID.id, storeID.store); } builder.AddProduct(product.id, product.type, ids); } else { builder.AddProduct(product.id, product.type); } } // In this case our products have the same identifier across all the App stores, // except on the Mac App store where product IDs cannot be reused across both Mac and // iOS stores. // So on the Mac App store our products have different identifiers, // and we tell Unity IAP this by using the IDs class. builder.AddProduct("100.gold.coins", ProductType.Consumable, new IDs { { "100.gold.coins.mac", MacAppStore.Name }, { "000000596586", TizenStore.Name }, { "com.ff", MoolahAppStore.Name }, } #if USE_PAYOUTS , new PayoutDefinition(PayoutType.Currency, "gold", 100) #endif //USE_PAYOUTS ); builder.AddProduct("500.gold.coins", ProductType.Consumable, new IDs { { "500.gold.coins.mac", MacAppStore.Name }, { "000000596581", TizenStore.Name }, { "com.ee", MoolahAppStore.Name }, } #if USE_PAYOUTS , new PayoutDefinition(PayoutType.Currency, "gold", 500) #endif //USE_PAYOUTS ); builder.AddProduct("sword", ProductType.NonConsumable, new IDs { { "sword.mac", MacAppStore.Name }, { "000000596583", TizenStore.Name }, } #if USE_PAYOUTS , new List <PayoutDefinition> { new PayoutDefinition(PayoutType.Item, "", 1, "item_id:76543"), new PayoutDefinition(PayoutType.Currency, "gold", 50) } #endif //USE_PAYOUTS ); builder.AddProduct("subscription", ProductType.Subscription, new IDs { { "subscription.mac", MacAppStore.Name } }); // Write Amazon's JSON description of our products to storage when using Amazon's local sandbox. // This should be removed from a production build. builder.Configure <IAmazonConfiguration>().WriteSandboxJSON(builder.products); // This enables simulated purchase success for Samsung IAP. // You would remove this, or set to SamsungAppsMode.Production, before building your release package. builder.Configure <ISamsungAppsConfiguration>().SetMode(SamsungAppsMode.AlwaysSucceed); // This records whether we are using Samsung IAP. Currently ISamsungAppsExtensions.RestoreTransactions // displays a blocking Android Activity, so: // A) Unity IAP does not automatically restore purchases on Samsung Galaxy Apps // B) IAPDemo (this) displays the "Restore" GUI button for Samsung Galaxy Apps m_IsSamsungAppsStoreSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.SamsungApps; // This selects the GroupId that was created in the Tizen Store for this set of products // An empty or non-matching GroupId here will result in no products available for purchase builder.Configure <ITizenStoreConfiguration>().SetGroupId("100000085616"); #if RECEIPT_VALIDATION string appIdentifier; #if UNITY_5_6_OR_NEWER appIdentifier = Application.identifier; #else appIdentifier = Application.bundleIdentifier; #endif validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), UnityChannelTangle.Data(), appIdentifier); #endif Action initializeUnityIap = () => { // Now we're ready to initialize Unity IAP. UnityPurchasing.Initialize(this, builder); }; bool needExternalLogin = m_IsUnityChannelSelected; if (!needExternalLogin) { initializeUnityIap(); } else { // Call UnityChannel initialize and (later) login asynchronously // UnityChannel configuration settings. Required for Xiaomi MiPay. // Collect this app configuration from the Unity Developer website at // [2017-04-17 PENDING - Contact support representative] // https://developer.cloud.unity3d.com/ providing your Xiaomi MiPay App // ID, App Key, and App Secret. This permits Unity to proxy from the // user's device into the MiPay system. // IMPORTANT PRE-BUILD STEP: For mandatory Chinese Government app auditing // and for MiPay testing, enable debug mode (test mode) // using the `AppInfo.debug = true;` when initializing Unity Channel. AppInfo unityChannelAppInfo = new AppInfo(); unityChannelAppInfo.appId = "abc123appId"; unityChannelAppInfo.appKey = "efg456appKey"; unityChannelAppInfo.clientId = "hij789clientId"; unityChannelAppInfo.clientKey = "klm012clientKey"; unityChannelAppInfo.debug = false; // Shared handler for Unity Channel initialization, here, and login, later unityChannelLoginHandler = new UnityChannelLoginHandler(); unityChannelLoginHandler.initializeFailedAction = (string message) => { Debug.LogError("Failed to initialize and login to UnityChannel: " + message); }; unityChannelLoginHandler.initializeSucceededAction = () => { initializeUnityIap(); }; StoreService.Initialize(unityChannelAppInfo, unityChannelLoginHandler); } }
void InitializePurchasing() { if (!IsPurchasingInitialized()) { ConfigurationBuilder configurationBuilder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); foreach (ProductDesc product in data.products) { configurationBuilder.AddProduct( product.id, product.type, new IDs { { product.id + postfixAppStore, AppleAppStore.Name }, { product.id + postfixGooglePlay, GooglePlay.Name } } ); } UnityPurchasing.Initialize(this, configurationBuilder); } }
void IStore.LoadProducts(Action onComplete, Action onFailure) { var purchasingModule = StandardPurchasingModule.Instance(); var builder = ConfigurationBuilder.Instance(purchasingModule); var appleConfiguration = builder.Configure <IAppleConfiguration>(); if (!appleConfiguration.canMakePayments) { var exception = new NotSupportedException($"\"{nameof(IAppleConfiguration)}.{nameof(IAppleConfiguration.canMakePayments)}\" is false!"); ExceptionHandler.Process(exception); onFailure(); return; } foreach (var(ProductId, ProductType) in ProductMap) { builder.AddProduct(ProductId, ProductType); } _storeListener = new StoreListener(); _storeListener.Initialized += OnInitialized; _storeListener.InitializeFailed += OnInitializeFailed; UnityPurchasing.Initialize(_storeListener, builder); void OnInitialized(object sender, InitializedEventArgs eventArgs) { _storeListener.Initialized -= OnInitialized; _storeListener.InitializeFailed -= OnInitializeFailed; _appleExtensions = eventArgs.AppleExtensions; _storeController = eventArgs.StoreController; PlayFabStore.LoadProducts( () => { ModifyProducts(); onComplete(); }, onFailure); } void OnInitializeFailed(object sender, InitializeFailedEventArgs eventArgs) { _storeListener.Initialized -= OnInitialized; _storeListener.InitializeFailed -= OnInitializeFailed; var exception = new Exception($"UnityPurchasing initialization failure! InitializationFailureReason: \"{eventArgs.InitializationFailureReason}\""); ExceptionHandler.Process(exception); onFailure(); } void ModifyProducts() { foreach (PlayFabProduct product in PlayFabStore.Products) { product.Purchase = Purchase; var itemId = PlayFabStore.GetItemId(((IProduct)product).Id); if (string.IsNullOrWhiteSpace(itemId)) { continue; } var uProduct = FindProduct(itemId); if (uProduct == null) { continue; } var currencyId = PlayFabStore.GetCurrencyId("RM"); var metadata = uProduct.metadata; var price = Convert.ToUInt32(metadata.localizedPrice * 100m); product.SetPrice(currencyId, price, metadata.isoCurrencyCode); } } }
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Purchasing; public class IAPManager : MonoBehaviour, IStoreListener { // Placing the Purchaser class in the CompleteProject namespace allows it to interact with ScoreManager, // one of the existing Survival Shooter scripts. // Deriving the Purchaser class from IStoreListener enables it to receive messages from Unity Purchasing. private static IStoreController m_StoreController; // The Unity Purchasing system. private static IExtensionProvider m_StoreExtensionProvider; // The store-specific Purchasing subsystems. // Product identifiers for all products capable of being purchased: // "convenience" general identifiers for use with Purchasing, and their store-specific identifier // counterparts for use with and outside of Unity Purchasing. Define store-specific identifiers // also on each platform's publisher dashboard (iTunes Connect, Google Play Developer Console, etc.) // General product identifiers for the consumable, non-consumable, and subscription products. // Use these handles in the code to reference which product to purchase. Also use these values // when defining the Product Identifiers on the store. Except, for illustration purposes, the // kProductIDSubscription - it has custom Apple and Google identifiers. We declare their store- // specific mapping to Unity Purchasing's AddProduct, below. //public static string kProductIDConsumable = "consumable"; public static string kProductIDNonConsumable = "noads"; //public static string kProductIDSubscription = "subscription"; // Apple App Store-specific product identifier for the subscription product. //private static string kProductNameAppleSubscription = "com.unity3d.subscription.new"; // Google Play Store-specific product identifier subscription product. //private static string kProductNameGooglePlaySubscription = "com.SushrutS.TowerTrouble.noads"; void Start() { // If we haven't set up the Unity Purchasing reference if (m_StoreController == null) { // Begin to configure our connection to Purchasing InitializePurchasing(); } } public void InitializePurchasing() { // If we have already connected to Purchasing ... if (IsInitialized()) { // ... we are done here. return; } // Create a builder, first passing in a suite of Unity provided stores. var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); // Add a product to sell / restore by way of its identifier, associating the general identifier // with its store-specific identifiers. //builder.AddProduct( kProductIDConsumable, ProductType.Consumable ); // Continue adding the non-consumable product. builder.AddProduct( kProductIDNonConsumable, ProductType.NonConsumable ); // And finish adding the subscription product. Notice this uses store-specific IDs, illustrating // if the Product ID was configured differently between Apple and Google stores. Also note that // one uses the general kProductIDSubscription handle inside the game - the store-specific IDs // must only be referenced here. //builder.AddProduct( kProductIDSubscription, ProductType.Subscription, new IDs(){ // { kProductNameAppleSubscription, AppleAppStore.Name }, // { kProductNameGooglePlaySubscription, GooglePlay.Name }, // } ); // Kick off the remainder of the set-up with an asynchrounous call, passing the configuration // and this class' instance. Expect a response either in OnInitialized or OnInitializeFailed. UnityPurchasing.Initialize( this, builder ); } private bool IsInitialized() { // Only say we are initialized if both the Purchasing references are set. return m_StoreController != null && m_StoreExtensionProvider != null; } public void BuyConsumable() { // Buy the consumable product using its general identifier. Expect a response either // through ProcessPurchase or OnPurchaseFailed asynchronously. //BuyProductID( kProductIDConsumable ); } public void BuyNonConsumable() { // Buy the non-consumable product using its general identifier. Expect a response either // through ProcessPurchase or OnPurchaseFailed asynchronously. BuyProductID( kProductIDNonConsumable ); } public void BuySubscription() { // Buy the subscription product using its the general identifier. Expect a response either // through ProcessPurchase or OnPurchaseFailed asynchronously. // Notice how we use the general product identifier in spite of this ID being mapped to // custom store-specific identifiers above. //BuyProductID( kProductIDSubscription ); } void BuyProductID(string productId) { // If Purchasing has been initialized ... if (IsInitialized()) { // ... look up the Product reference with the general product identifier and the Purchasing // system's products collection. Product product = m_StoreController.products.WithID(productId); // If the look up found a product for this device's store and that product is ready to be sold ... if (product != null && product.availableToPurchase) { Debug.Log( string.Format( "Purchasing product asychronously: '{0}'", product.definition.id ) ); // ... buy the product. Expect a response either through ProcessPurchase or OnPurchaseFailed // asynchronously. m_StoreController.InitiatePurchase( product ); } // Otherwise ... else { // ... report the product look-up failure situation Debug.Log( "BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase" ); } } // Otherwise ... else { // ... report the fact Purchasing has not succeeded initializing yet. Consider waiting longer or // retrying initiailization. Debug.Log( "BuyProductID FAIL. Not initialized." ); } } // Restore purchases previously made by this customer. Some platforms automatically restore purchases, like Google. // Apple currently requires explicit purchase restoration for IAP, conditionally displaying a password prompt. public void RestorePurchases() { // If Purchasing has not yet been set up ... if (!IsInitialized()) { // ... report the situation and stop restoring. Consider either waiting longer, or retrying initialization. Debug.Log( "RestorePurchases FAIL. Not initialized." ); return; } // If we are running on an Apple device ... if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.OSXPlayer) { // ... begin restoring purchases Debug.Log( "RestorePurchases started ..." ); // Fetch the Apple store-specific subsystem. var apple = m_StoreExtensionProvider.GetExtension<IAppleExtensions>(); // Begin the asynchronous process of restoring purchases. Expect a confirmation response in // the Action<bool> below, and ProcessPurchase if there are previously purchased products to restore. apple.RestoreTransactions( (result) => { // The first phase of restoration. If no more responses are received on ProcessPurchase then // no purchases are available to be restored. Debug.Log( "RestorePurchases continuing: " + result + ". If no further messages, no purchases available to restore." ); } ); } // Otherwise ... else { // We are not running on an Apple device. No work is necessary to restore purchases. Debug.Log( "RestorePurchases FAIL. Not supported on this platform. Current = " + Application.platform ); } } // // --- IStoreListener // public void OnInitialized(IStoreController controller, IExtensionProvider extensions) { // Purchasing has succeeded initializing. Collect our Purchasing references. Debug.Log( "OnInitialized: PASS" ); // Overall Purchasing system, configured with products for this application. m_StoreController = controller; // Store specific subsystem, for accessing device-specific store features. m_StoreExtensionProvider = extensions; } public void OnInitializeFailed(InitializationFailureReason error) { // Purchasing set-up has not succeeded. Check error for reason. Consider sharing this reason with the user. Debug.Log( "OnInitializeFailed InitializationFailureReason:" + error ); } public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) { // A consumable product has been purchased by this user. //if (String.Equals( args.purchasedProduct.definition.id, kProductIDConsumable, StringComparison.Ordinal )) //{ // Debug.Log( string.Format( "ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id ) ); // // The consumable item has been successfully purchased, add 100 coins to the player's in-game score. // //ScoreManager.score += 100; //} //// Or ... a non-consumable product has been purchased by this user. //else if (String.Equals( args.purchasedProduct.definition.id, kProductIDNonConsumable, StringComparison.Ordinal )) { Debug.Log( string.Format( "ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id ) ); PurchaseComplete(); // TODO: The non-consumable item has been successfully purchased, grant this item to the player. } // Or ... a subscription product has been purchased by this user. //else if (String.Equals( args.purchasedProduct.definition.id, kProductIDSubscription, StringComparison.Ordinal )) //{ // Debug.Log( string.Format( "ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id ) ); // // TODO: The subscription item has been successfully purchased, grant this to the player. //} // Or ... an unknown product has been purchased by this user. Fill in additional products here.... else { Debug.Log( string.Format( "ProcessPurchase: FAIL. Unrecognized product: '{0}'", args.purchasedProduct.definition.id ) ); UIScript.instance.SetPurchaseState( "UnKnown Product" ); } // Return a flag indicating whether this product has completely been received, or if the application needs // to be reminded of this purchase at next app launch. Use PurchaseProcessingResult.Pending when still // saving purchased products to the cloud, and when that save is delayed. return PurchaseProcessingResult.Complete; } public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) { // A product purchase attempt did not succeed. Check failureReason for more detail. Consider sharing // this reason with the user to guide their troubleshooting actions. Debug.Log( string.Format( "OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: {1}", product.definition.storeSpecificId, failureReason ) ); UIScript.instance.SetPurchaseState( "PUrchase Failed" + failureReason ); if(failureReason == PurchaseFailureReason.DuplicateTransaction)
static bool IsGooglePlayStoreSelected() { var currentAppStore = StandardPurchasingModule.Instance().appStore; return(currentAppStore == AppStore.GooglePlay); }
/// <summary> 초기화 부분 </summary> public void InitializePurchasing() { if (IsInitialized()) { return; } var module = StandardPurchasingModule.Instance(); isGooglePlayStoreSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.GooglePlay; isAppStoreSelected = Application.platform == RuntimePlatform.IPhonePlayer && module.appStore == AppStore.AppleAppStore; //구글 라이센싱 키는 windows>UnityIAP>Receipt Valiudation Obfuscator에 저장하면됨 var builder = ConfigurationBuilder.Instance(module); //스크립트로 저장하는 방법 //builder.Configure<IGooglePlayConfiguration>().SetPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmpZIPAm274xieiBOY34hUoNqbwPVdWLLzuWBcG8sitdlenSEJXsMLSphFD5Wo57gVVS7v1MCqObnVhO4JnLUUdulcIDpiZPM85NM3w8yXiJ9iyF6v5z8mf6ULp/d+/akB13dl+0TVeDNyABJ7tFYYn1tYu0ivh0lSQ/t9jMRVnXcMCNInvkGACRmgyNUH0Kc0XVxoxcRpV1xDvaR4u2HxN5duUdkYE0y9lFozhXBjJTz2Okaz/vKkN5t2gtxqvr2Zza0sOqyTJHVaT5JksSgfP1Qo1zRqQepz4zxmkKDFfjO5keH72uh2/dT0SYg6DHQMJeilatq3/s48W0fOx7gAQIDAQAB"); //아이템들 등록 builder.AddProduct(productID100ruby, ProductType.Consumable, new IDs() { { productApple100ruby, AppleAppStore.Name }, { productGooglePlay100ruby, GooglePlay.Name } }); builder.AddProduct(productID300ruby, ProductType.Consumable, new IDs() { { productApple300ruby, AppleAppStore.Name }, { productGooglePlay300ruby, GooglePlay.Name } }); builder.AddProduct(productID500ruby, ProductType.Consumable, new IDs() { { productApple500ruby, AppleAppStore.Name }, { productGooglePlay500ruby, GooglePlay.Name } }); builder.AddProduct(productID1000ruby, ProductType.Consumable, new IDs() { { productApple1000ruby, AppleAppStore.Name }, { productGooglePlay1000ruby, GooglePlay.Name } }); builder.AddProduct(productID3000ruby, ProductType.Consumable, new IDs() { { productApple3000ruby, AppleAppStore.Name }, { productGooglePlay3000ruby, GooglePlay.Name } }); builder.AddProduct(productID5000ruby, ProductType.Consumable, new IDs() { { productApple5000ruby, AppleAppStore.Name }, { productGooglePlay5000ruby, GooglePlay.Name } }); builder.AddProduct(productID10000ruby, ProductType.Consumable, new IDs() { { productApple10000ruby, AppleAppStore.Name }, { productGooglePlay10000ruby, GooglePlay.Name } }); builder.AddProduct(productApple100rubyDouble, ProductType.Consumable, new IDs() { { productApple100rubyDouble, AppleAppStore.Name }, { productGooglePlay100rubyDouble, GooglePlay.Name } }); builder.AddProduct(productID300rubyDouble, ProductType.Consumable, new IDs() { { productApple300rubyDouble, AppleAppStore.Name }, { productGooglePlay300rubyDouble, GooglePlay.Name } }); builder.AddProduct(productID500rubyDouble, ProductType.Consumable, new IDs() { { productApple500rubyDouble, AppleAppStore.Name }, { productGooglePlay500rubyDouble, GooglePlay.Name } }); builder.AddProduct(productID1000rubyDouble, ProductType.Consumable, new IDs() { { productApple1000rubyDouble, AppleAppStore.Name }, { productGooglePlay1000rubyDouble, GooglePlay.Name } }); builder.AddProduct(productID3000rubyDouble, ProductType.Consumable, new IDs() { { productApple3000rubyDouble, AppleAppStore.Name }, { productGooglePlay3000rubyDouble, GooglePlay.Name } }); builder.AddProduct(productID5000rubyDouble, ProductType.Consumable, new IDs() { { productApple5000rubyDouble, AppleAppStore.Name }, { productGooglePlay5000rubyDouble, GooglePlay.Name } }); builder.AddProduct(productID10000rubyDouble, ProductType.Consumable, new IDs() { { productApple10000rubyDouble, AppleAppStore.Name }, { productGooglePlay10000rubyDouble, GooglePlay.Name } }); builder.AddProduct(productIDPackage1, ProductType.Consumable, new IDs() { { productApplePackage1, AppleAppStore.Name }, { productGooglePlayPackage1, GooglePlay.Name } }); builder.AddProduct(productIDFixedCharge1, ProductType.Consumable, new IDs() { { productAppleFixedCharge1, AppleAppStore.Name }, { productGooglePlayFixedCharge1, GooglePlay.Name } }); UnityPurchasing.Initialize(this, builder); }
public void InitializePurchasing() { if (!IsInitialized()) { ConfigurationBuilder configurationBuilder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); configurationBuilder.AddProduct(coinpack1, ProductType.Consumable); configurationBuilder.AddProduct(coinpack2, ProductType.Consumable); configurationBuilder.AddProduct(coinpack3, ProductType.Consumable); configurationBuilder.AddProduct(coinpack4, ProductType.Consumable); configurationBuilder.AddProduct(coinpack5, ProductType.Consumable); configurationBuilder.AddProduct(removeads, ProductType.NonConsumable); configurationBuilder.AddProduct(subscription, ProductType.Subscription); configurationBuilder.AddProduct(trialsubscription, ProductType.Subscription); UnityPurchasing.Initialize(this, configurationBuilder); } }
public void Awake() { var module = StandardPurchasingModule.Instance(); // The FakeStore supports: no-ui (always succeeding), basic ui (purchase pass/fail), and // developer ui (initialization, purchase, failure code setting). These correspond to // the FakeStoreUIMode Enum values passed into StandardPurchasingModule.useFakeStoreUIMode. //FakeStore支持:无ui(总是成功)、基本ui(购买/失败),以及 //开发人员ui(初始化、购买、失败代码设置)。这些对应于 //传递给StandardPurchasingModule.useFakeStoreUIMode FakeStoreUIMode枚举值。 //module.useFakeStoreUIMode = FakeStoreUIMode.StandardUser; var builder = ConfigurationBuilder.Instance(module); // This enables the Microsoft IAP simulator for local testing. // You would remove this before building your release package. //这使Microsoft IAP模拟器能够进行本地测试。 //您将在构建您的发布包之前删除它。 builder.Configure <IMicrosoftConfiguration>().useMockBillingSystem = true; //m_IsGooglePlayStoreSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.GooglePlay; // CloudMoolah Configuration setings // All games must set the configuration. the configuration need to apply on the CloudMoolah Portal. // CloudMoolah APP Key //CloudMoolah配置设置 //所有的游戏都必须设定配置。配置需要在CloudMoolah门户上应用。 ////CloudMoolah应用的key //builder.Configure<IMoolahConfiguration>().appKey = "d93f4564c41d463ed3d3cd207594ee1b"; //// CloudMoolah Hash Key //builder.Configure<IMoolahConfiguration>().hashKey = "cc"; // This enables the CloudMoolah test mode for local testing. // You would remove this, or set to CloudMoolahMode.Production, before building your release package. //这使得CloudMoolah测试模式能够进行本地测试。 ////您可以删除这个,或者设置为CloudMoolahMode。在构建您的发布包之前,生产。 //builder.Configure<IMoolahConfiguration>().SetMode(CloudMoolahMode.AlwaysSucceed); // This records whether we are using Cloud Moolah IAP. // Cloud Moolah requires logging in to access your Digital Wallet, so: // A) IAPDemo (this) displays the Cloud Moolah GUI button for Cloud Moolah //这记录了我们是否使用了Cloud Moolah IAP。 //云Moolah需要登录才能进入你的数字钱包,所以: ////A)IAPDemo(这)显示云Moolah GUI按钮 //m_IsCloudMoolahStoreSelected = // Application.platform == RuntimePlatform.Android && module.appStore == AppStore.CloudMoolah; // UnityChannel, provides access to Xiaomi MiPay. // Products are required to be set in the IAP Catalog window. The file "MiProductCatalog.prop" // is required to be generated into the project's // Assets/Plugins/Android/assets folder, based off the contents of the // IAP Catalog window, for MiPay. //UnityChannel,提供对小米MiPay的访问。 //产品需要在IAP目录窗口中设置。文件“MiProductCatalog.prop” //需要被生成到项目中 //资产 / 插件 / Android / 文件夹,基础的内容 //IAP目录窗口,为MiPay。 m_IsUnityChannelSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.XiaomiMiPay; // UnityChannel supports receipt validation through a backend fetch. //UnityChannel通过后台取回支持接收验证。 builder.Configure <IUnityChannelConfiguration>().fetchReceiptPayloadOnPurchase = m_FetchReceiptPayloadOnPurchase; // Define our products. // Either use the Unity IAP Catalog, or manually use the ConfigurationBuilder.AddProduct API. // Use IDs from both the Unity IAP Catalog and hardcoded IDs via the ConfigurationBuilder.AddProduct API. // Use the products defined in the IAP Catalog GUI. // E.g. Menu: "Window" > "Unity IAP" > "IAP Catalog", then add products, then click "App Store Export". // 定义我们的产品。 //使用统一的IAP目录,或者手动使用配置构建器。AddProduct API。 //通过配置构建器从Unity IAP目录和硬编码的IDs中使用id。AddProduct API。 //使用在IAP目录GUI中定义的产品。 //例如菜单:“窗口”“统一IAP目录”,然后添加产品,然后点击“App Store导出”。 var catalog = ProductCatalog.LoadDefaultCatalog(); foreach (var product in catalog.allProducts) { if (product.allStoreIDs.Count > 0) { var ids = new IDs(); foreach (var storeID in product.allStoreIDs) { ids.Add(storeID.id, storeID.store); } builder.AddProduct(product.id, product.type, ids); } else { builder.AddProduct(product.id, product.type); } } // In this case our products have the same identifier across all the App stores, // except on the Mac App store where product IDs cannot be reused across both Mac and // iOS stores. // So on the Mac App store our products have different identifiers, // and we tell Unity IAP this by using the IDs class. //在这种情况下,我们的产品在所有应用商店中都有相同的标识符, //除了Mac App store,产品id不能在Mac和Mac上重复使用 //iOS商店。在Mac App store中,我们的产品有不同的标识符, //我们通过使用IDs类来告诉Unity IAP。 builder.AddProduct("100.gold.coins", ProductType.Consumable, new IDs { { "100.gold.coins.mac", MacAppStore.Name }, { "000000596586", TizenStore.Name }, { "com.ff", MoolahAppStore.Name }, } #if USE_PAYOUTS , new PayoutDefinition(PayoutType.Currency, "gold", 100) #endif //USE_PAYOUTS ); builder.AddProduct("500.gold.coins", ProductType.Consumable, new IDs { { "500.gold.coins.mac", MacAppStore.Name }, { "000000596581", TizenStore.Name }, { "com.ee", MoolahAppStore.Name }, } #if USE_PAYOUTS , new PayoutDefinition(PayoutType.Currency, "gold", 500) #endif //USE_PAYOUTS ); builder.AddProduct("sword", ProductType.NonConsumable, new IDs { { "sword.mac", MacAppStore.Name }, { "000000596583", TizenStore.Name }, } #if USE_PAYOUTS , new List <PayoutDefinition> { new PayoutDefinition(PayoutType.Item, "", 1, "item_id:76543"), new PayoutDefinition(PayoutType.Currency, "gold", 50) } #endif //USE_PAYOUTS ); builder.AddProduct("subscription", ProductType.Subscription, new IDs { { "subscription.mac", MacAppStore.Name } }); // Write Amazon's JSON description of our products to storage when using Amazon's local sandbox. // This should be removed from a production build. //在使用亚马逊的本地沙盒时,将亚马逊的JSON描述写入到存储中。 //这应该从生产构建中删除。 //builder.Configure<IAmazonConfiguration>().WriteSandboxJSON(builder.products); // This enables simulated purchase success for Samsung IAP. // You would remove this, or set to SamsungAppsMode.Production, before building your release package. //这为三星IAP提供了模拟的购买成功。 //你可以把它移开,或者把它调到三星。在构建您的发布包之前,生产。 // builder.Configure<ISamsungAppsConfiguration>().SetMode(SamsungAppsMode.AlwaysSucceed); // This records whether we are using Samsung IAP. Currently ISamsungAppsExtensions.RestoreTransactions // displays a blocking Android Activity, so: // A) Unity IAP does not automatically restore purchases on Samsung Galaxy Apps // B) IAPDemo (this) displays the "Restore" GUI button for Samsung Galaxy Apps //这记录了我们是否在使用三星IAP。目前ISamsungAppsExtensions.RestoreTransactions //显示一个阻塞的Android活动,所以: //A)统一IAP不会自动恢复三星Galaxy应用程序的购买 //B)IAPDemo(这)显示了三星Galaxy应用的“恢复”GUI按钮 //m_IsSamsungAppsStoreSelected = // Application.platform == RuntimePlatform.Android && module.appStore == AppStore.SamsungApps; // This selects the GroupId that was created in the Tizen Store for this set of products // An empty or non-matching GroupId here will result in no products available for purchase //它选择了在Tizen商店中为这组产品创建的GroupId //一个空的或非匹配的GroupId将导致没有可供购买的产品 //builder.Configure<ITizenStoreConfiguration>().SetGroupId("100000085616"); #if RECEIPT_VALIDATION string appIdentifier; #if UNITY_5_6_OR_NEWER appIdentifier = Application.identifier; #else appIdentifier = Application.bundleIdentifier; #endif validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), UnityChannelTangle.Data(), appIdentifier); #endif Action initializeUnityIap = () => { // Now we're ready to initialize Unity IAP. UnityPurchasing.Initialize(this, builder); }; bool needExternalLogin = m_IsUnityChannelSelected; if (!needExternalLogin) { initializeUnityIap(); } else { // Call UnityChannel initialize and (later) login asynchronously // UnityChannel configuration settings. Required for Xiaomi MiPay. // Collect this app configuration from the Unity Developer website at // [2017-04-17 PENDING - Contact support representative] // https://developer.cloud.unity3d.com/ providing your Xiaomi MiPay App // ID, App Key, and App Secret. This permits Unity to proxy from the // user's device into the MiPay system. // IMPORTANT PRE-BUILD STEP: For mandatory Chinese Government app auditing // and for MiPay testing, enable debug mode (test mode) // using the `AppInfo.debug = true;` when initializing Unity Channel. //调用UnityChannel初始化和(稍后)异步登录 // UnityChannel配置设置。小米所需MiPay。 //从Unity开发者网站收集这个应用程序配置 //2017-04-17等待-联络支持代表 // https://developer.cloud.unity3d.com/提供你小米MiPay应用 //ID、应用程序密钥和应用程序秘密。这使得联合可以从 //用户的设备进入MiPay系统。 //重要的预构建步骤:中国强制性的政府应用审核 //对于MiPay测试,启用调试模式(测试模式) //使用AppInfo.debug=true;初始化统一通道时。 AppInfo unityChannelAppInfo = new AppInfo(); unityChannelAppInfo.appId = "abc123appId"; unityChannelAppInfo.appKey = "efg456appKey"; unityChannelAppInfo.clientId = "hij789clientId"; unityChannelAppInfo.clientKey = "klm012clientKey"; unityChannelAppInfo.debug = false; // Shared handler for Unity Channel initialization, here, and login, later unityChannelLoginHandler = new UnityChannelLoginHandler(); unityChannelLoginHandler.initializeFailedAction = (string message) => { Debug.LogError("Failed to initialize and login to UnityChannel: " + message); }; unityChannelLoginHandler.initializeSucceededAction = () => { initializeUnityIap(); }; StoreService.Initialize(unityChannelAppInfo, unityChannelLoginHandler); } }
/// <summary> /// Awake is called when the script instance is being loaded. /// </summary> public void Awake() { var module = StandardPurchasingModule.Instance(); // The FakeStore supports: no-ui (always succeeding), basic ui (purchase pass/fail), and // developer ui (initialization, purchase, failure code setting). These correspond to // the FakeStoreUIMode Enum values passed into StandardPurchasingModule.useFakeStoreUIMode. module.useFakeStoreUIMode = FakeStoreUIMode.StandardUser; var builder = ConfigurationBuilder.Instance(module); // Set this to true to enable the Microsoft IAP simulator for local testing. builder.Configure <IMicrosoftConfiguration>().useMockBillingSystem = false; m_IsGooglePlayStoreSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.GooglePlay; // Define our products. // Either use the Unity IAP Catalog, or manually use the ConfigurationBuilder.AddProduct API. // Use IDs from both the Unity IAP Catalog and hardcoded IDs via the ConfigurationBuilder.AddProduct API. // Use the products defined in the IAP Catalog GUI. // E.g. Menu: "Window" > "Unity IAP" > "IAP Catalog", then add products, then click "App Store Export". var catalog = ProductCatalog.LoadDefaultCatalog(); foreach (var product in catalog.allValidProducts) { if (product.allStoreIDs.Count > 0) { var ids = new IDs(); foreach (var storeID in product.allStoreIDs) { ids.Add(storeID.id, storeID.store); } builder.AddProduct(product.id, product.type, ids); } else { builder.AddProduct(product.id, product.type); } } // In this case our products have the same identifier across all the App stores, // except on the Mac App store where product IDs cannot be reused across both Mac and // iOS stores. // So on the Mac App store our products have different identifiers, // and we tell Unity IAP this by using the IDs class. builder.AddProduct("100.gold.coins", ProductType.Consumable, new IDs { { "com.unity3d.unityiap.unityiapdemo.100goldcoins.7", MacAppStore.Name }, { "100.gold.coins", AmazonApps.Name }, { "100.gold.coins", AppleAppStore.Name } } #if USE_PAYOUTS , new List <PayoutDefinition> { new PayoutDefinition(PayoutType.Item, "", 1, "item_id:76543"), new PayoutDefinition(PayoutType.Currency, "gold", 50) } #endif //USE_PAYOUTS ); builder.AddProduct("500.gold.coins", ProductType.Consumable, new IDs { { "com.unity3d.unityiap.unityiapdemo.500goldcoins.7", MacAppStore.Name }, { "500.gold.coins", AmazonApps.Name }, } #if USE_PAYOUTS , new PayoutDefinition(PayoutType.Currency, "gold", 500) #endif //USE_PAYOUTS ); builder.AddProduct("300.gold.coins", ProductType.Consumable, new IDs { } #if USE_PAYOUTS , new List <PayoutDefinition> { new PayoutDefinition(PayoutType.Item, "", 1, "item_id:76543"), new PayoutDefinition(PayoutType.Currency, "gold", 50) } #endif //USE_PAYOUTS ); builder.AddProduct("sub1", ProductType.Subscription, new IDs { }); builder.AddProduct("sub2", ProductType.Subscription, new IDs { }); // Write Amazon's JSON description of our products to storage when using Amazon's local sandbox. // This should be removed from a production build. //builder.Configure<IAmazonConfiguration>().WriteSandboxJSON(builder.products); #if INTERCEPT_PROMOTIONAL_PURCHASES // 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"); #endif #if RECEIPT_VALIDATION string appIdentifier; #if UNITY_5_6_OR_NEWER appIdentifier = Application.identifier; #else appIdentifier = Application.bundleIdentifier; #endif try { validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), appIdentifier); } catch (NotImplementedException exception) { Debug.Log("Cross Platform Validator Not Implemented: " + exception); } #endif // Now we're ready to initialize Unity IAP. UnityPurchasing.Initialize(this, builder); }
// 初始化IAP; private void InitUnityPurchase() { if (IsInitialized()) { return; } Debug.Log("UNITY IAP start InitUnityPurchase"); var module = StandardPurchasingModule.Instance(); // The FakeStore supports: no-ui (always succeeding), basic ui (purchase pass/fail), and // developer ui (initialization, purchase, failure code setting). These correspond to // the FakeStoreUIMode Enum values passed into StandardPurchasingModule.useFakeStoreUIMode. module.useFakeStoreUIMode = FakeStoreUIMode.StandardUser; var builder = ConfigurationBuilder.Instance(module); Debug.Log("UNITY IAP after create builder"); // Set this to true to enable the Microsoft IAP simulator for local testing. builder.Configure <IMicrosoftConfiguration>().useMockBillingSystem = true; m_IsGooglePlayStoreSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.GooglePlay; Debug.Log("UNITY IAP will get products1"); if (m_Usr_Get_Products.IsNull) { return; } Debug.Log("UNITY IAP will get products2"); var all_products = m_Usr_Get_Products.SafeInvoke(); Debug.Log("UNITY IAP after get products"); if (null == all_products) { return; } Debug.Log("UNITY IAP all products count = " + all_products.Count); if (0 == builder.products.Count) { foreach (var item in all_products) { #if UNITY_IOS && PLATFORM_ID builder.AddProduct(item.m_unique_platform_id, item.m_type); #else builder.AddProduct(item.m_charge_id.ToString(), item.m_type, item.m_cross_platform_ids); #endif } } //var catalog = ProductCatalog.LoadDefaultCatalog(); //foreach (var product in catalog.allValidProducts) //{ // if (product.allStoreIDs.Count > 0) // { // var ids = new IDs(); // foreach (var storeID in product.allStoreIDs) // { // ids.Add(storeID.id, storeID.store); // } // builder.AddProduct(product.id, product.type, ids); // } // else // { // builder.AddProduct(product.id, product.type); // } //} //builder.AddProduct(C_ITEM_0, ProductType.Consumable); #if RECEIPT_VALIDATION string appIdentifier; #if UNITY_5_6_OR_NEWER appIdentifier = Application.identifier; #else appIdentifier = Application.bundleIdentifier; #endif validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), UnityChannelTangle.Data(), appIdentifier); #endif //初始化; UnityPurchasing.Initialize(this, builder); }
public void InitializePurchasing() { Debug.Log("InitializePurchasing"); // If we have already connected to Purchasing ... if (IsInitialized()) { // ... we are done here. return; } // Create a builder, first passing in a suite of Unity provided stores. var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); // Add a product to sell / restore by way of its identifier, associating the general identifier // with its store-specific identifiers. /* * builder.AddProduct("com.mysterytag.spider.booster_green_1", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.booster_blue_1", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.booster_purple_1", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.booster_green_10", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.booster_blue_10", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.booster_purple_10", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_1_free", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_2_free", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_3_free", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_4_free", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_1_green_payers", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_1_blue_payers", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_1_purple_payers", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_2_green_payers", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_2_blue_payers", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_2_purple_payers", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_3_green_payers", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_3_blue_payers", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.sale_3_purple_payers", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.energy_for_day", ProductType.Consumable); * builder.AddProduct("com.mysterytag.spider.chapter", ProductType.Consumable); */ builder.AddProduct("com.evogames.feedthespider.booster_green_1", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.booster_blue_1", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.booster_purple_1", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.booster_green_10", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.booster_blue_10", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.booster_purple_10", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_1_free", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_2_free", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_3_free", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_4_free", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_1_green_payers", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_1_blue_payers", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_1_purple_payers", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_2_green_payers", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_2_blue_payers", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_2_purple_payers", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_3_green_payers", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_3_blue_payers", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.sale_3_purple_payers", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.energy_for_day", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.chapter", ProductType.Consumable); builder.AddProduct("com.evogames.feedthespider.vip_week", ProductType.Subscription); builder.AddProduct("com.evogames.feedthespider.vip_month", ProductType.Subscription); builder.AddProduct("com.evogames.feedthespider.vip_year", ProductType.Subscription); // Continue adding the non-consumable product. //builder.AddProduct(kProductIDNonConsumable, ProductType.NonConsumable); // And finish adding the subscription product. Notice this uses store-specific IDs, illustrating // if the Product ID was configured differently between Apple and Google stores. Also note that // one uses the general kProductIDSubscription handle inside the game - the store-specific IDs // must only be referenced here. /* * builder.AddProduct(kProductIDSubscription, ProductType.Subscription, new IDs(){ * { kProductNameAppleSubscription, AppleAppStore.Name }, * { kProductNameGooglePlaySubscription, GooglePlay.Name }, * }); */ // Kick off the remainder of the set-up with an asynchrounous call, passing the configuration // and this class' instance. Expect a response either in OnInitialized or OnInitializeFailed. UnityPurchasing.Initialize(this, builder); }
public void InitializePurchasing() { // If we have already connected to Purchasing ... if (IsInitialized()) { // ... we are done here. return; } // Create a builder, first passing in a suite of Unity provided stores. var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); // Add a product to sell / restore by way of its identifier, associating the general identifier with its store-specific identifiers. #region build consumables if (consumable != null && consumable.Length > 0) { for (int i = 0; i < consumable.Length; i++) { if (consumable[i] != null && !string.IsNullOrEmpty(consumable[i].kProductID)) { string prodID = consumable[i].kProductID; builder.AddProduct(prodID, ProductType.Consumable, new IDs() { { appKey + "." + prodID, AppleAppStore.Name }, { googleKey + "." + prodID, GooglePlay.Name } }); // com.company.slotgame.productID consumable[i].clickEvent.RemoveAllListeners(); consumable[i].clickEvent.AddListener(() => { BuyProductID(prodID); }); } } } if (nonConsumable != null && nonConsumable.Length > 0) { for (int i = 0; i < nonConsumable.Length; i++) { if (nonConsumable[i] != null && !string.IsNullOrEmpty(nonConsumable[i].kProductID)) { string prodID = nonConsumable[i].kProductID; builder.AddProduct(prodID, ProductType.NonConsumable, new IDs() { { appKey + "." + prodID, AppleAppStore.Name }, { googleKey + "." + prodID, GooglePlay.Name } }); nonConsumable[i].clickEvent.RemoveAllListeners(); nonConsumable[i].clickEvent.AddListener(() => { BuyProductID(prodID); }); } } } if (subscriptions != null && subscriptions.Length > 0) { for (int i = 0; i < subscriptions.Length; i++) { if (subscriptions[i] != null && !string.IsNullOrEmpty(subscriptions[i].kProductID)) { string prodID = subscriptions[i].kProductID; builder.AddProduct(prodID, ProductType.Subscription, new IDs() { { appKey + "." + prodID, AppleAppStore.Name }, { googleKey + "." + prodID, GooglePlay.Name }, }); // Kick off the remainder of the set-up with an asynchrounous call, passing the configuration and this class' instance. Expect a response either in OnInitialized or OnInitializeFailed. nonConsumable[i].clickEvent.RemoveAllListeners(); nonConsumable[i].clickEvent.AddListener(() => { BuyProductID(prodID); }); } } } #endregion build consumables UnityPurchasing.Initialize(this, builder); }
/// <summary> /// Callback for succesful ProductService.GetSalesInventory /// </summary> /// <param name="in_jsonString"></param> /// <param name="in_object"></param> public void OnReadInventory(string in_jsonString, object in_object) { //Build IAPProducts based on all platform responses // ios and google play store now supported [smrj] m_productInventory.Clear(); // Clearing to fill with fresh data Dictionary <string, object> jsonMessage = (Dictionary <string, object>)JsonReader.Deserialize(in_jsonString); Dictionary <string, object> jsonData = (Dictionary <string, object>)jsonMessage[BrainCloudConsts.JSON_DATA]; var jsonArray = jsonData[JSON_PRODUCT_INVENTORY] as Array; Dictionary <string, object> product; Dictionary <string, object> priceData; #if UNITY_IOS Dictionary <string, object> idsObject; //itunes may have an array of ids for iphone, ipad and appletv #endif Dictionary <string, object> currencyRewards; IAPProduct iapProduct = null; #if BUY_CURRENCY_ENABLED && !STEAMWORKS_ENABLED var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); #endif for (int index = 0; index < jsonArray.Length; index++) { product = ((Dictionary <string, object>)jsonArray.GetValue(index)); priceData = ((Dictionary <string, object>)product[KEY_PRICEDATA]); #if UNITY_ANDROID var storeId = (string)priceData[KEY_ANDROIDID]; #elif UNITY_WEBGL var storeId = (string)product[KEY_PRODUCT_FBURL]; #elif UNITY_IOS var idsArray = priceData[KEY_IDS] as Array; idsObject = ((Dictionary <string, object>)idsArray.GetValue(0)); var storeId = (string)idsObject[KEY_ITUNESID]; #elif STEAMWORKS_ENABLED var storeId = ((int)priceData[KEY_PRODUCTID]).ToString(); #else var storeId = ""; try { // TODO add more store integration here [SMRJ] storeId = (string)priceData[KEY_ANDROIDID]; } catch (Exception) { continue; } #endif var braincloudID = (string)product[KEY_PRODUCTID]; var category = (string)product[KEY_CATEGORY]; var title = (string)product[KEY_TITLE]; var description = (string)product[KEY_DESCRIPTION]; var imageUrl = (string)product[KEY_IMAGEURL]; var referencePrice = Convert.ToDecimal(priceData[KEY_REFERENCEPRICE]); var price = referencePrice / 100; var isPromotion = (bool)priceData[KEY_ISPROMOTION]; //get the value of the currency with the same name as the category currencyRewards = (Dictionary <string, object>)product[KEY_CURRENCY]; // merge the peer / parent currencies within this dictionary as well if (product.ContainsKey(KEY_PARENT_CURRENCY)) { foreach (var item in product[KEY_PARENT_CURRENCY] as Dictionary <string, object> ) { foreach (var currencyReward in item.Value as Dictionary <string, object> ) { currencyRewards.Add(currencyReward.Key, currencyReward.Value); } } } if (product.ContainsKey(KEY_PEER_CURRENCY)) { foreach (var item in product[KEY_PEER_CURRENCY] as Dictionary <string, object> ) { foreach (var currencyReward in item.Value as Dictionary <string, object> ) { currencyRewards.Add(currencyReward.Key, currencyReward.Value); } } } object currencyVal; currencyRewards.TryGetValue(category, out currencyVal); var currencyValue = Convert.ToInt32(currencyVal); var type = (string)product[KEY_TYPE]; #if BUY_CURRENCY_ENABLED var productType = ProductType.Consumable; switch (type.ToLower()) { case PRODUCT_TYPE_SUBSCRIPTION: productType = ProductType.Subscription; break; case PRODUCT_TYPE_NON_CONSUMABLE: productType = ProductType.NonConsumable; break; case PRODUCT_TYPE_CONSUMABLE: default: //productType = ProductType.Consumable; -> Already set as default value break; } #endif Dictionary <string, object> packRewards = (Dictionary <string, object>)product[BrainCloudConsts.JSON_DATA]; #if BUY_CURRENCY_ENABLED iapProduct = new IAPProduct(braincloudID, storeId, productType, category, title, description, imageUrl, referencePrice, price, isPromotion, currencyValue, currencyRewards, packRewards); #else iapProduct = new IAPProduct(braincloudID, storeId, category, title, description, imageUrl, referencePrice, price, isPromotion, currencyValue, currencyRewards, packRewards); #endif iapProduct.PriceString = String.Format("{0:c}", referencePrice / 100); //update the regular price on sale items if (isPromotion && product.ContainsKey(KEY_DEFAULTPRICEDATA)) { var defaultPriceData = ((Dictionary <string, object>)product[KEY_DEFAULTPRICEDATA]); var refPrice = Convert.ToDecimal(defaultPriceData[KEY_REFERENCEPRICE]); #if UNITY_ANDROID var regularId = (string)defaultPriceData[KEY_ANDROIDID]; #elif UNITY_WEBGL var regularId = (string)product[KEY_PRODUCT_FBURL]; #elif STEAMWORKS_ENABLED var regularId = ((int)defaultPriceData[KEY_PRODUCTID]).ToString(); #else var ids = defaultPriceData[KEY_IDS] as Array; var regIdVal = ((Dictionary <string, object>)ids.GetValue(0)); var regularId = (string)regIdVal[KEY_ITUNESID]; #endif iapProduct.RegularPriceID = regularId; iapProduct.RegularPrice = refPrice / 100; iapProduct.RegularPriceString = String.Format("{0:c}", refPrice / 100); #if BUY_CURRENCY_ENABLED && !STEAMWORKS_ENABLED // unity does not support steam works iap builder.AddProduct(regularId, productType); //add this as a reference to the regular priced item #endif } #if BUY_CURRENCY_ENABLED && !STEAMWORKS_ENABLED // unity does not support steam works iap builder.AddProduct(iapProduct.StoreProductId, productType); //add to ConfigurationBuilder #endif m_productInventory.Add(iapProduct); //add to List of products } #if BUY_CURRENCY_ENABLED && !STEAMWORKS_ENABLED // unity does not support steam works iap UnityPurchasing.Initialize(this, builder); #else GEventManager.TriggerEvent(GEventManager.ON_IAP_PRODUCTS_UPDATED); #endif }
private void InitializePurchasing() { CashShopItems.Clear(); CashPackages.Clear(); if (cashShopDatabase != null) { foreach (var cashShopItem in cashShopDatabase.cashStopItems) { if (cashShopItem == null || CashShopItems.ContainsKey(cashShopItem.DataId)) { continue; } CashShopItems[cashShopItem.DataId] = cashShopItem; } } #if ENABLE_PURCHASING && UNITY_PURCHASING && (UNITY_ANDROID || UNITY_IOS) // If we have already connected to Purchasing ... if (IsPurchasingInitialized()) { return; } // Create a builder, first passing in a suite of Unity provided stores. var module = StandardPurchasingModule.Instance(); var builder = ConfigurationBuilder.Instance(module); #endif if (cashShopDatabase != null) { foreach (var cashPackage in cashShopDatabase.cashPackages) { if (cashPackage == null || CashPackages.ContainsKey(cashPackage.DataId)) { continue; } #if ENABLE_PURCHASING && UNITY_PURCHASING && (UNITY_ANDROID || UNITY_IOS) // Setup IAP package for clients var productCatalogItem = cashPackage.ProductCatalogItem; if (productCatalogItem == null) { continue; } Debug.Log("[" + TAG_INIT + "]: Adding product " + productCatalogItem.id + " type " + productCatalogItem.type.ToString()); if (productCatalogItem.allStoreIDs.Count > 0) { var ids = new IDs(); foreach (var storeID in productCatalogItem.allStoreIDs) { ids.Add(storeID.id, storeID.store); } builder.AddProduct(productCatalogItem.id, productCatalogItem.type, ids); } else { builder.AddProduct(productCatalogItem.id, productCatalogItem.type); } #endif CashPackages[cashPackage.DataId] = cashPackage; } } #if ENABLE_PURCHASING && UNITY_PURCHASING && (UNITY_ANDROID || UNITY_IOS) Debug.Log("[" + TAG_INIT + "]: Initializing Purchasing..."); // Kick off the remainder of the set-up with an asynchrounous call, passing the configuration // and this class' instance. Expect a response either in OnInitialized or OnInitializeFailed. try { UnityPurchasing.Initialize(this, builder); } catch (System.InvalidOperationException ex) { var errorMessage = "[" + TAG_INIT + "]: Cannot initialize purchasing, the platform may not supports."; Debug.LogError(errorMessage); Debug.LogException(ex); } #else Debug.Log("[" + TAG_INIT + "]: Initialized without purchasing"); #endif }
public void Awake() { StandardPurchasingModule module = StandardPurchasingModule.Instance(); // The FakeStore supports: no-ui (always succeeding), basic ui (purchase pass/fail), and // developer ui (initialization, purchase, failure code setting). These correspond to // the FakeStoreUIMode Enum values passed into StandardPurchasingModule.useFakeStoreUIMode. module.useFakeStoreUIMode = FakeStoreUIMode.StandardUser; ConfigurationBuilder builder = ConfigurationBuilder.Instance(module); // Set this to true to enable the Microsoft IAP simulator for local testing. builder.Configure <IMicrosoftConfiguration>().useMockBillingSystem = false; m_IsGooglePlayStoreSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.GooglePlay; #if AGGRESSIVE_INTERRUPT_RECOVERY_GOOGLEPLAY // For GooglePlay, if we have access to a backend server to deduplicate purchases, query purchase history // when attempting to recover from a network-interruption encountered during purchasing. Strongly recommend // deduplicating transactions across app reinstallations because this relies upon the on-device, deletable // TransactionLog database. builder.Configure <IGooglePlayConfiguration>().aggressivelyRecoverLostPurchases = true; // Use purchaseToken instead of orderId for all transactions to avoid non-unique transactionIDs for a // single purchase; two ProcessPurchase calls for one purchase, differing only by which field of the receipt // is used for the Product.transactionID. Automatically true if aggressivelyRecoverLostPurchases is enabled // and this API is not called at all. builder.Configure <IGooglePlayConfiguration>().UsePurchaseTokenForTransactionId(true); #endif // Define our products. // Either use the Unity IAP Catalog, or manually use the ConfigurationBuilder.AddProduct API. // Use IDs from both the Unity IAP Catalog and hardcoded IDs via the ConfigurationBuilder.AddProduct API. // Use the products defined in the IAP Catalog GUI. // E.g. Menu: "Window" > "Unity IAP" > "IAP Catalog", then add products, then click "App Store Export". ProductCatalog catalog = ProductCatalog.LoadDefaultCatalog(); foreach (ProductCatalogItem product in catalog.allValidProducts) { if (product.allStoreIDs.Count > 0) { IDs ids = new IDs(); foreach (StoreID storeID in product.allStoreIDs) { ids.Add(storeID.id, storeID.store); } builder.AddProduct(product.id, product.type, ids); } else { builder.AddProduct(product.id, product.type); } } // In this case our products have the same identifier across all the App stores, // except on the Mac App store where product IDs cannot be reused across both Mac and // iOS stores. // So on the Mac App store our products have different identifiers, // and we tell Unity IAP this by using the IDs class. builder.AddProduct("100.gold.coins", ProductType.Consumable, new IDs { { "com.unity3d.unityiap.unityiapdemo.100goldcoins.7", MacAppStore.Name }, { "100.gold.coins", AmazonApps.Name }, { "100.gold.coins", AppleAppStore.Name } } #if USE_PAYOUTS , new List <PayoutDefinition> { new PayoutDefinition(PayoutType.Item, "", 1, "item_id:76543"), new PayoutDefinition(PayoutType.Currency, "gold", 50) } #endif //USE_PAYOUTS ); builder.AddProduct("500.gold.coins", ProductType.Consumable, new IDs { { "com.unity3d.unityiap.unityiapdemo.500goldcoins.7", MacAppStore.Name }, { "500.gold.coins", AmazonApps.Name }, } #if USE_PAYOUTS , new PayoutDefinition(PayoutType.Currency, "gold", 500) #endif //USE_PAYOUTS ); builder.AddProduct("300.gold.coins", ProductType.Consumable, new IDs() #if USE_PAYOUTS , new List <PayoutDefinition> { new PayoutDefinition(PayoutType.Item, "", 1, "item_id:76543"), new PayoutDefinition(PayoutType.Currency, "gold", 50) } #endif //USE_PAYOUTS ); builder.AddProduct("sub1", ProductType.Subscription, new IDs()); builder.AddProduct("sub2", ProductType.Subscription, new IDs()); // Write Amazon's JSON description of our products to storage when using Amazon's local sandbox. // This should be removed from a production build. //builder.Configure<IAmazonConfiguration>().WriteSandboxJSON(builder.products); // This enables simulated purchase success for Samsung IAP. // You would remove this, or set to SamsungAppsMode.Production, before building your release package. builder.Configure <ISamsungAppsConfiguration>().SetMode(SamsungAppsMode.AlwaysSucceed); // This records whether we are using Samsung IAP. Currently ISamsungAppsExtensions.RestoreTransactions // displays a blocking Android Activity, so: // A) Unity IAP does not automatically restore purchases on Samsung Galaxy Apps // B) IAPDemo (this) displays the "Restore" GUI button for Samsung Galaxy Apps m_IsSamsungAppsStoreSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.SamsungApps; #if INTERCEPT_PROMOTIONAL_PURCHASES // 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"); #endif #if RECEIPT_VALIDATION string appIdentifier; #if UNITY_5_6_OR_NEWER appIdentifier = Application.identifier; #else appIdentifier = Application.bundleIdentifier; #endif validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), appIdentifier); #endif // Now we're ready to initialize Unity IAP. UnityPurchasing.Initialize(this, builder); }
public void Awake() { var module = StandardPurchasingModule.Instance(); // The FakeStore supports: no-ui (always succeeding), basic ui (purchase pass/fail), and // developer ui (initialization, purchase, failure code setting). These correspond to // the FakeStoreUIMode Enum values passed into StandardPurchasingModule.useFakeStoreUIMode. module.useFakeStoreUIMode = FakeStoreUIMode.StandardUser; var builder = ConfigurationBuilder.Instance(module); // Set this to true to enable the Microsoft IAP simulator for local testing. builder.Configure <IMicrosoftConfiguration>().useMockBillingSystem = false; m_IsGooglePlayStoreSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.GooglePlay; builder.Configure <IGooglePlayConfiguration>().SetPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoijNfTc9kS+M6R12DNc32dG7Mrg/czFABHPgYg8IQ8xebBoQMRXGEbmm4CHoNxCSJk+Fcs05wTogSsGbN0uemOmJUwCYowLQxzIeOBqH4aB2kDqMSDqKJnK08wDUFtDIrIBsczFincIW4i0E4JqtrGPksqn/tG5SvKvheG4x8yUcLWbd/MC885cZY1lMoRsaakVf/EoMfqtOccH+1x2dFVh0Q/NTAkgExILsN4KXHTpM2mHLKr6Dv3NK9ueYsLvf39kL9CwLZFFyD3413cyqtR4ZdfHL0BHw+9rSr0uysMtU3SGfqBHgyjMVNFL0eL6txWgVDhL3MaAXokIm0CePiwIDAQAB"); #if AGGRESSIVE_INTERRUPT_RECOVERY_GOOGLEPLAY // For GooglePlay, if we have access to a backend server to deduplicate purchases, query purchase history // when attempting to recover from a network-interruption encountered during purchasing. Strongly recommend // deduplicating transactions across app reinstallations because this relies upon the on-device, deletable // TransactionLog database. builder.Configure <IGooglePlayConfiguration>().aggressivelyRecoverLostPurchases = true; #endif // Define our products. // Either use the Unity IAP Catalog, or manually use the ConfigurationBuilder.AddProduct API. // Use IDs from both the Unity IAP Catalog and hardcoded IDs via the ConfigurationBuilder.AddProduct API. // Use the products defined in the IAP Catalog GUI. // E.g. Menu: "Window" > "Unity IAP" > "IAP Catalog", then add products, then click "App Store Export". var catalog = ProductCatalog.LoadDefaultCatalog(); foreach (var product in catalog.allValidProducts) { if (product.allStoreIDs.Count > 0) { var ids = new IDs(); foreach (var storeID in product.allStoreIDs) { ids.Add(storeID.id, storeID.store); } builder.AddProduct(product.id, product.type, ids); } else { builder.AddProduct(product.id, product.type); } } // In this case our products have the same identifier across all the App stores, // except on the Mac App store where product IDs cannot be reused across both Mac and // iOS stores. // So on the Mac App store our products have different identifiers, // and we tell Unity IAP this by using the IDs class. // builder.AddProduct("100.gold.coins", ProductType.Consumable, new IDs // { // {"com.unity3d.unityiap.unityiapdemo.100goldcoins.7", MacAppStore.Name}, // {"100.gold.coins", AmazonApps.Name}, // {"100.gold.coins", AppleAppStore.Name} // } // #if USE_PAYOUTS // , new List<PayoutDefinition> { // new PayoutDefinition(PayoutType.Item, "", 1, "item_id:76543"), // new PayoutDefinition(PayoutType.Currency, "gold", 50) // } // #endif //USE_PAYOUTS // ); // // builder.AddProduct("500.gold.coins", ProductType.Consumable, new IDs // { // {"com.unity3d.unityiap.unityiapdemo.500goldcoins.7", MacAppStore.Name}, // {"500.gold.coins", AmazonApps.Name}, // } // #if USE_PAYOUTS // , new PayoutDefinition(PayoutType.Currency, "gold", 500) // #endif //USE_PAYOUTS // ); // // builder.AddProduct("300.gold.coins", ProductType.Consumable, new IDs // { // } // #if USE_PAYOUTS // , new List<PayoutDefinition> { // new PayoutDefinition(PayoutType.Item, "", 1, "item_id:76543"), // new PayoutDefinition(PayoutType.Currency, "gold", 50) // } // #endif //USE_PAYOUTS // ); builder.AddProduct("sub1week", ProductType.Subscription, new IDs { }); builder.AddProduct("sub1month", ProductType.Subscription, new IDs { }); // Write Amazon's JSON description of our products to storage when using Amazon's local sandbox. // This should be removed from a production build. //builder.Configure<IAmazonConfiguration>().WriteSandboxJSON(builder.products); // This enables simulated purchase success for Samsung IAP. // You would remove this, or set to SamsungAppsMode.Production, before building your release package. builder.Configure <ISamsungAppsConfiguration>().SetMode(SamsungAppsMode.AlwaysSucceed); // This records whether we are using Samsung IAP. Currently ISamsungAppsExtensions.RestoreTransactions // displays a blocking Android Activity, so: // A) Unity IAP does not automatically restore purchases on Samsung Galaxy Apps // B) IAPDemo (this) displays the "Restore" GUI button for Samsung Galaxy Apps m_IsSamsungAppsStoreSelected = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.SamsungApps; #if INTERCEPT_PROMOTIONAL_PURCHASES // 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"); #endif #if RECEIPT_VALIDATION string appIdentifier; #if UNITY_5_6_OR_NEWER appIdentifier = Application.identifier; #else appIdentifier = Application.bundleIdentifier; #endif validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), appIdentifier); #endif // Now we're ready to initialize Unity IAP. UnityPurchasing.Initialize(this, builder); }