个人技术分享

问题

添加分账接收方遇到了一个问题,需要对敏感字段加密解密,出现了Wechatpay-Serial不正确的问题

解决

安装SKIT.FlurlHttpClient.Wechat.TenpayV3
在这里插入图片描述

/// <summary>
/// 单例模式注入
/// 支付客户端
/// </summary>
public class PayClient
{
    public WechatTenpayClient Instance { get; private set; }

    /// <summary>
    /// 构造函数注入
    /// </summary>
    /// <param name="wechatConfig"></param>
    public PayClient(IOptions<ConfigModel> wechatConfig, CertificateManager manager)
    {
        var options = new WechatTenpayClientOptions()
        {
            MerchantId = wechatConfig.Value.MiniProgramMchid,
            MerchantV3Secret = wechatConfig.Value.MiniProgramMchApiKey,
            MerchantCertificateSerialNumber = wechatConfig.Value.MiniProgramMchNumber,
            MerchantCertificatePrivateKey = $"-----BEGIN PRIVATE KEY-----{wechatConfig.Value.MiniProgramMchPrivateKey}-----END PRIVATE KEY-----",
            PlatformCertificateManager = manager // 证书管理器的具体用法请参阅下文的高级技巧与加密、验签有关的章节
        };
        Instance = new WechatTenpayClient(options);
    }
}
/// <summary>
/// 获取微信平台的证书
/// </summary>
/// <returns></returns>
public async Task<CertificateEntry?> GetWechatPayCer()
{
    var client = PayClient.Instance;
    var cerList = client.PlatformCertificateManager.AllEntries();
    //证书存在直接返回
    foreach (var cer in cerList)
    {
        if (cer.IsAvailable())
        {
            return cer;
        }
    }
    //证书不存在则查询获取
    var request = new QueryCertificatesRequest();
    request.AlgorithmType = "RSA";
    var res= await client.ExecuteQueryCertificatesAsync(request);
    if (res.IsSuccessful())
    {
        //解密
        client.DecryptResponseSensitiveProperty(res);
        foreach (var tmpCer in res.CertificateList)
        {
            client.PlatformCertificateManager.AddEntry(new CertificateEntry("RSA",tmpCer.SerialNumber,tmpCer.EncryptCertificate.CipherText,tmpCer.EffectiveTime,tmpCer.ExpireTime));
        }
        return client.PlatformCertificateManager.AllEntries().FirstOrDefault();
    }
    return null;
}


/// <summary>
/// 添加分账接收方
/// </summary>
/// <param name="openid"></param>
/// <param name="isMch">是否是商户</param>
/// <param name="name">如果是商户号必填,商户全称</param>
/// <returns></returns>
public async Task<bool> AddShareOrderUser(string openid, bool isMch,string name="")
{
   var client = weChatMiniProgramPayClient.Instance;
   var appid = options.Value.MiniProgramAppId;
   //获取publickey
   var cer = await GetWechatPayCer();
   AddProfitSharingReceiverRequest request = new AddProfitSharingReceiverRequest();
   request.WechatpayCertificateSerialNumber = cer.Value.SerialNumber;
   request.AppId = appid;
   if (isMch)
   {
       request.Type = "MERCHANT_ID";
       request.Name = name;
   }
   else
   {
       request.Type = "PERSONAL_OPENID";
   }
   request.Account = openid;
   request.RelationType = "DISTRIBUTOR";
   if (isMch)
   {
       client.EncryptRequestSensitiveProperty(request);
   }
   var response = await client.ExecuteAddProfitSharingReceiverAsync(request);
   var result = response.IsSuccessful();
   if (result)
   {
       logger.LogWarning($"添加分账接收方成功:{openid}");
   }
   else
   {
       logger.LogWarning($"添加分账接收方失败:{openid},{response.ErrorCode},{response.ErrorMessage},入参:{JsonConvert.SerializeObject(request)}");
   }
   return result;
}

其他类似的接口也是一样

参考

添加分账接收方
https://pay.weixin.qq.com/docs/merchant/apis/profit-sharing/receivers/add-receiver.html
加密解密
https://pay.weixin.qq.com/docs/merchant/development/interface-rules/sensitive-data-encryption.html
解密
加密
要自己开发的话可以参考腾讯给的案例https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/qian-ming-sheng-cheng
在这里插入图片描述