支付宝支付
对支付宝支付的二次封装,支持pc端和wap端支付
类图
pay(pc):
-
var orderNo = ""; //订单号
-
var subject = ""; //订单名称
-
var fee = 0.ToString("0.##"); //付款金额
-
var notifyUrl = "host/Alipay/NotifyUrl.aspx";
-
var returnUrl = "host/Alipay/ReturnUrl.aspx";
-
var show_url = "host";
-
var alipay = new Alipay.Submit();
-
alipay.Pay(orderNo, subject, fee, body, notify_url, return_url, show_url);
pay(wap):
var orderNo = ""; //订单号
var title = "在线捐赠(WAP):" + ""; //订单名称
var fee = 0.ToString("0.##"); //付款金额
var notifyUrl = "host/Alipay/NotifyUrl.aspx";
var returnUrl = "host/Alipay/ReturnUrl.aspx";
var show_url = "host";
var alipay = new Alipay.Submit();
alipay.Submit.Pay(orderNo, subject, fee, body, notify_url, return_url, show_url);
-
return(pc):
public partial class NotifyUrl : Alipay.NotifyPage
{
protected override void OnNotifyConfirm()
{
//todo:业务逻辑处理
}
}
public partial class NotifyUrl : Alipay.Wap.NotifyPage
{
protected override void OnNotifyConfirm()
{
//todo:业务逻辑处理
}
}
-
PC端的Submit.cs
using System.Text;
using System.IO;
using System.Net;
using System;
using System.Collections.Generic;
using System.Web;
using System.Xml;
namespace Alipay
{
/// <summary>
/// 支付宝各接口请求提交类
/// 构造支付宝各接口表单HTML文本,获取远程HTTP数据
/// </summary>
public class Submit
{
public Submit()
{
}
/// <summary>
/// 实例化
/// </summary>
/// <param name="partner">合作者身份ID</param>
/// <param name="key">交易安全校验码</param>
/// <param name="sellerMail">卖方(收款方)支付宝账户</param>
public Submit(string partner, string key, string sellerMail)
{
Config.Partner = partner;
Config.Key = key;
Config.SellerEmail = sellerMail;
}
/// <summary>
/// 提交支付请求,get
/// </summary>
/// <param name="orderNo">商户订单号</param>
/// <param name="fee">付款金额</param>
/// <param name="title">订单名称</param>
/// <param name="desc">订单描述</param>
/// <param name="notifyUrl">服务器异步通知页面路径</param>
/// <param name="returnUrl">页面跳转同步通知页面路径</param>
/// <param name="showUrl">商品展示地址</param>
public void Pay(string orderNo, string fee, string title, string desc, string notifyUrl,
string returnUrl, string showUrl)
{
var para = new SortedDictionary<string, string>
{
{"partner", Config.Partner},
{"_input_charset", Config._Charset.ToLower()},
{"service", Config._PayMode},
{"payment_type", Config._PayType},
{"notify_url", notifyUrl},
{"return_url", returnUrl},
{"seller_email", Config.SellerEmail},
{"out_trade_no", orderNo},
{"subject", title},
{"total_fee", fee},
{"body", desc},
{"show_url", showUrl},
{"anti_phishing_key", _GetDateTimeString()}
};
var dicPara = BuildRequestPara(para);
var sbHtml = new StringBuilder();
sbHtml.AppendFormat(
"<form id='alipaysubmit' name='alipaysubmit' action='{0}_input_charset={1}' method='get'>",
Config._GateWay, Config._Charset);
foreach (var temp in dicPara)
{
sbHtml.AppendFormat("<input type='hidden' name='{0}' value='{1}'/>", temp.Key, temp.Value);
}
//submit按钮控件请不要含有name属性
sbHtml.Append("<input type='submit' value='支付' style='display:none;'></form>");
sbHtml.Append("<script>document.forms['alipaysubmit'].submit();</script>");
HttpContext.Current.Response.Write(sbHtml.ToString());
}
/// <summary>
/// 提交支付请求,post
/// </summary>
/// <param name="notifyUrl">服务器异步通知页面路径</param>
/// <param name="returnUrl">页面跳转同步通知页面路径</param>
/// <param name="sellerEmail">卖家支付宝帐户</param>
/// <param name="orderNo">商户订单号</param>
/// <param name="subject">订单名称</param>
/// <param name="fee">付款金额</param>
/// <param name="title">订单描述</param>
/// <param name="showUrl">商品展示地址</param>
public void PostPay(string notifyUrl, string returnUrl, string sellerEmail, string orderNo, string subject
, string fee, string title, string showUrl)
{
var para = new SortedDictionary<string, string>
{
{"partner", Config.Partner},
{"_input_charset", Config._Charset.ToLower()},
{"service", Config._PayMode},
{"payment_type", Config._PayType},
{"notify_url", notifyUrl},
{"return_url", returnUrl},
{"seller_email", sellerEmail},
{"out_trade_no", orderNo},
{"subject", subject},
{"total_fee", fee},
{"body", title},
{"show_url", showUrl},
{"anti_phishing_key", _GetDateTimeString()}
};
var encoding = Encoding.GetEncoding(Config._Charset);
var strRequestData = BuildRequestParaToString(para, encoding);
var bytesRequestData = encoding.GetBytes(strRequestData);
var strUrl = string.Format("{0}_input_charset={1}", Config._GateWay, Config._Charset);
string strResult;
try
{
var myReq = (HttpWebRequest)WebRequest.Create(strUrl);
myReq.Method = "post";
myReq.ContentType = "application/x-www-form-urlencoded";
myReq.ContentLength = bytesRequestData.Length;
var requestStream = myReq.GetRequestStream();
requestStream.Write(bytesRequestData, 0, bytesRequestData.Length);
requestStream.Close();
var HttpWResp = (HttpWebResponse)myReq.GetResponse();
var myStream = HttpWResp.GetResponseStream();
var reader = new StreamReader(myStream, encoding);
var responseData = new StringBuilder();
string line;
while ((line = reader.ReadLine()) != null)
{
responseData.Append(line);
}
myStream.Close();
strResult = responseData.ToString();
}
catch (Exception ex)
{
strResult = "报错:" + ex.Message;
}
HttpContext.Current.Response.Write(strResult);
}
/// <summary>
/// 生成请求时的签名
/// </summary>
internal string BuildRequestMysign(Dictionary<string, string> sPara)
{
return MD5.Sign(Core.CreateLinkString(sPara), Config.Key, Config._Charset);
}
/// <summary>
/// 生成要请求给支付宝的参数数组
/// </summary>
internal Dictionary<string, string> BuildRequestPara(SortedDictionary<string, string> sParaTemp)
{
var sPara = Core.FilterPara(sParaTemp);
var mysign = BuildRequestMysign(sPara);
sPara.Add("sign", mysign);
sPara.Add("sign_type", Config._SignType);
return sPara;
}
/// <summary>
/// 用于防钓鱼,调用接口query_timestamp来获取时间戳的处理函数
/// 注意:远程解析XML出错,与IIS服务器配置有关
/// </summary>
/// <returns>时间戳字符串</returns>
private string _GetDateTimeString()
{
var url = string.Format("{0}service=query_timestamp&partner={1}", Config._GateWay, Config.Partner);
var Reader = new XmlTextReader(url);
var xmlDoc = new XmlDocument();
xmlDoc.Load(Reader);
return xmlDoc.SelectSingleNode("/alipay/response/timestamp/encrypt_key").InnerText;
}
/// <summary>
/// 生成要请求给支付宝的参数数组
/// </summary>
internal string BuildRequestParaToString(SortedDictionary<string, string> sParaTemp, Encoding code)
{
return Core.CreateLinkStringUrlencode(BuildRequestPara(sParaTemp), code);
}
/*
/// <summary>
/// 建立请求,以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果,带文件上传功能
/// </summary>
/// <param name="sParaTemp">请求参数数组</param>
/// <param name="strMethod">提交方式。两个值可选:post、get</param>
/// <param name="fileName">文件绝对路径</param>
/// <param name="data">文件数据</param>
/// <param name="contentType">文件内容类型</param>
/// <param name="lengthFile">文件长度</param>
/// <returns>支付宝处理结果</returns>
internal static string BuildRequest(SortedDictionary<string, string> sParaTemp, string strMethod, string fileName, byte[] data, string contentType, int lengthFile)
{
//待请求参数数组
Dictionary<string, string> dicPara = new Dictionary<string, string>();
dicPara = BuildRequestPara(sParaTemp);
//构造请求地址
string strUrl = Config._GateWay + "_input_charset=" + Config._Charset;
//设置HttpWebRequest基本信息
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(strUrl);
//设置请求方式:get、post
request.Method = strMethod;
//设置boundaryValue
string boundaryValue = DateTime.Now.Ticks.ToString("x");
string boundary = "--" + boundaryValue;
request.ContentType = "\r\nmultipart/form-data; boundary=" + boundaryValue;
//设置KeepAlive
request.KeepAlive = true;
//设置请求数据,拼接成字符串
StringBuilder sbHtml = new StringBuilder();
foreach (KeyValuePair<string, string> key in dicPara)
{
sbHtml.Append(boundary + "\r\nContent-Disposition: form-data; name=\"" + key.Key + "\"\r\n\r\n" + key.Value + "\r\n");
}
sbHtml.Append(boundary + "\r\nContent-Disposition: form-data; name=\"withhold_file\"; filename=\"");
sbHtml.Append(fileName);
sbHtml.Append("\"\r\nContent-Type: " + contentType + "\r\n\r\n");
string postHeader = sbHtml.ToString();
//将请求数据字符串类型根据编码格式转换成字节流
Encoding code = Encoding.GetEncoding(Config._Charset);
byte[] postHeaderBytes = code.GetBytes(postHeader);
byte[] boundayBytes = Encoding.ASCII.GetBytes("\r\n" + boundary + "--\r\n");
//设置长度
long length = postHeaderBytes.Length + lengthFile + boundayBytes.Length;
request.ContentLength = length;
//请求远程HTTP
Stream requestStream = request.GetRequestStream();
Stream myStream;
try
{
//发送数据请求服务器
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
requestStream.Write(data, 0, lengthFile);
requestStream.Write(boundayBytes, 0, boundayBytes.Length);
HttpWebResponse HttpWResp = (HttpWebResponse)request.GetResponse();
myStream = HttpWResp.GetResponseStream();
}
catch (WebException e)
{
return e.ToString();
}
finally
{
if (requestStream != null)
{
requestStream.Close();
}
}
//读取支付宝返回处理结果
StreamReader reader = new StreamReader(myStream, code);
StringBuilder responseData = new StringBuilder();
String line;
while ((line = reader.ReadLine()) != null)
{
responseData.Append(line);
}
myStream.Close();
return responseData.ToString();
}
*/
}
}
wap端的Submit.cs
-
using System.Text;
-
using System.IO;
-
using System.Net;
-
using System;
-
using System.Collections.Generic;
-
using System.Web;
-
using System.Xml;
-
namespace Alipay.Wap
-
{
-
/// <summary>
-
/// 支付宝各接口请求提交类
-
/// 构造支付宝各接口表单HTML文本,获取远程HTTP数据
-
/// </summary>
-
public class Submit
-
{
-
public Submit()
-
{
-
}
-
/// <summary>
-
/// 实例化
-
/// </summary>
-
/// <param name="partner">合作者身份ID</param>
-
/// <param name="key">交易安全校验码</param>
-
/// <param name="sellerMail">卖方(收款方)支付宝账户</param>
-
public Submit(string partner, string key, string sellerMail)
-
{
-
Config.Partner = partner;
-
Config.Key = key;
-
Config.SellerEmail = sellerMail;
-
}
-
/// <summary>
-
/// 提交支付请求,get
-
/// </summary>
-
/// <param name="orderNo">商户订单号</param>
-
/// <param name="fee">付款金额</param>
-
/// <param name="title">订单名称</param>
-
/// <param name="desc">订单描述</param>
-
/// <param name="notifyUrl">服务器异步通知页面路径</param>
-
/// <param name="returnUrl">页面跳转同步通知页面路径</param>
-
/// <param name="showUrl">商品展示地址</param>
-
public void Pay(string orderNo, string fee, string title, string desc, string notifyUrl,
-
string returnUrl, string showUrl)
-
{
-
var req_id = DateTime.Now.ToString("yyyyMMddHHmmssfff"); //请求号,须保证每次请求都是唯一
-
const string format = "xml";
-
const string v = "2.0";
-
if (string.IsNullOrEmpty(fee)) fee = "0";
-
if (string.IsNullOrEmpty(title)) title = "在线捐赠(WAP)";
-
if (string.IsNullOrEmpty(orderNo)) orderNo = req_id;
-
var req_dataToken =
-
string.Format(
-
"<direct_trade_create_req><notify_url>{0}</notify_url><call_back_url>{1}</call_back_url><seller_account_name>{2}</seller_account_name><out_trade_no>{3}</out_trade_no><subject>{4}</subject><total_fee>{5}</total_fee><merchant_url>{6}</merchant_url></direct_trade_create_req>",
-
notifyUrl, returnUrl, Config.SellerEmail, orderNo, title, fee, showUrl);
-
//创建支付宝交易订单,并获取授权码token,alipay.wap.trade.create.direct
-
var sParaTempToken = new SortedDictionary<string, string>();
-
sParaTempToken.Add("partner", Config.Partner);
-
sParaTempToken.Add("_input_charset", Config._Charset.ToLower());
-
sParaTempToken.Add("sec_id", Config._SignType.ToUpper());
-
sParaTempToken.Add("service", "alipay.wap.trade.create.direct");
-
sParaTempToken.Add("format", format);
-
sParaTempToken.Add("v", v);
-
sParaTempToken.Add("req_id", req_id);
-
sParaTempToken.Add("req_data", req_dataToken);
-
var sHtmlTextToken = BuildRequest(Config._GateWayWap, sParaTempToken);
-
var code = Encoding.GetEncoding(Config._Charset);
-
sHtmlTextToken = HttpUtility.UrlDecode(sHtmlTextToken, code);
-
var dicHtmlTextToken = ParseResponse(sHtmlTextToken);
-
var request_token = dicHtmlTextToken["request_token"];
-
//根据授权码token调用交易接口alipay.wap.auth.authAndExecute
-
var req_data = string.Format("<auth_and_execute_req><request_token>{0}</request_token></auth_and_execute_req>", request_token);
-
var sParaTemp = new SortedDictionary<string, string>
-
{
-
{"partner", Config.Partner},
-
{"_input_charset", Config._Charset.ToLower()},
-
{"sec_id", Config._SignType.ToUpper()},
-
{"service", "alipay.wap.auth.authAndExecute"},
-
{"format", format},
-
{"v", v},
-
{"req_data", req_data}
-
};
-
var sHtmlText = BuildRequest(Config._GateWayWap, sParaTemp, "get", "确认");
-
HttpContext.Current.Response.Write(sHtmlText);
-
}
-
/// <summary>
-
/// 建立请求,以表单HTML形式构造(默认)
-
/// </summary>
-
/// <param name="GATEWAY_NEW">支付宝网关地址</param>
-
/// <param name="sParaTemp">请求参数数组</param>
-
/// <param name="strMethod">提交方式。两个值可选:post、get</param>
-
/// <param name="strButtonValue">确认按钮显示文字</param>
-
/// <returns>提交表单HTML文本</returns>
-
private string BuildRequest(string GATEWAY_NEW, SortedDictionary<string, string> sParaTemp, string strMethod, string strButtonValue)
-
{
-
var dicPara = BuildRequestPara(sParaTemp);
-
var sbHtml = new StringBuilder();
-
sbHtml.Append("<form id='alipaysubmit' name='alipaysubmit' action='" + GATEWAY_NEW + "_input_charset=" + Config._Charset + "' method='" + strMethod.ToLower().Trim() + "'>");
-
foreach (var temp in dicPara)
-
{
-
sbHtml.Append("<input type='hidden' name='" + temp.Key + "' value='" + temp.Value + "'/>");
-
}
-
//submit按钮控件请不要含有name属性
-
sbHtml.Append("<input type='submit' value='" + strButtonValue + "' style='display:none;'></form>");
-
sbHtml.Append("<script>document.forms['alipaysubmit'].submit();</script>");
-
return sbHtml.ToString();
-
}
-
/// <summary>
-
/// 建立请求,以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果
-
/// </summary>
-
/// <param name="gateWayWap">支付宝网关地址</param>
-
/// <param name="sParaTemp">请求参数数组</param>
-
/// <returns>支付宝处理结果</returns>
-
private string BuildRequest(string gateWayWap, SortedDictionary<string, string> sParaTemp)
-
{
-
var code = Encoding.GetEncoding(Config._Charset);
-
var strRequestData = BuildRequestParaToString(sParaTemp,code);
-
var bytesRequestData = code.GetBytes(strRequestData);
-
var strUrl = string.Format("{0}_input_charset={1}", gateWayWap, Config._Charset);
-
string strResult;
-
try
-
{
-
var myReq = (HttpWebRequest)WebRequest.Create(strUrl);
-
myReq.Method = "post";
-
myReq.ContentType = "application/x-www-form-urlencoded";
-
myReq.ContentLength = bytesRequestData.Length;
-
var requestStream = myReq.GetRequestStream();
-
requestStream.Write(bytesRequestData, 0, bytesRequestData.Length);
-
requestStream.Close();
-
var HttpWResp = (HttpWebResponse)myReq.GetResponse();
-
var myStream = HttpWResp.GetResponseStream();
-
var reader = new StreamReader(myStream, code);
-
var responseData = new StringBuilder();
-
string line;
-
while ((line = reader.ReadLine()) != null)
-
{
-
responseData.Append(line);
-
}
-
myStream.Close();
-
strResult = responseData.ToString();
-
}
-
catch (Exception exp)
-
{
-
strResult = "报错:"+exp.Message;
-
}
-
return strResult;
-
}
-
/// <summary>
-
/// 生成要请求给支付宝的参数数组
-
/// </summary>
-
private string BuildRequestParaToString(SortedDictionary<string, string> sParaTemp, Encoding code)
-
{
-
return Core.CreateLinkStringUrlencode(BuildRequestPara(sParaTemp), code);
-
}
-
/// <summary>
-
/// 生成要请求给支付宝的参数数组
-
/// </summary>
-
private Dictionary<string, string> BuildRequestPara(SortedDictionary<string, string> sParaTemp)
-
{
-
var sPara = Core.FilterPara(sParaTemp);
-
var mysign = MD5.Sign(Core.CreateLinkString(sPara), Config.Key, Config._Charset);
-
sPara.Add("sign", mysign);
-
if (sPara["service"] != "alipay.wap.trade.create.direct" && sPara["service"] != "alipay.wap.auth.authAndExecute")
-
{
-
sPara.Add("sign_type", Config._SignType);
-
}
-
return sPara;
-
}
-
/// <summary>
-
/// 解析远程模拟提交后返回的信息
-
/// </summary>
-
/// <param name="strText">要解析的字符串</param>
-
/// <returns>解析结果</returns>
-
private Dictionary<string, string> ParseResponse(string strText)
-
{
-
var strSplitText = strText.Split('&');
-
var dicText = new Dictionary<string, string>();
-
foreach (string text in strSplitText)
-
{
-
var nPos = text.IndexOf('=');
-
dicText.Add(text.Substring(0, nPos), text.Substring(nPos + 1, text.Length - nPos - 1));
-
}
-
if (dicText["res_data"] != null)
-
{
-
//token从res_data中解析出来(也就是说res_data中已经包含token的内容)
-
var xmlDoc = new XmlDocument();
-
try
-
{
-
xmlDoc.LoadXml(dicText["res_data"]);
-
var strRequest_token = xmlDoc.SelectSingleNode("/direct_trade_create_res/request_token").InnerText;
-
dicText.Add("request_token", strRequest_token);
-
}
-
catch (Exception exp)
-
{
-
dicText.Add("request_token", exp.ToString());
-
}
-
}
-
return dicText;
-
}
-
}
-
}
-
Config.cs
-
using System.Configuration;
-
namespace Alipay
-
{
-
/// <summary>
-
/// 账户配置
-
/// 1.登录支付宝网站(www.alipay.com)
-
/// 2.点击“商家服务”(https://b.alipay.com/order/myOrder.htm)
-
/// 3.点击“查询合作者身份(PID)”、“查询安全校验码(Key)”
-
/// </summary>
-
public class Config
-
{
-
/// <summary>
-
/// 合作者身份ID
-
/// </summary>
-
public static string Partner{ internal get; set; }
-
/// <summary>
-
/// 交易安全校验码
-
/// </summary>
-
public static string Key { internal get; set; }
-
/// <summary>
-
/// 卖方(收款方)支付宝账户
-
/// </summary>
-
public static string SellerEmail { internal get; set; }
-
/// <summary>
-
/// 字符编码格式:utf-8
-
/// </summary>
-
internal static string _Charset { get { return "utf-8"; } }
-
/// <summary>
-
/// 签名方式:MD5
-
/// </summary>
-
internal static string _SignType { get { return "MD5"; } }
-
/// <summary>
-
/// 支付宝网关地址pc
-
/// </summary>
-
internal static string _GateWay { get { return "https://mapi.alipay.com/gateway.do?"; } }
-
/// <summary>
-
/// 支付宝网关地址wap
-
/// </summary>
-
internal static string _GateWayWap { get { return "http://wappaygw.alipay.com/service/rest.htm?"; } }
-
/// <summary>
-
/// 支付宝消息验证地址
-
/// </summary>
-
internal static string _VeryfyUrl { get { return "https://mapi.alipay.com/gateway.do?service=notify_verify&"; } }
-
/// <summary>
-
/// 交易方式:即时到账交易pc
-
/// </summary>
-
internal static string _PayMode { get { return "create_direct_pay_by_user"; } }
-
/// <summary>
-
/// 支付类型:1
-
/// </summary>
-
internal static string _PayType { get { return "1"; } }
-
/// <summary>
-
/// 日志路径:/log/Alipay
-
/// </summary>
-
internal static string _LogPath { get { return "/log/Alipay"; } }
-
/// <summary>
-
/// 商户的私钥,如果签名方式设置为“0001”时,请设置该参数
-
/// </summary>
-
internal static string _PrivateKey { get { return ""; } }
-
/// <summary>
-
/// 商户的公钥,如果签名方式设置为“0001”时,请设置该参数
-
/// </summary>
-
internal static string _PublicKey { get { return ""; } }
-
static Config()
-
{
-
if (string.IsNullOrEmpty(Partner))
-
Partner = ConfigurationManager.AppSettings["Alipay.Partner"];
-
if (string.IsNullOrEmpty(Key))
-
Key = ConfigurationManager.AppSettings["Alipay.Key"];
-
if (string.IsNullOrEmpty(SellerEmail))
-
SellerEmail = ConfigurationManager.AppSettings["Alipay.SellerEmail"];
-
}
-
}
-
}
-
Core.cs
-
using System.Linq;
-
using System.Web;
-
using System.Text;
-
using System.IO;
-
using System;
-
using System.Collections.Generic;
-
using System.Globalization;
-
namespace Alipay
-
{
-
internal class Core
-
{
-
/// <summary>
-
/// 除去数组中的空值和签名参数并以字母a到z的顺序排序
-
/// </summary>
-
internal static Dictionary<string, string> FilterPara(SortedDictionary<string, string> dicArrayPre)
-
{
-
return
-
dicArrayPre.Where(
-
temp =>
-
temp.Key.ToLower() != "sign" && temp.Key.ToLower() != "sign_type" &&
-
!string.IsNullOrEmpty(temp.Value)).ToDictionary(temp => temp.Key, temp => temp.Value);
-
}
-
/// <summary>
-
/// 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
-
/// </summary>
-
internal static string CreateLinkString(Dictionary<string, string> dicArray)
-
{
-
var prestr = new StringBuilder();
-
foreach (var temp in dicArray)
-
{
-
prestr.Append(temp.Key + "=" + temp.Value + "&");
-
}
-
prestr.Remove(prestr.Length - 1, 1);
-
return prestr.ToString();
-
}
-
/// <summary>
-
/// 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对参数值做urlencode
-
/// </summary>
-
internal static string CreateLinkStringUrlencode(Dictionary<string, string> dicArray, Encoding code)
-
{
-
var prestr = new StringBuilder();
-
foreach (var temp in dicArray)
-
{
-
prestr.AppendFormat("{0}={1}&", temp.Key, HttpUtility.UrlEncode(temp.Value, code));
-
}
-
prestr.Remove(prestr.Length - 1, 1);
-
return prestr.ToString();
-
}
-
/// <summary>
-
/// 写日志
-
/// </summary>
-
internal static void LogResult(string text)
-
{
-
var strPath = HttpContext.Current.Server.MapPath(Config._LogPath);
-
var dateFloderName = DateTime.Now.ToString("yyyyMM");
-
strPath = string.Format("{0}/{1}", strPath, dateFloderName);
-
if (!Directory.Exists(strPath))
-
{
-
Directory.CreateDirectory(strPath);
-
}
-
strPath = strPath + "\\" + DateTime.Now.ToString("yyyyMMddHHmmssffff", DateTimeFormatInfo.InvariantInfo) + ".txt";
-
var fs = new StreamWriter(strPath, true, Encoding.Default);
-
fs.Write(text);
-
fs.Close();
-
}
-
/// <summary>
-
/// 获取支付宝POST过来通知消息,并以“参数名=参数值”的形式组成数组
-
/// </summary>
-
internal static SortedDictionary<string, string> GetRequestPost()
-
{
-
int i;
-
var sArray = new SortedDictionary<string, string>();
-
var coll = HttpContext.Current.Request.Form;
-
var requestItem = coll.AllKeys;
-
for (i = 0; i < requestItem.Length; i++)
-
sArray.Add(requestItem[i], HttpContext.Current.Request.Form[requestItem[i]]);
-
return sArray;
-
}
-
/*
-
/// <summary>
-
/// 获取文件的md5摘要
-
/// </summary>
-
/// <param name="sFile">文件流</param>
-
/// <returns>MD5摘要结果</returns>
-
internal static string GetAbstractToMD5(Stream sFile)
-
{
-
System.Security.Cryptography.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>
-
internal static string GetAbstractToMD5(byte[] dataFile)
-
{
-
System.Security.Cryptography.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();
-
}
-
*/
-
}
-
}
-
MD5.cs
-
using System.Text;
-
using System.Security.Cryptography;
-
namespace Alipay
-
{
-
internal sealed class MD5
-
{
-
/// <summary>
-
/// 签名字符串
-
/// </summary>
-
/// <param name="str">需要签名的字符串</param>
-
/// <param name="key">密钥</param>
-
/// <param name="charset">编码格式</param>
-
/// <returns>签名结果</returns>
-
internal static string Sign(string str, string key, string charset)
-
{
-
var sb = new StringBuilder(32);
-
str += key;
-
var md5 = new MD5CryptoServiceProvider();
-
var t = md5.ComputeHash(Encoding.GetEncoding(charset).GetBytes(str));
-
for (var i = 0; i < t.Length; i++)
-
sb.Append(t[i].ToString("x").PadLeft(2, '0'));
-
return sb.ToString();
-
}
-
/// <summary>
-
/// 验证签名
-
/// </summary>
-
/// <param name="prestr">需要签名的字符串</param>
-
/// <param name="sign">签名结果</param>
-
/// <param name="key">密钥</param>
-
/// <param name="charset">编码格式</param>
-
/// <returns>验证结果</returns>
-
internal static bool Verify(string prestr, string sign, string key, string charset)
-
{
-
var mysign = Sign(prestr, key, charset);
-
return mysign == sign;
-
}
-
}
-
}
-
Notify.cs
-
Notify.cs
-
using System.Text;
-
using System.IO;
-
using System.Net;
-
using System;
-
using System.Collections.Generic;
-
namespace Alipay
-
{
-
/// <summary>
-
/// 处理支付宝各接口通知返回
-
/// </summary>
-
internal class Notify
-
{
-
/// <summary>
-
/// 验证消息是否是支付宝发出的合法消息
-
/// </summary>
-
/// <param name="inputPara">通知返回参数数组</param>
-
/// <param name="notifyId">通知验证ID</param>
-
/// <param name="sign">支付宝生成的签名结果</param>
-
/// <returns>验证结果</returns>
-
internal bool Verify(SortedDictionary<string, string> inputPara, string notifyId, string sign)
-
{
-
var isSign = GetSignVeryfy(inputPara, sign);
-
var responseTxt = "true";
-
if (!string.IsNullOrEmpty(notifyId)) { responseTxt = GetResponseTxt(notifyId); }
-
//判断responsetTxt是否为true,isSign是否为true
-
//responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
-
//isSign不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
-
return responseTxt == "true" && isSign;
-
}
-
/// <summary>
-
/// 获取返回时的签名验证结果
-
/// </summary>
-
/// <param name="inputPara">通知返回参数数组</param>
-
/// <param name="sign">对比的签名结果</param>
-
/// <returns>签名验证结果</returns>
-
private bool GetSignVeryfy(SortedDictionary<string, string> inputPara, string sign)
-
{
-
var sPara = Core.FilterPara(inputPara); //过滤空值、sign与sign_type参数
-
var preSignStr = Core.CreateLinkString(sPara); //获取待签名字符串
-
return MD5.Verify(preSignStr, sign, Config.Key, Config._Charset);
-
}
-
/// <summary>
-
/// 获取是否是支付宝服务器发来的请求的验证结果
-
/// </summary>
-
/// <param name="notifyId">通知验证ID</param>
-
/// <returns>验证结果</returns>
-
private string GetResponseTxt(string notifyId)
-
{
-
var veryfyUrl = string.Format("{0}partner={1}¬ify_id={2}", Config._VeryfyUrl, Config.Partner, notifyId);
-
//获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求
-
try
-
{
-
var myReq = (HttpWebRequest)WebRequest.Create(veryfyUrl);
-
myReq.Timeout = 120000;
-
var HttpWResp = (HttpWebResponse)myReq.GetResponse();
-
var myStream = HttpWResp.GetResponseStream();
-
var sr = new StreamReader(myStream, Encoding.Default);
-
var strBuilder = new StringBuilder();
-
while (-1 != sr.Peek())
-
{
-
strBuilder.Append(sr.ReadLine());
-
}
-
return strBuilder.ToString();
-
}
-
catch (Exception exp)
-
{
-
return string.Format("错误:{0}", exp.Message);
-
}
-
}
-
}
-
}
-
PC端的NotifyPage.cs
-
PC端的NotifyPage.cs
-
using System;
-
using System.Collections.Generic;
-
using System.Linq;
-
namespace Alipay
-
{
-
/// <summary>
-
/// pc网页支付接口接入页
-
/// </summary>
-
public abstract class NotifyPage : System.Web.UI.Page
-
{
-
/// <summary>
-
/// 商户订单号
-
/// </summary>
-
protected string OrderNo { get; private set; }
-
/// <summary>
-
/// 支付宝交易号
-
/// </summary>
-
protected string TradeNo { get; private set; }
-
/// <summary>
-
/// 交易状态
-
/// </summary>
-
protected string TradeStatus { get; private set; }
-
/// <summary>
-
/// 业务逻辑处理
-
/// </summary>
-
protected abstract void OnNotifyConfirm();
-
protected void Page_Load(object sender, EventArgs e)
-
{
-
if (IsPostBack) return;
-
var sPara = GetRequestPost();
-
Core.LogResult(Request.Url.ToString());
-
if (sPara.Count > 0) //判断是否有带返回参数
-
{
-
var formString = Request.Form.Keys.Cast<string>()
-
.Aggregate("", (current, key) =>
-
current + string.Format("{0} = {1}\r\n", key.PadLeft(30, ' '),
-
Request.Form[key]));
-
Core.LogResult(formString);
-
var aliNotify = new Notify();
-
var verifyResult = aliNotify.Verify(sPara, Request.Form["notify_id"], Request.Form["sign"]);
-
if (verifyResult)//验证成功
-
{
-
OrderNo = Request.Form["out_trade_no"];
-
TradeNo = Request.Form["trade_no"];
-
TradeStatus = Request.Form["trade_status"];
-
//该种交易状态只在一种情况下出现——开通了高级即时到账,买家付款成功后。
-
if (TradeStatus == "TRADE_FINISHED" || TradeStatus == "TRADE_SUCCESS")
-
{
-
OnNotifyConfirm(); //业务逻辑处理
-
Core.LogResult(string.Format("业务逻辑处理,OrderNo:{0},TradeNo:{1},TradeStatus:{2}", OrderNo, TradeNo, TradeStatus));
-
}
-
Response.Write("success");
-
}
-
else
-
{
-
using System;
-
using System.Linq;
-
using System.Xml;
-
namespace Alipay.Wap
-
{
-
/// <summary>
-
/// 手机网页支付接口接入页
-
/// </summary>
-
public abstract class NotifyPage : System.Web.UI.Page
-
{
-
/// <summary>
-
/// 商户订单号
-
/// </summary>
-
protected string OrderNo { get; private set; }
-
/// <summary>
-
/// 支付宝交易号
-
/// </summary>
-
protected string TradeNo { get; private set; }
-
/// <summary>
-
/// 交易状态
-
/// </summary>
-
protected string TradeStatus { get; private set; }
-
/// <summary>
-
/// 业务逻辑处理
-
/// </summary>
-
protected abstract void OnNotifyConfirm();
-
protected bool PaySucceed = false;
-
protected string PayMsg = "";
-
protected void Page_Load(object sender, EventArgs e)
-
{
-
if (IsPostBack) return;
-
var sPara = Core.GetRequestPost();
-
Core.LogResult(Request.Url.ToString());
-
if (sPara.Count > 0) //判断是否有带返回参数
-
{
-
var formString = Request.Form.Keys.Cast<string>()
-
.Aggregate("", (current, key) =>
-
current + string.Format("{0} = {1}\r\n", key.PadLeft(30, ' '),
-
Request.Form[key]));
-
Core.LogResult(formString);
-
var aliNotify = new Alipay.Notify();
-
var verifyResult = aliNotify.Verify(sPara, Request.Form["notify_id"], Request.Form["sign"]);
-
if (verifyResult) //验证成功
-
{
-
try
-
{
-
var xmlDoc = new XmlDocument();
-
xmlDoc.LoadXml(sPara["notify_data"]);
-
OrderNo = xmlDoc.SelectSingleNode("/notify/out_trade_no").InnerText; //商户订单号
-
TradeNo = xmlDoc.SelectSingleNode("/notify/trade_no").InnerText; //支付宝交易号
-
TradeStatus = xmlDoc.SelectSingleNode("/notify/trade_status").InnerText; //交易状态
-
//该种交易状态只在两种情况下出现
-
//1、开通了普通即时到账,买家付款成功后。
-
//2、开通了高级即时到账,从该笔交易成功时间算起,过了签约时的可退款时限(如:三个月以内可退款、一年以内可退款等)后
-
if (TradeStatus == "TRADE_FINISHED" || TradeStatus == "TRADE_SUCCESS")
-
{
-
try
-
{
-
OnNotifyConfirm();
-
Core.LogResult(string.Format("业务逻辑处理,OrderNo:{0},TradeNo:{1},TradeStatus:{2}", OrderNo, TradeNo, TradeStatus));
-
Response.Write("success");
-
}
-
catch
-
{
-
}
-
}
-
else
-
{
-
Response.Write(TradeStatus);
-
}
-
}
-
catch (Exception exc)
-
{
-
Response.Write(exc.ToString());
-
}
-
}
-
else //验证失败
-
{
-
Response.Write("fail");
-
}
-
}
-
else
-
{
-
Response.Write("无返回参数");
-
}
-
}
-
}
-
}
Response.Write("fail"); } } else { Response.Write("无返回参数"); } } /// <summary> /// 获取支付宝POST过来通知消息,并以“参数名=参数值”的形式组成数组 /// </summary> private SortedDictionary<string, string> GetRequestPost() { int i; var sArray = new SortedDictionary<string, string>(); var coll = Request.Form; var requestItem = coll.AllKeys; for (i = 0; i < requestItem.Length; i++) sArray.Add(requestItem[i], Request.Form[requestItem[i]]); return sArray; } }}