Development of small program payment function C#.NET

There are many pits in the development of small program payment functions, but caution is also a good thing for money. There are many examples of small program payment on the Internet, but most of them have some problems, and C# is less developed. The purpose of this document is to make a comment on the problems encountered in the development process, and also to facilitate other students to develop as a reference!


1, first of all, it is recommended that the official documents pay part of the three times, each detail should not pass, because any point and the request does not meet the requirements will lead to the failure of payment.

2, the verified WeChat payment function will require some merchant numbers, payment secret key and so on.

3, often encountered is the "signature error", please carefully look at the need to transfer the xml parameters and whether the value rules conform to the rules. There is a validation tool to verify whether the xml field sent is legitimate.


The following code:




    <add key="ConnectionString" value="server=;database=;uid=sa;pwd="/>
    <add key="ConnectionString2" value="server=;database=codematic2;uid=sa;pwd=1"/>
    <add key="appid" value=""/>//appid
    <add key="secret" value=""/>//Small program secret key
    <add key="mch_id" value=""/>//Merchant number
    <add key="key" value=""/>//Payment secret key
    <add key="ip" value=""/>//Server IP
    <add key="PayResulturl" value=""/>//WeChat returns the url address of the received information.

Payment background 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 = "-deposit";//// According to different application scenarios, the format of commodity description transaction field follows the following format: APP - APP name that needs to be introduced into the application market - actual commodity name, everyday love elimination - game recharge.

        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()*/},
    {"out_trade_no",roomid + DateTime.Now.ToString("yyyyMMddHHmmssfff") + Random.Next(999).ToString()},//Merchant's own order number
    {"spbill_create_ip",ip},//IP address of server
    {"notify_url",PayResulturl},//Asynchronous notification address, not with parameters
    {"trade_type","JSAPI" },
      //Signature added
            dic.Add("sign", GetSignString(dic));

            var sb = new StringBuilder();

            foreach (var d in dic)
                sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
            var xml = new XmlDocument();
            //  xml.LoadXml(GetPostString("", sb.ToString()));
            CookieCollection coo = new CookieCollection();
            Encoding en = Encoding.GetEncoding("UTF-8");

            HttpWebResponse response = CreatePostHttpResponse("", sb.ToString(), en);
            //Print the return value
            Stream stream = response.GetResponseStream();   //String Stream to Get Responses
            StreamReader sr = new StreamReader(stream); //Create a stream read stream
            string html = sr.ReadToEnd();   //Read from beginning to end, and put it in the string html
            //Processing the request return value

            var root = xml.DocumentElement;

            DataSet ds = new DataSet();
            StringReader stram = new StringReader(html);
            XmlTextReader reader = new XmlTextReader(stram);
            string return_code = ds.Tables[0].Rows[0]["return_code"].ToString();
            if (return_code.ToUpper() == "SUCCESS")
                //Successful communication
                string result_code = ds.Tables[0].Rows[0]["result_code"].ToString();//Business results
                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"}

                    //Sign on the server
                    res.Add("paySign", GetSignString(res));
                    // string signapp = res.ToString();
                    string signapp = JsonConvert.SerializeObject(res);
                    if ((context.Request.Params["openid"] != null) && (context.Request.Params["openid"] != ""))
                    //Store order information
                    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();



public bool IsReusable
        return false;

public string GetMd5Hash(String input)
    if (input == null)
        return null;

    MD5 md5Hash = MD5.Create();

    // Converting input strings to byte arrays and calculating hash data  
    byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

    // Create a Stringbuilder to collect bytes and create strings  
    StringBuilder sBuilder = new StringBuilder();

    // Loop through each byte of hash data and format it into a hexadecimal string  
    for (int i = 0; i < data.Length; i++)

    // Returns a hexadecimal string  
    return sBuilder.ToString();
/// <summary>  
/// Object serialization into 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>
/// Random from the string, specify the number of strings.
/// </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++)

Tags: Android xml encoding Database less

Posted on Mon, 07 Oct 2019 12:59:26 -0700 by Chad11