Jelajahi Sumber

[WeChatPay.V3] 新增 WeChatPayOptions.APIPrivateKey

Roc 4 tahun lalu
induk
melakukan
3187ca3c2c

+ 12 - 6
samples/WebApplicationSample/appsettings.Development.json

@@ -21,21 +21,27 @@
     // 为微信支付商户平台的商户号
     "MchId": "",
 
-    // API密钥
+    // 商户API密钥
     // 为微信支付商户平台的API密钥,请注意不是APIv3密钥
     "APIKey": "",
 
-    // APIv3密钥
+    // 商户APIv3密钥
     // 为微信支付商户平台的APIv3密钥,请注意不是API密钥,v3接口必填
     "APIv3Key": "",
 
-    // API证书(.p12)
-    // 为微信支付商户平台的API证书(.p12),v3接口必填
-    // 可为证书文件(.p12)路径 / 证书文件(.p12)的base64字符串
+    // 商户API证书
+    // 使用V2退款、付款等接口时必填
+    // 使用V3接口时必填
+    // 可为证书文件路径 / 证书文件的base64字符串
     "Certificate": "",
 
+    // 商户API私钥
+    // 当配置了P12格式证书时,已包含私钥,不必再单独配置API私钥。
+    // PEM格式证书,需要单独配置。
+    "APIPrivateKey": "",
+
     // RSA公钥
-    // 目前仅调用"企业付款到银行卡API"时使用,执行本示例中的"获取RSA加密公钥API"即可获取。
+    // 目前仅调用"企业付款到银行卡API [V2]"时使用,执行本示例中的"获取RSA加密公钥API [V2]"即可获取。
     "RsaPublicKey": ""
   },
 

+ 12 - 6
samples/WebApplicationSample/appsettings.json

@@ -22,21 +22,27 @@
     // 为微信支付商户平台的商户号
     "MchId": "",
 
-    // API密钥
+    // 商户API密钥
     // 为微信支付商户平台的API密钥,请注意不是APIv3密钥
     "APIKey": "",
 
-    // APIv3密钥
+    // 商户APIv3密钥
     // 为微信支付商户平台的APIv3密钥,请注意不是API密钥,v3接口必填
     "APIv3Key": "",
 
-    // API证书(.p12)
-    // 为微信支付商户平台的API证书(.p12),v3接口必填
-    // 可为证书文件(.p12)路径 / 证书文件(.p12)的base64字符串
+    // 商户API证书
+    // 使用V2退款、付款等接口时必填
+    // 使用V3接口时必填
+    // 可为证书文件路径 / 证书文件的base64字符串
     "Certificate": "",
 
+    // 商户API私钥
+    // 当配置了P12格式证书时,已包含私钥,不必再单独配置API私钥。
+    // PEM格式证书,需要单独配置。
+    "APIPrivateKey": "",
+
     // RSA公钥
-    // 目前仅调用"企业付款到银行卡API"时使用,执行本示例中的"获取RSA加密公钥API"即可获取。
+    // 目前仅调用"企业付款到银行卡API [V2]"时使用,执行本示例中的"获取RSA加密公钥API [V2]"即可获取。
     "RsaPublicKey": ""
   },
 

+ 1 - 1
src/Essensoft.Paylink.WeChatPay/V3/Extensions/HttpClientExtensions.cs

@@ -123,7 +123,7 @@ namespace Essensoft.Paylink.WeChatPay.V3.Extensions
             var timestamp = WeChatPayUtility.GetTimeStamp();
             var nonce = WeChatPayUtility.GenerateNonceStr();
             var message = BuildMessage(method, uri, timestamp, nonce, body);
-            var signature = SHA256WithRSA.Sign(options.CertificateRSAPrivateKey, message);
+            var signature = SHA256WithRSA.Sign(options.RSAPrivateKey, message);
 
             return $"mchid=\"{options.MchId}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{options.CertificateSerialNo}\",signature=\"{signature}\"";
         }

+ 1 - 1
src/Essensoft.Paylink.WeChatPay/V3/Request/WeChatPayAppSdkRequest.cs

@@ -58,7 +58,7 @@ namespace Essensoft.Paylink.WeChatPay.V3.Request
             sortedTxtParams.Add(WeChatPayConsts.timestamp, WeChatPayUtility.GetTimeStamp());
 
             var signatureSourceData = BuildSignatureSourceData(sortedTxtParams);
-            sortedTxtParams.Add(WeChatPayConsts.sign, SHA256WithRSA.Sign(options.CertificateRSAPrivateKey, signatureSourceData));
+            sortedTxtParams.Add(WeChatPayConsts.sign, SHA256WithRSA.Sign(options.RSAPrivateKey, signatureSourceData));
         }
 
         private static string BuildSignatureSourceData(WeChatPayDictionary sortedTxtParams)

+ 1 - 1
src/Essensoft.Paylink.WeChatPay/V3/Request/WeChatPayJsApiSdkRequest.cs

