You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
5.7 KiB

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using Furion.RemoteRequest;
using System.Threading.Tasks;
using GDZZ.Application.Service.WXPay.Dto;
using System.Text.Json;
/// <summary>
///JsApiPay 的摘要说明
/// </summary>
public class JsApiPay : IHttpDispatchProxy
{
const string PrivateKey = "App_Data/cert/apiclient_key.pem";
public async Task<JsPay> WithDrawsToWx(string url, string appid, string mchid, string serialNo, string openID, string partnerTradeNo, int totalFee, string hostting)
{
SortedDictionary<string, object> dic = new SortedDictionary<string, object>();
dic.Add("appid", appid);
dic.Add("out_batch_no", partnerTradeNo);
dic.Add("batch_name", DateTime.Now.ToString("D") + "提现记录");
dic.Add("batch_remark", DateTime.Now.ToString("D") + "提现记录");
dic.Add("total_amount", totalFee);
dic.Add("total_num", 1);
List<object> list = new List<object>();
SortedDictionary<string, object> dic1 = new SortedDictionary<string, object>();
dic1.Add("out_detail_no", partnerTradeNo);
dic1.Add("transfer_amount", totalFee);
dic1.Add("transfer_remark", "提现记录");
dic1.Add("openid", openID);
list.Add(dic1);
dic.Add("transfer_detail_list", list);
return await WxV3PostJson(url, Newtonsoft.Json.JsonConvert.SerializeObject(dic), mchid, serialNo, hostting); ; ;
}
/// <summary>
/// V3版本请求接口
/// </summary>
/// <param name="url">微信的接口地址</param>
/// <param name="postData">post请求的数据json格式 </param>
/// <param name="privateKey">apiclient_key.pem中的内容不要-----BEGIN PRIVATE KEY----- -----END PRIVATE KEY-----</param>
/// <param name="mchId">发起请求的商户(包括直连商户、服务商或渠道商)的商户号 mchid</param>
/// <param name="serialNo">商户证书号</param>
/// <param name="hostting"></param>
/// <returns></returns>
public async Task<JsPay> WxV3PostJson(string url, string postData, string mchId, string serialNo, string hostting)
{
string Authorization = GetAuthorization(url, "POST", postData, mchId, serialNo, hostting);
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/json;charset=UTF-8";
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36";
request.Accept = "application/json";
request.Headers.Add("Authorization", Authorization);
byte[] byteData = System.Text.Encoding.UTF8.GetBytes(postData);
request.ContentLength = byteData.Length;
Stream writer;
try
{
writer = request.GetRequestStream();
}
catch (Exception e)
{
Console.Write("连接服务器失败!");
throw;
}
writer.Write(byteData, 0, byteData.Length);
writer.Close();
string responseString = "";
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException e)
{
response = e.Response as HttpWebResponse;
}
Stream resStream = response.GetResponseStream();
StreamReader reader = new StreamReader(resStream);
responseString = reader.ReadToEnd();
return JsonSerializer.Deserialize<JsPay>(responseString);
}
private string GetAuthorization(string url, string method, string jsonParame, string mchId, string serialNo, string hostting)
{
var uri = new Uri(url);
string urlPath = uri.PathAndQuery;
string nonce = Guid.NewGuid().ToString();
var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
//数据签名 HTTP请求方法\n接口地址的url\n请求时间戳\n请求随机串\n请求报文主体\n
method = string.IsNullOrEmpty(method) ? "" : method;
string message = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n", method, urlPath, timestamp, nonce, jsonParame);
string signTxt = Sign(message, hostting);
//Authorization和格式
string authorzationTxt = string.Format("WECHATPAY2-SHA256-RSA2048 mchid=\"{0}\",nonce_str=\"{1}\",timestamp=\"{2}\",serial_no=\"{3}\",signature=\"{4}\"",
mchId,
nonce,
timestamp,
serialNo,
signTxt
);
return authorzationTxt;
}
private string Sign(string message, string hostting)
{
string base64X509Cert = "";
string pemPublicCert = Path.Combine(hostting, PrivateKey);
using (FileStream fs = new FileStream(pemPublicCert, FileMode.Open, FileAccess.Read))
{
using (StreamReader sr = new StreamReader(fs))
{
base64X509Cert = sr.ReadToEnd().Trim();
}
}
base64X509Cert = base64X509Cert.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "");
// NOTE 私钥不包括私钥文件起始的-----BEGIN PRIVATE KEY-----
// 亦不包括结尾的-----END PRIVATE KEY-----
byte[] keyData = Convert.FromBase64String(base64X509Cert);
var rsa = RSA.Create();
rsa.ImportPkcs8PrivateKey(keyData, out _);
byte[] data = System.Text.Encoding.UTF8.GetBytes(message);
var sigdata = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
var res = Convert.ToBase64String(sigdata);
return res;
}
}