手机网站支付教程(支付宝)

最近微信公众号商城需要增加支付宝支付,因为微信内部屏蔽了支付宝的请求,所以需要采用浏览器方式打开,如下所示:

大家想必都有这种困惑——拿到支付宝的接口代码后,尽管里面的程序有注释,接口代码包中也附有开发说明,但还是不知道该如何入手。这不难想象是什么原因,因为自己并不了解这个接口的工作原理是什么?请看这篇文章http://www.cnblogs.com/tangself/archive/2010/02/09/1666257.html,这边就不讲太多原理,主要分清楚用的哪个版本,新的支付宝接口已经没有MD5加密,因为不安全,只保留了RSA加密方式,该项目因为以前已经申请过,所以采用的是老版的接口。

具体步骤如下:

1.下好对应的支付宝官方API,找到对应的语言,我这边采用的是.net

2.将代码拷贝到自己的项目中,根据自己的项目分层对应代码放到对应的项目中

3.对于个性化的功能配置都配置的独立对应的XML文件中,如支付XML

4.修改AlipayConfig.cs文件

  1 #region
  2 
  3 using System;
  4 using System.Xml;
  5 
  6 #endregion
  7 
  8 namespace Com.Alipay
  9 {
 10     /// <summary>
 11     ///     类名:Config
 12     ///     功能:基础配置类
 13     ///     详细:设置帐户有关信息及返回路径
 14     ///     版本:3.3
 15     ///     日期:2012-07-05
 16     ///     说明:
 17     ///     以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
 18     ///     该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
 19     ///     如何获取安全校验码和合作身份者ID
 20     ///     1.用您的签约支付宝账号登录支付宝网站(www.alipay.com)
 21     ///     2.点击“商家服务”(https://b.alipay.com/order/myOrder.htm)
 22     ///     3.点击“查询合作者身份(PID)”、“查询安全校验码(Key)”
 23     /// </summary>
 24     public class Config
 25     {
 26         static Config()
 27         {
 28             XmlDocument xmlDoc = new XmlDocument();
 29             xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "\config\configPay.xml");
 30             XmlNode xmlNode = xmlDoc.SelectSingleNode("Configs/AliPay");
 31             //↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
 32             //合作身份者ID,以2088开头由16位纯数字组成的字符串
 33             Partner = xmlNode?.SelectSingleNode("Partner")?.InnerText;
 34 
 35             //收款支付宝账号
 36             SellerEmail = xmlNode?.SelectSingleNode("Seller_email")?.InnerText;
 37 
 38             //交易安全检验码,由数字和字母组成的32位字符串
 39             //如果签名方式设置为“MD5”时,请设置该参数
 40             Key = xmlNode?.SelectSingleNode("Key")?.InnerText;
 41 
 42             //商户的私钥
 43             //如果签名方式设置为“0001”时,请设置该参数
 44             PrivateKey = xmlNode?.SelectSingleNode("Private_key")?.InnerText;
 45             ;
 46 
 47             //支付宝的公钥
 48             //如果签名方式设置为“0001”时,请设置该参数
 49             PublicKey = xmlNode?.SelectSingleNode("Public_key")?.InnerText;
 50             ;
 51 
 52             //↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
 53 
 54             //字符编码格式 目前支持 utf-8
 55             InputCharset = xmlNode?.SelectSingleNode("Input_charset")?.InnerText;
 56             ;
 57 
 58             //签名方式,选择项:0001(RSA)、MD5
 59             SignType = xmlNode?.SelectSingleNode("Sign_type")?.InnerText;
 60             ;
 61             //无线的产品中,签名方式为rsa时,sign_type需赋值为0001而不是RSA
 62 
 63             //支付宝网关地址 
 64             GatewayNew = xmlNode?.SelectSingleNode("GATEWAY_NEW")?.InnerText;
 65 
 66             //服务器异步通知页面路径 
 67             NotifyUrl = xmlNode?.SelectSingleNode("notify_url")?.InnerText;
 68 
 69             //页面跳转同步通知页面路径
 70             CallBackUrl = xmlNode?.SelectSingleNode("call_back_url")?.InnerText;
 71 
 72             //操作中断返回地址
 73             MerchantUrl = xmlNode?.SelectSingleNode("merchant_url")?.InnerText;
 74 
 75             //返回格式
 76             Format = xmlNode?.SelectSingleNode("format")?.InnerText;
 77 
 78             //返回版本
 79             Version = xmlNode?.SelectSingleNode("v")?.InnerText;
 80         }
 81 
 82         #region 属性
 83 
 84         /// <summary>
 85         ///     获取或设置合作者身份ID
 86         /// </summary>
 87         public static string Partner { get; set; }
 88 
 89         /// <summary>
 90         ///     获取或设置收款支付宝账号
 91         /// </summary>
 92         public static string SellerEmail { get; set; }
 93 
 94         /// <summary>
 95         ///     获取或设交易安全校验码
 96         /// </summary>
 97         public static string Key { get; set; }
 98 
 99         /// <summary>
100         ///     获取或设置商户的私钥
101         /// </summary>
102         public static string PrivateKey { get; set; }
103 
104         /// <summary>
105         ///     获取或设置支付宝的公钥
106         /// </summary>
107         public static string PublicKey { get; set; }
108 
109         /// <summary>
110         ///     获取字符编码格式
111         /// </summary>
112         public static string InputCharset { get; }
113 
114         /// <summary>
115         ///     获取签名方式
116         /// </summary>
117         public static string SignType { get; }
118 
119         /// <summary>
120         ///     支付宝网关地址
121         /// </summary>
122         public static string GatewayNew { get; }
123 
124         /// <summary>
125         ///     服务器异步通知页面路径
126         /// </summary>
127         public static string NotifyUrl { get; }
128 
129         /// <summary>
130         ///     页面跳转同步通知页面路径
131         /// </summary>
132         public static string CallBackUrl { get; }
133 
134         /// <summary>
135         ///     操作中断返回地址
136         /// </summary>
137         public static string MerchantUrl { get; }
138 
139         /// <summary>
140         ///     返回格式
141         /// </summary>
142         public static string Format { get; }
143 
144         /// <summary>
145         ///     返回版本
146         /// </summary>
147         public static string Version { get; }
148 
149         #endregion
150     }
151 }
View Code

