Beispiel #1
0
    protected override void GameSetup()
    {
        PaymentProductCoins[] coins = new PaymentProductCoins[6];
        coins[0] = new PaymentProductCoins {
            Price = 0.99m, Currency = "USD", Coins = 1500, NoAds = 0, EventCode = "IAP_BunchofCoins", Description = LocaliseText.Get("Payment.BunchOfCoins"), LanguageKey = "Payment.BunchOfCoins", Product = new PaymentProduct {
                Name = "com.wordfarm.iap.BunchOfCoins", ProductType = ProductType.Consumable
            }
        };
        coins[1] = new PaymentProductCoins {
            Price = 4.99m, Currency = "USD", Coins = 8700, NoAds = 0, EventCode = "IAP_BagofCoins", Description = LocaliseText.Get("Payment.BagOfCoins"), LanguageKey = "Payment.BagOfCoins", Product = new PaymentProduct {
                Name = "com.wordfarm.iap.BagOfCoins", ProductType = ProductType.Consumable
            }
        };
        coins[2] = new PaymentProductCoins {
            Price = 7.99m, Currency = "USD", Coins = 17500, NoAds = 0, EventCode = "IAP_SackofCoins", Description = LocaliseText.Get("Payment.SackOfCoins"), LanguageKey = "Payment.SackOfCoins", Product = new PaymentProduct {
                Name = "com.wordfarm.iap.SackOfCoins", ProductType = ProductType.Consumable
            }
        };
        coins[3] = new PaymentProductCoins {
            Price = 11.99m, Currency = "USD", Coins = 38900, NoAds = 0, EventCode = "IAP_PotofCoins", Description = LocaliseText.Get("Payment.PotOfCoins"), LanguageKey = "Payment.PotOfCoins", Product = new PaymentProduct {
                Name = "com.wordfarm.iap.PotOfCoins", ProductType = ProductType.Consumable
            }
        };
        coins[4] = new PaymentProductCoins {
            Price = 16.99m, Currency = "USD", Coins = 60000, NoAds = 0, EventCode = "IAP_ChestofCoins", Description = LocaliseText.Get("Payment.ChestOfCoins"), LanguageKey = "Payment.ChestOfCoins", Product = new PaymentProduct {
                Name = "com.wordfarm.iap.ChestOfCoins", ProductType = ProductType.Consumable
            }
        };
        coins[5] = new PaymentProductCoins {
            Price = 1.99m, Currency = "USD", Coins = 0, NoAds = 1, EventCode = "IAP_NoAds", Description = LocaliseText.Get("Payment.NoAds"), LanguageKey = "Payment.NoAds", Product = new PaymentProduct {
                Name = "com.wordfarm.iap.noads", ProductType = ProductType.NonConsumable
            }
        };

        CustomPaymentManager.Coins = coins;

        Products = new PaymentProduct[coins.Length];

        for (int i = 0; i < coins.Length; i++)
        {
#if UNITY_ANDROID
            coins[i].Product.Name = coins[i].Product.Name.ToLower(); // android play store allow only lowercase
#endif
            Products[i] = coins[i].Product;
        }

        // Initialise purchasing
        if (InitOnAwake)
        {
            InitializePurchasing();
        }

        GameManager.SafeAddListener <ItemPurchasedMessage> (ItemPurchasedHandler);
        GameManager.SafeAddListener <LocalisationChangedMessage>(LocalisationHandler);

        validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(),
                                               UnityChannelTangle.Data(), Application.identifier);
    }
Beispiel #2
0
    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);
        }
    }
Beispiel #3
0
    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);
        }
    }
