[接口] 支付宝及时到帐接口使用详解[转载]

这两天写支付宝接口, 这个话题不新了, 因为很多人都 做过了, 在这里我说说我的看法吧, 先说一下实现
其实支付宝公司已经给我们做的很好了, 只要少量的改动就OK了,只是有的程序员不太明天他们的动作流程而以,我就以及时到帐为例子来说了,呵呵 
在这之前就大家先下载一下c#版的及时到帐代码 这里是下载地址
http://club.alipay.com/read-htm-tid-9976972.html
先看一下程序的结构吧
<ignore_js_op>

支付宝有一个类文件叫 AliPay 是一些加密算法之类的东西,包括构造URL
要吧看一下这个类的全部内容

[C#] 纯文本查看 复制代码

?


01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

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.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);

                }

                else

                {

                    prestr.Append(Sortedstr + "&");

                }

            }

            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.Split(delimiterChars)[0] + "=" + HttpUtility.UrlEncode(Sortedstr.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;

        }

    }

}

而我们一般不用管这个类,只要保证能调用 的到就行了,不用管他 
我们要做的很少,他是怎么工作的呢,

<ignore_js_op>

这是开发文档里的工作图

其实我们要处理的只有三个Aspx的文件,
先看第一个吧 Default.aspx
这是一个请求的界面