5.因为微信商城是由第三方用JAVA开发,我们采用接口的方式提供给他们,所以生成表单返回给对方,对方直接输出到浏览器跳到支付宝页面

 1   #region 手机网站支付(支付宝支付)
 2 
 3         /// <summary>
 4         /// 提交支付
 5         /// </summary>
 6         /// <param name="orderId">订单号</param>
 7         /// <returns></returns>
 8         /// <remarks></remarks>
 9         [WebMethod]
10         public ReturnEntity<string> SubmitAliPay(string orderId)
11         {
12             if (string.IsNullOrEmpty(orderId))
13             {
14                 return new ReturnEntity<string>(false, "订单编号不能为空");
15             }
16             try
17             {
18                 string posthtml = PayBLL.SubmitAliPay(orderId);
19                 return new ReturnEntity<string>(!string.IsNullOrEmpty(posthtml), string.Empty, posthtml);
20             }
21             catch (Exception ex)
22             {
23                 return new ReturnEntity<string>(false, ex.Message);
24             }
25         }
26 
27         #endregion
View Code

具体生成表单方法放到业务逻辑层,方法如下

 1 #region 手机网站支付(支付宝支付)
 2 
 3         /// <summary>
 4         ///     提交支付
 5         /// </summary>
 6         /// <param name="orderId">订单号</param>
 7         /// <returns></returns>
 8         /// <remarks></remarks>
 9         public static string SubmitAliPay(string orderId)
