unity内购-Google支付(unity In-App Purchasing)

unity In-App Purchasing 支付

支持二次验证,json解析完之后,把解析出来的参数发给服务器,因为是unity封装的sdk,code参数需要在购买成功之后的回调里给服务器发个int类型的参数,赋值为零。服务器要接Google源生的;

如果有不明白的加QQ群:636926481

1.打开unity

2.如果没有出现这个界面说明你没有登录unity,有账号的就登陆就可以,没有的自己申请

3.操作完之后点击import

5.全选,然后Cancel

6.添加第一个按钮,然后配置

8.选择商品按钮

9.打开IAPButten

10.代码复制进去,全部替换,

#if UNITY_PURCHASING
using UnityEngine.Events;
using UnityEngine.UI;
using System.IO;
using System.Collections.Generic;

namespace UnityEngine.Purchasing
{
    [RequireComponent(typeof(Button))]
    [AddComponentMenu("Unity IAP/IAP Button")]
    [HelpURL("https://docs.unity3d.com/Manual/UnityIAP.html")]
    public class IAPButton : MonoBehaviour
    {
        public enum ButtonType
        {
            Purchase,
            Restore
        }

        [System.Serializable]
        public class OnPurchaseCompletedEvent : UnityEvent<Product>
        {
        };

        [System.Serializable]
        public class OnPurchaseFailedEvent : UnityEvent<Product, PurchaseFailureReason>
        {
        };

        [HideInInspector]
        public string productId;

        [Tooltip("The type of this button, can be either a purchase or a restore button")]
        public ButtonType buttonType = ButtonType.Purchase;

        [Tooltip("Consume the product immediately after a successful purchase")]
        public bool consumePurchase = true;

        [Tooltip("Event fired after a successful purchase of this product")]
        public OnPurchaseCompletedEvent onPurchaseComplete;

        [Tooltip("Event fired after a failed purchase of this product")]
        public OnPurchaseFailedEvent onPurchaseFailed;

        [Tooltip("[Optional] Displays the localized title from the app store")]
        public Text titleText;

        [Tooltip("[Optional] Displays the localized description from the app store")]
        public Text descriptionText;

        [Tooltip("[Optional] Displays the localized price from the app store")]
        public Text priceText;
        
        //用于验证是否可购买
        private bool ISGoogle = true;

        void Start()
        {
            Button button = GetComponent<Button>();

            if (buttonType == ButtonType.Purchase)
            {
                if (button)
                {
                    button.onClick.AddListener(PurchaseProduct);
                }

                if (string.IsNullOrEmpty(productId))
                {
                    Debug.LogError("IAPButton productId is empty");
                }

                if (!CodelessIAPStoreListener.Instance.HasProductInCatalog(productId))
                {
                    Debug.LogWarning("The product catalog has no product with the ID \"" + productId + "\"");
                }
            }
            else if (buttonType == ButtonType.Restore)
            {
                if (button)
                {
                    button.onClick.AddListener(Restore);
                }
            }
        }

        void OnEnable()
        {
            if (buttonType == ButtonType.Purchase)
            {
                CodelessIAPStoreListener.Instance.AddButton(this);
                if (CodelessIAPStoreListener.initializationComplete) {
                    UpdateText();
                }
            }
        }

        void OnDisable()
        {
            if (buttonType == ButtonType.Purchase)
            {
                CodelessIAPStoreListener.Instance.RemoveButton(this);
            }
        }

        void PurchaseProduct()
        {
            if (buttonType == ButtonType.Purchase && ISGoogle == true )
            {
                    Debug.Log("IAPButton.PurchaseProduct() with product ID: " + productId);

                    Product product = CodelessIAPStoreListener.Instance.GetProduct(productId);
                    ISGoogle = false;
                    if (product != null)
                    {
                        Debug.LogFormat("product recipt:{0}", product.receipt);

                        Debug.LogFormat("Purchasing product asychronously productyType is:{0}", product.definition.type.ToString());

                        CodelessIAPStoreListener.Instance.InitiatePurchase(productId);
                    }
                

            }
        }

