274 lines
11 KiB
C#
274 lines
11 KiB
C#
#if UNITY_PURCHASE
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using Google.MiniJSON;
|
|
using Newtonsoft.Json;
|
|
using ThinkingData.Analytics;
|
|
using UnityEngine;
|
|
|
|
namespace WZ
|
|
{
|
|
public class ServerMgr : D_MonoSingleton<ServerMgr>
|
|
{
|
|
private const string XXTEA_KEY = "tkbff&(gBUjX#$s0710";
|
|
private const string secretKey = "tk~!@#$%^&*()_+0708";
|
|
|
|
public void CheckOrder(Dictionary<string, object> args, Action<int,string, SubscriptionInfo> callback)
|
|
{
|
|
Post(StaticValue.CheckOrderUrl, args,callback);
|
|
}
|
|
|
|
public void VerifyPurchase(Dictionary<string, object> args, Action<int, string, DataInfo> callback)
|
|
{
|
|
float fPrice;
|
|
if (!float.TryParse(args["price"].ToString(), out fPrice))
|
|
{
|
|
fPrice = 0.0f;
|
|
}
|
|
var ssProperties = new Dictionary<string, object>
|
|
{
|
|
{ "is_first", PlayerPrefsUtils.GetPlayerPrefsInt("First_Purchase", 0) == 0 },
|
|
{ "IAP", args["product_name"].ToString() },
|
|
{ "product_id", args["product_id"].ToString() },
|
|
{ "payment_type", "GooglePlay" },
|
|
{ "Price", fPrice }
|
|
};
|
|
try
|
|
{
|
|
if (TDAnalytics.GetSuperProperties().Count > 0)
|
|
{
|
|
ssProperties = ssProperties.Concat(TDAnalytics.GetSuperProperties()).ToDictionary(postParK => postParK.Key, PostParV => PostParV.Value);
|
|
}
|
|
|
|
if (TDAnalytics.GetPresetProperties().ToDictionary().Count > 0)
|
|
{
|
|
ssProperties = ssProperties.Concat(TDAnalytics.GetPresetProperties().ToDictionary()).ToDictionary(postParK => postParK.Key, PostParV => PostParV.Value);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
|
|
}
|
|
args.Add("ss_super_properties", JsonConvert.SerializeObject(ssProperties));
|
|
LoggerUtils.Debug("[iap] server verify purchase args: "+JsonConvert.SerializeObject(args));
|
|
LoggerUtils.Debug("[iap] server verify purchase url: "+ StaticValue.VerifyPurchaseUrl);
|
|
Post(StaticValue.VerifyPurchaseUrl, args, callback);
|
|
}
|
|
|
|
public void Post<T>(string url, Dictionary<string, object> args, Action<int, string, T> callback,
|
|
Dictionary<string, string> headers = null) where T : new()
|
|
{
|
|
args ??= new Dictionary<string, object>();
|
|
|
|
headers ??= new Dictionary<string, string>();
|
|
|
|
AddBaseParameters(args);
|
|
|
|
EncryptionParameters(args);
|
|
var requestBody = ConvertDictionaryToJson(args);
|
|
LoggerUtils.Debug("[iap] [server] url=> " + url +" requestBody=>"+requestBody);
|
|
var encryptBody = EncryptRequestBody(requestBody);
|
|
if (!string.IsNullOrEmpty(encryptBody))
|
|
{
|
|
headers["params"] = encryptBody;
|
|
headers["encrypt"] = true.ToString().ToLower();
|
|
requestBody = "";
|
|
}
|
|
headers.AddIfNotExists("Is-Dev", "0");
|
|
|
|
try
|
|
{
|
|
headers.AddIfNotExists("unity-platform", Application.platform.ToString());
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
// ignored
|
|
}
|
|
|
|
RequestHandler.Instance.SendPostRequest(url, requestBody, headers,
|
|
(code, res) =>
|
|
{
|
|
LoggerUtils.Debug($"[iap] [server] res ====> code : {code} res : {res}");
|
|
if (code == 0)
|
|
{
|
|
Response<T> resp = null;
|
|
var errorMsg = "";
|
|
|
|
try
|
|
{
|
|
res = DecryptResponseBody(res);
|
|
resp = JsonUtility.FromJson<Response<T>>(res);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
errorMsg = $"[iap] [server] Data conversion exception。{e.Message} {res}";
|
|
LoggerUtils.Debug(errorMsg);
|
|
}
|
|
|
|
LoggerUtils.Debug($"[iap] [server] resp ====> code : {resp.code} res : {resp.data}");
|
|
if (resp != null)
|
|
{
|
|
callback(resp.code, resp.msg, resp.data);
|
|
}
|
|
else
|
|
{
|
|
callback.Invoke(-1, errorMsg, new T());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
callback.Invoke(code, res, new T());
|
|
}
|
|
|
|
LoggerUtils.Debug("[iap] [server]" + "[res] " + res);
|
|
});
|
|
}
|
|
|
|
private static string EncryptRequestBody(string requestBody)
|
|
{
|
|
var encryptRequestBodyBytes = XXTEA.Encrypt(Encoding.UTF8.GetBytes(requestBody), Encoding.UTF8.GetBytes(XXTEA_KEY));
|
|
var encryptRequestBody = EncryptionUtils.BytesToHexString(encryptRequestBodyBytes, false);
|
|
LoggerUtils.Debug($"[iap] [server] [EncryptRequestBody] requestBody = {requestBody} encryptRequestBody = {encryptRequestBody}");
|
|
return encryptRequestBody;
|
|
}
|
|
|
|
private static string DecryptResponseBody(string responseBody)
|
|
{
|
|
var decryptResponseBodyBytes = XXTEA.Decrypt(EncryptionUtils.HexStringToBytes(responseBody), Encoding.UTF8.GetBytes(XXTEA_KEY));
|
|
var decryptResponseBody = Encoding.UTF8.GetString(decryptResponseBodyBytes);
|
|
LoggerUtils.Debug($"[iap] [[server]] [DecryptResponseBody] decryptResponseBody = {decryptResponseBody}");
|
|
return decryptResponseBody;
|
|
}
|
|
|
|
public static string GetMD5Hash(string input)
|
|
{
|
|
using (var md5 = MD5.Create())
|
|
{
|
|
var inputBytes = Encoding.ASCII.GetBytes(input);
|
|
var hashBytes = md5.ComputeHash(inputBytes);
|
|
|
|
var builder = new StringBuilder();
|
|
foreach (var t in hashBytes)
|
|
{
|
|
builder.Append(t.ToString("x2"));
|
|
}
|
|
|
|
return builder.ToString();
|
|
}
|
|
}
|
|
|
|
private static void EncryptionParameters(Dictionary<string, object> args)
|
|
{
|
|
var signString =
|
|
$"{secretKey}platform={args["platform"]}packagename={args["package_name"]}channel={args["channel"]}appversion={args["app_version"]}appversioncode={args["app_version_code"]}language={args["language"]}ip={args["ip"]}ts={args["ts"]}";
|
|
var sign = GetMD5Hash(signString);
|
|
args["sign"] = sign;
|
|
}
|
|
|
|
private static void AddBaseParameters(IDictionary<string, object> args)
|
|
{
|
|
|
|
args.AddIfNotExists("unity_sdk_version", RushSDKManager.GetSDKVersion());
|
|
|
|
args.AddIfNotExists("package_name", Application.identifier);
|
|
args.AddIfNotExists("platform", "android");
|
|
args.AddIfNotExists("platform_os", "android");
|
|
args.AddIfNotExists("channel", "googleplay");
|
|
args.AddIfNotExists("device_type", "Android");
|
|
args.AddIfNotExists("platform_channel", "gp");
|
|
args.AddIfNotExists("app_version", Application.version);
|
|
args.AddIfNotExists("app_version_code", DataUtils.AndroidVersionCode().ToString());
|
|
args.AddIfNotExists("language", "ZH");
|
|
args.AddIfNotExists("ip", "");
|
|
args.AddIfNotExists("device_id", AdjustManager.Instance.GetGdid());
|
|
args.AddIfNotExists("adjust_adid", AdjustManager.Instance.GetAdid());
|
|
args.AddIfNotExists("app_u8id", "");
|
|
args.AddIfNotExists("app_name", Application.productName);
|
|
args.AddIfNotExists("model", "");
|
|
args.AddIfNotExists("screen_size", "");
|
|
args.AddIfNotExists("network_type", "");
|
|
args.AddIfNotExists("ua", "");
|
|
args.AddIfNotExists("idfa", "");
|
|
args.AddIfNotExists("idfv", "");
|
|
args.AddIfNotExists("gaid", AdjustManager.Instance.GetGdid());
|
|
args.AddIfNotExists("oaid", "");
|
|
args.AddIfNotExists("android_id", "");
|
|
args.AddIfNotExists("adid", AdjustManager.Instance.GetAdid());
|
|
args.AddIfNotExists("fire_adid", "");
|
|
args.AddIfNotExists("ad_network", AdjustManager.Instance.GetAdjustNetwork());
|
|
args.AddIfNotExists("campaign", AdjustManager.Instance.GetAdjustCampaign());
|
|
args.AddIfNotExists("adgroup", AdjustManager.Instance.GetAdjustAdgroup());
|
|
args.AddIfNotExists("creative", AdjustManager.Instance.GetAdjustCreative());
|
|
args.AddIfNotExists("clickLabel", AdjustManager.Instance.GetAdjustClickLabel());
|
|
args.AddIfNotExists("referrer", "");
|
|
args.AddIfNotExists("memory", "");
|
|
args.AddIfNotExists("memory_usage", "");
|
|
args.AddIfNotExists("country", "");
|
|
args.AddIfNotExists("user_id", "");
|
|
args.AddIfNotExists("user_type", 0);
|
|
args.AddIfNotExists("ss_distinct_id", TDAnalytics.GetDistinctId() ?? "");
|
|
args.AddIfNotExists("ss_account_id", "");
|
|
args.AddIfNotExists("ts", "" + TimeUtils.CurrentTimestamp());
|
|
}
|
|
|
|
|
|
public static string ConvertDictionaryToJson(Dictionary<string, object> dictionary)
|
|
{
|
|
return Json.Serialize(dictionary);
|
|
}
|
|
|
|
[Serializable]
|
|
public class Response<T>
|
|
{
|
|
public int code = -1;
|
|
public string msg;
|
|
public T data;
|
|
public int ts;
|
|
}
|
|
|
|
[Serializable]
|
|
public class SensitiveDataInfo
|
|
{
|
|
public bool has_sensitive;
|
|
public string content;
|
|
}
|
|
|
|
[Serializable]
|
|
public class TranslateDataInfo
|
|
{
|
|
public string content;
|
|
}
|
|
|
|
[Serializable]
|
|
public class DataInfo
|
|
{
|
|
public string environment;
|
|
public int illegal_order = -1;
|
|
public string illegal_msg;
|
|
}
|
|
|
|
[Serializable]
|
|
public class SubscriptionInfo
|
|
{
|
|
public int illegal_order;
|
|
public string illegal_msg;
|
|
public string environment;
|
|
public string purchase_time;
|
|
public int is_subscribed;
|
|
public int is_expired;
|
|
public int is_cancelled;
|
|
public int is_free_trial;
|
|
public int is_auto_renewing;
|
|
public string remaining_time;
|
|
public string expiry_time;
|
|
public string latest_order_id;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#endif |