千家信息网

ASP.NET如何实现微信JS-SDK支付

发表于:2025-01-16 作者:千家信息网编辑
千家信息网最后更新 2025年01月16日,小编给大家分享一下ASP.NET如何实现微信JS-SDK支付,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!具体内容如下模型
千家信息网最后更新 2025年01月16日ASP.NET如何实现微信JS-SDK支付

小编给大家分享一下ASP.NET如何实现微信JS-SDK支付,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

具体内容如下

模型层实体类:

 public class JsEntities { ///  /// 公众号id ///  public string appId { get; set; } ///  /// 时间戳 ///  public string timeStamp { get; set; } ///  /// 随机字符串 ///  public string nonceStr { get; set; } ///  /// 订单详情扩展字符串 ///  public string package { get; set; } ///  /// 签名类型 ///  public string signType { get; set; } ///  /// 签名 ///  public string paySign { get; set; } }
 public class UnifyEntities { ///  /// 公众账号ID ///  public string appid { get; set; } ///  /// 微信支付分配的商户号 ///  public string mch_id { get; set; } ///  /// 微信支付分配的终端设备号 ///  public string device_info { get; set; } ///  /// 随机字符串,不长于32位 ///  public string nonce_str { get; set; } ///  /// 签名 ///  public string sign { get; set; } ///  /// 商品描述最大长度127 ///  public string body { get; set; } ///  /// 附加数据,原样返回 ///  public string attach { get; set; } ///  /// 商户系统内部的订单号,32 个字符内、可包含字母,确保在商户系统唯一,详细说明 ///  public string out_trade_no { get; set; } ///  /// 订单总金额,单位为分,不能带小数点 ///  public string total_fee { get; set; } ///  /// 终端IP ///  public string spbill_create_ip { get; set; } ///  /// 交易起始时间 ///  public string time_start { get; set; } ///  /// 交易结束时间 ///  public string time_expire { get; set; } ///  /// 接收微信支付成功通知 ///  public string notify_url { get; set; } ///  /// JSAPI、NATIVE、APP ///  public string trade_type { get; set; } ///  /// 用户在商户appid下的唯一标识,trade_type为JSAPI 时,此参数必传 ///  public string openid { get; set; } ///  /// 只在 trade_type 为 NATIVE 时需要填写。此id为二维码中包含的商品ID,商户自行维护。 ///  public string product_id { get; set; } }
 public class UnifyReceive { ///  /// SUCCESS/FAIL此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断 ///  public string return_code { get; set; } ///  /// 返回信息,如非空,为错误原因 ///  public string return_msg { get; set; } ///  /// 微信分配的公众账号ID ///  public string appid { get; set; } ///  /// 微信支付分配的商户号 ///  public string mch_id { get; set; } ///  /// 随机字符串,不长于32位 ///  public string nonce_str { get; set; } ///  /// 签名 ///  public string sign { get; set; } ///  /// 业务结果 ///  public string result_code { get; set; } ///  /// 预支付ID ///  public string prepay_id { get; set; } ///  /// 交易类型 ///  public string trade_type { get; set; } ///  /// 二维码链接 ///  public string code_url { get; set; } public UnifyReceive(string xml) {  XElement doc = XElement.Parse(xml);  return_code = doc.Element("return_code").Value;  return_msg = doc.Element("return_msg").Value;  if (return_code == "SUCCESS")  {  appid = doc.Element("appid").Value;  mch_id = doc.Element("mch_id").Value;  nonce_str = doc.Element("nonce_str").Value;  sign = doc.Element("sign").Value;  result_code = doc.Element("result_code").Value;  if (result_code == "SUCCESS")  {   trade_type = doc.Element("trade_type").Value;   prepay_id = doc.Element("prepay_id").Value;   if (trade_type == "NATIVE")   {   code_url = doc.Element("code_url").Value;   }   trade_type = doc.Element("trade_type").Value;  }  } } }

TestJs.aspx内容:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="JsPay.aspx.cs" Inherits="WeChatPayDemo.JsPay" %>      
商品描述: 商品价格: 订单号:

JsPay.aspx.cs代码:

 public partial class JsPay : System.Web.UI.Page { public string openid = ""; protected void Page_Load(object sender, EventArgs e) {  string code = Request["code"];  if (string.IsNullOrEmpty(code))  {  //如果code没获取成功,重新拉取一遍  GetAuthUrl("wxxxxxxxxxxxxxxxxxxxxxxx", "http://www.china101.net/JsPay.aspx");  }  openid = GetOpenID("wxxxxxxxxxxxxxxxxxxxxxxx", "dsdssdsdsdsdsdsdsdsdsd", JKRequest.GetQueryString("code"), () => { }); } public string GetOpenID(string appid, string secret, string code, Action CallBack) {  try  {  string retdata = Utils.HttpGet(string.Format("https://api.weixin.qq.com/sns/oauth3/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", appid, secret, code));  .LogHelper.WriteFile(retdata);  JObject jobj = (JObject)JsonConvert.DeserializeObject(retdata);  string openid = jobj.Value("openid");  return openid;  }  catch (Exception)  {  CallBack();  return "";  }  // return GetUserInfo(access_token, openid); } ///  /// 获取鉴权地址 ///  ///  ///  ///  public void GetAuthUrl(string appid, string redirect_url) {  Response.Redirect(string.Format("https://open.weixin.qq.com/connect/oauth3/authorize?appid={0}&redirect_uri={1}&response_type=code&scope=snsapi_base&state=123#wechat_redirect", appid, Utils.UrlEncode(redirect_url))); } }

WxPay.ashx代码:

///  /// WxPay 的摘要说明 ///  public class WxPay : IHttpHandler { ///  /// 公众账号ID ///  private string appid = "wxxxxxxxxxxxxxxxx"; ///  /// 商户号 ///  private string mch_id = "12333333333"; ///  /// 通知url ///  private string notify_url = "http://www.china101.net/Notify2.aspx"; ///  /// 密钥 ///  private string key = "chinapagexxxxxxxxxxxxx"; public void ProcessRequest(HttpContext context) {  string action = JKRequest.GetQueryString("action");  switch (action)  {  case "unifysign":   GetUnifySign(context); break;  case "jspayparam": GetJsPayParam(context); break;  case "nativedynamic": GetPayQr(context); break;  } } #region 获取js支付参数 void GetJsPayParam(HttpContext context) {  JsEntities jsEntities = new JsEntities()  {  appId = appid,  nonceStr = .Utils.GetRandom(),  package = string.Format("prepay_id={0}", GetPrepayId(context)),  signType = "MD5",  timeStamp = .Utils.ConvertDateTimeInt(DateTime.Now).ToString()  };  string url, sign;  string xmlStr = .Utils.GetUnifyRequestXml(jsEntities, key, out url, out sign);  LogHelper.WriteFile(xmlStr);  jsEntities.paySign = sign;  context.Response.Write(JsonConvert.SerializeObject(jsEntities)); } #endregion #region 获取预支付ID //-------------------------------------------------------------------------- string GetPrepayId(HttpContext context) {  string xml;  GetUnifySign(context, out xml);  LogHelper.WriteFile("GetPrepayId---71--" + xml);  UnifyReceive unifyReceive = new UnifyReceive(.Utils.HttpPost("https://api.mch.weixin.qq.com/pay/unifiedorder", xml));  LogHelper.WriteFile("unifyReceive---73--" + unifyReceive.prepay_id);  return unifyReceive.prepay_id; } #endregion #region 获取统一签名 void GetUnifySign(HttpContext context) {  string xml;  context.Response.Write(GetUnifySign(context, out xml)); } #endregion #region 获取统一签名 string GetUnifySign(HttpContext context, out string xml) {  string url, sign;  xml = WxPayHelper.Utils.GetUnifyUrlXml(GetUnifyEntities(context), key, out url, out sign);  return sign; } #endregion #region 获取二维码 void GetPayQr(HttpContext context) {  string url = GetPayUrl(context);  WxPayHelper.Utils.GetQrCode(url); } #endregion #region 获取二维码链接 string GetPayUrl(HttpContext context) {  string xml;  GetUnifySign(context, out xml);  WxPayHelper.Utils.WriteTxt(xml);  UnifyReceive unifyReceive = new UnifyReceive(WxPayHelper.Utils.HttpPost("https://api.mch.weixin.qq.com/pay/unifiedorder", xml));  return unifyReceive.code_url; } #endregion #region 获取统一支付接口参数对象 UnifyEntities GetUnifyEntities(HttpContext context) {  string msgid = JKRequest.GetQueryString("msgid");  LogHelper.WriteFile("115---------"+msgid);  UnifyEntities unify = new UnifyEntities  {  appid = appid,  body = JKRequest.GetQueryString("body"),  mch_id = mch_id,  nonce_str = WxPayHelper.Utils.GetRandom(),  out_trade_no = JKRequest.GetQueryString("out_trade_no"),  notify_url = notify_url,  spbill_create_ip = JKRequest.GetIP(),  trade_type = JKRequest.GetQueryString("trade_type"),  total_fee = JKRequest.GetQueryString("total_fee")  };  if (unify.trade_type == "NATIVE")  {  unify.product_id = msgid;  }  else  {  unify.openid = msgid;  }  return unify; } #endregion public bool IsReusable {  get  {  return false;  } } }

Utils.cs代码:

 public class Utils { #region MD5加密 public static string MD5(string pwd) {  MD5 md5 = new MD5CryptoServiceProvider();  byte[] data = System.Text.Encoding.Default.GetBytes(pwd);  byte[] md5data = md5.ComputeHash(data);  md5.Clear();  string str = "";  for (int i = 0; i < md5data.Length; i++)  {  str += md5data[i].ToString("x").PadLeft(2, '0');  }  return str; } ///  /// 获取文件的md5 ///  /// 文件路径,url路径 /// md5字符串 string GetMD5HashFromFile(string filepath) {  try  {  WebClient wc = new WebClient();  var file = wc.OpenRead(new Uri(filepath));  System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();  byte[] retVal = md5.ComputeHash(file);  file.Close();  StringBuilder sb = new StringBuilder();  for (int i = 0; i < retVal.Length; i++)  {   sb.Append(retVal[i].ToString("x2"));  }  return sb.ToString();  }  catch (Exception ex)  {  throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);  } } #endregion #region 对象转换处理 ///  /// 判断对象是否为Int32类型的数字 ///  ///  ///  public static bool IsNumeric(object expression) {  if (expression != null)  return IsNumeric(expression.ToString());  return false; } ///  /// 判断对象是否为Int32类型的数字 ///  ///  ///  public static bool IsNumeric(string expression) {  if (expression != null)  {  string str = expression;  if (str.Length > 0 && str.Length <= 11 && Regex.IsMatch(str, @"^[-]?[0-9]*[.]?[0-9]*$"))  {   if ((str.Length < 10) || (str.Length == 10 && str[0] == '1') || (str.Length == 11 && str[0] == '-' && str[1] == '1'))   return true;  }  }  return false; } ///  /// 是否为Double类型 ///  ///  ///  public static bool IsDouble(object expression) {  if (expression != null)  return Regex.IsMatch(expression.ToString(), @"^([0-9])[0-9]*(\.\w*)?$");  return false; } ///  /// 检测是否符合email格式 ///  /// 要判断的email字符串 /// 判断结果 public static bool IsValidEmail(string strEmail) {  return Regex.IsMatch(strEmail, @"^[\w\.]+([-]\w+)*@[A-Za-z0-9-_]+[\.][A-Za-z0-9-_]"); } public static bool IsValidDoEmail(string strEmail) {  return Regex.IsMatch(strEmail, @"^@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"); } ///  /// 检测是否是正确的Url ///  /// 要验证的Url /// 判断结果 public static bool IsURL(string strUrl) {  return Regex.IsMatch(strUrl, @"^(http|https)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{1,10}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$"); } ///  /// 将字符串转换为数组 ///  /// 字符串 /// 字符串数组 public static string[] GetStrArray(string str) {  return str.Split(new char[',']); } ///  /// 将数组转换为字符串 ///  /// List /// 分隔符 /// String public static string GetArrayStr(List list, string speater) {  StringBuilder sb = new StringBuilder();  for (int i = 0; i < list.Count; i++)  {  if (i == list.Count - 1)  {   sb.Append(list[i]);  }  else  {   sb.Append(list[i]);   sb.Append(speater);  }  }  return sb.ToString(); } ///  /// object型转换为bool型 ///  /// 要转换的字符串 /// 缺省值 /// 转换后的bool类型结果 public static bool StrToBool(object expression, bool defValue) {  if (expression != null)  return StrToBool(expression, defValue);  return defValue; } ///  /// string型转换为bool型 ///  /// 要转换的字符串 /// 缺省值 /// 转换后的bool类型结果 public static bool StrToBool(string expression, bool defValue) {  if (expression != null)  {  if (string.Compare(expression, "true", true) == 0)   return true;  else if (string.Compare(expression, "false", true) == 0)   return false;  }  return defValue; } ///  /// 将对象转换为Int32类型 ///  /// 要转换的字符串 /// 缺省值 /// 转换后的int类型结果 public static int ObjToInt(object expression, int defValue) {  if (expression != null)  return StrToInt(expression.ToString(), defValue);  return defValue; } ///  /// 将字符串转换为Int32类型 ///  /// 要转换的字符串 /// 缺省值 /// 转换后的int类型结果 public static int StrToInt(string expression, int defValue) {  if (string.IsNullOrEmpty(expression) || expression.Trim().Length >= 11 || !Regex.IsMatch(expression.Trim(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))  return defValue;  int rv;  if (Int32.TryParse(expression, out rv))  return rv;  return Convert.ToInt32(StrToFloat(expression, defValue)); } ///  /// Object型转换为decimal型 ///  /// 要转换的字符串 /// 缺省值 /// 转换后的decimal类型结果 public static decimal ObjToDecimal(object expression, decimal defValue) {  if (expression != null)  return StrToDecimal(expression.ToString(), defValue);  return defValue; } ///  /// string型转换为decimal型 ///  /// 要转换的字符串 /// 缺省值 /// 转换后的decimal类型结果 public static decimal StrToDecimal(string expression, decimal defValue) {  if ((expression == null) || (expression.Length > 10))  return defValue;  decimal intValue = defValue;  if (expression != null)  {  bool IsDecimal = Regex.IsMatch(expression, @"^([-]|[0-9])[0-9]*(\.\w*)?$");  if (IsDecimal)   decimal.TryParse(expression, out intValue);  }  return intValue; } ///  /// Object型转换为float型 ///  /// 要转换的字符串 /// 缺省值 /// 转换后的int类型结果 public static float ObjToFloat(object expression, float defValue) {  if (expression != null)  return StrToFloat(expression.ToString(), defValue);  return defValue; } ///  /// string型转换为float型 ///  /// 要转换的字符串 /// 缺省值 /// 转换后的int类型结果 public static float StrToFloat(string expression, float defValue) {  if ((expression == null) || (expression.Length > 10))  return defValue;  float intValue = defValue;  if (expression != null)  {  bool IsFloat = Regex.IsMatch(expression, @"^([-]|[0-9])[0-9]*(\.\w*)?$");  if (IsFloat)   float.TryParse(expression, out intValue);  }  return intValue; } ///  /// 将对象转换为日期时间类型 ///  /// 要转换的字符串 /// 缺省值 /// 转换后的int类型结果 public static DateTime StrToDateTime(string str, DateTime defValue) {  if (!string.IsNullOrEmpty(str))  {  DateTime dateTime;  if (DateTime.TryParse(str, out dateTime))   return dateTime;  }  return defValue; } ///  /// 将对象转换为日期时间类型 ///  /// 要转换的字符串 /// 转换后的int类型结果 public static DateTime StrToDateTime(string str) {  return StrToDateTime(str, DateTime.Now); } ///  /// 将对象转换为日期时间类型 ///  /// 要转换的对象 /// 转换后的int类型结果 public static DateTime ObjectToDateTime(object obj) {  return StrToDateTime(obj.ToString()); } ///  /// 将对象转换为日期时间类型 ///  /// 要转换的对象 /// 缺省值 /// 转换后的int类型结果 public static DateTime ObjectToDateTime(object obj, DateTime defValue) {  return StrToDateTime(obj.ToString(), defValue); } ///  /// 将对象转换为字符串 ///  /// 要转换的对象 /// 转换后的string类型结果 public static string ObjectToStr(object obj) {  if (obj == null)  return "";  return obj.ToString().Trim(); } ///  /// 判断是否邮箱 ///  ///  ///  public static bool IsEmail(string expression) {  return Regex.IsMatch(expression, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"); } ///  /// 判断是否手机 ///  ///  ///  public static bool IsMobile(string expression) {  return Regex.IsMatch(expression, @"^1[3|4|5|6|7|8|9][0-9]{9}$"); } public static bool IsPhone(string telphone) {  Regex regex = new Regex(@"^(\d{3,4}-)?\d{6,8}$");  return regex.IsMatch(telphone); } #endregion #region 分割字符串 ///  /// 分割字符串 ///  public static string[] SplitString(string strContent, string strSplit) {  if (!string.IsNullOrEmpty(strContent))  {  if (strContent.IndexOf(strSplit) < 0)   return new string[] { strContent };  return Regex.Split(strContent, Regex.Escape(strSplit), RegexOptions.IgnoreCase);  }  else  return new string[0] { }; } ///  /// 分割字符串 ///  ///  public static string[] SplitString(string strContent, string strSplit, int count) {  string[] result = new string[count];  string[] splited = SplitString(strContent, strSplit);  for (int i = 0; i < count; i++)  {  if (i < splited.Length)   result[i] = splited[i];  else   result[i] = string.Empty;  }  return result; } #endregion #region 删除最后结尾的一个逗号 ///  /// 删除最后结尾的一个逗号 ///  public static string DelLastComma(string str) {  if (str.Length < 1)  {  return "";  }  return str.Substring(0, str.LastIndexOf(",")); } #endregion #region 删除最后结尾的指定字符后的字符 ///  /// 删除最后结尾的指定字符后的字符 ///  public static string DelLastChar(string str, string strchar) {  if (string.IsNullOrEmpty(str))  return "";  if (str.LastIndexOf(strchar) >= 0 && str.LastIndexOf(strchar) == str.Length - 1)  {  return str.Substring(0, str.LastIndexOf(strchar));  }  return str; } #endregion #region 生成指定长度的字符串 ///  /// 生成指定长度的字符串,即生成strLong个str字符串 ///  /// 生成的长度 /// 以str生成字符串 ///  public static string StringOfChar(int strLong, string str) {  string ReturnStr = "";  for (int i = 0; i < strLong; i++)  {  ReturnStr += str;  }  return ReturnStr; } #endregion #region 生成日期随机码 ///  /// 生成日期随机码 ///  ///  public static string GetRamCode() {  #region  return DateTime.Now.ToString("yyyyMMddHHmmssffff");  #endregion } #endregion #region 生成随机字母或数字 ///  /// 生成随机数字 ///  /// 生成长度 ///  public static string Number(int Length) {  return Number(Length, false); } ///  /// 生成随机数字 ///  /// 生成长度 /// 是否要在生成前将当前线程阻止以避免重复 ///  public static string Number(int Length, bool Sleep) {  if (Sleep)  System.Threading.Thread.Sleep(3);  string result = "";  System.Random random = new Random();  for (int i = 0; i < Length; i++)  {  result += random.Next(10).ToString();  }  return result; } ///  /// 生成随机字母字符串(数字字母混和) ///  /// 待生成的位数 public static string GetCheckCode(int codeCount) {  string str = string.Empty;  int rep = 0;  long num2 = DateTime.Now.Ticks + rep;  rep++;  Random random = new Random(((int)(((ulong)num2) & 0xffffffffL)) | ((int)(num2 >> rep)));  for (int i = 0; i < codeCount; i++)  {  char ch;  int num = random.Next();  if ((num % 2) == 0)  {   ch = (char)(0x30 + ((ushort)(num % 10)));  }  else  {   ch = (char)(0x41 + ((ushort)(num % 0x1a)));  }  str = str + ch.ToString();  }  return str; } ///  /// 根据日期和随机码生成订单号 ///  ///  public static string GetOrderNumber() {  string num = DateTime.Now.ToString("yyMMddHHmmss");//yyyyMMddHHmmssms  return num + Number(2).ToString(); } private static int Next(int numSeeds, int length) {  byte[] buffer = new byte[length];  System.Security.Cryptography.RNGCryptoServiceProvider Gen = new System.Security.Cryptography.RNGCryptoServiceProvider();  Gen.GetBytes(buffer);  uint randomResult = 0x0;//这里用uint作为生成的随机数   for (int i = 0; i < length; i++)  {  randomResult |= ((uint)buffer[i] << ((length - 1 - i) * 8));  }  return (int)(randomResult % numSeeds); } #endregion #region 截取字符长度 ///  /// 截取字符长度 ///  /// 字符 /// 长度 ///  public static string CutString(string inputString, int len) {  if (string.IsNullOrEmpty(inputString))  return "";  inputString = DropHTML(inputString);  ASCIIEncoding ascii = new ASCIIEncoding();  int tempLen = 0;  string tempString = "";  byte[] s = ascii.GetBytes(inputString);  for (int i = 0; i < s.Length; i++)  {  if ((int)s[i] == 63)  {   tempLen += 2;  }  else  {   tempLen += 1;  }  try  {   tempString += inputString.Substring(i, 1);  }  catch  {   break;  }  if (tempLen > len)   break;  }  //如果截过则加上半个省略号   byte[] mybyte = System.Text.Encoding.Default.GetBytes(inputString);  if (mybyte.Length > len)  tempString += "…";  return tempString; } #endregion #region 清除HTML标记 public static string DropHTML(string Htmlstring) {  if (string.IsNullOrEmpty(Htmlstring)) return "";  //删除脚本   Htmlstring = Regex.Replace(Htmlstring, @"]*?>.*?", "", RegexOptions.IgnoreCase);  //删除HTML   Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);  Htmlstring = Regex.Replace(Htmlstring, @"([\r\n])[\s]+", "", RegexOptions.IgnoreCase);  Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);  Htmlstring = Regex.Replace(Htmlstring, @"
      
    
0