diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md index 48bb6b21..dd662590 100644 --- a/.gitee/ISSUE_TEMPLATE.zh-CN.md +++ b/.gitee/ISSUE_TEMPLATE.zh-CN.md @@ -44,7 +44,7 @@ 1. 操作系统:请填写发生问题的操作系统环境信息(如:Windows Server 2012 R2) 2. .NET 版本:请填写发生问题的 .NET 环境信息(如:.NET Framework 4.7.2 / .NET 5.0) -3. 使用的模块及版本:请填写发生问题的模板信息(如:SKIT.FlurlHttpClient.Wechat.Api 1.0.0) +3. 使用的模块及版本:请填写发生问题的模块信息(如:SKIT.FlurlHttpClient.Wechat.Api 1.0.0) 4. 其他环境信息。 --- diff --git a/.github/ISSUE_TEMPLATE/1_bug_report.md b/.github/ISSUE_TEMPLATE/1_bug_report.md index 333fd61c..259a63c3 100644 --- a/.github/ISSUE_TEMPLATE/1_bug_report.md +++ b/.github/ISSUE_TEMPLATE/1_bug_report.md @@ -40,7 +40,7 @@ assignees: '' 1. 操作系统:请填写发生问题的操作系统环境信息(如:Windows Server 2012 R2) 2. .NET 版本:请填写发生问题的 .NET 环境信息(如:.NET Framework 4.7.2 / .NET 5.0) -3. 使用的模块及版本:请填写发生问题的模板信息(如:SKIT.FlurlHttpClient.Wechat.Api 1.0.0) +3. 使用的模块及版本:请填写发生问题的模块信息(如:SKIT.FlurlHttpClient.Wechat.Api 1.0.0) 4. 其他环境信息。 --- diff --git a/docs/WechatTenpayV3/Advanced_EventDataSignatureVerification.md b/docs/WechatTenpayV3/Advanced_EventDataSignatureVerification.md index 2628cb24..39a05f26 100644 --- a/docs/WechatTenpayV3/Advanced_EventDataSignatureVerification.md +++ b/docs/WechatTenpayV3/Advanced_EventDataSignatureVerification.md @@ -6,7 +6,7 @@ 同样的,你既可以利用本库提供的 `RSAUtility` 工具类自行进行签名验证,也可以通过 `CertificateManager` 尝试自动完成签名验证: -注意,有关 `CertificateManager` 的具体用法,请务必阅读上方给出的相关文档。 +请注意,有关 `CertificateManager` 的具体用法、及相关证书或公钥格式的说明,请务必先阅读上方给出的相关文档。 ```csharp bool ret = client.VerifyEventSignature( diff --git a/docs/WechatTenpayV3/Advanced_ResponseSignatureVerification.md b/docs/WechatTenpayV3/Advanced_ResponseSignatureVerification.md index 48502f0a..76ab50a4 100644 --- a/docs/WechatTenpayV3/Advanced_ResponseSignatureVerification.md +++ b/docs/WechatTenpayV3/Advanced_ResponseSignatureVerification.md @@ -8,7 +8,7 @@ > > [《微信支付开发者文档 - 平台证书:更新指引》](https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay5_0.shtml) -验签过程中需要使用的微信商户平台证书,开发者可通过本库封装的 `QueryCertificatesAsync()` 方法来获取。 +验签过程中需要使用的平台证书,开发者可通过本库封装的 `QueryCertificatesAsync()` 方法来获取。 每个响应对象均包含名为 `WechatpayTimestamp`、`WechatpayNonce`、`WechatpaySignature` 的几个公共字段,你可根据官方文档的规则利用本库提供的 `RSAUtility` 工具类自行进行签名验证。 @@ -16,6 +16,19 @@ --- +### 重要说明 + +请在开发过程中注意区分**商户证书**和**平台证书**: + +- **商户证书**用于生成请求的签名,需要在构建客户端配置项时指定(即 `WechatTenpayClientOptions` 对象中的证书序列号和公钥); +- **平台证书**用于验证响应或回调的签名,需要通过接口获取(即 `QueryCertificatesAsync` 方法,注意证书内容需要解密)。 + +如果你在后面的验签过程出现验签不通过的情况,请先检查是否混淆了这两个证书。 + +关于证书的更多注意事项,请参阅[《微信支付开发者文档 - 常见问题:证书相关》](https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay7_0.shtml) + +--- + ### 密钥文件格式说明: 需要注意的是,微信商户平台提供的是 PEM 格式的密钥文件,分为以下几种: @@ -72,3 +85,40 @@ certManager.SetCertificate("CER 证书序列号", "CER 证书内容"); ```csharp bool ret = client.VerifyResponseSignature(response); ``` + +--- + +### 自定义 `CertificateManager` 实现 + +上一小节提到,你可自行继承并实现一个 `CertificateManager`,例如利用数据库或 Redis 等方式存取证书信息。 + +下面给出一个利用 Redis 存储的示例代码: + +```csharp +using StackExchange.Redis; + +public class RedisCertificateManager : CertificateManager +{ + private readonly ConnectionMultiplexer _connection; + + public RedisCertificateManager(string connectionString) + { + _connection = ConnectionMultiplexer.Connect(connectionString); + } + + private string GenerateRedisKey(string serialNumber) + { + return string.Format("wxpaypc-{0}", serialNumber); + } + + public override string GetCertificate(string serialNumber) + { + return _connection.StringGet(GenerateRedisKey(serialNumber)); + } + + public override void SetCertificate(string serialNumber, string certificate) + { + _connection.StringSet(GenerateRedisKey(serialNumber), certificate, TimeSpan.FromDays(90)); + } +} +``` \ No newline at end of file diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Settings/CertificateManager.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Settings/CertificateManager.cs index 24cb41b9..b9d04f96 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Settings/CertificateManager.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Settings/CertificateManager.cs @@ -1,9 +1,6 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings { @@ -32,7 +29,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings /// public class InMemoryCertificateManager : CertificateManager { - public IDictionary _dict; + private readonly IDictionary _dict; public InMemoryCertificateManager() {