Files
tysdk-intergration/sdk-intergration/Packages/tysdk/Runtime/TYSdkModel.cs
Liubing\LB de3ff3b7a4 feat: 支付验签框架 — 策略模式 + 装饰器重试
- 新增 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>
2026-05-11 11:25:20 +08:00

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
}