Google后台连接:

https://play.google.com/apps/publish/?account=4671074791115672368#AppListPlace Google后台设置:

首先在后台创建一个自己的应用:

unity苹果支付沙盒 unity接入支付_Code


unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_02


需要把后面打勾的全部设置为绿色才可以发布

unity苹果支付沙盒 unity接入支付_Code_03


第一应用版本选择一个版本

unity苹果支付沙盒 unity接入支付_Google_04


点击管理,创建版本

unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_05


拖入一个Apk(可以打开一个新Unity项目,打包时这个Apk包要设置它的签名Player Settings=>Publishing Settings)让后填写其他内容,保存

unity苹果支付沙盒 unity接入支付_Code_06


商品详情,根据上面的要求将图片加入其中

unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_07


选择游戏类型,保存

unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_08


定价和分发范围,选择自己的应用付费或免费,向下填一些选择问题

unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_09


在上传APK后要记得勾选上着三个按钮

unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_10


上传完APK,在发布之前,游戏内的物品一定要设置

点击“应用内商品”

unity苹果支付沙盒 unity接入支付_Google_11


点击创建受管理的商品

unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_12


点击添加价格

unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_13


设置完后就可以发布了,点击应用版本=>点击项目上有修改版本=>点击右下角的查看=>发布发布完成后,在版本管理=>应用版本 点击管理测试人员有一个加入测试的网址 打开连接加入一下

unity苹果支付沙盒 unity接入支付_Google_14


到这Google后台基本设置好了

Unity设置

打开Unity点击Window=>Services 或Ctrl+0

unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_15

unity苹果支付沙盒 unity接入支付_Google_16


Google后台密钥在 开发工具=> 服务与API

unity苹果支付沙盒 unity接入支付_Code_17


如果输入进去说格式不对或者无效先看看是不是有空格,还是不行的话

unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_18


unity苹果支付沙盒 unity接入支付_Google_19

unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_20


unity苹果支付沙盒 unity接入支付_Google_21


unity苹果支付沙盒 unity接入支付_Google_22


点击ALL Import

unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_23


unity苹果支付沙盒 unity接入支付_Code_24


unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_25


unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_26


选择商品:

unity苹果支付沙盒 unity接入支付_Google_27


点击编辑脚本:

unity苹果支付沙盒 unity接入支付_unity苹果支付沙盒_28

将代码全部替换
#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


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

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

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

注意:测试机一定要,一定支持Google四件套