c 微信扫码支付,完整版(包括回调)

huikawlkj 2018-11-02

1、我们需要用到的类,下载一个微信sdk。sdk中有相关的工具类链接地址为:

https://pay.weixin.qq.com/wiki/doc/api/download/WxPayAPI_CS_v3.zip

2、如果觉得不想下载没有关系,我贴代码

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Net;

using System.Net.Security;

using System.Security.Cryptography.X509Certificates;

using System.Text;

using System.Web;

namespace WxPayTest.WxHelper

{

public class HttpService

{

public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)

{

//直接确认,否则打不开

return true;

}

public static string Post(string xml, string url, bool isUseCert, int timeout)

{

System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接

string result = "";//返回结果

HttpWebRequest request = null;

HttpWebResponse response = null;

Stream reqStream = null;

try

{

//设置最大连接数

ServicePointManager.DefaultConnectionLimit = 200;

//设置https验证方式

if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))

{

ServicePointManager.ServerCertificateValidationCallback =

new RemoteCertificateValidationCallback(CheckValidationResult);

}

/***************************************************************

* 下面设置HttpWebRequest的相关属性

* ************************************************************/

request = (HttpWebRequest)WebRequest.Create(url);

request.Method = "POST";

request.Timeout = timeout * 1000;

//设置代理服务器

WebProxy proxy = new WebProxy(); //定义一个网关对象

proxy.Address = new Uri(WxPayConfig.PROXY_URL); //网关服务器端口:端口

request.Proxy = proxy;

//设置POST的数据类型和长度

request.ContentType = "text/xml";

byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);

request.ContentLength = data.Length;

//是否使用证书

if (isUseCert)

{

string path = HttpContext.Current.Request.PhysicalApplicationPath;

X509Certificate2 cert = new X509Certificate2(path + WxPayConfig.SSLCERT_PATH, WxPayConfig.SSLCERT_PASSWORD);

request.ClientCertificates.Add(cert);

}

//往服务器写入数据

reqStream = request.GetRequestStream();

reqStream.Write(data, 0, data.Length);

reqStream.Close();

//获取服务端返回

response = (HttpWebResponse)request.GetResponse();

//获取服务端返回数据

StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);

result = sr.ReadToEnd().Trim();

sr.Close();

}

catch (System.Threading.ThreadAbortException e)

{

System.Threading.Thread.ResetAbort();

}

catch (WebException e)

{

if (e.Status == WebExceptionStatus.ProtocolError)

{

}

throw new WxPayException(e.ToString());

}

catch (Exception e)

{

throw new WxPayException(e.ToString());

}

finally

{

//关闭连接和流

if (response != null)

{

response.Close();

}

if (request != null)

{

request.Abort();

}

}

return result;

}

/// <summary>

/// 请求Url,发送数据

/// </summary>

public static string PostUrl(string url, string postData)

{

byte[] data = Encoding.UTF8.GetBytes(postData);

// 设置参数

HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;

CookieContainer cookieContainer = new CookieContainer();

request.CookieContainer = cookieContainer;

request.AllowAutoRedirect = true;

request.Method = "POST";

request.ContentType = "application/x-www-form-urlencoded";

request.ContentLength = data.Length;

Stream outstream = request.GetRequestStream();

outstream.Write(data, 0, data.Length);

outstream.Close();

//发送请求并获取相应回应数据

HttpWebResponse response = request.GetResponse() as HttpWebResponse;

//直到request.GetResponse()程序才开始向目标网页发送Post请求

Stream instream = response.GetResponseStream();

StreamReader sr = new StreamReader(instream, Encoding.UTF8);

//返回结果网页(html)代码

string content = sr.ReadToEnd();

return content;

}

/// <summary>

/// 处理http GET请求,返回数据

/// </summary>

/// <param name="url">请求的url地址</param>

/// <returns>http GET成功后返回的数据,失败抛WebException异常</returns>