[C#] 纯文本查看 复制代码

?


01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

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 = "https://www.alipay.com/cooperate/gateway.do?";    //支付接口

        string service = "create_direct_pay_by_user";                       //服务名称,这个是识别是何接口实现何功能的标识,请勿修改

        string seller_email = "写自己的";                     //商家签约时的支付宝帐号,即收款的支付宝帐号

        string sign_type = "MD5";                                           //加密类型,签名方式“不用改”

        string key = "写自己的";                    //安全校验码,与partner是一组,获取方式是:用签约时支付宝帐号登陆支付宝网站[url=http://www.alipay.com/]www.alipay.com[/url],在商家服务我的商家里即可查到。

        string partner = "写自己的";                                //商户ID,合作身份者ID,合作伙伴ID

        string _input_charset = "utf-8";                                    //编码类型,完全根据客户自身的项目的编码格式而定,千万不要填错。否则极其容易造成MD5加密错误。

        string show_url = "http://www.alipay.com/";                         //展示地址,即在支付页面时,商品名称旁边的“详情”的链接地址。

        string out_trade_no = TxtOrderno.Text.Trim();                       //客户自己的订单号,订单号必须在自身订单系统中保持唯一性

        string subject = "4.0系统支付宝充值";                            //商品名称,也可称为订单名称,该接口并不是单一的只能买一样东西,可把一次支付当作一次下订单

        string body = "商户:" + TxtOrderno.Text.Trim() + "通过支付宝给自己充值:" + TxtTotal_fee.Text.Trim() + "元";                                   //商品描述,即备注

        string total_fee = TxtTotal_fee.Text.Trim();                        //商品价格,也可称为订单的总金额

        //服务器通知url(Alipay_Notify.aspx文件所在路经),必须是完整的路径地址

        string notify_url = [url=http://0.0.6.108/Alipay/Alipay_Notify.aspx;]http://0.0.6.108/Alipay/Alipay_Notify.aspx;[/url]

        //服务器返回url(Alipay_Return.aspx文件所在路经),必须是完整的路径地址

        string return_url = [url=http://0.0.6.108/Alipay/Alipay_Return.aspx;]http://0.0.6.108/Alipay/Alipay_Return.aspx;[/url]

        //构造数组;

        //以下数组即是参与加密的参数,若参数的值不允许为空,若该参数为空,则不要成为该数组的元素

        string[] para ={

        "service="+service,

        "partner=" + partner,

        "seller_email=" + seller_email,

        "out_trade_no=" + out_trade_no,

        "subject=" + subject,

        "body=" + body,

        "total_fee=" + total_fee,

        "show_url=" + show_url,

        "payment_type=1",

        "notify_url=" + notify_url,

        "return_url=" + return_url,

        "_input_charset="+_input_charset

        };

        //支付URL生成

        string aliay_url = AliPay.CreatUrl(

            //gateway,//GET方式传递参数时请去掉注释

            para,

            _input_charset,

            sign_type,

            key

            );

        //以下是GET方式传递参数

        //Response.Redirect(aliay_url);

        //以下是POST方式传递参数

        Response.Write("<form name=‘alipaysubmit‘ method=‘post‘ action=‘https://www.alipay.com/cooperate/gateway.do?_input_charset=utf-8‘>");

        Response.Write("<input type=‘hidden‘ name=‘service‘ value=" + service + ">");

        Response.Write("<input type=‘hidden‘ name=‘partner‘ value=" + partner + ">");

        Response.Write("<input type=‘hidden‘ name=‘seller_email‘ value=" + seller_email + ">");

        Response.Write("<input type=‘hidden‘ name=‘out_trade_no‘ value=" + out_trade_no + ">");

        Response.Write("<input type=‘hidden‘ name=‘subject‘ value=" + subject + ">");

        Response.Write("<input type=‘hidden‘ name=‘body‘ value=" + body + ">");

        Response.Write("<input type=‘hidden‘ name=‘total_fee‘ value=" + total_fee + ">");

        Response.Write("<input type=‘hidden‘ name=‘show_url‘ value=" + show_url + ">");

        Response.Write("<input type=‘hidden‘ name=‘return_url‘ value=" + return_url + ">");

        Response.Write("<input type=‘hidden‘ name=‘notify_url‘ value=" + notify_url + ">");

        Response.Write("<input type=‘hidden‘ name=‘payment_type‘ value=1>");

        Response.Write("<input type=‘hidden‘ name=‘sign‘ value=" + aliay_url + ">");

        Response.Write("<input type=‘hidden‘ name=‘sign_type‘ value=" + sign_type + ">");

        Response.Write("</form>");

        Response.Write("<script>");

        Response.Write("document.alipaysubmit.submit()");

        Response.Write("</script>");

    }

}

代码里的key和 partner的获取方法
<ignore_js_op>

现在我们只要按代码里的信息填写一样就可以了, 
然后远行网页
点提交
就会进入
<ignore_js_op>

下面的操作就是在支付平台的完成了, 跟咱的程序没有关系了
现在我们应该想,那付完钱之后呢?
我们有两个界面来处理这个问题一个是
Alipay_Return.aspx

[C#] 纯文本查看 复制代码

?


01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

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 = "https://www.alipay.com/cooperate/gateway.do?service=notify_verify";

        //string alipayNotifyURL = "http://notify.alipay.com/trade/notify_query.do?";//此路径是在上面链接地址无法起作用时替换使用。

        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, 120000);

        //*******加密签名程序开始//*******

        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] != "" && Sortedstr != "sign" && Sortedstr != "sign_type")

            {

                if (i == Sortedstr.Length - 1)

                {

                    prestr.Append(Sortedstr + "=" + Request.QueryString[Sortedstr]);

                }

                else

                {

                    prestr.Append(Sortedstr + "=" + Request.QueryString[Sortedstr] + "&");

                }

            }

        }

        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("商户:" + login[1].ToString().Trim() + "<br>金额:" + strPrice + "   交易成功");     //成功,可美化该页面,提示信息

            ////写文本,纪录支付宝返回消息,比对md5计算结果(如网站不支持写txt文件,可改成写数据库)

            string TOEXCELLR = "MD5结果:mysign=" + mysign + ",sign=" + sign + ",responseTxt=" + responseTxt + "   交易信息" + "商户:" + login[1].ToString().Trim() + "<br>金额:" + strPrice + "   交易成功";

            StreamWriter fs = new StreamWriter(Server.MapPath("Return_DATA/" + DateTime.Now.ToString().Replace(":", "")) + ".txt", false, System.Text.Encoding.Default);

            fs.Write(TOEXCELLR);

            fs.Close();

        }

        else

        {

            Response.Write("------------------------------------------");

            Response.Write("<br>Result:responseTxt=" + responseTxt);

            Response.Write("<br>Result:mysign=" + mysign);

            Response.Write("<br>Result:sign=" + sign);

            Response.Write("支付失败");

            ////写文本,纪录支付宝返回消息,比对md5计算结果(如网站不支持写txt文件,可改成写数据库)

            string TOEXCELLR = "MD5结果:mysign=" + mysign + ",sign=" + sign + ",responseTxt=" + responseTxt;

            StreamWriter fs = new StreamWriter(Server.MapPath("Return_DATA/" + DateTime.Now.ToString().Replace(":", "")) + ".txt", false, System.Text.Encoding.Default);

            fs.Write(TOEXCELLR);

            fs.Close();

            //支付失败,提示信息

        }

    }

}

