支付宝(3)创建支付宝需要调用的类库
类库名称:FaceToFacePayment
(未经允许!不得转载!转载也行!请加链接!)
类1:NewClass (界面调用该类)
using Aop.Api; using Com.Alipay; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using AlipayAccountInformation; using System.Drawing; using ZXing; using Aop.Api.Response; using Aop.Api.Request; using System.Threading; namespace AlipayRelevant { public class NewClass { private LogHelper log = new LogHelper(AppDomain.CurrentDomain.BaseDirectory + "/log/log.txt"); public IAopClient client = new DefaultAopClient(Account.serverUrl, Account.appId, Account.merchant_private_key, "", Account.version, Account.sign_type, Account.alipay_public_key, Account.charset); /// <summary> /// 生成二维码 /// </summary> /// <param name="msg">二维码信息</param> /// <returns>图片</returns> public Bitmap GenByZXingNet(string msg) { BarcodeWriter writer = new BarcodeWriter(); writer.Format = BarcodeFormat.QR_CODE; writer.Options.Hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8");//编码问题 writer.Options.Hints.Add( EncodeHintType.ERROR_CORRECTION, ZXing.QrCode.Internal.ErrorCorrectionLevel.H ); const int codeSizeInPixels = 250; //设置图片长宽 writer.Options.Height = writer.Options.Width = codeSizeInPixels; writer.Options.Margin = 0;//设置边框 ZXing.Common.BitMatrix bm = writer.Encode(msg); Bitmap img = writer.Write(bm); return img; } public Aop.Api.Response.AlipayTradePayResponse Pay(string biz_content) { AlipayTradePayRequest payRequst = new Aop.Api.Request.AlipayTradePayRequest(); payRequst.BizContent = biz_content; Dictionary<string, string> paramsDict = (Dictionary<string, string>)payRequst.GetParameters(); //new DefaultAopClient(Config.serverUrl, Config.appId, Config.merchant_private_key); Aop.Api.Response.AlipayTradePayResponse payResponse = client.Execute(payRequst); return payResponse; } public AlipayTradePrecreateResponse Prepay(string biz_content) { AlipayTradePrecreateRequest payRequst = new AlipayTradePrecreateRequest(); payRequst.BizContent = biz_content; //需要异步通知的时候,需要是指接收异步通知的地址。 payRequst.SetNotifyUrl("http://10.5.21.14/notify_url.aspx"); Dictionary<string, string> paramsDict = (Dictionary<string, string>)payRequst.GetParameters(); //new DefaultAopClient(Config.serverUrl, Config.appId, Config.merchant_private_key); AlipayTradePrecreateResponse payResponse = client.Execute(payRequst); return payResponse; } public AlipayTradeCancelResponse Cancel(string biz_content) { AlipayTradeCancelRequest cancelRequest = new AlipayTradeCancelRequest(); cancelRequest.BizContent = biz_content; AlipayTradeCancelResponse cancelResponse = client.Execute(cancelRequest); if (null != cancelResponse) { if (cancelResponse.Code == ResultCode.FAIL && cancelResponse.RetryFlag == "Y") { //if (cancelResponse.Body.Contains("\"retry_flag\":\"Y\"")) //cancelOrderRetry(biz_content); // 新开一个线程重试撤销 ParameterizedThreadStart ParStart = new ParameterizedThreadStart(cancelOrderRetry); Thread myThread = new Thread(ParStart); object o = biz_content; myThread.Start(o); } } return cancelResponse; } public void cancelOrderRetry(object o) { int retryCount = 50; for (int i = 0; i < retryCount; ++i) { Thread.Sleep(10000); AlipayTradeCancelRequest cancelRequest = new AlipayTradeCancelRequest(); cancelRequest.BizContent = o.ToString(); // Dictionary<string, string> paramsDict = (Dictionary<string, string>)cancelRequest.GetParameters(); AlipayTradeCancelResponse cancelResponse = client.Execute(cancelRequest); if (null != cancelResponse) { if (cancelResponse.Code == ResultCode.FAIL) { //if (cancelResponse.Body.Contains("\"retry_flag\":\"N\"")) if (cancelResponse.RetryFlag == "N") { break; } } if ((cancelResponse.Code == ResultCode.SUCCESS)) { break; } } if (i == retryCount - 1) { // 处理到最后一次,还是未撤销成功,需要在商户数据库中对此单最标记,人工介入处理 } } } public AlipayTradeQueryResponse LoopQuery(string biz_content) { AlipayTradeQueryRequest payRequst = new AlipayTradeQueryRequest(); payRequst.BizContent = biz_content; Dictionary<string, string> paramsDict = (Dictionary<string, string>)payRequst.GetParameters(); AlipayTradeQueryResponse payResponse = null; for (int i = 1; i <= 6; i++) { //Thread.Sleep(5000); payResponse = client.Execute(payRequst); if (string.Compare(payResponse.Code, ResultCode.SUCCESS, false) == 0) { if (payResponse.TradeStatus == "TRADE_FINISHED" || payResponse.TradeStatus == "TRADE_SUCCESS" || payResponse.TradeStatus == "TRADE_CLOSED") break; } } //----------------------------------------------------------------------------------------------------- //---------------------------------执行以下代码就退款了..-------------------- //StringBuilder sb1 = new StringBuilder(); //sb1.Append("{\"out_trade_no\":\"" + payResponse.OutTradeNo + "\"}"); //biz_content = sb1.ToString(); //Cancel(biz_content); return payResponse; } } }
创建类:AlipayCore
using System.Web; using System.Text; using System.Security.Cryptography; using System.IO; using System.Net; using System; using System.Collections.Generic; using System.Xml; namespace Com.Alipay { /// <summary> /// 类名:Core /// 功能:支付宝接口公用函数类 /// 详细:该类是请求、通知返回两个文件所调用的公用函数核心处理文件,不需要修改 /// 版本:3.4 /// 修改日期:2015-06-05 /// 说明: /// 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。 /// 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。 /// </summary> public class Core { public Core() { } /// <summary> /// 除去数组中的空值和签名参数并以字母a到z的顺序排序 /// </summary> /// <param name="dicArrayPre">过滤前的参数组</param> /// <returns>过滤后的参数组</returns> public static Dictionary<string, string> FilterPara(SortedDictionary<string, string> dicArrayPre) { Dictionary<string, string> dicArray = new Dictionary<string, string>(); foreach (KeyValuePair<string, string> temp in dicArrayPre) { if (temp.Key.ToLower() != "sign" && temp.Key.ToLower()!="sign_type" && temp.Value != "" && temp.Value != null) { dicArray.Add(temp.Key, temp.Value); } } return dicArray; } /// <summary> /// 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串 /// </summary> /// <param name="sArray">需要拼接的数组</param> /// <returns>拼接完成以后的字符串</returns> public static string CreateLinkString(Dictionary<string, string> dicArray) { StringBuilder prestr = new StringBuilder(); foreach (KeyValuePair<string, string> temp in dicArray) { prestr.Append(temp.Key + "=" + temp.Value + "&"); } //去掉最後一個&字符 int nLen = prestr.Length; prestr.Remove(nLen-1,1); return prestr.ToString(); } /// <summary> /// 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对参数值做urlencode /// </summary> /// <param name="sArray">需要拼接的数组</param> /// <param name="code">字符编码</param> /// <returns>拼接完成以后的字符串</returns> public static string CreateLinkStringUrlencode(Dictionary<string, string> dicArray, Encoding code) { StringBuilder prestr = new StringBuilder(); foreach (KeyValuePair<string, string> temp in dicArray) { prestr.Append(temp.Key + "=" + HttpUtility.UrlEncode(temp.Value, code) + "&"); } //去掉最後一個&字符 int nLen = prestr.Length; prestr.Remove(nLen - 1, 1); return prestr.ToString(); } /// <summary> /// 写日志,方便测试(看网站需求,也可以改成把记录存入数据库) /// </summary> /// <param name="sWord">要写入日志里的文本内容</param> public static void LogResult(string sWord) { string strPath = HttpContext.Current.Server.MapPath("log"); strPath = strPath + "\\" + DateTime.Now.ToString().Replace(":", "") + ".txt"; StreamWriter fs = new StreamWriter(strPath, false, System.Text.Encoding.Default); fs.Write(sWord); fs.Close(); } /// <summary> /// 获取文件的md5摘要 /// </summary> /// <param name="sFile">文件流</param> /// <returns>MD5摘要结果</returns> public static string GetAbstractToMD5(Stream sFile) { MD5 md5 = new MD5CryptoServiceProvider(); byte[] result = md5.ComputeHash(sFile); StringBuilder sb = new StringBuilder(32); for (int i = 0; i < result.Length; i++) { sb.Append(result[i].ToString("x").PadLeft(2, '0')); } return sb.ToString(); } /// <summary> /// 获取文件的md5摘要 /// </summary> /// <param name="dataFile">文件流</param> /// <returns>MD5摘要结果</returns> public static string GetAbstractToMD5(byte[] dataFile) { MD5 md5 = new MD5CryptoServiceProvider(); byte[] result = md5.ComputeHash(dataFile); StringBuilder sb = new StringBuilder(32); for (int i = 0; i < result.Length; i++) { sb.Append(result[i].ToString("x").PadLeft(2, '0')); } return sb.ToString(); } } }
创建类:Alipaynotify
using System.Web; using System.Text; using System.IO; using System.Net; using System; using System.Collections.Generic; using Aop.Api.Util; using AlipayAccountInformation; namespace Com.Alipay { /// <summary> /// 类名:Notify /// 功能:支付宝通知处理类 /// 详细:处理支付宝各接口通知返回 /// 版本:3.3 /// 修改日期:2011-07-05 /// '说明: /// 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。 /// 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。 /// /// //////////////////////注意///////////////////////////// /// 调试通知返回时,可查看或改写log日志的写入TXT里的数据,来检查通知返回是否正常 /// </summary> public class Notify { #region 字段 private string _partner = "2088802227086771 "; //合作身份者ID private string _key = "gtnavijplc13e5ta662gkmxmhm1rbtk1 "; //商户的私钥 private string _charset = "utf-8"; //编码格式 private string _sign_type = "MD5"; //签名方式 //支付宝消息验证地址 private string Https_veryfy_url = ""; #endregion /// <summary> /// 构造函数 /// 从配置文件中初始化变量 /// </summary> /// <param name="inputPara">通知返回参数数组</param> /// <param name="notify_id">通知验证ID</param> public Notify() { //初始化基础配置信息 _charset = Account.charset.Trim().ToLower(); _sign_type = Account.sign_type.Trim().ToUpper(); _partner = Account.pid; Https_veryfy_url = Account.mapiUrl + "?service=notify_verify&"; } /// <summary> /// 验证消息是否是支付宝发出的合法消息 /// </summary> /// <param name="inputPara">通知返回参数数组</param> /// <param name="notify_id">通知验证ID</param> /// <param name="sign">支付宝生成的签名结果</param> /// <returns>验证结果</returns> public bool Verify(SortedDictionary<string, string> inputPara, string notify_id, string sign) { //获取返回时的签名验证结果 bool isSign = GetSignVeryfy(inputPara, sign); //获取是否是支付宝服务器发来的请求的验证结果 string responseTxt = "true"; if (notify_id != null && notify_id != "") { responseTxt = GetResponseTxt(notify_id); } //写日志记录(若要调试,请取消下面两行注释) //string sWord = "responseTxt=" + responseTxt + "\n isSign=" + isSign.ToString() + "\n 返回回来的参数:" + GetPreSignStr(inputPara) + "\n "; //Core.LogResult(sWord); //判断responsetTxt是否为true,isSign是否为true //responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关 //isSign不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关 if (responseTxt == "true" && isSign)//验证成功 { return true; } else//验证失败 { return false; } } /// <summary> /// 获取待签名字符串(调试用) /// </summary> /// <param name="inputPara">通知返回参数数组</param> /// <returns>待签名字符串</returns> private string GetPreSignStr(SortedDictionary<string, string> inputPara) { Dictionary<string, string> sPara = new Dictionary<string, string>(); //过滤空值、sign与sign_type参数 sPara = Core.FilterPara(inputPara); //获取待签名字符串 string preSignStr = Core.CreateLinkString(sPara); return preSignStr; } /// <summary> /// 获取返回时的签名验证结果 /// </summary> /// <param name="inputPara">通知返回参数数组</param> /// <param name="sign">对比的签名结果</param> /// <returns>签名验证结果</returns> private bool GetSignVeryfy(SortedDictionary<string, string> inputPara, string sign) { Dictionary<string, string> sPara = new Dictionary<string, string>(); //过滤空值、sign与sign_type参数 sPara = Core.FilterPara(inputPara); //获取待签名字符串 string preSignStr = Core.CreateLinkString(sPara); //获得签名验证结果 bool isSign = false; if (sign != null && sign != "") { switch (_sign_type) { //isSgin = AlipayMD5.Verify(preSignStr, sign, _key, charset); case "RSA": isSign = AlipaySignature.RSACheckContent(preSignStr, sign, Account.alipay_public_key, _charset); break; default: break; } } return isSign; } /// <summary> /// 获取是否是支付宝服务器发来的请求的验证结果 /// </summary> /// <param name="notify_id">通知验证ID</param> /// <returns>验证结果</returns> private string GetResponseTxt(string notify_id) { string veryfy_url = Https_veryfy_url + "partner=" + _partner + "¬ify_id=" + notify_id; //获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求 string responseTxt = Get_Http(veryfy_url, 120000); return responseTxt; } /// <summary> /// 获取远程服务器ATN结果 /// </summary> /// <param name="strUrl">指定URL路径地址</param> /// <param name="timeout">超时时间设置</param> /// <returns>服务器ATN结果</returns> private string Get_Http(string strUrl, int timeout) { string strResult; try { HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strUrl); myReq.Timeout = timeout; HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse(); Stream myStream = HttpWResp.GetResponseStream(); StreamReader sr = new StreamReader(myStream, Encoding.Default); StringBuilder strBuilder = new StringBuilder(); while (-1 != sr.Peek()) { strBuilder.Append(sr.ReadLine()); } strResult = strBuilder.ToString(); } catch (Exception exp) { strResult = "错误:" + exp.Message; } return strResult; } } }
创建类:LogHelper
using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Web; namespace Com.Alipay { /// <summary> /// LogHelper 的摘要说明 /// </summary> public class LogHelper { string logFile = ""; /// <summary> /// 不带参数的构造函数 /// </summary> public LogHelper() { } /// <summary> /// 带参数的构造函数 /// </summary> /// <param name="logFile"></param> public LogHelper(string logFile) { this.logFile = logFile; if (!File.Exists(logFile)) { FileStream fs = File.Create(logFile); fs.Close(); } } /// <summary> /// 追加一条信息 /// </summary> /// <param name="text"></param> public void Write(string text) { using (StreamWriter sw = new StreamWriter(logFile, true, Encoding.UTF8)) { sw.Write(DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss] ") + text); } } /// <summary> /// 追加一条信息 /// </summary> /// <param name="logFile"></param> /// <param name="text"></param> public void Write(string logFile, string text) { using (StreamWriter sw = new StreamWriter(logFile, true, Encoding.UTF8)) { sw.Write(DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss] ") + text); } } /// <summary> /// 追加一行信息 /// </summary> /// <param name="text"></param> public void WriteLine(string text) { text += "\r\n"; using (StreamWriter sw = new StreamWriter(logFile, true, Encoding.UTF8)) { sw.Write(DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss] ") + text); } } /// <summary> /// 追加一行信息 /// </summary> /// <param name="logFile"></param> /// <param name="text"></param> public void WriteLine(string logFile, string text) { text += "\r\n"; using (StreamWriter sw = new StreamWriter(logFile, true, Encoding.UTF8)) { sw.Write(DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss] ") + text); } } } }
创建类:PayResultEnum
using System; using System.Collections.Generic; //using System.Linq; using System.Web; namespace Com.Alipay { public class ResultCode { public const string SUCCESS = "10000"; public const string INRROCESS = "10003"; public const string FAIL = "40004"; } }
完成之后 引用之前创建的两个类库AlipayAccountInformation和AopSdk