Scan code payment (PC end), pc
Here, the scan code payment refers to the use of payment on the PC website, that is, the official mode 2. The website is Asp.net MVC, which is organized as follows. (The demo is at the bottom)
I. Preparations
The key parameter for the unified order method in the API used is'Public account ID (appid) ', 'Merchant ID (mch_id)', and 'Merchant payment KEY (KEY )',Therefore, you must first have a public account that has been reviewed, activate the payment function, and then apply for the merchant. After the account passes the review, you will get the merchant ID, that is, the login name of the merchant platform. The merchant's payment key is used for signature, so that the url is not tampered. After entering the merchant platform, set it in API security to a 32-Bit String.
Note the following when you have these three parameters:Transaction Start TimeAndTransaction End TimeThe interval should be five minutes or more than two hours. Otherwise, an error is returned when you get the payment url.
Ii. Generate payment QR code
With the above parameters, download the SDK:. net SDK and the example.
Unfortunately, the official example does not run correctly at the beginning. Reference the related dll to the MVC directory. Create a WxPayAPI folder to copy the related classes.
ThenWxPayConfigAnd then modify the GetPayUrl method,
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); // product description data. setValue ("detail", product. attributeDescription); // product description data. setValue ("attach", "Beijing Branch"); // additional data. setValue ("out_trade_no", order. tradeNumber); // random string // data. setValue ("total_fee", Convert. toInt32 (order. orderTotal * 100); // total data. setValue ("total_fee", 1); // total data. setValue ("spbill_create_ip", ip); // total data. setValue ("time_start", DateTime. now. toString ("yyyyMMddHHmmss"); // transaction start time data. setValue ("time_expire", DateTime. now. addMinutes (30 ). toString ("yyyyMMddHHmmss"); // transaction end time data. setValue ("goods_tag", "smart crib"); // product tag data. setValue ("policy_url "," http://www.xxxx.com/Checkout/ResultNotify "); // Notification address data. setValue ("trade_type", "NATIVE"); // transaction type data. setValue ("product_id", product. productId); // product ID data. setValue ("sign", data. makeSign (); // sign Logger. info ("Get signature" + data. getValue ("sign"); WxPayData result = WxPayApi. unifiedOrder (data); // call the unified order interface Logger. info (result. toJson (); string url = result. getValue ("code_url "). toString (); // obtain the QR code link Logger returned by the unified order interface. info ("pay url:" + url); return url ;}
TradeNumber is generated by calling the WxPayApi. GenerateOutTradeNo () method, and yy_url is the address of the notification after the user pays. The unit of the amount is minute. Only int or string type can be passed. decimal needs to be converted. After obtaining the url, create a payment method in the Controller that is responsible for the payment. Used to display the QR code:
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(); }
Here, we only return a url on the page:
The backend uses qrCodeEncoder to generate a QR code.
Public FileResult MakeQRCode (string data) {if (string. isNullOrEmpty (data) throw new ArgumentException ("data"); // initialize the QR code generation tool QRCodeEncoder qrCodeEncoder = new QRCodeEncoder (); qrCodeEncoder. QRCodeEncodeMode = QRCodeEncoder. ENCODE_MODE.BYTE; qrCodeEncoder. QRCodeErrorCorrect = QRCodeEncoder. ERROR_CORRECTION.M; qrCodeEncoder. QRCodeVersion = 0; qrCodeEncoder. QRCodeScale = 4; // generate the string to the QR code image Bitmap image = qrCodeEncoder. encode (data, Encoding. default); // Save As PNG to memory stream MemoryStream MS = new MemoryStream (); image. save (MS, ImageFormat. jpeg); return File (ms. toArray (), "image/jpeg ");}
After the payment is successful, the payment page is displayed:
The payment page is displayed after scanning:
Iii. Callback
After payment, the user sends a message to the previously reserved interface (the interface cannot contain parameters). The website verifies and confirms the message after receiving the message, and then sends a message after confirmation. For detailed parameters and documentation, see the official API
Here, the method in the demo is slightly changed to the Controller:
Public ActionResult ResultNotify () {// receives the data Stream s = Request from the background POST. 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); // convert the data format and Verify the signature WxPayData data = new WxPayData (); try {data. fromXml (builder. toString ();} catch (WxPayException ex) {// if the signature is incorrect, the result is immediately returned to the payment background 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 sig N success "); ProcessNotify (data); return View ();} public void ProcessNotify (WxPayData data) {WxPayData policydata = data; // check whether transaction_id exists in the payment result if (! Yydata. isSet ("transaction_id") {// If transaction_id does not exist, return the result immediately to the payment background WxPayData res = new WxPayData (); res. setValue ("return_code", "FAIL"); res. setValue ("return_msg", "the order number does not exist in the payment result"); Logger. error (this. getType () + "The Pay result is error:" + res. toXml (); Response. write (res. toXml (); Response. end ();} string transaction_id = policydata. getValue ("transaction_id "). toString (); // query the order and determine the order authenticity if (! QueryOrder (transaction_id) {// if the order query fails, the result is immediately returned to the payment background WxPayData res = new WxPayData (); res. setValue ("return_code", "FAIL"); res. setValue ("return_msg", "Order query failed"); 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 ();}}
After receiving the confirmation, we want to update the order status:
Public void SetPaymentResult (string tradeno, PaymentStatus status) {Logger. Info ("order Number:" + 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 ("order:" + tradeno + "successfully updated to" + status );}}
Then, check the order status on the page. After confirming that the order is successful, go to the page.
In the background of the merchant platform, we can query:
Summary: This is the main process. because local debugging is not supported, it takes a long time to debug logs. I hope it will be helpful to you. Next we will study the refund (certificate required ).
Demo download: http://wd.jb51.net: 81 // 201701/yuanma/WXPayDemo_jb51.rar
The above is all the content of this article. I hope this article will help you in your study or work. I also hope to provide more support to the customer's home!