        void Restore()
        {
            if (buttonType == ButtonType.Restore)
            {
                if (Application.platform == RuntimePlatform.WSAPlayerX86 ||
                    Application.platform == RuntimePlatform.WSAPlayerX64 ||
                    Application.platform == RuntimePlatform.WSAPlayerARM)
                {
                    CodelessIAPStoreListener.Instance.ExtensionProvider.GetExtension<IMicrosoftExtensions>()
                        .RestoreTransactions();
                }
                else if (Application.platform == RuntimePlatform.IPhonePlayer ||
                         Application.platform == RuntimePlatform.OSXPlayer ||
                         Application.platform == RuntimePlatform.tvOS)
                {
                    CodelessIAPStoreListener.Instance.ExtensionProvider.GetExtension<IAppleExtensions>()
                        .RestoreTransactions(OnTransactionsRestored);
                }
                else if (Application.platform == RuntimePlatform.Android &&
                         StandardPurchasingModule.Instance().appStore == AppStore.SamsungApps)
                {
                    CodelessIAPStoreListener.Instance.ExtensionProvider.GetExtension<ISamsungAppsExtensions>()
                        .RestoreTransactions(OnTransactionsRestored);
                }
                else if (Application.platform == RuntimePlatform.Android &&
                         StandardPurchasingModule.Instance().appStore == AppStore.CloudMoolah)
                {
                    CodelessIAPStoreListener.Instance.ExtensionProvider.GetExtension<IMoolahExtension>()
                        .RestoreTransactionID((restoreTransactionIDState) =>
                        {
                            OnTransactionsRestored(
                                restoreTransactionIDState != RestoreTransactionIDState.RestoreFailed &&
                                restoreTransactionIDState != RestoreTransactionIDState.NotKnown);
                        });
                }
                else
                {
                    Debug.LogWarning(Application.platform.ToString() +
                                     " is not a supported platform for the Codeless IAP restore button");
                }
            }
        }

        void OnTransactionsRestored(bool success)
        {
            Debug.Log("Transactions restored: " + success);
        }

        /**
         *  Invoked to process a purchase of the product associated with this button
         */
        public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)
        {
            Debug.Log(string.Format("IAPButton.ProcessPurchase(PurchaseEventArgs {0} - {1})", e,
                e.purchasedProduct.definition.id));
            ISGoogle = true;
            onPurchaseComplete.Invoke(e.purchasedProduct);
            //json解析
            var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(purchasedProduct.receipt);
            var store = (string)wrapper["Store"];
            var payload = (string)wrapper["Payload"];
            var gpDetails = (Dictionary<string, object>)MiniJson.JsonDecode(payload);
            var gpJson = (string)gpDetails["json"];
            var gpSig = (string)gpDetails["signature"];

            return (consumePurchase) ? PurchaseProcessingResult.Complete : PurchaseProcessingResult.Pending;
        }

        /**
         *  Invoked on a failed purchase of the product associated with this button
         */
        public void OnPurchaseFailed(Product product, PurchaseFailureReason reason)
        {
            Debug.Log(string.Format("IAPButton.OnPurchaseFailed(Product {0}, PurchaseFailureReason {1})", product,
                reason));

            onPurchaseFailed.Invoke(product, reason);
            ISGoogle = true;
        }

        internal void UpdateText()
        {
            var product = CodelessIAPStoreListener.Instance.GetProduct(productId);
            if (product != null)
            {
                if (titleText != null)
                {
                    titleText.text = product.metadata.localizedTitle;
                }

                if (descriptionText != null)
                {
                    descriptionText.text = product.metadata.localizedDescription;
                }

                if (priceText != null)
                {
                    priceText.text = product.metadata.localizedPriceString;
                }
            }
        }
    }
}
#endif

对于后期会涉及到更新,需要代码控制商品的游戏,建议使用

需要把第七步填写的参数全部去掉,把客户端商品上的APIButten去掉,代码放在商城界面上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.Purchasing.Security;

public class Purchaser : MonoBehaviour, IStoreListener
{

    private IStoreController mStoreController;
    private IExtensionProvider mExtensionProvider;
    ConfigurationBuilder builder;
    public static string kProductIDConsumable = "consumable";   //消耗商品
    public static string kProductIDNonConsumable = "nonconsumable";   //非消耗商品
    public static string kProductIDSubscription = "subscription";       //订阅产品


    //商品
    private const string product_1 = "buy_gold_001";
    private const string product_2 = "buy_gold_002";
    private const string product_3 = "buy_gold_003";
    private const string product_4 = "buy_gold_004";

    private bool ISGoogle = true;

    void Start()
    {
        if (mStoreController == null)
        {
            InitPurchasing();
        }
    }


