update:逻辑更新

This commit is contained in:
2026-05-21 00:37:19 +08:00
parent eecf54c6a4
commit ed6fe668ad
29 changed files with 677 additions and 747 deletions

View File

@@ -1,10 +1,10 @@
package com.unity3d.player;
public class ChannelHelpers {
public class ChannelEntry {
public static final String CHANNEL = "GooglePlay";
static void register() {
// GooglePlay uses default behavior, no additional SDKHelper
public static SDKManager.IChannelSDKAdapter createSDKAdapter() {
return null;
}
public static String normalizeSkuList(String msg) {

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 576805d2d0194634b8d235fd6837195e
guid: eac9aa9954e93c54fbafd3974ca30a5b
PluginImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -34,12 +34,10 @@ import com.tuyoo.gamesdk.model.InitParam;
import com.tuyoo.gamesdk.pay.model.PayType;
import com.tuyoo.gamesdk.util.SDKLog;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@@ -57,57 +55,74 @@ public class SDKManager {
private static SnsInfo tmpSnsInfo;
private static String channel = "GooglePlay";
// Channel helper
public interface ISDKHelper {
// Channel SDK adapter
public interface IChannelSDKAdapter {
void init(Activity activity);
}
public interface IPaymentAdapter {
void pay(Activity activity, String productId, String productPrice,
String productName, String productCount, String prodorderId,
String appInfo);
void queryProducts();
void consume(String token);
}
private static ISDKHelper sdkHelper;
public interface IProductQueryAdapter {
void queryProducts();
void queryProducts(String productIds);
}
public static void registerHelper(ISDKHelper helper) {
sdkHelper = helper;
public interface IPendingPurchaseAdapter {
String getPendingPurchases();
}
private static IChannelSDKAdapter sdkAdapter;
public static void queryProductsByIDs(String productIds) {
if (sdkAdapter instanceof IProductQueryAdapter) {
((IProductQueryAdapter) sdkAdapter).queryProducts(productIds);
return;
}
Log.e(TAG, "queryProductsByIDs: no product query adapter");
}
public static void ConsumePurchase(String token) {
Log.i(TAG, "ConsumePurchase: token=" + token);
if (sdkHelper != null) {
sdkHelper.consume(token);
if (sdkAdapter instanceof IPaymentAdapter) {
((IPaymentAdapter) sdkAdapter).consume(token);
}
}
public static String GetPendingPurchases() {
if (sdkAdapter instanceof IPendingPurchaseAdapter) {
return ((IPendingPurchaseAdapter) sdkAdapter).getPendingPurchases();
}
return "[]";
}
public static void CancelBillingFlow() {
Log.w(TAG, "CancelBillingFlow");
// FlexionSDKService.cancelPurchase();
}
// -------------------------------------------------------------------------
// Init — with channel helper support
// -------------------------------------------------------------------------
public static void InitSDK(Activity activity, String ch) {
channel = ChannelHelpers.CHANNEL;
ChannelHelpers.register();
// var builder = SDKManager.ExtendBuilder()
// .WithChannel(SDKManagerExt.CHANNEL)
// .WithInit(SDKManagerExt.GetInit())
// .WithPay(SDKManagerExt.GetPay())
// .WithQuery(SDKManagerExt.GetQuery())
// .Builder()
channel = ChannelEntry.CHANNEL;
sdkAdapter = ChannelEntry.createSDKAdapter();
Log.i(TAG, "[CHANNEL-VERIFY] Java InitSDK channel=" + channel
+ " fromCSharp=" + ch
+ " helper=" + (sdkHelper != null ? sdkHelper.getClass().getSimpleName() : "default"));
+ " adapter=" + (sdkAdapter != null ? sdkAdapter.getClass().getSimpleName() : "default"));
// Sync channel to C# ChannelConfig
UnityPlayer.UnitySendMessage(ConfigManager.UNITY_FACADE_NAME,
"SetChannelFromNative", channel);
// build.init(activity)
if (sdkHelper != null) {
sdkHelper.init(activity);
if (sdkAdapter != null) {
sdkAdapter.init(activity);
} else {
initDefault(activity);
}
@@ -394,7 +409,7 @@ public class SDKManager {
// -------------------------------------------------------------------------
public static void UnityKnow(String productId, String productName, String productCount,
String prodorderId, String appInfo) {
String prodorderId, String appInfo) {
SDKLog.i("UnityKnow : " + productId);
HashMap<String, String> extraInfo = new HashMap<String, String>();
extraInfo.put("appInfo", appInfo);
@@ -405,8 +420,8 @@ public class SDKManager {
public static void UnityKnowNew(String productId, String productPrice, String productName,
String productCount, String prodorderId, String appInfo,
String ptype) {
if (sdkHelper != null) {
sdkHelper.pay(UnityPlayer.currentActivity, productId, productPrice, productName, productCount, prodorderId, appInfo);
if (sdkAdapter instanceof IPaymentAdapter) {
((IPaymentAdapter) sdkAdapter).pay(UnityPlayer.currentActivity, productId, productPrice, productName, productCount, prodorderId, appInfo);
return;
}
PayEventData.PayData payData = new PayEventData.PayData();
@@ -430,9 +445,9 @@ public class SDKManager {
// -------------------------------------------------------------------------
public static void thirdExtend() {
Log.e(TAG, "thirdExtend called, sdkHelper=" + (sdkHelper != null ? sdkHelper.getClass().getSimpleName() : "null"));
if (sdkHelper != null) {
sdkHelper.queryProducts();
Log.e(TAG, "thirdExtend called, sdkAdapter=" + (sdkAdapter != null ? sdkAdapter.getClass().getSimpleName() : "null"));
if (sdkAdapter instanceof IProductQueryAdapter) {
((IProductQueryAdapter) sdkAdapter).queryProducts();
return;
}
defaultThirdExtend();
@@ -454,7 +469,7 @@ public class SDKManager {
JSONObject result = new JSONObject();
result.put("code", code);
if (code == SDKCallBack.Extend.EXTEND_CODE_SUCCESS) {
result.put("respObj", ChannelHelpers.normalizeSkuList(msg));
result.put("respObj", ChannelEntry.normalizeSkuList(msg));
} else {
Log.e(TAG, "thirdExtend failed: " + msg);
result.put("thirdExtend_errStr", msg);
@@ -520,7 +535,7 @@ public class SDKManager {
case 2: GetGameGa().track(EventType.COIN, eventstr, paramsBuilder); break;
case 3: GetGameGa().track(EventType.PAY, eventstr, paramsBuilder); break;
case 4: GetGameGa().track(EventType.GAME, eventstr, paramsBuilder); break;
case 5: GetGameGa().track(EventType.PAY, eventstr, paramsBuilder); break;
case 5: GetGameGa().track(EventType.LOGIN, eventstr, paramsBuilder); break;
case 6: GetGameGa().track(EventType.PUSH, eventstr, paramsBuilder); break;
case 7: GetGameGa().track(EventType.ADBOX, eventstr, paramsBuilder); break;
case 8: GetGameGa().track(EventType.PREFORMANCE, eventstr, paramsBuilder); break;

View File

@@ -1,258 +0,0 @@
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using asap.core;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Networking;
namespace tysdk
{
public interface IPaymentVerifier
{
Task<PaymentVerifyResult> VerifyAsync(PaymentInfo info);
}
public interface IPurchaseConsumer
{
Task<PurchaseConsumeResult> ConsumeAsync(string token);
}
public class PaymentVerifyResult
{
public bool success;
public string msg;
public string orderId;
}
public class FlexionOrderResult
{
public int code { get; set; }
public string info { get; set; }
public string orderId { get; set; }
}
public class PurchaseConsumeResult
{
public bool success;
public string msg;
}
public class PaymentProcessor
{
public IPaymentVerifier verifier;
public IPurchaseConsumer consumer;
}
public static class PaymentProcessorFactory
{
private static PaymentProcessor _processor;
private static string _cachedChannel;
public static PaymentProcessor GetProcessor()
{
var channel = ChannelConfig.Channel;
if (_processor != null && _cachedChannel == channel)
return _processor;
_processor = channel switch
{
"Flexion" => new PaymentProcessor
{
verifier = new RetryingPaymentVerifier(new FlexionPaymentVerifier()),
consumer = new FlexionPurchaseConsumer()
},
"Dummy" => new PaymentProcessor
{
verifier = new RetryingPaymentVerifier(new FakePaymentVerifier()),
consumer = new FakePurchaseConsumer()
},
_ => null
};
_cachedChannel = channel;
return _processor;
}
}
public class RetryingPaymentVerifier : IPaymentVerifier
{
private readonly IPaymentVerifier _inner;
private const int MaxRetries = 2;
private static readonly TimeSpan RetryInterval = TimeSpan.FromSeconds(2);
public RetryingPaymentVerifier(IPaymentVerifier inner)
{
_inner = inner;
}
public async Task<PaymentVerifyResult> VerifyAsync(PaymentInfo info)
{
PaymentVerifyResult lastResult = null;
for (int attempt = 0; attempt <= MaxRetries; attempt++)
{
if (attempt > 0)
{
Debug.Log($"[RetryingPaymentVerifier] Retry {attempt}/{MaxRetries}, waiting {RetryInterval.TotalSeconds}s");
await Task.Delay(RetryInterval);
}
lastResult = await _inner.VerifyAsync(info);
if (lastResult.success) return lastResult;
Debug.LogWarning($"[RetryingPaymentVerifier] Attempt {attempt + 1} failed: {lastResult.msg}");
}
return lastResult;
}
}
public class FlexionPaymentVerifier : IPaymentVerifier
{
private const string DEFAULT_PAY_VERIFY_URL = "http://192.168.9.91:7036/api/FlexionCallback";
private readonly string _verifyUrl;
private static readonly TimeSpan Timeout = TimeSpan.FromSeconds(30);
public FlexionPaymentVerifier()
{
var config = GContext.container.Resolve<IConfig>();
_verifyUrl = config.Get<string>("PAY_VERIFY_URL", DEFAULT_PAY_VERIFY_URL);
}
#if UNITY_EDITOR
public async Task<PaymentVerifyResult> VerifyAsync(PaymentInfo info)
{
Debug.LogWarning("[FlexionPaymentVerifier] Editor placeholder: auto success");
await Task.Yield();
return new PaymentVerifyResult { success = true, msg = "editor_placeholder" };
}
#else
public async Task<PaymentVerifyResult> VerifyAsync(PaymentInfo info)
{
var cts = new CancellationTokenSource(Timeout);
try
{
Debug.Log($"[FlexionPaymentVerifier] VerifyAsync start: url={_verifyUrl}");
Debug.Log($"[FlexionPaymentVerifier] Verify fields: orderId={info.orderId} productId={info.productId}" +
$" hasPurchaseJson={!string.IsNullOrEmpty(info.purchaseJson)} hasSignature={!string.IsNullOrEmpty(info.signature)}" +
$" purchaseToken={info.purchaseToken}");
var body = JsonConvert.SerializeObject(info);
Debug.Log("[FlexionPaymentVerifier] Request body: " + body);
using var req = new UnityWebRequest(_verifyUrl, "POST");
req.certificateHandler = new BypassCertificateHandler();
req.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(body));
req.downloadHandler = new DownloadHandlerBuffer();
req.SetRequestHeader("Content-Type", "application/json");
var tcs = new TaskCompletionSource<PaymentVerifyResult>(TaskCreationOptions.RunContinuationsAsynchronously);
cts.Token.Register(() => tcs.TrySetResult(new PaymentVerifyResult { success = false, msg = "timeout" }));
req.SendWebRequest().completed += _ =>
{
if (req.result == UnityWebRequest.Result.Success)
{
var respText = req.downloadHandler.text;
Debug.Log("[FlexionPaymentVerifier] Response: " + respText);
var orderResult = JsonConvert.DeserializeObject<FlexionOrderResult>(respText);
if (orderResult == null)
{
tcs.TrySetResult(new PaymentVerifyResult { success = false, msg = "parse_error" });
}
else if (orderResult.code == 0)
{
tcs.TrySetResult(new PaymentVerifyResult
{ success = true, msg = orderResult.info, orderId = orderResult.orderId });
}
else if (orderResult.code == 1)
{
tcs.TrySetResult(new PaymentVerifyResult
{ success = true, msg = orderResult.info, orderId = orderResult.orderId });
}
else if (orderResult.code == 2)
{
tcs.TrySetResult(new PaymentVerifyResult
{ success = true, msg = orderResult.info, orderId = orderResult.orderId });
}
else
{
// -1: 公钥/签名/玩家验证失败, -2: 写入失败, -3: 数据解析错误
tcs.TrySetResult(new PaymentVerifyResult
{ success = false, msg = orderResult.info ?? $"code={orderResult.code}" });
}
}
else
{
Debug.LogWarning("[FlexionPaymentVerifier] Failed: " + req.error);
tcs.TrySetResult(new PaymentVerifyResult { success = false, msg = req.error });
}
};
return await tcs.Task;
}
catch (Exception e)
{
Debug.LogError("[FlexionPaymentVerifier] Exception: " + e.Message);
return new PaymentVerifyResult { success = false, msg = e.Message };
}
finally
{
cts.Dispose();
}
}
#endif
}
public class FlexionPurchaseConsumer : IPurchaseConsumer
{
#if UNITY_EDITOR
public async Task<PurchaseConsumeResult> ConsumeAsync(string token)
{
await Task.Yield();
return new PurchaseConsumeResult { success = true, msg = "editor_placeholder" };
}
#elif UNITY_ANDROID
public async Task<PurchaseConsumeResult> ConsumeAsync(string token)
{
if (string.IsNullOrEmpty(token))
return new PurchaseConsumeResult { success = false, msg = "empty_token" };
UnityBridgeFunc.ConsumePurchase(token);
await Task.Yield();
return new PurchaseConsumeResult { success = true, msg = "consume_requested" };
}
#else
public async Task<PurchaseConsumeResult> ConsumeAsync(string token)
{
await Task.Yield();
return new PurchaseConsumeResult { success = false, msg = "unsupported_platform" };
}
#endif
}
public class FakePaymentVerifier : IPaymentVerifier
{
public async Task<PaymentVerifyResult> VerifyAsync(PaymentInfo info)
{
Debug.Log("[FakePaymentVerifier] Verifying purchase: " + info.orderId);
await Task.Delay(500);
return new PaymentVerifyResult { success = true, msg = "fake_ok" };
}
}
public class FakePurchaseConsumer : IPurchaseConsumer
{
public async Task<PurchaseConsumeResult> ConsumeAsync(string token)
{
Debug.Log("[FakePurchaseConsumer] Consume: " + token);
await Task.Yield();
return new PurchaseConsumeResult { success = true, msg = "fake_ok" };
}
}
internal class BypassCertificateHandler : CertificateHandler
{
protected override bool ValidateCertificate(byte[] certificateData) => true;
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 1b7f5b1ccc26bf047b00f9b79d7fa3da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,53 +0,0 @@
using System.Collections.Generic;
namespace tysdk
{
// TYSdkFacade 的登录/链接/ATT 等方法要依赖这些 POCO。
public enum EAccoutType
{
hwGoogle,
hwFacebook,
hwGuest,
hwVkid,
Apple,
none
}
public class LoginInfo
{
public bool isSuccess;
public int userId;
public string StrUserId => userId.ToString();
public string msg;
public int code;
}
public class LinkResult
{
// 0: success, 1: fail, -1 exists
public int code;
// when success and fail userId is current user
// when exists userId is 0
public int userId;
// not none when exists
public Dictionary<string, string> bindInfo;
}
public class ChangeLinkResult
{
public int code;
public int userId;
public string msg;
}
public class LinkCheckInfo
{
public int code;
}
public class ATTInfo
{
public bool isAccepted;
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2d36f2094aa5783423ab1ef40a88ccbe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -34,20 +34,13 @@ namespace tysdk
}
}
private static Dictionary<string, EAccoutType> accoutTypeMap = new Dictionary<string, EAccoutType>()
{
private static Dictionary<string, EAccoutType> accoutTypeMap = new Dictionary<string, EAccoutType>(){
{"google", EAccoutType.hwGoogle},
{"fb", EAccoutType.hwFacebook},
{"tyGuest", EAccoutType.hwGuest},
{"ios13", EAccoutType.Apple},
{"vk.global.app", EAccoutType.hwVkid},
{"ios13", EAccoutType.Apple}
};
public static void AddAccoutType(string key, EAccoutType value)
{
accoutTypeMap[key] = value;
}
private static EAccoutType ConvertAccoutType(string accountType)
{
if (accoutTypeMap.ContainsKey(accountType))
@@ -108,10 +101,12 @@ namespace tysdk
}
}
// ================== Singleton ==================
private static TYSdkFacade _instance;
private static AccountInfo _accountInfo;
public static AccountInfo TYAccountInfo => _accountInfo;
protected static AccountInfo _accountInfo;
private static TYSdkFacade _instance;
public static bool IsSdkInited { get; private set; }
public static event System.Action<bool, string> OnInitComplete;
public static TYSdkFacade Instance
{
@@ -125,47 +120,55 @@ namespace tysdk
return _instance;
}
}
public static string Channel => ChannelConfig.Channel;
private int LoginTimeoutSeconds => ChannelConfig.LoginTimeoutSeconds;
public static bool IsSdkInited { get; private set; }
public static event System.Action<bool, string> OnInitComplete;
// ================== Init ==================
public void Init()
{
Debug.Log($"[TYSdkFacade] Init()");
#if UNITY_ANDROID
UnityBridgeFunc.InitSDK();
UnityBridgeFunc.InitSDK(ChannelConfig.Channel);
#endif
}
public void SetChannelFromNative(string channel)
{
Debug.Log($"[TYSdkFacade] SetChannelFromNative: {channel}");
ChannelConfig.SetChannel(channel);
}
public void InitResult(string json)
{
var data = Newtonsoft.Json.Linq.JObject.Parse(json);
var code = (int)data["code"];
var msg = (string)data["msg"];
IsSdkInited = code == 0;
UnityEngine.Debug.Log($"[TYSdkFacade] InitResult: code={code} msg={msg}");
OnInitComplete?.Invoke(IsSdkInited, msg);
Debug.Log($"[TYSdkFacade] InitResult: {json}");
var success = false;
var msg = string.Empty;
try
{
var data = JObject.Parse(json);
success = (int)data["code"] == 0;
msg = (string)data["msg"];
}
catch (Exception e)
{
msg = e.Message;
Debug.LogWarning($"[TYSdkFacade] InitResult parse failed: {e}");
}
IsSdkInited = success;
OnInitComplete?.Invoke(success, msg);
}
// Called from Java SDKManager.InitSDK to sync channel
public void SetChannelFromNative(string ch)
{
ChannelConfig.SetChannel(ch);
UnityEngine.Debug.Log($"[CHANNEL-VERIFY] C# SetChannelFromNative → channel={ch}, payType={ChannelConfig.PayType}, loginTimeout={ChannelConfig.LoginTimeoutSeconds}");
}
/*================================================
_ _
/ \ ___ ___ ___ _ _ _ __ | |_
/ _ \ / __/ __/ _ \| | | | '_ \| __|
/ ___ \ (_| (_| (_) | |_| | | | | |_
/_/ \_\___\___\___/ \__,_|_| |_|\__|
=================================================*/
public static bool IsLoggedIn => _accountInfo != null;
public void Logout()
@@ -182,7 +185,7 @@ namespace tysdk
public async Task<LoginInfo> Login(EAccoutType accoutType)
{
#if UNITY_EDITOR
#if UNITY_EDITOR
await Task.Yield();
var deviceId = UnityEngine.Device.SystemInfo.deviceUniqueIdentifier.Split('-')[0].Substring(0, 8);
@@ -200,25 +203,25 @@ namespace tysdk
};
#elif UNITY_ANDROID || UNITY_IOS
var task = TYSDKCallbackManager.Instance.RegisterCallback<LoginInfo>(TimeSpan.FromSeconds(LoginTimeoutSeconds));
var task = TYSDKCallbackManager.Instance.RegisterCallback<LoginInfo>(TimeSpan.FromSeconds(30));
UnityBridgeFunc.UnityLogin(accoutType);
try
{
var loginInfo = await task;
if (loginInfo.isSuccess)
{
_accountInfo.channel = accoutType;
_accountInfo.AddLinkedAccount(accoutType);
_accountInfo.Save();
}
return loginInfo;
var loginInfo = await task;
if(loginInfo.isSuccess)
{
_accountInfo.channel = accoutType;
_accountInfo.AddLinkedAccount(accoutType);
_accountInfo.Save();
}
return loginInfo;
}
catch (Exception e)
catch(Exception e)
{
Debug.LogWarning($"[TYSdkFacade] Login failed: {e}");
return new LoginInfo() { isSuccess = false };
Debug.LogWarning($"[TYSdkFacade] Login failed: {e}");
return new LoginInfo(){isSuccess = false};
}
#endif
}
@@ -247,7 +250,7 @@ namespace tysdk
return new LoginInfo() { isSuccess = false };
}
}
public async Task<LoginInfo> LoginBySns()
{
Debug.Log("[TYSdkFacade] LoginBySns");
@@ -332,17 +335,18 @@ namespace tysdk
UnityBridgeFunc.SetGaUserInfo(strUserId);
}
#if UNITY_EDITOR
public async Task<LinkResult> LinkAccount(EAccoutType accoutType)
{
await Task.Delay(300);
return new LinkResult() { code = 1 };
return new LinkResult(){code = 1};
}
#elif UNITY_IOS || UNITY_ANDROID
public async Task<LinkResult> LinkAccount(EAccoutType accoutType)
public async Task<LinkResult> LinkAccount(EAccoutType accoutType)
{
if (_accountInfo == null) return new LinkResult() { code = 1 };
if (_accountInfo.linkedAccout.Contains(accoutType)) return new LinkResult() { code = 0 };
if (_accountInfo == null) return new LinkResult(){ code = 1};
if (_accountInfo.linkedAccout.Contains(accoutType)) return new LinkResult(){ code = 0};
var task = TYSDKCallbackManager.Instance.RegisterCallback<LinkResult>(TimeSpan.FromMinutes(1));
UnityBridgeFunc.LinkAccount(accoutType);
@@ -364,7 +368,6 @@ namespace tysdk
return new LinkResult() { code = 1 };
}
}
#endif
public void LinkAccoutResult(string message)
{
@@ -387,18 +390,21 @@ namespace tysdk
}
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
}
#endif
public void CleanLinkTempSnSInfo()
{
UnityBridgeFunc.CleanLinkTmpSnsInfo();
}
#if UNITY_EDITOR
public async Task<ChangeLinkResult> ChangeLinkAccount(EAccoutType accoutType, int oldUserId, int newUserId)
{
#if UNITY_EDITOR
await Task.Delay(300);
return new ChangeLinkResult() { code = 1 };
#else
return new ChangeLinkResult(){code = 1};
}
#elif UNITY_IOS || UNITY_ANDROID
public async Task<ChangeLinkResult> ChangeLinkAccount(EAccoutType accoutType, int oldUserId, int newUserId)
{
var task = TYSDKCallbackManager.Instance.RegisterCallback<ChangeLinkResult>(TimeSpan.FromSeconds(30));
UnityBridgeFunc.ChangeLinkAccount(accoutType, oldUserId, newUserId);
try
@@ -420,8 +426,8 @@ namespace tysdk
{
CleanLinkTempSnSInfo();
}
#endif
}
#endif
public void ChangeLinkAccountResult(string message)
{
@@ -435,6 +441,14 @@ namespace tysdk
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
}
/// <summary>
/// 检查是否已经绑定
/// <returns>
/// 1 已经绑定
/// 0 未绑定
/// -1 失败
/// </returns>
/// </summary>
public async Task<bool> LinkCheck(EAccoutType accoutType)
{
if (_accountInfo == null) return false;
@@ -460,7 +474,7 @@ namespace tysdk
return result.code == 1;
}
catch (Exception e)
catch(Exception e)
{
Debug.LogWarning($"[TYSdkFacade] CheckLinkResult error: {e}");
return false;
@@ -482,6 +496,7 @@ namespace tysdk
IConfig config = GContext.container.Resolve<IConfig>();
var tyurl = config.Get<string>("AGG_SERVER", defaultTyurl);
string tycs = tyurl == defaultTyurl ?
"https://hwcsh.tygameworld.com/template/appCancel/note.html"
:
@@ -503,12 +518,23 @@ namespace tysdk
string uid = $"uid={_accountInfo.userId}";
list.Add(uid);
list.Add("roleid=0");
list.Add("gameid=20587");
list.Add("cloudid=128");
list.Add("gamename=FishingTravel");
list.Add("certification=0");
list.Add("ischannel=1");
string roleid = "roleid=0";
list.Add(roleid);
string gameid = "gameid=20587";
list.Add(gameid);
string cloudid = "cloudid=128";
list.Add(cloudid);
string gamename = "gamename=FishingTravel";
list.Add(gamename);
string certification = "certification=0";
list.Add(certification);
string ischannel = "ischannel=1";
list.Add(ischannel);
string tysdktoken = $"tysdktoken={_accountInfo.token}";
list.Add(tysdktoken);
@@ -518,6 +544,7 @@ namespace tysdk
string listStr = string.Join("&", list.ToArray());
string sign = listStr +
"csh-api-6dfa879490a249be9fbc92e97e4d898d-api-csh";
//对sign进行MD5加密
string signMd5 = CalculateMD5Hash(sign);
string url = $"{tycs}?{listStr}&sign={signMd5}&isAbroad=1&lan=en";
Debug.Log($"[TYSdkFacade:Signout] url \n{url}");
@@ -526,16 +553,25 @@ namespace tysdk
private string CalculateMD5Hash(string input)
{
// Create a new instance of the MD5CryptoServiceProvider object.
MD5 md5Hasher = MD5.Create();
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
}
}

View File

@@ -4,17 +4,17 @@ using UnityEngine;
namespace tysdk
{
public partial class TYSdkFacade
public partial class TYSdkFacade : MonoBehaviour
{
/*================================================
_ _____ _____
_ _____ _____
/ \|_ _|_ _|
/ _ \ | | | |
/ ___ \| | | |
/_/ \_\_| |_|
=================================================*/
/ _ \ | | | |
/ ___ \| | | |
/_/ \_\_| |_|
=================================================*/
public bool IsAttAccepted()
{
@@ -25,25 +25,25 @@ namespace tysdk
{
#if UNITY_EDITOR || UNITY_ANDROID
await Task.Yield();
return new ATTInfo() { isAccepted = true };
return new ATTInfo(){isAccepted = true};
#elif UNITY_IOS
var task = TYSDKCallbackManager.Instance.RegisterCallback<ATTInfo>();
var task = tysdk.TYSDKCallbackManager.Instance.RegisterCallback<ATTInfo>();
UnityBridgeFunc.RequestATT();
try
{
return await task;
try{
return await task;
}
catch (Exception e)
catch(Exception e)
{
Debug.LogWarning(e.Message);
return new ATTInfo() { isAccepted = false };
Debug.LogWarning(e.Message);
return new ATTInfo(){isAccepted = false};
}
#endif
}
public void RequestATTResult(string r)
{
TYSDKCallbackManager.Instance.TryTriggerCallback(new ATTInfo() { isAccepted = r == "1" });
TYSDKCallbackManager.Instance.TryTriggerCallback(new ATTInfo(){isAccepted = r == "1"});
}
}
}

View File

@@ -2,14 +2,14 @@ using UnityEngine;
namespace tysdk
{
public partial class TYSdkFacade
public partial class TYSdkFacade : MonoBehaviour
{
/*================================================
_____ _ _____ _
_____ _ _____ _
| ____|_ _____ _ __ | |_ |_ _| __ __ _ ___| | __
| _| \ \ / / _ \ '_ \| __| | || '__/ _` |/ __| |/ /
| |___ \ V / __/ | | | |_ | || | | (_| | (__| <
| |___ \ V / __/ | | | |_ | || | | (_| | (__| <
|_____| \_/ \___|_| |_|\__| |_||_| \__,_|\___|_|\_\
=================================================*/
@@ -21,18 +21,18 @@ namespace tysdk
#endif
}
}
public enum GATrackType
{
GA_TRACK = 1,
GA_CION = 2,
GA_PAY = 3,
GA_GAME = 4,
GA_LOGIN = 5,
GA_PUSH = 6,
GA_ADBOX = 7,
GA_PREFORMANCE = 8,
GA_SDK = 9,
GA_ABTest = 10,
GA_TRACK = 1, //默认类型
GA_CION = 2, //金流相关事件
GA_PAY = 3, //支付相关事件
GA_GAME = 4, //游戏行为
GA_LOGIN = 5, //登录注册相关事件
GA_PUSH = 6, //推送相关事件
GA_ADBOX = 7, //adbox相关事件
GA_PREFORMANCE = 8, //性能上报相关事件
GA_SDK = 9, //SDK相关事件
GA_ABTest = 10, //abtest相关事件
}
}

View File

@@ -8,30 +8,33 @@ using System.Text;
namespace tysdk
{
public partial class TYSdkFacade
public partial class TYSdkFacade : MonoBehaviour
{
/*================================================
____ _
| _ \ __ _ _ _ _ __ ___ ___ _ __ | |_
____ _
| _ \ __ _ _ _ _ __ ___ ___ _ __ | |_
| |_) / _` | | | | '_ ` _ \ / _ \ '_ \| __|
| __/ (_| | |_| | | | | | | __/ | | | |_
| __/ (_| | |_| | | | | | | __/ | | | |_
|_| \__,_|\__, |_| |_| |_|\___|_| |_|\__|
|___/
|___/
=================================================*/
private bool _payFirstNegativeHandled;
//public async Task<PaymentInfo> Pay(string prodId, string prodPrice, string prodName, int count, string pType, string price_amount_micros =null)
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)
if(purchaseInfo == null)
purchaseInfo = new JObject();
purchaseInfo["orderId"] = orderId;
string extraInfo = purchaseInfo.ToString(Newtonsoft.Json.Formatting.None);
//to base64
extraInfo = Convert.ToBase64String(Encoding.UTF8.GetBytes(extraInfo));
Debug.Log("[TYSdk] extraInfo: " + extraInfo);
var prodId = prod.ProdID;
@@ -59,7 +62,7 @@ namespace tysdk
var task = TYSDKCallbackManager.Instance.RegisterCallback<PaymentInfo>(TimeSpan.FromSeconds(90));
try
{
UnityBridgeFunc.UnityKnowNew(prodId, prodPrice, prodName, count.ToString(), orderId, extraInfo, pType);
UnityBridgeFunc.UnityKnowNew(prodId, prodPrice, prodName, count.ToString(), orderId, extraInfo,pType);
var result = await task;
result.count = count;
result.orderId = orderId;
@@ -103,6 +106,7 @@ namespace tysdk
#endif
}
//支付的回调
public void PayResult(string json)
{
Debug.Log("[TYSdkFacade] pay callback:" + json);
@@ -110,11 +114,25 @@ namespace tysdk
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();
var purchaseJson = jresult["purchaseJson"]?.ToString();
var signature = jresult["signature"]?.ToString();
var purchaseToken = jresult["purchaseToken"]?.ToString();
result.purchaseJson = purchaseJson;
result.signature = signature;
result.purchaseToken = purchaseToken;
if (!string.IsNullOrEmpty(purchaseJson) || !string.IsNullOrEmpty(purchaseToken))
{
result.Receipt = new PaymentReceipt
{
Provider = PaymentReceiptProvider.Flexion,
PurchaseJson = purchaseJson,
Signature = signature,
PurchaseToken = purchaseToken
};
}
result.storeOrderId = jresult["orderId"]?.ToString();
result.userId = _accountInfo?.strUserId;
if (result.code == "-1")
if(result.code == "-1")
{
if (!_payFirstNegativeHandled)
{
@@ -128,60 +146,15 @@ namespace tysdk
}
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);
}
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
}
// Get Pay list
public async Task<ProductListInfo> GetSKUList()
{
if (!IsLoggedIn) return new ProductListInfo() { code = -1, msg = "未登录" };
#if UNITY_EDITOR
#if UNITY_EDITOR
await Task.Yield();
var result = new ProductListInfo();
@@ -194,6 +167,25 @@ namespace tysdk
#endif
}
//通过商品ID列表获取商品详情Flexion 渠道使用)
public async Task<ProductListInfo> GetSKUListByIapIds(string productIds)
{
if (!IsLoggedIn) return new ProductListInfo() { code = -1, msg = "未登录" };
#if UNITY_EDITOR
await Task.Yield();
return new ProductListInfo();
#elif UNITY_ANDROID
var task = TYSDKCallbackManager.Instance.RegisterCallback<ProductListInfo>();
UnityBridgeFunc.GetSKUListByIapIds(productIds);
var result = await task;
return result;
#else
return new ProductListInfo() { code = -1, msg = "unsupported platform" };
#endif
}
//商品列表的回调
public void SKUListResult(string json)
{
Debug.Log("[TYSdkFacade] GetSKUList callback");
@@ -216,3 +208,7 @@ namespace tysdk
}
}
}

View File

@@ -1,14 +1,82 @@
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace tysdk
{
public enum EAccoutType
{
hwGoogle,
hwFacebook,
hwGuest,
hwVkid,
Apple,
none
}
public enum PaymentReceiptProvider
{
None,
Flexion
}
public class PaymentReceipt
{
public PaymentReceiptProvider Provider;
public string PurchaseJson;
public string Signature;
public string PurchaseToken;
public bool HasPayload => !string.IsNullOrEmpty(PurchaseJson);
public bool CanConsume => !string.IsNullOrEmpty(PurchaseToken);
}
public class PaymentReceiptVerification
{
public bool Verified;
public string ServerOrderId;
public int ProviderCode;
public string ProviderMessage;
}
public class LoginInfo
{
public bool isSuccess;
public int userId;
public string StrUserId => userId.ToString();
public string msg;
public int code;
}
public class LinkResult
{
// 0: success, 1: fail, -1 exists
public int code;
// when success and fail userId is current user
// when exists userId is 0
public int userId;
// not none when exists
public Dictionary<string, string> bindInfo;
}
public class ChangeLinkResult
{
public int code;
public int userId;
public string msg;
}
public class LinkCheckInfo
{
public int code;
}
public class PaymentInfo
{
public bool isSuccessFromSdk => code == "0";
public bool isSuccess => isSuccessFromSdk && confirmed;
private bool confirmed { get; set; } = false;
private bool confirmed {get; set;} = false;
public int count;
public string orderId;
public string productId;
@@ -17,6 +85,8 @@ namespace tysdk
public string code;
public string msg;
// Compatibility fields for legacy server payload and existing call sites.
// New payment flow should read receipt data from Receipt.
// Flexion: purchase.getOriginalJson(), used by server for RSA signature verification
public string purchaseJson;
// Flexion: purchase.getSignature(), used by server for RSA signature verification
@@ -24,6 +94,21 @@ namespace tysdk
// Flexion: purchase token, used to consume after server verification
public string purchaseToken;
[JsonIgnore]
public PaymentReceipt Receipt;
[JsonIgnore]
public PaymentReceiptVerification ReceiptVerification;
[JsonIgnore]
public bool HasReceipt => Receipt != null && Receipt.HasPayload;
[JsonIgnore]
public bool CanConsumeReceipt => Receipt != null && Receipt.CanConsume;
// Store order ID from Flexion SDK (e.g. GPA.xxx)
public string storeOrderId;
public bool verified;
// Server-side order ID returned from verification
@@ -36,17 +121,17 @@ namespace tysdk
{
confirmed = orderId == this.orderId && productId == this.productId;
if (!confirmed)
if(!confirmed)
UnityEngine.Debug.LogWarning("[TYSdk Pay] order not confirmed");
return confirmed;
}
public override string ToString()
{
return JsonConvert.SerializeObject(this);
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
}
}
public class ProductListInfo
{
public int code = 1;
@@ -70,6 +155,7 @@ namespace tysdk
products = prodList;
}
#endif
}
#if UNITY_IOS
@@ -90,7 +176,7 @@ namespace tysdk
public override string ToString()
{
return JsonConvert.SerializeObject(this);
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
}
}
#else
@@ -98,24 +184,37 @@ namespace tysdk
{
public string description;
public string ourProductId;
public string productId;
public string price;
public string price_amount_micros;
public string price_currency_code;
public string productId;
public string title;
public string type;
public string currency;
public string price_amount;
public override string ToString()
{
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
}
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
public class ATTInfo
{
public bool isAccepted;
}
public class FlexionOrderResult
{
public int code { get; set; }
public string info { get; set; }
public string orderId { get; set; }
}
}

View File

@@ -4,87 +4,96 @@ using UnityEngine;
namespace tysdk
{
public static class UnityBridgeFunc
{
#if UNITY_EDITOR
public static void InitSDK() { }
#if UNITY_EDITOR
//初始化sdk
public static void InitSDK(string channel){}
public static void UnityResetServerUrl(string url) { }
//更新登录支付域名
public static void UnityResetServerUrl(string url){}
public static void UnityLoginByTokenFun(string token) { }
//登录
public static void UnityLoginByTokenFun(string token){}
public static string UnityLoginBySnsInfoFun() => null;
public static void UnityLogin(EAccoutType accoutType) { }
public static void UnityLogin(EAccoutType accoutType){}
public static void CleanLinkTmpSnsInfo() { }
public static void LinkAccount(EAccoutType accoutType) { }
public static void ChangeLinkAccount(EAccoutType accoutType, int oldUserId, int newUserId) { }
public static void LinkCheck(EAccoutType accoutType) { }
public static void UnityGetIdentityFun(string type) { }
public static void LinkAccount(EAccoutType accoutType){}
public static void ChangeLinkAccount(EAccoutType accoutType, int oldUserId, int newUserId){}
public static void LinkCheck(EAccoutType accoutType){}
public static void UnityLogOutByChannel(EAccoutType accoutType) { }
public static void UnityGetIdentityFun(string type){}
public static void UnityLogOutByChannel(EAccoutType accoutType){}
//支付new
public static void UnityKnowNew(string productId, string productPrice, string productName,
string productCount, string prodorderId, string appInfo, string pType) { }
//支付
public static void UnityKnow(String productId, String productName, String productCount,
String prodorderId, String appInfo) { }
String prodorderId, String appInfo) {}
//获取商品列表
public static void GetSKUList() { }
public static void SetGaUserInfo(string userId) { }
public static void SetGaCommonInfo(string SetGaCommonInfo) { }
public static void GAReportParams(int type, string eventstr, string paramstr) { }
public static void RequestATT() { }
public static int GetATT() { return 1; }
public static void Review() { }
public static void ConsumePurchase(string token) { }
public static string GetPendingPurchases() => "[]";
//打点
public static void SetGaUserInfo(string userId){}
public static void SetGaCommonInfo(string SetGaCommonInfo){}
public static void GAReportParams(int type, string eventstr, string paramstr){}
//ATT
public static void RequestATT(){}
public static int GetATT() {return 1;}
public static void Review() { }
public static void FBShareLink(string title, string content, string url) { }
public static void MessengerShareLink(string title, string content, string url) { }
#elif UNITY_ANDROID
private static string SDK_CLASS = "com.unity3d.player.SDKManager";
private static string EAccountTypeToStr(EAccoutType accoutType)
{
return accoutType == EAccoutType.hwVkid ? "vk.global.app" : accoutType.ToString();
}
public static void InitSDK()
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
//初始化sdk
public static void InitSDK(string channel){
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
using (var activityCls = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
using(var activityCls = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
var activity = activityCls.GetStatic<AndroidJavaObject>("currentActivity");
UnityEngine.Debug.Log("[CHANNEL-VERIFY] C# InitSDK → ChannelConfig.Channel=" + ChannelConfig.Channel);
sdkManager.CallStatic("InitSDK", activity, ChannelConfig.Channel);
sdkManager.CallStatic("InitSDK", activity, channel);
}
}
}
//更新登录支付域名
public static void UnityResetServerUrl(string url)
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("UnityResetServerUrl", url);
}
}
//登录
public static void UnityLoginByTokenFun(string token)
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("UnityLoginByTokenFun", token);
}
@@ -92,7 +101,7 @@ namespace tysdk
public static String UnityLoginBySnsInfoFun()
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
return sdkManager.CallStatic<string>("UnityLoginBySnsInfo");
}
@@ -100,16 +109,15 @@ namespace tysdk
public static void UnityLogin(EAccoutType accoutType)
{
var accountInfo = EAccountTypeToStr(accoutType);
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("UnityLogin", accountInfo);
sdkManager.CallStatic("UnityLogin", accoutType.ToString());
}
}
public static void UnityGetIdentityFun(string type)
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("UnityGetIdentityFun", type);
}
@@ -117,87 +125,118 @@ namespace tysdk
public static void UnityLogOutByChannel(EAccoutType accoutType)
{
var accountInfo = EAccountTypeToStr(accoutType);
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("UnityLogOutByChannel", accountInfo);
sdkManager.CallStatic("UnityLogOutByChannel", accoutType.ToString());
}
}
public static void LinkAccount(EAccoutType accoutType)
{
string userId = TYSdkFacade.TYAccountInfo.strUserId;
var accountInfo = EAccountTypeToStr(accoutType);
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("LinkAccount", accountInfo, userId);
string userId = TYSdkFacade.TYAccountInfo.strUserId;
sdkManager.CallStatic("LinkAccount", accoutType.ToString(), userId);
}
}
public static void CleanLinkTmpSnsInfo()
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
public static void CleanLinkTmpSnsInfo(){
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("CleanLinkTmpSnsInfo");
using(var activityCls = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
sdkManager.CallStatic("CleanLinkTmpSnsInfo");
}
}
}
public static void ChangeLinkAccount(EAccoutType accoutType, int oldUserId, int newUserId)
{
var accountInfo = EAccountTypeToStr(accoutType);
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("ChangeLinkAccount", accountInfo, oldUserId, newUserId);
sdkManager.CallStatic("ChangeLinkAccount", accoutType.ToString(), oldUserId, newUserId);
}
}
public static void LinkCheck(EAccoutType accoutType)
{
var accountInfo = EAccountTypeToStr(accoutType);
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("LinkCheck", accountInfo);
sdkManager.CallStatic("LinkCheck", accoutType.ToString());
}
}
//支付new
public static void UnityKnowNew(string productId, string productPrice, string productName,
string productCount, string prodorderId, string appInfo, string pType)
string productCount, string prodorderId, string appInfo,string pType)
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("UnityKnowNew", productId, productPrice, productName,
productCount, prodorderId, appInfo, pType);
productCount, prodorderId, appInfo,pType);
}
}
public static void ConsumePurchase(string token)
//支付
public static void UnityKnow(String productId, String productName, String productCount, String prodorderId, String appInfo)
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("ConsumePurchase", token);
}
}
public static void UnityKnow(String productId, String productName, String productCount, String prodorderId, String appInfo)
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("UnityKnow", productId, productName, productCount, prodorderId, appInfo);
sdkManager.CallStatic("UnityKnow", productId, productName, productCount, prodorderId, appInfo);
}
}
//获取商品列表
public static void GetSKUList()
{
UnityEngine.Debug.Log("UnityBridgeFunc.GetSKUList()");
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("thirdExtend");
}
}
//通过商品ID列表获取商品详情Flexion 渠道使用)
public static void GetSKUListByIapIds(string productIds)
{
UnityEngine.Debug.Log("UnityBridgeFunc.GetSKUListByIapIds(productIds)");
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("queryProductsByIDs", productIds);
}
}
public static void ConsumePurchase(string token)
{
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("ConsumePurchase", token);
}
}
public static string GetPendingPurchases()
{
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
return sdkManager.CallStatic<string>("GetPendingPurchases");
}
}
public static void CancelBillingFlow()
{
UnityEngine.Debug.Log("UnityBridgeFunc.CancelBillingFlow");
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("CancelBillingFlow");
}
}
//打点
public static void SetGaUserInfo(string userId)
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("SetGaUserInfo", userId);
}
@@ -205,7 +244,7 @@ namespace tysdk
public static void SetGaCommonInfo(string SetGaCommonInfo)
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("SetGaCommonInfo", SetGaCommonInfo);
}
@@ -213,35 +252,37 @@ namespace tysdk
public static void GAReportParams(int type, string eventstr, string paramstr)
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("GAReportParams", type, eventstr, paramstr);
}
}
public static void RequestATT() { }
public static int GetATT() { return 1; }
//ATT
public static void RequestATT(){}
public static int GetATT() {return 1;}
public static void Review()
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("Review");
}
}
public static void FBShareLink(string title, string content, string url)
public static void FBShareLink(string title, string content, string url)
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("FBShareLink", title, content, url);
}
}
public static void MessengerShareLink(string title, string content, string url)
public static void MessengerShareLink(string title, string content, string url)
{
using (var sdkManager = new AndroidJavaClass(SDK_CLASS))
using(var sdkManager = new AndroidJavaClass(SDK_CLASS))
{
sdkManager.CallStatic("MessengerShareLink", title, content, url);
}
@@ -249,9 +290,11 @@ namespace tysdk
#elif UNITY_IOS
//更新登录支付域名
[DllImport("__Internal")]
public static extern void UnityResetServerUrl(string url);
//登录
[DllImport("__Internal")]
public static extern void UnityLoginByTokenFun(string token);
@@ -267,6 +310,7 @@ namespace tysdk
return string.Empty;
}
// Convert C string to C# string
string result = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(ptr);
return result ?? string.Empty;
}
@@ -357,6 +401,7 @@ namespace tysdk
}
}
[DllImport("__Internal")] private static extern void LinkGoogle(int userId);
[DllImport("__Internal")] private static extern void LinkFacebook(int userId);
[DllImport("__Internal")] private static extern void LinkApple(int userId);
@@ -374,25 +419,31 @@ namespace tysdk
case EAccoutType.hwFacebook:
IsLinkedFacebook();
break;
case EAccoutType.Apple:
IsLinkedApple();
break;
}
}
[DllImport("__Internal")] public static extern void CleanLinkTmpSnsInfo();
[DllImport("__Internal")] private static extern void IsLinkedGoogle();
[DllImport("__Internal")] private static extern void IsLinkedFacebook();
[DllImport("__Internal")] private static extern void IsLinkedApple();
//支付
[DllImport("__Internal")]
public static extern void UnityKnow(string userId, string productId, string productPrice, string productName,
string productCount, string prodorderId, string appInfo);
//获取商品列表
[DllImport("__Internal")]
public static extern void GetSKUList();
//打点
[DllImport("__Internal")]
public static extern void SetGaUserInfo(string userId);
@@ -402,6 +453,7 @@ namespace tysdk
[DllImport("__Internal")]
public static extern void GAReportParams(int type, string eventstr, string paramstr);
//ATT
[DllImport("__Internal")]
public static extern void RequestATT();
@@ -414,6 +466,10 @@ namespace tysdk
[DllImport("__Internal")]
public static extern void MessengerShareLink(string title, string content, string url);
public static void ConsumePurchase(string token) { }
public static string GetPendingPurchases() => "[]";
#endif
}
}