10         {
11             //请求号
12             string req_id = DateTime.Now.ToString("yyyyMMddHHmmss") + new Random().Next(10000, 99999);
13             //必填,须保证每次请求都是唯一
14 
15             //商户订单号
16             string out_trade_no = orderId;
17             //商户网站订单系统中唯一订单号,必填
18 
19             //订单名称
20             string subject = orderId.StartsWith("R") ? "会员账户充值" : "会员在线购物";
21             //必填
22 
23             //付款金额
24             string total_fee = OrderBLL.GetOrderTotalFee(orderId);
25             if (string.IsNullOrEmpty(total_fee))
26             {
27                 throw new Exception("会员在线购物总额为0");
28             }
29             if (Utils.ConvertRowData<double>(total_fee) == 0.00)
30             {
31                 throw new Exception("会员在线购物总额为0");
32             }
33 
34             //必填
35 
36             //请求业务参数详细
37             string req_dataToken = "<direct_trade_create_req>" +
38                                    "<notify_url>" + Config.NotifyUrl + "</notify_url>" +
39                                    "<call_back_url>" + Config.CallBackUrl + "</call_back_url>" +
40                                    "<seller_account_name>" + Config.SellerEmail + "</seller_account_name>" +
41                                    "<out_trade_no>" + out_trade_no + "</out_trade_no>" +
42                                    "<subject>" + subject + "</subject>" +
43                                    "<total_fee>" + total_fee + "</total_fee>" +
44                                    "<merchant_url>" + Config.MerchantUrl + "</merchant_url>" +
45                                    "</direct_trade_create_req>";
46             //必填
47 
48             //把请求参数打包成数组
49             Dictionary<string, string> sParaTempToken = new Dictionary<string, string>
50             {
51                 {"partner", Config.Partner},
52                 {"_input_charset", Config.InputCharset.ToLower()},
53                 {"sec_id", Config.SignType.ToUpper()},
54                 {"service", "alipay.wap.trade.create.direct"},
55                 {"format", Config.Format},
56                 {"v", Config.Version},
57                 {"req_id", req_id},
58                 {"req_data", req_dataToken}
59             };
60 
61             //建立请求
62             string sHtmlTextToken = Submit.BuildRequest(Config.GatewayNew, sParaTempToken);
63             //URLDECODE返回的信息
64             Encoding code = Encoding.GetEncoding(Config.InputCharset);
65             sHtmlTextToken = HttpUtility.UrlDecode(sHtmlTextToken, code);
66 
67             //解析远程模拟提交后返回的信息
68             Dictionary<string, string> dicHtmlTextToken = Submit.ParseResponse(sHtmlTextToken);
69 
70             //获取token
71             string request_token = dicHtmlTextToken["request_token"];
72 
73             ////////////////////////////////////////////根据授权码token调用交易接口alipay.wap.auth.authAndExecute////////////////////////////////////////////
74 
75 
76             //业务详细
77             string req_data = "<auth_and_execute_req><request_token>" + request_token +
78                               "</request_token></auth_and_execute_req>";
79             //必填
80 
81             //把请求参数打包成数组
82             Dictionary<string, string> sParaTemp = new Dictionary<string, string>
83             {
84                 {"partner", Config.Partner},
85                 {"_input_charset", Config.InputCharset.ToLower()},
86                 {"sec_id", Config.SignType.ToUpper()},
87                 {"service", "alipay.wap.auth.authAndExecute"},
88                 {"format", Config.Format},
89                 {"v", Config.Version},
90                 {"req_data", req_data}
91             };
92 
93             //建立请求
94             string sHtmlText = Submit.BuildRequest(Config.GatewayNew, sParaTemp, "get", "确认");
95             return sHtmlText;
96         }
97 
98         #endregion
View Code

6.接下来对方直接输出到浏览器如果参数,签名之类没有问题,则会跳到这个页面

接下来就是支付宝的事情了

7.支付宝支付后会有异步通知和返回两个操作,通常来说异步通知的优先级会大于同步返回,且功能准确性高

a.异步通知代码如下,主要状态码官网有说明,根据自己业务需要在对应分支下更新自己的业务逻辑,获取数据采用POST方式,返回的是XML数据需要解析节点

b.同步返回代码如下,其实业务逻辑与异步通知一样,主要就是获取数据有区别,是GET方式获取

8.如果以上呜呜,恭喜你成功了,不得不说一句,支付宝接口真的是良心产品,官方DEMO也是非常完善

原文地址:https://www.cnblogs.com/yuzk/p/5145072.html