    //初始化
    public void InitPurchasing()
    {
        if (IsInitialized())
        {
            return;
        }

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

        //添加商品ID和类型 对应定义的商品ID
        builder.AddProduct(product_1, ProductType.Consumable, new IDs
            {
                {product_1, GooglePlay.Name }
            });
        builder.AddProduct(product_2, ProductType.Consumable, new IDs
            {
                {product_2, GooglePlay.Name }
            });
        builder.AddProduct(product_3, ProductType.Consumable, new IDs
            {
                {product_3, GooglePlay.Name }
            });
        builder.AddProduct(product_4, ProductType.Consumable, new IDs
            {
                {product_4, GooglePlay.Name }
            });

        UnityPurchasing.Initialize(this, builder);
    }


    //购买
    public void BuyProduct(string productID)
    {
        ISGoogle = false;
        if (IsInitialized() && ISGoogle == true)
        {
            Product produdt = mStoreController.products.WithID(productID);
            if (produdt != null && produdt.availableToPurchase)
            {
                mStoreController.InitiatePurchase(produdt);

                Debug.Log(produdt.metadata.localizedPrice);
            }
            else
            {
                Debug.Log("fail");
            }
        }
        else
        {
            Debug.Log("BuyProductID FAIL. Not initialized.");
        }
    }

    //恢复购买
    public void ReSotre()
    {
        if (!IsInitialized())
        {
            return;
        }

        if (mExtensionProvider != null&& (Application.platform == RuntimePlatform.IPhonePlayer|| Application.platform == RuntimePlatform.OSXPlayer))
        {
            var apple = mExtensionProvider.GetExtension<IAppleExtensions>();
            apple.RestoreTransactions((result) =>
            {
                // Restore purchases initiated. See ProcessPurchase for any restored transacitons.
                Debug.Log("RestorePurchases continuing: " + result + ". If no further messages, no purchases available to restore.");
            });
        }
    }

    private bool IsInitialized()
    {
        return mStoreController != null && mExtensionProvider != null;
    }



    public void BuyConsumable1()
    {

        BuyProduct(product_1);
    }

    public void BuyConsumable2()
    {

        BuyProduct(product_2);
    }

    public void BuyConsumable3()
    {

        BuyProduct(product_3);
    }

    public void BuyConsumable4()
    {

        BuyProduct(product_4);
    }


    //---------------IStoreListener的四个接口的实现-----------

    //初始化成功
    public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
    {
        mStoreController = controller;
        mExtensionProvider = extensions;
        Debug.Log("----------------初始化成功---------------------");

    }

    //初始化失败
    public void OnInitializeFailed(InitializationFailureReason error)
    {

        Debug.Log("----------------初始化失败-------------------- -:" + error);
    }

    //购买失败
    public void OnPurchaseFailed(Product e, PurchaseFailureReason p)
    {

        var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(e.receipt);
        var store = (string)wrapper["Store"];

        var payload = (string)wrapper["Payload"];
        ISGoogle = true;
        var gpDetails = (Dictionary<string, object>)MiniJson.JsonDecode(payload);
        var gpJson = (string)gpDetails["json"];
        var gpSig = (string)gpDetails["signature"];

        NetworkManager.SendCustom(CLIENT_CUSTOM_MESSAGE_ENUM.CLIENT_CUSTOMMSG_GOOGLE_DELIVERY, (int)p, gpJson, gpSig);
        Debug.Log( "购买失败--------------------");
    }


    //购买成功和恢复成功的回调,可以根据id的不同进行不同的操作
    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)
    {
        var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(e.purchasedProduct.receipt);
        var store = (string)wrapper["Store"];
        ISGoogle = true;
        var payload = (string)wrapper["Payload"];

        var gpDetails = (Dictionary<string, object>)MiniJson.JsonDecode(payload);
        var gpJson = (string)gpDetails["json"];
        var gpSig = (string)gpDetails["signature"];

        NetworkManager.SendCustom(CLIENT_CUSTOM_MESSAGE_ENUM.CLIENT_CUSTOMMSG_GOOGLE_DELIVERY, 0, gpJson, gpSig);


        return PurchaseProcessingResult.Complete;

    }


}

出现支付页面证明sdk接入成功

注意:如果有报错-1002,就是测试机的问题,在设置里面把Google商店和谷歌的所有产品的  允许应用弹出窗口  的权限打开,在测试就会出来支付窗口了

注意:如果内购无法购买并且报错没有初始化,但是初始化逻辑能走通,可能是测试机的google账号的问题,把测试机上的google账号全部移除,在重新登录就好了,就可以了

猜你喜欢

转载自blog.csdn.net/qq_39954479/article/details/82085400