581 lines
24 KiB
C#
581 lines
24 KiB
C#
|
#if UNITY_PURCHASE
|
|||
|
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using NUnit.Framework.Constraints;
|
|||
|
using Unity.Services.Core;
|
|||
|
using Unity.Services.Core.Environments;
|
|||
|
using UnityEngine;
|
|||
|
using UnityEngine.Purchasing;
|
|||
|
using UnityEngine.Purchasing.Extension;
|
|||
|
using static WZ.IAPOrderManager;
|
|||
|
|
|||
|
|
|||
|
namespace WZ
|
|||
|
{
|
|||
|
public class IAPPurchaseManager : D_MonoSingleton<IAPPurchaseManager>, IDetailedStoreListener
|
|||
|
{
|
|||
|
#region API
|
|||
|
public void BuyProductByID(string productId, string productName, string gameExtraParam)
|
|||
|
{
|
|||
|
#if !UNITY_EDITOR
|
|||
|
RushSDKManager.Instance.OnPurchaseComplete(new PurchaseInfo(
|
|||
|
productName: productName,
|
|||
|
productID: productId,
|
|||
|
orderID: "",
|
|||
|
currency: "USD",
|
|||
|
price: "",
|
|||
|
gameExtra: gameExtraParam,
|
|||
|
failReason: "",
|
|||
|
orderAlreadyExists: false,
|
|||
|
purchaseResult: true,
|
|||
|
resultType: IAPResultType.PurchasingSuccess,
|
|||
|
productType: ""
|
|||
|
));
|
|||
|
#else
|
|||
|
_productName = productName;
|
|||
|
_gameExtraParam = gameExtraParam;
|
|||
|
Product m_p = GetProductInfoByID(productId);
|
|||
|
var currencyCode = "";
|
|||
|
var localizedPrice = "";
|
|||
|
if (m_p != null)
|
|||
|
{
|
|||
|
currencyCode = m_p.metadata.isoCurrencyCode;
|
|||
|
localizedPrice = m_p.metadata.localizedPrice.ToString();
|
|||
|
}
|
|||
|
|
|||
|
IAPEvent.LogIAPButtonClick(new PurchaseInfo(
|
|||
|
productName: _productName,
|
|||
|
productID: productId,
|
|||
|
orderID: "",
|
|||
|
currency: currencyCode,
|
|||
|
price: localizedPrice,
|
|||
|
gameExtra: _gameExtraParam,
|
|||
|
failReason: "",
|
|||
|
orderAlreadyExists: false,
|
|||
|
purchaseResult: false,
|
|||
|
resultType: IAPResultType.NULL,
|
|||
|
productType: ""));
|
|||
|
|
|||
|
if (IsInitialized())
|
|||
|
{
|
|||
|
if (_inPurchaseProgress)
|
|||
|
{
|
|||
|
LoggerUtils.Debug("[iap] The payment is in progress, please do not initiate the payment repeatedly.");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
Product product = _storeController.products.WithID(productId);
|
|||
|
if (product != null && product.availableToPurchase)
|
|||
|
{
|
|||
|
_inPurchaseProgress = true;
|
|||
|
LoggerUtils.Debug(
|
|||
|
string.Format("[iap] Purchasing product asychronously: '{0}'", product.definition.id));
|
|||
|
|
|||
|
if (_googlePlayConfiguration != null)
|
|||
|
{
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(productName))
|
|||
|
{
|
|||
|
_googlePlayConfiguration.SetObfuscatedAccountId(productName);
|
|||
|
}
|
|||
|
_googlePlayConfiguration.SetObfuscatedProfileId(gameExtraParam);
|
|||
|
LoggerUtils.Debug($"[iap] [BuyProductByID] 设置成功 userId = {productName} profileId = {gameExtraParam}");
|
|||
|
}
|
|||
|
_storeController.InitiatePurchase(product);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
IAPEvent.LogPurchaseFail(new PurchaseInfo(
|
|||
|
productName: _productName,
|
|||
|
productID: productId,
|
|||
|
orderID: "",
|
|||
|
currency: currencyCode,
|
|||
|
price: localizedPrice,
|
|||
|
gameExtra: _gameExtraParam,
|
|||
|
failReason: "BuyProductID FAIL. Not purchasing product, either is not found or is not available for purchase",
|
|||
|
orderAlreadyExists: false,
|
|||
|
purchaseResult: false,
|
|||
|
resultType: IAPResultType.NULL,
|
|||
|
productType: product.definition.type.ToString()));
|
|||
|
LoggerUtils.Debug("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase");
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
RushSDKManager.Instance.OnPurchaseComplete(new PurchaseInfo(
|
|||
|
productName: productName,
|
|||
|
productID: productId,
|
|||
|
orderID: "",
|
|||
|
currency: "",
|
|||
|
price: "",
|
|||
|
gameExtra: _gameExtraParam,
|
|||
|
failReason: "BuyProductID FAIL. IAP Not initialized or Not add product.",
|
|||
|
orderAlreadyExists: false,
|
|||
|
purchaseResult: false,
|
|||
|
resultType: IAPResultType.PurchasingUnavailable,
|
|||
|
productType: ""));
|
|||
|
|
|||
|
IAPEvent.LogPurchaseFail(new PurchaseInfo(
|
|||
|
productName: _productName,
|
|||
|
productID: productId,
|
|||
|
orderID: "",
|
|||
|
currency: currencyCode,
|
|||
|
price: localizedPrice,
|
|||
|
gameExtra: _gameExtraParam,
|
|||
|
failReason: "BuyProductID FAIL. Not purchasing product, either is not found or is not available for purchase",
|
|||
|
orderAlreadyExists: false,
|
|||
|
purchaseResult: false,
|
|||
|
resultType: IAPResultType.NULL,
|
|||
|
productType: ""));
|
|||
|
LoggerUtils.Debug("[iap] BuyProductID FAIL. IAP Not initialized or Not add product.");
|
|||
|
LoggerUtils.Debug("[iap] OnPurchaseFailed -> productId : " + productId + " , transactionID : " + "" + " , localizedPrice : " + "" + " , isoCurrencyCode : " + "");
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
public Product GetProductInfoByID(string pID)
|
|||
|
{
|
|||
|
if (_storeController == null && _storeExtensionProvider == null)
|
|||
|
return null;
|
|||
|
for (int i = 0; i < _storeController.products.all.Length; i++)
|
|||
|
{
|
|||
|
Product tItem = _storeController.products.all[i];
|
|||
|
if (tItem.definition.id.Equals(pID))
|
|||
|
{
|
|||
|
return tItem;
|
|||
|
}
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
public void AddProducts(Dictionary<string, ProductType> products, Action<bool, string> onProductsResult = null)
|
|||
|
{
|
|||
|
_initProductDic = products;
|
|||
|
|
|||
|
FetchAdditionalProducts(products, onProductsResult);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
|
|||
|
#region 购买成功
|
|||
|
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs purchaseEvent)
|
|||
|
{
|
|||
|
_inPurchaseProgress = false;
|
|||
|
|
|||
|
LoggerUtils.Debug("[iap] Purchase OK: " + purchaseEvent.purchasedProduct.definition.id);
|
|||
|
|
|||
|
var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(purchaseEvent.purchasedProduct.receipt);
|
|||
|
var payload = (string)wrapper["Payload"];
|
|||
|
var profileId = _gameExtraParam;
|
|||
|
var _productName = "";
|
|||
|
var payloadObj = (Dictionary<string, object>)MiniJson.JsonDecode(payload);
|
|||
|
var o = (string)payloadObj["json"];
|
|||
|
var payloadData = (Dictionary<string, object>)MiniJson.JsonDecode(o);
|
|||
|
|
|||
|
if (payloadData.TryGetValue("obfuscatedAccountId", out var obfuscatedAccountIdValue))
|
|||
|
{
|
|||
|
var obfuscatedAccountId = (string)obfuscatedAccountIdValue;
|
|||
|
if (!string.IsNullOrEmpty(obfuscatedAccountId))
|
|||
|
{
|
|||
|
_productName = obfuscatedAccountId;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (payloadData.TryGetValue("obfuscatedProfileId", out var value))
|
|||
|
{
|
|||
|
var obfuscatedProfileId = (string)value;
|
|||
|
if (!string.IsNullOrEmpty(obfuscatedProfileId))
|
|||
|
{
|
|||
|
profileId = obfuscatedProfileId;
|
|||
|
}
|
|||
|
}
|
|||
|
LoggerUtils.Debug("[iap] productName" + _productName + " profileId:" + profileId);
|
|||
|
|
|||
|
string token = "";
|
|||
|
string orderId = "";
|
|||
|
if (Application.platform == RuntimePlatform.Android)
|
|||
|
{
|
|||
|
var gpDetails = (Dictionary<string, object>)MiniJson.JsonDecode(payload);
|
|||
|
var gpJson = (string)gpDetails["json"];
|
|||
|
var tokenJson = (Dictionary<string, object>)MiniJson.JsonDecode(gpJson);
|
|||
|
token = (string)tokenJson["purchaseToken"];
|
|||
|
orderId = (string)tokenJson["orderId"];
|
|||
|
|
|||
|
LoggerUtils.Debug("[iap] ClientIAPSuccess productId : " + purchaseEvent.purchasedProduct.definition.id
|
|||
|
+ " , transactionID : " + orderId
|
|||
|
+ " , token : " + token
|
|||
|
+ " , localizedPrice : " + purchaseEvent.purchasedProduct.metadata.localizedPriceString
|
|||
|
+ " , isoCurrencyCode : " + purchaseEvent.purchasedProduct.metadata.isoCurrencyCode);
|
|||
|
}
|
|||
|
|
|||
|
IAPDataConfig newData = new IAPDataConfig();
|
|||
|
newData.info = new Dictionary<string, string>
|
|||
|
{
|
|||
|
{ "price", purchaseEvent.purchasedProduct.metadata.localizedPrice.ToString() },
|
|||
|
{ "product_id", purchaseEvent.purchasedProduct.definition.id },
|
|||
|
{ "product_name", (string)_productName },
|
|||
|
{ "purchase_token", token },
|
|||
|
{ "order_id", orderId },
|
|||
|
{ "currency", purchaseEvent.purchasedProduct.metadata.isoCurrencyCode },
|
|||
|
{ "payment_method", "googleplay" },
|
|||
|
{ "product_type", purchaseEvent.purchasedProduct.definition.type.ToString() },
|
|||
|
{ "mGameExtraParam", (string)profileId }
|
|||
|
};
|
|||
|
newData.state = IAPDataStateType.def;
|
|||
|
|
|||
|
IAPEvent.LogClientComplete(new PurchaseInfo(
|
|||
|
productName: (string)_productName,
|
|||
|
productID: purchaseEvent.purchasedProduct.definition.id,
|
|||
|
orderID: orderId,
|
|||
|
currency: purchaseEvent.purchasedProduct.metadata.isoCurrencyCode,
|
|||
|
price: purchaseEvent.purchasedProduct.metadata.localizedPrice.ToString(),
|
|||
|
gameExtra: _gameExtraParam,
|
|||
|
failReason: "",
|
|||
|
orderAlreadyExists: false,
|
|||
|
purchaseResult: true,
|
|||
|
resultType: IAPResultType.PurchasingSuccess,
|
|||
|
productType: purchaseEvent.purchasedProduct.definition.type.ToString()
|
|||
|
));
|
|||
|
|
|||
|
IAPOrderManager.Instance.SaveOrder(newData);
|
|||
|
IAPOrderManager.Instance.VerifyPurchase(newData);
|
|||
|
return PurchaseProcessingResult.Complete;
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 动态添加商品
|
|||
|
private void FetchAdditionalProducts(Dictionary<string, ProductType> ProductDic,
|
|||
|
Action<bool, string> onProductsResult = null)
|
|||
|
{
|
|||
|
if (!IsInitialized())
|
|||
|
{
|
|||
|
_addProductsDic = ProductDic;
|
|||
|
LoggerUtils.Debug("[iap] IAP not init.Now InitUnityPurchase");
|
|||
|
InitUnityPurchase();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (_isFetchingAdditionalProducts)
|
|||
|
{
|
|||
|
LoggerUtils.Debug("[iap] Now fetching additional products,don't call repeatedly");
|
|||
|
if (onProductsResult != null)
|
|||
|
{
|
|||
|
onProductsResult(false, "Now fetching additional products,don't call repeatedly");
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
_isFetchingAdditionalProducts = true;
|
|||
|
if (ProductDic != null)
|
|||
|
{
|
|||
|
var additional = new HashSet<ProductDefinition>();
|
|||
|
foreach (string tID in ProductDic.Keys)
|
|||
|
{
|
|||
|
additional.Add(new ProductDefinition(tID, ProductDic[tID]));
|
|||
|
}
|
|||
|
|
|||
|
Action onSuccess = () =>
|
|||
|
{
|
|||
|
_isFetchingAdditionalProducts = false;
|
|||
|
|
|||
|
LoggerUtils.Debug("[iap] Fetched successfully!");
|
|||
|
RushSDKManager.Instance.OnGetProductsInfo?.Invoke(_storeController.products.all);
|
|||
|
|
|||
|
foreach (var product in _storeController.products.all)
|
|||
|
{
|
|||
|
LoggerUtils.Debug("[iap]" + product.metadata.localizedTitle
|
|||
|
+ "|" + product.metadata.localizedPriceString
|
|||
|
+ "|" + product.metadata.localizedDescription
|
|||
|
+ "|" + product.metadata.isoCurrencyCode);
|
|||
|
}
|
|||
|
|
|||
|
if (onProductsResult != null)
|
|||
|
{
|
|||
|
onProductsResult(true, "Fetched successfully!");
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Action<InitializationFailureReason, string> onFailure = (InitializationFailureReason i, string msg) =>
|
|||
|
{
|
|||
|
_isFetchingAdditionalProducts = false;
|
|||
|
if (onProductsResult != null)
|
|||
|
{
|
|||
|
onProductsResult(true, "Fetching failed for the specified reason: " + i + " msg: " + msg);
|
|||
|
}
|
|||
|
|
|||
|
LoggerUtils.Debug("[iap] Fetching failed for the specified reason: " + i + " msg: " + msg);
|
|||
|
};
|
|||
|
|
|||
|
_storeController.FetchAdditionalProducts(additional, onSuccess, onFailure);
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 初始化
|
|||
|
public void PreInitialize()
|
|||
|
{
|
|||
|
LoggerUtils.Debug("[iap] PreInitialize() mServiceInit: " + _serviceInit);
|
|||
|
if (!_serviceInit)
|
|||
|
{
|
|||
|
InitializeUnityServices(OnSuccess, OnError);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void InitializeUnityServices(Action onSuccess, Action<string> onError)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
var options = new InitializationOptions().SetEnvironmentName("production");
|
|||
|
|
|||
|
UnityServices.InitializeAsync(options).ContinueWith(task => onSuccess());
|
|||
|
}
|
|||
|
catch (Exception exception)
|
|||
|
{
|
|||
|
onError(exception.Message);
|
|||
|
}
|
|||
|
}
|
|||
|
private void OnSuccess()
|
|||
|
{
|
|||
|
LoggerUtils.Debug("[iap] Congratulations!\nUnity Gaming Services has been successfully initialized.");
|
|||
|
_serviceInit = true;
|
|||
|
IAPEvent.LogPurchaseInit();
|
|||
|
}
|
|||
|
|
|||
|
private void OnError(string message)
|
|||
|
{
|
|||
|
LoggerUtils.Debug($"[iap] Unity Gaming Services failed to initialize with error: {message}.");
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 初始化IAP
|
|||
|
/// </summary>
|
|||
|
public void Initialize()
|
|||
|
{
|
|||
|
LoggerUtils.Debug("[iap] IAP Initialize() _storeController.Debug:" + _storeController + " m_StoreExtensionProvider: " + _storeExtensionProvider);
|
|||
|
if (_storeController == null && _storeExtensionProvider == null)
|
|||
|
InitUnityPurchase();
|
|||
|
}
|
|||
|
|
|||
|
private void InitUnityPurchase()
|
|||
|
{
|
|||
|
LoggerUtils.Debug("[iap] IAP InitUnityPurchase() IsInitialized: " + IsInitialized());
|
|||
|
if (IsInitialized()) return;
|
|||
|
|
|||
|
_repeatCountDic = new Dictionary<string, int>();
|
|||
|
|
|||
|
_module ??= StandardPurchasingModule.Instance();
|
|||
|
|
|||
|
// 配置模式;
|
|||
|
_builder ??= ConfigurationBuilder.Instance(_module);
|
|||
|
|
|||
|
int productsNum = 0;
|
|||
|
|
|||
|
if (_initProductDic != null && _initProductDic.Count > 0)
|
|||
|
{
|
|||
|
foreach (string tID in _initProductDic.Keys)
|
|||
|
{
|
|||
|
productsNum++;
|
|||
|
if (!string.IsNullOrEmpty(tID))
|
|||
|
{
|
|||
|
LoggerUtils.Debug($"[iap] Add InitProductDic APProducts: {tID}");
|
|||
|
_builder.AddProduct(tID, _initProductDic[tID]);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (_addProductsDic != null && _addProductsDic.Count > 0)
|
|||
|
{
|
|||
|
foreach (string tID in _addProductsDic.Keys)
|
|||
|
{
|
|||
|
productsNum++;
|
|||
|
if (!string.IsNullOrEmpty(tID))
|
|||
|
{
|
|||
|
LoggerUtils.Debug($"[iap] Add AddProductsDic IAPProducts: {tID}");
|
|||
|
_builder.AddProduct(tID, _addProductsDic[tID]);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
_googlePlayConfiguration = _builder.Configure<IGooglePlayConfiguration>();
|
|||
|
if (productsNum > 0)
|
|||
|
{
|
|||
|
UnityPurchasing.Initialize(this, _builder);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
LoggerUtils.Debug(
|
|||
|
"[iap] UnityPurchasing will not initialize.Products is empty,please add product.");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private bool IsInitialized()
|
|||
|
{
|
|||
|
return _storeController != null && _storeExtensionProvider != null;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 初始化成功
|
|||
|
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
|
|||
|
{
|
|||
|
LoggerUtils.Debug("[iap] IAP initialize Succeed!");
|
|||
|
|
|||
|
_storeController = controller;
|
|||
|
_storeExtensionProvider = extensions;
|
|||
|
|
|||
|
RushSDKManager.Instance.OnGetProductsInfo?.Invoke(_storeController.products.all);
|
|||
|
foreach (var product in _storeController.products.all)
|
|||
|
{
|
|||
|
LoggerUtils.Debug("[iap] " + product.metadata.localizedTitle
|
|||
|
+ "|" + product.metadata.localizedPriceString
|
|||
|
+ "|" + product.metadata.localizedDescription
|
|||
|
+ "|" + product.metadata.isoCurrencyCode
|
|||
|
+ "|" + product.definition.id
|
|||
|
+ "|" + product.definition.type);
|
|||
|
}
|
|||
|
|
|||
|
// CheckSubscribeReceipt();
|
|||
|
RushSDKManager.Instance.OnGetProductsInfo?.Invoke(_storeController.products.all);
|
|||
|
RushSDKManager.Instance.OnPurchaseInitComplete?.Invoke(true, "");
|
|||
|
IAPEvent.LogPurchaseInit(true);
|
|||
|
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 初始化失败
|
|||
|
public void OnInitializeFailed(InitializationFailureReason error)
|
|||
|
{
|
|||
|
OnInitializeFailed(error, "");
|
|||
|
RushSDKManager.Instance.OnPurchaseInitComplete?.Invoke(false, error.ToString());
|
|||
|
}
|
|||
|
|
|||
|
public void OnInitializeFailed(InitializationFailureReason error, string message)
|
|||
|
{
|
|||
|
LoggerUtils.Debug("[iap] IAP OnInitializeFailed error:" + error.ToString() + " msg:" + message);
|
|||
|
switch (error)
|
|||
|
{
|
|||
|
case InitializationFailureReason.AppNotKnown:
|
|||
|
LoggerUtils.Debug("[iap] Is your App correctly uploaded on the relevant publisher console?");
|
|||
|
break;
|
|||
|
case InitializationFailureReason.PurchasingUnavailable:
|
|||
|
LoggerUtils.Debug("[iap] Billing disabled! Ask the user if billing is disabled in device settings.");
|
|||
|
break;
|
|||
|
case InitializationFailureReason.NoProductsAvailable:
|
|||
|
LoggerUtils.Debug("[iap] No products available for purchase! Developer configuration error; check product metadata!");
|
|||
|
break;
|
|||
|
}
|
|||
|
IAPEvent.LogPurchaseInit(false, error.ToString());
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 购买失败
|
|||
|
public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription)
|
|||
|
{
|
|||
|
LoggerUtils.Debug("[iap] OnPurchaseFailed productId : " + failureDescription.productId
|
|||
|
+ " , transactionID : " + product.transactionID
|
|||
|
+ " , localizedPrice : " + product.metadata.localizedPriceString
|
|||
|
+ " , isoCurrencyCode : " + product.metadata.isoCurrencyCode
|
|||
|
+ "failureDescription" + failureDescription.message);
|
|||
|
|
|||
|
|
|||
|
// 失败打点
|
|||
|
IAPEvent.LogPurchaseFail(new PurchaseInfo(
|
|||
|
productName: product.metadata.localizedTitle,
|
|||
|
productID: product.definition.id,
|
|||
|
orderID: "",
|
|||
|
currency: product.metadata.isoCurrencyCode,
|
|||
|
price: product.metadata.localizedPriceString,
|
|||
|
gameExtra: _gameExtraParam,
|
|||
|
failReason: failureDescription.message,
|
|||
|
orderAlreadyExists: false,
|
|||
|
purchaseResult: false,
|
|||
|
resultType: (IAPResultType)failureDescription.reason,
|
|||
|
productType: product.definition.type.ToString()
|
|||
|
));
|
|||
|
|
|||
|
// 购买失败回调
|
|||
|
RushSDKManager.Instance.OnPurchaseComplete(new PurchaseInfo(
|
|||
|
productName: product.metadata.localizedTitle,
|
|||
|
productID: product.definition.id,
|
|||
|
orderID: "",
|
|||
|
currency: product.metadata.isoCurrencyCode,
|
|||
|
price: product.metadata.localizedPriceString,
|
|||
|
gameExtra: _gameExtraParam,
|
|||
|
failReason: failureDescription.message,
|
|||
|
orderAlreadyExists: false,
|
|||
|
purchaseResult: false,
|
|||
|
resultType: (IAPResultType)failureDescription.reason,
|
|||
|
productType: product.definition.type.ToString()
|
|||
|
));
|
|||
|
}
|
|||
|
|
|||
|
public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
|
|||
|
{
|
|||
|
// m_PurchaseInProgress = false;
|
|||
|
LoggerUtils.Debug("[iap] OnPurchaseFailed productId -> : " + product.definition.id
|
|||
|
+ " , transactionID : " + product.transactionID
|
|||
|
+ " , localizedPrice : " + product.metadata.localizedPriceString
|
|||
|
+ " , isoCurrencyCode : " + product.metadata.isoCurrencyCode
|
|||
|
+ " , failureReason : " + failureReason.ToString());
|
|||
|
|
|||
|
|
|||
|
// 失败打点
|
|||
|
IAPEvent.LogPurchaseFail(new PurchaseInfo(
|
|||
|
productName: product.metadata.localizedTitle,
|
|||
|
productID: product.definition.id,
|
|||
|
orderID: "",
|
|||
|
currency: product.metadata.isoCurrencyCode,
|
|||
|
price: product.metadata.localizedPriceString,
|
|||
|
gameExtra: _gameExtraParam,
|
|||
|
productType: "",
|
|||
|
failReason: failureReason.ToString(),
|
|||
|
orderAlreadyExists: false,
|
|||
|
purchaseResult: false,
|
|||
|
resultType: (IAPResultType)failureReason)
|
|||
|
);
|
|||
|
|
|||
|
// 购买失败回调
|
|||
|
RushSDKManager.Instance.OnPurchaseComplete(new PurchaseInfo(
|
|||
|
productName: product.metadata.localizedTitle,
|
|||
|
productID: product.definition.id,
|
|||
|
orderID: "",
|
|||
|
currency: product.metadata.isoCurrencyCode,
|
|||
|
price: product.metadata.localizedPriceString,
|
|||
|
gameExtra: _gameExtraParam,
|
|||
|
failReason: failureReason.ToString(),
|
|||
|
orderAlreadyExists: false,
|
|||
|
purchaseResult: false,
|
|||
|
resultType: (IAPResultType)failureReason,
|
|||
|
productType: product.definition.type.ToString()
|
|||
|
|
|||
|
));
|
|||
|
// ReadFailOrderId();
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Properties
|
|||
|
private StandardPurchasingModule _module;
|
|||
|
private ConfigurationBuilder _builder;
|
|||
|
private static IStoreController _storeController;
|
|||
|
private static IExtensionProvider _storeExtensionProvider;
|
|||
|
public string _gameExtraParam = "";
|
|||
|
private static string _productName = "";
|
|||
|
private bool _inPurchaseProgress = false;
|
|||
|
public Dictionary<string, Dictionary<string, object>> _productArgs = new Dictionary<string, Dictionary<string, object>>();
|
|||
|
private bool _serviceInit = false;
|
|||
|
private Dictionary<string, ProductType> _addProductsDic;
|
|||
|
private Dictionary<string, ProductType> _initProductDic;
|
|||
|
private Dictionary<string, int> _repeatCountDic;
|
|||
|
private IGooglePlayConfiguration _googlePlayConfiguration;
|
|||
|
private bool _isFetchingAdditionalProducts = false;
|
|||
|
#endregion
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endif
|