public static string Get(string url)

{

System.GC.Collect();

string result = "";

HttpWebRequest request = null;

HttpWebResponse response = null;

//请求url以获取数据

try

{

//设置最大连接数

ServicePointManager.DefaultConnectionLimit = 200;

//设置https验证方式

if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))

{

ServicePointManager.ServerCertificateValidationCallback =

new RemoteCertificateValidationCallback(CheckValidationResult);

}

/***************************************************************

* 下面设置HttpWebRequest的相关属性

* ************************************************************/

request = (HttpWebRequest)WebRequest.Create(url);

request.Method = "GET";

//设置代理

WebProxy proxy = new WebProxy();

proxy.Address = new Uri(WxPayConfig.PROXY_URL);

request.Proxy = proxy;

//获取服务器返回

response = (HttpWebResponse)request.GetResponse();

//获取HTTP返回数据

StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);

result = sr.ReadToEnd().Trim();

sr.Close();

}

catch (System.Threading.ThreadAbortException e)

{

System.Threading.Thread.ResetAbort();

}

catch (WebException e)

{

if (e.Status == WebExceptionStatus.ProtocolError)

{

}

throw new WxPayException(e.ToString());

}

catch (Exception e)

{

throw new WxPayException(e.ToString());

}

finally

{

//关闭连接和流

if (response != null)

{

response.Close();

}

if (request != null)

{

request.Abort();

}

}

return result;

}

}

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace WxPayTest.WxHelper

{

public class NativePay

{

/**

* 生成直接支付url,支付url有效期为2小时,模式二

* @param productId 商品ID

* @return 模式二URL

*/

public string GetPayUrl(string productId)

{

WxPayData data = new WxPayData();

data.SetValue("body", "test");//商品描述

data.SetValue("attach", "test");//附加数据

data.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo());//随机字符串

data.SetValue("total_fee", 1);//总金额

data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始时间

data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));//交易结束时间

data.SetValue("goods_tag", "jjj");//商品标记

data.SetValue("trade_type", "NATIVE");//交易类型

data.SetValue("product_id", productId);//商品ID

WxPayData result = WxPayApi.UnifiedOrder(data);//调用统一下单接口

string url = result.GetValue("code_url").ToString();//获得统一下单接口返回的二维码链接

return url;

}

/**

* 参数数组转换为url格式

* @param map 参数名与参数值的映射表

* @return URL字符串

*/

private string ToUrlParams(SortedDictionary<string, object> map)

{

string buff = "";

foreach (KeyValuePair<string, object> pair in map)

{

buff += pair.Key + "=" + pair.Value + "&";

}

buff = buff.Trim('&');

return buff;

}

}

}

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Net;

using System.Text;

using System.Web;

namespace WxPayTest.WxHelper

{

public class WeiXinHelper

{

/**

* 生成直接支付url,支付url有效期为2小时,模式二

* @param productId 商品ID

* @return 模式二URL

*/

public string GetPayUrl(string productId)

{

WxPayData data = new WxPayData();

data.SetValue("body", "test");//商品描述

data.SetValue("attach", "test");//附加数据

data.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo());//随机字符串

data.SetValue("total_fee", 1);//总金额

data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始时间

data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));//交易结束时间

data.SetValue("goods_tag", "jjj");//商品标记

data.SetValue("trade_type", "NATIVE");//交易类型

data.SetValue("product_id", productId);//商品ID

WxPayData result = WxPayApi.UnifiedOrder(data);//调用统一下单接口

string url = result.GetValue("code_url").ToString();//获得统一下单接口返回的二维码链接

return url;

}

/**

* 参数数组转换为url格式

* @param map 参数名与参数值的映射表

* @return URL字符串

*/

private string ToUrlParams(SortedDictionary<string, object> map)

