资源描述
大型网上购物系统除了能让会员选取货到付款结账方式外,还应当提供某些更以便快捷网上支付方式。如果网上商店没有足够实力提供会员直接在网站中建立钞票账户功能,就可以将订单信息转接到支付宝,让会员从支付宝付款。固然就算会员可以在网站上建立自己钞票账户,提供支付宝支付功能也不失为另一种以便快捷支付方式,这可以给客户提供更多可选支付方式。
一方面,网上购物系统必要与支付宝公司订立合伙合同,以保证从本购物网站上传到
支付宝网站上订单信息能被对的接受。
当会员于购物网站上买下一系列商品并选取支付宝付款方式后,购物系统即将会员购物订单信息转发到支付宝,网站页面也会转到支付宝付款页面。此时,支付宝页面会发送一种验证信息到本网站以确认支付宝对的收到订单信息。
会员于支付宝网站付款完毕后,网站页面会重新跳回本购物网站,同步支付宝会将已付款订单信息发回本网站以便对本购物网站数据库进行必要修改操作。此外本网站还需要向支付宝网站发送一种返回信息,告知支付宝本系统已对的收到付款完毕订单信息并且已经完毕对数据解决操作。
向支付宝网站传送订单信息时重要参数含义:
gateway :支付接口
service:辨认是何接口实现何功能表达
seller_email:商家签约时支付宝账号,即收款支付宝账号
key:安全校验码,与partner是一组
partner:商户ID,合伙伙伴ID
sign_type:加密类型
_input_charset:编码类型
show_url:展示地址,即在支付宝页面时商品名称旁边“详情”链接地址
out_trade_no:会员订单编号,订单编号必要在本系统中保持唯一
subject:商品名称,也可称为订单名称,该接口并不是单一只能买同样东西,可把一次支付当作一次下订单
body:商品描述,即备注
total_fee:商品价格,也可称为订单总金额
源码分析(C#):
一方面必要建立一种告知页面(Notify.aspx)和一种返回页面(Return.aspx)以接受并验证从支付宝返回信息并对数据库中相应订单信息做修改解决操作。
Notify.aspx.cs
代码
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Collections.Specialized;
using System.IO;
using Gateway;
/// <summary>
/// 创立该页面文献时,请留意该页面文献中无任何HTML代码及空格。
/// 该页面称作“告知页”,是异步被支付宝服务器所调用。
/// 当支付宝订单状态变化时,支付宝服务器则会自动调用此页面,因而请做好自身网站订单信息与支付宝上订单同步工作
/// </summary>
public partial class Alipay_Notify :System.Web.UI.Page
{
protected void Page_Load(object sender,EventArgs e)
{
string alipayNotifyURL = "";
//string alipayNotifyURL = "";//此途径是在上面链接地址无法起作用时替代使用。
string partner = ""; //partner合伙伙伴id(必要填写)
string key = "";//partner 相应交易安全校验码(必要填写)
string _input_charset = "utf-8";//编码类型,完全依照客户自身项目编码格式而定,千万不要填错。否则极其容易导致MD5加密错误。
alipayNotifyURL = alipayNotifyURL + "&partner=" + partner + "¬ify_id=" + Request.Form["notify_id"];
//获取支付宝ATN返回成果,true是对的订单信息,false 是无效
string responseTxt = AliPay.Get_Http(alipayNotifyURL,10);
//*******加密签名程序开始*******
int i;
NameValueCollection coll;
//Load Form variables into NameValueCollection variable.
coll = Request.Form;
// Get names of all forms into a string array.
String[] requestarr = coll.AllKeys;
//进行排序;
string[] Sortedstr = AliPay.BubbleSort(requestarr);
//构造待md5摘要字符串 ;
StringBuilder prestr = new StringBuilder();
for (i = 0;i < Sortedstr.Length;i++)
{
if (Request.Form[Sortedstr[i]] != "" && Sortedstr[i] != "sign" && Sortedstr[i] != "sign_type")
{
if (i == Sortedstr.Length - 1)
{
prestr.Append(Sortedstr[i] + "=" + Request.Form[Sortedstr[i]]);
}
else
{
prestr.Append(Sortedstr[i] + "=" + Request.Form[Sortedstr[i]] + "&");
}
}
}
prestr.Append(key);
string mysign = AliPay.GetMD5(prestr.ToString(),_input_charset);
//*******加密签名程序结束*******
string sign = Request.Form["sign"];
if (mysign == sign && responseTxt == "true") //验证支付发过来消息,签名与否对的,只要成功进如这个判断里,则表达该页面已被支付宝服务器成功调用
//但判断内浮现自身编写程序有关错误导致告知给支付宝并不是发送success消息或没有更新客户自身数据库状况,请自身程序编写好应对办法,否则查明因素时困难之极
{
if (Request.Form["trade_status"] == "WAIT_BUYER_PAY")// 判断支付状态_等待买家付款(文档中有枚举表可以参照)
{
//更新自己数据库订单语句,请自己填写一下
string strOrderNO = Request.Form["out_trade_no"];//订单号
string strPrice = Request.Form["total_fee"];//金额 如果你申请了商家购物卷功能,在返回信息里面请不要做金额判断,否则会校验通过不了。
}
else if (Request.Form["trade_status"] == "TRADE_FINISHED" || Request.Form["trade_status"] == "TRADE_SUCCESS")// 判断支付状态_交易成功结束(文档中有枚举表可以参照)
{
//更新自己数据库订单语句,请自己填写一下
string strOrderNO = Request.Form["out_trade_no"];//订单号
string strPrice = Request.Form["total_fee"];//金额
}
else
{
//更新自己数据库订单语句,请自己填写一下
}
Response.Write("success"); //返回给支付宝消息,成功,请不要改写这个success
//success与fail及其她字符区别在于,支付宝服务器若遇到success时,则不再发送祈求告知(即不再调用该页面,让该页面再次运营起来),
//若不是success,则支付宝默认没有收到成功信息,则会重复不断地调用该页面直到失效,有效调用时间是24小时以内。
//最佳写TXT文献,以记录下与否异步返回记录。
////写文本,纪录支付宝返回消息,比对md5计算成果(如网站不支持写txt文献,可改成写数据库)
//string TOEXCELLR = "MD5成果:mysign=" + mysign + ",sign=" + sign + ",responseTxt=" + responseTxt;
//StreamWriter fs = new StreamWriter(Server.MapPath("Notify_DATA/" + DateTime.Now.ToString().Replace(":","")) + ".txt",false,System.Text.Encoding.Default);
//fs.Write(TOEXCELLR);
//fs.Close();
}
else
{
Response.Write("fail");
//最佳写TXT文献,以记录下与否异步返回记录。
//写文本,纪录支付宝返回消息,比对md5计算成果(如网站不支持写txt文献,可改成写数据库)
string TOEXCELLR = "MD5成果:mysign=" + mysign + ",sign=" + sign + ",responseTxt=" + responseTxt;
StreamWriter fs = new StreamWriter(Server.MapPath("Notify_DATA/" + DateTime.Now.ToString().Replace(":","")) + ".txt",false,System.Text.Encoding.Default);
fs.Write(TOEXCELLR);
fs.Close();
}
}
}
Return.aspx.cs
代码
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Collections.Specialized;
using System.IO;
using Gateway;
/// <summary>
/// 创立该页面文献时,请留意该页面文献是可以对其进行美工解决,因素在于支付完毕后来,当前窗口会从支付宝页面跳转回这个页面。
/// 该页面称作“返回页”,是同步被支付宝服务器所调用,可当作是支付完毕后提示信息页,如“您某某某订单,多少金额已支付成功”。
/// </summary>
public partial class Alipay_Return :System.Web.UI.Page
{
protected void Page_Load(object sender,EventArgs e)
{
string alipayNotifyURL = "";
//string alipayNotifyURL = "";//此途径是在上面链接地址无法起作用时替代使用。
string key = "";//partner 相应交易安全校验码(必要填写)
string partner = ""; //partner合伙伙伴id(必要填写)
string _input_charset = "utf-8";//编码类型,完全依照客户自身项目编码格式而定,千万不要填错。否则极其容易导致MD5加密错误。
alipayNotifyURL = alipayNotifyURL + "&partner=" + partner + "¬ify_id=" + Request.QueryString["notify_id"];
//获取支付宝ATN返回成果,true是对的订单信息,false 是无效
string responseTxt = AliPay.Get_Http(alipayNotifyURL,10);
//*******加密签名程序开始//*******
int i;
NameValueCollection coll;
//Load Form variables into NameValueCollection variable.
coll = Request.QueryString;
// Get names of all forms into a string array.
String[] requestarr = coll.AllKeys;
//进行排序;
string[] Sortedstr = AliPay.BubbleSort(requestarr);
//构造待md5摘要字符串 ;
StringBuilder prestr = new StringBuilder();
for (i = 0;i < Sortedstr.Length;i++)
{
if (Request.Form[Sortedstr[i]] != "" && Sortedstr[i] != "sign" && Sortedstr[i] != "sign_type")
{
if (i == Sortedstr.Length - 1)
{
prestr.Append(Sortedstr[i] + "=" + Request.QueryString[Sortedstr[i]]);
}
else
{
prestr.Append(Sortedstr[i] + "=" + Request.QueryString[Sortedstr[i]] + "&");
}
}
}
prestr.Append(key);
//生成Md5摘要;
string mysign = AliPay.GetMD5(prestr.ToString(),_input_charset);
//*******加密签名程序结束*******
string sign = Request.QueryString["sign"];
// Response.Write(prestr.ToString()); //调试用,支付宝服务器返回时完整途径。
if (mysign == sign && responseTxt == "true") //验证支付发过来消息,签名与否对的
{
//更新自己数据库订单语句,请自己填写一下
string strOrderNO = Request.QueryString["out_trade_no"];//订单号
string strPrice = Request.QueryString["total_fee"];//金额
string strTradeStatus = Request.QueryString["TRADE_STATUS"];//订单状态
Response.Write("订单号:" + strOrderNO + "<br>金额:" + strPrice); //成功,可美化该页面,提示信息
}
else
{
Response.Write("------------------------------------------");
Response.Write("<br>Result:responseTxt=" + responseTxt);
Response.Write("<br>Result:mysign=" + mysign);
Response.Write("<br>Result:sign=" + sign);
Response.Write("支付失败"); //支付失败,提示信息
}
}
}
除此之外在Notify.aspx页面和Return.aspx页面公用某些办法,可以提取出来放在一种公共类里面(Alipay.cs)
Alipay.cs
代码
using System.Web;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Net;
using System;
/// <summary>
/// New Interface for AliPay
/// </summary>
namespace Gateway
{
public class AliPay
{
/// <summary>
/// 与ASP兼容MD5加密算法
/// </summary>
public static string GetMD5(string s,string _input_charset)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] t = md5.ComputeHash(Encoding.GetEncoding(_input_charset).GetBytes(s));
StringBuilder sb = new StringBuilder(32);
for (int i = 0;i < t.Length;i++)
{
sb.Append(t[i].ToString("x").PadLeft(2,'0'));
}
return sb.ToString();
}
/// <summary>
/// 冒泡排序法
/// 按照字母序列从a到z顺序排列
/// </summary>
public static string[] BubbleSort(string[] r)
{
int i,j;//互换标志
string temp;
bool exchange;
for (i = 0;i < r.Length;i++) //最多做R.Length-1趟排序
{
exchange = false;//本趟排序开始前,互换标志应为假
for (j = r.Length - 2;j >= i;j--)
{//互换条件
if (System.String.CompareOrdinal(r[j + 1],r[j]) < 0)
{
temp = r[j + 1];
r[j + 1] = r[j];
r[j] = temp;
exchange = true;//发生了互换,故将互换标志置为真
}
}
if (!exchange) //本趟排序未发生互换,提前终结算法
{
break;
}
}
return r;
}
/// <summary>
/// 生成URL链接或加密成果
/// </summary>
/// <param name="para">参数加密数组</param>
/// <param name="_input_charset">编码格式</param>
/// <param name="sign_type">加密类型</param>
/// <param name="key">安全校验码</param>
/// <returns>字符串URL或加密成果</returns>
public static string CreatUrl(
//string gateway,//GET方式传递参数时请去掉注释
string[] para,
string _input_charset,
string sign_type,
string key
)
{
int i;
//进行排序;
string[] Sortedstr = BubbleSort(para);
//构造待md5摘要字符串 ;
StringBuilder prestr = new StringBuilder();
for (i = 0;i < Sortedstr.Length;i++)
{
if (i == Sortedstr.Length - 1)
{
prestr.Append(Sortedstr[i]);
}
else
{
prestr.Append(Sortedstr[i] + "&");
}
}
prestr.Append(key);
//生成Md5摘要;
string sign = GetMD5(prestr.ToString(),_input_charset);
//如下是POST方式传递参数
return sign;
//如下是GET方式传递参数
//构造支付Url;
// char[] delimiterChars = { '='};
// StringBuilder parameter = new StringBuilder();
// parameter.Append(gateway);
// for (i = 0;i < Sortedstr.Length;i++)
// {//UTF-8格式编码转换
// parameter.Append(Sortedstr[i].Split(delimiterChars)[0] + "=" + HttpUtility.UrlEncode(Sortedstr[i].Split(delimiterChars)[1]) + "&");
// }
//
// parameter.Append("sign=" + sign + "&sign_type=" + sign_type);
//
// //返回支付Url;
// return parameter.ToString();
}
//获取远程服务器ATN成果,验证与否是支付宝服务器发来祈求
public static string Get_Http(string a_strUrl,int timeout)
{
string strResult;
try
{
HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(a_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;
}
}
}
以上三个文献建之后,就可以在需要地方对支付宝接口进行调用以完毕支付宝支付功能了(Default.aspx.cs)
代码
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Gateway;
public partial class _Default :System.Web.UI.Page
{
protected void Page_Load(object sender,EventArgs e)
{
}
protected void BtnAlipay_Click(object sender,EventArgs e)
{
//业务参数赋值;
string gateway = ""; //支付接口
string service = "create_direct_pay_by_user"; //服务名称,这个是辨认是何接口实现何功能标记,请勿修改
string seller_email = ""; //商家签约时支付宝帐号,即收款支付宝帐号
string sign_type = "MD5"; //加密类型,签名方式“不用改”
string key = ""; //安全校验码,与partner是一组,获取方式是:用签约时支付宝帐号登陆支付宝网站.com,在商家服务我商家里即可查到。
string partner = ""; //商户ID,合伙身份者ID,合伙伙伴ID
string _input_charset = "utf-8"; //编码类型,完全依照客户自身项目编码格式而定,千万不要填错。否则极其容易导致MD5加密错误。
string show_url = ""; //展示地址,即在支付页面时,商品名称旁边“详情”链接地址。
string out_trade_no = TxtOrderno.Text.Trim(); //客户自己订单号,订单号必要在自身订单系统中保持唯一性
string subject = TxtSubject.Text.Trim();
展开阅读全文