Beispiel #4
0
        // 初始化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);
        }
        // Private Methods

        private static void _init(List <IAPProductSetting> productSettings)
        {
            // build the product list
            products = new Dictionary <string, IAPProduct>();
            foreach (IAPProductSetting setting in productSettings)
            {
                string         id   = setting.productId;
                IAPProductType type = setting.productType;
                IAPProduct     p    = new IAPProduct(id, type);
                p.amazonProductId  = (setting.amazonProductId != null && setting.amazonProductId != "") ? setting.amazonProductId : setting.productId;
                p.googleProductId  = (setting.googleProductId != null && setting.googleProductId != "") ? setting.googleProductId : setting.productId;
                p.appleProductId   = (setting.appleProductId != null && setting.appleProductId != "") ? setting.appleProductId : setting.productId;
                p.samsungProductId = (setting.samsungProductId != null && setting.samsungProductId != "") ? setting.samsungProductId : setting.productId;
                p.macProductId     = (setting.macProductId != null && setting.macProductId != "") ? setting.macProductId : setting.productId;
                p.tizenProductId   = (setting.tizenProductId != null && setting.tizenProductId != "") ? setting.tizenProductId : setting.productId;
                p.moolahProductId  = (setting.moolahProductId != null && setting.moolahProductId != "") ? setting.moolahProductId : setting.productId;

                p.buyButtonText      = setting.buyButtonText;
                p.disabledButtonText = setting.disabledButtonText;

                if (products.ContainsKey(id))
                {
                    Debug.Log("[IAPManager] Product id \"" + id + "\" already exist.");
                }
                else
                {
                    Debug.Log("[IAPManager] Add product with id \"" + id + "\"");
                    products.Add(id, p);
                }
                //				Debug.Log("product id: " + p.id);
            }

            var module = StandardPurchasingModule.Instance();

            // Create a builder, first passing in a suite of Unity provided stores.
            var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());

            // CloudMoolah Configuration setings
            // All games must set the configuration. the configuration need to apply on the CloudMoolah Portal.
            // CloudMoolah APP Key
            if (_setting.MoolahAppKey != null && _setting.MoolahAppKey != "")
            {
                builder.Configure <IMoolahConfiguration>().appKey = _setting.MoolahAppKey;
            }
            // CloudMoolah Hash Key
            if (_setting.MoolahHashKey != null && _setting.MoolahHashKey != "")
            {
                builder.Configure <IMoolahConfiguration>().hashKey = _setting.MoolahHashKey;
            }

            // Test Mode Enbled
            if (_setting.testMode)
            {
                // This enables the Microsoft IAP simulator for local testing.
                builder.Configure <IMicrosoftConfiguration>().useMockBillingSystem = true;
                if (_setting.GooglePublicKey != null && _setting.GooglePublicKey != "")
                {
                    builder.Configure <IGooglePlayConfiguration>().SetPublicKey(_setting.GooglePublicKey);
                }
                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
            }

            // Add Product to builder
            foreach (KeyValuePair <string, IAPProduct> item in products)
            {
                IAPProduct p   = item.Value;
                IDs        ids = new IDs();

                if (p.appleProductId != null)
                {
                    ids.Add(p.appleProductId, AppleAppStore.Name);
                }
                if (p.googleProductId != null)
                {
                    ids.Add(p.googleProductId, GooglePlay.Name);
                }
                if (p.amazonProductId != null)
                {
                    ids.Add(p.amazonProductId, AmazonApps.Name);
                }
                if (p.macProductId != null)
                {
                    ids.Add(p.macProductId, MacAppStore.Name);
                }
                if (p.samsungProductId != null)
                {
                    ids.Add(p.samsungProductId, SamsungApps.Name);
                }
                if (p.tizenProductId != null)
                {
                    ids.Add(p.tizenProductId, TizenStore.Name);
                }
                if (p.moolahProductId != null)
                {
                    ids.Add(p.moolahProductId, MoolahAppStore.Name);
                }
                //				Debug.Log("builder id: " + p.id);
                builder.AddProduct(p.id, ConvertFromIAPProductType(p.productType), ids);
            }

            // Test Mode Enabled
            if (_setting.testMode)
            {
                // 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
            }


            // 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(_setting.TizenGroupId);


            // Check Platform
            _isGooglePlayStore  = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.GooglePlay;
            _isCloudMoolahStore = Application.platform == RuntimePlatform.Android && module.appStore == AppStore.CloudMoolah;
            _isSamsungAppsStore = module.appStore == AppStore.SamsungApps;

            // build validator
#if RECEIPT_VALIDATION
            string appIdentifier;
#if UNITY_5_6_OR_NEWER
            appIdentifier = Application.identifier;
#else
            appIdentifier = Application.bundleIdentifier;
#endif
            _ReceiptValidator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(),
                                                           UnityChannelTangle.Data(), appIdentifier);
#endif

            UnityPurchasing.Initialize(_instance, builder);
        }