- 新增 IPaymentVerifier 接口 (Verify + Consume),渠道无关 - 新增 PaymentVerifierFactory 按 Channel 分发 - 新增 FlexionPaymentVerifier: HTTP 验签 + 线性 backoff 重试 - 新增 DummyPaymentVerifier: 占位验签实现 - 新增 RetryablePaymentVerifier: 装饰器,流程级重试 - TYSdkFacade_Pay: PayResult 增加验签分支,先验签后消费再回调 - TYSdkModel: PaymentInfo 增加 verified 字段 - UnityBridgeFunc: 移除 ConsumeFlexionPurchase(职责收归 Verifier) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
116 lines
3.5 KiB
C#
116 lines
3.5 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace tysdk
|
|
{
|
|
public class PaymentInfo
|
|
{
|
|
public bool isSuccessFromSdk => code == "0";
|
|
public bool isSuccess => isSuccessFromSdk && confirmed;
|
|
private bool confirmed { get; set; } = false;
|
|
public int count;
|
|
public string orderId;
|
|
public string productId;
|
|
public string price;
|
|
|
|
public string code;
|
|
public string msg;
|
|
|
|
// Flexion: purchase.getOriginalJson(), used by server for RSA signature verification
|
|
public string purchaseJson;
|
|
// Flexion: purchase.getSignature(), used by server for RSA signature verification
|
|
public string signature;
|
|
// Flexion: purchase token, used to consume after server verification
|
|
public string purchaseToken;
|
|
|
|
public bool verified;
|
|
|
|
public bool Check(string orderId, string productId)
|
|
{
|
|
confirmed = orderId == this.orderId && productId == this.productId;
|
|
|
|
if (!confirmed)
|
|
UnityEngine.Debug.LogWarning("[TYSdk Pay] order not confirmed");
|
|
return confirmed;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return JsonConvert.SerializeObject(this);
|
|
}
|
|
}
|
|
|
|
public class ProductListInfo
|
|
{
|
|
public int code = 1;
|
|
public string msg = string.Empty;
|
|
public List<SKUDetail> products;
|
|
|
|
#if UNITY_IOS && !UNITY_EDITOR
|
|
public void ReadSKUFromJson(string json)
|
|
{
|
|
var prodList = Newtonsoft.Json.Linq.JArray.Parse(json).Select(x => {
|
|
return new SKUDetail() {
|
|
price = x["price"].ToString(),
|
|
productId = x["productId"].ToString(),
|
|
price_currency_code = x["LocaleCurrencyCode"].ToString(),
|
|
localeCurrencySymbol = x["localeCurrencySymbol"].ToString(),
|
|
localizedDescription = x["localizedDescription"].ToString(),
|
|
title = x["localizedTitle"].ToString(),
|
|
ProdKey = x["productIdentifier"].ToString()
|
|
};
|
|
}).ToList();
|
|
products = prodList;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#if UNITY_IOS
|
|
public class SKUDetail
|
|
{
|
|
public string price;
|
|
public string productId;
|
|
public string price_currency_code;
|
|
public string localeCurrencySymbol;
|
|
public string localizedDescription;
|
|
public string title;
|
|
public string type;
|
|
|
|
public string ProdPriceStr => price;
|
|
public float ProdPrice => float.Parse(price);
|
|
public string ProdID => productId;
|
|
public string ProdKey;
|
|
|
|
public override string ToString()
|
|
{
|
|
return JsonConvert.SerializeObject(this);
|
|
}
|
|
}
|
|
#else
|
|
public class SKUDetail
|
|
{
|
|
public string description;
|
|
public string ourProductId;
|
|
public string productId;
|
|
public string price;
|
|
public string price_amount_micros;
|
|
public string price_currency_code;
|
|
public string title;
|
|
public string type;
|
|
public string currency;
|
|
public string price_amount;
|
|
|
|
public string ProdPriceStr => price;
|
|
public float ProdPrice => float.Parse(price_amount_micros) / 1000000;
|
|
public string ProdID => ourProductId;
|
|
public string ProdKey => productId;
|
|
|
|
public override string ToString()
|
|
{
|
|
return JsonConvert.SerializeObject(this);
|
|
}
|
|
}
|
|
#endif
|
|
}
|