欧美大屁股bbbbxxxx,狼人大香伊蕉国产www亚洲,男ji大巴进入女人的视频小说,男人把ji大巴放进女人免费视频,免费情侣作爱视频

歡迎來(lái)到入門(mén)教程網(wǎng)!

C#教程

當(dāng)前位置:主頁(yè) > 軟件編程 > C#教程 >

C# MVC 微信支付教程系列之掃碼支付代碼實(shí)例

來(lái)源:本站原創(chuàng)|時(shí)間:2020-01-10|欄目:C#教程|點(diǎn)擊: 次

今天,我們來(lái)一起探討一下這個(gè)微信掃碼支付。何為掃碼支付呢?這里面,掃的碼就是二維碼了,就是我們經(jīng)常掃一掃的那種二維碼圖片,例如,我們自己添加好友的時(shí)候,可以通過(guò)輸入對(duì)方的微信號(hào),也可以掃一掃對(duì)方的二維碼。掃碼支付,作為,微信支付里面,不可或缺的一個(gè)功能,對(duì)商品的支付提供了極為方便的體驗(yàn),用途也非常的多。

例如我們?cè)诘罔F、公交站常見(jiàn)的那些自動(dòng)售貨機(jī)(不錯(cuò),就是那種投硬幣,就可以自動(dòng)出貨的那種機(jī)器)中都用到。微信(支付寶)的掃碼支付的出現(xiàn),大大的減少了這方面的風(fēng)險(xiǎn),近些年來(lái),二維碼的應(yīng)用越來(lái)越廣,甚至有些地方,直接用來(lái)自動(dòng)售票(就是把起始點(diǎn)設(shè)定好,票價(jià)設(shè)定好,直接把二維碼貼出來(lái),讓乘客自動(dòng)掃相關(guān)的二維碼,完成購(gòu)票,上車(chē)的時(shí)候,只需要提供自己的支付憑證給乘車(chē)員驗(yàn)證即可),這樣,不僅綠色環(huán)保了,還大大的提高了售票的速度(去過(guò)大車(chē)站購(gòu)票的人應(yīng)該深有體驗(yàn),排隊(duì)買(mǎi)個(gè)票,好歹半個(gè)小時(shí)以上,心里也是萬(wàn)頭草泥馬在奔騰的)。

咱就不扯遠(yuǎn)了,說(shuō)回咱么今天要做的微信支付之掃碼支付。微信官方的文檔,這個(gè)掃碼支付(NativePay)分為兩種,一種是“生成掃描支付模式”,另外一種是“生成直接支付url,支付url有效期為2小時(shí)”,至于這里面,兩種掃碼模式,怎么靈活利用呢,官方也沒(méi)有一個(gè)明確的說(shuō)明。個(gè)人理解為,第一種(生成掃描支付模式),適用于固定二維碼的,就是永久使用的那種。

例如一些商家的公眾號(hào)的二維碼,是永久的,什么時(shí)候掃,都是關(guān)注這個(gè)公眾號(hào)的,但是,這種的話,我記得微信是有限量的,貌似是一個(gè)公眾號(hào),限量10w,個(gè)人觀點(diǎn),覺(jué)得這個(gè)限量,是足夠我們使用的。第二種(生成直接支付url,支付url有效期為2小時(shí)),這種的話,因?yàn)橛杏行谶@種時(shí)間限制,超過(guò)了2個(gè)小時(shí),該二維碼就失效,但是對(duì)生成的二維碼數(shù)量沒(méi)有限制,所以,這種個(gè)人觀點(diǎn)覺(jué)得適用于那種臨時(shí)根據(jù)實(shí)際情況生成的二維碼,例如:公眾平臺(tái)登陸的時(shí)候二次驗(yàn)證的二維碼,自定義生成,僅為一次性繳費(fèi)使用的二維碼,等等)。接下來(lái),我們就開(kāi)始講講實(shí)際例子,首先將的就是第一種模式。

掃碼支付之模式一(生成掃描支付模式):

