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.

141 lines
5.4 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.Web;
using System.Runtime.Serialization;
using System.IO;
using System.Text;
using System.Net;
using Furion.Logging;
using SqlSugar;
using Enyim.Caching;
using System.Security.Cryptography;
/// <summary>
///JsApiPay 的摘要说明
/// </summary>
public static class JsApiPay
{
public static string WithDrawsToWx(string appid, string mchid, string serialNo, string openID, string partnerTradeNo, decimal totalFee)
{
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);
var url = "https://api.mch.weixin.qq.com/v3/transfer/batches";
string transactionsResponse = WxV3PostJson(url, Newtonsoft.Json.JsonConvert.SerializeObject(dic), mchid, serialNo);
//Log.Info("商户转账到零钱返回:" , transactionsResponse);
return transactionsResponse; ;
}
/// <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="merchantId">发起请求的商户(包括直连商户、服务商或渠道商)的商户号 mchid</param>
/// <param name="serialNo">商户证书号</param>
/// <param name="method"></param>
/// <returns></returns>
public static string WxV3PostJson(string url, string postData, string mchId, string serialNo)
{
HttpWebRequest 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";
//Log.Info("发起开始申请商户转账到零钱请求", "发起请求1");
string Authorization = GetAuthorization(url, "POST", postData, mchId, serialNo);
request.Headers.Add("Authorization", Authorization);
//Log.Info("返回申请商户转账到零钱结果", Authorization);
byte[] paramJsonBytes;
paramJsonBytes = System.Text.Encoding.UTF8.GetBytes(postData);
request.ContentLength = paramJsonBytes.Length;
Stream writer;
try
{
writer = request.GetRequestStream();
}
catch (Exception)
{
writer = null;
Console.Write("连接服务器失败!");
}
writer.Write(paramJsonBytes, 0, paramJsonBytes.Length);
writer.Close();
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
response = ex.Response as HttpWebResponse;
}
Stream resStream = response.GetResponseStream();
StreamReader reader = new StreamReader(resStream);
string text = reader.ReadToEnd();
return text;
}
private static string GetAuthorization(string url, string method, string jsonParame, string mchId, string serialNo)
{
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);
//Log.Info("请求message", message);
//string signTxt = Sign(message, privateKey);
string signTxt = Sign(message);
//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 static string Sign(string message)
{
// NOTE 私钥不包括私钥文件起始的-----BEGIN PRIVATE KEY-----
// 亦不包括结尾的-----END PRIVATE KEY-----
string privateKey = "{你的私钥}";
byte[] keyData = Convert.FromBase64String(privateKey);
var rsa = RSA.Create();
rsa.ImportPkcs8PrivateKey(keyData, out _);
byte[] data = System.Text.Encoding.UTF8.GetBytes(message);
return Convert.ToBase64String(rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));
}
}