zoukankan      html  css  js  c++  java
  • 手机网站支付教程(支付宝)

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

    大家想必都有这种困惑——拿到支付宝的接口代码后,尽管里面的程序有注释,接口代码包中也附有开发说明,但还是不知道该如何入手。这不难想象是什么原因,因为自己并不了解这个接口的工作原理是什么?请看这篇文章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也是非常完善

  • 相关阅读:
    hdu 4710 Balls Rearrangement()
    hdu 4707 Pet(DFS水过)
    hdu 4706 Children's Day(模拟)
    hdu 4712 Hamming Distance(随机函数暴力)
    csu 1305 Substring (后缀数组)
    csu 1306 Manor(优先队列)
    csu 1312 榜单(模拟题)
    csu 1303 Decimal (数论题)
    网络爬虫
    Python处理微信利器——itchat
  • 原文地址:https://www.cnblogs.com/yuzk/p/5145072.html
Copyright © 2011-2022 走看看