首先,我們新建一個(gè)“MVC”的項(xiàng)目(asp.net的官方的demo就是了,要asp.net的自己看demo吧,demo地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1),然后把系統(tǒng)自動(dòng)生成的HomeControler和View中的Home都刪了。

然后自己新建一個(gè)HomeControler,代碼如下:

 // GET: Home
 public ActionResult Index()
 {
  return View();
 } 

再添加一個(gè)View,代碼如下:

@{
 Layout = null;
}
<!DOCTYPE html>
<html>
<head>
 <meta name="viewport" content="width=device-width" />
 <title>首頁(yè)</title>
</head>
<body>
 <div> 
 </div>
</body>
</html> 

接下來(lái),我們先把官方的demo的一些我們會(huì)用到的東西拷貝過(guò)來(lái),其中包括以下幾個(gè)文件夾,如下圖:

就這個(gè)lib和business兩個(gè),把這兩個(gè)文件夾,支付復(fù)制到咱們的新項(xiàng)目中,并且包含在項(xiàng)目中,如下:

然后我們?cè)佟爸匦律伞币韵马?xiàng)目,或者快捷鍵:ctrl+shift+b,這時(shí)候,會(huì)提下如下錯(cuò)誤:

 

這時(shí)候,我們?nèi)ヌ砑右?,把lib文件夾中的LitJson.dll 添加上即可,如下圖:

到這里,我們就基本把官方的demo的環(huán)境給搭建好了,接下來(lái),我們就要開(kāi)始編寫(xiě)代碼了。

首先,我的邏輯是,從前到后,就是從前端到后端。前端是顯示二維碼的地方,那么我們就先給他一個(gè)div(本文使用到的是jquery的二維碼生成插件,全名叫:jquery.qrcode.min.js,我會(huì)傳到附件上),然后在頁(yè)面加載完畢的時(shí)候,會(huì)請(qǐng)求后臺(tái),讓他返回二維碼字符串,然后再通過(guò)jquery的二維碼生成插件,讓他生成二維碼并顯示在前臺(tái),代碼如下:

前端:

@{
 Layout = null;
}
<!DOCTYPE html>
<html>
<head>
 <meta name="viewport" content="width=device-width" />
 <title>首頁(yè)</title>
 <link href="~/Scripts/jquery-easyui-1.4.5/themes/bootstrap/easyui.css" rel="stylesheet" />
 <link href="~/Scripts/jquery-easyui-1.4.5/themes/mobile.css" rel="stylesheet" />
 <link href="~/Scripts/jquery-easyui-1.4.5/themes/icon.css" rel="stylesheet" />
</head>
<body>
 <p>
  模式一:生成掃描支付模式
  <br />
  <div id="QRCode1">
  </div>
 </p>
 <p>
  模式二:生成直接支付url,支付url有效期為2小時(shí)
  <br />
  <div id="QRCode2">
  </div>
 </p>
 <script src="~/Scripts/jquery-1.10.2.js"></script>
 <script src="~/Scripts/jquery-easyui-1.4.5/jquery.easyui.min.js"></script>
 <script src="~/Scripts/jquery-easyui-1.4.5/jquery.easyui.mobile.js"></script>
 <script src="~/Scripts/jquery-easyui-1.4.5/easyloader.js"></script>
 <script src="~/Scripts/jquery.qrcode.min.js"></script>
 <script type="text/javascript">
  $(function () {
   fGetQRCode1();
  })
  function fGetQRCode1() {
   $.messager.progress({
    title: "",
    msg: "正在生成二維碼:模式一,請(qǐng)稍后..."
   });
   $.ajax({
    type: "post",
    url: "/Home/GetQRCode1",
    data: {
     time: new Date(),
     productId:7788
    },
    success: function (json) {
     $.messager.progress('close');//記得關(guān)閉
     if (json.result) {
      $('#QRCode1').qrcode(json.str); //生成二維碼
     }
     else {
      $('#QRCode1').html("二維碼生成失敗");
     }
    }
   })
  }
 </script>
</body>
</html>

