. net wechat code scanning payment access (mode 2 – National)

Time:2021-4-10

1、 Preface

After two or three days of deliberation, we have finally completed the wechat code scanning payment function, and we have to sigh a few words:

The demo provided by wechat is good. You can run by copying and pasting directly;
I am really satisfied with the configuration platform of wechat. Public platform, merchant platform, open platform, one platform, one set of account password, in capitals
Demo address:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

The Lib folder in. Net demo is the key. Copy it directly to your own code, or type it as DLL as you wish.

2、 Text

Step 1: the order number of the merchant must be generated and sent to the background of wechat. Wechat will form a two-dimensional code string and return it to you. Then you can make the string into a picture;

/// <summary>
 ///Get QR code
 /// </summary>
 /// <param name="orderNumber"></param>
 /// <returns></returns>
 public string GetCodeUrl(string orderNumber)
 {
  var result = string.Empty;
  if (!string.IsNullOrEmpty(orderNumber))
  {
  var matchedItem = db.OrderInfoForProducts.FirstOrDefault(x => x.OrderNumber == orderNumber);
  if (matchedItem != null && matchedItem.IsPaid == false)
  {
   WxPayData data = new WxPayData();
   data.SetValue ("body", "productbody"); // product description
   data.SetValue ("attach", "attach data"); // attach data
   data.SetValue ("out_ trade_ no",  WxPayApi.GenerateOutTradeNo ()); // random string
   data.SetValue ("total_ Fee ", price); // total amount
   data.SetValue ("time_ start",  DateTime.Now.ToString ("yyyymmddhhmmss"); // transaction start time
   data.SetValue ("time_ expire",  DateTime.Now.AddMinutes (10) . toString ("yyyymmddhhmmss"); // transaction end time
   data.SetValue ("goods_ Tag "," tag "); // product tag
   data.SetValue ("trade_ // transaction type
   data.SetValue ("product_ id",  WxPayApi.GenerateOutTradeNo ()); // product ID
   result =  WxPayApi.UnifiedOrder (data).GetValue("code_ URL "). Tostring(); // call the unified ordering interface
  }
  }
  return result;
 }

Here, I put the company’s merchant order number in the attach field, because the company’s merchant order number is longer than 32 digits. out_ trade_ No and product_ ID field up to 32 bits, please be careful!

The price in wechat can’t take decimal, so 0.01 yuan should be written as 100.

Step 2: after successfully returning the QR code string, you can generate the image, which I use here ThoughtWorks.QRCode.dll To generate images:

/// <summary>
 ///Get the corresponding two-dimensional code according to the string
 /// </summary>
 /// <param name="qrInfo"></param>
 /// <param name="productName"></param>
 /// <param name="version"></param>
 /// <returns></returns>
 public static Image CreateQRCodeImage(string qrInfo, string productName, string version)
 {
  try
  {
  if (!string.IsNullOrEmpty(qrInfo))
  {
   QRCodeEncoder encoder = new QRCodeEncoder
   {
   QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE,
   QRCodeScale = 4,
   QRCodeVersion = 0,
   QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M
   };
   //Note: byte can support Chinese, alpha_ Numeric scans all numbers)
   //Size (the larger the value, the higher the pixels of the generated QR code image)
   //Version (Note: setting to 0 is mainly to prevent errors when the encoded string is too long)
   //Error validation, error correction (4 levels)

   Image image = encoder.Encode(qrInfo, Encoding.GetEncoding("utf-8"));
   string filename = $"{productName}_{version}.png";
   var userLocalPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
   var docPath = Path.Combine(userLocalPath, @"Your Product\QRCode");
   if (!Directory.Exists(docPath))
   {
   Directory.CreateDirectory(docPath);
   }
   string filepath = Path.Combine(docPath, filename); 
   using (FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write))
   {
   image.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
   fs.Close();
   image.Dispose();
   }
   return image;
  }
  }
  catch (Exception)
  {
  return null;
  }
  return null;
 }

Step 3: after the user scans the QR code, wechat will launch a callback, and then we can handle our own business logic. Here my updatepaystatus returns an empty page

/// <summary>
 ///Callback function
 /// </summary>
 public ActionResult UpdatePayStatus()
 {
  //Receiving data from wechat background post
  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();

  //Convert data format and verify signature
  WxPayData data = new WxPayData();
  try
  {
  data.FromXml(builder.ToString());
  }
  catch (WxPayException ex)
  {
  //If the signature is wrong, the result will be returned to wechat payment background immediately
  WxPayData res = new WxPayData();
  res.SetValue("return_code", "FAIL");
  res.SetValue("return_msg", ex.Message);

  LogEntity signErrorLog = new LogEntity();
  signErrorLog.errorMessage = ex.Message;
  LogHelper.WriteLog(signErrorLog, null);

  Response.Write(res.ToXml());
  Response.End();
  }

  ProcessNotify(data);  
  return View();
 }


 /// <summary>
 ///Processing callback data
 /// </summary>
 /// <param name="data"></param>
 public void ProcessNotify(WxPayData data)
 {
  WxPayData notifyData = data;
  //Check the transaction in the payment result_ Does ID exist
  if (!notifyData.IsSet("transaction_id"))
  {
  //If transaction_ If Id does not exist, the result will be returned to wechat payment background immediately
  WxPayData res = new WxPayData();
  res.SetValue("return_code", "FAIL");
  res.SetValue ("return_ The wechat order number does not exist in the payment result);

  LogEntity orderLog = new LogEntity();
  orderLog.errorMessage  ="The wechat order number does not exist in the payment result";
  LogHelper.WriteLog(orderLog, null);

  Response.Write(res.ToXml());
  Response.End();
  }

  string transaction_id = notifyData.GetValue("transaction_id").ToString();

  //Query the order and judge the authenticity of the order
  if (!QueryOrder(transaction_id))
  {
  //If the order query fails, the result will be returned to wechat payment background immediately
  WxPayData res = new WxPayData();
  res.SetValue("return_code", "FAIL");
  res.SetValue ("return_ MSG "," order query failed ");

  LogEntity orderqueryLog = new LogEntity();
  orderqueryLog.errorMessage  ="Order query failed";
  LogHelper.WriteLog(orderqueryLog, null);

  Response.Write(res.ToXml());
  Response.End();
  }
  //Order inquiry successful
  else
  {
  WxPayData res = new WxPayData();
  res.SetValue("return_code", "SUCCESS");
  res.SetValue("return_msg", "OK");

  Setpaymentresult (data); // the parameter here is data!!! Not res!!!

  Response.Write(res.ToXml());
  Response.End();
  }
 }

 /// <summary>
 ///Merchant background update
 /// </summary>
 /// <param name="res"></param>
 private void SetPaymentResult(WxPayData res)
 {
  var isSucessFlagOne = res.GetValue("return_code").ToString();
  var isSuccessFlagTwo = res.GetValue("result_code").ToString();
  
  if (isSucessFlagOne == "SUCCESS" && isSuccessFlagTwo == "SUCCESS")
  {
  //Own business logic!!!!
  }
 }

 //Order inquiry
 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;
  }
 }

3、 End

After completing the Alipay and WeChat scan code payment, it is found that Alipay’s access is much more convenient than WeChat, and there is a synchronous request. And make complaints about other platforms. The approval rate of WeChat’s open platform is much slower than that of Alipay. In addition, wechat payment doesn’t have to use sandbox test before it goes online. After it is finished, it can be tested every cent.

The above is the whole content of this article, I hope to help you learn, and I hope you can support developer more.

Recommended Today

Review of SQL Sever basic command

catalogue preface Installation of virtual machine Commands and operations Basic command syntax Case sensitive SQL keyword and function name Column and Index Names alias Too long to see? Space Database connection Connection of SSMS Connection of command line Database operation establish delete constraint integrity constraint Common constraints NOT NULL UNIQUE PRIMARY KEY FOREIGN KEY DEFAULT […]