这个是当交易成功后要调用 的界面 在这里只要改动一下就行了, 其实我们要做的只是改一下这里,只要在这里更新一下你的数据库就行了

[C#] 纯文本查看 复制代码

?


01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

//生成对象

            //OfficeFinanceServices objOfficeFinanceServices = new OfficeFinanceServices();

            //订单信息

            string[] login = strOrderNO.Split(new string[] { "_" }, StringSplitOptions.RemoveEmptyEntries);

            ////查询当前的余额

            //decimal objdm = objOfficeFinanceServices.OfficeFinanceSelect(Convert.ToInt32(login[0].ToString().Trim()), true);

            //OfficeFinance objofficeFinance = new OfficeFinance();

            //objofficeFinance.ofId = Convert.ToInt32(login[0].ToString().Trim());

            //objofficeFinance.ofOrid = "cz";

            //objofficeFinance.ofTime = DateTime.Now;

            //objofficeFinance.ofType = 1;

            //objofficeFinance.ofAmount = Convert.ToDecimal(strPrice.ToString().Trim());

            //objofficeFinance.ofRemainAmount = Convert.ToDecimal(strPrice.ToString().Trim()) + objdm;

            //objofficeFinance.ofIsCurrentValue = 1;

            //objofficeFinance.ofUserId = -10;

            //objofficeFinance.ofNote1 = "支付宝上帐:" + strPrice.ToString().Trim() + "元";

            //objofficeFinance.ofNote2 = "商户:" + login[1].ToString().Trim() + "  通过支付宝上帐金额:" + strPrice + "元";

            //objOfficeFinanceServices.addOfficeFinanceOne(objofficeFinance);

大家现在会问我为什么会把他们注释了呢? 
我测试过,,这个界面呢是只到成功的时候 调用 一次以后就再不会调用 了,
所以这样有一个不好的地方 ,就是有些客户他们对转帐操作的很老手,当交易成功之后不等调用这个界面就关闭了浏览器,这个时候会出现什么问题呢?
那支付宝就再也不会调用这个界面 了,只能等下次交易,钱是打上了,我们也收到了,但是就是没有给客户充上钱,这个时候客户就会打电话到公司,怎么回事啊, 钱打过去了, 可是我这边还没有上帐,我们上支付宝一看有啊,但就是没有上帐 ,怎么办,最后只能手动给客户上了,但又怕他程序再自动上一把,呵呵 
所以在这里不我建议使用这个页面,如果你只是修改自己的订单状态的话当然是可以的 
修改余额就不要在这里写了,而是写在这个Alipay_Notify.aspx页面里,这个界面是当交易状态 发生变化时就会调用 ,在没有收到成功的消息前就会一直调用,
时效是24小时,这样的话我们就不用管他是不是转到了成功页面了,只要把这个页面挂在网上等通知就行了,
当交易成功的时候上帐 就OK了

[C#] 纯文本查看 复制代码

?


01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

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;

using SystemModel;

/// <summary>

/// 创建该页面文件时,请留心该页面文件中无任何HTML代码及空格。

/// 该页面称作“通知页”,是异步被支付宝服务器所调用。

/// 当支付宝的订单状态改变时,支付宝服务器则会自动调用此页面,因此请做好自身网站订单信息与支付宝上的订单的同步工作

/// </summary>

public partial class Alipay_Notify : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

        string alipayNotifyURL = "https://www.alipay.com/cooperate/gateway.do?service=notify_verify";

        //string alipayNotifyURL = "http://notify.alipay.com/trade/notify_query.do?";//此路径是在上面链接地址无法起作用时替换使用。

        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, 120000);

        //*******加密签名程序开始*******

        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] != "" && Sortedstr != "sign" && Sortedstr != "sign_type")

            {

                if (i == Sortedstr.Length - 1)

                {

                    prestr.Append(Sortedstr + "=" + Request.Form[Sortedstr]);

                }

                else

                {

                    prestr.Append(Sortedstr + "=" + Request.Form[Sortedstr] + "&");

                }

            }

        }

        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"];//金额    如果你申请了商家购物卷功能,在返回信息里面请不要做金额的判断,否则会校验通过不了。

                string TOEXCELL = "MD5结果:mysign=" + mysign + ",sign=" + sign + ",responseTxt=" + responseTxt;

                StreamWriter f = new StreamWriter(Server.MapPath("Notify_DATA/" + DateTime.Now.ToString().Replace(":", "")) + ".txt", false, System.Text.Encoding.Default);

                f.Write(TOEXCELL + "订单号:" + strOrderNO.ToString().Trim() + "  金额:" + strPrice.ToString().Trim());

                f.Close();

                //以下是我处理自己的订单状态

                Alipaym objalipay = new Alipaym();

                objalipay.APID = strOrderNO;

                objalipay.addTime = DateTime.Now;

                objalipay.total_fee = Convert.ToDecimal(strPrice);

                objalipay.trade_status = "等待买家付款";

                objalipay.Text1 = DateTime.Now.ToString();

                objalipay.Text2 = "";

                objalipay.Text3 = "";

                objalipay.Text4 = "";

                objalipay.Text5 = "";

                OfficeFinanceServices.Update(objalipay);

            }

            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"];//金额 

                //生成对象

                OfficeFinanceServices objOfficeFinanceServices = new OfficeFinanceServices();

                //订单信息

                string[] login = strOrderNO.Split(new string[] { "_" }, StringSplitOptions.RemoveEmptyEntries);

                ////查询当前的余额

                decimal objdm = objOfficeFinanceServices.OfficeFinanceSelect(Convert.ToInt32(login[0].ToString().Trim()), true);

                OfficeFinance objofficeFinance = new OfficeFinance();

                objofficeFinance.ofId = Convert.ToInt32(login[0].ToString().Trim());

                objofficeFinance.ofOrid = "cz";

                objofficeFinance.ofTime = DateTime.Now;

                objofficeFinance.ofType = 1;

                objofficeFinance.ofAmount = Convert.ToDecimal(strPrice.ToString().Trim());

                objofficeFinance.ofRemainAmount = Convert.ToDecimal(strPrice.ToString().Trim()) + objdm;

                objofficeFinance.ofIsCurrentValue = 1;

                objofficeFinance.ofUserId = -10;

                objofficeFinance.ofNote1 = "支付宝上帐:" + strPrice.ToString().Trim() + "元";

                objofficeFinance.ofNote2 = "商户:" + login[1].ToString().Trim() + "  通过支付宝上帐金额:" + strPrice + "元";

                if (objOfficeFinanceServices.addOfficeFinanceOne(objofficeFinance))

                {

                    Response.Write("success");

                    Alipaym objalipay = new Alipaym();

                    objalipay.APID = strOrderNO;

                    objalipay.addTime = DateTime.Now;

                    objalipay.total_fee = Convert.ToDecimal(strPrice);

                    objalipay.trade_status = "交易成功";

                    objalipay.Text1 = DateTime.Now.ToString();

                    objalipay.Text2 = "";

                    objalipay.Text3 = "";

                    objalipay.Text4 = "";

                    objalipay.Text5 = "";

                    OfficeFinanceServices.Update(objalipay);

                }

                else

                {

                    Response.Write("fail");

                }

            }

            else

            {

                //更新自己数据库的订单语句,请自己填写一下

            }

            //Response.Write("success");     //返回给支付宝消息,成功,请不要改写这个success

            //success与fail及其他字符的区别在于,支付宝的服务器若遇到success时,则不再发送请求通知(即不再调用该页面,让该页面再次运行起来),

            //若不是success,则支付宝默认没有收到成功的信息,则会反复不停地调用该页面直到失效,有效调用时间是24小时以内。

            ////写文本,纪录支付宝返回消息,比对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");

            //写文本,纪录支付宝返回消息,比对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();

        }

    }

}

