支付宝的接口通用处理方法(C#)

//======================================================================

//--------The Common Interface For Alipay, Powered by Qgzxol------------

//-------支付宝的接口通用处理方法,中国高校勤工助学网站@版权所有.--------

//-------Author:WinLin.   Email:[email protected] QQ:398510617------

//======================================================================

一.系统模型
二.源码管理
1. F:/WinLin/NetShop/AlipayKernel/AssemblyInfo.cs

using System.Reflection;

using System.Runtime.CompilerServices;

//======================================================================

//--------The Common Interface For Alipay, Powered by Qgzxol------------

//-------支付宝的接口通用处理方法,中国高校勤工助学网站@版权所有.--------

//-------Author:WinLin.   Email:[email protected] QQ:398510617------

//======================================================================

[assembly: AssemblyTitle("Qgzxol.AlipayKernel")]

[assembly: AssemblyDescription("支付宝的接口通用处理方法")]

[assembly: AssemblyConfiguration("")]

[assembly: AssemblyCompany("中国高校勤工助学网站")]

[assembly: AssemblyProduct("")]

[assembly: AssemblyCopyright("Qgzxol&WinLin")]

[assembly: AssemblyTrademark("")]

[assembly: AssemblyCulture("")]     

[assembly: AssemblyVersion("1.0.*")]

[assembly: AssemblyDelaySign(false)]

[assembly: AssemblyKeyFile("")]

[assembly: AssemblyKeyName("")]

2. F:/WinLin/NetShop/AlipayKernel/Config.cs

using System;

//======================================================================

//--------The Common Interface For Alipay, Powered by Qgzxol------------

//-------支付宝的接口通用处理方法,中国高校勤工助学网站@版权所有.--------

//-------Author:WinLin.   Email:[email protected] QQ:398510617------

//======================================================================

namespace Qgzxol.AlipayKernel

{

     ///

     /// Qgzxol.AlipayKernel.Config

     /// [配置类.

     ///

     public class Config

     {

         //--=================================================================--

         //------------------------服务器PayTo生成查询配置段--------------------

         //--=================================================================--

         #region //------------------------服务器PayTo生成查询配置段--------------------

         ///

         ///商家在支付宝上的eMail;

         ///读取web.config的seller配置字节.

         ///

         public static string seller

         {

              get

              {

                   string o=System.Configuration.ConfigurationSettings.AppSettings["seller"];

                   return o==null? "[email protected]":o;

              }

         }

         ///

         ///商家在支付宝上的"安全验证码";

         ///读取web.config的valiCode字节.

         ///

         public static string valiCode

         {

              get

              {

                   string o=System.Configuration.ConfigurationSettings.AppSettings["valiCode"];

                   return o==null? "6u34q7sq 8c572miml8bsg0bh2qdutzxl":o;

              }

         }

         ///

         ///默认编码;

         ///读取web.config的encoding字节.

         ///

         public static string encoding

         {

              get

              {

                   string o=System.Configuration.ConfigurationSettings.AppSettings["encoding"];

                   return o==null? "gb2312":o;

              }

         }

         #endregion

         //--=================================================================--

         //------------------------服务器ATN响应通知配置段----------------------

         //--=================================================================--

         #region //------------------------服务器ATN响应通知配置段----------------------

         ///

         ///在输出结果到服务器时候

         ///是否隐藏整个页面,默认是隐藏页面.

         ///例如,当我们发货后,给服务器返回Y信号,若此属性为true,则只返回一个单独的Y字符.

         ///

         public static bool isHidePage

         {

              get

              {

                   string o=System.Configuration.ConfigurationSettings.AppSettings["isHidePage"];

                   return o==null? false:!Convert.ToBoolean(o);

              }

         }

         ///

         ///当服务器的动作是test时候;

         ///我们是否响应服务器,返回Y则响应服务器,并从服务器中获取数据;

         ///否则服务器会暂时保留订单的数据直到我们响应了服务器.

         ///

         public static bool isResponseTest

         {

              get

              {

                   string o=System.Configuration.ConfigurationSettings.AppSettings["isResponseTest"];

                   return o==null? true:Convert.ToBoolean(o);

              }

         }

         ///

         ///是否把服务器的请求信息记录到数据库.

         ///在测试时,这是非常必要的.记录QueryString到数据库后,我们可以本地模拟.

         ///

         public static bool isRegisterATN

         {

              get

              {

                   string o=System.Configuration.ConfigurationSettings.AppSettings["isRegisterATN"];

                   return o==null? false:Convert.ToBoolean(o);

              }

         }

         ///

         ///是否把服务器的请求信息记录到数据库.

         ///在测试时,这是非常必要的.记录QueryString到数据库后,我们可以本地模拟.

         ///

         public static string registerATNSqlConnStr

         {

              get

              {

                   string o=System.Configuration.ConfigurationSettings.AppSettings["registerATNSqlConnStr"];

                   return o==null? "server=.;uid=sa;pwd=;database=ATNRegister;packet size=4096":Convert.ToString(o);

              }

         }

         #endregion

     }

}

3. F:/WinLin/NetShop/AlipayKernel/Keys.cs

using System;

//======================================================================

//--------The Common Interface For Alipay, Powered by Qgzxol------------

//-------支付宝的接口通用处理方法,中国高校勤工助学网站@版权所有.--------

//-------Author:WinLin.   Email:[email protected] QQ:398510617------

//======================================================================

//下面是payTo命名空间,主要处理发送事务.

namespace Qgzxol.AlipayKernel.PayTo

{

     ///

     /// Qgzxol.AlipayKernel.PayTo.Keys

     ///是键的枚举,键是指Alipay的开发文档中所说明的那些参数.

     ///屏蔽了ac和seller的设置,它们不属于普通信息,只能在Object中直接以属

     ///性初始化.

     ///

     public class Keys

     {

         ///

         ///本类的序列化字符串;

         ///必须按照这个序列添加才能正确的生成ac.

         ///添加的字段也要在对应的位置添加,否则会出错.

         ///

         public readonly static string[] serialFormat=

              new string[]{

                                 Keys.cmd

                                 ,Keys.subject

                                 ,Keys.body

                                 ,Keys.order_no

                                 ,Keys.price

                                 ,Keys.url

                                 ,Keys.type

                                 ,Keys.number

                                 ,Keys.transport

                                 ,Keys.ordinary_fee

                                 ,Keys.express_fee

                                 ,Keys.ems_fee//新增字段

                                 ,Keys.readonly_

                                 ,Keys.buyer_msg

                                 ,Keys.seller

                                 ,Keys.buyer

                                 ,Keys.buyer_name

                                 ,Keys.buyer_address

                                 ,Keys.buyer_zipcode

                                 ,Keys.buyer_tel

                                 ,Keys.buyer_mobile};

         //=============================================================

         //附一:请求参数汇总表

         #region请求参数汇总表

         //字段命名         字段名称      类型          说明

         //-------------------------------------------------------------

         //控制项

         ///

          ///命令码;String(30);默认值为0001

         ///

         public const string cmd="cmd";

         //-------------------------------------------------------------

         //商品基本信息

         ///

         ///商品名称;String(256)

         ///

         public const string subject="subject";

         ///

         ///商品描述;String(400)

         ///

         public const string body="body";

         ///

         ///商户订单号;String(64)

         ///

         public const string order_no="order_no";

         ///

         ///商品单价;Number(5,2);0.01~50000.00

         ///

         public const string price="price";

         ///

         ///商品展示网址;String(400)

         ///

         public const string url="url";

         //-------------------------------------------------------------

         //交易信息

         ///

         ///支付类型;String(4);1:商品购买2:服务购买3:网络拍卖4:捐赠

         ///

         public const string type="type";

         ///

         ///购买数量;Number(6,0);>0即可.

         ///

         public const string number="number";

         ///

         ///发货方式;Number(2,0);1:平邮2:快递3:虚拟物品7:EMS快递。

         ///

         public const string transport="transport";

         ///

         ///平邮运费;Number(5,2);0.01~50000.00

         ///

         public const string ordinary_fee="ordinary_fee";

         ///

         ///快递运费;Number(5,2);0.01~50000.00

         ///

         public const string express_fee="express_fee";

         ///

         /// EMS运费;Number(5,2);0.01~50000.00//新增字段

         ///

         public const string ems_fee="ems_fee";

         ///

         ///交易信息是否只读;Boolean;"true"或"false",默认值为false

         ///

         public const string readonly_="readonly";

         ///

         ///买家给卖家的留言;String(200)

         ///

         public const string buyer_msg="buyer_msg";

         //-------------------------------------------------------------

         //买卖双方信息

         ///

         ///卖家Email;String(100);payto:后的第一个参数,不需要传入

         ///

         public const string seller = "seller";

         ///

         ///买家Email;String(100)

         ///

         public const string buyer="buyer";

         ///

         ///买家姓名;String(128)

         ///

         public const string buyer_name="buyer_name";

         ///

         ///买家地址;String(256)

         ///

         public const string buyer_address="buyer_address";

         ///

         ///买家邮编;String(6)

         ///

         public const string buyer_zipcode="buyer_zipcode";

         ///

         ///买家电话号码;String(30)

         ///

         public const string buyer_tel="buyer_tel";

         ///

         ///买家手机号码;String(11)

         ///

         public const string buyer_mobile="buyer_mobile";

         //-------------------------------------------------------------

         //其他项

         ///

         ///合作伙伴ID;String(100);保留字段

         ///

         //public const string partner="partner";

         //-------------------------------------------------------------

         //安全项

         ///

         /// MD5摘要;String(32);不建议直接设置,而是由程序生成.

         ///

         //ac

         #endregion

     }

}

//下面是Notify命名空间,主要处理ATN事务.

namespace Qgzxol.AlipayKernel.Notify

{

     ///

     /// Qgzxol.AlipayKernel.Notify.Keys

     ///是键的枚举,键是指Alipay的开发文档中所说明的那些参数.

     ///屏蔽了ac和seller的设置,它们不属于普通信息,只能在Object中直接以属

     ///性初始化.

     ///

     public class Keys

     {

         ///

         ///本类的序列化字符串;

         ///必须按照这个序列添加才能正确的生成ac.

         ///添加的字段也要在对应的位置添加,否则会出错.

         ///

         public readonly static string[] serialFormat=

              new string[]{

                                 Keys.msg_id

                                 ,Keys.order_no

                                 ,Keys.gross

                                 ,Keys.buyer_email

                                 ,Keys.buyer_name

                                 ,Keys.buyer_address

                                 ,Keys.buyer_zipcode

                                 ,Keys.buyer_tel

                                 ,Keys.buyer_mobile

                                 ,Keys.action

                                 ,Keys.date

                            };

         //=============================================================

         //附二:通知参数汇总表

         #region通知参数汇总表

         //字段命名         字段名称      类型          说明

         //-------------------------------------------------------------

         ///

         ///通知任务ID

         ///

         public const string msg_id="msg_id";

         ///

         ///商户订单号

         ///

         public const string order_no="order_no";

         ///

         ///金额

         ///

         public const string gross="gross";

         ///

         ///买家Email

         ///

         public const string buyer_email="buyer_email";

         ///

         ///买家姓名

         ///

         public const string buyer_name="buyer_name";

         ///

         ///买家地址

         ///

         public const string buyer_address="buyer_address";

         ///

         ///买家邮编

         ///

         public const string buyer_zipcode="buyer_zipcode";

         ///

         ///买家电话

         ///

         public const string buyer_tel="buyer_tel";

         ///

         ///买家手机

         ///

         public const string buyer_mobile="buyer_mobile";

         ///

         ///通知动作

         ///

         public const string action="action";

         ///

         ///通知发起日期

         ///

         public const string date="date";

         ///

         /// MD5摘要

         ///

         public const string ac="ac";

         #endregion

     }

     ///

     ///服务器的通知事件类型,

     ///通常有三个事件,test,sendOff和checkOut

     ///

     public class ServerNotifyType

     {

         #region服务器通知类型

         ///

         /// test表示我们的帐户有新的买卖了,但是我们的系统出了问题,

         ///在这期间,支付宝会保留我们的交易信息,并重发信息到我们的通知url,这时,test就响应了.

         ///若我们的系统在故障中,我们在web.config中配置查询为false,表示不响应test.

         ///若我们系统排除故障后正常运行,我们配置为true即可.在正常运行中,我们一般配置为true.

         ///相当于服务器发问:

         ///           您的系统现在能收取交易信息了吗?

         ///

         public const string test="test";

         ///

         /// sendOff是有客户购物并付款到支付宝了,支付宝向我们发出的通知,

         ///当我们进行了发货处理后,我们才可以发送Y到服务器,否则发送N到服务器.

         ///相当于服务器发问:

         ///           您发货了吗?

         ///

         public const string sendOff="sendOff";

         ///

         /// checkOut是发货后,客户确认收到货了,

         ///支付宝把客户的支付转到我们的帐户里的通知,

         ///若我们收到了款,发送Y到服务器,否则发送N到服务器.

         ///相当于服务器发问:

         ///           你收到了客户的交易款了吗?

         ///

         public const string checkOut="checkOut";

         #endregion

     }

     ///

     /// Qgzxol.AlipayKernel.Notify.ATNResult

     /// ATN的结果,响应服务器的通知,Y表示结果真.N表示结果假.

     ///通常需要响应三个事件:test,sendOff,checkOut,它们在下面的事件常量类中有说明.

     ///

     public class ATNResult

     {

         //表2-2&表2-4 ATN(通知)期望返回结果

         #region ATN(通知)期望返回结果

         ///

         ///客户购买时:发货成功,支付宝将设置该交易状态为已经发货,结束发送

         ///客户收货时:处理成功,结束发送

         ///

         public const string Y="Y";

         ///

         ///客户购买时:发货失败,支付宝不改变交易状态,重新发送

         ///客户收货时:处理失败,重新发送

         ///

         public const string N="N";

         #endregion

     }

     ///

     /// Qgzxol.AlipayKernel.Notify.ATResult

     /// AT查询的结果,当我们收到通知后,我们需要查询服务器,以检验这个通知的有效性,

     ///通常响应test事件时不进行查询,若我们配置为true则响应服务器,服务器发送消息过来即可.

     ///只有在响应sendOff和checkOut事件时,我们才需要到服务器查询.

     ///

     public class ATResult

     {

         //表2-8 AT(查询)期待返回结果

         #region AT(查询)期待返回结果

         ///

         ///传入的参数无效

         ///

         public const string invalid="invalid";

         ///

         ///查询到的通知任务的状态是“新建的通知任务”

         ///

         public const string true_="true";

         ///

         ///查询到的通知任务的状态不是“新建的通知任务”,或超时(通知发起1分钟内该通知可被查询)

         ///

          public const string false_="false";

         #endregion

     }

}

4. F:/WinLin/NetShop/AlipayKernel/Md5.cs

using System;

//======================================================================

//--------The Common Interface For Alipay, Powered by Qgzxol------------

//-------支付宝的接口通用处理方法,中国高校勤工助学网站@版权所有.--------

//-------Author:WinLin.   Email:[email protected] QQ:398510617------

//======================================================================

namespace Qgzxol.AlipayKernel

{

     ///

     /// Qgzxol.AlipayKernel.Md5

     ///获取md5的通用加密方法.

     ///来源:http://dev.alipay.com/forum/viewthread.php?tid=538&extra=page%3D1

     /// md5也有编码问题.

     ///

     public class Md5

     {

         ///

         ///获取md5加密字符串重载.

         ///默认gb2312编码格式.

         ///

         ///源字符串

         ///加密后的字符串.

         public static string GetMD5(string s)

         {

              return GetMD5(s,"gb2312");

         }

         ///

         ///获取md5加密字符串

         ///

         ///源字符串

         ///编码格式

         ///加密后的字符串

         public static string GetMD5(string s,string encoding)

         {

              System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();

              byte[] t = md5.ComputeHash(System.Text.Encoding.GetEncoding(encoding).GetBytes(s));

              System.Text.StringBuilder sb = new System.Text.StringBuilder(32);

              for (int i = 0; i < t.Length; i++)

              {

                   sb.Append(t[i].ToString("x").PadLeft(2, '0'));

              }

              return sb.ToString();

         }

     }

}

5. F:/WinLin/NetShop/AlipayKernel/Object.cs

using System;

using System.Collections;

using System.Net;

using System.IO;

//======================================================================

//--------The Common Interface For Alipay, Powered by Qgzxol------------

//-------支付宝的接口通用处理方法,中国高校勤工助学网站@版权所有.--------

//-------Author:WinLin.   Email:[email protected] QQ:398510617------

//======================================================================

//下面是处理核心基类,完成PayTo.Object和Notify.Object的共同部分.

namespace Qgzxol.AlipayKernel

{

     ///

     /// Qgzxol.AlipayKernel.Object

     ///处理事务的核心逻辑.

     ///完成PayTo.Object和Notify.Object的共同部分.

     ///

     public class Object

     {

         #region构造函数和成员的定义区域

         ///

         ///成员哈希表.

         ///存储了键(key)和值(value).

         ///键一般是设置的键枚举.

         ///

         private Hashtable elem=null;

         ///

         ///成员哈希表.

         ///存储了键(key)和值(value).

         ///键一般是设置的键枚举.

         ///

         protected Hashtable Elem

         {

              get

              {

                   return this.elem==null? new Hashtable():this.elem;

              }

              set

              {

                   this.elem=value;

              }

         }

         ///

         ///支付宝的安全验证码

         ///

         private string valiCode=null;

         ///

         ///支付宝的安全验证码

         ///

         public string ValiCode

         {

              set

              {

                   this.valiCode=value;

              }

              get

              {

                   //默认为winlin的安全验证码

                   if(this.valiCode==null)

                   {

                       this.valiCode=Qgzxol.AlipayKernel.Config.valiCode;

                   }

                   return this.valiCode;

              }

         }

         ///

         ///支付宝的卖家邮箱

         ///

         private string seller=null;

         ///

         ///支付宝的卖家邮箱

         ///

         public string Seller

         {

              set

              {

                   this.seller=value;

              }

              get

              {

                   //默认为winlin的邮箱

                   if(this.seller==null)

                   {

                       this.seller=Qgzxol.AlipayKernel.Config.seller;

                   }

                   return this.seller;

              }

         }

         ///

         ///生成摘要的md5的编码类型.

          ///中文推荐gb2312或者是gbk.

         ///

         private string encoding=null;

         ///

         ///生成摘要的md5的编码类型.

         ///中文推荐gb2312或者是gbk.

         ///

         public string Encoding

         {

              set

              {

                   this.encoding=value;

              }

              get

              {

                   //默认为gb2312,.netFramework1.1使用.

                   if(this.encoding==null)

                   {

                       this.encoding=Qgzxol.AlipayKernel.Config.encoding;

                   }

                   return this.encoding;

              }

         }

         ///

         ///页面对象,构造字符串时候使用.

         ///

         protected System.Web.UI.Page page=null;

         ///

         ///默认构造函数

         ///

         public Object(System.Web.UI.Page page)

         {

              //init the hashTable member.

              if(this.elem==null)

              {

                   this.elem=new Hashtable();

              }

              //init page

              if(this.page==null)

              {

                   this.page=page;

              }

         }

         public Object(System.Web.UI.Page page,string seller,string valiCode)

         {

              //init the hashTable member.

              if(this.elem==null)

              {

                   this.elem=new Hashtable();

              }

              //init page

              if(this.page==null)

              {

                   this.page=page;

              }

              this.Seller=seller;

              this.ValiCode=valiCode;

         }

         #endregion

         #region常规成员函数定义区域

         ///

         ///添加配置键到对象

         ///

         ///键枚举,用枚举:Qgzxol.AlipayKernel.Keys

         ///键枚举所对应的值.

         ///返回添加的结果,添加成功返回true,否则返回false

         public bool Add(object key,object value)

         {

              if(this.elem==null)

                   return false;

              //save key-value into hashtable

              this.elem[key]=value;

              return true;

         }

         ///

         ///从配置对象中移除值.

         ///

         ///键枚举,用枚举:Qgzxol.AlipayKernel.Keys

         ///返回删除的结果,删除成功返回true,否则返回false

         public bool Remove(object key)

         {

              if(this.elem==null)

                   return false;

              //find key from hashtable

              if(this.elem.ContainsKey(key)==true)

              {

                   this.elem.Remove(key);

                   return true;

              }

              return false;

         }

         ///

         ///返回配置键所对应的值

         ///

         ///键枚举,用枚举:Qgzxol.AlipayKernel.Keys

         ///若值存在,返回值;否则返回null.

         public string GetValue(object key)

         {

              if(this.elem==null)

                   return null;

              //get key's value from hashtable

              return Convert.ToString(this.elem[key]);

         }

         ///

         ///查看键在对象中是否存在.

         ///

         ///键枚举,用枚举:Qgzxol.AlipayKernel.Keys

         ///若键所对应的对象存在,返回true;否则返回false

         public bool IsExists(object key)

         {

              if(this.elem==null)

                   return false;

              //judge if the key exists in hashtable

              return this.elem.ContainsKey(key);

         }

         ///

         ///设置验证码对象

         ///

         ///验证码

         ///返回设置的结果,设置成功返回true;否则返回false.

         public bool SetValiCode(object code)

         {

              if(code==null)

                   return false;

              //set valiCode

              this.valiCode=Convert.ToString(code);

              return true;

         }

         #endregion

     }

}

//下面是payTo命名空间,主要处理发送事务.

//主要是生成payto查询字符串.

namespace Qgzxol.AlipayKernel.PayTo

{

     ///

     /// Qgzxol.AlipayKernel.Object.PayTo

     ///主要处理PayTo事务的核心逻辑.

     ///

     public class Object : Qgzxol.AlipayKernel.Object

     {

         #region构造函数定义区域

         ///

         ///默认构造函数

         ///

         public Object(System.Web.UI.Page page):base(page)

         {

         }

         public Object(System.Web.UI.Page page,string seller,string valiCode):base(page,seller,valiCode)

         {

         }

         #endregion

         #region成员函数定义区域,主要是生成url的函数定义

         ///

         ///根据配置对象来获取url.

         ///

         ///返回配置对象所对应的url

         public string GetUrl()

         {

              if(this.page==null)

                   return null;

              #region实例字符串

              //实例字符串为:

              //https://www.alipay.com/payto:[email protected]?cmd=0001&subject=%c6%bf%d7%d3&body=Bottle&buyer_msg=hello,bottle&ac= 9c 93c1ebc 2f 282291f24227bd 002f 5f4

              //我们的返回字符串是下面部分:

              //payto:[email protected]?cmd=0001&subject=%c6%bf%d7%d3&body=Bottle&buyer_msg=hello,bottle&ac= 9c 93c1ebc 2f 282291f24227bd 002f 5f4

              //此字符串的key无先后之分.

              #endregion

              string head="";//payto.

              #region构造payto头,初始化head变量

              head+="https://www.alipay.com/payto:"+this.Seller+"?";

              //https://www.alipay.com/payto:[email protected]?

              #endregion

              string ac="";//ac摘要

              string eInner="";//编码后的字符串

              #region按照固定的序列初始化ac,和初始化eInner

              for(int i=0;i

              {

                   this.getAcSerial(Qgzxol.AlipayKernel.PayTo.Keys.serialFormat[i],ref ac,ref eInner);

              }

              //去掉最后的&号

              if(eInner.Length>0&&eInner.IndexOf("&",eInner.Length-1)!=-1)

              {

                   eInner=eInner.Substring(0,eInner.Length-1);

              }

              #endregion

              #region构造ac摘要,初始化ac

              ac=ac.Replace("=","");

              ac=ac.Replace("&","");

              //添加安全码部分.

              //实例为:ac+this.ValiCode

              ac+=this.ValiCode;

              //获取的完整ac是:

              //cmd0001subject瓶子bodyBottlebuyer_msghello,[email protected] 8c572miml8bsg0bh2qdutzxl

              //取摘要

              ac=Qgzxol.AlipayKernel.Md5.GetMD5(ac,this.Encoding);

              #endregion

              string url="";//完整的url

              #region构造完整的url

              url=head+eInner+"&ac="+ac;

              #endregion

              return url;

         }

         ///

         ///获取指定的键中的

         ///

         ///需要检测的键

         ///存储的目标字符串

         private void getAcSerial(string key,ref string ac,ref string eInner)

         {

              if(this.page==null)

                   return;

              //单独处理seller,因为它不能添加到url中发送,而且需要用来构造ac

              if(key==Qgzxol.AlipayKernel.PayTo.Keys.seller)

              {

                   ac+=key;

                   ac+="=";

                   ac+=this.Seller;

                   return;

              }

              //若键在容器中存在,我们就添加到构造和url中,否则放弃添加.

              if(this.Elem.ContainsKey(key))

              {

                   ac+=key;//inner="subject"

                   ac+="=";//inner="subject="

                   ac+=Convert.ToString(this.Elem[key]);//inner="subject=瓶子"

                   ac+="&";//inner="subject=瓶子&"

                   eInner+=key;//inner="subject"

                   eInner+="=";//inner="subject="

                   eInner+=this.page.Server.UrlEncode

                       (Convert.ToString(this.Elem[key]));//inner="subject=瓶子"

                   eInner+="&";//inner="subject=瓶子&"

              }

         }

         #endregion

     }

}

//下面是Notify命名空间,主要处理ATN事务.

//主要根据支付宝的通知进行查询和处理.

namespace Qgzxol.AlipayKernel.Notify

{

     ///

     /// Qgzxol.AlipayKernel.Notify.Object

     ///主要处理Notify事务的核心逻辑.

     ///用于验证支付宝的响应和向支付宝返回请求.

     ///

     public class Object : Qgzxol.AlipayKernel.Object

     {

         #region checkOff和checkOut事件定义区

         ///

         /// checkOff事件定义

         ///

         public event SendOffHandler sendOff;

         ///

         /// checkOut事件定义

         ///

         public event CheckOutHandler checkOut;

         ///

         /// checkOff事件激发函数

         ///

         ///事件源,默认为本类对象.

         public void OnSendOff(object sender)

         {

              this.sendOff(sender);

         }

         ///

         /// chenckOut事件激发函数

         ///

         ///事件源,默认为本类对象

         public void OnCheckOut(object sender)

         {

              this.checkOut(sender);

         }

         #endregion

         #region构造函数和属性定义区域

         ///

         ///默认构造函数

         ///

         public Object(System.Web.UI.Page page):base(page)

         {

         }

         public Object(System.Web.UI.Page page,string seller,string valiCode):base(page,seller,valiCode)

         {

         }

         ///

         ///处理请求的返回字符串,

         ///默认是N,不进行处理.当我们在激发的checkOff和checkOut事件中进行处理时;

         ///会根据本对象的数据,判断数据库中的处理情况,从而修改这个状态.

         ///

         public string returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.N;

         ///

         ///原始的从支付宝服务器传递过来的解码后的字符串.

         ///不包含ac字符串.

         ///

         public string originalTxt="";

         ///

         ///原始的从支付宝服务器传递过来的ac摘要字符串.

          ///

         public string ac="";

         #endregion

         #region反解析url,侦听支付宝服务器的处理请求

         ///

         ///根据通知,反解析Keys.

         ///因为这种工作模式很像线程和Socket的侦听,所以,

         ///改变这个函数为StartListener,意思是指开始侦听.

         ///实际上,这个类的接口是两个事件:checkOff和checkOut,

         ///我们只要给这两个事件添加处理代码就可以了.

         ///

         ///返回反解结果

         public bool StartListener()

         {

              #region初始化页面和返回值以及校验页面

              //做基本校验.

              if(this.page==null)

                   return false;

              //初始化返回值,默认是N,没有处理.

              this.returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.N;

              //一般要求清除页面输出.

              this.page.Visible=Qgzxol.AlipayKernel.Config.isHidePage;

              #endregion

              #region把服务器的消息记录到数据库

              //若需要的记录

              if(Qgzxol.AlipayKernel.Config.isRegisterATN==true)

              {

                   try

                   {

                       string _url=this.page.Request.Url.AbsolutePath;

                       _url+=this.page.Request.Url.Query.ToString();

                       string _ip=this.page.Request.UserHostAddress;

                       string _os=this.page.Request.Browser.Platform;

                       if(_url.Length>1000)

                            _url=_url.Substring(1000-_url.Length);

                       if(_ip.Length>50)

                            _ip=_ip.Substring(50-_ip.Length);

                       if(_os.Length>30)

                            _os=_os.Substring(30-_os.Length);

                       Qgzxol.QgzxolCore.DataCore.ExecuteNonQuery

                            (Qgzxol.AlipayKernel.Config.registerATNSqlConnStr

                            ,"proc_ATNRegister_ServerATNHistroy_RegisterNew"

                            ,new object[]{_url,_ip,_os});

                   }

                   catch{}

              }

              #endregion

              //md5摘要验证

              #region从QueryString取值,并从ac验证合法性

              //获取摘要值

              this.ac=this.page.Request.QueryString[Qgzxol.AlipayKernel.Notify.Keys.ac];

              if(this.ac==null||this.ac=="")

              {

                   return false;

              }

              //获取完整的request值.

              string url="";

              for(int i=0;i

              {

                   this.getUrlDeSerial(Qgzxol.AlipayKernel.Notify.Keys.serialFormat[i],ref url,ref this.originalTxt);

              }

              //ac="adfee01adf01d4d1d02ads47w5dgdes 01a"

              //url="[email protected]_namewinlinbuyer_addressCSUbuyer_zipcode410012buyer_tel8710041buyer_mobile13017276840actionsellerOffdate20051215"

              //处理原始字符串,去掉最后的&号

              if(this.originalTxt.Length>0&&this.originalTxt.IndexOf("&",this.originalTxt.Length-1)!=-1)

              {

                   this.originalTxt=this.originalTxt.Substring(0,this.originalTxt.Length-1);

              }

              //验证摘要值

              url+=this.ValiCode;

              url=Qgzxol.AlipayKernel.Md5.GetMD5(url);

              if(this.ac!=url)

              {

                   return false;

              }

              #endregion

              #region action的test验证

              //做action前期验证,若为test,表示服务器的测试请求,

              //返回Y要求服务器进行重发.

              if(this.GetValue(Qgzxol.AlipayKernel.Notify.Keys.action)

                   ==Qgzxol.AlipayKernel.Notify.ServerNotifyType.test)

              {

                   if(Qgzxol.AlipayKernel.Config.isResponseTest==true)

                       this.returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.Y;

                   this.page.Response.Clear();

                   this.page.Response.Write(this.returnTxt);

                   return true;

              }

              #endregion

              //查询验证

              #region发送查询字符串到支付宝服务器进行验证

              string query="http://notify.alipay.com/trade/notify_query.do?";

              query+="msg_id=" + this.GetValue(Qgzxol.AlipayKernel.Notify.Keys.msg_id);

              query+="&email=" + this.Seller;

              query+="&order_no=" + this.GetValue(Qgzxol.AlipayKernel.Notify.Keys.order_no);

              string msg=Qgzxol.AlipayKernel.Notify.ATResult.invalid;

              //读取查询页面,一般只是一个字符而已.

              for(int i=0;i<100;i++)

              {

                   try

                   {

                       Uri uri=new Uri(query);

                       WebRequest wr=WebRequest.Create(uri);

                       Stream stream=wr.GetResponse().GetResponseStream();

                       StreamReader reader=new StreamReader(stream);

                       msg=reader.ReadToEnd();

                       break;

                   }

                   catch{}

              }

              //进行查询验证

              if(msg==Qgzxol.AlipayKernel.Notify.ATResult.invalid)

              {

                   this.returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.N;

                   this.page.Response.Clear();

                   this.page.Response.Write(this.returnTxt);

                   return false;

              }

              #endregion

              //action的其余验证

              //事件触发,可以在不同的地方进行处理;

              //若我们可以在声明这个对象时,进行一个处理对象的初始化;

              //并把这个处理对象的处理函数注册到这个事件中,这样,我们的处理对象就独立于本类库进行处理了.

              //只是记住接口:若处理相关的事务完毕,则把本对象的returnTxt赋值为Y即可.

              #region action的sendOff验证

              //做action验证,若为checkOff,表示有合法买主订单,

              //我们触发这个事件,并把本对象传递给事件处理机构作为数据源.

              if(this.GetValue(Qgzxol.AlipayKernel.Notify.Keys.action)

                   ==Qgzxol.AlipayKernel.Notify.ServerNotifyType.sendOff)

              {

                   this.OnSendOff(this);

                   this.page.Response.Clear();

                   this.page.Response.Write(this.returnTxt);

                   return true;

              }

              #endregion

              #region action的checkOut验证

              //做action验证,若为checkOut,表示有合法买主收到订货后的确认信息,

              //我们触发这个事件,并把本对象传递给事件处理机构作为数据源.

              if(this.GetValue(Qgzxol.AlipayKernel.Notify.Keys.action)

                   ==Qgzxol.AlipayKernel.Notify.ServerNotifyType.checkOut)

              {

                   this.OnCheckOut(this);

                   this.page.Response.Clear();

                   this.page.Response.Write(this.returnTxt);

                   return true;

              }

              #endregion

              #region action非三种服务器通知的处理

              //当上面三种事件都没有处理时,就是没有action字段时候.

              this.returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.N;

              this.page.Response.Clear();

              this.page.Response.Write(this.returnTxt);

              return true;

              #endregion

         }

         ///

         ///从url反序列化到哈希表和url;

         ///按照固定的序列添加存在的值到目标中.

         ///

         ///

         ///存储值的url

         private void getUrlDeSerial(string key,ref string url,ref string originalTxt)

         {

              string obj=this.page.Request.QueryString[key];

              if(obj!=null)//注意,对方加密的形式是:key空也算进去,我们只需要验证存在(!null)即可.&&obj!=""

              {

                   obj=this.page.Server.UrlDecode(obj);

                   //filter some attack words

                   obj=obj.Replace(";","");

                   obj=obj.Replace("'","");

                   obj=obj.Replace("&","");

                   obj=obj.Replace(" ","");

                   obj=obj.Replace(" ","");

                   obj=obj.Replace("%20","");

                   obj=obj.Replace("--","");

                   obj=obj.Replace("==","");

                   obj=obj.Replace("<","");

                   obj=obj.Replace(">","");

                   obj=obj.Replace("%","");

                   //add it into elem hashTable

                   this.Add(key,obj);

                   //add it into string url

                   url+=key;

                   url+=obj;

                   //add it into originalTxt

                   originalTxt+=key;

                   originalTxt+="=";

                   originalTxt+=obj;

                   originalTxt+="&";

              }

         }

         #endregion

     }

     ///

     /// checkOut事件委托

     ///

     public delegate void CheckOutHandler(object sender);

     ///

     /// checkOff事件委托

     ///

     public delegate void SendOffHandler(object sender);

}

三.简化说明

//======================================================================

//--------The Common Interface For Alipay, Powered by Qgzxol------------

//-------支付宝的接口通用处理方法,中国高校勤工助学网站@版权所有.--------

//-------Author:WinLin.   Email:[email protected] QQ:398510617------

//======================================================================

1.怎样处理payTo过程:
在页面中添加一个按纽,双击,添加代码如下:

private void Btn_Buy_Click(object sender, System.Web.UI.ImageClickEventArgs e)

{

     this.o=new Qgzxol.AlipayKernel.PayTo.Object

           (this,"[email protected]","14xdd11zhcoeg 8a60wagv7rnbddffyl2");

     o.Add(Qgzxol.AlipayKernel.PayTo.Keys.subject,"瓶子");

     o.Add(Qgzxol.AlipayKernel.PayTo.Keys.price,"0.01");

     o.Add(Qgzxol.AlipayKernel.PayTo.Keys.number,"1");

     o.Add(Qgzxol.AlipayKernel.PayTo.Keys.transport,"3");//注意:只有为3时,我们才可以通过返回Y来改变交易状态.

     o.Add(Qgzxol.AlipayKernel.PayTo.Keys.order_no,"200512162057");

     o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer,"[email protected]");

     this.Response.Redirect(o.GetUrl());

}

上面只使用了几条信息,可以继续添加到对象.
2.怎样处理ATN服务器通知
服务器通知包括test,sendoff和checkOut通知.
这三个通知在本项目中均封装了,只要您在支付宝中设置”通知url”即可.
处理sendOff通知,只需要注册一个函数到对象中,若需要返回Y,则需要重设它的returnTxt属性即可,假设我们的通知url为Listener.aspx页面,它的典型代码如下:

private void Page_Load(object sender, System.EventArgs e)

{

     if(this.Page.IsPostBack==false)

     {

         Qgzxol.AlipayKernel.Notify.Object o=new Qgzxol.AlipayKernel.Notify.Object(this);

         o.sendOff+=new Qgzxol.AlipayKernel.Notify.SendOffHandler(this.ProcessSendOff);

         o.checkOut+=new Qgzxol.AlipayKernel.Notify.CheckOutHandler(this.ProcessCheckOut);

         o.StartListener();

     }

}

public void ProcessSendOff(object sender)

{

     Qgzxol.AlipayKernel.Notify.Object o=(Qgzxol.AlipayKernel.Notify.Object)sender;

     ///测试期间,我们只是设定这个交易发货.

     ///在处理的时候,我们一般是把从服务器送来的发货请求sendOff保存到数据库,

     ///然后手动发货,发货后,我们向服务器送去发货通知,这就是修改returnTxt=Y即可.

     o.returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.Y;

}

public void ProcessCheckOut(object sender)

{

     Qgzxol.AlipayKernel.Notify.Object o=(Qgzxol.AlipayKernel.Notify.Object)sender;

     ///测试期间,我们只是设定这个交易发货.

     ///在处理的时候,我们一般是把从服务器送来的发货请求checkOut保存到数据库,

     ///然后查询是否收到款,收款后,我们向服务器送去已经收款通知,这就是修改returnTxt=Y     o.returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.Y;

}

4关于测试的建议
您引用这个Qgzxol.AlipayKernel.dll后,注册两个账号,用银行卡给这两个账号充0.01-1.0元即可,然后用账号1买账号2的东西.
注意,不需要通过”信息*身份证*银行卡”的认证就可以买卖东西了.
开启vs.net 2003/2005的调试进行访问的捕获即可.
5更多详细的说明
请参考这个文件AlipayKernel接口说明.doc.
四.详细说明

//======================================================================

//--------The Common Interface For Alipay, Powered by Qgzxol------------

//-------支付宝的接口通用处理方法,中国高校勤工助学网站@版权所有.--------

//-------Author:WinLin.   Email:[email protected] QQ:398510617------

//======================================================================

1..项目内容
1.本项目包含了集成Alipay(支付宝)的所有必须逻辑.可以直接使用在asp.net中进行调用.
2.本项目遵守支付宝商家工具接口说明文档.pdf规范,所以接口都和此规范一致.
3.本项目用到的名词:
l         AliPay文档    支付宝商家工具接口说明文档.pdf
l         ValiCode         验证码,即是支付宝的”安全校验码”,这是生成md5校验的必要验证码.
l         Key                键.就是ApliPay文档中附录中提到的各个参数名称.
l         Value              值.就是对应上面的键的值.
4.主要包含的逻辑是:
l         Add(key,value)       添加对应key的value值.
l         Remove(key)         移除存在的key的值.
l         GetUrl()                生成url,根据提供的信息生成url.
l         GetValue (key)                     获取key对应的值.
l         IsExists(key)         获取布尔值,看指定的key是否存在于对象中.
l         SetValiCode(code) 设置ValiCode验证码.
5.包含各个参数的属性调用.
详见各个参数.
2..函数说明:
1>.GetUrl()
由于涉及到编码问题,所以规定如下:
GetUrl只返回https://www.alipay.com/后面的url字符串,使用时,你可以根据gb2312/gbk来设置url的编码格式,就是说,使用GetUrl函数的标准方法如下:

              url=this.Server.UrlEncode(Object.GetUrl());

              url="https://www.alipay.com/"+url;
url就是我们最终的url了.
2>. o.sendOff
这是一个sendOff通知的处理逻辑.调用方法是:
建立一个函数ProcessSendOff,然后利用下面的代码注册到事件中:
o.sendOff+=new Qgzxol.AlipayKernel.Notify.SendOffHandler(this.ProcessCheckOff);
3>.o.checkOut
这是checkOut事件的处理逻辑,调用方法是:
建立一个函数ProcessCheckOut,然后利用下面的代码注册到事件中:
o.checkOut+=new Qgzxol.AlipayKernel.Notify.CheckOutHandler(this.ProcessCheckOut);
3..实例说明(简化)
1>.怎样处理payTo过程:
在页面中添加一个按纽,双击,添加代码如下:

private void Btn_Buy_Click(object sender, System.Web.UI.ImageClickEventArgs e)

{

     this.o=new Qgzxol.AlipayKernel.PayTo.Object

           (this,"[email protected]","14xdd11zhcoeg 8a60wagv7rnbddffyl2");

//this.o=new Qgzxol.AlipayKernel.PayTo.Object(this,"商家邮箱","商家安全验证码");

     o.Add(Qgzxol.AlipayKernel.PayTo.Keys.subject,"瓶子");

     o.Add(Qgzxol.AlipayKernel.PayTo.Keys.price,"0.01");

     o.Add(Qgzxol.AlipayKernel.PayTo.Keys.number,"1");

     o.Add(Qgzxol.AlipayKernel.PayTo.Keys.order_no,"200512162057");

     o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer,"[email protected]");

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.cmd,"0001");

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.body,"本人长期代写小学寒……");

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.express_fee,"1000");

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.ems_fee,"5000");//新增EMS方式。

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.ordinary_fee,"5000");

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.type,"4");

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.url,"http://202.197.75.231/Stat/Test/winlin.htm");

     o.Add(Qgzxol.AlipayKernel.PayTo.Keys.transport,"3");//注意:只有为3时,我们才可以通过返回Y来改变交易状态.

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.readonly_,"false");

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_msg,"Hello");