后端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WxPayAPI;
namespace WxPay.Controllers
{
 public class HomeController : Controller
 {
  // GET: Home
  public ActionResult Index()
  {
   return View();
  }
  /// <summary>
  /// 模式一
  /// </summary>
  /// <returns></returns>
  [HttpPost]
  public ActionResult GetQRCode1()
  {
   object objResult = "";
   string strProductID = Request.Form["productId"];
   string strQRCodeStr = GetPrePayUrl(strProductID);
   if (!string.IsNullOrWhiteSpace(strProductID))
   {
    objResult = new { result = true, str = strQRCodeStr };
   }
   else
   {
    objResult = new { result = false };
   }
   return Json(objResult);
  }
  /**
  * 生成掃描支付模式一URL
  * @param productId 商品ID
  * @return 模式一URL
  */
  public string GetPrePayUrl(string productId)
  {
   WxPayData data = new WxPayData();
   data.SetValue("appid", WxPayConfig.APPID);//公眾帳號(hào)id
   data.SetValue("mch_id", WxPayConfig.MCHID);//商戶號(hào)
   data.SetValue("time_stamp", WxPayApi.GenerateTimeStamp());//時(shí)間戳
   data.SetValue("nonce_str", WxPayApi.GenerateNonceStr());//隨機(jī)字符串
   data.SetValue("product_id", productId);//商品ID
   data.SetValue("sign", data.MakeSign());//簽名
   string str = ToUrlParams(data.GetValues());//轉(zhuǎn)換為URL串
   string url = "weixin://wxpay/bizpayurl?" + str;
   return url;
  }
  /**
  * 參數(shù)數(shù)組轉(zhuǎn)換為url格式
  * @param map 參數(shù)名與參數(shù)值的映射表
  * @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;
  }
 }
}

這時(shí)候,模式一是不是感覺(jué)就完成了?那么我們現(xiàn)在試試,我們?yōu)g覽該頁(yè)面,如下:

然后用微信掃一掃功能掃一下,發(fā)現(xiàn)提示如下:

這是什么鬼,是不是,你心里面是不是想知道為啥,那我來(lái)告訴你,這是為啥,這是因?yàn)椋氵€沒(méi)有設(shè)置回調(diào)頁(yè)面或者回調(diào)頁(yè)面有問(wèn)題,這個(gè)時(shí)候,我們?cè)傩陆ㄒ粋€(gè)Control,命名為:NativeNotifyController.cs,代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using WxPayAPI;
namespace WxPay.Controllers
{
 public class NativeNotifyController : Controller
 {
  // GET: NativeNotify
  public ActionResult Index()
  {
   string strData = ProcessNotify();
   Response.Write(strData);
   return View();
  }
  public string ProcessNotify()
  {
   WxPayData notifyData = GetNotifyData();
   //檢查openid和product_id是否返回
   if (!notifyData.IsSet("openid") || !notifyData.IsSet("product_id"))
   {
    WxPayData res = new WxPayData();
    res.SetValue("return_code", "FAIL");
    res.SetValue("return_msg", "回調(diào)數(shù)據(jù)異常");
    return res.ToXml();
   }
   //調(diào)統(tǒng)一下單接口,獲得下單結(jié)果
   string openid = notifyData.GetValue("openid").ToString();
   string product_id = notifyData.GetValue("product_id").ToString();
   WxPayData unifiedOrderResult = new WxPayData();
   try
   {
    unifiedOrderResult = UnifiedOrder(openid, product_id);
   }
   catch (Exception ex)//若在調(diào)統(tǒng)一下單接口時(shí)拋異常,立即返回結(jié)果給微信支付后臺(tái)
   {
    WxPayData res = new WxPayData();
    res.SetValue("return_code", "FAIL");
    res.SetValue("return_msg", "統(tǒng)一下單失敗");
    return res.ToXml();
   }
   //若下單失敗,則立即返回結(jié)果給微信支付后臺(tái)
   if (!unifiedOrderResult.IsSet("appid") || !unifiedOrderResult.IsSet("mch_id") || !unifiedOrderResult.IsSet("prepay_id"))
   {
    WxPayData res = new WxPayData();
    res.SetValue("return_code", "FAIL");
    res.SetValue("return_msg", "統(tǒng)一下單失敗");
    return res.ToXml();
   }
   //統(tǒng)一下單成功,則返回成功結(jié)果給微信支付后臺(tái)
   WxPayData data = new WxPayData();
   data.SetValue("return_code", "SUCCESS");
   data.SetValue("return_msg", "OK");
   data.SetValue("appid", WxPayConfig.APPID);
   data.SetValue("mch_id", WxPayConfig.MCHID);
   data.SetValue("nonce_str", WxPayApi.GenerateNonceStr());
   data.SetValue("prepay_id", unifiedOrderResult.GetValue("prepay_id"));
   data.SetValue("result_code", "SUCCESS");
   data.SetValue("err_code_des", "OK");
   data.SetValue("sign", data.MakeSign());
   return data.ToXml();
  }
  /// <summary>
  /// 接收從微信支付后臺(tái)發(fā)送過(guò)來(lái)的數(shù)據(jù)并驗(yàn)證簽名
  /// </summary>
  /// <returns>微信支付后臺(tái)返回的數(shù)據(jù)</returns>
  public WxPayData GetNotifyData()
  {
   //接收從微信后臺(tái)POST過(guò)來(lái)的數(shù)據(jù)
   System.IO.Stream s = Request.InputStream;
   int count = 0;
   byte[] buffer = new byte[1024];
   StringBuilder builder = new StringBuilder();
   while ((count = s.Read(buffer, 0, 1024)) > 0)
   {
    builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
   }
   s.Flush();
   s.Close();
   s.Dispose();
   //轉(zhuǎn)換數(shù)據(jù)格式并驗(yàn)證簽名
   WxPayData data = new WxPayData();
   try
   {
    data.FromXml(builder.ToString());
   }
   catch (WxPayException ex)
   {
    //若簽名錯(cuò)誤,則立即返回結(jié)果給微信支付后臺(tái)
    WxPayData res = new WxPayData();
    res.SetValue("return_code", "FAIL");
    res.SetValue("return_msg", ex.Message);
   }
   return data;
  }
  private WxPayData UnifiedOrder(string openId, string productId)
  {
   //統(tǒng)一下單
   WxPayData req = new WxPayData();
   req.SetValue("body", "廣東XXXX股份有限公司");
   req.SetValue("attach", "附加信息,用于后臺(tái)或者存入數(shù)據(jù)庫(kù),做自己的判斷");
   req.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo());
   req.SetValue("total_fee", 1);
   req.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));
   req.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));
   req.SetValue("goods_tag", "商品的備忘,可以自定義");
   req.SetValue("trade_type", "NATIVE");
   req.SetValue("openid", openId);
   req.SetValue("product_id", productId);
   WxPayData result = WxPayApi.UnifiedOrder(req);
   return result;
  }
 }
}

記得,也要新建一個(gè)View,就是在Index那里,右鍵添加一個(gè)View,View的代碼如下(你沒(méi)眼花,就是空的,不管他):

@{
 Layout = null;
}
<!DOCTYPE html>
<html>
<head>
 <meta name="viewport" content="width=device-width" />
 <title>Index</title>
</head>
<body>
 <div> 
 </div>
</body>
</html>

接著,把這個(gè)項(xiàng)目,發(fā)布出來(lái),放到服務(wù)器的iis上,這里面,我把他發(fā)布在http://sm.lmx.ren/上面(必須要發(fā)布到網(wǎng)上哈,如果不懂發(fā)布的,你可以自己去學(xué)習(xí)基礎(chǔ)知識(shí)先了),這還沒(méi)完,還需要把到公眾平臺(tái)上,設(shè)置回調(diào)頁(yè)面,操作如下:

這樣,就大功告成了。這時(shí)候,我們?cè)僭囋噿叽a,發(fā)現(xiàn)已經(jīng)得到以下提示了,這樣子,就代表,我們的模式一,已經(jīng)成功完成了。如下圖:

 

這時(shí)候,細(xì)心的朋友就會(huì)提問(wèn)了,我這都支付成功了,怎么頁(yè)面沒(méi)啥提示呀,這頁(yè)面不交互很不友好啊。嗯,沒(méi)錯(cuò),童鞋,你有前途,現(xiàn)在我就告訴你,怎么做交互,但是,為了你日后更加有前途,我只告訴你邏輯,具體怎么實(shí)現(xiàn),自己來(lái)想,多動(dòng)腦。

那么邏輯是怎么的呢?常規(guī)邏輯下,我們微信掃頁(yè)面上的這個(gè)二維碼的時(shí)候,這個(gè)時(shí)候,他已經(jīng)把我們二維碼里面的參數(shù),傳到微信服務(wù)器,然后有他們開(kāi)始統(tǒng)一下單(如果對(duì)邏輯不清晰,可以看看官方的文檔:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_3):他們?cè)诮y(tǒng)一下單的時(shí)候,就會(huì)生成一個(gè)product_id,這個(gè)家伙的作用呢 ,就是告訴你現(xiàn)在微信服務(wù)器,已經(jīng)生成了一個(gè)單號(hào),勞資已經(jīng)收到你的支付請(qǐng)求了,趕緊給老子付款,O(∩_∩)O哈哈~。。。停,停,停。這時(shí)候,思路不能繼續(xù)往下走了。

記得,前面有個(gè)叫做“統(tǒng)一下單“,那既然有這個(gè)步驟,那我們可以利用一下,就是當(dāng)他統(tǒng)一下單成功的時(shí)候,我們可以在頁(yè)面更新一下?tīng)顟B(tài),告訴客戶:您已成功掃描,并下單成功,請(qǐng)支付。是不是,我們可以提示他們這個(gè)。然后等用戶在手機(jī)上,支付成功的時(shí)候,這個(gè)時(shí)候,頁(yè)面是不是也要反饋給用戶,告訴他,小子,你的錢(qián)已經(jīng)到我的口袋了,你可以走了(你走,我沒(méi)有你這樣的寶寶)。O(∩_∩)O哈哈~,但是,你還要停,停住,停下來(lái)。我們服務(wù)公司怎么知道這個(gè)微信用戶已經(jīng)付款成功了呢?來(lái),我們把視線回到代碼上,找到lib/Config.cs,如下圖:

然后打開(kāi)config.cs,找到以下代碼:

對(duì)了,你很聰明。微信的處理邏輯就是,等用戶支付成功之后,他會(huì)給這個(gè)鏈接發(fā)送支付結(jié)果,默認(rèn)是以前那個(gè)aspx的頁(yè)面,現(xiàn)在我換成mvc,所以,我們得手動(dòng)新建一個(gè)control了,命名為:ResultNotifyController,然后代碼如下:

using LmxPublic.Log;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using WxPayAPI;
namespace WxPay.Controllers
{
 public class ResultNotifyController : Controller
 {
  // GET: ResultNotify
  public ActionResult Index()
  {
   string strData = ProcessNotify();
   Response.Write(strData);
   return View();
  }
  public string ProcessNotify()
  {
   WxPayData notifyData = GetNotifyData();
   //檢查支付結(jié)果中transaction_id是否存在
   if (!notifyData.IsSet("transaction_id"))
   {
    //若transaction_id不存在,則立即返回結(jié)果給微信支付后臺(tái)
    WxPayData res = new WxPayData();
    res.SetValue("return_code", "FAIL");
    res.SetValue("return_msg", "支付結(jié)果中微信訂單號(hào)不存在");
    return res.ToXml();
   }
   string transaction_id = notifyData.GetValue("transaction_id").ToString();
   //查詢訂單,判斷訂單真實(shí)性
   if (!QueryOrder(transaction_id))
   {
    //若訂單查詢失敗,則立即返回結(jié)果給微信支付后臺(tái)
    WxPayData res = new WxPayData();
    res.SetValue("return_code", "FAIL");
    res.SetValue("return_msg", "訂單查詢失敗");
    return res.ToXml();
   }
   //查詢訂單成功
   else
   {
    WxPayData res = new WxPayData();
    res.SetValue("return_code", "SUCCESS");
    res.SetValue("return_msg", "OK");
    Log.Info(this.GetType().ToString(), "order query success : " + res.ToXml());
    string strXml = res.ToXml();
    FileLog.WriteLog(strXml);
    return res.ToXml();//如果我們走到這一步了,那就代表,用戶已經(jīng)支付成功了,所以,該干嘛干嘛了。
   }
  }
  /// <summary>
  /// 接收從微信支付后臺(tái)發(fā)送過(guò)來(lái)的數(shù)據(jù)并驗(yàn)證簽名
  /// </summary>
  /// <returns>微信支付后臺(tái)返回的數(shù)據(jù)</returns>
  public WxPayData GetNotifyData()
  {
   //接收從微信后臺(tái)POST過(guò)來(lái)的數(shù)據(jù)
   System.IO.Stream s = Request.InputStream;
   int count = 0;
   byte[] buffer = new byte[1024];
   StringBuilder builder = new StringBuilder();
   while ((count = s.Read(buffer, 0, 1024)) > 0)
   {
    builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
   }
   s.Flush();
   s.Close();
   s.Dispose();
   Log.Info(this.GetType().ToString(), "Receive data from WeChat : " + builder.ToString());
   //轉(zhuǎn)換數(shù)據(jù)格式并驗(yàn)證簽名
   WxPayData data = new WxPayData();
   try
   {
    data.FromXml(builder.ToString());
   }
   catch (WxPayException ex)
   {
    //若簽名錯(cuò)誤,則立即返回結(jié)果給微信支付后臺(tái)
    WxPayData res = new WxPayData();
    res.SetValue("return_code", "FAIL");
    res.SetValue("return_msg", ex.Message);
    Log.Error(this.GetType().ToString(), "Sign check error : " + res.ToXml());
    return res;
   }
   
   return data;
  }
  //查詢訂單
  private bool QueryOrder(string transaction_id)
  {
   WxPayData req = new WxPayData();
   req.SetValue("transaction_id", transaction_id);
   WxPayData res = WxPayApi.OrderQuery(req);
   if (res.GetValue("return_code").ToString() == "SUCCESS" &&
    res.GetValue("result_code").ToString() == "SUCCESS")
   {
    return true;
   }
   else
   {
    return false;
   }
  }
 }
}

前臺(tái),對(duì),也是要新建一個(gè)View,代碼如下(沒(méi)錯(cuò),也是空的)

@{
 Layout = null;
}
<!DOCTYPE html>
<html>
<head>
 <meta name="viewport" content="width=device-width" />
 <title>Index</title>
</head>
<body>
 <div> 
 </div>
</body>
</html>

好,模式一就到這里了,呼呼。。。沒(méi)想到啊,一個(gè)模式一,讓我從上午寫(xiě)到下午,真心累。。。還有一個(gè)模式二呢。。。喝口水先,咱,接著來(lái)。

好,喝完水,接著干,下面是模式二:

模式二(生成直接支付url,支付url有效期為2小時(shí))

由于有了上面模式一的詳細(xì)說(shuō)明,模式二,我就簡(jiǎn)單一點(diǎn)的來(lái)說(shuō)了,如果又不懂的,到群里來(lái)問(wèn)我吧。

模式二,前端,增加一些代碼,如下(完整的,包括模式一的代碼了):

@{
 Layout = null;
}
<!DOCTYPE html>
<html>
<head>
 <meta name="viewport" content="width=device-width" />
 <title>首頁(yè)</title>
 <link href="~/Scripts/jquery-easyui-1.4.5/themes/bootstrap/easyui.css" rel="stylesheet" />
 <link href="~/Scripts/jquery-easyui-1.4.5/themes/mobile.css" rel="stylesheet" />
 <link href="~/Scripts/jquery-easyui-1.4.5/themes/icon.css" rel="stylesheet" />
</head>
<body>
 <p>
  模式一:生成掃描支付模式
  <br />
  <div id="QRCode1">
  </div>
 </p>
 <p>
  模式二:生成直接支付url,支付url有效期為2小時(shí)
  <br />
  <div id="QRCode2">
  </div>
 </p>
 <script src="~/Scripts/jquery-1.10.2.js"></script>
 <script src="~/Scripts/jquery-easyui-1.4.5/jquery.easyui.min.js"></script>
 <script src="~/Scripts/jquery-easyui-1.4.5/jquery.easyui.mobile.js"></script>
 <script src="~/Scripts/jquery-easyui-1.4.5/easyloader.js"></script>
 <script src="~/Scripts/jquery.qrcode.min.js"></script>
 <script type="text/javascript">
  $(function () {
   fGetQRCode1();
  })
  function fGetQRCode1() {
   $.messager.progress({
    title: "",
    msg: "正在生成二維碼:模式一,請(qǐng)稍后..."
   });
   $.ajax({
    type: "post",
    url: "/Home/GetQRCode1",
    data: {
     time: new Date(),
     productId:7788
    },
    success: function (json) {
     $.messager.progress('close');//記得關(guān)閉
     if (json.result) {
      $('#QRCode1').qrcode(json.str); //生成二維碼
     }
     else {
      $('#QRCode1').html("二維碼生成失敗");
     }
     fGetQRCode2();
    },
    error: function (json) {
     $('#QRCode1').html("二維碼生成失敗");
     fGetQRCode2();
    }
   })
  }
  function fGetQRCode2() {
   $.messager.progress({
    title: "",
    msg: "正在生成二維碼:模式二,請(qǐng)稍后..."
   });
   $.ajax({
    type: "post",
    url: "/Home/GetQRCode2",
    data: {
     time: new Date(),
     productId: 7788
    },
    success: function (json) {
     $.messager.progress('close');//記得關(guān)閉
     if (json.result) {
      $('#QRCode2').qrcode(json.str); //生成二維碼
     }
     else {
      $('#QRCode2').html("二維碼生成失敗");
     }
    },
    error: function (json) {
     $('#QRCode2').html("二維碼生成失敗");
    }
   })
  }
 </script>
</body>
</html>

后端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WxPayAPI;
namespace WxPay.Controllers
{
 public class HomeController : Controller
 {
  // GET: Home
  public ActionResult Index()
  {
   return View();
  }
  /// <summary>
  /// 模式一
  /// </summary>
  /// <returns></returns>
  [HttpPost]
  public ActionResult GetQRCode1()
  {
   object objResult = "";
   string strProductID = Request.Form["productId"];
   string strQRCodeStr = GetPrePayUrl(strProductID);
   if (!string.IsNullOrWhiteSpace(strProductID))
   {
    objResult = new { result = true, str = strQRCodeStr };
   }
   else
   {
    objResult = new { result = false };
   }
   return Json(objResult);
  }
  /// <summary>
  /// 模式二
  /// </summary>
  /// <returns></returns>
  [HttpPost]
  public ActionResult GetQRCode2()
  {
   object objResult = "";
   string strProductID = Request.Form["productId"];
   string strQRCodeStr = GetPayUrl(strProductID);
   if (!string.IsNullOrWhiteSpace(strProductID))
   {
    objResult = new { result = true, str = strQRCodeStr };
   }
   else
   {
    objResult = new { result = false };
   }
   return Json(objResult);
  }
  /**
  * 生成掃描支付模式一URL
  * @param productId 商品ID
  * @return 模式一URL
  */
  public string GetPrePayUrl(string productId)
  {
   WxPayData data = new WxPayData();
   data.SetValue("appid", WxPayConfig.APPID);//公眾帳號(hào)id
   data.SetValue("mch_id", WxPayConfig.MCHID);//商戶號(hào)
   data.SetValue("time_stamp", WxPayApi.GenerateTimeStamp());//時(shí)間戳
   data.SetValue("nonce_str", WxPayApi.GenerateNonceStr());//隨機(jī)字符串
   data.SetValue("product_id", productId);//商品ID
   data.SetValue("sign", data.MakeSign());//簽名
   string str = ToUrlParams(data.GetValues());//轉(zhuǎn)換為URL串
   string url = "weixin://wxpay/bizpayurl?" + str;
   return url;
  }
  /**
  * 參數(shù)數(shù)組轉(zhuǎn)換為url格式
  * @param map 參數(shù)名與參數(shù)值的映射表
  * @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;
  }
  /**
  * 生成直接支付url,支付url有效期為2小時(shí),模式二
  * @param productId 商品ID
  * @return 模式二URL
  */
  public string GetPayUrl(string productId)
  {
   WxPayData data = new WxPayData();
   data.SetValue("body", "廣東XXXX股份有限公司");//商品描述
   data.SetValue("attach", "附加信息,用于后臺(tái)或者存入數(shù)據(jù)庫(kù),做自己的判斷");//附加數(shù)據(jù)
   data.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo());//隨機(jī)字符串
   data.SetValue("total_fee", 1);//總金額
   data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始時(shí)間
   data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));//交易結(jié)束時(shí)間
   data.SetValue("goods_tag", "商品的備忘,可以自定義");//商品標(biāo)記
   data.SetValue("trade_type", "NATIVE");//交易類(lèi)型
   data.SetValue("product_id", productId);//商品ID
   WxPayData result = WxPayApi.UnifiedOrder(data);//調(diào)用統(tǒng)一下單接口
   string url = result.GetValue("code_url").ToString();//獲得統(tǒng)一下單接口返回的二維碼鏈接
   
   return url;
  }
 }
}

