程序是一门艺术

程序架构与公共代码--本博客文章均系原创

让支付宝更容易,面相对象的支付宝

支付宝接口,我拿到代码后,重新整理了一下.

具体的,将功能分为4个文件

Alipay.cs --->支付宝数据结构类

AlipayComm.cs--->公共代码静态类

AlipayResults.cs--->返回值类型类

AlipayServiceType.cs--->服务类型(比如我就是用的即时到帐)

 

Alipay.cs:

 

Code

 

AlipayComm.cs:

 

using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Security.Cryptography;
using System.Net;

namespace System.AlipaySystem
{
    
/// <summary>
    
/// AlipayComm 支付宝接口公共代码
    
/// </summary>
    public static class AlipayComm
    {
        
/// <summary>
        
/// 接口地址
        
/// </summary>
        public const string AlipayGateWay = "https://www.alipay.com/cooperate/gateway.do?";

        
/// <summary>
        
/// 支付宝ID(支付宝公司提供)
       
/// </summary>
        public const string AlipayName = "20880xxxxxx";
        
/// <summary>
        
/// 支付宝密码,这里填写你的密码(支付宝公司提供)
        
/// </summary>
        public const string AlipayPassword = "mmxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
        
/// <summary>
        
/// 支付宝默认编码
        
/// </summary>
        public const string AlipayCharset = "utf-8";

        
/// <summary>
        
/// 支付宝账户(支付宝公司提供)
        
/// </summary>
        public const string AlipayEmail = "xxx@xxxx.com";

        
/// <summary>
        
/// 加密方式
        
/// </summary>
        public const string AlipaySignType = "MD5";

        
#region CreateNew()
        
/// <summary>
        
/// 工厂模式建立一个支付类型
        
/// </summary>
        
/// <returns></returns>
        public static Alipay CreateNew()
        {
            Alipay pay 
= new Alipay();
            pay.Partner 
= AlipayName;
            pay.Key 
= AlipayPassword;
            pay.GateWay 
= AlipayGateWay;
            pay.InputCharset 
= AlipayCharset;
            pay.PaymentType 
= "2";
            pay.SignType 
= AlipaySignType;
            pay.SellerEmail 
= AlipayEmail;
            
return pay;
        }
        
#endregion

        
#region CreateMd5(s,charset)
        
/// <summary>
        
/// 与ASP兼容的MD5加密算法
        
/// </summary>
        public static string CreateMd5(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();
        }

        
public static string CreateMd5(string s)
        {
            
return CreateMd5(s, AlipayCharset);
        }
        
#endregion



        
#region Sort(r)
        
/// <summary>
        
/// 对参数进行排序
        
/// </summary>
        
/// <param name="r"></param>
        
/// <returns></returns>
        public static string[] Sort(string[] r)
        {
            
/// <summary>
            
/// 冒泡排序法
            
/// </summary>

            
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;
        }
        
#endregion

        
#region CreateHttpRequestUrl()
        
/// <summary>
        
/// 建立Http请求的Url
        
/// </summary>
        
/// <param name="gateway"></param>
        
/// <param name="service"></param>
        
/// <param name="partner"></param>
        
/// <param name="sign_type"></param>
        
/// <param name="out_trade_no"></param>
        
/// <param name="subject"></param>
        
/// <param name="body"></param>
        
/// <param name="payment_type"></param>
        
/// <param name="total_fee"></param>
        
/// <param name="show_url"></param>
        
/// <param name="seller_email"></param>
        
/// <param name="key"></param>
        
/// <param name="return_url"></param>
        
/// <param name="_input_charset"></param>
        
/// <param name="notify_url"></param>
        
/// <returns></returns>
        public static string CreatHttpRequestUrl(
          
string gateway,
          
string service,
          
string partner,
          
string sign_type,
          
string out_trade_no,
          
string subject,
          
string body,
          
string payment_type,
          
string total_fee,
          
string show_url,
          
string seller_email,
          
string key,
          
string return_url,
          
string _input_charset,
          
string notify_url
          )
        {
            
/// <summary>
            
/// created by sunzhizhi 2006.5.21,sunzhizhi@msn.com。
            
/// </summary>
            int i;

            
//构造数组;
            string[] Oristr =
                
"service="+service, 
                
"partner=" + partner, 
                
"subject=" + subject, 
                
"body=" + body, 
                
"out_trade_no=" + out_trade_no, 
                
"total_fee=" + total_fee, 
                
"show_url=" + show_url,  
                
"payment_type=" + payment_type, 
                
"seller_email=" + seller_email, 
                
"notify_url=" + notify_url,
                
"_input_charset="+_input_charset,          
                
"return_url=" + return_url
                };

            
//进行排序;
            string[] Sortedstr = Sort(Oristr);// BubbleSort(Oristr);


            
//构造待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 = CreateMd5(prestr.ToString(), _input_charset);// GetMD5(prestr.ToString(), _input_charset);

            
//构造支付Url;
            
//char[] delimiterChars = { '=' };
            StringBuilder parameter = new StringBuilder();
            parameter.Append(gateway);
            
//重新写构造代码,原来的代码有'='无法进行解码的问题
            int index1;
            
for (i = 0; i < Sortedstr.Length; i++)
            {
                index1 
= Sortedstr[i].IndexOf('=');
                
//append key
                parameter.Append(Sortedstr[i].Substring(0, index1!=-1?index1:Sortedstr[i].Length));
                parameter.Append(
"=");
                
//append value
                parameter.Append(index1 != -1 && index1 != Sortedstr[i].Length - 1 ? HttpUtility.UrlEncode(Sortedstr[i].Substring(index1 + 1)) : string.Empty);
                parameter.Append(
"&");
                
//原来的Url解码有问题,上面已经重写
                
//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();

        }
        
#endregion

        
#region GetRequestResult(url,timeout)
        
//获取远程服务器ATN结果
        public static string GetRequestResult(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;
        }
        
#endregion


        
#region CreateDateString()
        
public static string CreateDateString()
        {
            
return CreateDateString(DateTime.Now);
        }

        
public static string CreateDateString(DateTime time)
        {
            
return CreateDateString(time.ToString("g"));
        }

        
public static string CreateDateString(string dts)
        {
            TextBuilder text 
= TextBuilder.GetTextBuilder(dts);
            text.Replace(
"-""");
            text.Replace(
";""");
            text.Replace(
" """);
            dts 
= text.ToString();
            TextBuilder.Release(text);
            
return dts;
        }
        
#endregion

    }
}

 

