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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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