//   //o.Add(Qgzxol.AlipayKernel.PayTo.Keys.seller,"[email protected]");

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_name,"小欣");

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_address,"CSU");

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_zipcode,"410012");

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_tel,"*******");

//   o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_mobile,"1354968****");

     this.Response.Redirect(o.GetUrl());

}

上面只使用了几条信息,可以继续添加到对象.
2>.怎样处理ATN服务器通知
服务器通知包括test,sendoff和checkOut通知.
这三个通知在本项目中均封装了,只要您在支付宝中设置”通知url”即可.
处理sendOff通知,只需要注册一个函数到对象中,若需要返回Y,则需要重设它的returnTxt属性即可,假设我们的通知url为Listener.aspx页面,它的典型代码如下:

         private void Page_Load(object sender, System.EventArgs e)

         {

              if(this.Page.IsPostBack==false)

              {

         Qgzxol.AlipayKernel.Notify.Object o=new Qgzxol.AlipayKernel.Notify.Object(this);

         o.sendOff+=new Qgzxol.AlipayKernel.Notify.SendOffHandler(this.ProcessSendOff);

         o.checkOut+=new Qgzxol.AlipayKernel.Notify.CheckOutHandler(this.ProcessCheckOut);

         o.StartListener();

              }

         }

         public void ProcessSendOff(object sender)

         {

              Qgzxol.AlipayKernel.Notify.Object o=(Qgzxol.AlipayKernel.Notify.Object)sender;

              ///测试期间,我们只是设定这个交易发货.

              ///在处理的时候,我们一般是把从服务器送来的发货请求sendOff保存到数据库,

              ///然后手动发货,发货后,我们向服务器送去发货通知,这就是修改returnTxt=Y即可.

              o.returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.Y;

         }

         public void ProcessCheckOut(object sender)

         {

              Qgzxol.AlipayKernel.Notify.Object o=(Qgzxol.AlipayKernel.Notify.Object)sender;

              ///测试期间,我们只是设定这个交易发货.

              ///在处理的时候,我们一般是把从服务器送来的发货请求checkOut保存到数据库,

              ///然后查询是否收到款,收款后,我们向服务器送去已经收款通知,这就是修改returnTxt=Y          o.returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.Y;

         }