AlipayResult.cs:

 

Code

 

 

AlipayServiceType.cs:

 

Code

 

 

注意的是,Alypay.cs这个类里面的参数一定要填写完整.

我在AlipayComm.cs里面有一个CreateNew是一个工厂模式的静态实例化方法

比如可以Alipay pay=AlipayComm.CreateNew();

大家可以自己添加自己的实例化代码.

 

原来的支付宝,有个问题,Return_Url返回地址不能带参数,

也就是return_url="http://www.163.com/?uid=123";这句话会出现错误"ILLEGAL_SIGN";

原因是支付宝给的CreatUrl函数中:

  char[] delimiterChars = { '='};
            StringBuilder parameter = new StringBuilder();
            parameter.Append(gateway);
            for (i = 0; i < Sortedstr.Length; i++)
            {

                parameter.Append(Sortedstr[i].Split(delimiterChars)[0] + "=" + HttpUtility.UrlEncode(Sortedstr[i].Split(delimiterChars)[1]) + "&");

 

在上面的代码片段中.Split的问题.

比如http://www.163.com/?uid=123这个返回网址,他会错误的把等于号(=)左右切开.然后分别赋值.

这样的话,uid=123又变成了一个参数.....MD5校验,怎么都不回通过的.

 

posted on 2009-06-28 15:50  甘蔗皮  阅读(650)  评论(1编辑  收藏  举报

导航