最好是记录一下日志文件,这样一但出了问题还可以有个参考的地方
我的代码写的有点乱大家可以适当的改一下,呵呵 
短短两年的时间,我公司也写过不少接口方面的东东了,在这里和大家分享我的心得和体会,一般人一说到和什么接口对接可能会感觉 到很难,或是感觉很利害的样子,如果是和银行的接口对接,那首先想到的就是安全问题,再就是技术含量,其实不然,接口的产生是为了方便双方的合作,基本没有听说过有那两家公司因为程序对接 不上而放弃合作的,基本没有,都是其它方面的原因,接口是为了方便对接和不同公司和程序之间的交互和通信的,都是为了方便,不是我们想像的那样难,高技术含量,要说技术含量吧也是有一些
我根据自己的开发心得总结一下吧



这种方式的做法是,服务方提供一个方法,但是一般会在第一个参数或是最后一个参数验证一下加密串,这个加密串一般是用所传的参数组合加密而来,最常见的就是MD5加密了,像支付宝的就是。我把这一类型的看做是最低级的一种,因为这种是最不安全的,只要我知道了你的加密算法和后就可以自己改动参数了
对于Http的方法最重要的只有一个方法

[C#] 纯文本查看 复制代码

?


01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

/// <summary>

   /// 请求指定 URL 资源,并获取响应结果

   /// </summary>

   /// <param name="url">需要请求的 URL 资源</param>

   /// <returns>

   /// 响应结果;

   /// 出现任意异常,均返回字串"Runtime Error"

   /// </returns>

   private string RequestContent(string url)

   {

       string content = string.Empty;

       try

       {

           HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

           request.KeepAlive = false;

           HttpWebResponse response = (HttpWebResponse)request.GetResponse();

           StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);

           content = reader.ReadToEnd();

           reader.Close();

       }

       catch (Exception)

       {

           content = "Runtime Error";

       }

       return content;

   }

