以前写的东西——支付宝

由于现在来博客园少了,blog也不常更新,其实有时候还在写东西,大部分懒的传。今天想更新,才发现写的东西也不知道扔哪里了,也许被误删除了,尤其有两篇自己比较满意的也找不见了。明天去公司找找,把能找到的都传上来。
把以前写的最终版本支付宝接口放上来。
 

库的改变:

1、 增加了一个接口,

public void CommonProcessNotify(Page page, string verifyUrl, string key, Verify verify, string encode)

这个接口触发NotifyEvent事件,此事件通过NotifyEventArgs类型暴露了支付宝Notify通知的所有参数,并且不给支付宝回发“success”或者“fail”,回发由调用者实现。这个方法提供了支付宝Notify通知的所有功能。

    如果仅仅需要处理下面几个事件,可以参考:http://www.cnblogs.com/bluewater/archive/ 2006/10/16 /530630.aspx

WaitBuyerPay

WaitSellerConfirmTrade

WaitSysConfirmPay

WaitSellerSendGoods

WwaitBuyerConfirmGoods

WaitSysPaySeller

TradeFinished

TradeClosed

这几个事件细化了支付宝的Notify通知,定义了最常用的几个事件,调用起来要方便些。

2、 记录了日志记录功能。

Log4net记录了Request.Form集合,可以看到支付宝Notify发过来的整个参数,便于调试。日志默认是Error级别,并且只有在debug版本有日志输出,实际使用时应该用release版本的库(或者修改Log4net的日志级别),以免记录下许多无用的日志。

调用方式的改变:

Notify接口模拟出了Return方式。支付宝的Return接口虽然方便调用,但是安全可靠性差,很难在实际中应用。通过下面的方式,可以用Notify模拟return,如果支付宝的Notify发送的及时还可以完全替代Return方式。

解决方法是:让提交给支付宝信息的页面一直等待,直到收到Notify通知。

         AutoResetEvent ansyCard=new AutoResetEvent(false);

        ansyCard.WaitOne();   //阻塞当前线程,直到Notify完成。displaycard.aspx

ansyCard.Set();//Notify页面发解除阻塞通知,displaycard页面继续执行。Notify.aspx

思路就是上面那么简单,但实际上还有几个问题:1、支付宝服务器发Notify页面和其他的页面不在一个线程,不属于用一个Session2、支付宝会一直发Notify,必须要保证,解锁的是设置锁的那个线程,而不能把其他的线程锁解开。

详细的实现方式可以看源代码,此方法可为解决这种类型的问题提供了一个思路。

调试:

调试支付宝必须满足两个条件:

1、 有个公网IP,如果是ADSL每次拨号也会分配一个,可以通过ipconfig命令查到此次拨号分配的IP,这样支付宝就能访问到你。

2、 必须附加到IIS,一是通过手动附加到aspnet_wp进程,二是把启动选项的服务器改称虚拟目录的地址。

满足上面两个条件就可以调试支付宝了。

源代码的使用方法:

修改web.config中的下面几项后,就可以直接运行实例程序。Temp.aspx是测试AutoResetEvent的页面。

<add key="key" value=" "/>

    <add key="partner" value=""/>

    <add key="sellerEmail" value=" "/>

    <add key="sellerId" value=" "/>

<add key="notifyUrl" value=" "/>

关于AutoResetEvent可以看下面的文章

http://www.cnblogs.com/bluewater/archive/ 2006/08/14 /476720.html

    string  key  =  ConfigurationManager.AppSettings[ " key " ];
            
string  partner  =  ConfigurationManager.AppSettings[ " partner " ];
            
string  sellerEmail  =  ConfigurationManager.AppSettings[ " sellerEmail " ];
            
string  sellerId  =  ConfigurationManager.AppSettings[ " sellerId " ];
            
string  outTradeNo  =  Guid.NewGuid().ToString();
            
string  url  =  ConfigurationManager.AppSettings[ " notifyUrl " ].ToString();
            
string  gatewayUrl  =   " https://www.alipay.com/cooperate/gateway.do " ;
            
//
            AliPay ap  =   new  AliPay();
            DigitalGoods dg 
=   new  DigitalGoods( " create_digital_goods_trade_p " , partner, key,  " MD5 " , subject, outTradeNo, ( decimal )money,  1 , sellerEmail, sellerId);
            dg.Buyer_Id 
=   " temp " ;
            dg.Notify_Url 
=  url;
            Session[
" outtradeNo " =  outTradeNo;
            ap.CreateDigitalTrade(gatewayUrl, dg, 
this );
            
string  myScript  =   @" document.all['discard'].src='displayCard.aspx' " ;
            Page.ClientScript.RegisterStartupScript(
this .GetType(),  " myScript " , myScript,  true );

display.aspx
   protected   void  Page_Load( object  sender, EventArgs e)
        
{
            
//Session["outtradeNo"] = Request.QueryString["a"];
            AutoResetEvent ansyCard=new AutoResetEvent(false);
            Application[Session[
"outtradeNo"].ToString() + "Event"= ansyCard;
            ansyCard.WaitOne();         
           
            
if (Application[Session["outtradeNo"].ToString()] != null)
            
{

                
string s = string.Format("<script language='javascript'>alert('你的充值卡密码是:{0}')</script>", Application[Session["outtradeNo"].ToString()]);               
                Response.Write(s);

            }

        }

notify.aspx
  void  ap_WaitBuyerPay( object  sender, NotifyEventArgs e)
    
{
        Card card 
= new Card();
        AutoResetEvent ansyCard 
= (AutoResetEvent)Application[e.Out_Trade_No + "Event"]; 
        TradeLog tradeLog 
= null;

        
try
        
{
            tradeLog 
= new TradeLog(e.Buyer_Id, e.Trade_Status, e.Trade_No, e.Buyer_Id, e.Subject, (int)e.Price, 1);
            SNInfo snInfo 
= card.GetSn((int)e.Price);
            card.WriteLog(tradeLog);
            Application[e.Out_Trade_No] 
= snInfo.Password;
           

            ansyCard.Set();


        }

        
catch (Exception ex)
        
{
            
//日志
            
//
            if (tradeLog != null)
            
{

                
string t = e.Buyer_Id + e.Trade_Status + e.Trade_No + e.Buyer_Id + e.Subject + (int)e.Price + "sendgoods";
                Log4net.log.Error(t, ex);
            }

            
else
            
{
                
//
                Log4net.log.Error(GetForms(Request.Form), ex);
            }

                       ansyCard.Set();
        }
 
    }

代码:
http://www.cnblogs.com/files/bluewater/commonalipay2.rar
以前写的东西——支付宝

你可能感兴趣的:(支付宝)