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}
}
);
#if !UNITY_EDITOR
validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), Application.bundleIdentifier);
#endif
UnityPurchasing.Initialize (this, builder);
}
解析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}
}
);
#if !UNITY_EDITOR
validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), Application.bundleIdentifier);
#endif
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");
}
}
实现IStoreListener支付回调
成功:
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());
}
IOS deferred:
/// <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);
}