Unity自带IAP插件使用(googleplay)
https://blog.csdn.net/ar__ha/article/details/64439872
Unity Services里的Unity IAP对于IOS和GooglePlay的支付用这个插件就足够了。
1.集成插件
Window-Services(Ctrl+0)在Services面板Link你的工程,启用In-App Purchase,Import/Update一下,插件就在Assets/Plugins/UnityPurchasing下。
2.设置
以GooglePlay的设置为例
Window - Unity Iap - Android - Target Google Play :选择GooglePlay,
Window - Unity Iap - Receipt Validation Obfuscator :输入GooglePlay的PublicKey,
点击Obfuscate secrets后,在Assets/Plugins/UnityPurchasing/generated下会生产GooglePlayTangle自动生成的文件,不用管他。
但是要注意到他的宏定义
#if UNITY_ANDROID || UNITY_IPHONE || UNITY_STANDALONE_OSX || UNITY_TVOS
3.DEMO
插件的demo在Assets/Plugins/UnityPurchasing/scenes/IAP Demo 这个场景里
也可以直接看cs文件,Assets/Plugins/UnityPurchasing/script/IAPDemo.cs
主要用到的是UnityEngine.Purchasing.IStoreListener 这个接口
4.初始化
-
//使用这个解析IAP成功后的receipt
-
private UnityEngine.Purchasing.Security.CrossPlatformValidator validator;
-
-
-
private void InitUnityPurchase() {
-
var module = StandardPurchasingModule.Instance();
-
var builder = ConfigurationBuilder.Instance (module);
-
-
//添加计费点
-
// UnityEngine.Purchasing.ProductType
-
builder.AddProduct("item1", ProductType.Consumable, new IDs
-
{
-
{"苹果计费点", AppleAppStore.Name },
-
{"谷歌计费点", GooglePlay.Name}
-
}
-
);
-
-
validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), Application.bundleIdentifier);
-
-
UnityPurchasing.Initialize (this, builder);
-
}
实现IStoreListener 接口初始化回调
成功:
-
private IStoreController m_Controller;
-
-
-
//UNITY IAP初始化成功
-
public void OnInitialized (IStoreController controller, IExtensionProvider extensions) {
-
m_Controller = controller;
-
-
// On Apple platforms we need to handle deferred purchases caused by Apple's Ask to Buy feature.
-
// On non-Apple platforms this will have no effect; OnDeferred will never be called.
-
var m_AppleExtensions = extensions.GetExtension<IAppleExtensions> ();
-
m_AppleExtensions.RegisterPurchaseDeferredListener(OnDeferred);
-
-
var product = m_Controller.products.WithID("item1");
-
//价格 (带货币单位的字符串)
-
var priceString = product.metadata.localizedPriceString;
-
//价格 (换算汇率后的价格)
-
var price = product.metadata.localizedPrice;
-
}
失败:
-
//初始化失败(没有网络的情况下并不会调起,而是一直等到有网络连接再尝试初始化)
-
public void OnInitializeFailed (InitializationFailureReason error) {
-
-
Debug.Log("Billing failed to initialize!");
-
switch (error) {
-
case InitializationFailureReason.AppNotKnown:
-
Debug.LogError("Is your App correctly uploaded on the relevant publisher console?");
-
break;
-
case InitializationFailureReason.PurchasingUnavailable:
-
// Ask the user if billing is disabled in device settings.
-
Debug.Log("Billing disabled!");
-
break;
-
case InitializationFailureReason.NoProductsAvailable:
-
// Developer configuration error; check product metadata.
-
Debug.Log("No products available for purchase!");
-
break;
-
}
-
}
5.发起支付
-
public void DoIapPurchase (Action<bool, string> callback) {
-
if (m_Controller != null) {
-
var product = m_Controller.products.WithID ("item1");
-
if (product != null && product.availableToPurchase) {
-
//调起支付
-
m_Controller.InitiatePurchase(product);
-
}
-
else {
-
callback (false, "no available product");
-
}
-
}
-
else {
-
callback ( false, "m_Controller is null");
-
}
-
}
成功:
-
public PurchaseProcessingResult ProcessPurchase (PurchaseEventArgs e) {
-
try {
-
var result = validator.Validate (e.purchasedProduct.receipt);
-
Debug.Log ("Receipt is valid. Contents:");
-
foreach (IPurchaseReceipt productReceipt in result) {
-
Debug.Log(productReceipt.productID);
-
Debug.Log(productReceipt.purchaseDate);
-
Debug.Log(productReceipt.transactionID);
-
-
AppleInAppPurchaseReceipt apple = productReceipt as AppleInAppPurchaseReceipt;
-
if (null != apple) {
-
Debug.Log(apple.originalTransactionIdentifier);
-
Debug.Log(apple.subscriptionExpirationDate);
-
Debug.Log(apple.cancellationDate);
-
Debug.Log(apple.quantity);
-
-
-
//如果有服务器,服务器用这个receipt去苹果验证。
-
var receiptJson = JSONObject.Parse(e.purchasedProduct.receipt);
-
var receipt = receiptJson.GetString("Payload");
-
}
-
-
GooglePlayReceipt google = productReceipt as GooglePlayReceipt;
-
if (null != google) {
-
Debug.Log(google.purchaseState);
-
Debug.Log(google.purchaseToken);
-
}
-
}
-
return PurchaseProcessingResult.Complete;
-
} catch (IAPSecurityException) {
-
Debug.Log("Invalid receipt, not unlocking content");
-
return PurchaseProcessingResult.Complete;
-
}
-
return PurchaseProcessingResult.Complete;
-
}
-
public void OnPurchaseFailed(Product i, PurchaseFailureReason p) {
-
Logger.Warning("purchase failed of reason : " + p.ToString());
-
}
-
/// <summary>
-
/// iOS Specific.
-
/// This is called as part of Apple's 'Ask to buy' functionality,
-
/// when a purchase is requested by a minor and referred to a parent
-
/// for approval.
-
///
-
/// When the purchase is approved or rejected, the normal purchase events
-
/// will fire.
-
/// </summary>
-
/// <param name="item">Item.</param>
-
private void OnDeferred(Product item)
-
{
-
Logger.Warning("Purchase deferred: " + item.definition.id);
-
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术