微信掃碼支付(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
- Laravel 搞定支付寶和微信掃碼支付Laravel
- 微信支付V3 Java jsApi 掃碼支付JavaJSAPI
- java實現掃碼槍-微信支付Java
- Thinkphp5微信掃碼支付例項PHP
- ASP.NET CORE微信支付回撥示例程式碼ASP.NET
- Thinkphp5框架整合微信掃碼支付方法PHP框架
- 整理 PC 端微信掃碼支付全過程 --- easywechat + Laravel 5.8Laravel
- 騰訊等關聯公司涉及“微信掃碼支付”侵權
- 親身經歷之微信支付沙箱環境掃碼支付遇到的那些坑
- 微信掃碼登入
- 基於Koa2開發微信二維碼掃碼支付相關流程
- iOS12捷徑掃碼付款怎麼用?蘋果iOS12微信支付寶掃碼支付捷徑設定教程iOS蘋果
- 微信支付,支付寶支付
- Python提取支付寶和微信支付二維碼Python
- 微信小程式掃碼解析小程式碼微信小程式
- 支付寶、微信支付(.NET)
- 關於微信支付,支付寶支付
- 淺析微信掃碼登入原理
- PHP對接微信掃碼登入PHP
- php微信掃碼領優惠券PHP
- 微信JSAPI支付JSAPI
- 微信App支付APP
- 支付寶微信合單支付
- 支付寶、微信支付收款碼禁止商用系誤讀NL
- SpringBoot微信掃碼登入(小程式版)Spring Boot
- 微信授權(Net Mvc)MVC
- 微信、支付寶支付那點事
- PHP-Laravel支付寶支付和微信支付PHPLaravel
- 對iOS端支付寶和微信支付程式碼進行整合iOS
- 微信開發超市全反系統,微信支付刷卡支付,微信介面簡單配置!
- .Net微信網頁開發之使用微信JS-SDK呼叫微信掃一掃功能網頁JS
- 微信支付團隊釋出“微信青蛙pro” 支援刷臉支付功能
- Android 微信支付 微信是否安裝判斷Android
- 移動支付新時代——低程式碼如何對接支付寶和微信支付
- 微信小程式之支付微信小程式
- PHP微信支付開發PHP
- 微信jsapi支付 退款介面JSAPI