国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - ASP.NET教程 - .Net Core微信服務(wù)商二次進(jìn)件的開發(fā)

.Net Core微信服務(wù)商二次進(jìn)件的開發(fā)

2021-12-21 17:42偏執(zhí)的光輝歲月 ASP.NET教程

這篇文章主要介紹了.Net Core微信服務(wù)商二次進(jìn)件的開發(fā),包括服務(wù)商證書獲取方法及查詢進(jìn)件狀態(tài)的詳細(xì)代碼,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下

最近商城進(jìn)行微信服務(wù)商二次進(jìn)件的開發(fā),大致有幾個點(diǎn)

一,服務(wù)商簽名

二,服務(wù)商證書獲取

三,圖片上傳

四,敏感信息加密

五,查詢進(jìn)件狀態(tài)

除此之外,就是進(jìn)件信息的拼裝

.Net Core微信服務(wù)商二次進(jìn)件的開發(fā)

電商二級商戶進(jìn)件申請單-狀態(tài)流轉(zhuǎn)

.Net Core微信服務(wù)商二次進(jìn)件的開發(fā)

一 服務(wù)商簽名

首先準(zhǔn)備必須的配置:商戶號、證書、秘鑰、小程序appid、appsecret

#region 服務(wù)商簽名
        private string SrvPayBuildAuthAsync(string uri, string body, string method = "POST")
        {
            var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
            string nonce = Guid.NewGuid().ToString();

            string message = $"{method}
{uri}
{timestamp}
{nonce}
{body}
";
            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 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

使用的實(shí)體: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
                   );

三,上傳圖片

因?yàn)槲业膱D片保存在oss,首先要網(wǎng)絡(luò)圖片Bytes,對圖片進(jìn)行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);//獲取網(wǎng)絡(luò)圖片Bytes
            if ((fileBytes?.Length ?? 0) == 0)
            {
                return new MKResult<V3WXPayFileUploadOutModel>(code: 400, msg: "轉(zhuǎn)換圖片失敗");
            }
            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 二進(jìn)制內(nèi)容進(jìn)行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,進(jìn)行加密

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);
        }

    }

五,查詢進(jìn)件狀態(tài)

直接使用進(jìn)件返回的Id,調(diào)用接口查詢就Ok了

到此這篇關(guān)于.Net Core微信服務(wù)商二次進(jìn)件的文章就介紹到這了,更多相關(guān).Net Core微信服務(wù)商內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://www.cnblogs.com/liuYingwei/p/15437991.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人aaa | 亚洲国产一区二区在线观看 | 国产第一区二区三区 | 黄色片免费观看 | 色综合88| 久久九九 | 精品国产乱码久久久久久蜜柚 | 在线不卡一区 | 亚洲成人av在线 | 成人午夜精品 | 欧美疯狂性受xxxxx另类 | 日韩福利| 亚洲九九 | 18视频在线观看网站 | 免费在线观看黄色网址 | 久久av网 | 国产精品美女久久久久久免费 | 欧美日韩在线视频观看 | 成人免费看 | 黄视频网站在线观看 | 久久久一区二区三区 | 午夜视频在线观看网站 | 日韩一区中文字幕 | 亚洲一区二区中文字幕 | 国产成人精品一区二区三区视频 | 一级黄片毛片 | 国产日韩精品久久 | 精品自拍视频在线观看 | 久久国产欧美日韩精品 | 亚洲视频在线观看 | 亚洲一区综合 | 好吊色欧美一区二区三区四区 | 国产黄色在线观看 | 精久久久 | 午夜激情视频在线 | 伊人一区二区三区 | 国产亚洲精品久久久久久久 | 香港黄色录像片 | 免费精品 | 狠狠操夜夜爱 | 自拍视频网站 |