后面给出了一个详细注释的版本.
4..sendOffcheckOff通知处理页面的详细说明
下面的Listener.aspx给出了详细的说明.

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.SessionState;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

namespace Qgzxol.Trade.TradeMd5

{

     ///

     /// Listener是响应支付宝服务器事件的一个页面侦听器,

     ///响应test,sendOff和checkOut三个事件并进行相关的处理..

     ///

     public class Listener : System.Web.UI.Page

     {

         private void Page_Load(object sender, System.EventArgs e)

         {

              if(this.Page.IsPostBack==false)

              {

         Qgzxol.AlipayKernel.Notify.Object o=new Qgzxol.AlipayKernel.Notify.Object(this);

         o.sendOff+=new Qgzxol.AlipayKernel.Notify.SendOffHandler(this.ProcessSendOff);

         o.checkOut+=new Qgzxol.AlipayKernel.Notify.CheckOutHandler(this.ProcessCheckOut);

         o.StartListener();

              }

         }

         ///

         ///处理sendOff事件的逻辑;

         ///外部逻辑处理sendOff事件.

         /// sendOff描述为:您是否已经发货?

         ///若我们已经发了货,则需要把sender对象的returnTxt置为Y;否则为N.

         ///一般的逻辑是:

         ///收到这条信息则在本地数据库中搜索,若没有记录,建立记录;