{

string buff = "";

foreach (KeyValuePair<string, object> pair in map)

{

buff += pair.Key + "=" + pair.Value + "&";

}

buff = buff.Trim('&');

return buff;

}

}

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace WxPayTest.WxHelper

{

public class WxPayApi

{

/**

*

* 统一下单

* @param WxPaydata inputObj 提交给统一下单API的参数

* @param int timeOut 超时时间

* @throws WxPayException

* @return 成功时返回,其他抛异常

*/

public static WxPayData UnifiedOrder(WxPayData inputObj, int timeOut = 600)

{

string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

//检测必填参数

if (!inputObj.IsSet("out_trade_no"))

{

throw new WxPayException("缺少统一支付接口必填参数out_trade_no!");

}

else if (!inputObj.IsSet("body"))

{

throw new WxPayException("缺少统一支付接口必填参数body!");

}

else if (!inputObj.IsSet("total_fee"))

{

throw new WxPayException("缺少统一支付接口必填参数total_fee!");

}

else if (!inputObj.IsSet("trade_type"))

{

throw new WxPayException("缺少统一支付接口必填参数trade_type!");

}

//关联参数

if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid"))

{

throw new WxPayException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");

}

if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id"))

{

throw new WxPayException("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");

}

//异步通知url未设置,则使用配置文件中的url

if (!inputObj.IsSet("notify_url"))

{

inputObj.SetValue("notify_url", WxPayConfig.NOTIFY_URL);//异步通知url

}

inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID

inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号

inputObj.SetValue("spbill_create_ip", WxPayConfig.IP);//终端ip

inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串

//签名

inputObj.SetValue("sign", inputObj.MakeSign());

string xml = inputObj.ToXml();

var start = DateTime.Now;

//string response = HttpService.Post(xml, url, false, timeOut);

string response = HttpService.PostUrl(url, xml);

var end = DateTime.Now;

int timeCost = (int)((end - start).TotalMilliseconds);

WxPayData result = new WxPayData();

result.FromXml(response);

ReportCostTime(url, timeCost, result);//测速上报

return result;

}

/**

*

* 测速上报

* @param string interface_url 接口URL

* @param int timeCost 接口耗时

* @param WxPayData inputObj参数数组

*/

private static void ReportCostTime(string interface_url, int timeCost, WxPayData inputObj)

{

//如果不需要进行上报

if (WxPayConfig.REPORT_LEVENL == 0)

{

return;

}

//如果仅失败上报

if (WxPayConfig.REPORT_LEVENL == 1 && inputObj.IsSet("return_code") && inputObj.GetValue("return_code").ToString() == "SUCCESS" &&

inputObj.IsSet("result_code") && inputObj.GetValue("result_code").ToString() == "SUCCESS")

{

return;

}

//上报逻辑

WxPayData data = new WxPayData();

data.SetValue("interface_url", interface_url);

data.SetValue("execute_time_", timeCost);

//返回状态码

if (inputObj.IsSet("return_code"))

{

data.SetValue("return_code", inputObj.GetValue("return_code"));

}

//返回信息

if (inputObj.IsSet("return_msg"))

{

data.SetValue("return_msg", inputObj.GetValue("return_msg"));

}

//业务结果

if (inputObj.IsSet("result_code"))

{

data.SetValue("result_code", inputObj.GetValue("result_code"));

}

//错误代码

if (inputObj.IsSet("err_code"))

{

data.SetValue("err_code", inputObj.GetValue("err_code"));

}

//错误代码描述

if (inputObj.IsSet("err_code_des"))

{

data.SetValue("err_code_des", inputObj.GetValue("err_code_des"));

}

//商户订单号

if (inputObj.IsSet("out_trade_no"))

{

data.SetValue("out_trade_no", inputObj.GetValue("out_trade_no"));

}

//设备号

if (inputObj.IsSet("device_info"))

{

data.SetValue("device_info", inputObj.GetValue("device_info"));

}

try

{

Report(data);

}

catch (WxPayException ex)

{

//不做任何处理

}

}

/**

*

* 测速上报接口实现

* @param WxPayData inputObj 提交给测速上报接口的参数

* @param int timeOut 测速上报接口超时时间

* @throws WxPayException

* @return 成功时返回测速上报接口返回的结果,其他抛异常

*/

public static WxPayData Report(WxPayData inputObj, int timeOut = 1)

{

string url = "https://api.mch.weixin.qq.com/payitil/report";

//检测必填参数

if (!inputObj.IsSet("interface_url"))

{

throw new WxPayException("接口URL,缺少必填参数interface_url!");

}

if (!inputObj.IsSet("return_code"))

{

throw new WxPayException("返回状态码,缺少必填参数return_code!");

}

if (!inputObj.IsSet("result_code"))

{

throw new WxPayException("业务结果,缺少必填参数result_code!");

}

if (!inputObj.IsSet("user_ip"))

{

throw new WxPayException("访问接口IP,缺少必填参数user_ip!");

}

if (!inputObj.IsSet("execute_time_"))

{

throw new WxPayException("接口耗时,缺少必填参数execute_time_!");

}

inputObj.SetValue("appid", WxPayConfig.APPID);//公众账号ID

inputObj.SetValue("mch_id", WxPayConfig.MCHID);//商户号

inputObj.SetValue("user_ip", WxPayConfig.IP);//终端ip

inputObj.SetValue("time", DateTime.Now.ToString("yyyyMMddHHmmss"));//商户上报时间

inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串

inputObj.SetValue("sign", inputObj.MakeSign());//签名

string xml = inputObj.ToXml();

string response = HttpService.Post(xml, url, false, timeOut);

WxPayData result = new WxPayData();

result.FromXml(response);

return result;

}

/**

* 根据当前系统时间加随机序列来生成订单号

* @return 订单号

*/

public static string GenerateOutTradeNo()

{

var ran = new Random();

return string.Format("{0}{1}{2}", WxPayConfig.MCHID, DateTime.Now.ToString("yyyyMMddHHmmss"), ran.Next(999));

}

/**

* 生成时间戳,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数

* @return 时间戳

*/

public static string GenerateTimeStamp()

{

TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);

return Convert.ToInt64(ts.TotalSeconds).ToString();

}

/**<pre name="code" class="csharp">using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace WxPayTest.WxHelper

{

/**

* 配置账号信息

*/

public class WxPayConfig

{

//=======【基本信息设置】=====================================

/* 微信公众号信息配置

* APPID:绑定支付的APPID(必须配置)

* MCHID:商户号(必须配置)

* KEY:商户支付密钥,参考开户邮件设置(必须配置)

* APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置)

*/

public const string APPID = "11111111111111"; //需要自己提供我就不提供

public const string MCHID = "11111111111111";//需要自己提供我就不提供

public const string KEY = "11111111111111";//需要自己提供我就不提供

public const string APPSECRET = "11111111111111";//需要自己提供我就不提供

//=======【证书路径设置】=====================================

/* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要)

*/

public const string SSLCERT_PATH = "cert/apiclient_cert.p12";

public const string SSLCERT_PASSWORD = "1233410002";

//=======【支付结果通知url】=====================================

/* 支付结果通知回调url,用于商户接收支付结果

*/

public const string NOTIFY_URL = "http://paysdk.weixin.qq.com/example/ResultNotifyPage.aspx"; //需要写自己的回调地址,方便处理

//=======【商户系统后台机器IP】=====================================

/* 此参数可手动配置也可在程序中自动获取

*/

public const string IP = "8.8.8.8";

//=======【代理服务器设置】===================================

/* 默认IP和端口号分别为0.0.0.0和0,此时不开启代理(如有需要才设置)

*/

public const string PROXY_URL = "http://10.152.18.220:8080";

//=======【上报信息配置】===================================

/* 测速上报等级,0.关闭上报; 1.仅错误时上报; 2.全量上报

*/

public const int REPORT_LEVENL = 1;

//=======【日志级别】===================================

/* 日志等级,0.不输出日志;1.只输出错误信息; 2.输出错误和正常信息; 3.输出错误信息、正常信息和调试信息

*/

public const int LOG_LEVENL = 0;

}

}