只要我们把要传的参数和URL对接后传给这 个方法就算是完事了,另外在MD5加密是时间注意对方是否要区分大小写,最好是把加密串一下子全转成小写或是大写的 
加密的方法一般如下

[C#] 纯文本查看 复制代码

?


01

02

03

04

05

06

07

08

09

/// <summary>

    /// 传入明文,返回用MD%加密后的字符串

    /// </summary>

    /// <param name="str">要加密的字符串</param>

    /// <returns>用MD5加密后的字符串</returns>

    public static string ToMD5(string str)

    {

        return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "md5");

    }

在做这样的接口的时候一定要注意一定要验证的地方有三点:第一点就是验证加密串了
这里就是把所需要的参数在本地加一下密然后和服务端发来的对比
第二点就是控制页面只在首次加载时执行这个我们可以通过下面的方式来实现

[C#] 纯文本查看 复制代码

?


01

02

03

04

if (!IsPostBack)

        {

            ............

        }

我们只要在IF块里面写我们的代码就可以了
第三点也是最关键的一点那就是验证一下请求过来的DNS或是IP
就是说你要验证一下发过来请求的来源电脑是不是你的服务商的DNS或是IP,如果不是就可以不执行程序或是提示为非法操作,这样可以防止有人知道了你的加密算法后自己生成一些代码来高乱你的程序给公司带来损失,特别是即使到账的接口,这一点一定要验证好,而且在IIS服务器最好是绑定一下IP,只接收授权的IP发来的消息。这样基本可以保证安全问题了。
好了对于 这种方法我来用一个Http的例子来演示一下吧

[C#] 纯文本查看 复制代码

?


01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

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;

using SystemModel;

/// <summary>

/// 创建该页面文件时,请留心该页面文件是可以对其进行美工处理的,原因在于支付完成以后,当前窗口会从支付宝的页面跳转回这个页面。

/// 该页面称作“返回页”,是同步被支付宝服务器所调用,可当作是支付完成后的提示信息页,如“您的某某某订单,多少金额已支付成功”。

/// </summary>

public partial class Alipay_Return : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

if (!IsPostBack)

{

//生成对象

OfficeFinanceServices objOfficeFinanceServices = new OfficeFinanceServices();

Alipaym objalipay = new Alipaym();

try

{

string alipayNotifyURL = "https://www.alipay.com/cooperate/gateway.do?service=notify_verify";

//string alipayNotifyURL = "http://notify.alipay.com/trade/notify_query.do?";//此路径是在上面链接地址无法起作用时替换使用。

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, 120000);

//*******加密签名程序开始//*******

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] != "" && Sortedstr != "sign" && Sortedstr != "sign_type")

{

if (i == Sortedstr.Length - 1)

{

prestr.Append(Sortedstr + "=" + Request.QueryString[Sortedstr]);

}

else

{

prestr.Append(Sortedstr + "=" + Request.QueryString[Sortedstr] + "&");

}

}

}

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" && Request.UserHostName == "www.alipay.com") //验证支付发过来的消息,签名是否正确

