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


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

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

  • 相关阅读:
    2015南阳CCPC L
    2015南阳CCPC H
    2015南阳CCPC G
    2015南阳CCPC D
    2015南阳CCPC C
    2015南阳CCPC A
    2015长春赛区总结(其实是流水账
    Codeforces Round #326 (Div. 2) D. Duff in Beach dp
    Codeforces Round #326 (Div. 2) C. Duff and Weight Lifting 水题
    Codeforces Round #326 (Div. 2) B. Duff in Love 分解质因数
  • 原文地址:https://www.cnblogs.com/yuzk/p/5145072.html
Copyright © 2020-2023  润新知