         ///若本地数据库中有这个记录,且这个记录的标记为:发货.那么我们就可以回答:已经发货了.

         ///核心关键字:处理后,修改sender的returnTxt属性.

         ///

         ///事件源,是Qgzxol.AlipayKernel.Notify.Object对象,包含了交易信息

         public void ProcessSendOff(object sender)

         {

              Qgzxol.AlipayKernel.Notify.Object o=(Qgzxol.AlipayKernel.Notify.Object)sender;

              ///测试期间,我们只是设定这个交易发货.

              ///在处理的时候,我们一般是把从服务器送来的发货请求sendOff保存到数据库,

              ///然后手动发货,发货后,我们向服务器送去发货通知,这就是修改returnTxt=Y即可.

              o.returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.Y;

         }

         ///

         ///处理checkOut事件的逻辑;

         ///外部逻辑处理checkOut事件.

         /// checkOut描述为:您是否已经收到交易款了?

         ///若我们已经收到了交易的交易款,则需要把sender对象的returnTxt置为Y;否则为N.

         ///一般的逻辑是:

         ///收到这条信息则在本地数据库中搜索,若没有记录,建立记录;

         ///若本地数据库中有这个记录,且这个记录的标记为:已经收款了.那么我们就可以回答:已经收款了.

         ///核心关键字:处理后,修改sender的returnTxt属性.