{

//更新自己数据库的订单语句,请自己填写一下

string strOrderNO = Request.QueryString["out_trade_no"];//订单号

string strPrice = Request.QueryString["total_fee"];//金额

string strTradeStatus = Request.QueryString["TRADE_STATUS"];//订单状态

string result = objOfficeFinanceServices.CheckNo(strOrderNO.ToString().Trim());

if (result.Trim() == "0")

{

//成功,可美化该页面,提示信息

////写文本,纪录支付宝返回消息,比对md5计算结果(如网站不支持写txt文件,可改成写数据库)

string TOEXCELLR = "MD5结果:mysign=" + mysign + ",sign=" + sign +

",responseTxt=" + responseTxt ;

StreamWriter fs = new StreamWriter(Server.MapPath("Return_DATA/" + DateTime.Now.ToString().Replace(":", "")) + ".txt", false, System.Text.Encoding.Default);

fs.Write(TOEXCELLR);

fs.Close();

//修改订单状态

}

else if (result == "-1")

{

//修改订单状态

////写文本,纪录支付宝返回消息,比对md5计算结果(如网站不支持写txt文件,可改成写数据库)

string TOEXCELLR = "MD5结果:mysign=" + mysign + ",sign=" + sign + ",responseTxt=" + responseTxt + "perky_" + result.Trim() + Request.UserHostName.Trim() + Request.UserHostAddress.Trim();

StreamWriter fs = new StreamWriter(Server.MapPath("Return_DATA/" + "e" + DateTime.Now.ToString().Replace(":", "")) + ".txt", false, System.Text.Encoding.Default);

fs.Write(TOEXCELLR);

fs.Close();

Response.Write("查询订单时失败!!! 请确定你是否下单!!!");

}

else

{

//修改订单状态

////写文本,纪录支付宝返回消息,比对md5计算结果(如网站不支持写txt文件,可改成写数据库)

string TOEXCELLR = "MD5结果:mysign=" + mysign + ",sign=" + sign + ",responseTxt=" + responseTxt + "perky_" + result.Trim() + Request.UserHostName.Trim() + Request.UserHostAddress.Trim();

StreamWriter fs = new StreamWriter(Server.MapPath("Return_DATA/" + "e" + DateTime.Now.ToString().Replace(":", "")) + ".txt", false, System.Text.Encoding.Default);

fs.Write(TOEXCELLR);

fs.Close();

Response.Write("重复使用界面无效!!!");

}

}

else

{

Response.Write("------------------------------------------");

Response.Write("<br>Result:responseTxt=" + responseTxt);

Response.Write("<br>Result:mysign=" + mysign);

Response.Write("<br>Result:sign=" + sign);

Response.Write("支付失败");

////写文本,纪录支付宝返回消息,比对md5计算结果(如网站不支持写txt文件,可改成写数据库)

string TOEXCELLR = "MD5结果:mysign=" + mysign + ",sign=" + sign + ",responseTxt=" + responseTxt + Request.UserHostName.Trim() + Request.UserHostAddress.Trim();

StreamWriter fs = new StreamWriter(Server.MapPath("Return_DATA/" + "e" + DateTime.Now.ToString().Replace(":", "")) + ".txt", false, System.Text.Encoding.Default);

fs.Write(TOEXCELLR);

fs.Close();

}

}

catch (Exception ex)

{

////写文本,纪录支付宝返回消息,比对md5计算结果(如网站不支持写txt文件,可改成写数据库)

string TOEXCELLR = Request.Url.ToString() + " " + ex.Message.ToString() + Request.UserHostName.Trim() + Request.UserHostAddress.Trim();

StreamWriter fs = new StreamWriter(Server.MapPath("Return_DATA/" + "m" + DateTime.Now.ToString().Replace(":", "")) + ".txt", false, System.Text.Encoding.Default);

fs.Write(TOEXCELLR);

fs.Close();

}

}

}

}

Http的方法有的接口还是要带证书才能实现的

时间: 2024-11-01 23:09:26

[接口] 支付宝及时到帐接口使用详解[转载]的相关文章

ThinkPHP3.2对接开发支付宝即时到帐接口