using Newtonsoft.Json;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Security.Cryptography;

using System.Text;

using System.Web;

using System.Xml;

namespace WxPayTest.WxHelper

{

/// <summary>

/// 微信支付协议接口数据类,所有的API接口通信都依赖这个数据结构,

/// 在调用接口之前先填充各个字段的值,然后进行接口通信,

/// 这样设计的好处是可扩展性强,用户可随意对协议进行更改而不用重新设计数据结构,

/// 还可以随意组合出不同的协议数据包,不用为每个协议设计一个数据包结构

/// </summary>

public class WxPayData

{

public WxPayData()

{

}

//采用排序的Dictionary的好处是方便对数据包进行签名,不用再签名之前再做一次排序

private SortedDictionary<string, object> m_values = new SortedDictionary<string, object>();

/**

* 设置某个字段的值

* @param key 字段名

* @param value 字段值

*/

public void SetValue(string key, object value)

{

m_values[key] = value;

}

/**

* 根据字段名获取某个字段的值

* @param key 字段名

* @return key对应的字段值

*/

public object GetValue(string key)

{

object o = null;

m_values.TryGetValue(key, out o);

return o;

}

/**

* 判断某个字段是否已设置

* @param key 字段名

* @return 若字段key已被设置,则返回true,否则返回false

*/

public bool IsSet(string key)

{

object o = null;

m_values.TryGetValue(key, out o);

if (null != o)

return true;

else

return false;

}

/**

* @将Dictionary转成xml

* @return 经转换得到的xml串

* @throws WxPayException

**/

public string ToXml()

{

//数据为空时不能转化为xml格式

if (0 == m_values.Count)

{

throw new WxPayException("WxPayData数据为空!");

}

string xml = "<xml>";

foreach (KeyValuePair<string, object> pair in m_values)

{

//字段值不能为null,会影响后续流程

if (pair.Value == null)

{

throw new WxPayException("WxPayData内部含有值为null的字段!");

}

if (pair.Value.GetType() == typeof(int))

{

xml += "<" + pair.Key + ">" + pair.Value + "</" + pair.Key + ">";

}

else if (pair.Value.GetType() == typeof(string))

{

xml += "<" + pair.Key + ">" + "<![CDATA[" + pair.Value + "]]></" + pair.Key + ">";

}

else//除了string和int类型不能含有其他数据类型

{

throw new WxPayException("WxPayData字段数据类型错误!");

}

}

xml += "</xml>";

return xml;

}

/**

* @将xml转为WxPayData对象并返回对象内部的数据

* @param string 待转换的xml串

* @return 经转换得到的Dictionary

* @throws WxPayException

*/

public SortedDictionary<string, object> FromXml(string xml)

{

if (string.IsNullOrEmpty(xml))

{

throw new WxPayException("将空的xml串转换为WxPayData不合法!");

}

XmlDocument xmlDoc = new XmlDocument();

xmlDoc.LoadXml(xml);

XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点<xml>

XmlNodeList nodes = xmlNode.ChildNodes;

foreach (XmlNode xn in nodes)

{

XmlElement xe = (XmlElement)xn;

m_values[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中

}

try

{

//2015-06-29 错误是没有签名

if (m_values["return_code"] != "SUCCESS")

{

return m_values;

}

CheckSign();//验证签名,不通过会抛异常

}

catch (WxPayException ex)

{

throw new WxPayException(ex.Message);

}

return m_values;

}

/**

* @Dictionary格式转化成url参数格式

* @ return url格式串, 该串不包含sign字段值

*/

public string ToUrl()

{

string buff = "";

foreach (KeyValuePair<string, object> pair in m_values)

{

if (pair.Value == null)

{

throw new WxPayException("WxPayData内部含有值为null的字段!");

}

if (pair.Key != "sign" && pair.Value.ToString() != "")

{

buff += pair.Key + "=" + pair.Value + "&";

}

}

buff = buff.Trim('&');

return buff;

}

/**

* @Dictionary格式化成Json

* @return json串数据

*/

public string ToJson()

{

string jsonStr =JsonConvert.SerializeObject(m_values);

return jsonStr;

}

/**

* @values格式化成能在Web页面上显示的结果(因为web页面上不能直接输出xml格式的字符串)

*/

public string ToPrintStr()

{

string str = "";

foreach (KeyValuePair<string, object> pair in m_values)

{

if (pair.Value == null)

{

throw new WxPayException("WxPayData内部含有值为null的字段!");

}

str += string.Format("{0}={1}<br>", pair.Key, pair.Value.ToString());

}

return str;

}

/**

* @生成签名,详见签名生成算法

* @return 签名, sign字段不参加签名

*/

public string MakeSign()

{

//转url格式

string str = ToUrl();

//在string后加入API KEY

str += "&key=" + WxPayConfig.KEY;

//MD5加密

var md5 = MD5.Create();

var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str));

var sb = new StringBuilder();

foreach (byte b in bs)

{

sb.Append(b.ToString("x2"));

}

//所有字符转为大写

return sb.ToString().ToUpper();

}

/**

*

* 检测签名是否正确

* 正确返回true,错误抛异常

*/

public bool CheckSign()

{

//如果没有设置签名,则跳过检测

if (!IsSet("sign"))

{

//"WxPayData签名存在但不合法!"

return false;

}

//如果设置了签名但是签名为空,则抛异常

else if (GetValue("sign") == null || GetValue("sign").ToString() == "")

{

//"WxPayData签名存在但不合法!"

return false;

}

//获取接收到的签名

string return_sign = GetValue("sign").ToString();

//在本地计算新的签名

string cal_sign = MakeSign();

if (cal_sign == return_sign)

{

return true;

}

else

{

return false;

}

}

/**

* @获取Dictionary

*/

public SortedDictionary<string, object> GetValues()

{

return m_values;

}

}

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

