需求
定时任务:每天统计昨天的公司支付宝账户实际收益(扣除手续费)。
流程
1 、调用支付宝接口, 获取zip 下载地址2 、下载AopSdk.dll3 、代码public void downloadAllBillAlypay()
{
//1、支付宝下载地址
IAopClient client = new DefaultAopClient("https://openapi.alipay.com/gateway.do", Newalipayconfig.app_id, Newalipayconfig.private_key, "json", "1.0", "RSA2", Newalipayconfig.alipay_public_key, Newalipayconfig.charset, false);
AlipayDataDataserviceBillDownloadurlQueryrequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();
request.BizContent = "{"
"\"bill_type\":\"trade\","
"\"bill_date\":\"2020-04-20\""
" }";
AlipayDataDataserviceBillDownloadurlQueryResponse response = client.Execute(request);
//2、支付宝下载到本地
string url = System.AppDomain.CurrentDomain.BaseDirectory "zfb.zip";
string Jxurl = System.AppDomain.CurrentDomain.BaseDirectory "zfb\\";
FileDownHelper File = new FileDownHelper();
bool flag = file.Download(response.BillDownloadUrl, url);
//3、下载之后解压文件
bool f = FileDownHelper.Decompression(url, Jxurl, true);
//4、获取.CSV文件里面的数据转json
//文件全路径 文件名
string name = GetPathByFile1(Jxurl);
//文件名
//string filename = GetPathByFile2("D:\\abc\\");
//转json
string json = Common.DownloadFile(name);
DataTable dt = JsonHelper.FromJson<DataTable>(json);
//dt就是支付宝账单数据,保存到本地数据库中
}
工具类代码
using Ionic.ZIP;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
namespace SysFrameWeb.example
{
/// <summary>
/// 文件下载类
/// </summary>
public class FileDownHelper
{
/// <summary>
/// Http方式下载文件
/// </summary>
/// <param name="url">http地址</param>
/// <param name="localfile">本地文件</param>
/// <returns></returns>
public bool Download(string url, string localfile)
{
bool flag = false;
long startPosition = 0; // 上次下载的文件起始位置
FileStream writeStream; // 写入本地文件流对象
// 判断要下载的文件夹是否存在
if (File.Exists(localfile))
{
writeStream = File.OpenWrite(localfile); // 存在则打开要下载的文件
startPosition = writeStream.Length; // 获取已经下载的长度
writeStream.Seek(startPosition, SeekOrigin.Current); // 本地文件写入位置定位
}
else
{
writeStream = new FileStream(localfile, FileMode.Create);// 文件不保存创建一个文件
startPosition = 0;
}
try
{
HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(url);// 打开网络连接
if (startPosition > 0)
{
myRequest.AddRange((int)startPosition);// 设置Range值,与上面的writeStream.Seek用意相同,是为了定义远程文件读取位置
}
Stream readStream = myRequest.GetResponse().GetResponseStream();// 向服务器请求,获得服务器的回应数据流
byte[] btArray = new byte[512];// 定义一个字节数据,用来向readStream读取内容和向writeStream写入内容
int contentSize = readStream.Read(btArray, 0, btArray.Length);// 向远程文件读第一次
while (contentSize > 0)// 如果读取长度大于零则继续读
{
writeStream.Write(btArray, 0, contentSize);// 写入本地文件
contentSize = readStream.Read(btArray, 0, btArray.Length);// 继续向远程文件读取
}
//关闭流
writeStream.Close();
readStream.Close();
flag = true; //返回true下载成功
}
catch (Exception)
{
writeStream.Close();
flag = false; //返回false下载失败
}
return flag;
}
/// <summary>
/// 解压RAR和ZIP文件(需存在Winrar.exe(只要自己电脑上可以解压或压缩文件就存在Winrar.exe))
/// </summary>
/// <param name="UnPath">解压后文件保存目录</param>
/// <param name="rarPathName">待解压文件存放绝对路径(包括文件名称)</param>
/// <param name="IsCover">所解压的文件是否会覆盖已存在的文件(如果不覆盖,所解压出的文件和已存在的相同名称文件不会共同存在,只保留原已存在文件)</param>
/// <param name="PassWord">解压密码(如果不需要密码则为空)</param>
/// <returns>true(解压成功);false(解压失败)</returns>
public static bool UnRarOrZip(string UnPath, string rarPathName, bool IsCover, string PassWord)
{
if (!Directory.Exists(UnPath))
Directory.CreateDirectory(UnPath);
Process Process1 = new Process();
Process1.StartInfo.FileName = "Winrar.exe";
Process1.StartInfo.CreateNoWindow = true;
string cmd = "";
if (!string.IsNullOrEmpty(PassWord) && IsCover)
//解压加密文件且覆盖已存在文件( -p密码 )
cmd = string.Format(" x -p{0} -o {1} {2} -y", PassWord, rarPathName, UnPath);
else if (!string.IsNullOrEmpty(PassWord) && !IsCover)
//解压加密文件且不覆盖已存在文件( -p密码 )
cmd = string.Format(" x -p{0} -o- {1} {2} -y", PassWord, rarPathName, UnPath);
else if (IsCover)
//覆盖命令( x -o 代表覆盖已存在的文件)
cmd = string.Format(" x -o {0} {1} -y", rarPathName, UnPath);
else
//不覆盖命令( x -o- 代表不覆盖已存在的文件)
cmd = string.Format(" x -o- {0} {1} -y", rarPathName, UnPath);
//命令
Process1.StartInfo.Arguments = cmd;
Process1.Start();
Process1.WaitForExit();//无限期等待进程 winrar.exe 退出
//Process1.ExitCode==0指正常执行,Process1.ExitCode==1则指不正常执行
if (Process1.ExitCode == 0)
{
Process1.Close();
return true;
}
else
{
Process1.Close();
return false;
}
}
/// <summary>
/// 压缩文件成RAR或ZIP文件(需存在Winrar.exe(只要自己电脑上可以解压或压缩文件就存在Winrar.exe))
/// </summary>
/// <param name="filesPath">将要压缩的文件夹或文件的绝对路径</param>
/// <param name="rarPathName">压缩后的压缩文件保存绝对路径(包括文件名称)</param>
/// <param name="IsCover">所压缩文件是否会覆盖已有的压缩文件(如果不覆盖,所压缩文件和已存在的相同名称的压缩文件不会共同存在,只保留原已存在压缩文件)</param>
/// <param name="PassWord">压缩密码(如果不需要密码则为空)</param>
/// <returns>true(压缩成功);false(压缩失败)</returns>
public static bool CondenseRarOrZip(string filesPath, string rarPathName, bool IsCover, string PassWord)
{
string rarPath = Path.GetDirectoryName(rarPathName);
if (!Directory.Exists(rarPath))
Directory.CreateDirectory(rarPath);
Process Process1 = new Process();
Process1.StartInfo.FileName = "Winrar.exe";
Process1.StartInfo.CreateNoWindow = true;
string cmd = "";
if (!string.IsNullOrEmpty(PassWord) && IsCover)
//压缩加密文件且覆盖已存在压缩文件( -p密码 -o 覆盖 )
cmd = string.Format(" a -ep1 -p{0} -o {1} {2} -r", PassWord, rarPathName, filesPath);
else if (!string.IsNullOrEmpty(PassWord) && !IsCover)
//压缩加密文件且不覆盖已存在压缩文件( -p密码 -o-不覆盖 )
cmd = string.Format(" a -ep1 -p{0} -o- {1} {2} -r", PassWord, rarPathName, filesPath);
else if (string.IsNullOrEmpty(PassWord) && IsCover)
//压缩且覆盖已存在压缩文件( -o 覆盖 )
cmd = string.Format(" a -ep1 -o {0} {1} -r", rarPathName, filesPath);
else
//压缩且不覆盖已存在压缩文件( -o-不覆盖 )
cmd = string.Format(" a -ep1 -o- {0} {1} -r", rarPathName, filesPath);
//命令
Process1.StartInfo.Arguments = cmd;
Process1.Start();
Process1.WaitForExit();//无限期等待进程 winrar.exe 退出
//Process1.ExitCode==0指正常执行,Process1.ExitCode==1则指不正常执行
if (Process1.ExitCode == 0)
{
Process1.Close();
return true;
}
else
{
Process1.Close();
return false;
}
}
/// <summary>
/// 解压Zip文件
/// </summary>
/// <param name="strZipPath">待解压的ZIP文件</param>
/// <param name="strUnZipPath">解压的目录</param>
/// <param name="overWrite">是否覆盖</param>
/// <returns>成功:true/失败:false</returns>
public static bool Decompression(string strZipPath, string strUnZipPath, bool overWrite)
{
try
{
ReadOptions options = new ReadOptions();
options.Encoding = encoding.Default;//设置编码,解决解压文件时中文乱码
using (ZipFile zip = ZipFile.Read(strZipPath, options))
{
foreach (ZipEntry entry in zip)
{
if (string.IsNullOrEmpty(strUnZipPath))
{
strUnZipPath = strZipPath.Split('.').First();
}
if (overWrite)
{
entry.Extract(strUnZipPath, ExtractExistingFileAction.OverwriteSilently);//解压文件,如果已存在就覆盖
}
else
{
entry.Extract(strUnZipPath, ExtractExistingFileAction.DoNotOverwrite);//解压文件,如果已存在不覆盖
}
}
return true;
}
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// 将DataTable中数据写入到CSV文件中
/// </summary>
/// <param name="dt">提供保存数据的DataTable</param>
/// <param name="fileName">CSV的文件路径</param>
public static void SaveCSV(DataTable dt, string fullPath)
{
FileInfo fi = new FileInfo(fullPath);
if (!fi.Directory.Exists)
{
fi.Directory.Create();
}
FileStream fs = new FileStream(fullPath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
//StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Default);
StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8);
string data = "";
//写出列名称
for (int i = 0; i < dt.Columns.Count; i )
{
data = dt.Columns[i].ColumnName.ToString();
if (i < dt.Columns.Count - 1)
{
data = ",";
}
}
sw.WriteLine(data);
//写出各行数据
for (int i = 0; i < dt.Rows.Count; i )
{
data = "";
for (int j = 0; j < dt.Columns.Count; j )
{
string str = dt.Rows[i][j].ToString();
str = str.Replace("\"", "\"\"");//替换英文冒号 英文冒号需要换成两个冒号
if (str.Contains(',') || str.Contains('"')
|| str.Contains('\r') || str.Contains('\n')) //含逗号 冒号 换行符的需要放到引号中
{
str = string.Format("\"{0}\"", str);
}
data = str;
if (j < dt.Columns.Count - 1)
{
data = ",";
}
}
sw.WriteLine(data);
}
sw.Close();
fs.Close();
//DialogResult result = MessageBox.Show("CSV文件保存成功!");
//if (result == DialogResult.OK)
//{
// System.Diagnostics.Process.Start("explorer.exe", Common.PATH_LANG);
//}
}
/// <summary>
/// 将CSV文件的数据读取到DataTable中
/// </summary>
/// <param name="fileName">CSV文件路径</param>
/// <returns>返回读取了CSV数据的DataTable</returns>
public static DataTable OpenCSV(string filePath)
{
Encoding encoding = Common.GetType(filePath); //Encoding.ASCII;//
DataTable dt = new DataTable();
FileStream fs = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
//StreamReader sr = new StreamReader(fs, Encoding.UTF8);
StreamReader sr = new StreamReader(fs, encoding);
//string fileContent = sr.ReadToEnd();
//encoding = sr.CurrentEncoding;
//记录每次读取的一行记录
string strLine = "";
//记录每行记录中的各字段内容
string[] aryLine = null;
string[] tableHead = null;
//标示列数
int columnCount = 0;
//标示是否是读取的第一行
bool IsFirst = true;
//逐行读取CSV中的数据
while ((strLine = sr.ReadLine()) != null)
{
//strLine = Common.ConvertStringUTF8(strLine, encoding);
//strLine = Common.ConvertStringUTF8(strLine);
if (IsFirst == true)
{
tableHead = strLine.Split(',');
IsFirst = false;
columnCount = tableHead.Length;
//创建列
for (int i = 0; i < columnCount; i )
{
DataColumn dc = new DataColumn(tableHead[i]);
dt.Columns.Add(dc);
}
}
else
{
aryLine = strLine.Split(',');
DataRow dr = dt.NewRow();
for (int j = 0; j < columnCount; j )
{
dr[j] = aryLine[j];
}
dt.Rows.Add(dr);
}
}
if (aryLine != null && aryLine.Length > 0)
{
dt.DefaultView.Sort = tableHead[0] " " "asc";
}
sr.Close();
fs.Close();
return dt;
}
}
public class Common
{
/// 给定文件的路径,读取文件的二进制数据,判断文件的编码类型
/// <param name="FILE_NAME">文件路径</param>
/// <returns>文件的编码类型</returns>
public static System.Text.Encoding GetType(string FILE_NAME)
{
System.IO.FileStream fs = new System.IO.FileStream(FILE_NAME, System.IO.FileMode.Open,
System.IO.FileAccess.Read);
System.Text.Encoding r = GetType(fs);
fs.Close();
return r;
}
/// 通过给定的文件流,判断文件的编码类型
/// <param name="fs">文件流</param>
/// <returns>文件的编码类型</returns>
public static System.Text.Encoding GetType(System.IO.FileStream fs)
{
byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 };
byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 };
byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //带BOM
System.Text.Encoding reVal = System.Text.Encoding.Default;
System.IO.BinaryReader r = new System.IO.BinaryReader(fs, System.Text.Encoding.Default);
int i;
int.TryParse(fs.Length.ToString(), out i);
byte[] ss = r.ReadBytes(i);
if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF))
{
reVal = System.Text.Encoding.UTF8;
}
else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00)
{
reVal = System.Text.Encoding.BigEndianUnicode;
}
else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41)
{
reVal = System.Text.Encoding.Unicode;
}
r.Close();
return reVal;
}
/// 判断是否是不带 BOM 的 UTF8 格式
/// <param name="data"></param>
/// <returns></returns>
private static bool IsUTF8Bytes(byte[] data)
{
int charByteCounter = 1; //计算当前正分析的字符应还有的字节数
byte curByte; //当前分析的字节.
for (int i = 0; i < data.Length; i )
{
curByte = data[i];
if (charByteCounter == 1)
{
if (curByte >= 0x80)
{
//判断当前
while (((curByte <<= 1) & 0x80) != 0)
{
charByteCounter ;
}
//标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X
if (charByteCounter == 1 || charByteCounter > 6)
{
return false;
}
}
}
else
{
//若是UTF-8 此时第一位必须为1
if ((curByte & 0xC0) != 0x80)
{
return false;
}
charByteCounter--;
}
}
if (charByteCounter > 1)
{
throw new Exception("非预期的byte格式");
}
return true;
}
/// <summary>
/// 从指定url下载csv数据,然后给文件根据下载时间命名,返回文件名
/// </summary>
/// <param name="directory">文件夹路径</param>
/// <param name="url">下载地址</param>
/// <returns>文件名称</returns>
public static string DownloadFile(string directory, string url)
{
try
{
string fileName = CreateFileName(url);
if (!Directory.Exists(directory))//判断指定路径下是否存在指定的文件夹或文件
{
Directory.CreateDirectory(directory);//创建路径下的文件夹
}
WebClient client = new WebClient();
client.DownloadFile(url, directory fileName);
string datajson=CsvRead(0, directory fileName);//读取excel表中数据
//另一种方法,将文件地址封装
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("DownExcellocation", directory fileName);
//csvRead(0, dic["DownExcellocation"]);
return fileName;
}
catch
{
return "";
}
}
public static string DownloadFile(string url)
{
string datajson = CsvRead(4, url);//读取excel表中数据
//另一种方法,将文件地址封装
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("DownExcellocation", url);
return datajson;
}
/// <summary>
/// 创建文件名称
/// </summary>
public static string CreateFileName(string url)
{
string fileName = "";
string fileExt = url.Substring(url.LastIndexOf(".")).Trim().ToLower();
//Random rnd = new Random();
//fileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") rnd.Next(10, 99).ToString() fileExt;//获取随机数
fileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") System.Guid.NewGuid().ToString().Replace("-", "") fileExt;
return fileName;
}
/// <summary>
/// 将Csv读入DataTable 及返回json数据
/// </summary>
/// <param name="filePath">csv文件路径</param>
/// <param name="n">表示第n行是字段title,第n 1行是记录开始</param>
/// <param name="k">可选参数表示最后K行不算记录默认0</param>
public static string CsvRead(int n, string filePath)
{
DataTable dt = new DataTable();
String csvSplitBy = "(?<=^|,)(\"(?:[^\"]|\"\")*\"|[^,]*)";
StreamReader reader = new StreamReader(filePath, System.Text.Encoding.Default, false);
int i = 0, m = 0;
reader.Peek();
int r = reader.Peek();
while (reader.Peek()-4 > 0)
{
m = m 1;
string str = reader.ReadLine();
if (m >= n 1)
{
if (m == n 1) //如果是字段行,则自动加入字段。
{
MatchCollection mcs = Regex.Matches(str, csvSplitBy);
foreach (Match mc in mcs)
{
dt.Columns.Add(mc.Value); //增加列标题
}
}
else
{
MatchCollection mcs = Regex.Matches(str, "(?<=^|,)(\"(?:[^\"]|\"\")*\"|[^,]*)");
i = 0;
System.Data.DataRow dr = dt.NewRow();
foreach (Match mc in mcs)
{
dr[i] = mc.Value;
i ;
}
dt.Rows.Add(dr); //DataTable 增加一行
}
}
}
// 去掉汇总的后四行数据
for (int t = 1; t <= 4; t )
{
dt.Rows.Remove(dt.Rows[dt.Rows.Count - 1]);
}
string excelJson = DataTableToJson(dt);
//Console.WriteLine(excelJson);
return excelJson;
}
/// <summary>
/// 将Csv读入DataTable 及返回json数据
/// </summary>
/// <param name="filePath">csv文件路径</param>
/// <param name="n">表示第n行是字段title,第n 1行是记录开始</param>
/// <param name="k">可选参数表示最后K行不算记录默认0</param>
public static DataTable CsvReadBydt(int n, string filePath)
{
DataTable dt = new DataTable();
String csvSplitBy = "(?<=^|,)(\"(?:[^\"]|\"\")*\"|[^,]*)";
StreamReader reader = new StreamReader(filePath, System.Text.Encoding.Default, false);
int i = 0, m = 0;
reader.Peek();
while (reader.Peek() > 0)
{
m = m 1;
string str = reader.ReadLine();
if (m >= n 1)
{
if (m == n 1) //如果是字段行,则自动加入字段。
{
MatchCollection mcs = Regex.Matches(str, csvSplitBy);
foreach (Match mc in mcs)
{
dt.Columns.Add(mc.Value); //增加列标题
}
}
else
{
MatchCollection mcs = Regex.Matches(str, "(?<=^|,)(\"(?:[^\"]|\"\")*\"|[^,]*)");
i = 0;
System.Data.DataRow dr = dt.NewRow();
foreach (Match mc in mcs)
{
dr[i] = mc.Value;
i ;
}
dt.Rows.Add(dr); //DataTable 增加一行
}
}
}
return dt;
}
#region 帮助类DataSet转换为Json
/// <summary>
/// DataSet转换为Json
/// </summary>
/// <param name="dataSet">DataSet对象</param>
/// <returns>Json字符串</returns>
public static string DataSetToJson(DataSet dataSet)
{
string jsonString = "{";
foreach (DataTable table in dataSet.Tables)
{
jsonString = "\"" table.TableName "\":" DataTableToJson(table) ",";
}
jsonString = jsonString.TrimEnd(',');
return jsonString "}";
}
#endregion
#region 帮助类Datatable转换为Json
/// <summary>
/// Datatable转换为Json
/// </summary>
/// <param name="table">Datatable对象</param>
/// <returns>Json字符串</returns>
public static string DataTableToJson(DataTable dt)
{
StringBuilder jsonString = new StringBuilder();
jsonString.Append("[");
DataRowCollection drc = dt.Rows;
for (int i = 0; i < drc.Count; i )
{
jsonString.Append("{");
for (int j = 0; j < dt.Columns.Count; j )
{
string strKey = dt.Columns[j].ColumnName;
string strValue = drc[i][j].ToString();
Type type = dt.Columns[j].DataType;
jsonString.Append("\"" strKey "\":");
strValue = StringFormat(strValue, type);
if (j < dt.Columns.Count - 1)
{
jsonString.Append(strValue ",");
}
else
{
jsonString.Append(strValue);
}
}
jsonString.Append("},");
}
jsonString.Remove(jsonString.Length - 1, 1);
jsonString.Append("]");
return jsonString.ToString();
}
#endregion
#region 帮助类格式化字符型、日期型、布尔型StringFormat
/// <summary>
/// 格式化字符型、日期型、布尔型
/// </summary>
/// <param name="str"></param>
/// <param name="type"></param>
/// <returns></returns>
private static string StringFormat(string str, Type type)
{
if (type == typeof(string))
{
str = String2Json(str);
str = "\"" str "\"";
}
else if (type == typeof(DateTime))
{
str = "\"" str "\"";
}
else if (type == typeof(bool))
{
str = str.ToLower();
}
else if (type != typeof(string) && string.IsNullOrEmpty(str))
{
str = "\"" str "\"";
}
return str;
}
#endregion
#region 过滤特殊字符String2Json(String s)
/// <summary>
/// 过滤特殊字符
/// </summary>
/// <param name="s">字符串</param>
/// <returns>json字符串</returns>
private static string String2Json(String s)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.Length; i )
{
char c = s.ToCharArray()[i];
switch (c)
{
case '\"':
sb.Append("\\\""); break;
case '\\':
sb.Append("\\\\"); break;
case '/':
sb.Append("\\/"); break;
case '\b':
sb.Append("\\b"); break;
case '\f':
sb.Append("\\f"); break;
case '\n':
sb.Append("\\n"); break;
case '\r':
sb.Append("\\r"); break;
case '\t':
sb.Append("\\t"); break;
default:
sb.Append(c); break;
}
}
return sb.ToString();
}
#endregion
}
}
其他一些需要的调用
如何获取文件夹下所有的文件名称?
//第一种方法
public string GetPathByFile1(string path)
{
string fileName = string.Empty;
var files = Directory.GetFiles(path, "*.csv");
foreach (var file in files)
{
if (!file.Contains("总汇"))
{
fileName = file;
}
}
return fileName;
}
//第二种方法
public string GetPathByFile2(string path)
{
string fileName = string.Empty;
DirectoryInfo folder = new DirectoryInfo(path);
foreach (FileInfo file in folder.GetFiles("*.csv"))
{
if (!file.Name.Contains("总汇"))
{
fileName = file.Name;
}
}
return fileName;
}
支付宝配置参数
public class Newalipayconfig
{
public Newalipayconfig()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
// 应用ID,您的APPID
public static string app_id = "appid";
// 支付宝网关
public static string gatewayUrl = "https://openapi.alipay.com/gateway.do";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static string alipay_public_key = "支付宝公钥";
// 商户私钥,您的原始格式RSA私钥
public static string private_key = "支付宝私钥";
// 签名方式
public static string sign_type = "RSA2";
// 编码格式
public static string charset = "UTF-8";
}