         ///

         ///事件源,是Qgzxol.AlipayKernel.Notify.Object对象,包含了交易信息

         public void ProcessCheckOut(object sender)

         {

              Qgzxol.AlipayKernel.Notify.Object o=(Qgzxol.AlipayKernel.Notify.Object)sender;

              ///测试期间,我们只是设定这个交易发货.

              ///在处理的时候,我们一般是把从服务器送来的发货请求checkOut保存到数据库,

              ///然后查询是否收到款,收款后,我们向服务器送去已经收款通知,这就是修改returnTxt=Y

              o.returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.Y;

         }

         #region Web 窗体设计器生成的代码

         override protected void OnInit(EventArgs e)

         {

              InitializeComponent();

              base.OnInit(e);

         }

         private void InitializeComponent()

         {   

              this.Load += new System.EventHandler(this.Page_Load);

         }

         #endregion

     }

}

5..web.config中的一些配置
本项目亦支持web.config中配置关键信息.
具体说明如下(下面是web.config的结尾部分):

--by winlin,QQ:3698510617 Email:[email protected]>

 <appSettings>

     <addkey="seller"value="[email protected]"/>--商家,默认的全局商家,在多商家的情况下可以设置商家-->

     <addkey="valiCode"value="14xdd11zhcoeg 8a60wagv7rnbddffyl2"/>--商家的验证码,默认的全局商家的验证码,在多商家的情况下可以设置商家-->

     <addkey="encoding"value="gb2312"/>--编码,默认的编码,在md5取摘要时需要这个字段.-->

     --服务器响应字段配置-->

     <addkey="isHidePage"value="true"/>--是否在响应服务器时不输出多余信息,如若我们在收取了客户的订单后,需要向alipay服务器中回执Y字符,若此属性为true,则只是回执一个Y字符,不会有html的其他信息;此字段在系统工作模式下,需要为true.-->

     <addkey="isResponseTest"value="true"/>--是否响应服务器发送的test信号.若我们很久没有处理服务器的用户订单,也就是我们没有发货给订货的客户,那么服务器会重试发送信息到我们的系统.这个test就是在重试很多次后,服务器认为我们的系统崩溃的一种试探.若我们修复了系统,可以处理信息了,则响应服务器以获取积累的信息-->

 appSettings>

