• 微信支付特约商户进件中base64格式图片上传


    微信图片上传接口地址:https://api.mch.weixin.qq.com/v3/merchant/media/upload

    1、上传方法

     1 using HttpHandlerDemo;
     2 using Newtonsoft.Json;
     3 using System;
     4 using System.Collections.Generic;
     5 using System.IO;
     6 using System.Linq;
     7 using System.Net;
     8 using System.Net.Http;
     9 using System.Net.Http.Headers;
    10 using System.Security.Cryptography;
    11 using System.Text;
    12 using HttpHandler = Lib.HttpHandler;
    13 
    14 namespace API
    15 {
    16     public class Helper
    17     {        
    18         public static string UploadImg(string b64)
    19         {
    20             byte[] data = Convert.FromBase64String(b64);
    21             //证书本地路径
    22             string certPath = @"***";
    23             //证书秘钥
    24             string certPwd = "***";
    25             //商户号
    26             string mchid = "***";
    27             //证书编号
    28             string serialNo = "***";
    29             string boundary = string.Format("--{0}", DateTime.Now.Ticks.ToString("x"));
    30             var sha256 = Sha256(data);
    31             var meta = new
    32             {
    33                 sha256 = sha256,
    34                 filename = Guid.NewGuid().ToString().Replace("-", "") + ".png"
    35             };
    36             var json = JsonConvert.SerializeObject(meta);
    37             var httpHandler = new HttpHandler(mchid, serialNo, certPath, certPwd, json);
    38             HttpClient client = new HttpClient(httpHandler);
    39             using (var content = new MultipartFormDataContent(boundary))
    40             {
    41                 content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data"); //这里必须添加
    42                 content.Add(new StringContent(json, Encoding.UTF8, "application/json"), ""meta""); //这里主要必须要双引号
    43 
    44                 var byteArrayContent = new ByteArrayContent(data);
    45                 byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");
    46                 content.Add(byteArrayContent, ""file"", """ + meta.filename + """);  //这里主要必须要双引号
    47                 try
    48                 {
    49                     using (var response = client.PostAsync("https://api.mch.weixin.qq.com/v3/merchant/media/upload", content)) //上传
    50                     using (var responseContent = response.Result.Content)
    51                     {
    52                         string responseBody = responseContent.ReadAsStringAsync().Result;
    53                         var dic = Newtonsoft.Json.Linq.JObject.Parse(responseBody);
    54                         return dic["media_id"].ToString();
    55                     }
    56                 }
    57                 catch (Exception e)
    58                 {
    59                     return null;
    60                 }
    61 
    62 
    63             }
    64         }
    65 
    66         public static string Sha256(byte[] bytes)
    67         {
    68             byte[] hash = SHA256Managed.Create().ComputeHash(bytes);
    69             StringBuilder builder = new StringBuilder();
    70             for (int i = 0; i < hash.Length; i++)
    71             {
    72                 builder.Append(hash[i].ToString("X2"));
    73             }
    74             return builder.ToString();
    75         }
    76 
    77     }
    78 }

    2、Lib.HttpHandler代码

      1 using System;
      2 using System.Collections.Generic;
      3 using System.IO;
      4 using System.Net.Http;
      5 using System.Net.Http.Headers;
      6 using System.Security.Authentication;
      7 using System.Security.Cryptography;
      8 using System.Security.Cryptography.X509Certificates;
      9 using System.Text;
     10 using System.Threading;
     11 using System.Threading.Tasks;
     12 
     13 namespace Lib
     14 {
     15     /// <summary>
     16     /// 头文件
     17     /// </summary>
     18     public class HttpHandler : DelegatingHandler
     19     {
     20         private readonly string merchantId;
     21         private readonly string serialNo;
     22         private readonly string certPath;
     23         private readonly string certPwd;
     24         private readonly string json;
     25         /// <summary>
     26         /// 构造方法
     27         /// </summary>
     28         /// <param name="merchantId">商户号</param>
     29         /// <param name="merchantSerialNo">证书序列号</param>
     30         /// <param name="certPath">证书路径</param>
     31         /// <param name="certPwd">证书秘钥</param>
     32         /// <param name="json">签名json数据,默认不需要传入,获取body内容,如传入签名传入参数上传图片时需传入</param>
     33         public HttpHandler(string merchantId, string merchantSerialNo, string certPath, string certPwd, string json = "")
     34         {
     35 
     36             HttpClientHandler handler = new HttpClientHandler();
     37             handler.ClientCertificateOptions = ClientCertificateOption.Manual;
     38             handler.SslProtocols = SslProtocols.Tls12;
     39             try
     40             {
     41                 handler.ClientCertificates.Add(new X509Certificate2(certPath, certPwd,
     42                     X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet));
     43             }
     44             catch (Exception e)
     45             {
     46                 throw new Exception("ca err(证书错误)");
     47             }
     48             handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
     49             handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
     50             InnerHandler = handler;
     51             this.merchantId = merchantId;
     52             this.serialNo = merchantSerialNo;
     53             this.certPath = certPath;
     54             this.certPwd = certPwd;
     55             this.json = json;
     56         }
     57 
     58         protected async override Task<HttpResponseMessage> SendAsync(
     59             HttpRequestMessage request,
     60             CancellationToken cancellationToken)
     61         {
     62             var auth = await BuildAuthAsync(request);
     63             string value = $"WECHATPAY2-SHA256-RSA2048 {auth}";
     64             request.Headers.Add("Authorization", value);
     65             request.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36");
     66             MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeader = new MediaTypeWithQualityHeaderValue("application/json");
     67             request.Headers.Accept.Add(mediaTypeWithQualityHeader);
     68             request.Headers.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8"));
     69             return await base.SendAsync(request, cancellationToken);
     70         }
     71 
     72         protected async Task<string> BuildAuthAsync(HttpRequestMessage request)
     73         {
     74             string method = request.Method.ToString();
     75             string body = "";
     76             if (method == "POST" || method == "PUT" || method == "PATCH")
     77             {
     78                 if (!string.IsNullOrEmpty(json))
     79                     body = json;
     80                 else
     81                 {
     82                     var content = request.Content;
     83                     body = await content.ReadAsStringAsync();
     84                 }
     85             }
     86             string uri = request.RequestUri.PathAndQuery;
     87             var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
     88             string nonce = Guid.NewGuid().ToString("n");
     89             string message = $"{method}
    {uri}
    {timestamp}
    {nonce}
    {body}
    ";
     90 
     91             string signature = Sign(message);
     92             return $"mchid="{merchantId}",nonce_str="{nonce}",timestamp="{timestamp}",serial_no="{serialNo}",signature="{signature}"";
     93         }
     94 
     95         //SHA256withRSA
     96         public string Sign(string str)
     97         {
     98             byte[] bt = Encoding.GetEncoding("utf-8").GetBytes(str);
     99             var sha256 = new SHA256CryptoServiceProvider();
    100             byte[] rgbHash = sha256.ComputeHash(bt);
    101 
    102             try
    103             {
    104                 var rsa = GetPrivateKey();
    105                 var key = new RSACryptoServiceProvider();
    106                 var paras = rsa.ExportParameters(true);
    107                 key.ImportParameters(paras);
    108                 RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
    109                 formatter.SetHashAlgorithm("SHA256");
    110                 byte[] inArray = formatter.CreateSignature(rgbHash);
    111                 return Convert.ToBase64String(inArray);
    112             }
    113             catch (Exception e)
    114             {
    115                 return e.Message;
    116             }
    117         }
    118 
    119         private RSACryptoServiceProvider GetPrivateKey()
    120         {
    121             var pc = new X509Certificate2(certPath, certPwd, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
    122             return (RSACryptoServiceProvider)pc.PrivateKey;
    123         }
    124 
    125     }
    126 }

    仅此记录一下

  • 相关阅读:
    01pxc集群的部署
    Python简单爬虫获取岗位招聘人数
    nginx跨域问题记录
    自动备份远程mongodb数据库并拉取到本地
    ftp和mysql数据库结合使用
    flask蓝图的简单使用
    apache无法启动报错No space left on device
    简单的接口测试类和测试生成报告工具HTMLTestRunner.py
    简单python接口测试编写和django开发环境的搭建
    Fiddler模拟自动响应数据
  • 原文地址:https://www.cnblogs.com/grax/p/13100764.html
Copyright © 2020-2023  润新知