NEWS

技术文章

微信小程序支付功能 C# .NET开发

编辑:
起点网络
发布时间:
2018-8-13
点击:
 1、首先建议把官方文档支付部分看上三遍,每个细节都不要放过,因为任何一个点和微信要求不符都会导致支付不成功。https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=3_1

      2、经过验证的微信支付功能,会需要一些商户号、支付秘钥等,不要搞混。

     3、经常遇到的是“签名错误”,请仔细看需要传送的xml参数及取值规则是否符合微信规则。微信有个验证工具可以验证发送的xml字段是否合法。



下面上代码:



web.config


    <add key="ConnectionString" value="server=127.0.0.1;database=;uid=sa;pwd="/>
    <add key="ConnectionString2" value="server=127.0.0.1;database=codematic2;uid=sa;pwd=1"/>
    <add key="appid" value=""/>//appid
    <add key="secret" value=""/>//小程序秘钥
    <add key="mch_id" value=""/>//商户号
    <add key="key" value=""/>//支付秘钥
    <add key="ip" value=""/>//服务器IP
    <add key="PayResulturl" value=""/>//微信返回接收信息的url地址
  </appSettings>
支付后台xiadan.ashx

<%@ WebHandler Language="C#" Class="xiadan" %>
 
using System;
using System.Web;
using System.Net;
using System.IO;
using System.Configuration;
using Maticsoft.Model;
using Maticsoft.BLL;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Serialization;
using System.Xml;
using System.Collections.Generic;
using System.Data;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Linq;
using Newtonsoft.Json;
 
public class xiadan : IHttpHandler
{
 
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        string openid = context.Request.Params["openid"];
        string ordertime = context.Request.Params["ordertime"];
 
        string appid = ConfigurationManager.AppSettings["appid"];
        string secret = ConfigurationManager.AppSettings["secret"];
        string key = ConfigurationManager.AppSettings["key"];
        string mch_id = ConfigurationManager.AppSettings["mch_id"];
        string ip = ConfigurationManager.AppSettings["ip"];
        string PayResulturl = ConfigurationManager.AppSettings["PayResulturl"];
        string roomid = context.Request.Params["roomid"];
        string aa = "-押金";////商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。
 
        string strcode = aa;
        byte[] buffer = Encoding.UTF8.GetBytes(strcode);
        string body = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
        string totalfee = context.Request.Params["totalfee"];
        string output = "";
        if ((context.Request.Params["openid"] != null) && (context.Request.Params["openid"] != ""))
        {
            //OrderInfo order = new OrderInfo();
 
            //order.appid = appid;
 
            System.Random Random = new System.Random();
 
 
 
            var dic = new Dictionary<string, string>
{
    {"appid", appid},
    {"mch_id", mch_id},
    {"nonce_str", GetRandomString(20)/*Random.Next().ToString()*/},
    {"body",body},
    {"out_trade_no",roomid + DateTime.Now.ToString("yyyyMMddHHmmssfff") + Random.Next(999).ToString()},//商户自己的订单号码
    {"total_fee",totalfee},
    {"spbill_create_ip",ip},//服务器的IP地址
    {"notify_url",PayResulturl},//异步通知的地址,不能带参数
    {"trade_type","JSAPI" },
    {"openid",openid}
};
      //加入签名
            dic.Add("sign", GetSignString(dic));
 
            var sb = new StringBuilder();
            sb.Append("<xml>");
 
 
            foreach (var d in dic)
            {
                sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
            }
            sb.Append("</xml>");
            var xml = new XmlDocument();
            //  xml.LoadXml(GetPostString("https://api.mch.weixin.qq.com/pay/unifiedorder", sb.ToString()));
            CookieCollection coo = new CookieCollection();
            Encoding en = Encoding.GetEncoding("UTF-8");
 
            HttpWebResponse response = CreatePostHttpResponse("https://api.mch.weixin.qq.com/pay/unifiedorder", sb.ToString(), en);
            //打印返回值
            Stream stream = response.GetResponseStream();   //获取响应的字符串流
            StreamReader sr = new StreamReader(stream); //创建一个stream读取流
            string html = sr.ReadToEnd();   //从头读到尾,放到字符串html
                                            //Console.WriteLine(html);
            xml.LoadXml(html);
            //对请求返回值 进行处理
 
            var root = xml.DocumentElement;
 
            DataSet ds = new DataSet();
            StringReader stram = new StringReader(html);
            XmlTextReader reader = new XmlTextReader(stram);
            ds.ReadXml(reader);
            string return_code = ds.Tables[0].Rows[0]["return_code"].ToString();
            if (return_code.ToUpper() == "SUCCESS")
            {
                //通信成功
                string result_code = ds.Tables[0].Rows[0]["result_code"].ToString();//业务结果
                if (result_code.ToUpper() == "SUCCESS")
                {
                    var res = new Dictionary<string, string>
{
    {"appId", appid},
    {"timeStamp", GetTimeStamp()},
    {"nonceStr", dic["nonce_str"]},
    {"package",  "prepay_id="+ds.Tables[0].Rows[0]["prepay_id"].ToString()},
    {"signType", "MD5"}
};
 
                    //在服务器上签名
                    res.Add("paySign", GetSignString(res));
                    // string signapp = res.ToString();
                    string signapp = JsonConvert.SerializeObject(res);
                    if ((context.Request.Params["openid"] != null) && (context.Request.Params["openid"] != ""))
                    { 
                    //存储订单信息
                    Maticsoft.Model.order_history oh = new Maticsoft.Model.order_history();
                    //oh.shop_id =
                    oh.room_id = Convert.ToInt32(roomid);
                    oh.pay_price = Convert.ToDecimal(totalfee);
                    oh.out_trade_no = dic["out_trade_no"];
                    oh.order_timestart = Convert.ToDateTime(ordertime);
                    oh.openid = openid;
                    oh.creating_date = DateTime.Now;
 
                    Maticsoft.BLL.order_history bll = new Maticsoft.BLL.order_history();
                    bll.Add(oh);
 
                }
                context.Response.Write(signapp);
            }
        }
 
 
 
 
    }
    context.Response.Write(output);
    }
 