ThinkPHP3.2对接开发支付宝即时到帐接口 在做一些商城.自动发卡网站.会员积分充值.金币充值等等这类网站都时候,我们极大可能需要使用到第三方都支付接口.不管是财付通.支付宝.银联.贝宝.易宝这些都 ThinkPHP3.2对接开发支付宝即时到帐接口        在做一些商城.自动发卡网站.会员积分充值.金币充值等等这类网站都时候,我们极大可能需要使用到第三方都支付接口.不管是财付通.支付宝.银联.贝 宝.易宝这些都好,总之这些第三方支付平台给我们带来了很多便利都地方.我们只需要跟这些平台

支付宝即时到帐接口的python实现,示例采用django框架

因工作需要研究了支付宝即时到帐接口,并成功应用到网站上,把过程拿出来分享. 即时到帐只是支付宝众多商家服务中的一个,表示客户付款,客户用支付宝付款,支付宝收到款项后,马上通知你,并且此笔款项与交易脱离关系,商家可以马上使用. 即时到帐只对企业客户服务,注册成功企业账号以后,申请签约即时到帐产品,大约3-5个工作日后,签约成功,可以马上进入集成产品阶段. 这个是支付宝提供的接口,有asp,c#,java,php四种语言的,每种语言提供GBK和UTF-8两种方案.另带一份支付宝的文档,这份文档我感觉

C#进阶系列——WebApi 接口参数不再困惑:传参详解

C#进阶系列--WebApi 接口参数不再困惑:传参详解

FileUpload上传控件用法详解 (转载)

FileUpload 类显示一个文本框控件和一个浏览按钮,使用户可以选择客户端上的文件并将它上载到 Web 服务器.用户通过在控件的文本框中输入本地计算机上文件的完整路径(例如,C:\MyFiles\TestFile.txt )来指定要上载的文件.用户也可以通过单击“浏览” 按钮,然后在“选择文件” 对话框中定位文件来选择文件. 注意: FileUpload 控件设计为仅用于部分页面呈现期间的回发情况,并不用于异步回发情况.在 UpdatePanel 控件内部使用 FileUpload 控件时,

GridView内容详解(转载)

GridView内容详解(转载) GridView是ASP.NET界面开发中的一个重要的控件,对GridView使用的熟练程度直接影响软件开发的进度及功能的实现.(车延禄)GridView的主要新特性:    1.与DataSource控件结合实现了显示与数据操作的分离,大大减化了代码的编写量;    2.实现"双向绑定",无需手动检索数据.    2.在列的类型上新增了CheckBoxField和ImageField两个类型列;    3.对排序和分页可以实现异步操作;    4.对

MySQL 数据类型 详解 (转载)

数值类型 MySQL 的数值数据类型可以大致划分为两个类别,一个是整数,另一个是浮点数或小数.许多不同的子类型对这些类别中的每一个都是可用的,每个子类型支持不同大小的数据,并且 MySQL 允许我们指定数值字段中的值是否有正负之分或者用零填补. 表列出了各种数值类型以及它们的允许范围和占用的内存空间. 类型 大小 范围(有符号) 范围(无符号) 用途 TINYINT 1 字节 (-128,127) (0,255) 小整数值 SMALLINT 2 字节 (-32 768,32 767) (0,65

HTML中META属性详解 转载自 hero_213的博客

HTML中META属性详解 meta是html语言head区的一个辅助性标签.几乎所有的网页里,我们可以看到类似下面这段的html代码: <head> <meta   http-equiv= "content-Type "   content= "text/html;   charset=gb2312 "> </head>         也许你认为这些代码可有可无.其实如果你能够用好meta标签,会给你带来意想不到的效果,例如加

Python安装、配置图文详解(转载)

Python安装.配置图文详解 目录: 一. Python简介 二. 安装python 1. 在windows下安装 2. 在Linux下安装 三. 在windows下配置python集成开发环境(IDE) 1. 在Eclipse中安装PyDev插件 2. 配置Python Interpreters 四. 创建Python Project 五. 编写HelloWorld 六. 小结 一. Python简介: Python在Linux.windows.Mac os等操作系统下都有相应的版本,不管在

【DataGuard】部署Data Guard相关参数详解 (转载)

原文地址:[DataGuard]部署Data Guard相关参数详解 作者:secooler 有关物理Data Guard部署参考<[DataGuard]同一台主机实现物理Data Guard配置安装>(http://space.itpub.net/519536/viewspace-578181),本文对部署Data Guard过程中主备库使用到的参数进行比较描述. 1.DB_NAME,数据库名字,需要保持同一个Data Guard 中所有数据库DB_NAME相同primary端和standb