如何理解.Net Core微信服务商二次进件的开发
发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,这篇文章主要介绍"如何理解.Net Core微信服务商二次进件的开发",在日常操作中,相信很多人在如何理解.Net Core微信服务商二次进件的开发问题上存在疑惑,小编查阅了各式资料,整理出简单好用的
千家信息网最后更新 2025年01月19日如何理解.Net Core微信服务商二次进件的开发
这篇文章主要介绍"如何理解.Net Core微信服务商二次进件的开发",在日常操作中,相信很多人在如何理解.Net Core微信服务商二次进件的开发问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"如何理解.Net Core微信服务商二次进件的开发"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
最近商城进行微信服务商二次进件的开发,大致有几个点
一,服务商签名
二,服务商证书获取
三,图片上传
四,敏感信息加密
五,查询进件状态
除此之外,就是进件信息的拼装
电商二级商户进件申请单-状态流转
一 服务商签名
首先准备必须的配置:商户号、证书、秘钥、小程序appid、appsecret
#region 服务商签名 private string SrvPayBuildAuthAsync(string uri, string body, string method = "POST") { var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); string nonce = Guid.NewGuid().ToString(); string message = $"{method}\n{uri}\n{timestamp}\n{nonce}\n{body}\n"; string signature = SrvSign(message); return $"mchid=\"{_wxCfg.SrvPayMerchantId}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{_wxCfg.SrvPayCertNo}\",signature=\"{signature}\""; } private string SrvSign(string message) { var bytes = Utils.ReadBytesIfExist(_wxCfg.SrvPayCertFile); if (bytes is null) { return ""; } X509Certificate2 cert = new(bytes, _wxCfg.SrvPayMerchantId); RSA rsa = cert.GetRSAPrivateKey(); var signData = rsa.SignData(Encoding.UTF8.GetBytes(message), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); return Convert.ToBase64String(signData); }
二 获取证书
分为:第一步获取证书,第二步解密证书
1 获取证书
https://api.mch.weixin.qq.com/v3/certificates
#region 获取平台证书 public async TaskGetSrvCert() { string uri = "/v3/certificates"; var auth = SrvPayBuildAuthAsync(uri, "", "GET"); var header = new Dictionary { { "Authorization",$"WECHATPAY2-SHA256-RSA2048 {auth}"}, { "Accept","*/*" }, { "Accept-Encoding","gzip,deflate,brn" }, { "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Edg/90.0.818.46" }, }; return await GetUrlAsync (uri, header); } #endregion
使用的实体:CertificatesOutModel
public sealed class CertificatesOutModel : IWXResponse { [JsonPropertyName("data")] public IEnumerableData { get; set; } public string Code { get; set; } public string Message { get; set; } } public class Certificates { [JsonPropertyName("serial_no")] public string SerialNo { get; set; } [JsonPropertyName("effective_time")] public string EffectiveTime { get; set; } [JsonPropertyName("expire_time")] public string ExpireTime { get; set; } [JsonPropertyName("encrypt_certificate")] public EncryptCertificate EncryptCertificate { get; set; } }
请求方法:GetUrlAsync
protected async TaskGetUrlAsync (string url, Dictionary headers = null) { HttpResponseMessage res = null; try { if (headers != null && headers.Count > 0) { foreach (var header in headers) { _client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value); } } res = await _client.GetAsync(url); res.EnsureSuccessStatusCode(); var result = await res.Content.ReadAsStringAsync(); if (result == null) { return default; } return result.ToJson (); } catch { var result = await res.Content.ReadAsStringAsync(); if (result == null) { return default; } return result.ToJson (); } }
解密方法
//获取证书 var cert = await _wxClient.GetSrvCert(); var certificateModel = cert.Data.FirstOrDefault(); if (!cert.Data.Any()) { return new MKResult(code: 400, msg: "未获取到平台证书"); } if (!string.IsNullOrEmpty(applyment.Body.SerialNo)) { certificateModel = cert.Data.SingleOrDefault(s => s.SerialNo == applyment.Body.SerialNo); } certificateModel.EncryptCertificate.Ciphertext = AESUtility.AesGcmDecrypt( _wxCfg.SrvApiV3Key, certificateModel.EncryptCertificate.AssociatedData, certificateModel.EncryptCertificate.Nonce, certificateModel.EncryptCertificate.Ciphertext );
三,上传图片
因为我的图片保存在oss,首先要网络图片Bytes,对图片进行sha256,方法在后面
protected async TaskGetUrlBytesAsync(string url, Dictionary headers = null) { try { if (headers != null && headers.Count > 0) { foreach (var header in headers) { _client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value); } } var res = await _client.GetAsync(url); res.EnsureSuccessStatusCode(); return await res.Content.ReadAsByteArrayAsync(); } catch { return default; } }
然后上传图片
////// 上传图片 /// /// ///public async Task > UploadFile(string url) { string fileContentType; string filetype; if (url!.Contains(".bmp", StringComparison.OrdinalIgnoreCase)) { fileContentType = "image/bmp"; filetype = ".bmp"; } else if (url!.Contains(".jpg", StringComparison.OrdinalIgnoreCase)) { fileContentType = "image/jpeg"; filetype = ".jpg"; } else if (url!.Contains(".jpeg", StringComparison.OrdinalIgnoreCase)) { fileContentType = "image/jpeg"; filetype = ".jpeg"; } else { fileContentType = "image/png"; filetype = ".png"; } UploadMerchantMediaImageRequest meta = new(); var fileBytes = await GetUrlBytesAsync(url);//获取网络图片Bytes if ((fileBytes?.Length ?? 0) == 0) { return new MKResult (code: 400, msg: "转换图片失败"); } meta.FileHash = GetHash(fileBytes); meta.FileName = Guid.NewGuid().ToString("N").ToLower() + filetype; string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x"); using var fileContent = new ByteArrayContent(fileBytes); using var metaContent = new StringContent(meta.ToJson(), Encoding.UTF8, "application/json"); using var httpContent = new MultipartFormDataContent(boundary); httpContent.Add(metaContent, "\"meta\"");//meta 必须要加双引号 httpContent.Add(fileContent, "\"file\"", "\"" + meta.FileName + "\"");//必须要加双引号 httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data; boundary=" + boundary);// boundary不能加引号 metaContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(fileContentType); var uri = $"/v3/merchant/media/upload"; var res = await V3UpLoadFile (uri, meta.ToJson(), httpContent); return new MKResult (res, 1); }
private async TaskV3UpLoadFile (string uri, string meta, MultipartFormDataContent content) { var auth = SrvPayBuildAuthAsync(uri, meta); var header = new Dictionary { { "Authorization",$"WECHATPAY2-SHA256-RSA2048 {auth}"}, { "Accept","*/*" }, { "Accept-Encoding","gzip,deflate,brn" }, { "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Edg/90.0.818.46" }, }; return await V3PostFileAsync (uri, header, content); }
protected async TaskV3PostFileAsync (string url, Dictionary headers, MultipartFormDataContent content) { HttpResponseMessage res = null; try { if (headers != null && headers.Count > 0) { foreach (var header in headers) { _client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value); } } res = await _client.PostAsync(url, content); res.EnsureSuccessStatusCode(); var result = await res.Content.ReadAsStringAsync(); if (result == null) { return default; } return result.ToJson (); } catch { var result = await res.Content.ReadAsStringAsync(); if (result == null) { return default; } return result.ToJson (); } finally { if (content != null) { content.Dispose(); } } }
#region 二进制内容进行sha256 private static string GetHash(byte[] bytes) { if (bytes == null) throw new ArgumentNullException(nameof(bytes)); using SHA256 sha = SHA256.Create(); byte[] hashBytes = sha.ComputeHash(bytes); return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); }
四,敏感信息加密
使用获取到的证书certificateModel,进行加密
public static class RSAUtility { public static string RSAEncrypt(string text, Certificates certificateModel) { var bytes = Encoding.UTF8.GetBytes(certificateModel.EncryptCertificate.Ciphertext); using var x509 = new X509Certificate2(bytes); var rsaParam = x509.GetRSAPublicKey().ExportParameters(false); var rsa = new RSACryptoServiceProvider(); rsa.ImportParameters(rsaParam); var buff = rsa.Encrypt(Encoding.UTF8.GetBytes(text), true); return Convert.ToBase64String(buff); } }
五,查询进件状态
直接使用进件返回的Id,调用接口查询就Ok了
到此,关于"如何理解.Net Core微信服务商二次进件的开发"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
证书
图片
务商
开发
方法
服务商
学习
服务
引号
状态
加密
查询
信息
商户
平台
更多
网络
帮助
实用
接下来
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
关注网络安全 主题班会
传奇3 服务器满员
网络安全事件等级的确定
西安西电网络技术有限公司
ug编程刀具数据库视频
网络安全法 英语
邯郸crm软件开发
手机热点网络安全密钥不匹配
福州迅龙网络技术
煤矿重点危险源数据库
鸡泽县委网络安全局
数据库上机公式
数据库使用时很卡是什么原因
云桌面服务器组成架构
举例说说生活中的数据库操作
网络安全周活动宣传总结
自身网络安全心理建设论文
服务器安全策略开放端口
福田区无源网络技术开发经验丰富
插入参考文献使用哪个数据库
数据库可简写
网络安全发展的主要特点
网络安全的重要属性
在事业单位做软件开发好吗
软件开发公司因软件运营方
金智维软件开发的待遇怎么样
我的世界服务器挖掘记录
网络安全检测 360
2019年网络安全专项
成都网络安全工程师