@@ -47,7 +47,7 @@ namespace Essensoft.Paylink.WeChatPay.V3.Request
             sortedTxtParams.Add(WeChatPayConsts.signType, WeChatPayConsts.RSA);
 
             var signatureSourceData = BuildSignatureSourceData(sortedTxtParams);
-            sortedTxtParams.Add(WeChatPayConsts.paySign, SHA256WithRSA.Sign(options.CertificateRSAPrivateKey, signatureSourceData));
+            sortedTxtParams.Add(WeChatPayConsts.paySign, SHA256WithRSA.Sign(options.RSAPrivateKey, signatureSourceData));
         }
 
         private static string BuildSignatureSourceData(WeChatPayDictionary sortedTxtParams)

+ 1 - 1
src/Essensoft.Paylink.WeChatPay/V3/Request/WeChatPayMiniProgramSdkRequest.cs

@@ -47,7 +47,7 @@ namespace Essensoft.Paylink.WeChatPay.V3.Request
             sortedTxtParams.Add(WeChatPayConsts.signType, WeChatPayConsts.RSA);
 
             var signatureSourceData = BuildSignatureSourceData(sortedTxtParams);
-            sortedTxtParams.Add(WeChatPayConsts.paySign, SHA256WithRSA.Sign(options.CertificateRSAPrivateKey, signatureSourceData));
+            sortedTxtParams.Add(WeChatPayConsts.paySign, SHA256WithRSA.Sign(options.RSAPrivateKey, signatureSourceData));
         }
 
         private static string BuildSignatureSourceData(WeChatPayDictionary sortedTxtParams)

+ 34 - 8
src/Essensoft.Paylink.WeChatPay/WeChatPayOptions.cs

@@ -12,6 +12,7 @@ namespace Essensoft.Paylink.WeChatPay
     {
         private string certificate;
         private string certificatePassword;
+        private string privateKey;
 
         /// <summary>
         /// 应用号
@@ -54,10 +55,10 @@ namespace Essensoft.Paylink.WeChatPay
         public string SubMchId { get; set; }
 
         /// <summary>
-        /// API证书(.p12格式)
+        /// 商户API证书
         /// </summary>
         /// <remarks>
-        /// 可为 .p12证书文件路径、.p12证书文件的Base64编码
+        /// 可为 证书文件路径、证书文件的Base64编码
         /// </remarks>
         public string Certificate
         {
@@ -73,7 +74,7 @@ namespace Essensoft.Paylink.WeChatPay
         }
 
         /// <summary>
-        /// API证书密码
+        /// 商户API证书密码
         /// </summary>
         /// <remarks>
         /// 默认为商户号
@@ -92,12 +93,33 @@ namespace Essensoft.Paylink.WeChatPay
         }
 
         /// <summary>
-        /// API密钥
+        /// 商户API私钥
+        /// </summary>
+        /// <remarks>
+        /// 当配置了P12格式证书时,已包含私钥信息,不必再配置API私钥。PEM格式则必须配置。
+        /// </remarks>
+        public string APIPrivateKey
+        {
+            get => privateKey;
+            set
+            {
+                if (!string.IsNullOrEmpty(value))
+                {
+                    privateKey = value;
+                    var rsa = RSA.Create();
+                    rsa.ImportPkcs8PrivateKey(Convert.FromBase64String(privateKey), out var _);
+                    RSAPrivateKey = rsa;
+                }
+            }
+        }
+
+        /// <summary>
+        /// 商户API密钥
         /// </summary>
         public string APIKey { get; set; }
 
         /// <summary>
-        /// APIv3密钥
+        /// 商户APIv3密钥
         /// </summary>
         public string APIv3Key { get; set; }
 
@@ -105,12 +127,12 @@ namespace Essensoft.Paylink.WeChatPay
         /// RSA公钥
         /// </summary>
         /// <remarks>
-        /// 目前仅调用"企业付款到银行卡API"时使用,执行"获取RSA加密公钥API"即可获取。
+        /// 目前仅调用"企业付款到银行卡API [V2]"时使用,执行"获取RSA加密公钥API [V2]"即可获取。
         /// </remarks>
         public string RsaPublicKey { get; set; }
 
         internal X509Certificate2 Certificate2;
-        internal RSA CertificateRSAPrivateKey;
+        internal RSA RSAPrivateKey;
         internal string CertificateSerialNo;
 
         private void GetCertificateInfo()
@@ -137,7 +159,11 @@ namespace Essensoft.Paylink.WeChatPay
             }
 
             CertificateSerialNo = Certificate2.GetSerialNumberString();
-            CertificateRSAPrivateKey = Certificate2.GetRSAPrivateKey();
+
+            if (RSAPrivateKey == null)
+            {
+                RSAPrivateKey = Certificate2.GetRSAPrivateKey();
+            }
         }
     }
 }