configuration>

五.使用实例
1. http://localhost/TradeMd5/Default.aspx

         <formid="Form1"method="post"runat="server">

              <FONTface="宋体">

                   <asp:Labelid="Label7"style="Z-INDEX: 103; LEFT: 168px; POSITION: absolute; TOP: 104px"runat="server"

                       Font-Size="12px">单价:3.5$asp:Label>

                   <asp:ImageButtonid="ImageButton3"style="Z-INDEX: 112; LEFT: 152px; POSITION: absolute; TOP: 456px"

                       runat="server"ImageUrl="Images/alipay_bwrss.gif">asp:ImageButton>

                   <asp:Labelid="Label4"style="Z-INDEX: 111; LEFT: 152px; POSITION: absolute; TOP: 432px"runat="server"

                       Font-Size="12px">单价:无价asp:Label>

                   <asp:Labelid="Label3"style="Z-INDEX: 110; LEFT: 152px; POSITION: absolute; TOP: 400px"runat="server"

                       Font-Size="12px">商品名称:瓶子asp:Label>

                   <asp:ImageButtonid="ImageButton1"style="Z-INDEX: 107; LEFT: 152px; POSITION: absolute; TOP: 312px"

                       runat="server"ImageUrl="Images/alipay_bwrss.gif">asp:ImageButton>

                   <asp:Labelid="Label2"style="Z-INDEX: 106; LEFT: 160px; POSITION: absolute; TOP: 280px"runat="server"

                       Font-Size="12px">单价:无价asp:Label>

                   <asp:Labelid="Label1"style="Z-INDEX: 105; LEFT: 152px; POSITION: absolute; TOP: 248px"runat="server"

                       Font-Size="12px">商品名称:狂笨asp:Label>

                   <asp:Labelid="Label6"style="Z-INDEX: 102; LEFT: 168px; POSITION: absolute; TOP: 72px"runat="server"

                       Font-Size="12px">商品名称:WinLinasp:Label><IMGstyle="Z-INDEX: 101; LEFT: 24px; POSITION: absolute; TOP: 24px"src="Images/winlin.jpg">

                   <asp:ImageButtonid="ImageButton2"style="Z-INDEX: 100; LEFT: 160px; POSITION: absolute; TOP: 136px"

                       runat="server"ImageUrl="Images/alipay_bwrss.gif">asp:ImageButton> FONT>

              <IMGstyle="Z-INDEX: 104; LEFT: 40px; POSITION: absolute; TOP: 248px"src="Images/bb.jpg"><IMGstyle="Z-INDEX: 109; LEFT: 48px; POSITION: absolute; TOP: 392px"src="Images/avatar.jpg">

         form>

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.SessionState;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