特此更正,感謝“ abc54288”的指出,模式二也是有回調(diào)的,回調(diào)的接口設(shè)置在Config.cs,中,如下圖:

所以下面的作廢,但是如果需要手動(dòng)查詢訂單情況的,還可以用下列的方法查詢。再次感謝園友:“ abc54288”。

由于模式二是沒(méi)有支付結(jié)果回調(diào)的,所以,我們要查詢支付成功與否,需要自己寫(xiě)方法來(lái)查詢,官方提供的查詢支付成功與否的方法有以下,

/***
  * 訂單查詢完整業(yè)務(wù)流程邏輯
  * @param transaction_id 微信訂單號(hào)(優(yōu)先使用)
  * @param out_trade_no 商戶訂單號(hào)
  * @return 訂單查詢結(jié)果(xml格式)
  */
  public static string Run(string transaction_id, string out_trade_no)
  {
   Log.Info("OrderQuery", "OrderQuery is processing...");
   WxPayData data = new WxPayData();
   if(!string.IsNullOrEmpty(transaction_id))//如果微信訂單號(hào)存在,則以微信訂單號(hào)為準(zhǔn)
   {
    data.SetValue("transaction_id", transaction_id);
   }
   else//微信訂單號(hào)不存在,才根據(jù)商戶訂單號(hào)去查單
   {
    data.SetValue("out_trade_no", out_trade_no);
   }
   WxPayData result = WxPayApi.OrderQuery(data);//提交訂單查詢請(qǐng)求給API,接收返回?cái)?shù)據(jù)
   Log.Info("OrderQuery", "OrderQuery process complete, result : " + result.ToXml());
   return result.ToPrintStr();
  }