namespace WxPayTest.WxHelper

{

public class WxPayException : Exception

{

public WxPayException(string msg)

: base(msg)

{

}

}

}

* 生成随机串,随机串包含字母或数字 * @return 随机串 */ public static string GenerateNonceStr() { return Guid.NewGuid().ToString().Replace("-", ""); } }}

3、所有的工具类完成了,下面就开始调用

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using WxPayTest.WxHelper;

namespace WxPayTest.Controllers

{

public class TestController : Controller

{

//

// GET: /Test/

public ActionResult Index()

{

NativePay nativePay = new NativePay();

//生成扫码支付url

string url2 = nativePay.GetPayUrl("123456789");

ViewBag.url = url2;

return View();

}

}

}

4、页面操作,因为之前的调用微信给我们有用的东西就是一个二维码链接,我们还得把这个连接转换为二维码。

jquery.qrcode.min.js 可以百度下载,我这里提供一个连接:http://download.csdn.net/detail/zuozhiyoulaisam/8117785

@{

ViewBag.Title = "Index";

}

<script src="~/Scripts/jquery-1.10.2.min.js"></script>

<script src="~/Scripts/jquery.qrcode.min.js"></script>

<h2>Index</h2>

<div id="code"></div>

<script>

var urlText = '@ViewBag.url';

jQuery('#code').qrcode("" + urlText + "");

</script>

5、ok你可以完整的使用微信扫码支付了,回调操作后续在写(回调链接地址)。

c 微信扫码支付,完整版(包括回调)

相关推荐