namespace Qgzxol.Trade.TradeMd5

{

     ///

     /// _Default 的摘要说明。

     ///

     public class _Default : System.Web.UI.Page

     {

         protected System.Web.UI.WebControls.ImageButton ImageButton2;

         protected System.Web.UI.WebControls.Label Label6;

         protected System.Web.UI.WebControls.Label Label7;

         protected System.Web.UI.WebControls.Label Label1;

         protected System.Web.UI.WebControls.Label Label2;

         protected System.Web.UI.WebControls.ImageButton ImageButton1;

         protected System.Web.UI.WebControls.Label Label3;

         protected System.Web.UI.WebControls.Label Label4;

         protected System.Web.UI.WebControls.ImageButton ImageButton3;

         Qgzxol.AlipayKernel.PayTo.Object o=null;

    

         private void Page_Load(object sender, System.EventArgs e)

         {

              if(this.Page.IsPostBack==false)

              {

                   //编码GBK

                   this.Response.ContentEncoding=System.Text.Encoding.GetEncoding("gb2312");

              }

         }

         #region Web 窗体设计器生成的代码

         override protected void OnInit(EventArgs e)

         {

              //

              // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。

              //

              InitializeComponent();

              base.OnInit(e);

         }

        

         ///

         ///设计器支持所需的方法 - 不要使用代码编辑器修改

         ///此方法的内容。

         ///

         private void InitializeComponent()

         {   

              this.ImageButton2.Click += new System.Web.UI.ImageClickEventHandler(this.ImageButton2_Click);

              this.ImageButton1.Click += new System.Web.UI.ImageClickEventHandler(this.ImageButton1_Click);

              this.ImageButton3.Click += new System.Web.UI.ImageClickEventHandler(this.ImageButton3_Click);

              this.Load += new System.EventHandler(this.Page_Load);

         }

         #endregion

         private void ImageButton2_Click(object sender, System.Web.UI.ImageClickEventArgs e)

