Files
tysdk-intergration/sdk-intergration/Packages/tysdk/Runtime/TYSdkFacade_Pay.cs

219 lines
8.0 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using UnityEngine;
using System;
using System.Text;
namespace tysdk
{
public partial class TYSdkFacade
{
/*================================================
____ _
| _ \ __ _ _ _ _ __ ___ ___ _ __ | |_
| |_) / _` | | | | '_ ` _ \ / _ \ '_ \| __|
| __/ (_| | |_| | | | | | | __/ | | | |_
|_| \__,_|\__, |_| |_| |_|\___|_| |_|\__|
|___/
=================================================*/
private bool _payFirstNegativeHandled;
public async Task<PaymentInfo> Pay(SKUDetail prod, int count, float usdprice, JObject purchaseInfo)
{
if (!IsLoggedIn) return new PaymentInfo() { code = "-1", msg = "未登录" };
var orderId = System.Guid.NewGuid().ToString();
if (purchaseInfo == null)
purchaseInfo = new JObject();
string extraInfo = purchaseInfo.ToString(Newtonsoft.Json.Formatting.None);
extraInfo = Convert.ToBase64String(Encoding.UTF8.GetBytes(extraInfo));
Debug.Log("[TYSdk] extraInfo: " + extraInfo);
var prodId = prod.ProdID;
var prodPrice = usdprice.ToString();
var prodName = prod.title;
#if UNITY_EDITOR
await Task.Yield();
var result = new PaymentInfo()
{
code = "0",
msg = "success",
count = count,
orderId = orderId,
productId = prodId,
price = prodPrice
};
return result;
#elif UNITY_ANDROID
var pType = ChannelConfig.PayType;
var task = TYSDKCallbackManager.Instance.RegisterCallback<PaymentInfo>(TimeSpan.FromSeconds(90));
try
{
UnityBridgeFunc.UnityKnowNew(prodId, prodPrice, prodName, count.ToString(), orderId, extraInfo, pType);
var result = await task;
result.count = count;
result.orderId = orderId;
result.productId = prodId;
result.price = prodPrice;
result.Check(orderId, prodId);
return result;
}
catch (Exception e)
{
Debug.LogWarning($"[TYSdkFacade::Pay] Faild {e.Message}");
return new PaymentInfo(){code = "-1"};
}
finally
{
_payFirstNegativeHandled = false;
}
#elif UNITY_IOS
var task = TYSDKCallbackManager.Instance.RegisterCallback<PaymentInfo>(TimeSpan.FromSeconds(30));
UnityBridgeFunc.UnityKnow(_accountInfo.strUserId, prodId, prodPrice, prodName, count.ToString(), orderId, extraInfo);
try{
var result = await task;
result.count = count;
result.orderId = orderId;
result.productId = prodId;
result.price = prodPrice;
return result;
}
catch(Exception e)
{
Debug.LogWarning($"[TYSdkFacade::Pay] Faild {e.Message}");
return new PaymentInfo(){code = "-1"};
}
finally
{
_payFirstNegativeHandled = false;
}
#endif
}
public void PayResult(string json)
{
Debug.Log("[TYSdkFacade] pay callback:" + json);
var jresult = JObject.Parse(json);
var result = new PaymentInfo();
result.code = jresult["code"].ToString();
result.msg = jresult["errStr"].ToString();
result.purchaseJson = jresult["purchaseJson"]?.ToString();
result.signature = jresult["signature"]?.ToString();
result.purchaseToken = jresult["purchaseToken"]?.ToString();
result.userId = _accountInfo?.strUserId;
if (result.code == "-1")
{
if (!_payFirstNegativeHandled)
{
_payFirstNegativeHandled = true;
TYSDKCallbackManager.Instance.ResetCallbackTimeout<PaymentInfo>(TimeSpan.FromSeconds(5));
Debug.Log("[TYSdkFacade] pay failed (first time): reset timeout to 5s, waiting next pay callback");
}
else
{
Debug.Log("[TYSdkFacade] pay failed: waiting next pay callback");
}
return;
}
var processor = PaymentProcessorFactory.GetProcessor();
if (processor?.verifier != null && !string.IsNullOrEmpty(result.purchaseJson))
{
_VerifyPurchase(result, processor);
}
else
{
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
}
}
private async void _VerifyPurchase(PaymentInfo result, PaymentProcessor processor)
{
TYSDKCallbackManager.Instance.ResetCallbackTimeout<PaymentInfo>(TimeSpan.FromSeconds(60));
try
{
var verifyResult = await processor.verifier.VerifyAsync(result);
if (verifyResult.success)
{
result.verified = true;
if (!string.IsNullOrEmpty(verifyResult.orderId))
result.serverOrderId = verifyResult.orderId;
if (processor.consumer != null && !string.IsNullOrEmpty(result.purchaseToken))
{
var consumeResult = await processor.consumer.ConsumeAsync(result.purchaseToken);
if (!consumeResult.success)
{
Debug.LogWarning("[TYSdkFacade] Purchase consume failed: " + consumeResult.msg);
}
}
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
}
else
{
Debug.LogWarning("[TYSdkFacade] Payment verification failed: " + verifyResult.msg);
result.code = "-1";
result.msg = "verification_failed: " + verifyResult.msg;
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
}
}
catch (Exception e)
{
Debug.LogError("[TYSdkFacade] Verification exception: " + e.Message);
result.code = "-1";
result.msg = "verification_error: " + e.Message;
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
}
}
public async Task<ProductListInfo> GetSKUList()
{
if (!IsLoggedIn) return new ProductListInfo() { code = -1, msg = "未登录" };
#if UNITY_EDITOR
await Task.Yield();
var result = new ProductListInfo();
return result;
#elif UNITY_ANDROID || UNITY_IOS
var task = TYSDKCallbackManager.Instance.RegisterCallback<ProductListInfo>();
UnityBridgeFunc.GetSKUList();
var result = await task;
return result;
#endif
}
public void SKUListResult(string json)
{
Debug.Log("[TYSdkFacade] GetSKUList callback");
var jresult = JObject.Parse(json);
int code = int.Parse(jresult["code"].ToString());
var result = new ProductListInfo();
if (code == 0)
{
string productStr = jresult["respObj"].ToString();
result.code = code;
#if UNITY_ANDROID && !UNITY_EDITOR
var jsonObjList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<SKUDetail>>(productStr);
result.products = jsonObjList;
#elif UNITY_IOS && !UNITY_EDITOR
result.ReadSKUFromJson(productStr);
#endif
}
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
}
}
}