public bool IsReusable
{
    get
    {
        return false;
    }
}
 
public string GetMd5Hash(String input)
{
    if (input == null)
    {
        return null;
    }
 
    MD5 md5Hash = MD5.Create();
 
    // 将输入字符串转换为字节数组并计算哈希数据  
    byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
 
    // 创建一个 Stringbuilder 来收集字节并创建字符串  
    StringBuilder sBuilder = new StringBuilder();
 
    // 循环遍历哈希数据的每一个字节并格式化为十六进制字符串  
    for (int i = 0; i < data.Length; i++)
    {
        sBuilder.Append(data[i].ToString());
    }
 
    // 返回十六进制字符串  
    return sBuilder.ToString();
}
/// <summary>  
/// 对象序列化成 XML String  
/// </summary>  
public static string XmlSerialize<T>(T obj)
{
    string xmlString = string.Empty;
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
    using (MemoryStream ms = new MemoryStream())
    {
        xmlSerializer.Serialize(ms, obj);
        xmlString = Encoding.UTF8.GetString(ms.ToArray());
    }
    return xmlString;
}
/// <summary>
/// 从字符串里随机得到,规定个数的字符串.
/// </summary>
/// <param name="allChar"></param>
/// <param name="CodeCount"></param>
/// <returns></returns>
public static string GetRandomString(int CodeCount)
{
    string allChar = "1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,i,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
    string[] allCharArray = allChar.Split(',');
    string RandomCode = "";
    int temp = -1;
    Random rand = new Random();
    for (int i = 0; i < CodeCount; i++)
    {
        if (temp != -1)
        {
            rand = new Random(temp * i * ((int)DateTime.Now.Ticks));
        }
        int t = rand.Next(allCharArray.Length - 1);
        while (temp == t)
        {
            t = rand.Next(allCharArray.Length - 1);
        }
        temp = t;
        RandomCode += allCharArray[t];
    }
 
    return RandomCode;
}
 
 
public static string GetWebClientIp()
{
    string userIP = "IP";
 
    try
    {
        if (System.Web.HttpContext.Current == null
    || System.Web.HttpContext.Current.Request == null
    || System.Web.HttpContext.Current.Request.ServerVariables == null)
            return "";
 
        string CustomerIP = "";
 
        //CDN加速后取到的IP   
        CustomerIP = System.Web.HttpContext.Current.Request.Headers["Cdn-Src-Ip"];
        if (!string.IsNullOrEmpty(CustomerIP))
        {
            return CustomerIP;
        }
 
        CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
 
 
        if (!String.IsNullOrEmpty(CustomerIP))
            return CustomerIP;
 
        if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
        {
            CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (CustomerIP == null)
                CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
        }
        else
        {
            CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
 
        }
 
        if (string.Compare(CustomerIP, "unknown", true) == 0)
            return System.Web.HttpContext.Current.Request.UserHostAddress;
        return CustomerIP;
    }
    catch { }
 
    return userIP;
}
 
 
 
 
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
    return true; //总是接受   
}
 
public static HttpWebResponse CreatePostHttpResponse(string url, string datas, Encoding charset)
{
    HttpWebRequest request = null;
    //HTTPSQ请求
    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
    request = WebRequest.Create(url) as HttpWebRequest;
    request.ProtocolVersion = HttpVersion.Version10;
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
 
    //如果需要POST数据   
    //if (!(parameters == null || parameters.Count == 0))
    //{
    StringBuilder buffer = new StringBuilder();
    //int i = 0;
    //foreach (string key in parameters.Keys)
    //{
    //    if (i > 0)
    //    {
    //        buffer.AppendFormat("&{0}={1}", key, parameters[key]);
    //    }
    //    else
    //    {
    //        buffer.AppendFormat("{0}={1}", key, parameters[key]);
    //    }
    //    i++;
    //}
    buffer.AppendFormat(datas);
    byte[] data = charset.GetBytes(buffer.ToString());
    using (Stream stream = request.GetRequestStream())
    {
        stream.Write(data, 0, data.Length);
    }
    //}
    return request.GetResponse() as HttpWebResponse;
}
 
 
public string GetSignString(Dictionary<string, string> dic)
{
    string key = System.Web.Configuration.WebConfigurationManager.AppSettings["key"].ToString();//商户平台 API安全里面设置的KEY  32位长度
                                                                                                //排序
    dic = dic.OrderBy(d => d.Key).ToDictionary(d => d.Key, d => d.Value);
    //连接字段
    var sign = dic.Aggregate("", (current, d) => current + (d.Key + "=" + d.Value + "&"));
    sign += "key=" + key;
    //MD5
    // sign = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sign, "MD5").ToUpper();
    System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
    sign = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(sign))).Replace("-", null);
    return sign;
}
 
 
/// <summary>  
/// 获取时间戳  
/// </summary>  
/// <returns></returns>  
public static string GetTimeStamp()
{
    TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
    return Convert.ToInt64(ts.TotalSeconds).ToString();
}
}
 

标签  微信小程序开发 asp.net开发
上一条新闻:apicloud开发api介绍
相关文章

Copyright@宁波起点网络. All rights reserved. Powered by 起点网络       备案号:浙ICP备 16017710号