支持二次验证,json解析完之后,把解析出来的参数发给服务器,因为是unity封装的sdk,code参数需要在购买成功之后的回调里给服务器发个int类型的参数,赋值为零。服务器要接Google源生的;
如果有不明白的加QQ群:636926481
我写这个是需要跟我们服务器验证的,如果不用跟服务器验证就不用复制本文档的代码,直接在untiy里面设置商品就可以;
1.打开unity
2.如果没有出现这个界面说明你没有登录unity,有账号的就登陆就可以,没有的自己申请
3.操作完之后点击import
如果遇到
解决办法
https://blog.csdn.net/qq_39954479/article/details/92831042
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
{
};
[System.Serializable]
public class OnPurchaseFailedEvent : UnityEvent
{
};
[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
对于后期会涉及到更新,需要代码控制商品的游戏,建议使用
需要把第七步填写的参数全部去掉,把客户端商品上的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();
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)MiniJson.JsonDecode(e.receipt);
var store = (string)wrapper["Store"];
var payload = (string)wrapper["Payload"];
ISGoogle = true;
var gpDetails = (Dictionary)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)MiniJson.JsonDecode(e.purchasedProduct.receipt);
var store = (string)wrapper["Store"];
ISGoogle = true;
var payload = (string)wrapper["Payload"];
var gpDetails = (Dictionary)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账号全部移除,在重新登录就好了,就可以了