Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions Samples/TenPayV3/Senparc.Weixin.Sample.TenPayV3/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,18 @@
"TenPayV3_SubAppSecret": "#{TenPayV3_SubAppSecret}#",
"TenPayV3_MchId": "#{TenPayV3_MchId}#",
"TenPayV3_SubMchId": "#{TenPayV3_SubMchId}#", //子商户,没有可留空
"TenPayV3_Key": "#{TenPayV3_Key}#",
"TenPayV3_TenpayNotify": "#{TenPayV3_TenpayNotify}#", //https://YourDomainName/TenpayApiV3/PayNotifyUrl
/* 支付证书私钥
* 1、支持明文私钥(无换行字符)
* 2、私钥文件路径(如:~/App_Data/cert/apiclient_key.pem),注意:必须放在 App_Data 等受保护的目录下,避免泄露
*/
"TenPayV3_PrivateKey": "#{TenPayV3_PrivateKey}#", //(新)证书私钥
"TenPayV3_SerialNumber": "#{TenPayV3_SerialNumber}#", //(新)证书序列号
"TenPayV3_ApiV3Key": "#{TenPayV3_APIv3Key}#", //(新)APIv3 密钥
"TenPayV3_Key": "#{TenPayV3_Key}#", // 微信支付商户后台 【商户APIv2密钥】
"TenPayV3_CertPath": "#{TenPayV3_CertPath}#", // 微信支付商户后台 【商户API证书 apiclient_cert.p12】 支付证书物理路径,如:D:\\cert\\apiclient_cert.p12
"TenPayV3_CertSecret": "#{TenPayV3_CertSecret}#", //(新)支付证书密码【原始密码和 MchId 相同】
"TenPayV3_TenpayNotify": "#{TenPayV3_TenpayNotify}#", //http://YourDomainName/TenpayV3/PayNotifyUrl
"TenPayV3_PrivateKey": "#{TenPayV3_PrivateKey}#", // 微信支付商户后台 【商户API证书 apiclient_key.pem】 支持本地项目路径(D:\\cert\\apiclient_key.pem)/字符串(字符串全量即可2.1.0后支持)
"TenPayV3_SerialNumber": "#{TenPayV3_SerialNumber}#", // 微信支付商户后台中【商户API证书 证书序列号】
"TenPayV3_ApiV3Key": "#{TenPayV3_APIv3Key}#", //微信支付商户后台 【APIv3密钥】
"TenPayV3_PlatformCertDisable": "#{TenPayV3_PlatformCertDisable}#", // 微信平台证书是否禁用 true/false 默认false 禁用
"TenPayV3_TenPayPubKey": "#{TenPayV3_TenPayPubKey}#", // 微信支付商户后台 【微信支付公钥证书】 支持本地项目路径(D:\\cert\\pub_key.pem)/字符串(字符串全量即可2.1.0后支持),空则代表使用原来的平台证书
"TenPayV3_TenPayPubKeyID": "#{TenPayV3_TenPayPubKeyID}#", // 微信支付商户后台 【微信支付公钥证书】,空则代表使用原来的平台证书,如PUB_KEY_ID_0000000000000000000000
//如果不设置TenPayV3_WxOpenTenpayNotify,默认在 TenPayV3_TenpayNotify 的值最后加上 "WxOpen"
"TenPayV3_WxOpenTenpayNotify": "#{TenPayV3_WxOpenTenpayNotify}#", //http://YourDomainName/TenpayV3/PayNotifyUrlWxOpen
"EncryptionType": "#{EncryptionType}#" // 加密类型:RSA / SM
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class BasePayApisTests : BaseTenPayTest
public void CertificatesTest()
{
BasePayApis basePayApis = new BasePayApis();
string algorithmType = Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting.EncryptionType == CertType.SM.ToString() ? "SM2" : "RSA";
CertType algorithmType = Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting.EncryptionType == CertType.SM ? CertType.SM : CertType.RSA;
var certs = basePayApis.CertificatesAsync(algorithmType).GetAwaiter().GetResult();
Assert.IsNotNull(certs);
Console.WriteLine(certs.ToJson(true));
Expand All @@ -40,7 +40,7 @@ public void CertificatesTest()
var tenpayV3Setting = Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting;
var cert = certs.data.First();
var pubKey = string.Empty;
if (Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting.EncryptionType == CertType.SM.ToString())
if (Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting.EncryptionType == CertType.SM)
{
pubKey = GmHelper.Sm4DecryptGCM(tenpayV3Setting.TenPayV3_APIv3Key, cert.encrypt_certificate.nonce, cert.encrypt_certificate.associated_data, cert.encrypt_certificate.ciphertext);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ public void CreatePaySignTest()
var nonceStr = "5K8264ILTKCH16CQ2502SI8ZNMTM67VS";

var separcWeixinSetting = Config.SenparcWeixinSetting with
{
TenPayV3_AppId = appId,
TenPayV3_PrivateKey = privateKey
};
{
TenPayV3_AppId = appId,
TenPayV3_PrivateKey = privateKey
};

var result = TenPaySignHelper.CreatePaySign(timestamp, nonceStr, package, separcWeixinSetting);
Assert.IsNotNull(result);
Expand All @@ -44,7 +44,7 @@ public void CreatePaySign_ByPrivateKeyTest()
var timestamp = "1414561699";
var nonceStr = "5K8264ILTKCH16CQ2502SI8ZNMTM67VS";

var result = TenPaySignHelper.CreatePaySign(timestamp, nonceStr, package, appId, privateKey);
var result = TenPaySignHelper.CreatePaySign(timestamp, nonceStr, package, appId, privateKey, CertType.RSA);
Assert.IsNotNull(result);
Console.WriteLine(result);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,19 @@
"TenPayV3_SubAppSecret": "#{TenPayV3_SubAppSecret}#",
"TenPayV3_MchId": "#{TenPayV3_MchId}#",
"TenPayV3_SubMchId": "#{TenPayV3_SubMchId}#", //子商户,没有可留空
"TenPayV3_Key": "#{TenPayV3_Key}#",
"TenPayV3_CertPath": "#{TenPayV3_CertPath}#", //(新)支付证书物理路径,如:D:\\cert\\apiclient_cert.p12
"TenPayV3_CertSecret": "#{TenPayV3_CertSecret}#", //(新)支付证书密码原始密码和 MchId 相同
"TenPayV3_Key": "#{TenPayV3_Key}#", // 微信支付商户后台 【商户APIv2密钥】
"TenPayV3_CertPath": "#{TenPayV3_CertPath}#", // 微信支付商户后台 【商户API证书 apiclient_cert.p12】 支付证书物理路径,如:D:\\cert\\apiclient_cert.p12
"TenPayV3_CertSecret": "#{TenPayV3_CertSecret}#", //(新)支付证书密码原始密码和 MchId 相同
"TenPayV3_TenpayNotify": "#{TenPayV3_TenpayNotify}#", //http://YourDomainName/TenpayV3/PayNotifyUrl
"TenPayV3_PrivateKey": "#{TenPayV3_PrivateKey}#", //(新)证书私钥
"TenPayV3_SerialNumber": "#{TenPayV3_SerialNumber}#", //(新)证书序列号
"TenPayV3_ApiV3Key": "#{TenPayV3_APIv3Key}#", //(新)APIv3 密钥
"TenPayV3_TenPayPubKey": "#{TenPayV3_TenPayPubKey}#", // (新)微信支付公钥证书-验证微信支付身份,支持本地项目路径/字符串,空则代表使用原来的平台证书,如:D:\\cert\\cert.pem
"TenPayV3_TenPayPubKeyID": "#{TenPayV3_TenPayPubKeyID}#", // (新)微信支付公钥ID-验证微信支付身份,空则代表使用原来的平台证书,如PUB_KEY_ID_0000000000000000000000
"TenPayV3_PrivateKey": "#{TenPayV3_PrivateKey}#", // 微信支付商户后台 【商户API证书 apiclient_key.pem】 支持本地项目路径(D:\\cert\\apiclient_key.pem)/字符串(字符串全量即可2.1.0后支持)
"TenPayV3_SerialNumber": "#{TenPayV3_SerialNumber}#", // 微信支付商户后台中【商户API证书 证书序列号】
"TenPayV3_ApiV3Key": "#{TenPayV3_APIv3Key}#", //微信支付商户后台 【APIv3密钥】
"TenPayV3_PlatformCertDisable": "#{TenPayV3_PlatformCertDisable}#", // 微信平台证书是否禁用 true/false 默认false 禁用
"TenPayV3_TenPayPubKey": "#{TenPayV3_TenPayPubKey}#", // 微信支付商户后台 【微信支付公钥证书】 支持本地项目路径(D:\\cert\\pub_key.pem)/字符串(字符串全量即可2.1.0后支持),空则代表使用原来的平台证书
"TenPayV3_TenPayPubKeyID": "#{TenPayV3_TenPayPubKeyID}#", // 微信支付商户后台 【微信支付公钥证书】,空则代表使用原来的平台证书,如PUB_KEY_ID_0000000000000000000000
//如果不设置TenPayV3_WxOpenTenpayNotify,默认在 TenPayV3_TenpayNotify 的值最后加上 "WxOpen"
"TenPayV3_WxOpenTenpayNotify": "#{TenPayV3_WxOpenTenpayNotify}#", //http://YourDomainName/TenpayV3/PayNotifyUrlWxOpen
"EncryptionType": "#{EncryptionType}#", // 加密类型:RSA / SM
//开放平台
"Component_Appid": "#{Component_Appid}#",
"Component_Secret": "#{Component_Secret}#",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public BasePayApis(ISenparcWeixinSettingForTenpayV3 senparcWeixinSettingForTenpa

if (!_tenpayV3Setting.EncryptionType.HasValue)
{
throw new Senparc.Weixin.Exceptions.WeixinException("没有设置证书加密类型(EncryptionType)");
_tenpayV3Setting.EncryptionType = CertType.RSA;
}
}

Expand Down Expand Up @@ -140,11 +140,17 @@ public async Task<PublicKeyCollection> GetPublicKeysAsync(/*int timeOut = Config
{
PublicKeyCollection keys = new();

if (!string.IsNullOrWhiteSpace(_tenpayV3Setting.TenPayV3_TenPayPubKeyID))
if (_tenpayV3Setting.TenPayV3_TenPayPubKeyEnable)
{
keys[_tenpayV3Setting.TenPayV3_TenPayPubKeyID] = SecurityHelper.GetUnwrapCertKey(_tenpayV3Setting.TenPayV3_TenPayPubKey);
}

// 如果平台证书禁用了,直接返回
if (_tenpayV3Setting.TenPayV3_PlatformCertDisable)
{
return keys;
}

var certificates = await CertificatesAsync(_tenpayV3Setting.EncryptionType.Value);
if (!certificates.ResultCode.Success)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ public interface ISenparcWeixinSettingForTenpayV3 : ISenparcWeixinSettingBase
/// </summary>
string TenPayV3_APIv3Key { get; set; }

/// <summary>
/// 微信平台证书是否禁用 true/false 默认false 禁用
/// </summary>
bool TenPayV3_PlatformCertDisable { get; set; }

/// <summary>
/// 微信支付(V3)微信平台公钥(替换平台证书)
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,11 @@ public virtual string TenPayV3_PrivateKey
/// </summary>
public virtual string TenPayV3_APIv3Key { get; set; }

/// <summary>
/// 微信平台证书是否禁用 true/false 默认false 禁用
/// </summary>
public virtual bool TenPayV3_PlatformCertDisable { get; set; }


private string _tenPayV3_WeixinPubKey;
/// <summary>
Expand All @@ -349,7 +354,7 @@ public virtual string TenPayV3_TenPayPubKey
public virtual string TenPayV3_TenPayPubKeyID { get; set; }

/// <summary>
/// 微信支付(V3)公钥证书 是否启用
/// 微信支付(V3)公钥证书 是否启用 内部构造
/// </summary>
public virtual bool TenPayV3_TenPayPubKeyEnable
{
Expand Down
25 changes: 23 additions & 2 deletions src/Senparc.Weixin/Senparc.Weixin/Helpers/TenPay/TenPayHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,12 @@ public static string GetRegisterKey(ISenparcWeixinSettingForTenpayV3 senparcWeix
/// <returns></returns>
public static string TryGetPrivateKeyFromFile(ref string tenPayV3_PrivateKey)
{
if (tenPayV3_PrivateKey != null && tenPayV3_PrivateKey.Length < 100 && tenPayV3_PrivateKey.StartsWith("~/"))
if (string.IsNullOrWhiteSpace(tenPayV3_PrivateKey))
{
return tenPayV3_PrivateKey;
}

if (tenPayV3_PrivateKey.Length < 100 && tenPayV3_PrivateKey.StartsWith("~/"))
{
//虚拟路径
//尝试读取文件
Expand All @@ -82,6 +87,11 @@ public static string TryGetPrivateKeyFromFile(ref string tenPayV3_PrivateKey)
var privateKey = regex.Replace(fileContent, "");
tenPayV3_PrivateKey = privateKey;
}
else
{
var privateKey = tenPayV3_PrivateKey.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "");
tenPayV3_PrivateKey = privateKey;
}
return tenPayV3_PrivateKey;
}

Expand All @@ -91,7 +101,12 @@ public static string TryGetPrivateKeyFromFile(ref string tenPayV3_PrivateKey)
/// <returns></returns>
public static string TryGetPublicKeyFromFile(ref string tenPayV3_PubKey)
{
if (tenPayV3_PubKey != null && tenPayV3_PubKey.Length < 100 && tenPayV3_PubKey.StartsWith("~/"))
if (string.IsNullOrWhiteSpace(tenPayV3_PubKey))
{
return default;
}

if (tenPayV3_PubKey.Length < 100 && tenPayV3_PubKey.StartsWith("~/"))
{
//虚拟路径
//尝试读取文件
Expand All @@ -106,6 +121,12 @@ public static string TryGetPublicKeyFromFile(ref string tenPayV3_PubKey)
var publicKey = regex.Replace(fileContent, "");
tenPayV3_PubKey = publicKey;
}
else
{
var publicKey = tenPayV3_PubKey.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "");
tenPayV3_PubKey = publicKey;
}

return tenPayV3_PubKey;
}
}
Expand Down