微信支付特约商户进件中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 }

仅此记录一下

原文地址:https://www.cnblogs.com/grax/p/13100764.html