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