diff --git a/csharp/AlipayEasySDK/Factory/MultipleFactory.cs b/csharp/AlipayEasySDK/Factory/MultipleFactory.cs new file mode 100644 index 0000000..b294fbe --- /dev/null +++ b/csharp/AlipayEasySDK/Factory/MultipleFactory.cs @@ -0,0 +1,258 @@ +using System; +using Alipay.EasySDK.Kernel; +using System.Reflection; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace Alipay.EasySDK.Factory +{ + /// + /// 多账户客户端工厂,用于快速配置和访问各种场景下的API Client + /// + /// 注:该MultipleFactory获取的Client不可储存重复使用,请每次均通过MultipleFactory完成调用 + /// + public static class MultipleFactory + { + public const string SDK_VERSION = "alipay-easysdk-net-2.1.0"; + + /// + /// 将一些初始化耗时较多的信息缓存在上下文中 + /// + private static ConcurrentDictionary contexts; + + /// + /// 设置客户端参数,只需设置一次,即可反复使用各种场景下的API Client + /// + /// 客户端参数对象列表 + public static void SetOptions(Dictionary options) + { + if (contexts == null) + { + contexts = new ConcurrentDictionary(); + } + + foreach (var option in options) + { + if (contexts.ContainsKey(option.Key)) + { + contexts.TryRemove(option.Key, out _); + } + contexts.TryAdd(option.Key, new Context(option.Value, SDK_VERSION)); + } + } + + /// + /// 获取调用OpenAPI所需的客户端实例 + /// 本方法用于调用SDK扩展包中的API Client下的方法 + /// + /// 注:返回的实例不可重复使用,只可用于单次调用 + /// + /// 泛型参数 + /// API Client的类型对象 + /// client实例,用于发起单次调用 + public static T GetClient(string key) + { + Type type = typeof(T); + ConstructorInfo constructor = type.GetConstructor(new Type[] { typeof(Client) }); + contexts[key].SdkVersion = GetSdkVersion(type, key); + return (T)constructor.Invoke(new object[] { new Client(contexts[key]) }); + } + + private static string GetSdkVersion(Type client, string key) + { + return contexts[key].SdkVersion + "-" + client.FullName + .Replace("EasySDK.", "") + .Replace(".Client", "") + .Replace(".", "-"); + } + + /// + /// 基础能力相关 + /// + public static class Base + { + /// + /// 获取图片相关API Client + /// + /// 图片相关API Client + public static EasySDK.Base.Image.Client Image(string key) + { + return new EasySDK.Base.Image.Client(new Client(contexts[key])); + } + + /// + /// 获取视频相关API Client + /// + /// 视频相关API Client + public static EasySDK.Base.Video.Client Video(string key) + { + return new EasySDK.Base.Video.Client(new Client(contexts[key])); + } + + /// + /// 获取OAuth认证相关API Client + /// + /// OAuth认证相关API Client + public static EasySDK.Base.OAuth.Client OAuth(string key) + { + return new EasySDK.Base.OAuth.Client(new Client(contexts[key])); + } + + /// + /// 获取小程序二维码相关API Client + /// + /// 小程序二维码相关API Client + public static EasySDK.Base.Qrcode.Client Qrcode(string key) + { + return new EasySDK.Base.Qrcode.Client(new Client(contexts[key])); + } + } + + /// + /// 营销能力相关 + /// + public static class Marketing + { + /// + /// 获取生活号相关API Client + /// + /// 生活号相关API Client + public static EasySDK.Marketing.OpenLife.Client OpenLife(string key) + { + return new EasySDK.Marketing.OpenLife.Client(new Client(contexts[key])); + } + + /// + /// 获取支付宝卡包相关API Client + /// + /// 支付宝卡包相关API Client + public static EasySDK.Marketing.Pass.Client Pass(string key) + { + return new EasySDK.Marketing.Pass.Client(new Client(contexts[key])); + } + + /// + /// 获取小程序模板消息相关API Client + /// + /// 小程序模板消息相关API Client + public static EasySDK.Marketing.TemplateMessage.Client TemplateMessage(string key) + { + return new EasySDK.Marketing.TemplateMessage.Client(new Client(contexts[key])); + } + } + + /// + /// 会员能力相关 + /// + public static class Member + { + /// + /// 获取支付宝身份认证相关API Client + /// + /// 支付宝身份认证相关API Client + public static EasySDK.Member.Identification.Client Identification(string key) + { + return new EasySDK.Member.Identification.Client(new Client(contexts[key])); + } + } + + /// + /// 支付能力相关 + /// + public static class Payment + { + /// + /// 获取支付通用API Client + /// + /// 支付通用API Client + public static EasySDK.Payment.Common.Client Common(string key) + { + return new EasySDK.Payment.Common.Client(new Client(contexts[key])); + } + + /// + /// 获取当面付API Client + /// + /// 当面付API Client + public static EasySDK.Payment.FaceToFace.Client FaceToFace(string key) + { + return new EasySDK.Payment.FaceToFace.Client(new Client(contexts[key])); + } + + /// + /// 获取花呗API Client + /// + /// 花呗API Client + public static EasySDK.Payment.Huabei.Client Huabei(string key) + { + return new EasySDK.Payment.Huabei.Client(new Client(contexts[key])); + } + + /// + /// 获取手机APP支付API Client + /// + /// 手机APP支付API Client + public static EasySDK.Payment.App.Client App(string key) + { + return new EasySDK.Payment.App.Client(new Client(contexts[key])); + } + + /// + /// 获取电脑网站支付API Client + /// + /// 电脑网站支付API + public static EasySDK.Payment.Page.Client Page(string key) + { + return new EasySDK.Payment.Page.Client(new Client(contexts[key])); + } + + /// + /// 获取手机网站支付API Client + /// + /// 手机网站支付API + public static EasySDK.Payment.Wap.Client Wap(string key) + { + return new EasySDK.Payment.Wap.Client(new Client(contexts[key])); + } + } + + /// + /// 安全能力相关 + /// + public static class Security + { + /// + /// 获取文本风险识别相关API Client + /// + /// 文本风险识别相关API Client + public static EasySDK.Security.TextRisk.Client TextRisk(string key) + { + return new EasySDK.Security.TextRisk.Client(new Client(contexts[key])); + } + } + + /// + /// 辅助工具 + /// + public static class Util + { + /// + /// 获取OpenAPI通用接口,可通过自行拼装参数,调用几乎所有OpenAPI + /// + /// OpenAPI通用接口 + public static EasySDK.Util.Generic.Client Generic(string key) + { + return new EasySDK.Util.Generic.Client(new Client(contexts[key])); + } + + /// + /// 获取AES128加解密相关API Client,常用于会员手机号的解密 + /// + /// AES128加解密相关API Client + public static EasySDK.Util.AES.Client AES(string key) + { + return new EasySDK.Util.AES.Client(new Client(contexts[key])); + } + } + } +} \ No newline at end of file diff --git a/csharp/AlipayEasySDK/Util/Generic/Client.cs b/csharp/AlipayEasySDK/Util/Generic/Client.cs index 4bed55f..3e8f435 100644 --- a/csharp/AlipayEasySDK/Util/Generic/Client.cs +++ b/csharp/AlipayEasySDK/Util/Generic/Client.cs @@ -13,7 +13,7 @@ namespace Alipay.EasySDK.Util.Generic { - public class Client + public class Client { protected Alipay.EasySDK.Kernel.Client _kernel; @@ -40,7 +40,7 @@ public AlipayOpenApiGenericResponse Execute(string method, Dictionary 0) { @@ -67,6 +67,10 @@ public AlipayOpenApiGenericResponse Execute(string method, Dictionary(); + } request_.Protocol = this._kernel.GetConfig("protocol"); request_.Method = "POST"; request_.Pathname = "/gateway.do"; @@ -140,7 +144,7 @@ public async Task ExecuteAsync(string method, Dict Exception _lastException = null; long _now = System.DateTime.Now.Millisecond; int _retryTimes = 0; - while (TeaCore.AllowRetry((IDictionary) runtime_["retry"], _retryTimes, _now)) + while (TeaCore.AllowRetry((IDictionary)runtime_["retry"], _retryTimes, _now)) { if (_retryTimes > 0) { @@ -167,6 +171,10 @@ public async Task ExecuteAsync(string method, Dict {"app_cert_sn", this._kernel.GetMerchantCertSN()}, {"alipay_root_cert_sn", this._kernel.GetAlipayRootCertSN()}, }; + if (textParams == null) + { + textParams = new Dictionary(); + } request_.Protocol = this._kernel.GetConfig("protocol"); request_.Method = "POST"; request_.Pathname = "/gateway.do"; @@ -222,7 +230,7 @@ public async Task ExecuteAsync(string method, Dict throw new TeaUnretryableException(_lastRequest, _lastException); } - + /// /// ISV代商户代用,指定appAuthToken /// diff --git a/csharp/UnitTest/Util/Generic/ClientTest.cs b/csharp/UnitTest/Util/Generic/ClientTest.cs index 003ef76..ed9fcdd 100644 --- a/csharp/UnitTest/Util/Generic/ClientTest.cs +++ b/csharp/UnitTest/Util/Generic/ClientTest.cs @@ -34,8 +34,8 @@ public void TestExecuteWithoutAppAuthToken() public void TestExecuteWithAppAuthToken() { string outTradeNo = Guid.NewGuid().ToString(); - AlipayOpenApiGenericResponse response = Factory.Util.Generic().Execute( - "alipay.trade.create", GetTextParams(), GetBizParams(outTradeNo)); + AlipayOpenApiGenericResponse response = Factory.Util.Generic().Agent(GetAppAuthToken()).Execute( + "alipay.trade.create", null, GetBizParams(outTradeNo)); Assert.IsFalse(ResponseChecker.Success(response)); Assert.AreEqual(response.Code, "20001"); @@ -45,6 +45,11 @@ public void TestExecuteWithAppAuthToken() Assert.NotNull(response.HttpBody); } + private string GetAppAuthToken() + { + return "201712BB_D0804adb2e743078d1822d536956X34"; + } + private Dictionary GetTextParams() { return new Dictionary