微信掃碼支付(Asp.Net MVC)
這裡的掃碼支付指的是PC網站上面使用微信支付,也就是官方的模式二,網站是Asp.net MVC
,整理如下。(demo在最下方)
一、準備工作
使用的微信API中的統一下單方法,關鍵的引數是‘公眾賬號ID(appid
)’,‘商戶號(mch_id
)’和’商戶支付金鑰(KEY
)‘,所以首先要有一個稽核過的公眾號,並開通支付功能,然後申請商戶,通過稽核後得到商戶號,也就是商戶平臺的登入名。商戶支付金鑰是用來簽名的,確保url
不被篡改。進入商戶平臺後在API安全中設定,是一個32位的字串。
有這三個引數後,還有一點要注意的是交易起始時間和交易結束時間的間隔應該在五分鐘以上2小時以內。不然獲取支付url的時候回報錯。
二、生成支付二維碼
有了上面的引數,接下來就是下載SDK: .net SDK及示例 。
可惜官方的這個示例一開始並不能執行正確。把相關dll
引用MVC目錄下。並建立一個WxPayAPI
資料夾把相關類複製過來。
然後將WxPayConfig
中的相關引數設定成自己的引數,再修改GetPayUrl
方法,
public string GetPayUrl(Order order,string ip)
{
if (order == null)
{
throw new ArgumentNullException("order");
}
var product = order.OrderItems.First();
WxPayData data = new WxPayData();
data.SetValue("appid", WxPayConfig.APPID);
data.SetValue("mch_id", WxPayConfig.MCHID);
// data.SetValue("device_info", "iphone4s");
data.SetValue("nonce_str", WxPayApi.GenerateNonceStr());
data.SetValue("body", product.AttributeDescription);//商品描述
data.SetValue("detail", product.AttributeDescription);//商品描述
data.SetValue("attach", "北京分店");//附加資料
data.SetValue("out_trade_no", order.TradeNumber);//隨機字串
// data.SetValue("total_fee", Convert.ToInt32(order.OrderTotal * 100));//總金額
data.SetValue("total_fee", 1);//總金額
data.SetValue("spbill_create_ip",ip);//總金額
data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始時間
data.SetValue("time_expire", DateTime.Now.AddMinutes(30).ToString("yyyyMMddHHmmss"));//交易結束時間
data.SetValue("goods_tag", "智慧嬰兒床");//商品標記
data.SetValue("notify_url", "http://www.xxxx.com/Checkout/ResultNotify");//通知地址
data.SetValue("trade_type", "NATIVE");//交易型別
data.SetValue("product_id", product.ProductId);//商品ID
data.SetValue("sign", data.MakeSign());//簽名
Logger.Info("獲得簽名" + data.GetValue("sign"));
WxPayData result = WxPayApi.UnifiedOrder(data);//呼叫統一下單介面
Logger.Info(result.ToJson());
string url = result.GetValue("code_url").ToString();//獲得統一下單介面返回的二維碼連結
Logger.Info("pay url:" + url);
return url;
}
TradeNumber
是呼叫WxPayApi.GenerateOutTradeNo()
方法生成的,notify_url
是使用者支付之後微信通知的地址。金額的單位是分
,只能傳int
型或string
型,decimal
需要轉換一下。獲取url
成功後,在負責支付的控制器中建立一個payment
方法。用於顯示二維碼:
public ActionResult Payment(string guid)
{
if(string.IsNullOrEmpty(guid))
throw new ArgumentException("guide");
var order = _orderService.GetOrderByGuid(new Guid(guid));var user = _workContext.CurrentUser;
NativePay nativePay = new NativePay();
string url2 = nativePay.GetPayUrl(order, user.LastIpAddress);
ViewBag.QRCode = "/Checkout/MakeQRCode?data=" + HttpUtility.UrlEncode(url2);
ViewBag.Order = order;
return View();
}
這裡只是返回了一個url
,在頁面上:
<img src="@ViewBag.QRCode" class="qrcode" />
後臺用的qrCodeEncoder
生成二維碼。
public FileResult MakeQRCode(string data)
{
if (string.IsNullOrEmpty(data))
throw new ArgumentException("data");
//初始化二維碼生成工具
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
qrCodeEncoder.QRCodeVersion = 0;
qrCodeEncoder.QRCodeScale = 4;
//將字串生成二維碼圖片
Bitmap image = qrCodeEncoder.Encode(data, Encoding.Default);
//儲存為PNG到記憶體流
MemoryStream ms = new MemoryStream();
image.Save(ms, ImageFormat.Jpeg);
return File(ms.ToArray(), "image/jpeg");
}
成功之後得到支付頁面:
掃碼後跳出支付頁面:
三、回撥
使用者支付之後,微信會給之前預留的介面(介面不能帶引數)發訊息, 網站在收到訊息後進行驗證和確認,確定之後再給微信發一個訊息。詳細引數和文件請看官方API
這裡還是把demo
中的方法稍作改動放到了控制器裡面:
public ActionResult ResultNotify()
{
//接收從微信後臺POST過來的資料
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();
Logger.Info(this.GetType()+ "Receive data from WeChat : " + builder);
//轉換資料格式並驗證簽名
WxPayData data = new WxPayData();
try
{
data.FromXml(builder.ToString());
}
catch (WxPayException ex)
{
//若簽名錯誤,則立即返回結果給微信支付後臺
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());
Response.Write(res.ToXml());
Response.End();
}
Logger.Info(this.GetType()+ "Check sign success");
ProcessNotify(data);
return View();
}
public void ProcessNotify(WxPayData data)
{
WxPayData notifyData = data;
//檢查支付結果中transaction_id是否存在
if (!notifyData.IsSet("transaction_id"))
{
//若transaction_id不存在,則立即返回結果給微信支付後臺
WxPayData res = new WxPayData();
res.SetValue("return_code", "FAIL");
res.SetValue("return_msg", "支付結果中微信訂單號不存在");
Logger.Error(this.GetType()+"The Pay result is error : " + res.ToXml());
Response.Write(res.ToXml());
Response.End();
}
string transaction_id = notifyData.GetValue("transaction_id").ToString();
//查詢訂單,判斷訂單真實性
if (!QueryOrder(transaction_id))
{
//若訂單查詢失敗,則立即返回結果給微信支付後臺
WxPayData res = new WxPayData();
res.SetValue("return_code", "FAIL");
res.SetValue("return_msg", "訂單查詢失敗");
Logger.Error(this.GetType()+"Order query failure : " + res.ToXml());
Response.Write(res.ToXml());
Response.End();
}
//查詢訂單成功
else
{
WxPayData res = new WxPayData();
res.SetValue("return_code", "SUCCESS");
res.SetValue("return_msg", "OK");
Logger.Info(this.GetType()+"order query success : " + res.ToXml());
SetPaymentResult(data.GetValue("out_trade_no").ToString(), PaymentStatus.Paid);
Response.Write(res.ToXml());
Response.End();
}
}
收到確認後,我們要更新訂單的狀態:
public void SetPaymentResult(string tradeno, PaymentStatus status)
{
Logger.Info("訂單號:"+tradeno);
var order = _orderService.GetOrderByTradeNumber(tradeno);
if (order != null)
{
order.PaymentStatus = status;
if (status == PaymentStatus.Paid)
{
order.PaidDate = DateTime.Now;
}
_orderService.UpdateOrder(order);
Logger.Info("訂單:"+tradeno+"成功更新狀態為"+status);
}
}
然後在頁面上檢測訂單的狀態,確定成功後,跳轉頁面。
在商戶平臺的後臺,我們可以查詢到:
小結:主要過程就是這樣,因為不能本地除錯,打日誌除錯比較耗時,希望對你有幫助。接下來研究下退款(需要證照)。
demo 下載:http://files.cnblogs.com/files/stoneniqiu/WXPayDemo.zip
相關文章
- nodejs微信支付之掃碼支付NodeJS
- Android微信掃碼支付Android
- 微信掃碼支付全解析
- Laravel 搞定支付寶和微信掃碼支付Laravel
- 微信支付開發(2) 掃碼支付模式一模式
- 微信支付開發(4)掃碼支付模式二模式
- java實現掃碼槍-微信支付Java
- 微信支付V3 Java jsApi 掃碼支付JavaJSAPI
- Thinkphp5微信掃碼支付例項PHP
- 微信的三種支付方式接入:APP支付、公眾號支付、掃碼支付APP
- ASP.NET Core 2.0 支付寶當面付之掃碼支付ASP.NET
- 第一次使用微信掃碼支付_JavaJava
- Thinkphp5框架整合微信掃碼支付方法PHP框架
- 親身經歷之微信支付沙箱環境掃碼支付遇到的那些坑
- 微信掃碼支付~官方DEMO的坑~引數不能自定義
- ASP.NET CORE微信支付回撥示例程式碼ASP.NET
- 【微信開發筆記】掃碼支付之二維碼的處理筆記
- 整理 PC 端微信掃碼支付全過程 --- easywechat + Laravel 5.8Laravel
- iOS12捷徑掃碼付款怎麼用?蘋果iOS12微信支付寶掃碼支付捷徑設定教程iOS蘋果
- 基於Koa2開發微信二維碼掃碼支付相關流程
- 微信掃碼登入
- 掃碼支付後都發生了啥?
- ASP.NET MVC驗證碼演示ASP.NETMVC
- 微信小程式掃碼解析小程式碼微信小程式
- Python提取支付寶和微信支付二維碼Python
- UnionPay,ChinaPay 最新 銀聯支付介面C#\Asp.net\MVC 版本C#ASP.NETMVC
- php微信掃碼領優惠券PHP
- 淺析微信掃碼登入原理
- PHP對接微信掃碼登入PHP
- 2行程式碼調起微信支付寶支付行程
- asp.net mvc 之旅 —— 第五站 從原始碼中分析asp.net mvc 中的TempDataASP.NETMVC原始碼
- 微信開發 微信支付
- 移動支付新時代——低程式碼如何對接支付寶和微信支付
- 對iOS端支付寶和微信支付程式碼進行整合iOS
- 支付寶收款正式釋出:路邊買茶葉蛋也可掃碼支付
- 微信App支付APP
- PHPcms微信支付PHP
- 聚合二維碼支付代理現在還能做嗎?掃碼支付的前景究竟如何?