         {

              this.o=new Qgzxol.AlipayKernel.PayTo.Object(this);

              //this.o=new Qgzxol.AlipayKernel.PayTo.Object(this,"商家邮箱","商家安全验证码");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.cmd,"0001");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.subject,"瓶子");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.body,"本人长期代写小学寒,暑假作业.替小学生欺负其他同学(限5-10岁内)有意者密我.钱好谈..因生活极度困难,本人承接以下业务:苦力搬运,装卸,车,钳焊,水电,瓦工,砸墙,漆墙,通下水道,室内装璜,Vb,C++,.NET,Java,j2ee, asp,汇编,手机游戏开发,网络维护,3维建模,平面设计,建筑效果图,flash动画,硬件设计,四六级替考,办证,黑枪,黑车,暗杀,洗钱,要债,割双眼皮…");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.price,"0.01");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.express_fee,"1000");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.ems_fee,"5000");//新增EMS方式。

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.ordinary_fee,"5000");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.type,"4");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.number,"1");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.url,"http://202.197.75.231/Stat/Test/winlin.htm");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.transport,"3");//注意:只有为3时,我们才可以通过返回Y来改变交易状态.

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.readonly_,"false");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_msg,"Hello");

//            //o.Add(Qgzxol.AlipayKernel.PayTo.Keys.seller,"[email protected]");

              DateTime now=DateTime.Now;

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.order_no,"2005"+now.Month.ToString()+now.Hour.ToString()+now.Minute.ToString());

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer,"[email protected]");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_name,"小欣");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_address,"CSU");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_zipcode,"410012");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_tel,"*******");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_mobile,"1354968****");

              this.Response.Redirect(o.GetUrl());

         }

         private void ImageButton1_Click(object sender, System.Web.UI.ImageClickEventArgs e)

         {

              this.o=new Qgzxol.AlipayKernel.PayTo.Object(this);

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.cmd,"0001");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.subject,"狂笨师姐");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.body,"认识她的原因是因为陈哲老是在QQ里面说,瓶子呀,中勤有个人和你一样的垃圾性格,垃圾得一模一样咧.小小也经常这么说.说得多了,就开始好奇.奇怪,居然有据说和瓶子一样好的人,真的是很难找呀,所以会悄悄问一下,那个所谓的狂奔是哪个.当然啦,刚开始认识的时候还有点假像,感觉都好客气的.可是,没过多久就原形毕露了......果然是一样的垃圾呀...呼呼...慢慢地,混熟了...于是,经常三个人一起去吃...确实,我们在一起唯一能做的事就是吃...");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.price,"无价");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.express_fee,"1000");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.ordinary_fee,"5000");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.type,"4");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.number,"100");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.url,"http://www.qgzxol.com/bbs/User/9/Profile.aspx");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.transport,"3");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.readonly_,"false");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_msg,"Hello");

              //o.Add(Qgzxol.AlipayKernel.PayTo.Keys.seller,"[email protected]");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.order_no,"20051214001");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer,"[email protected]");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_name,"");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_address,"CSU");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_zipcode,"410012");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_tel,"*******");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_mobile,"**************");

              this.Response.Redirect(o.GetUrl());

         }

         private void ImageButton3_Click(object sender, System.Web.UI.ImageClickEventArgs e)

         {

              this.o=new Qgzxol.AlipayKernel.PayTo.Object(this);

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.cmd,"0001");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.subject,"瓶子");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.body,"瓶子,三岁食贫,五岁进中勤.一两年,树敌无数,凄凄惨惨凄凄;十指间,柔情似水,呼呼吼吼嘿嘿.整天不务正业,以QQ宠物为伴,实为可惜. ");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.price,"0.01");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.express_fee,"1000");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.ordinary_fee,"5000");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.type,"4");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.number,"1");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.url,"http://www.qgzxol.com/bbs/User/22/Profile.aspx");

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.transport,"3");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.readonly_,"false");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_msg,"Hello");

//            //o.Add(Qgzxol.AlipayKernel.PayTo.Keys.seller,"[email protected]");

              DateTime now=DateTime.Now;

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.order_no,"2005"+now.Month.ToString()+now.Hour.ToString()+now.Minute.ToString());

              o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer,"[email protected]");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_name,"");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_address,"CSU");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_zipcode,"410012");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_tel,"*******");

//            o.Add(Qgzxol.AlipayKernel.PayTo.Keys.buyer_mobile,"**************");

              this.Response.Redirect(o.GetUrl());      

         }

     }

}

2. http://localhost/TradeMd5/Listener.aspx

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.SessionState;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

namespace Qgzxol.Trade.TradeMd5

{

     ///

     /// Listener是响应支付宝服务器事件的一个页面侦听器,

     ///响应test,sendOff和checkOut三个事件并进行相关的处理..

     ///

     public class Listener : System.Web.UI.Page

     {

         private void Page_Load(object sender, System.EventArgs e)

         {

              if(this.Page.IsPostBack==false)

              {

                   Qgzxol.AlipayKernel.Notify.Object o=new Qgzxol.AlipayKernel.Notify.Object(this);

                   o.sendOff+=new Qgzxol.AlipayKernel.Notify.SendOffHandler(this.ProcessSendOff);

                   o.checkOut+=new Qgzxol.AlipayKernel.Notify.CheckOutHandler(this.ProcessCheckOut);

                   o.StartListener();

              }

         }

         ///

         ///处理sendOff事件的逻辑;

         ///外部逻辑处理sendOff事件.

         /// sendOff描述为:您是否已经发货?

         ///若我们已经发了货,则需要把sender对象的returnTxt置为Y;否则为N.

         ///一般的逻辑是:

         ///收到这条信息则在本地数据库中搜索,若没有记录,建立记录;

         ///若本地数据库中有这个记录,且这个记录的标记为:发货.那么我们就可以回答:已经发货了.

         ///核心关键字:处理后,修改sender的returnTxt属性.

          ///

         ///事件源,是Qgzxol.AlipayKernel.Notify.Object对象,包含了交易信息

         public void ProcessSendOff(object sender)

         {

              Qgzxol.AlipayKernel.Notify.Object o=(Qgzxol.AlipayKernel.Notify.Object)sender;

              ///测试期间,我们只是设定这个交易发货.

              ///在处理的时候,我们一般是把从服务器送来的发货请求sendOff保存到数据库,

              ///然后手动发货,发货后,我们向服务器送去发货通知,这就是修改returnTxt=Y即可.

              o.returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.Y;

         }

         ///

         ///处理checkOut事件的逻辑;

         ///外部逻辑处理checkOut事件.

         /// checkOut描述为:您是否已经收到交易款了?

         ///若我们已经收到了交易的交易款,则需要把sender对象的returnTxt置为Y;否则为N.

         ///一般的逻辑是:

         ///收到这条信息则在本地数据库中搜索,若没有记录,建立记录;

         ///若本地数据库中有这个记录,且这个记录的标记为:已经收款了.那么我们就可以回答:已经收款了.

         ///核心关键字:处理后,修改sender的returnTxt属性.

         ///

         ///事件源,是Qgzxol.AlipayKernel.Notify.Object对象,包含了交易信息

         public void ProcessCheckOut(object sender)

         {

              Qgzxol.AlipayKernel.Notify.Object o=(Qgzxol.AlipayKernel.Notify.Object)sender;

              ///测试期间,我们只是设定这个交易发货.

              ///在处理的时候,我们一般是把从服务器送来的发货请求checkOut保存到数据库,

              ///然后查询是否收到款,收款后,我们向服务器送去已经收款通知,这就是修改returnTxt=Y即可.

              o.returnTxt=Qgzxol.AlipayKernel.Notify.ATNResult.Y;

         }

         #region Web 窗体设计器生成的代码

         override protected void OnInit(EventArgs e)

         {

              InitializeComponent();

              base.OnInit(e);

         }

         private void InitializeComponent()

         {   

              this.Load += new System.EventHandler(this.Page_Load);

         }

         #endregion

     }

}

六.附加模型

七.End

 

 出处:
http://blog.csdn.net/winlin398510617/archive/2005/12/19/555931.aspx
开发文档
http://dev.alipay.com/forum/archiver/?tid-2889.html
这个比较简单
http://flourish.cnblogs.com/articles/309366.html

你可能感兴趣的:(C#,ASP.NET)