本文主要介绍“如何理解的发展。网芯微信服务商的二次feed”。在日常操作中,相信很多人对于如何理解的发展都有疑惑。网芯微信服务商的二次feed。边肖查阅了各种资料,整理出简单易用的操作方法,希望能帮助大家解答“如何理解的发展。网芯微信服务商的二次feed”。接下来,请和边肖一起学习!
最近商城进行了微信服务商第二feed的开发,有几点。
1.服务提供商签名。
二是服务商证书获取。
第三,上传图片。
敏感信息的加密。
5.查询来料零件状态。
此外,它是传入信息的集合。
电子商务二级商户入局申请表-状态流转。

一 服务商签名
首先准备必要的配置:商户号、证书、密钥、applet appid和appsecret。
#地区服务提供商签名。
privatestringSrvPayBuildAuthAsync(string uri,stringbody,stringmethod='POST ')
{
vartimestamp=DateTimeOffset。now . ToUnixTimeSeconds();
stringnonce=Guid。NewGuid()。ToString();
string message=$ ' { method } \ n { uri } \ n { timestamp } \ n { nonce } \ n { body } \ n ';
stringsignature=SrvSign(消息);
返回$'mchid=\'{_wxCfg。SrvPayMerchantId } \ ',nonce_str=\'{nonce}\ ',timestamp=\'{timestamp}\ ',serial_no=\'{_wxCfg。SrvPayCertNo}\ ',签名=\ ' { signature } \
}
privatestringSrvSign(字符串消息)
{
varbytes=Utils。readbytesfexist(_ Wxcfg。SrvPayCertFile);
if(字节数)
{
返回“”;
铌
sp; }
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 Task<CertificatesOutModel> GetSrvCert()
{
string uri = "/v3/certificates";
var auth = SrvPayBuildAuthAsync(uri, "", "GET");
var header = new Dictionary<string, string>
{
{ "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<CertificatesOutModel>(uri, header);
}
#endregion
使用的实体:CertificatesOutModel
public sealed class CertificatesOutModel : IWXResponse
{
[JsonPropertyName("data")]
public IEnumerable<Certificates> Data { 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 Task<T> GetUrlAsync<T>(string url, Dictionary<string, string> 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<T>();
}
catch
{
var result = await res.Content.ReadAsStringAsync();
if (result == null)
{
return default;
}
return result.ToJson<T>();
}
}
解密方法
//获取证书
var cert = await _wxClient.GetSrvCert();
var certificateModel = cert.Data.FirstOrDefault();
if (!cert.Data.Any())
{
return new MKResult<V3WXPayApplymentIdOutModel>(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 Task<byte[]> GetUrlBytesAsync(string url, Dictionary<string, string> 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;
}
}
然后上传图片
/// <summary>
/// 上传图片
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public async Task<MKResult<V3WXPayFileUploadOutModel>> 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<V3WXPayFileUploadOutModel>(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<V3WXPayFileUploadOutModel>(uri, meta.ToJson(), httpContent);
return new MKResult<V3WXPayFileUploadOutModel>(res, 1);
}
private async Task<T> V3UpLoadFile<T>(string uri, string meta, MultipartFormDataContent content)
{
var auth = SrvPayBuildAuthAsync(uri, meta);
var header = new Dictionary<string, string>
{
{ "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<T>(uri, header, content);
}
protected async Task<T> V3PostFileAsync<T>(string url, Dictionary<string, string> 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<T>();
}
catch
{
var result = await res.Content.ReadAsStringAsync();
if (result == null)
{
return default;
}
return result.ToJson<T>();
}
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微信服务商二次进件的开发”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/44636.html
