public class ShangJiaPayChange
{
public static string partner_trade_no { get; set; }
public static string openId { get; set; }
public static int amount { get; set; }
public static string desc { get; set; }
public static int guestType { get; set; }
public static string AppId { get; set; }
public static string mchid { get; set; }
public static string serialNo { get; set; }
public static string CerPath { get; set; }
public static string QuaryMoneyDetail()
{
string url = "https://api.mch.weixin.qq.com/v3/transfer/batches/out-batch-no/"+partner_trade_no+ "?need_query_detail=True&detail_status=ALL";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
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, "GET", string.Empty, mchid, serialNo);
request.Headers.Add("Authorization", Authorization);
LogHelper.Info("返回申请商户转账到零钱结果", url);
//byte[] paramJsonBytes;
//paramJsonBytes = System.Text.Encoding.UTF8.GetBytes(postData);
//request.ContentLength = paramJsonBytes.Length;
string reslut = "";
HttpWebResponse wbResponse = (HttpWebResponse)request.GetResponse();
using (Stream responseStream = wbResponse.GetResponseStream())
{
using (StreamReader sReader = new StreamReader(responseStream))
{
reslut = sReader.ReadToEnd();
}
}
return reslut;
}
public static string WithDrawsToWx()
{
//string partnerTradeNo = "xcx" + DateTime.Now.ToString("yyyyMMddHHmmfff");
SortedDictionary<string, object> dic = new SortedDictionary<string, object>();
dic.Add("appid", AppId);
dic.Add("out_batch_no", partner_trade_no);
dic.Add("batch_name", DateTime.Now.ToString("D") + "提现记录");
dic.Add("batch_remark", DateTime.Now.ToString("D") + "提现记录");
dic.Add("total_amount", amount);
dic.Add("total_num", 1);
List<object> list = new List<object>();
SortedDictionary<string, object> dic1 = new SortedDictionary<string, object>();
dic1.Add("out_detail_no", partner_trade_no);
dic1.Add("transfer_amount", amount);
dic1.Add("transfer_remark", desc);
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;
}
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;
}
protected 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);
//Log.Info("返回签名:", signTxt);
//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;
}
//protected 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));
//}
protected static string Sign(string message)
{
//PASSWORD = "商户号"
X509Certificate2 cert = new X509Certificate2(CerPath, mchid, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
var privateKey = cert.PrivateKey.ToXmlString(true);
var certSerialNo = cert.SerialNumber;
using (RSACryptoServiceProvider sha256 = new RSACryptoServiceProvider())
{
byte[] dataInBytes = Encoding.UTF8.GetBytes(message);
sha256.FromXmlString(privateKey);
byte[] inArray = sha256.SignData(dataInBytes, CryptoConfig.MapNameToOID("SHA256"));
string sign = Convert.ToBase64String(inArray);
return sign;
}
}
}
注意,查询的时候,https://api.mch.weixin.qq.com/v3/transfer/batches/out-batch-no/"+partner_trade_no+ "?need_query_detail=True&detail_status=ALL这个True,需要大写,我第一次的时候只有need_query_detail这一个参数,总是提示参数不正确,后来加上detail_status之后,好像就行了,大家注意一下!!!!
后续遇到一些加密的问题,或者Header缺少的问题可以访问:转账金额大于2000的问题