• 说一说我和微信支付V3


    做微信支付的时候遇到了挺多坑,现在记录下来和大家分享分享。

    第一个坑:算签名的时候,总是提示签名失败。用微信提供的计算签名的工具,计算出来的签名是一致的。

    原因是:密钥拿错了,我用的是公众平台的app密钥。实际应该拿的是微信支付商户平台设置的API密钥。

    第二个坑:使用JSAPI调用支付组件的时候,总是提示AppId无效。

    原因:公众平台设置的测试路径和实际测试的路径有一个字母大小写不一样。如:b:B。微信文档里说,大小写必须一致。

    关于微信支付的源码以后有时间的时候在贴上。

    代码文件:

    首先是几个必要文件:

    HttpUtil.cs--------用来发送HTTP请求

    WeChatConfig.cs---------配置类

    ResponseHandler.cs-----接收微信同步回调信息的类

    RequestHandler.cs------向微信发送请求时会使用的类

    WeChatPayment.cs-----封装好的几个方法,方便在平台的其他地方调用

    WeChatParameter.cs----调用接口时使用的一些传递参数的类型

    WeChatViewParameter.cs--------这个类型主要传递参数给JSAPI使用

    ImageResult.cs -----------------返回给浏览器时使用的Result类型

    其他----------------------还有一些辅助函数,分散在项目的其他文件中(如果有园友看到,且需要就密我吧!)

    HttpUtil.cs

     1 using System;
     2 using System.Collections.Generic;
     3 using System.IO;
     4 using System.Linq;
     5 using System.Net;
     6 using System.Text;
     7 using System.Web;
     8 
     9 namespace Mimo.Payment.WeChatPay
    10 {
    11     public class HttpUtil
    12     {
    13 
    14         private const string sContentType = "application/x-www-form-urlencoded";
    15         private const string sUserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
    16         public static string Send(string data, string url)
    17         {
    18             return Send(Encoding.GetEncoding("UTF-8").GetBytes(data), url);
    19         }
    20 
    21         public static string Send(byte[] data, string url)
    22         {
    23             Stream responseStream;
    24             HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
    25             if (request == null)
    26             {
    27                 throw new ApplicationException(string.Format("Invalid url string: {0}", url));
    28             }
    29         
    30             request.ContentType = sContentType;
    31             request.UserAgent = sUserAgent;
    32             request.Method = "POST";
    33             request.ContentLength = data.Length;
    34             Stream requestStream = request.GetRequestStream();
    35             requestStream.Write(data, 0, data.Length);
    36             requestStream.Close();
    37             try
    38             {
    39                 responseStream = request.GetResponse().GetResponseStream();
    40             }
    41             catch (Exception exception)
    42             {
    43                 throw exception;
    44             }
    45             string str = string.Empty;
    46             using (StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("UTF-8")))
    47             {
    48                 str = reader.ReadToEnd();
    49             }
    50             responseStream.Close();
    51             return str;
    52         }  
    53     }
    54 }
    View Code

    WeChatConfig.cs

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace Mimo.Payment
     8 {
     9     /// <summary>
    10     /// liuyt 2015.03.16
    11     /// 微信支付的配置文件
    12     /// </summary>
    13     public class WeChatConfig
    14     {
    15         #region UnifiedOrderUrl 统一下单接口URL
    16         private static string unifiedOrderUrl;
    17         public static string UnifiedOrderUrl
    18         {
    19             get { return unifiedOrderUrl; }
    20         }
    21         #endregion
    22 
    23         #region ApiSecret  微信支付商户平台设置的API密钥
    24         private static string apiSecret;
    25         public static string ApiSecret
    26         {
    27             get { return apiSecret; }
    28         }
    29         #endregion
    30 
    31         #region AppId 应用ID  微信公众平台-->开发者中心-->配置项-->AppID
    32         private static string appId;
    33         public static string AppId
    34         {
    35             get { return appId; }
    36         }
    37         #endregion
    38 
    39         #region Mch_id 商户ID  微信支付的商户号--在微信返回的审核通过的邮件中
    40         private static string mch_id;
    41         public static string Mch_id
    42         {
    43             get { return mch_id; }
    44         } 
    45         #endregion
    46 
    47         #region 构造函数
    48         static WeChatConfig()
    49         {
    50             unifiedOrderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    51             apiSecret = "填上自己的密钥";
    52             appId = "填上自己的appId";
    53             mch_id = "填上自己的mch_id";
    54         } 
    55         #endregion
    56     }
    57 }
    View Code

    RequestHandler.cs

      1 using System;
      2 using System.Collections;
      3 using System.Text;
      4 using System.Web;
      5 using System.Xml;
      6 using System.Security.Cryptography;
      7 using System.Collections.Generic;
      8 using System.Text.RegularExpressions;
      9 using Mimo.Payment.Common;
     10 namespace Mimo.Payment.WeChatPay
     11 {
     12     /**
     13     '签名工具类
     14      ============================================================================/// <summary>
     15     'api说明:
     16     'init();
     17     '初始化函数,默认给一些参数赋值。
     18     'setKey(key_)'设置商户密钥
     19     'createMd5Sign(signParams);字典生成Md5签名
     20     'genPackage(packageParams);获取package包
     21     'createSHA1Sign(signParams);创建签名SHA1
     22     'parseXML();输出xml
     23     'getDebugInfo(),获取debug信息
     24      * 
     25      * ============================================================================
     26      */
     27     public class RequestHandler
     28     {
     29     
     30         public RequestHandler(HttpContext httpContext)
     31         {
     32             parameters = new Hashtable();
     33 
     34             this.httpContext = httpContext;
     35            
     36         }
     37         /**  密钥 */
     38         private string key;
     39 
     40         protected HttpContext httpContext;
     41 
     42         /** 请求的参数 */
     43         protected Hashtable parameters;
     44         
     45         /** debug信息 */
     46         private string debugInfo;
     47         
     48         /** 初始化函数 */
     49         public virtual void init() 
     50         {
     51         }
     52         /** 获取debug信息 */
     53         public String getDebugInfo() 
     54         {
     55             return debugInfo;
     56         }
     57         /** 获取密钥 */
     58         public String getKey() 
     59         {
     60             return key;
     61         }
     62 
     63         /** 设置密钥 */
     64         public void setKey(string key) 
     65         {
     66             this.key = key;
     67            // this.partne = key;
     68         }
     69 
     70         /** 设置参数值 */
     71         public void setParameter(string parameter, string parameterValue)
     72         {
     73             if (parameter != null && parameter != "")
     74             {
     75                 if (parameters.Contains(parameter))
     76                 {
     77                     parameters.Remove(parameter);
     78                 }
     79 
     80                 parameters.Add(parameter, parameterValue);
     81             }
     82         }
     83 
     84        
     85         //创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
     86         
     87         protected virtual void  createSign() 
     88         {
     89             StringBuilder sb = new StringBuilder();
     90 
     91             ArrayList akeys=new ArrayList(parameters.Keys); 
     92             akeys.Sort();
     93 
     94             foreach(string k in akeys)
     95             {
     96                 string v = (string)parameters[k];
     97                 if(null != v && "".CompareTo(v) != 0
     98                     && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0) 
     99                 {
    100                     sb.Append(k + "=" + v + "&");
    101                 }
    102             }
    103 
    104             sb.Append("key=" + this.getKey());
    105             string sign = AlipayMD5.GetMD5(sb.ToString(), getCharset()).ToUpper();
    106 
    107             this.setParameter("sign", sign);
    108         
    109             //debug信息
    110             this.setDebugInfo(sb.ToString() + " => sign:" + sign);        
    111         }
    112      
    113 
    114        //创建package签名
    115         public virtual string createMd5Sign()
    116         {
    117             StringBuilder sb = new StringBuilder();
    118             ArrayList akeys=new ArrayList(parameters.Keys); 
    119             akeys.Sort();
    120 
    121             foreach(string k in akeys)
    122             {
    123                 string v = (string)parameters[k];
    124                 if(null != v && "".CompareTo(v) != 0
    125                     && "sign".CompareTo(k) != 0 && "".CompareTo(v) != 0) 
    126                 {
    127                     sb.Append(k + "=" + v + "&");
    128                 }
    129             }
    130             string sign = AlipayMD5.GetMD5(sb.ToString(), getCharset()).ToLower();
    131 
    132             this.setParameter("sign", sign);
    133             return sign;
    134     }
    135 
    136         /// <summary>
    137         /// 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名(微信V3 package签名(MD5签名))
    138         /// </summary>
    139         /// <param name="key">参数名</param>
    140         /// <param name="value">参数值</param>
    141         /// key和value通常用于填充最后一组参数
    142         /// <returns></returns>
    143         public virtual string createMd5Sign(string key, string value)
    144         {
    145             StringBuilder sb = new StringBuilder();
    146 
    147             ArrayList akeys = new ArrayList(parameters.Keys);
    148             akeys.Sort();
    149 
    150             foreach (string k in akeys)
    151             {
    152                 string v = (string)parameters[k];
    153                 if (null != v && "".CompareTo(v) != 0
    154                     && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0)
    155                 {
    156                     sb.Append(k + "=" + v + "&");
    157                 }
    158             }
    159 
    160             sb.Append(key + "=" + value);
    161 
    162             string sign = AlipayMD5.GetMD5(sb.ToString(), getCharset()).ToUpper();
    163 
    164             return sign;
    165         }
    166 
    167 
    168 
    169          //输出XML
    170         public string parseXML()
    171         {
    172             StringBuilder sb = new StringBuilder();
    173             sb.Append("<xml>");
    174             foreach (string k in parameters.Keys)
    175             {
    176                 string v = (string)parameters[k];
    177                 if (Regex.IsMatch(v, @"^[0-9.]$"))
    178                 {
    179 
    180                     sb.Append("<" + k + ">" + v + "</" + k + ">");
    181                 }
    182                 else
    183                 {
    184                     sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">");
    185                 }
    186 
    187            }
    188             sb.Append("</xml>");
    189             return sb.ToString();
    190         }
    191 
    192        
    193 
    194         /** 设置debug信息 */
    195         public void setDebugInfo(String debugInfo) 
    196         {
    197             this.debugInfo = debugInfo;
    198         }
    199 
    200         public Hashtable getAllParameters()
    201         {
    202             return this.parameters;
    203         }
    204 
    205          protected virtual string getCharset()
    206       {
    207 
    208           return this.httpContext.Request.ContentEncoding.BodyName;
    209       } 
    210     }
    211 }
    View Code

    ResponseHandler.cs

      1 using Mimo.BLL;
      2 using Mimo.Model;
      3 using Mimo.Payment.Common;
      4 using Mimo.Payment.Common.PayPalJSON;
      5 using System;
      6 using System.Collections;
      7 using System.Collections.Specialized;
      8 using System.Text;
      9 using System.Web;
     10 using System.Xml;
     11 
     12 namespace Mimo.Payment.WeChatPay
     13 {
     14 
     15     /** 
     16     '============================================================================
     17     'api说明:
     18     'getKey()/setKey(),获取/设置密钥
     19     'getParameter()/setParameter(),获取/设置参数值
     20     'getAllParameters(),获取所有参数
     21     'isTenpaySign(),是否正确的签名,true:是 false:否
     22     'isWXsign(),是否正确的签名,true:是 false:否
     23     ' * isWXsignfeedback判断微信维权签名
     24     ' *getDebugInfo(),获取debug信息
     25     '============================================================================
     26     */
     27 
     28     public class ResponseHandler
     29     {
     30         // 密钥 
     31         private string key = WeChatConfig.ApiSecret;
     32 
     33 
     34         //xmlMap
     35         private Hashtable xmlMap;
     36 
     37         // 应答的参数
     38         protected Hashtable parameters;
     39 
     40         //debug信息
     41         private string debugInfo;
     42 
     43         /// <summary>
     44         /// 保存微信支付回调时 xml
     45         /// </summary>
     46         private string xmlInfo;
     47         //原始内容
     48         protected string content;
     49 
     50         private string charset = "utf-8";
     51 
     52 
     53         protected HttpContext httpContext;
     54 
     55         //初始化函数
     56         public virtual void init()
     57         {
     58         }
     59 
     60 
     61         //获取页面提交的get和post参数
     62         public ResponseHandler(HttpContext httpContext)
     63         {
     64             parameters = new Hashtable();
     65             xmlMap = new Hashtable();
     66 
     67             this.httpContext = httpContext;
     68             NameValueCollection collection;
     69             //post data
     70             if (this.httpContext.Request.HttpMethod == "POST")
     71             {
     72                 collection = this.httpContext.Request.Form;
     73                 foreach (string k in collection)
     74                 {
     75                     string v = (string)collection[k];
     76                     this.setParameter(k, v);
     77                 }
     78             }
     79             //query string
     80             collection = this.httpContext.Request.QueryString;
     81             foreach (string k in collection)
     82             {
     83                 string v = (string)collection[k];
     84                 this.setParameter(k, v);
     85             }
     86             if (this.httpContext.Request.InputStream.Length > 0)
     87             {
     88                 XmlDocument xmlDoc = new XmlDocument();
     89                 xmlDoc.Load(this.httpContext.Request.InputStream);
     90                 XmlNode root = xmlDoc.SelectSingleNode("xml");
     91                 XmlNodeList xnl = root.ChildNodes;
     92                 foreach (XmlNode xnf in xnl)
     93                 {
     94                     xmlMap.Add(xnf.Name, xnf.InnerText);
     95                 }
     96                 try
     97                 {
     98                     xmlInfo = JSON.Serialize(xmlDoc);
     99                 }
    100                 catch
    101                 {
    102                 }
    103             }
    104         }
    105 
    106 
    107         /** 获取密钥 */
    108         public string getKey()
    109         {
    110             return key;
    111         }
    112 
    113         /** 设置密钥 */
    114         public void setKey(string key)
    115         {
    116             this.key = key;
    117         }
    118 
    119         /** 获取参数值 */
    120         public string getParameter(string parameter)
    121         {
    122             string s = (string)parameters[parameter];
    123             return (null == s) ? "" : s;
    124         }
    125 
    126         /** 获取参数值 */
    127         public string getMpParameter(string parameter)
    128         {
    129             string s = (string)xmlMap[parameter];
    130             return (null == s) ? "" : s;
    131         }
    132 
    133         /** 设置参数值 */
    134         public void setParameter(string parameter, string parameterValue)
    135         {
    136             if (parameter != null && parameter != "")
    137             {
    138                 if (parameters.Contains(parameter))
    139                 {
    140                     parameters.Remove(parameter);
    141                 }
    142 
    143                 parameters.Add(parameter, parameterValue);
    144             }
    145         }
    146 
    147         //判断签名 微信安全支付V3
    148         public virtual Boolean isWXsign_MD5()
    149         {
    150             StringBuilder sb = new StringBuilder();
    151             Hashtable signMap = new Hashtable();
    152             foreach (string k in xmlMap.Keys)
    153             {
    154                 if (k != "sign")
    155                 {
    156                     signMap.Add(k.ToLower(), xmlMap[k]);
    157                 }
    158             }
    159 
    160             ArrayList akeys = new ArrayList(signMap.Keys);
    161             akeys.Sort();
    162 
    163             foreach (string k in akeys)
    164             {
    165                 string v = (string)signMap[k];
    166                 sb.Append(k + "=" + v + "&");
    167             }
    168             sb.Append("key=" + this.key);
    169 
    170             string sign = AlipayMD5.GetMD5(sb.ToString(), charset).ToString().ToUpper();
    171             this.setDebugInfo(sb.ToString() + " => sign:" + sign);
    172             return sign.Equals(xmlMap["sign"]);
    173 
    174         }
    175 
    176         /** 获取debug信息 */
    177         public string getDebugInfo()
    178         {
    179             return debugInfo;
    180         }
    181         /** 获取debug信息 */
    182         public string getXmlInfo()
    183         {
    184             return xmlInfo;
    185         }
    186         /** 设置debug信息 */
    187         protected void setDebugInfo(String debugInfo)
    188         {
    189             this.debugInfo = debugInfo;
    190         }
    191 
    192     }
    193 }
    View Code

     WeChatPayment.cs

      1 using Mimo.Payment.Common;
      2 using Mimo.Payment.WeChatPay;
      3 using System;
      4 using System.Collections.Generic;
      5 using System.Linq;
      6 using System.Text;
      7 using System.Threading.Tasks;
      8 using System.Xml.Linq;
      9 
     10 namespace Mimo.Payment.Payment
     11 {
     12     /// <summary>
     13     /// liuyt 2015.03.16 add
     14     /// 微信支付的公用方法
     15     /// </summary>
     16     public class WeChatPayment
     17     {
     18         /// <summary>
     19         /// liuyt 2015.03.16 add
     20         /// 调用统一下单接口获取预交易订单号或者Code_URL,参数值 取决于trade_type的参数值
     21         /// </summary>
     22         /// <param name="model"></param>
     23         /// <returns></returns>
     24         #region 调用统一下单接口获取预交易订单号
     25         public static string GetprepayId(WeChatParameter model)
     26         {
     27             //创建支付应答对象
     28             RequestHandler packageReqHandler = new RequestHandler(System.Web.HttpContext.Current);
     29             //初始化
     30             packageReqHandler.init();
     31             //设置package订单参数
     32             packageReqHandler.setParameter("appid", WeChatConfig.AppId);          //公众账号ID
     33             packageReqHandler.setParameter("mch_id", WeChatConfig.Mch_id);          //商户号
     34             packageReqHandler.setParameter("nonce_str", PaymentCommon.GetNoncestr());                    //随机字符串
     35             packageReqHandler.setParameter("body", "test");                //商品描述  128字节以下
     36             packageReqHandler.setParameter("out_trade_no", model.out_trade_no.Trim());        //商家订单号
     37             packageReqHandler.setParameter("total_fee", (model.total_fee * 100).ToString("F0"));                    //商品金额,以分为单位(money * 100).ToString()
     38             packageReqHandler.setParameter("spbill_create_ip", model.spbill_create_ip);   //用户的公网ip,不是商户服务器IP
     39             packageReqHandler.setParameter("notify_url", model.notify_url);            //接收财付通通知的URL
     40             packageReqHandler.setParameter("trade_type", model.trade_type);                        //交易类型
     41             if (model.trade_type.ToLower() == "jsapi")
     42             {
     43                 packageReqHandler.setParameter("openid", model.openid);
     44             }       //用户的openId      
     45             string sign = packageReqHandler.createMd5Sign("key", WeChatConfig.ApiSecret);//key 密钥
     46             packageReqHandler.setParameter("sign", sign);    //签名    
     47             string data = packageReqHandler.parseXML();
     48             string result = HttpUtil.Send(data, WeChatConfig.UnifiedOrderUrl);
     49             var res = XDocument.Parse(result);
     50             string rs = string.Empty;
     51             if (model.trade_type.ToLower() == "jsapi")
     52             {
     53                 rs = res.Element("xml").Element("prepay_id").Value;  //微信V3预支付交易订单号
     54             }
     55             else if (model.trade_type.ToLower() == "native")
     56             {
     57                 rs = res.Element("xml").Element("code_url").Value;  //微信V3预支付交易订单号
     58             }
     59             return rs;
     60         }
     61         #endregion
     62 
     63         /// <summary>
     64         /// liuyt 2015.03.16 add
     65         /// 获取支付密钥
     66         /// </summary>
     67         /// <param name="prepayId"></param>
     68         /// <returns></returns>
     69         #region 获取支付密钥
     70         public static string GetPaySign(WeChatViewParameter model)
     71         {
     72             RequestHandler paySignReqHandler = new RequestHandler(System.Web.HttpContext.Current);
     73             paySignReqHandler.setParameter("appId", model.AppId);
     74             paySignReqHandler.setParameter("timeStamp", model.TimeStamp);
     75             paySignReqHandler.setParameter("nonceStr", model.NonceStr);
     76             paySignReqHandler.setParameter("package", string.Format("prepay_id={0}", model.Prepay_id));
     77             paySignReqHandler.setParameter("signType", "MD5");
     78             string paySign = paySignReqHandler.createMd5Sign("key", WeChatConfig.ApiSecret);//key 密钥
     79             return paySign;
     80         }
     81         #endregion
     82 
     83         /// <summary>
     84         /// liuyt 2015.03.16 add
     85         ///  获取扫码支付的二维码图
     86         /// </summary>
     87         /// <param name="model"></param>
     88         /// <returns></returns>
     89         #region 获取扫码支付的二维码图
     90         public static ImageResult GetNativeImageResult(WeChatParameter model)
     91         {
     92             string code_url = GetprepayId(model);
     93             return PaymentCommon.GetQRCodeImageResult(code_url);
     94         }
     95         #endregion
     96 
     97         /// <summary>
     98         /// liuyt 2015.03.16 add
     99         /// 获取微信支付的异步通知的参数
    100         /// </summary>
    101         /// <returns></returns>
    102         #region 获取微信支付的异步通知的参数
    103         public static WeChatResultParameter GetNotifyResult()
    104         {
    105             WeChatResultParameter model = new WeChatResultParameter();
    106 
    107             ResponseHandler resHandler = new ResponseHandler(System.Web.HttpContext.Current);
    108             string debugInfo = resHandler.getDebugInfo();
    109             #region 协议参数=====================================
    110             //--------------协议参数--------------------------------------------------------
    111             //SUCCESS/FAIL此字段是通信标识,非交易标识,交易是否成功需要查
    112             string return_code = resHandler.getMpParameter("return_code");
    113             model.result_code = return_code;
    114             //返回信息,如非空,为错误原因签名失败参数格式校验错误
    115             string return_msg = resHandler.getMpParameter("return_msg");
    116             model.return_msg = return_msg;
    117             //微信分配的公众账号 ID
    118             string appid = resHandler.getMpParameter("appid");
    119             model.appid = appid;
    120             //以下字段在 return_code 为 SUCCESS 的时候有返回--------------------------------
    121             //微信支付分配的商户号
    122             string mch_id = resHandler.getMpParameter("mch_id");
    123             model.mch_id = mch_id;
    124             //微信支付分配的终端设备号
    125             string device_info = resHandler.getMpParameter("device_info");
    126             model.device_info = device_info;
    127             //微信分配的公众账号 ID
    128             string nonce_str = resHandler.getMpParameter("nonce_str");
    129             model.nonce_str = nonce_str;
    130             //业务结果 SUCCESS/FAIL
    131             string result_code = resHandler.getMpParameter("result_code");
    132             model.return_code = result_code;
    133             //错误代码 
    134             string err_code = resHandler.getMpParameter("err_code");
    135             model.err_code = err_code;
    136             //结果信息描述
    137             string err_code_des = resHandler.getMpParameter("err_code_des");
    138             model.err_code_des = err_code_des;
    139             //以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回---------------
    140             //-------------业务参数---------------------------------------------------------
    141             //用户在商户 appid 下的唯一标识
    142             string openid = resHandler.getMpParameter("openid");
    143             model.openid = openid;
    144             //用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效
    145             string is_subscribe = resHandler.getMpParameter("is_subscribe");
    146             model.is_subscribe = is_subscribe;
    147             //JSAPI、NATIVE、MICROPAY、APP
    148             string trade_type = resHandler.getMpParameter("trade_type");
    149             model.trade_type = trade_type;
    150             //银行类型,采用字符串类型的银行标识
    151             string bank_type = resHandler.getMpParameter("bank_type");
    152             model.bank_type = bank_type;
    153             //订单总金额,单位为分
    154             string total_fee = resHandler.getMpParameter("total_fee");
    155             model.total_fee = total_fee;
    156             //货币类型,符合 ISO 4217 标准的三位字母代码,默认人民币:CNY
    157             string fee_type = resHandler.getMpParameter("fee_type");
    158             model.fee_type = fee_type;
    159             //微信支付订单号
    160             string transaction_id = resHandler.getMpParameter("transaction_id");
    161             model.transaction_id = transaction_id;
    162             //商户系统的订单号,与请求一致。
    163             string out_trade_no = resHandler.getMpParameter("out_trade_no");
    164             model.out_trade_no = out_trade_no;
    165             //商家数据包,原样返回
    166             string attach = resHandler.getMpParameter("attach");
    167             model.attach = attach;
    168             //支 付 完 成 时 间 , 格 式 为yyyyMMddhhmmss,如 2009 年12 月27日 9点 10分 10 秒表示为 20091227091010。时区为 GMT+8 beijing。该时间取自微信支付服务器
    169             string time_end = resHandler.getMpParameter("time_end");
    170             model.time_end = time_end;
    171             #endregion
    172             if (resHandler.isWXsign_MD5())
    173             {
    174                 model.isWXsign_MD5 = true;
    175                 if (!out_trade_no.Equals("") && return_code.Equals("SUCCESS") && result_code.Equals("SUCCESS"))
    176                 {
    177                     model.RsIsSuccess = true;
    178                 }
    179                 else
    180                 {
    181                     model.RsIsSuccess = false;
    182                 }
    183             }
    184             else
    185             {
    186                 model.isWXsign_MD5 = false;
    187                 model.RsIsSuccess = false;
    188             }
    189             model.debugInfo = resHandler.getDebugInfo();
    190             model.xmlInfo = resHandler.getXmlInfo();
    191             return model;
    192         }
    193         #endregion
    194 
    195         /// <summary>
    196         /// liuyt 2015.03.16 add
    197         /// 设置XML格式的响应数据
    198         /// </summary>
    199         /// <param name="return_code"></param>
    200         /// <param name="return_msg"></param>
    201         #region 设置XML格式的响应数据
    202         public static void ResponseXML(string return_code, string return_msg)
    203         {
    204             RequestHandler returnReqHandler = new RequestHandler(System.Web.HttpContext.Current);
    205             returnReqHandler.setParameter("return_code", return_code);
    206             returnReqHandler.setParameter("return_msg", return_msg);
    207             string xmlStr = returnReqHandler.parseXML();
    208             System.Web.HttpContext.Current.Response.ContentType = "text/xml";
    209             System.Web.HttpContext.Current.Response.Clear();
    210             System.Web.HttpContext.Current.Response.Write(xmlStr);
    211             System.Web.HttpContext.Current.Response.End();
    212         } 
    213         #endregion
    214 
    215     }
    216 }
    View Code

    WeChatParameter.cs

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace Mimo.Payment.Common
     8 {
     9     /// <summary>
    10     /// liuyt 2015.03.16 add
    11     /// 微信支付参数类
    12     /// </summary>
    13     public class WeChatParameter
    14     {
    15         #region 1.0 属性
    16         /// <summary>
    17         /// 商品描述
    18         /// </summary>
    19         public string body { get; set; }
    20 
    21         /// <summary>
    22         /// 商户订单号 必须唯一不弄重复
    23         /// </summary>
    24         public string out_trade_no { get; set; }
    25 
    26         /// <summary>
    27         /// 商品总价 单位:元
    28         /// </summary>
    29         public double total_fee { get; set; }
    30 
    31         /// <summary>
    32         /// JSAPI 用户IP,Native 商户服务器IP  注意两者的区别
    33         /// </summary>
    34         public string spbill_create_ip { get; set; }
    35 
    36         /// <summary>
    37         /// 微信支付异步通知的URL
    38         /// </summary>
    39         public string notify_url { get; set; }
    40 
    41         /// <summary>
    42         /// 交易类型
    43         /// </summary>
    44         public string trade_type { get; set; }
    45 
    46         /// <summary>
    47         /// 用户的openid
    48         /// </summary>
    49         public string openid { get; set; } 
    50         #endregion
    51 
    52         #region 2.0 构造函数
    53         public WeChatParameter()
    54         {
    55 
    56         }
    57 
    58         public WeChatParameter(string body, string out_trade_no, double total_fee, string spbill_create_ip, string notify_url, string trade_type, string openid)
    59         {
    60             
    61             this.body = body;
    62             this.out_trade_no = out_trade_no;
    63             this.total_fee = total_fee;
    64             this.spbill_create_ip = spbill_create_ip;
    65             this.notify_url = notify_url;
    66             this.trade_type = trade_type;
    67             this.openid = openid;
    68         }
    69         public WeChatParameter(string body, string out_trade_no, double total_fee, string spbill_create_ip, string notify_url, string trade_type)
    70         {
    71             this.body = body;
    72             this.out_trade_no = out_trade_no;
    73             this.total_fee = total_fee;
    74             this.spbill_create_ip = spbill_create_ip;
    75             this.notify_url = notify_url;
    76             this.trade_type = trade_type;
    77         } 
    78         #endregion
    79     }
    80 }
    View Code

    WeChatViewParameter.cs

     1 using Mimo.Payment.Payment;
     2 using System;
     3 using System.Collections.Generic;
     4 using System.Linq;
     5 using System.Text;
     6 using System.Threading.Tasks;
     7 
     8 namespace Mimo.Payment.Common
     9 {
    10     /// <summary>
    11     /// 给JSAPI使用的参数类
    12     /// </summary>
    13     public class WeChatViewParameter
    14     {
    15 
    16         /// <summary>
    17         /// 公众号ID
    18         /// </summary>
    19         public string AppId
    20         {
    21             get { return WeChatConfig.AppId; }
    22         }
    23 
    24         private string timeStamp = PaymentCommon.GetTimestamp();
    25 
    26         /// <summary>
    27         /// 时间戳
    28         /// </summary>
    29         public string TimeStamp
    30         {
    31             get { return timeStamp; }
    32         }
    33         //WeChatParameter wcp = new WeChatParameter("此订单为用户在 上的商品", out_trade_no, 1, spbill_create_ip, notify_url, trade_type, openid);
    34         //  string prepayId = WeChatPayment.GetprepayId(wcp);
    35 
    36         /// <summary>
    37         /// 随机字符串
    38         /// </summary>
    39         private string nonceStr = PaymentCommon.GetNoncestr();
    40         public string NonceStr
    41         {
    42             get { return nonceStr; }
    43         }
    44 
    45         /// <summary>
    46         /// 获取预交易订单号
    47         /// </summary>
    48         private string prepay_id;
    49         public string Prepay_id
    50         {
    51             get { return prepay_id; }
    52         }
    53 
    54         /// <summary>
    55         /// 微信支付签名
    56         /// </summary>
    57         private string paySign;
    58         public string PaySign
    59         {
    60             get { return paySign; }
    61             set { paySign = value; }
    62         }
    63         public void SetPaySign(string prepay_id)
    64         {
    65             this.prepay_id = prepay_id;
    66             paySign = WeChatPayment.GetPaySign(this);
    67         }
    68         public void SetPaySign(WeChatParameter model)
    69         {
    70             string prepayId = WeChatPayment.GetprepayId(model);
    71             this.prepay_id = prepayId;
    72             paySign = WeChatPayment.GetPaySign(this);
    73         }
    74     }
    75 }
    View Code

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    一下是一些调用示例:

     1 using Mimo.BLL;
     2 using Mimo.BLL.Common;
     3 using Mimo.Components.Helper;
     4 using Mimo.Components.Web;
     5 using Mimo.Model;
     6 using Mimo.Payment;
     7 using Mimo.Payment.Common;
     8 using Mimo.Payment.Payment;
     9 using System;
    10 using System.Linq;
    11 using System.Web.Mvc;
    12 using System.Xml;
    13 
    14 namespace Mimo.Web.controllers
    15 {
    16     public class BizWechatController : Controller
    17     { /// <summary>
    18         /// 测试链接 JSAPI
    19         /// </summary>
    20         /// <returns></returns>
    21         public ActionResult Index()
    22         {
    23             Random d = new Random();
    24             string out_trade_no = Convert.ToString(d.Next(10000, 100000));
    25             string spbill_create_ip = "119.129.208.90"; //PaymentCommon.ClientIP;
    26             string notify_url = "http://*******";
    27             string trade_type = "JSAPI";
    28             string openid = "*******";
    29 
    30             WeChatParameter wcp = new WeChatParameter("此订单为用户在*****上的商品", out_trade_no, 0.01, spbill_create_ip, notify_url, trade_type, openid);
    31             WeChatViewParameter wcPara = new WeChatViewParameter();
    32             wcPara.SetPaySign(wcp);
    33 
    34             ViewBag.WcPara = wcPara;
    35             return View(wcPara);
    36         }
    37 
    38         /// <summary>
    39         /// 测试链接 扫码支付
    40         /// </summary>
    41         /// <returns></returns>
    42         public ActionResult Native()
    43         {
    44             Random d = new Random();
    45             string out_trade_no = Convert.ToString(d.Next(10000, 100000));
    46             string spbill_create_ip = PaymentCommon.GetServerIP();//服务器Ip
    47             string notify_url = "http://********";
    48             string trade_type = "NATIVE";
    49 
    50             WeChatParameter wcp = new WeChatParameter("此订单为用户在**** 上的商品", out_trade_no, 0.01, spbill_create_ip, notify_url, trade_type);
    51 
    52             ImageResult imgResult = WeChatPayment.GetNativeImageResult(wcp);
    53             return imgResult;
    54         }
    55     }
    56 }
    View Code

    Index.cshtml (调用JSAPI的示例)

     1 @{
     2     ViewBag.Title = "GGG";
     3 }
     4 
     5 <!DOCTYPE html>
     6 
     7 <html>
     8 <head>
     9     <meta name="viewport" content="width=device-width" />
    10     <title>Index</title>
    11     <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
    12     <script type="text/javascript">
    13         @{  Mimo.Payment.Common.WeChatViewParameter wcPara =@ViewBag.WcPara;}
    14     //调用微信JS api 支付
    15     function jsApiCall() {
    16         var divObj = document.getElementById("msg");
    17         WeixinJSBridge.invoke(
    18 
    19             'getBrandWCPayRequest', {
    20                 "appId": "@wcPara.AppId",     //公众号名称,由商户传入
    21                 "timeStamp": "@wcPara.TimeStamp",         //时间戳,自1970年以来的秒数
    22                 "nonceStr": "@wcPara.NonceStr", //随机串
    23                 "package": "prepay_id=@wcPara.Prepay_id",
    24                 "signType": "MD5",         //微信签名方式:
    25                 "paySign": "@wcPara.PaySign" //微信签名
    26     
    27             },
    28             function (res) {
    29                 WeixinJSBridge.log(res.err_msg);
    30                 divObj.innerHTML = JSON.stringify(res);
    31                 var divObjRs = document.getElementById("rsmsg");
    32                 if (res.err_msg == "get_brand_wcpay_request:ok") {
    33 
    34                     divObjRs.innerHTML = JSON.stringify(res);
    35                 } else {
    36                     divObjRs.innerHTML = "失败了!";
    37                 }
    38             }
    39         );
    40     }
    41     function callpay() {
    42         if (typeof WeixinJSBridge == "undefined") {
    43             if (document.addEventListener) {
    44                 document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
    45             } else if (document.attachEvent) {
    46                 document.attachEvent('WeixinJSBridgeReady', jsApiCall);
    47                 document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
    48             }
    49         } else {
    50             jsApiCall();
    51         }
    52     }
    53     </script>
    54 
    55 </head>
    56 <body>
    57 
    58     <div id="msgasda">@{Mimo.Payment.Common.PayPalJSON.JSON.Serialize(wcPara);}</div>
    59     <div id="msg"></div>
    60     <div id="rsmsg"></div>
    61     </br></br></br></br>
    62     <div align="center">
    63         <button style="210px; height:30px; background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer;  color:white;  font-size:16px;" type="button" onclick="callpay()">我任性</button>
    64     </div>
    65 </body>
    66 </html>
    View Code


    调用扫码支付的示例:

    调用扫码支付时,只需要把生成的响应对象放到浏览器就行了,其中生成二维码的组件使用的是ThoughtWorks.QRCode.dll

     1   /// <summary>
     2         /// 测试链接 扫码支付
     3         /// </summary>
     4         /// <returns></returns>
     5         public ActionResult Native()
     6         {
     7             Random d = new Random();
     8             string out_trade_no = Convert.ToString(d.Next(10000, 100000));
     9             string spbill_create_ip = PaymentCommon.GetServerIP();//服务器Ip
    10             string notify_url = "http://****************";
    11             string trade_type = "NATIVE";
    12 
    13             WeChatParameter wcp = new WeChatParameter("此订单为用户在******* 上的商品", out_trade_no, 0.01, spbill_create_ip, notify_url, trade_type);
    14 
    15             ImageResult imgResult = WeChatPayment.GetNativeImageResult(wcp);
    16             return imgResult;
    17         }
    18         /// <summary>
    19         ///  liuyt 2015.01.12 add
    20         /// 根据一定数据生成 二维码,返回视图响应数据
    21         /// </summary>
    22         /// <param name="data"></param>
    23         /// <returns></returns>
    24         #region 根据一定数据生成 二维码,返回视图响应数据+static ImageResult GetQRCodeImage(string data)
    25         public static ImageResult GetQRCodeImageResult(string data)
    26         {
    27             QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
    28             qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;//二维码编码格式:ALPHA_NUMERIC,NUMERIC,BYTE
    29             qrCodeEncoder.QRCodeScale = 8;//二维码大小,自定义
    30             qrCodeEncoder.QRCodeVersion = 0;//二维码版本
    31             qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;//有H,L,M,Q可选,错误机制级别
    32             Image image = qrCodeEncoder.Encode(data, Encoding.Default);//image 就是生成的二维码图片,可以按照自己的方式去保存,这里直接显示到网页
    33             ImageResult imgResult = new ImageResult(image);
    34             return imgResult;
    35         }
    36         #endregion
    View Code

    ImageResult.cs 返回给浏览器时使用的Result类型

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Drawing;
     4 using System.Drawing.Imaging;
     5 using System.Linq;
     6 using System.Text;
     7 using System.Threading.Tasks;
     8 using System.Web;
     9 using System.Web.Mvc;
    10 
    11 namespace Mimo.Payment.Common
    12 {
    13     /// <summary>
    14     /// 构造返回图片的视图
    15     /// </summary>
    16     public class ImageResult : ActionResult
    17     {
    18         // 图片
    19         public Image imageData;
    20 
    21 
    22         // 构造器
    23         public ImageResult(Image image)
    24         {
    25             imageData = image;
    26         }
    27 
    28         // 主要需要重写的方法
    29         public override void ExecuteResult(ControllerContext context)
    30         {
    31             if (context == null)
    32             {
    33                 throw new ArgumentNullException("context");
    34             }
    35             HttpResponseBase response = context.HttpContext.Response;
    36             // 设置 HTTP Header
    37             response.ContentType = "image/jpeg";
    38             // 将图片数据写入Response 
    39             imageData.Save(context.HttpContext.Response.OutputStream, ImageFormat.Jpeg);
    40         }
    41     }
    42 }
    View Code

    2015.03.20 以上就是最近完成的微信支付

  • 相关阅读:
    oop第四次课作业总结
    我罗斯方块
    getline()、cin.getline()、cin.get()的区分和应用
    20200328上记笔记
    Markdown使用方法
    A Lovely Message Board
    NOIP2020游记
    题解 Codeforces Round #678 (Div. 2) (CF1436)
    CSP-S2020 第一轮认证(初赛)游记
    题解 Codeforces Round #670 (Div. 2) (CF1406)
  • 原文地址:https://www.cnblogs.com/liuyu7177/p/4353889.html
Copyright © 2020-2023  润新知