diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5b5527bb..66042038 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -127,6 +127,7 @@ - _wxapi_:关于 `SKIT.FlurlHttpClient.Wechat.Api` 项目的变化; - _tenpayv2_:关于 `SKIT.FlurlHttpClient.Wechat.TenpayV2` 项目的变化; - _tenpayv3_:关于 `SKIT.FlurlHttpClient.Wechat.TenpayV3` 项目的变化; + - _tenpaybusiness_:关于 `SKIT.FlurlHttpClient.Wechat.TenpayBusiness` 项目的变化; - _work_:关于 `SKIT.FlurlHttpClient.Wechat.Work` 项目的变化; - _wxads_:关于 `SKIT.FlurlHttpClient.Wechat.Ads` 项目的变化; - _openai_:关于 `SKIT.FlurlHttpClient.Wechat.OpenAI` 项目的变化; diff --git a/README.md b/README.md index 9def00b9..f2f2c42f 100644 --- a/README.md +++ b/README.md @@ -37,14 +37,15 @@ ## 模块 -| 名称 | NuGet | 其他 | -| :----------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------: | -| 公众平台(公众号、小程序)
+ 开放平台模块 | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.Api.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Api)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.Api.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Api) | [开发文档](./docs/WechatApi/README.md)|[示例项目](./docs/WechatApi/Sample.md) | -| 商户平台(微信支付)模块
(针对 v3 版接口) | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.TenpayV3.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayV3)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.TenpayV3.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayV3) | [开发文档](./docs/WechatTenpayV3/README.md)|[示例项目](./docs/WechatTenpayV3/Sample.md) | -| 商户平台(微信支付)模块
(针对 v2 版接口) | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.TenpayV2.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayV2)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.TenpayV2.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayV2) | [开发文档](./docs/WechatTenpayV2/README.md) | -| 企业微信(企业号)模块 | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.Work.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Work)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.Work.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Work) | [开发文档](./docs/WechatWork/README.md) | -| 广告平台(广点通)模块 | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.Ads.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Ads)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.Ads.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Ads) | [开发文档](./docs/WechatAds/README.md) | -| 对话开放平台(微信智能对话)模块 | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.OpenAI.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.OpenAI)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.OpenAI.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.OpenAI) | [开发文档](./docs/WechatOpenAI/README.md) | +| 名称 | NuGet | 其他 | +| :------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------: | +| 公众平台(公众号、小程序)
+ 开放平台模块 | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.Api.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Api)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.Api.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Api) | [开发文档](./docs/WechatApi/README.md)|[示例项目](./docs/WechatApi/Sample.md) | +| 商户平台(微信支付)模块
(针对 v3 版接口) | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.TenpayV3.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayV3)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.TenpayV3.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayV3) | [开发文档](./docs/WechatTenpayV3/README.md)|[示例项目](./docs/WechatTenpayV3/Sample.md) | +| 商户平台(微信支付)模块
(针对 v2 版接口) | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.TenpayV2.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayV2)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.TenpayV2.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayV2) | [开发文档](./docs/WechatTenpayV2/README.md) | +| 商户平台(腾讯微企付)模块
(针对微企付接口) | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.TenpayBusiness.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayBusiness)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.TenpayBusiness.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayBusiness) | [开发文档](./docs/TenpayBusiness/README.md) | +| 企业微信(企业号)模块 | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.Work.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Work)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.Work.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Work) | [开发文档](./docs/WechatWork/README.md) | +| 广告平台(广点通)模块 | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.Ads.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Ads)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.Ads.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Ads) | [开发文档](./docs/WechatAds/README.md) | +| 对话开放平台(微信智能对话)模块 | [![NuGet Version](https://img.shields.io/nuget/v/SKIT.FlurlHttpClient.Wechat.OpenAI.svg?label=NuGet)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.OpenAI)
[![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.OpenAI.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.OpenAI) | [开发文档](./docs/WechatOpenAI/README.md) | --- diff --git a/docs/WechatTenpayBusiness/Advanced_EventSignatureVerification.md b/docs/WechatTenpayBusiness/Advanced_EventSignatureVerification.md new file mode 100644 index 00000000..343c7ef9 --- /dev/null +++ b/docs/WechatTenpayBusiness/Advanced_EventSignatureVerification.md @@ -0,0 +1,31 @@ +## 如何验证回调通知事件签名? + +--- + +### 验签流程 + +验证回调通知事件签名的方法与验证响应签名的类似,请参阅本文档[《高级技巧 - 如何验证响应签名?》](./Advanced_ResponseSignatureVerification.md)的有关章节。 + +同样地,你既可以利用本库提供的 `RSAUtility` 工具类自行进行签名验证,也可以通过封装好的扩展方法完成签名验证: + +```csharp +bool ret = client.VerifyEventSignature( + callbackAuthorization: "微企付回调通知中的 TBEP-Authorization 标头", + callbackBody: "微企付回调通知中请求正文" +); +``` + +--- + +### 调试验签错误: + +由于 `VerifyEventSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证回调通知事件签名时指定接收最后一个 `out` 返回参数,该参数中包含了一些异常的原因和相关堆栈信息。 + +```csharp +bool ret = client.VerifyEventSignature(timestamp, nonce, body, signature, serialNumber, out Exception error); +if (!ret) +{ + Console.WriteLine(error); + Console.WriteLine(error.InnerException); +} +``` diff --git a/docs/WechatTenpayBusiness/Advanced_IHttpClientFactory.md b/docs/WechatTenpayBusiness/Advanced_IHttpClientFactory.md new file mode 100644 index 00000000..49ba31f2 --- /dev/null +++ b/docs/WechatTenpayBusiness/Advanced_IHttpClientFactory.md @@ -0,0 +1,17 @@ +## 如何在 ASP.NET Core 中与 `IHttpClientFactory` 集成? + +--- + +本功能来自于公共组件,请参阅公共组件下的相关文档: + +> [《SKIT.FlurlHttpClient FAQ:如何在 ASP.NET Core 中与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_IHttpClientFactory.md) + +需要注意的是,由于部分微信支付接口需要显式地在构造 `System.Net.Http.HttpMessageHandler` 时指定双向认证的 SSL 证书,按照上文提供的方式自定义 `Flurl.Http.Configuration.DefaultHttpClientFactory` 时,也就必须重写此部分逻辑。 + +关于这点可以参考本库内置的一个类型,完整的代码请参阅项目目录下的 _src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Settings/HttpClientFactory_ 文件。 + +--- + +### 镜像站点 + +国内用户如访问 GitHub 网络状况不佳,可在打开上述链接后,手动将域名部分的 **github.com** 替换为 **gitee.com**、剩余路径部分保持不变,即可访问。 diff --git a/docs/WechatTenpayBusiness/Advanced_Interceptor.md b/docs/WechatTenpayBusiness/Advanced_Interceptor.md new file mode 100644 index 00000000..2bc28620 --- /dev/null +++ b/docs/WechatTenpayBusiness/Advanced_Interceptor.md @@ -0,0 +1,13 @@ +## 如何使用拦截器? + +--- + +本功能来自于公共组件,请参阅公共组件下的相关文档: + +> [《SKIT.FlurlHttpClient FAQ:如何使用拦截器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_Interceptor.md) + +--- + +### 镜像站点 + +国内用户如访问 GitHub 网络状况不佳,可在打开上述链接后,手动将域名部分的 **github.com** 替换为 **gitee.com**、剩余路径部分保持不变,即可访问。 diff --git a/docs/WechatTenpayBusiness/Advanced_JsonSerializer.md b/docs/WechatTenpayBusiness/Advanced_JsonSerializer.md new file mode 100644 index 00000000..a9df787e --- /dev/null +++ b/docs/WechatTenpayBusiness/Advanced_JsonSerializer.md @@ -0,0 +1,13 @@ +## 如何指定 JSON 序列化器? + +--- + +本功能来自于公共组件,请参阅公共组件下的相关文档: + +> [《SKIT.FlurlHttpClient FAQ:如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_JsonSerializer.md) + +--- + +### 镜像站点 + +国内用户如访问 GitHub 网络状况不佳,可在打开上述链接后,手动将域名部分的 **github.com** 替换为 **gitee.com**、剩余路径部分保持不变,即可访问。 diff --git a/docs/WechatTenpayBusiness/Advanced_ModelDefinition.md b/docs/WechatTenpayBusiness/Advanced_ModelDefinition.md new file mode 100644 index 00000000..ee6722e2 --- /dev/null +++ b/docs/WechatTenpayBusiness/Advanced_ModelDefinition.md @@ -0,0 +1,53 @@ +## 如何快速找到需要调用的 API 模型类名 / 方法名? + +--- + +本库提供的请求模型、响应模型和接口方法,三者均保持同名。 + +例如,申请产品开通的请求是 `CreateMSEPayProductApplicationRequest`,响应是 `CreateMSEPayProductApplicationResponse`,接口是 `ExecuteCreateMSEPayProductApplicationAsync()`。知道其中一个,其余两个就可以快速地推断出了。 + +再有,每个对象的命名与官方文档的接口地址大体保持一致。例如刚刚提到的申请产品开通,它的接口地址是 `[POST] /mse-pay/product-applications`,将其中的反斜杠去掉、并以大驼峰命名法的方式调整它,就可以得到前文提到的几个对象了。 + +另外,以 `Query` 开头的一般表示列表查询;以 `Get` 开头的一般表示获取详情;以 `Create` 开头的一般表示发起或新建操作。 + +完整的模型定义可以参考项目目录下的 _src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Models_ 目录。 + +--- + +### 【附】微企付商户 API 模型命名速查表: + +
+ +[展开查看] + +- 商户入驻 + + - 申请产品开通:`CreateMSEPayProductApplication` + + - 查询产品开通:`GetMSEPayProductApplicationByOutRequestNumber` / `GetMSEPayProductApplicationByRequestNumber` + + - 创建开通跳转链接:`CreateMSEPayProductApplicationLink` + + - 图片上传接口:`UploadFile` + +- H5 支付 + + - H5 支付预下单:`CreateMSEPayPaymentH5Pay` + + - 根据交易订单查询付款结果:`GetMSEPayPaymentByOutPaymentId` / `GetMSEPayPaymentByPaymentId` + + - 主动关单:`CloseMSEPayPayment` + + - 主动关单:`CloseMSEPayPayment` + +- 公共资源 Redirect: + + - 获取跳转对象:`CreateMSEPayRedirectLink` + +- 文件获取: + + - 获取账单文件下载地址:`GetMSEPayAccountBill` + + - 文件获取:`DownloadMSEPayAccountBill` + +
diff --git a/docs/WechatTenpayBusiness/Advanced_RequestSensitiveDataEncryption.md b/docs/WechatTenpayBusiness/Advanced_RequestSensitiveDataEncryption.md new file mode 100644 index 00000000..c84b2e68 --- /dev/null +++ b/docs/WechatTenpayBusiness/Advanced_RequestSensitiveDataEncryption.md @@ -0,0 +1,66 @@ +## 如何加密请求中的敏感数据? + +--- + +### 加密流程 + +对于部分接口请求传递的敏感信息,腾讯微企付可能会需要使用以下方式进行加密: + +- 使用腾讯微企付公钥基于 RSAES-OAEP + SM4 算法加密。 + +开发者利用本库提供的 `RSAUtility`、`SM4Utility` 工具类自行加密相关字段。下面给出一个使用 `RSAUtility`、`SM4Utility` 工具类加密数据的示例代码: + +```csharp +// 先通过腾讯微企付公钥基于 RSAES-OAEP 得到加密后的 SM4 密钥 +string sm4IV = "SM4 偏移量"; +string sm4Key = "SM4 密钥"; +string sm4EncryptedKey = RSAUtility.EncryptWithECB(tbepPublicKey, sm4Key); +// 再通过 SM4 得到敏感信息密文 +string plainText = "待加密的数据"; +string cipherText = SM4Utility.EncryptWithCBC(sm4Key, sm4IV, plainText); +// 最后在请求模型中指定加密参数 +request.TBEPEncryption = new WechatTenpayBusinessRequestTBEPEncryption() +{ + Algorithm = Constants.EncryptionAlgorithms.RSA_OAEP_WITH_SM4_128_CBC, + CertificateSerialNumber = tbepCertificateSerialNumber, + EncryptedKey = sm4EncryptedKey, + IV = sm4Key +}; +``` + +此外,本库还封装了直接加密请求中敏感信息字段的扩展方法。下面给出一个手动调用的示例: + +```csharp +var request = new Models.CreateMSEPayProductApplicationRequest() +{ + BusinessLicense = new Models.CreateMSEPayProductApplicationRequest.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.ExecuteCreateMSEPayProductApplicationAsync(request); +``` + +如果你希望本库在请求前能自动完成这项操作,你可以在构造得到 `WechatTenpayBusinessClient` 对象时指定自动化参数: + +```csharp +var options = new WechatTenpayBusinessOptions() +{ + // 其他配置项略 + AutoEncryptRequestSensitiveProperty = true, + SensitivePropertyEncryptionSM4Key = "SM4 密钥", + SensitivePropertyEncryptionSM4IV = "SM4 偏移量" +}; +var client = new WechatTenpayBusinessClient(options); +``` + +这样,本库会在实际发出请求前自动为你调用 `EncryptRequestSensitiveProperty()` 方法。 + +此外,该扩展方法使用反射、并依赖 `WechatTenpayBusinessSensitiveAttribute`、`WechatTenpayBusinessSensitivePropertyAttribute` 特性,相比较手动加密,可能会存在一定的性能开销。 diff --git a/docs/WechatTenpayBusiness/Advanced_ResponseSensitiveDataDecryption.md b/docs/WechatTenpayBusiness/Advanced_ResponseSensitiveDataDecryption.md new file mode 100644 index 00000000..5f1f0a00 --- /dev/null +++ b/docs/WechatTenpayBusiness/Advanced_ResponseSensitiveDataDecryption.md @@ -0,0 +1,46 @@ +## 如何解密响应中的敏感数据? + +--- + +### 解密流程 + +对于部分接口响应返回的敏感信息,腾讯微企付可能会需要使用以下方式进行解密: + +- 使用平台私钥基于 RSAES-OAEP + SM4 算法解密。 + +开发者利用本库提供的 `RSAUtility`、`SM4Utility` 工具类自行解密相关字段。下面给出一个使用 `RSAUtility`、`SM4Utility` 工具类解密数据的示例代码: + +```csharp +// 先通过平台私钥基于 RSAES-OAEP 得到解密后的 SM4 密钥 +string sm4EncryptedKey = response.TBEPEncryption.EncryptedKey; +string sm4Key = RSAUtility.DecryptWithECB(platformPrivateKey, sm4EncryptedKey); +string sm4IV = response.TBEPEncryption.IV; +// 再通过 SM4 得到敏感信息明文 +string cipherText = "待解密的数据"; +string plainText = SM4Utility.DecryptWithCBC(sm4Key, sm4IV, cipherText); +``` + +此外,本库还封装了直接解密响应中敏感信息字段的扩展方法,下面给出一个示例代码: + +```csharp +var request = new Models.GetMSEPayPaymentByPaymentIdRequest(); +var response = await client.ExecuteGetMSEPayPaymentByPaymentIdAsync(request); + +Console.WriteLine("before: {0}", response.Payee.EnterpriseName); // 此时仍是密文 +client.DecryptResponseSensitiveProperty(response); +Console.WriteLine("after: {0}", response.Payee.EnterpriseName); // 此时已是明文 +``` + +如果你希望本库在响应后能自动完成这项操作,你可以在构造得到 `WechatTenpayBusinessClient` 对象时指定自动化参数: + +```csharp +var options = new WechatTenpayBusinessClientOptions() +{ + AutoDecryptResponseSensitiveProperty = true +}; +var client = new WechatTenpayBusinessClient(options); +``` + +这样,本库会在实际收到响应后自动为你调用 `DecryptResponseSensitiveProperty()` 方法。 + +此外,该扩展方法使用反射、并依赖 `WechatTenpayBusinessSensitiveAttribute`、`WechatTenpayBusinessSensitivePropertyAttribute` 特性,相比较手动解密,可能会存在一定的性能开销。 diff --git a/docs/WechatTenpayBusiness/Advanced_ResponseSignatureVerification.md b/docs/WechatTenpayBusiness/Advanced_ResponseSignatureVerification.md new file mode 100644 index 00000000..82c4128a --- /dev/null +++ b/docs/WechatTenpayBusiness/Advanced_ResponseSignatureVerification.md @@ -0,0 +1,37 @@ +## 如何验证响应签名? + +--- + +### 验签流程 + +每个响应对象均包含键为 `TBEP-Authorization` 的响应标头,你可根据官方文档的规则利用本库提供的 `RSAUtility` 工具类自行进行签名验证。 + +下面给出一个使用 `RSAUtility` 工具类验证签名的示例代码: + +```csharp +string data = "拼接好的验签数据"; +string sign = "待验证的签名"; +string tbepPublicKey = "腾讯微企付公钥"; +bool ret = RSAUtility.VerifyWithSHA256(tbepPublicKey, data, sign); +``` + +此外,本库还封装了直接验证响应签名的扩展方法,下面给出一个示例代码: + +```csharp +bool ret = client.VerifyResponseSignature(response); +``` + +--- + +### 调试验签错误: + +由于 `VerifyResponseSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证响应签名时指定接收最后一个 `out` 返回参数,该参数中包含了一些异常的原因和相关堆栈信息。 + +```csharp +bool ret = client.VerifyResponseSignature(response, out Exception error); +if (!ret) +{ + Console.WriteLine(error); + Console.WriteLine(error.InnerException); +} +``` diff --git a/docs/WechatTenpayBusiness/README.md b/docs/WechatTenpayBusiness/README.md new file mode 100644 index 00000000..91568626 --- /dev/null +++ b/docs/WechatTenpayBusiness/README.md @@ -0,0 +1,91 @@ +# SKIT.FlurlHttpClient.Wechat.TenpayBusiness + +基于 `Flurl.Http` 的[腾讯微企付](https://business.tenpay.com/p/gateway-pay/) API 客户端。 + +--- + +## 功能 + +- 基于腾讯微企付 API 封装。 + +- 请求时自动生成签名,无需开发者手动干预。 + +- 提供了腾讯微企付所需的 RSA、SHA-256、SM3、SM4 等算法工具类。 + +- 提供了解析回调通知事件等扩展方法。 + +--- + +## 基础用法 + +### 安装: + +提示:如果你使用 Visual Studio NuGet 管理器图形化界面,请在搜索结果中勾选“**包括预发行版**”。 + +```shell +# 通过 NuGet 安装 +> Install-Package SKIT.FlurlHttpClient.Wechat.TenpayBusiness + +# 通过 dotnet-tools 安装 +> dotnet add package SKIT.FlurlHttpClient.Wechat.TenpayBusiness +``` + +### 初始化: + +```csharp +using SKIT.FlurlHttpClient.Wechat; +using SKIT.FlurlHttpClient.Wechat.TenpayBusiness; + +var options = new WechatTenpayBusinessClientOptions() +{ + PlatformId = "腾讯微企付平台账号", + PlatformCertificateSerialNumber = "腾讯微企付平台 API 证书序列号", + PlatformCertificatePrivateKey = "-----BEGIN PRIVATE KEY-----腾讯微企付平台 API 证书私钥-----END PRIVATE KEY-----", + TBEPCertificateSerialNumber = "腾讯微企付证书序列号", + TBEPCertificatePublicKey = "-----BEGIN PUBLIC KEY-----腾讯微企付证书公钥-----END PUBLIC KEY-----" +}; +var client = new WechatTenpayBusinessClient(options); +``` + +### 请求 & 响应: + +```csharp +using SKIT.FlurlHttpClient.Wechat.TenpayBusiness; +using SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Models; + +/* 以根据交易订单查询付款结果接口为例 */ +var request = new GetMSEPayPaymentByPaymentIdRequest() +{ + OutPaymentId = "平台支付单号" +}; +var response = await client.ExecuteGetMSEPayPaymentByOutPaymentIdAsync(request); +if (response.IsSuccessful()) +{ + Console.WriteLine("微企付支付单号:" + response.PaymentId); +} +else +{ + Console.WriteLine("错误代码:" + response.Error.Code); + Console.WriteLine("错误描述:" + response.Error.Description); +} +``` + +--- + +## 高级技巧 + +- [如何快速找到需要调用的 API 模型类名 / 方法名(附完整 API 对照表)?](./Advanced_ModelDefinition.md) + +- [如何在 ASP.NET Core 中与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md) + +- [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md) + +- [如何使用拦截器?](./Advanced_Interceptor.md) + +- [如何加密请求中的敏感数据?](./Advanced_RequestSensitiveDataEncryption.md) + +- [如何解密响应中的敏感数据?](./Advanced_ResponseSensitiveDataDecryption.md) + +- [如何验证响应签名?](./Advanced_ResponseSignatureVerification.md) + +- [如何验证回调通知事件签名?](./Advanced_EventSignatureVerification.md) diff --git a/docs/WechatTenpayV3/Advanced_EventSignatureVerification.md b/docs/WechatTenpayV3/Advanced_EventSignatureVerification.md index 0c28228f..82a1d32e 100644 --- a/docs/WechatTenpayV3/Advanced_EventSignatureVerification.md +++ b/docs/WechatTenpayV3/Advanced_EventSignatureVerification.md @@ -37,11 +37,11 @@ ```csharp bool ret = client.VerifyEventSignature( - callbackTimestamp: "微信回调通知中的 Wechatpay-Timestamp 字段", - callbackNonce: "微信回调通知中的 Wechatpay-Nonce 字段", + callbackTimestamp: "微信回调通知中的 Wechatpay-Timestamp 标头", + callbackNonce: "微信回调通知中的 Wechatpay-Nonce 标头", callbackBody: "微信回调通知中请求正文", - callbackSignature: "微信回调通知中的 Wechatpay-Signature 字段", - callbackSerialNumber: "微信回调通知中的 Wechatpay-Serial 字段" + callbackSignature: "微信回调通知中的 Wechatpay-Signature 标头", + callbackSerialNumber: "微信回调通知中的 Wechatpay-Serial 标头" ); ``` diff --git a/docs/WechatTenpayV3/Advanced_RequestSensitiveDataEncryption.md b/docs/WechatTenpayV3/Advanced_RequestSensitiveDataEncryption.md index 6d61864f..bf532c49 100644 --- a/docs/WechatTenpayV3/Advanced_RequestSensitiveDataEncryption.md +++ b/docs/WechatTenpayV3/Advanced_RequestSensitiveDataEncryption.md @@ -67,14 +67,14 @@ var request = new Models.AddProfitSharingReceiverRequest() RelationType = "PARTNER" }; -string temp = request.Name; // 此时仍是明文 +Console.WriteLine("before: {0}", request.Name); // 此时仍是明文 client.EncryptRequestSensitiveProperty(request); -string temp = request.Name; // 此时已是密文 +Console.WriteLine("after: {0}", request.Name); // 此时已是密文 var response = await client.ExecuteAddProfitSharingReceiverAsync(request); ``` -如果你希望本库在请求前能自动完成这项操作,你可以在构造得到 `WechatApiClient` 对象时指定自动化参数: +如果你希望本库在请求前能自动完成这项操作,你可以在构造得到 `WechatTenpayClient` 对象时指定自动化参数: ```csharp var options = new WechatTenpayClientOptions() @@ -97,7 +97,7 @@ var client = new WechatTenpayClient(options); 微信商户平台证书需要通过 API 的方式获取、且可能同时存在多个有效证书,本库提供了一个 `CertificateManager` 类型可用于管理证书信息。 -你可以在构造得到 `WechatApiClient` 对象时指定证书管理器: +你可以在构造得到 `WechatTenpayClient` 对象时指定证书管理器: ```csharp var manager = new InMemoryCertificateManager(); // 为便于后续使用,该对象可使用同一商户号下全局单例的方式声明 diff --git a/docs/WechatTenpayV3/Advanced_ResponseSensitiveDataDecryption.md b/docs/WechatTenpayV3/Advanced_ResponseSensitiveDataDecryption.md index ad23d75a..84c0a728 100644 --- a/docs/WechatTenpayV3/Advanced_ResponseSensitiveDataDecryption.md +++ b/docs/WechatTenpayV3/Advanced_ResponseSensitiveDataDecryption.md @@ -21,10 +21,10 @@ 开发者利用本库提供的 `RSAUtility`、`AESUtility` 工具类自行解密相关字段。下面给出一个使用 `RSAUtility` 工具类解密数据的示例代码: ```csharp -string chiperText = "待解密的数据"; +string cipherText = "待解密的数据"; string privateKey = "PKCS#8 私钥内容"; /* 通过私钥解密数据 */ -string plainText = RSAUtility.DecryptWithECB(privateKey, chiperText); +string plainText = RSAUtility.DecryptWithECB(privateKey, cipherText); ``` 此外,本库还封装了直接解密响应中敏感信息字段的扩展方法,下面给出一个示例代码: @@ -33,12 +33,12 @@ string plainText = RSAUtility.DecryptWithECB(privateKey, chiperText); var request = new Models.QueryCertificatesRequest(); var response = await client.ExecuteQueryCertificatesAsync(request); -string temp = response.CertificateList.First().EncryptCertificate.CipherText; // 此时仍是密文 +Console.WriteLine("before: {0}", response.CertificateList.First().EncryptCertificate.CipherText); // 此时仍是密文 client.DecryptResponseSensitiveProperty(response); -string temp = response.CertificateList.First().EncryptCertificate.CipherText; // 此时已是明文 +Console.WriteLine("after: {0}", response.CertificateList.First().EncryptCertificate.CipherText); // 此时已是明文 ``` -如果你希望本库在响应后能自动完成这项操作,你可以在构造得到 `WechatApiClient` 对象时指定自动化参数: +如果你希望本库在响应后能自动完成这项操作,你可以在构造得到 `WechatTenpayClient` 对象时指定自动化参数: ```csharp var options = new WechatTenpayClientOptions() diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/Internal/WechatTenpayBusinessClientSignExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/Internal/WechatTenpayBusinessClientSignExtensions.cs index 75ac6feb..6b72b298 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/Internal/WechatTenpayBusinessClientSignExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/Internal/WechatTenpayBusinessClientSignExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientRequestEncryptionExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientRequestEncryptionExtensions.cs index 57b452fd..047ed1df 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientRequestEncryptionExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientRequestEncryptionExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Reflection; diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientResponseVerificationExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientResponseVerificationExtensions.cs index 453fbdb3..96a50079 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientResponseVerificationExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientResponseVerificationExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Models/MSEPayPayments/GetMSEPayPaymentByOutPaymentIdResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Models/MSEPayPayments/GetMSEPayPaymentByOutPaymentIdResponse.cs index 5e774c5b..d98ff316 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Models/MSEPayPayments/GetMSEPayPaymentByOutPaymentIdResponse.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Models/MSEPayPayments/GetMSEPayPaymentByOutPaymentIdResponse.cs @@ -1,8 +1,9 @@ -namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Models +namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Models { /// /// 表示 [GET] /mse-pay/payments/out-payment-id/{out_payment_id} 接口的响应。 /// + [WechatTenpayBusinessSensitive] public class GetMSEPayPaymentByOutPaymentIdResponse : GetMSEPayPaymentByPaymentIdResponse { } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Models/MSEPayPayments/GetMSEPayPaymentByPaymentIdResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Models/MSEPayPayments/GetMSEPayPaymentByPaymentIdResponse.cs index a4add701..87974d44 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Models/MSEPayPayments/GetMSEPayPaymentByPaymentIdResponse.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Models/MSEPayPayments/GetMSEPayPaymentByPaymentIdResponse.cs @@ -1,4 +1,4 @@ -namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Models +namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Models { /// /// 表示 [GET] /mse-pay/payments/{payment_id} 接口的响应。 diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/README.md b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/README.md index 73cf0691..24ca7384 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/README.md +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/README.md @@ -2,13 +2,13 @@ [![GitHub Stars](https://img.shields.io/github/stars/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat?logo=github&label=Stars)](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat) [![GitHub Forks](https://img.shields.io/github/forks/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat?logo=github&label=Forks)](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat) [![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.TenpayBusiness.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayBusiness) [![License](https://img.shields.io/github/license/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat?label=License)](https://mit-license.org/) -基于 `Flurl.Http` 的腾讯微企付 API v3 版客户端。 +基于 `Flurl.Http` 的腾讯微企付 API 客户端。 --- ### 【功能特性】 -- 基于腾讯微企付 v3 版 API 封装。 +- 基于腾讯微企付 API 封装。 - 请求时自动生成签名,无需开发者手动干预。 - 提供了腾讯微企付所需的 RSA、SHA-256、SM3、SM4 等算法工具类。 - 提供了解析回调通知事件等扩展方法。 @@ -23,4 +23,4 @@ ### 【更新日志】 -[点此查看](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat/blob/main/CHANGELOG.md)。 \ No newline at end of file +[点此查看](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat/blob/main/CHANGELOG.md)。 diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/SKIT.FlurlHttpClient.Wechat.TenpayBusiness.csproj b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/SKIT.FlurlHttpClient.Wechat.TenpayBusiness.csproj index c48145ee..b44ccec8 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/SKIT.FlurlHttpClient.Wechat.TenpayBusiness.csproj +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/SKIT.FlurlHttpClient.Wechat.TenpayBusiness.csproj @@ -8,14 +8,14 @@ - SKIT.FlurlHttpClient.Wechat.TenpayBusinessV3 + SKIT.FlurlHttpClient.Wechat.TenpayBusiness LOGO.png README.md MIT https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat Flurl.Http Tencent Tenpay 腾讯 微企付 - 0.0.1-alpha.1 - 基于 Flurl.Http 的腾讯微企付 API v3 版客户端。 + 2.0.0-rc.1 + 基于 Flurl.Http 的腾讯微企付 API 客户端。 Fu Diwei git https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat.git diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Settings/Credentials.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Settings/Credentials.cs index 0fd824f7..fb05b27f 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Settings/Credentials.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Settings/Credentials.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Settings { @@ -30,7 +30,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Settings public string TBEPCertificatePublicKey { get; } /// - /// 初始化客户端时 的副本。 + /// 初始化客户端时 的副本。 /// public string SensitivePropertyEncryptionAlgorithm { get; set; } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/WechatTenpayBusinessClientOptions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/WechatTenpayBusinessClientOptions.cs index 29e111fa..35ab7b21 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/WechatTenpayBusinessClientOptions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/WechatTenpayBusinessClientOptions.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness {