c#版在pc端發(fā)起微信掃碼支付的實例
等了好久,微信官方終于發(fā)布了.net的demo。
主要代碼:
/**
* 生成直接支付url,支付url有效期為2小時,模式二
* @param productId 商品ID
* @return 模式二URL
*/
public string GetPayUrl(string productId, string body, string attach, int total_fee, string goods_tag)
{
Log.Info(this.GetType().ToString(), "Native pay mode 2 url is producing...");
WxPayData data = new WxPayData();
data.SetValue("body", body);//商品描述
data.SetValue("attach", attach);//附加數(shù)據(jù)
data.SetValue("out_trade_no", productId);//隨機字符串
data.SetValue("total_fee", total_fee);//總金額
data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始時間
data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));//交易結束時間
data.SetValue("goods_tag", goods_tag);//商品標記
data.SetValue("trade_type", "NATIVE");//交易類型
data.SetValue("product_id", productId);//商品ID
WxPayData result = WxPayApi.UnifiedOrder(data);//調用統(tǒng)一下單接口
string url = result.GetValue("code_url").ToString();//獲得統(tǒng)一下單接口返回的二維碼鏈接
Log.Info(this.GetType().ToString(), "Get native pay mode 2 url : " + url);
return url;
}
配置信息:
public class Config
{
//=======【基本信息設置】=====================================
/* 微信公眾號信息配置
* APPID:綁定支付的APPID(必須配置)
* MCHID:商戶號(必須配置)
* KEY:商戶支付密鑰,參考開戶郵件設置(必須配置)
* APPSECRET:公眾帳號secert(僅JSAPI支付的時候需要配置)
*/
public const string APPID = "你的微信公眾號APPID";
public const string MCHID = "你的微信公眾號的商戶號";
public const string KEY = "你的微信公眾號的商戶支付密鑰";
public const string APPSECRET = "你的微信公眾號的APPSECRET";
//=======【證書路徑設置】=====================================
/* 證書路徑,注意應該填寫絕對路徑(僅退款、撤銷訂單時需要)
*/
public const string SSLCERT_PATH = "cert/apiclient_cert.p12";
public const string SSLCERT_PASSWORD = "1233410002";
//=======【支付結果通知url】=====================================
/* 支付結果通知回調url,用于商戶接收支付結果
*/
public const string NOTIFY_URL = "http://你的網(wǎng)站/Pay/ResultNotifyPage.aspx";
//=======【商戶系統(tǒng)后臺機器IP】=====================================
/* 此參數(shù)可手動配置也可在程序中自動獲取
*/
public const string IP = "你的服務器IP";
//=======【代理服務器設置】===================================
/* 默認IP和端口號分別為0.0.0.0和0,此時不開啟代理(如有需要才設置)
*/
public const string PROXY_URL = "";
//=======【上報信息配置】===================================
/* 測速上報等級,0.關閉上報; 1.僅錯誤時上報; 2.全量上報
*/
public const int REPORT_LEVENL = 1;
//=======【日志級別】===================================
/* 日志等級,0.不輸出日志;1.只輸出錯誤信息; 2.輸出錯誤和正常信息; 3.輸出錯誤信息、正常信息和調試信息
*/
public const int LOG_LEVENL = 0;
}
不使用代理要注釋HttpService.cs里面post和get方法的下面代碼:
//設置代理服務器
//WebProxy proxy = new WebProxy(); //定義一個網(wǎng)關對象
//proxy.Address = new Uri(Config.PROXY_URL); //網(wǎng)關服務器端口:端口
//request.Proxy = proxy;
統(tǒng)一下單:
/**
*
* 統(tǒng)一下單
* @param WxPaydata inputObj 提交給統(tǒng)一下單API的參數(shù)
* @param int timeOut 超時時間
* @throws WxPayException
* @return 成功時返回,其他拋異常
*/
public static WxPayData UnifiedOrder(WxPayData inputObj, int timeOut = 6)
{
string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
//檢測必填參數(shù)
if (!inputObj.IsSet("out_trade_no"))
{
throw new WxPayException("缺少統(tǒng)一支付接口必填參數(shù)out_trade_no!");
}
else if (!inputObj.IsSet("body"))
{
throw new WxPayException("缺少統(tǒng)一支付接口必填參數(shù)body!");
}
else if (!inputObj.IsSet("total_fee"))
{
throw new WxPayException("缺少統(tǒng)一支付接口必填參數(shù)total_fee!");
}
else if (!inputObj.IsSet("trade_type"))
{
throw new WxPayException("缺少統(tǒng)一支付接口必填參數(shù)trade_type!");
}
//關聯(lián)參數(shù)
if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid"))
{
throw new WxPayException("統(tǒng)一支付接口中,缺少必填參數(shù)openid!trade_type為JSAPI時,openid為必填參數(shù)!");
}
if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id"))
{
throw new WxPayException("統(tǒng)一支付接口中,缺少必填參數(shù)product_id!trade_type為JSAPI時,product_id為必填參數(shù)!");
}
//異步通知url未設置,則使用配置文件中的url
if (!inputObj.IsSet("notify_url"))
{
inputObj.SetValue("notify_url", Config.NOTIFY_URL);//異步通知url
}
inputObj.SetValue("appid", Config.APPID);//公眾賬號ID
inputObj.SetValue("mch_id", Config.MCHID);//商戶號
inputObj.SetValue("spbill_create_ip", Config.IP);//終端ip
inputObj.SetValue("nonce_str", GenerateNonceStr());//隨機字符串
//簽名
inputObj.SetValue("sign", inputObj.MakeSign());
string xml = inputObj.ToXml();
var start = DateTime.Now;
Log.Debug("WxPayApi", "UnfiedOrder request : " + xml);
string response = HttpService.Post(xml, url, false, timeOut);
Log.Debug("WxPayApi", "UnfiedOrder response : " + response);
var end = DateTime.Now;
int timeCost = (int)((end - start).TotalMilliseconds);
WxPayData result = new WxPayData();
result.FromXml(response);
ReportCostTime(url, timeCost, result);//測速上報
return result;
}
看我的調用例子:
MakeQRCode.aspx頁面照抄:
public partial class Pay_MakeQRCode : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(base.Request.QueryString["data"]))
{
string str = base.Request.QueryString["data"];
Bitmap image = new QRCodeEncoder
{
QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE,
QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M,
QRCodeVersion = 0,
QRCodeScale = 4
}.Encode(str, Encoding.Default);
MemoryStream ms = new MemoryStream();
image.Save(ms, ImageFormat.Png);
base.Response.BinaryWrite(ms.GetBuffer());
base.Response.End();
}
}
}
這個頁面是用來生成二維碼的,需要引入ThoughtWorks.QRCode.dll組件。
我使用模式二,回調頁面是ResultNotifyPage.aspx,就是在配置信息那里填寫的那個回調頁面。
protected void Page_Load(object sender, EventArgs e)
{
ResultNotify resultNotify = new ResultNotify(this);
WxPayData res = resultNotify.ProcessNotify2();
if (res.GetValue("return_code") == "SUCCESS")
{
//查詢微信訂單信息
string paySignKey = ConfigurationManager.AppSettings["paySignKey"].ToString();
string mch_id = ConfigurationManager.AppSettings["mch_id"].ToString();
string appId = ConfigurationManager.AppSettings["AppId"].ToString();
QueryOrder queryorder = new QueryOrder();
queryorder.appid = appId;
queryorder.mch_id = mch_id;
queryorder.transaction_id = res.GetValue("transaction_id").ToString();
queryorder.out_trade_no = "";
queryorder.nonce_str = TenpayUtil.getNoncestr();
TenpayUtil tenpay = new TenpayUtil();
OrderDetail orderdeatil = tenpay.getOrderDetail(queryorder, paySignKey);
//寫微信記錄
(new vinson()).WriteReturnWXDetail(orderdeatil);
//寫充值記錄
FilliedOnline(orderdeatil.out_trade_no);
}
Response.Write(res.ToXml());
Response.End();
}
掃碼支付成功后會異步到這個頁面執(zhí)行代碼,我們自己的業(yè)務邏輯就要寫在這里。使用微信官方的ProcessNotify()函數(shù)可不行,我們稍微修改下就好了。增加ProcessNotify2函數(shù):
public WxPayData ProcessNotify2()
{
WxPayData notifyData = GetNotifyData();
//檢查支付結果中transaction_id是否存在
if (!notifyData.IsSet("transaction_id"))
{
//若transaction_id不存在,則立即返回結果給微信支付后臺
WxPayData res = new WxPayData();
res.SetValue("transaction_id", "");
res.SetValue("return_code", "FAIL");
res.SetValue("return_msg", "支付結果中微信訂單號不存在");
return res;
}
string transaction_id = notifyData.GetValue("transaction_id").ToString();
//查詢訂單,判斷訂單真實性
if (!QueryOrder(transaction_id))
{
//若訂單查詢失敗,則立即返回結果給微信支付后臺
WxPayData res = new WxPayData();
res.SetValue("transaction_id", transaction_id);
res.SetValue("return_code", "FAIL");
res.SetValue("return_msg", "訂單查詢失敗");
return res;
}
//查詢訂單成功
else
{
WxPayData res = new WxPayData();
res.SetValue("transaction_id", transaction_id);
res.SetValue("return_code", "SUCCESS");
res.SetValue("return_msg", "OK");
return res;
}
}
返回WxPayData對象,這樣一判斷
if (res.GetValue("return_code") == "SUCCESS")
表示支付成功,就可以進入我們的業(yè)務邏輯。
然后我們還要對當前訂單查單,獲取訂單的相關信息,之前微信未出demo的時候我自己寫了個查單的,就直接用了,關鍵WxPayData對象會返回微信的訂單號:res.GetValue("transaction_id").ToString()。
完事后還要發(fā)送信息回給微信,通知微信后臺不要繼續(xù)發(fā)送異步請求了:
Response.Write(res.ToXml()); Response.End();
這個代碼比較重要了。
再說說放置二維碼的頁面:
<div class="g-body">
<div class="g-wrap">
<div class="m-weixin">
<div class="m-weixin-header">
<p><strong>請您及時付款,以便訂單盡快處理!訂單號:<asp:Label ID="trade_no" runat="server" Text="Label"></asp:Label></strong></p>
<p>請您在提交訂單后1小時內支付,否則訂單會自動取消。</p>
</div>
<div class="m-weixin-main">
<h1 class="m-weixin-title">
<img alt="微信支付" src="../images/wxlogo_pay.png"/>
</h1>
<p class="m-weixin-money"><font>掃一掃付款</font><br/><strong>¥<asp:Label ID="money" runat="server" Text="Label"></asp:Label></strong></p>
<p>
<img id="payQRImg" width="260" height="260" class="m-weixin-code" style="position: absolute;" src="<%=ImageUrl %>" alt="二維碼" style="border-width:0px;" />
<img class="m-weixin-demo" src="../images/wxwebpay_guide.png" alt="掃一掃" />
<img style="margin-top:300px;" src="../images/weixin_1.png" alt="請使用微信掃描二維碼以完成支付" />
</p>
<p id="we_ok" style="display:none;">
<input value="完成" style="width: 300px; height: 50px; background: rgb(21, 164, 21) none repeat scroll 0% 0%; color: white; font-size: 30px; border: medium none; cursor: pointer;" type="button" />
</p>
</div>
</div>
</div>
</div>
寫個js查單支付情況進行顯示:
$(function () {
var success = "<%=success %>";
if (success == "error") {
$(".g-body").hide();
}
})
var iCount = setInterval(check, 2000); //每隔2秒執(zhí)行一次check函數(shù)。
function check() {
$.ajax({
contentType: "application/json",
url: "/WebService/vinson.asmx/queryWeiXin",
data: "{OrderID:'" + $("#trade_no").text() + "'}",
type: "POST",
dataType: "json",
success: function (json) {
json = eval("(" + json.d + ")");
if (json.success == "success") {
clearInterval(iCount);
$(".m-weixin-money font").html("已成功付款");
$("#payQRImg").remove();
$(".m-weixin-demo").before('<img alt="" src="../images/wx_ok.jpg" width="200">');
$(".m-weixin-demo").next().remove();
$("#we_ok").show();
}
},
error: function (err, ex) {
}
});
}
是的,我又寫了個給ajax使用的查單函數(shù)queryWeiXin。
我這里才是生成訂單和二維碼:
恩,還有啥呢,恩,看看效果吧:
支付成功后:
原文鏈接:http://www.cnblogs.com/vinsonLu/p/5166214.html
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持我們。
您可能感興趣的文章
- 01-10winform實現(xiàn)創(chuàng)建最前端窗體的方法
- 01-10C#獲取客戶端相關信息實例總結
- 01-10使用C#編寫簡單的圖形化的可發(fā)送附件的郵件客戶端程序
- 01-10C#簡單實現(xiàn)在網(wǎng)頁上發(fā)郵件的案例
- 01-10C#基于TCP協(xié)議的服務器端和客戶端通信編程的基礎教程
- 01-10SMTP客戶端未通過身份驗證等多種錯誤解決方案分享
- 01-10C#與Java的MD5簡單驗證(實例代碼)
- 01-10詳解C# Socket簡單例子(服務器與客戶端通信)
- 01-10C#實現(xiàn)圖片上傳(PC端和APP)保存及 跨域上傳說明
- 01-10SuperSocket入門--Telnet服務器和客戶端請求處理


閱讀排行
本欄相關
- 01-10C#通過反射獲取當前工程中所有窗體并
- 01-10關于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現(xiàn)txt定位指定行完整實例
- 01-10WinForm實現(xiàn)仿視頻播放器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已
隨機閱讀
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10delphi制作wav文件的方法
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 01-10C#中split用法實例總結
- 04-02jquery與jsp,用jquery
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文