可以通過(guò)這個(gè)微信訂單號(hào)(transaction_id)來(lái)查詢,也可以通過(guò)商戶訂單號(hào)(out_trade_no),所以,我們要合理利用這里面的技巧,上述模式二,我用的out_trade_no 是一個(gè)隨機(jī)字符串,我們可以把這個(gè)字符串記錄好,放數(shù)據(jù)庫(kù)還是放哪里,你自己喜歡,然后寫(xiě)一個(gè)ajsx長(zhǎng)輪詢來(lái),定時(shí)查詢這個(gè)商戶訂單號(hào),看看有沒(méi)有支付成功,來(lái)做支付確認(rèn)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。

上一篇:C#判斷字符串是否是int/double(實(shí)例)

欄    目:C#教程

下一篇:詳解二維碼生成工廠

本文標(biāo)題:C# MVC 微信支付教程系列之掃碼支付代碼實(shí)例

本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/6080.html

網(wǎng)頁(yè)制作CMS教程網(wǎng)絡(luò)編程軟件編程腳本語(yǔ)言數(shù)據(jù)庫(kù)服務(wù)器

如果侵犯了您的權(quán)利,請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)進(jìn)行處理、任何非本站因素導(dǎo)致的法律后果,本站均不負(fù)任何責(zé)任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有