### Installation Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayBusiness/README.md Instructions on how to install the SDK using NuGet package manager. ```APIDOC ## Installation ```shell # Via NuGet > Install-Package SKIT.FlurlHttpClient.Wechat.TenpayBusiness # Via dotnet-tools > dotnet add package SKIT.FlurlHttpClient.Wechat.TenpayBusiness ``` **Note:** When using the Visual Studio NuGet Package Manager GUI, ensure to check "Include prerelease" in the search results. ``` -------------------------------- ### Install SKIT.FlurlHttpClient.Wechat.TenpayV3 via dotnet-tools Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayV3/README.md Use this command to install the SDK using the dotnet-tools CLI. ```shell # 通过 dotnet-tools 安装 > dotnet add package SKIT.FlurlHttpClient.Wechat.TenpayV3 ``` -------------------------------- ### Install SKIT.FlurlHttpClient.Wechat.TenpayV3 via NuGet Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayV3/README.md Use this command to install the SDK via the NuGet Package Manager. ```shell # 通过 NuGet 安装 > Install-Package SKIT.FlurlHttpClient.Wechat.TenpayV3 ``` -------------------------------- ### Install SKIT.FlurlHttpClient.Wechat.TenpayBusiness via NuGet Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayBusiness/README.md Use this command to install the SDK package using the NuGet Package Manager. ```shell Install-Package SKIT.FlurlHttpClient.Wechat.TenpayBusiness ``` -------------------------------- ### Install SKIT.FlurlHttpClient.Wechat.OpenAI via NuGet Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatOpenAI/README.md Install the library using the NuGet Package Manager. Ensure 'Include prerelease' is checked if using a pre-release version. ```shell # Through NuGet installation > Install-Package SKIT.FlurlHttpClient.Wechat.OpenAI # Through dotnet-tools installation > dotnet add package SKIT.FlurlHttpClient.Wechat.OpenAI ``` -------------------------------- ### Initialization Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayBusiness/README.md Example of how to initialize the WechatTenpayBusinessClient with necessary options. ```APIDOC ## Initialization ```csharp using SKIT.FlurlHttpClient.Wechat.TenpayBusiness; var options = new WechatTenpayBusinessClientOptions() { PlatformId = "微企付平台账号", PlatformCertificateSerialNumber = "微企付平台 API 证书序列号", PlatformCertificatePrivateKey = "-----BEGIN PRIVATE KEY-----微企付平台 API 证书私钥-----END PRIVATE KEY-----", EnterpriseId = "微企付企业商户 ID(非必填)", EnterpriseCertificateSerialNumber = "微企付企业商户 API 证书序列号(非必填)", EnterpriseCertificatePrivateKey = "-----BEGIN PRIVATE KEY-----微企付企业商户 API 证书私钥(非必填)-----END PRIVATE KEY-----", TBEPCertificateSerialNumber = "微企付证书序列号", TBEPCertificatePublicKey = "-----BEGIN PUBLIC KEY-----微企付证书公钥-----END PUBLIC KEY-----" }; var client = WechatTenpayBusinessClientBuilder.Create(options).Build(); ``` ``` -------------------------------- ### Install SKIT.FlurlHttpClient.Wechat.Work via NuGet Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatWork/README.md Use this command to install the package using the NuGet Package Manager. ```shell # Through NuGet installation > Install-Package SKIT.FlurlHttpClient.Wechat.Work ``` -------------------------------- ### Request and Response Example Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayBusiness/README.md Demonstrates how to make a request to the 'Get Payment by Payment ID' API and handle the response. ```APIDOC ## Request & Response Example ```csharp using SKIT.FlurlHttpClient.Wechat.TenpayBusiness; using SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Models; /* Example: Querying payment result by transaction order ID */ var request = new GetPaymentByPaymentIdRequest() { OutPaymentId = "平台支付单号" }; var response = await client.ExecuteGetPaymentByOutPaymentIdAsync(request); if (response.IsSuccessful()) { Console.WriteLine("微企付支付单号:" + response.PaymentId); } else { Console.WriteLine("错误代码:" + response.Error.Code); Console.WriteLine("错误描述:" + response.Error.Description); } ``` ``` -------------------------------- ### Install SKIT.FlurlHttpClient.Wechat.TenpayBusiness via dotnet-tools Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayBusiness/README.md Use this command to add the SDK package to your project using the .NET CLI. ```shell dotnet add package SKIT.FlurlHttpClient.Wechat.TenpayBusiness ``` -------------------------------- ### Install SKIT.FlurlHttpClient.Wechat.Ads via NuGet Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatAds/README.md Use this command to install the library via the NuGet Package Manager Console. Ensure 'Include prerelease' is checked in the Visual Studio NuGet Package Manager UI if needed. ```shell Install-Package SKIT.FlurlHttpClient.Wechat.Ads ``` -------------------------------- ### Install SKIT.FlurlHttpClient.Wechat.Work via dotnet-tools Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatWork/README.md Use this command to add the package to your project using the .NET CLI. ```shell # Through dotnet-tools installation > dotnet add package SKIT.FlurlHttpClient.Wechat.Work ``` -------------------------------- ### Install SKIT.FlurlHttpClient.Wechat.Api via NuGet Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatApi/README.md Use this command to install the library via the NuGet Package Manager Console. ```shell > Install-Package SKIT.FlurlHttpClient.Wechat.Api ``` -------------------------------- ### Make a WeChat Work API Request (Get User Info) Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatWork/README.md Example of making a request to the Get User Info API. Ensure you have a valid AccessToken and UserId. The response handling demonstrates checking for success or error. ```csharp using SKIT.FlurlHttpClient.Wechat.Work; using SKIT.FlurlHttpClient.Wechat.Work.Models; /* 以获取用户信息接口为例 */ var request = new CgibinUserGetRequest() { AccessToken = "企业微信应用的 AccessToken", UserId = "企业成员账号" }; var response = await client.ExecuteCgibinUserGetAsync(request); if (response.IsSuccessful()) { Console.WriteLine("名称:" + response.Name); Console.WriteLine("头像:" + response.AvatarUrl); } else { Console.WriteLine("错误代码:" + response.ErrorCode); Console.WriteLine("错误描述:" + response.ErrorMessage); } ``` -------------------------------- ### Install SKIT.FlurlHttpClient.Wechat.Api via dotnet-tools Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatApi/README.md Use this command to add the library as a dependency using the .NET CLI. ```shell > dotnet add package SKIT.FlurlHttpClient.Wechat.Api ``` -------------------------------- ### Install SKIT.FlurlHttpClient.Wechat.Ads via dotnet-tools Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatAds/README.md Use this command to add the library as a dependency to your project using the .NET CLI. ```shell dotnet add package SKIT.FlurlHttpClient.Wechat.Ads ``` -------------------------------- ### Make an API Request and Handle Response Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatApi/README.md Example of calling the CgibinUserInfo API to retrieve user information. It demonstrates how to set request parameters, execute the request, and check the response for success or failure, logging relevant details. ```csharp using SKIT.FlurlHttpClient.Wechat.Api; using SKIT.FlurlHttpClient.Wechat.Api.Models; /* 以公众号获取用户信息接口为例 */ var request = new CgibinUserInfoRequest() { AccessToken = "微信 AccessToken", OpenId = "微信 OpenId" }; var response = await client.ExecuteCgibinUserInfoAsync(request); if (response.IsSuccessful()) { Console.WriteLine("昵称:" + response.Nickname); Console.WriteLine("头像:" + response.HeadImageUrl); } else { Console.WriteLine("错误代码:" + response.ErrorCode); Console.WriteLine("错误描述:" + response.ErrorMessage); } ``` -------------------------------- ### Make a Request to WeChat Ads API Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatAds/README.md Example of making a request to the WeChat Ads API, specifically the CampaignsAdd interface. This demonstrates how to set request parameters and execute the request using the initialized client. ```csharp using SKIT.FlurlHttpClient.Wechat.Ads; using SKIT.FlurlHttpClient.Wechat.Ads.Models; /* 以创建推广计划接口为例 */ var request = new CampaignsAddRequest() { AccessToken = "广告主的 AccessToken", CampaignType = "CAMPAIGN_TYPE_WECHAT_OFFICIAL_ACCOUNTS", ProductType = "PRODUCT_TYPE_LINK_WECHAT" }; var response = await client.ExecuteCampaignsAddAsync(request); ``` -------------------------------- ### Execute BotQueryV2Async for intelligent conversation Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatOpenAI/README.md Example of calling an intelligent conversation API. This method automatically generates signatures for v2 interfaces. Ensure you have the WeChat AccessToken. ```csharp using SKIT.FlurlHttpClient.Wechat.OpenAI; using SKIT.FlurlHttpClient.Wechat.OpenAI.Models; /* Example of calling the intelligent conversation interface */ var request = new Models.BotQueryV2Request() { QueryString = "What is my father's father?", UserId = "User ID", UserName = "User Nickname", AccessToken = "WeChat AccessToken" }; var response = await client.ExecuteBotQueryV2Async(request); if (response.IsSuccessful()) { Console.WriteLine("Matched Answer: " + response.Data.Answer); } else { Console.WriteLine("Return Code: " + response.Code); } ``` -------------------------------- ### Generate JSAPI Payment Parameters Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayV3/Basic_Parameters.md Example of creating a JSAPI payment transaction request and generating the necessary parameters for client-side invocation. The resulting parameter map can be directly returned to the client. ```csharp /* 以生成 JSAPI 调起支付所需参数为例 */ var request = new CreatePayTransactionJsapiRequest() { OutTradeNumber = "商户订单号", AppId = "公众号 AppId", Description = "描述", NotifyUrl = "回调地址", Amount = new CreatePayTransactionJsapiRequest.Types.Amount() { Total = 0 }, Payer = new CreatePayTransactionJsapiRequest.Types.Payer() { OpenId = "用户 OpenId" } }; var response = await client.ExecuteCreatePayTransactionJsapiAsync(request); /* 下面的参数字典可直接以 JSON 格式返回给客户端,客户端反序列化后再原样传递给 WeixinJSBridge.invoke('getBrandWCPayRequest') 方法即可 */ var paramMap = client.GenerateParametersForJsapiPayRequest(request.AppId, response.PrepayId); ``` -------------------------------- ### Execute JSAPI Unified Order Request Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayV3/README.md Example of creating and executing a JSAPI unified order request using the initialized client. Handles request and response processing, including error checking. ```csharp using SKIT.FlurlHttpClient.Wechat.TenpayV3; using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models; /* 以 JSAPI 统一下单接口为例 */ var request = new CreatePayTransactionJsapiRequest() { OutTradeNumber = "商户订单号", AppId = "微信 AppId", Description = "订单描述", ExpireTime = DateTimeOffset.Now.AddMinutes(15), NotifyUrl = "https://example.com", Amount = new CreatePayTransactionJsapiRequest.Types.Amount() { Total = 1 }, Payer = new CreatePayTransactionJsapiRequest.Types.Payer() { OpenId = "微信 OpenId" } }; var response = await client.ExecuteCreatePayTransactionJsapiAsync(request); if (response.IsSuccessful()) { Console.WriteLine("PrepayId:" + response.PrepayId); } else { Console.WriteLine("错误代码:" + response.ErrorCode); Console.WriteLine("错误描述:" + response.ErrorMessage); } ``` -------------------------------- ### Custom CertificateManager Implementation with Redis Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayV3/Basic_RequestSensitiveDataEncryption.md Implement a `CertificateManager` by inheriting from `ICertificateManager` and utilizing Redis HASH data structures for storing certificate information. This example demonstrates adding, retrieving, and removing certificate entries, along with managing their expiration. ```csharp using StackExchange.Redis; public class RedisCertificateManager : ICertificateManager { private const string REDIS_KEY_PREFIX = "wxpaypc-"; private readonly ConnectionMultiplexer Connection { get; } public RedisCertificateManager(string connectionString) { Connection = ConnectionMultiplexer.Connect(connectionString); } private string GenerateRedisKey(string serialNumber) { return $"{REDIS_KEY_PREFIX}{serialNumber}"; } private CertificateEntry ConvertHashEntriesToCertificateEntry(HashEntry[] values) { if (values == null) throw new ArgumentNullException(nameof(values)); IDictionary map = values.ToDictionary(k => k.Name.ToString(), v => v.Value.ToString()); return new CertificateEntry( algorithmType: map[nameof(CertificateEntry.AlgorithmType)], serialNumber: map[nameof(CertificateEntry.SerialNumber)], certificate: map[nameof(CertificateEntry.Certificate)], effectiveTime: DateTimeOffset.Parse(map[nameof(CertificateEntry.EffectiveTime)]), expireTime: DateTimeOffset.Parse(map[nameof(CertificateEntry.ExpireTime)]) ); } private HashEntry[] ConvertCertificateEntryToHashEntries(CertificateEntry entry) { return new HashEntry[] { new HashEntry(nameof(CertificateEntry.AlgorithmType), entry.AlgorithmType), new HashEntry(nameof(CertificateEntry.SerialNumber), entry.SerialNumber), new HashEntry(nameof(CertificateEntry.Certificate), entry.Certificate), new HashEntry(nameof(CertificateEntry.EffectiveTime), entry.EffectiveTime.ToString()), new HashEntry(nameof(CertificateEntry.ExpireTime), entry.ExpireTime.ToString()) }; } public IEnumerable AllEntries() { // 生产环境中不应该使用 Redis KEYS 命令,这里代码仅作参考 // 你可以使用 SCAN + CURSOR 来实现类似功能 RedisKey[] keys = Connection.GetServer().Keys($"{REDIS_KEY_PREFIX}*"); if (keys.Any()) { Task[] pipelineTasks = keys.Select(key => Connection.GetDatabase().HashGetAllAsync(key)).ToArray(); Connection.WaitAll(pipelineTasks); return pipelineTasks .Where(t => t.IsCompletedSuccessfully && t.Result.Any()) .Select(t => ConvertHashEntriesToCertificateEntry(t.Result)) .ToArray(); } return Array.Empty(); } public void AddEntry(CertificateEntry entry) { string key = GenerateRedisKey(serialNumber); HashEntry[] values = ConvertCertificateEntryToHashEntries(entry); Connection.GetDatabase().HashSet(key, values); Connection.GetDatabase().KeyExpire(key, entry.ExpireTime - DateTimeOffset.Now); } public CertificateEntry? GetEntry(string serialNumber) { string key = GenerateRedisKey(serialNumber); HashEntry[] values = Connection.GetDatabase().HashGetAll(key); if (values.Any()) { return ConvertHashEntriesToCertificateEntry(values); } return null; } public bool RemoveEntry(string serialNumber) { string key = GenerateRedisKey(serialNumber); return Connection.GetDatabase().KeyDelete(key); } } ``` -------------------------------- ### Accessing Raw Response Data in v2.x vs v3.x Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatApi/Migration_V3.md Illustrates the change in accessing raw response status code, headers, and body from properties in v2.x to methods in v3.x. Note that the Get methods return the same object reference and should not be modified after retrieval. ```csharp /* v2.x 读取单个响应原始状态码 */ int statusCode = response.RawStatus; /* v2.x 读取单个响应原始响应标头 */ IDictionary headers = response.RawHeaders; /* v2.x 读取单个响应原始响应体 */ byte[] bytes = response.RawBytes; /* v3.x 读取单个响应原始状态码 */ int statusCode = response.GetRawStatus(); /* v3.x 读取单个响应原始响应标头 */ HttpHeaderCollection headers = response.GetRawHeaders(); /* v3.x 读取单个响应原始响应体 */ byte[] bytes = response.GetRawBytes(); ``` -------------------------------- ### Instantiate WechatWorkClient with Options Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatWork/Migration_V3.md Demonstrates the traditional way of instantiating WechatWorkClient with options, which remains available in v3.x. ```csharp var options = new WechatWorkClientOptions() { /* 具体配置项略 */ }; var client = new WechatWorkClient(options); ``` -------------------------------- ### Get Media File Buffer Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatWork/Basic_FinanceSDK.md Manually retrieves a specific chunk (buffer) of a media file. This is useful for more granular control over the download process, allowing you to get parts of the file and manage the next buffer index. ```APIDOC ## Get Media File Buffer Manually retrieves a specific chunk (buffer) of a media file. This is useful for more granular control over the download process, allowing you to get parts of the file and manage the next buffer index. ### Request - **FileId** (string) - The ID of the media file. - **BufferIndex** (string) - The index of the buffer to retrieve. ### Response - **FileBufferBytes** (byte[]) - The byte array of the requested file buffer. - **NextBufferIndex** (string) - The index for the next buffer to request. - **IsFinished** (bool) - Indicates if this is the last buffer of the file. - **ReturnCode** (int) - The return code of the operation. ### Code Example ```csharp var request = new GetMediaFileBufferRequest() { FileId = "SDK_FILE_ID", BufferIndex = "INDEX_BUF" }; var response = await client.ExecuteGetMediaFileBufferAsync(request); if (response.IsSuccessful()) { Console.WriteLine("分片的字节数组:" + response.FileBufferBytes); Console.WriteLine("下一次的分片索引:" + response.NextBufferIndex); Console.WriteLine("是否已是最后一个分片:" + response.IsFinished); } else { Console.WriteLine("返回值:" + response.ReturnCode); } ``` ``` -------------------------------- ### Instantiating WechatApiClient with Options Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatApi/Migration_V3.md Demonstrates the traditional way of instantiating WechatApiClient with options, which remains available in v3.x. ```csharp var options = new WechatApiClientOptions() { /* 具体配置项略 */ }; var client = new WechatApiClient(options); ``` -------------------------------- ### Initialize WechatOpenAIClient for v2 APIs Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatOpenAI/README.md Initialize the client for the new openai.weixin.qq.com APIs. Requires AppId, Token, and EncodingAESKey. ```csharp using SKIT.FlurlHttpClient.Wechat; using SKIT.FlurlHttpClient.Wechat.OpenAI; /* Construct the client for the new openaiapi.weixin.qq.com related interfaces */ var options = new WechatOpenAIClientOptions() { AppId = "WeChat Intelligent Conversation AppId", Token = "WeChat Intelligent Conversation Token", EncodingAESKey = "WeChat Intelligent Conversation EncodingAESKey" }; var client = WechatOpenAIlientBuilder.Create(options).Build(); ``` -------------------------------- ### Get Media File Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatWork/Basic_FinanceSDK.md Downloads a media file associated with a chat record. The SDK handles the fragmentation and reassembly of the file, including automatic retries. ```APIDOC ## Get Media File Downloads a media file associated with a chat record. The SDK handles the fragmentation and reassembly of the file, including automatic retries. ### Request - **FileId** (string) - The ID of the media file to download. ### Response - **FileBytes** (byte[]) - The byte array representing the complete media file. - **ReturnCode** (int) - The return code of the operation. ### Code Example ```csharp var request = new GetMediaFileRequest() { FileId = "SDK_FILE_ID" }; var response = await client.ExecuteGetMediaFileAsync(request); if (response.IsSuccessful()) { Console.WriteLine("文件的字节数组:" + response.FileBytes); } else { Console.WriteLine("返回值:" + response.ReturnCode); } ``` ``` -------------------------------- ### Get Chat Records Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatWork/Basic_FinanceSDK.md Fetches chat records from Enterprise WeChat. This method allows retrieving messages with options for the last sequence and a limit on the number of records. ```APIDOC ## Get Chat Records Fetches chat records from Enterprise WeChat. This method allows retrieving messages with options for the last sequence and a limit on the number of records. ### Request - **LastSequence** (long) - The sequence ID of the last record to fetch from. - **Limit** (int) - The maximum number of records to retrieve. ### Response - **RecordList** (array) - A list of chat records. - **ReturnCode** (int) - The return code of the operation. - **ErrorCode** (int) - The error code if the operation failed. - **ErrorMessage** (string) - The error message if the operation failed. ### Code Example ```csharp var request = new GetChatRecordsRequest() { LastSequence = 0, Limit = 100 }; var response = await client.ExecuteGetChatRecordsAsync(request); if (response.IsSuccessful()) { Console.WriteLine("聊天记录:" + response.RecordList); } else { Console.WriteLine("返回值:" + response.ReturnCode); Console.WriteLine("错误代码:" + response.ErrorCode); Console.WriteLine("错误描述:" + response.ErrorMessage); } ``` ``` -------------------------------- ### Execute WechatTenpayBusiness API Request Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayBusiness/README.md Example of executing an API request, specifically querying payment results by payment ID. Handles successful responses and errors. ```csharp using SKIT.FlurlHttpClient.Wechat.TenpayBusiness; using SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Models; /* 以根据交易订单查询付款结果接口为例 */ var request = new GetPaymentByPaymentIdRequest() { OutPaymentId = "平台支付单号" }; var response = await client.ExecuteGetPaymentByOutPaymentIdAsync(request); if (response.IsSuccessful()) { Console.WriteLine("微企付支付单号:" + response.PaymentId); } else { Console.WriteLine("错误代码:" + response.Error.Code); Console.WriteLine("错误描述:" + response.Error.Description); } ``` -------------------------------- ### Initialize WechatTenpayBusinessClient Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayBusiness/README.md Configure and build the WechatTenpayBusinessClient with your platform and enterprise credentials. Ensure all required platform details are provided. ```csharp using SKIT.FlurlHttpClient.Wechat.TenpayBusiness; var options = new WechatTenpayBusinessClientOptions() { PlatformId = "微企付平台账号", PlatformCertificateSerialNumber = "微企付平台 API 证书序列号", PlatformCertificatePrivateKey = "-----BEGIN PRIVATE KEY-----微企付平台 API 证书私钥-----END PRIVATE KEY-----", EnterpriseId = "微企付企业商户 ID(非必填)", EnterpriseCertificateSerialNumber = "微企付企业商户 API 证书序列号(非必填)", EnterpriseCertificatePrivateKey = "-----BEGIN PRIVATE KEY-----微企付企业商户 API 证书私钥(非必填)-----END PRIVATE KEY-----", TBEPCertificateSerialNumber = "微企付证书序列号", TBEPCertificatePublicKey = "-----BEGIN PUBLIC KEY-----微企付证书公钥-----END PUBLIC KEY-----" }; var client = WechatTenpayBusinessClientBuilder.Create(options).Build(); ``` -------------------------------- ### Initialize WechatApiClient Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatApi/README.md Configure and build the WechatApiClient with your AppId, AppSecret, and other relevant service keys. Ensure all necessary credentials are provided for the services you intend to use. ```csharp using SKIT.FlurlHttpClient.Wechat; using SKIT.FlurlHttpClient.Wechat.Api; var options = new WechatApiClientOptions() { AppId = "微信 AppId", AppSecret = "微信 AppSecret", ImmeDeliveryAppKey = "即时配送相关服务 AppKey,不用则不填", ImmeDeliveryAppSecret = "即时配送相关服务 AppSecret,不用则不填", VirtualPaymentAppKey = "虚拟支付相关服务 AppKey,不用则不填", MidasOfferId = "米大师 1.0 相关服务 OfferId,不用则不填", MidasAppKey = "米大师 1.0 相关服务 AppKey,不用则不填", MidasOfferIdV2 = "米大师 2.0 相关服务 OfferId,不用则不填", MidasAppKeyV2 = "米大师 2.0 相关服务 AppKey,不用则不填" }; var client = WechatApiClientBuilder.Create(options).Build(); ``` -------------------------------- ### Build WechatWorkClient with Constructor Pattern Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatWork/Migration_V3.md Shows how to construct a WechatWorkClient using the new builder pattern with options, which offers more flexible client configuration. ```csharp var options = new WechatWorkClientOptions() { /* 具体配置项略 */ }; var client = WechatWorkClientBuilder.Create(options).Build(); ``` -------------------------------- ### Encrypting Sensitive Properties Manually Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayBusiness/Basic_RequestSensitiveDataEncryption.md Encrypt sensitive properties of a request object before sending it. This example demonstrates calling the EncryptRequestSensitiveProperty extension method and verifying the change. ```csharp var request = new CreateProductApplicationRequest() { BusinessLicense = new CreateProductApplicationRequest.Types.BusinessLicense() { BusinessRegisterType = "TYPE", MerchantName = "商户", LegalPersonName = "法人姓名明文" } }; Console.WriteLine("before: {0}", request.BusinessLicense.Name); // 此时仍是明文 client.EncryptRequestSensitiveProperty(request); Console.WriteLine("after: {0}", request.BusinessLicense.Name); // 此时已是密文 var response = await client.ExecuteCreateProductApplicationAsync(request); ``` -------------------------------- ### Verify Echo Event Signature Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatApi/Basic_EventSignatureVerification.md Verifies the signature for echo events sent by Wechat servers. This is typically used during the initial setup to confirm the token and other parameters. ```APIDOC ## VerifyEventSignatureForEcho ### Description Verifies the signature of an echo event from the Wechat server. ### Method `VerifyEventSignatureForEcho` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters for Verification - **webhookTimestamp** (string) - Required - The timestamp field from the Wechat callback notification. - **webhookNonce** (string) - Required - The nonce field from the Wechat callback notification. - **webhookSignature** (string) - Required - The signature field from the Wechat callback notification. ### Request Example ```csharp bool ret = client.VerifyEventSignatureForEcho( webhookTimestamp: "timestamp_value", webhookNonce: "nonce_value", webhookSignature: "signature_value" ); ``` ### Response - **ret** (bool) - Returns true if the signature is valid, false otherwise. ``` -------------------------------- ### Initialize WechatTenpayClient with Options Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayV3/README.md Configure and build the WechatTenpayClient using your merchant details and certificate paths. Supports certificate-based or public key-based authentication. ```csharp using SKIT.FlurlHttpClient.Wechat.TenpayV3; using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings; var options = new WechatTenpayClientOptions() { MerchantId = "微信商户号", MerchantV3Secret = "微信商户 v3 API 密钥", MerchantCertificateSerialNumber = "微信商户证书序列号", MerchantCertificatePrivateKey = System.IO.File.ReadAllText("/微信商户证书私钥文件路径/apiclient_key.pem"), // 基于平台证书的认证方式还需设置以下参数: PlatformAuthScheme = Settings.PlatformAuthScheme.Certificate, PlatformCertificateManager = new InMemoryCertificateManager() // 基于平台公钥的认证方式还需设置以下参数: PlatformAuthScheme = Settings.PlatformAuthScheme.PublicKey, PlatformPublicKeyManager = new InMemoryPublicKeyManager() }; var client = WechatTenpayClientBuilder.Create(options).Build(); ``` -------------------------------- ### Verify Event Signature with Error Details Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayBusiness/Basic_EventSignatureVerification.md This snippet shows how to get detailed error information during signature verification by specifying the return type as `ErroredResult`. This is useful for debugging. ```APIDOC ## VerifyEventSignature (ErroredResult) ### Description Verifies the signature of an incoming event notification and returns detailed error information if verification fails. This is useful for debugging. ### Method Signature ```csharp ErroredResult VerifyEventSignature( string authorization, string signature ); ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters for Verification - **authorization** (string) - Required - The value from the `TBEP-Authorization` header. - **signature** (string) - Required - The signature to verify. ### Request Example ```csharp ErroredResult res = client.VerifyEventSignature(authorization, signature); if (!res.Result) { Console.WriteLine(res.Error); } ``` ### Response - **Result** (bool) - Returns `true` if the signature is valid, `false` otherwise. - **Error** (string) - If `Result` is `false`, this field contains the error message and stack trace. ``` -------------------------------- ### Initialize WechatApiClient with Push Parameters Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatApi/Basic_EventSignatureVerification.md Before verifying signatures, initialize the WechatApiClient with necessary parameters like PushToken and PushEncodingAESKey. These are required for secure communication and signature validation. ```csharp /* 在初始化客户端时需指定服务器推送的相关参数 */ var options = new WechatApiClientOptions() { // 其他配置项略 PushToken = "Token", PushEncodingAESKey = "EncodingAESKey" }; var client = WechatApiClientBuilder.Create(options).Build(); ``` -------------------------------- ### Initialize WechatChatbotClient for original APIs Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatOpenAI/README.md Initialize the client for the original chatbot.weixin.qq.com APIs. Requires AppId, Token, and EncodingAESKey. ```csharp using SKIT.FlurlHttpClient.Wechat; using SKIT.FlurlHttpClient.Wechat.OpenAI; /* Construct the client for the original chatbot.weixin.qq.com related interfaces */ var options = new WechatChatbotClientOptions() { AppId = "WeChat Intelligent Conversation AppId", Token = "WeChat Intelligent Conversation Token", EncodingAESKey = "WeChat Intelligent Conversation EncodingAESKey" }; var client = WechatChatbotClientBuilder.Create(options).Build(); ``` -------------------------------- ### Account Hosting Mode (Merchant Onboarding) API Models Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayV3/Basic_ModelDefinition.md APIs for managing the account hosting mode for merchants, including submitting applications, querying status, revoking applications, and signing verification. ```APIDOC ## Account Hosting Mode (Merchant Onboarding) API Models ### Create Ecommerce Applyment For SubmitAccountHosting - **Description**: Submits an application for account hosting. - **Method**: POST (Assumed) - **Endpoint**: /v3/ecommerce/applyment/account-hosting ### Get Ecommerce Applyment By OutRequestNumber - **Description**: Queries an application status by its out-request number. - **Method**: GET (Assumed) - **Endpoint**: /v3/ecommerce/applyment/out-number/{out_request_number} ### Get Ecommerce Applyment By ApplymentId - **Description**: Queries an application status by its applyment ID. - **Method**: GET (Assumed) - **Endpoint**: /v3/ecommerce/applyment/{applyment_id} ### Revoke Ecommerce Applyment By OutRequestNumber - **Description**: Revokes an application by its out-request number. - **Method**: POST (Assumed) - **Endpoint**: /v3/ecommerce/applyment/out-number/{out_request_number}/revoke ### Revoke Ecommerce Applyment By ApplymentId - **Description**: Revokes an application by its applyment ID. - **Method**: POST (Assumed) - **Endpoint**: /v3/ecommerce/applyment/{applyment_id}/revoke ### Create Ecommerce Applyment For SubmitSignVerifyInfo - **Description**: Submits sign and verify information for platform agent signing. - **Method**: POST (Assumed) - **Endpoint**: /v3/ecommerce/applyment/sign-verify ``` -------------------------------- ### Enable Grayscale Compatibility for Platform Certificate and Public Key Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatTenpayV3/Basic_Certificate2PublicKey.md Configure the WechatTenpayClient to support both platform certificates and platform public keys during a grayscale transition. This involves setting fallback switch, authentication scheme, and providing both certificate and public key managers. This feature incurs a performance cost and should be disabled after the transition is complete. ```csharp var options = new WechatTenpayClientOptions() { // 其他配置项略 PlatformAuthFallbackSwitch = true, PlatformAuthScheme = Settings.PlatformAuthScheme.PublicKey, PlatformCertificateManager = , // 需要同时设置 `CertificateManager` 并存入至少一个平台证书 PlatformPublicKeyManager = , // 需要同时设置 `PublicKeyManager` 并存入至少一个平台公钥 }; var client = WechatTenpayClientBuilder.Create(options).Build(); ``` -------------------------------- ### Get Chat Records Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatWork/Basic_FinanceSDK.md Retrieves chat records from the Wechat Work service. Specify 'LastSequence' for pagination and 'Limit' for the number of records to fetch. Handles successful responses and errors by logging relevant information. ```csharp var request = new GetChatRecordsRequest() { LastSequence = 0, Limit = 100 }; var response = await client.ExecuteGetChatRecordsAsync(request); if (response.IsSuccessful()) { Console.WriteLine("聊天记录:" + response.RecordList); } else { Console.WriteLine("返回值:" + response.ReturnCode); Console.WriteLine("错误代码:" + response.ErrorCode); Console.WriteLine("错误描述:" + response.ErrorMessage); } ``` -------------------------------- ### Generate JS-SDK wx.config Parameters and Signature Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatWork/Basic_Parameters.md Use this snippet to generate the parameter map required for initializing the wx.config function in the JS-SDK. Ensure you have the correct AccessToken to fetch the Ticket. ```csharp /* 以生成 wx.config() 所需参数为例 */ var request = new CgibinGetJsapiTicketRequest() { AccessToken = "企业微信应用的 AccessToken" }; var response = await client.ExecuteCgibinGetJsapiTicketAsync(request); var paramMap = client.GenerateParametersForJssdkConfigRequest(response.Ticket, "https://example.com"); ``` -------------------------------- ### Generate JS-SDK Config Parameters with Signature Source: https://github.com/fudiwei/dotnetcore.skit.flurlhttpclient.wechat/blob/main/docs/WechatApi/Basic_Parameters.md Use this method to generate the parameter map required for wx.config(). Ensure JsapiTicket and AccessToken are managed with persistence and update mechanisms due to rate limits and expiration. ```csharp /* 以生成 wx.config() 所需参数为例 */ var request = new CgibinTicketGetTicketRequest() { AccessToken = "微信 AccessToken" }; var response = await client.ExecuteCgibinTicketGetTicketAsync(request); var paramMap = client.GenerateParametersForJSSDKConfig(response.Ticket, "https://example.com"); ```