During the development of WeChat JS-SDK, getLocation is used to obtain coordinate positions. How to directly apply the coordinates obtained by WeChat to Baidu map, displaying the following effects:
Note: The red icon is the position converted from WeChat, and the blue icon is the position around it. First, let’s explain it from the WeChat development process.
1. WeChat JS-SDK development document
First, enter the help document on the official website: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
You can study the document in detail. To obtain location information, the following steps are divided into the following steps:
Step 1: Bind the domain name
Enter the WeChat official account, find the "Official Account Settings" menu, and enter the "Function Settings" panel.
Click "Settings" to set the relevant domain name that references js:
Step 2: Quoting the official js class library
Introduce the following JS file on the page that needs to call the JS interface (support https): http://res.wx.qq.com/open/js/jweixin-1.0.0.js.
The referenced page is location.aspx, as follows:
<%@ Page Title="Get Location" Language="C#" AutoEventWireup="true" MasterPageFile="~/wxcrm/Site.Master" CodeFile="location.aspx.cs" Inherits="DTcms.Web.wxcrm.location" %><asp:Content ID="Content1" ContentPlaceHolderID="cphHead" runat="server"> <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script type="text/javascript"> $("#mask").show(); wx.config({ debug: false, //Open debug mode, if true, each js function call will pop up appId: '<%= ResultJsData.GetValue("appid") %>', //Required, the unique identifier of the official account timestamp: <%= ResultJsData.GetValue("timestamp") %>, //Required, generate the signature timestamp nonceStr: '<%= ResultJsData.GetValue("noncestr") %>', //Required, generate the signature random string signature: '<%= ResultJsData.GetValue("signature") %>', //Required, signature jsApiList: [ 'checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'hideMenuItems', 'showMenuItems', 'hideAllNonBaseMenuItems', 'showAllNonBaseMenuItems', 'showAllNonBaseMenuItems', 'showAllNonBaseMenuItems', 'translateVoice', 'startRecord', 'stopRecord', 'onRecordEnd', 'playVoice', 'pauseVoice', 'stopVoice', 'uploadVoice', 'downloadVoice', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'getNetworkType', 'openLocation', 'getLocation', 'hideOptionMenu', 'showOptionMenu', 'closeWindow', 'scanQRCode', 'chooseWXPay', 'openProductSpecificView', 'addCard', 'chooseCard', 'openCard' ] }); wx.ready(function(){ wx.checkJsApi({ jsApiList: [ 'getNetworkType', 'previewImage', 'getLocation' ], success: function (res) { } }); wx.getLocation({ type: 'wgs84', // The default is the gps coordinate of wgs84. If you want to return the Mars coordinates used directly to openLocation, you can pass in 'gcj02' success: function (res) { try { var latitude = res.latitude; // Latitude, floating point number, range is 90 ~ -90 var longitude = res.longitude; // longitude, floating point number, range is 180 ~ -180. var speed = res.speed; // speed, measured in meters/per second var accuracy = res.accuracy; // position accuracy // aalert(JsonUti.convertToString(res)); // wx.openLocation({ // latitude: res.latitude, // latitude, floating point number, range is 90 ~ -90 // longitude: res.longitude, // longitude, floating point number, range is 180 ~ -180. // name: 'Current position', // position name// address: 'Click to view', // address details// scale: 28, // Map zoom level, shaping value, range from 1 to 28. The default is maximum // infoUrl: "location1.aspx?m=Home&c=Index&a=getlocation&latitude="+latitude+"&longitude="+longitude // The hyperlink displayed at the bottom of the viewing location interface can be clicked to jump //}); //alert(latitude+"-"+longitude); $("#mask").hide(); window.location.href = "location1.aspx?m=Home&c=Index&a=getlocation&latitude=" + latitude + "&longitude=" + longitude + "&=speed" + speed + "&accuracy=" + accuracy; } catch (e) { alert(e.message); } }, cancel: function (res) { window.location.href="none.aspx?msg=Reject to get the geographic location&r=" + Math.random();//Reject}, fail:function() { alert("Failed to get the geographic location! First check whether the phone is enabled for WeChat location."); } }); }); wx.error(function(res) { // config information verification failure will execute an error function. If the signature expires, the verification will fail. For specific error messages, you can open the debug mode of config, or view it in the returned res parameter. The signature can be updated here for SPA. }); wx.fail(function(res) { }); </script></asp:Content><asp:Content ID="Content2" ContentPlaceHolderID="cphTitle" runat="server"> Get the location</asp:Content><asp:Content ID="Content3" ContentPlaceHolderID="cphContainer" runat="server"> <br /> <br /> <center style="display: block;"> <i></i> <div> Getting geographic location information... </div> </center> <div style="display: none;"> <span> <img src="/templates/txwap/images/mask.gif" /> </span> </div></asp:Content>Page effect:
Notes:
(1) If the mobile phone settings do not allow WeChat to obtain location information, the above information will be prompted.
(2) The parameters in the figure above obtain the GPS coordinates. If you use Baidu map, you need to make a certain conversion and will be reflected in location1.aspx.
(3) All pages that require JS-SDK must be injected with configuration information first, otherwise they will not be called.
Corresponding location.aspx.cs implementation:
using Payment.WxWebHlper;using Payment.WxWebHlper.Actions;using System;using System.Globalization;using WxJsSDK;using WxPayAPI;namespace DTcms.Web.wxcrm{ public partial class location : PageBase { protected string appId { get; set; } protected string timestamp { get; set; } protected string nonceStr { get; set; } protected string signature { get; set; } public static string WxJsApiParam { get; set; } public WxJsData ResultJsData { get; set; } protected void Page_Load(object sender, EventArgs e) { JudgeCode(); var webAuthorize = new WebAuthorizeAction(); Code2TokenResult = webAuthorize.Code2Token(Request["code"]); if (Code2TokenResult.HasError()) { Response.Redirect(Urls.PageOfLocation); GotoNonePage("Failed to obtain user credentials, please re-get"); return; } GetUserInfoResult = webAuthorize.GetUserInfo(Code2TokenResult.access_token); if (GetUserInfoResult.HasError()) { GotoNonePage("Failed to obtain user information, please re-get"); } var userid = wxOperation.HasBind(GetUserInfoResult.openid); if (userid.Equals(Guid.Empty)) { Response.Redirect(Urls.Oauth2Url); GotoNonePage("WeChat user not bound"); } appId = WxPayConfig.APPID; timestamp = WxPayApi.GenerateTimeStamp(); nonceStr = WxPayApi.GenerateNonceStr(); //The following implementation will be reflected in 3. The core code implementation var jsApi = new JsApi(this); ResultJsData = jsApi.GetJsData(); WxJsApiParam = jsApi.GetJsApiParameters();//Get H5 to tune JS API parameters} }}2. Convert WeChat GPS coordinates to Baidu coordinates
After WeChat successfully obtains coordinates, the page will automatically jump to location1.aspx, and the processing flow is as follows:
WeChat coordinates -> Convert to Baidu map coordinates -> Obtain location information according to Baidu map API -> Display coordinates according to Baidu map API
<%@ Page Title="Online Check-in" Language="C#" MasterPageFile="~/wxcrm/Site.Master" AutoEventWireup="true" CodeFile="location1.aspx.cs" Inherits="DTcms.Web.wxcrm.location1" %><asp:Content ID="Content1" ContentPlaceHolderID="cphHead" runat="server"> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css"> #allmap { width: 100%; height: 300px; } </style> <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=dhRLKMR9QUO4wHmnnSZTarta"></script> <script type="text/javascript"> //GPS coordinate var yy = <%= this.Request["longitude"] %>; //Longitude, floating point number, range is 180 ~ -180. var xx = <%= this.Request["latitude"] %>; //latitude, floating point number, range is 90 ~ -90 var gpsPoint = new BMap.Point(xx,yy); var bxx = 0.0; var byy = 0.0; /* * http://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition */ var PositionUrl = "http://api.map.baidu.com/geoconv/v1/?"; function changePosition(){ var str = "coords="+yy+","+xx+"&from=1&to=5"; var url = PositionUrl + str; $("#positionUrl").html(url+"&ak=dhRLKMR9QUO4wHmnnSZTartg"); var script = document.createElement('script'); script.src = url + '&ak=dhRLKMR9QUO4wHmnnSZTarta&callback=dealResult'; document.getElementsByTagName("head")[0].appendChild(script); } function dealResult(msg){ if(msg.status != 0){ alert("No correct return result."); $("#mask").hide(); return; } //JsonUti.convertToString(msg); bxx = msg.result[0].x; byy = msg.result[0].y; doOptions(); } function getBaiduPosition() { var url ="http://api.map.baidu.com/geoconv/v1/?coords="+yy+","+xx+"&from=1&to=5&ak=dhRLKMR9QUO4wHmnnSZTarta"; $.ajax({ url: url, success: function(data,status,xhr) { alert(status); alert(data.status); }, dataType: json }); } var ADVANCED_POST = ''; var advancedOptions = ''; var address; var map; function renderOption(response) { var html = ''; if (response.status ) { $("#mask").hide(); var text = "No correct return result!"; alert(text); return; } var result = response.result; var location = response.result.location; var uri = 'http://api.map.baidu.com/marker?location='+ location.lat+','+location.lng +'&title='+response.result.level+'&content='+address+'&output=html'; var staticimageUrl = "http://api.map.baidu.com/staticimage?center=" + location.lng+','+location.lat + "&markers=" + location.lng+','+location.lat; html = '<p>Coordinates: Latitude: ' + location.lat + " Longitude: " + location.lng+'<br />'; html += 'Precision: '+response.result.precise+'<br />' ; html += 'Currency: '+response.result.confidence +'<br />'; html += 'Address type: '+response.result.level+'</p>' ; html += '<p><img src="' + staticimageUrl + '" /></p>' ; html += '<p>Share this point: <a href="' + uri + '" target="_blank">' + uri + '</a></p>'; //Set this link to clickable // Baidu Map API function map = new BMap.Map("allmap"); var point = new BMap.Point(bxx, byy); var marker = new BMap.Marker(point); // Create annotation map.addOverlay(marker); // Add annotation to the map map.centerAndZoom(point, 100); var opts = { width: 200, // Information window width height: 100, // Information window height title: "My position", // Information window title enableMessage: true,//Set allow information window to send short messages message: result.formatted_address } $("#divPo").html("Current location: " + result.formatted_address); var infoWindow = new BMap.InfoWindow(result.formatted_address, opts); // Create information window object marker.addEventListener("click", function () { map.openInfoWindow(infoWindow, point); // Open the information window}); var myIcon = new BMap.Icon("http://api.map.baidu.com/img/markers.png", new BMap.Size(23, 25), { offset: new BMap.Size(10, 25), // Specify the positioning position imageOffset: new BMap.Size(0, 0 - 10 * 25) // Set image offset}); var pois = result.pois; for(var i=0;i<pois.length;i++){ var marker = new BMap.Marker(new BMap.Point(pois[i].point.x,pois[i].point.y),{icon:myIcon}); // Create annotation var name = pois[i].name; var addr = pois[i].addr; map.addOverlay(marker); // Add annotation to the map addClickHandler(name,addr,marker); } $("#mask").hide(); $("#btnSign").show(); return; } function addClickHandler(name,addr,marker){ marker.addEventListener("click",function(e){ openInfo(name,addr,e)} ); } function openInfo(name,addr,e){ var p = e.target; var point = new BMap.Point(p.getPosition().lng, p.getPosition().lat); var opts = { width: 200, // Information window width height: 100, // Information window height title: name, // Information window title enableMessage: true,//Set allow the information window to send short messages message: addr } var infoWindow = new BMap.InfoWindow(addr,opts); // Create the information window object map.openInfoWindow(infoWindow,point); // Open the information window} function doOptions() { var script = document.createElement('script'); script.type = 'text/javascript'; ADVANCED_POST ="http://api.map.baidu.com/geocoder/v2/?ak=dhRLKMR9QUO4wHmnnSZTartg&callback=renderOption&location=" + byy + ","+bxx+ "&output=json&pois=2"; script.src = ADVANCED_POST; document.body.appendChild(script); }; $(function () { $("#mask").show(); $("#btnSign").hide(); changePosition(); }); </script></asp:Content><asp:Content ID="Content2" ContentPlaceHolderID="cphTitle" runat="server"> Online check-in</asp:Content><asp:Content ID="Content3" ContentPlaceHolderID="cphContainer" runat="server"> <form id="frmLocation" runat="server"> <div> <div><span>Location information</span></div> <div style="padding-left: 0"> <ul style="height: 300px;"> <div id="allmap"></div> </ul> </div> <div style="padding-left: 0"> <ul> <div id="divPo"></div> </ul> </div> </div> </div> <div style="text-align: center; margin-top: -50px;"> <input id="btnSign" type="button" value="I want to check in" style="cursor: pointer; width: 210px; height: 50px; border-radius: 15px; background-color: #00CD00; border: 0px #FE6714 solid; cursor: pointer; color: white; font-size: 16px;" /> </div> <div style="display: none;"> <span> <img src="/templates/txwap/images/mask.gif" /> </span> </div> </form></asp:Content>This page mainly involves Baidu Map open platform, and you need to apply for Baidu Map ag. Otherwise, calling js will prompt: The APP does not exist, if there is any error in AK, please recheck and try again.
(1) Baidu Map Technology 1: Coordinate Conversion API
Official website address: http://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition
API service address: http://api.map.baidu.com/geoconv/v1/?
The document has detailed descriptions, so I won't repeat them.
(2) Baidu Map Technology 2: Obtain location based on coordinates
Official website: http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
The Geocoding API includes address resolution and inverse address resolution functions:
Geographic encoding: that is, address analysis, and Baidu latitude and longitude information is obtained from the detailed structured address of the street. For example, the address analysis result of "No. 27, Zhongguancun South Street, Haidian District, Beijing" is "lng:116.31985, lat:39.959836". At the same time, geocoding also supports direct resolution of places, historical sites and landmark buildings and return to Baidu latitude and longitude. For example, the result of the address analysis of "Baidu Building" is "lng:116.30815, lat:40.056885". It is a common POI retrieval requirement, and it is recommended to use Place API.
Inverse geocoding: that is, inverse address analysis, and structured address information is obtained from Baidu latitude and longitude information. For example, "lat:31.325152, lng:120.558957" The result of inverse address analysis is "No. 318, Tayuan Road, Huqiu District, Suzhou City, Jiangsu Province".
API service address: http://api.map.baidu.com/geocoder/v2/
For specific parameters, please check the official documentation.
Example: http://api.map.baidu.com/geocoder/v2/?ak=Appliced for Baidu KEY&location=34.79563,114.23075222912&callback=showLocation&output=xml&pois=1
Notes:
(1) Baidu Developer Key Application
(2) Baidu map coordinate system is different from WeChat coordinate system
(3) API call address and parameter description
(4) The meaning of api callback function
(5) Understand the meaning of json and jsonp
3. WeChat JS-SDK core code
(1) JsAPI.cs generates relevant JS-SDK configuration parameters
using System;using System.Globalization;using System.Linq;using System.Web.Security;using System.Web.UI;using WxPayAPI;namespace WxJsSDK{ public class JsApi { /// <summary> /// Save the page object because you want to use the Page's Request object in the class's method/// </summary> private Page page { get; set; } public WxJsData ResultJsData { get; set; } /// <summary> /// // </summary> /// <param name="page"></param> public JsApi(Page page) { this.page = page; } public WxJsData GetJsData() { var data = new WxJsData(); data.SetValue("appid", WxPayConfig.APPID);//Public account ID data.SetValue("timestamp", WxPayApi.GenerateTimeStamp()); data.SetValue("noncestr", WxPayApi.GenerateNonceStr());//Random string var url = GetUrl(); data.SetValue("url", url); var jsToken = GetJsApiTicket(); data.SetValue("jsapi_ticket", jsToken); var signature = MakeSignature(jsToken, data.GetValue("noncestr").ToString(), data.GetValue("timestamp").ToString(), url); data.SetValue("signature", signature); ResultJsData = data; return data; } private string MakeSignature(string jsapiTicket, string noncestr, string timestamp, string url) { string[] arrayList = { "jsapi_ticket=" + jsapiTicket, "timestamp=" + timestamp, "noncestr=" + noncestr, "url=" + url }; Array.Sort(arrayList); var signature = string.Join("&", arrayList); signature = FormsAuthentication.HashPasswordForStoringInConfigFile(signature, "SHA1").ToLower(); return signature; } private string GetJsApiTicket() { var jsAuth = new JsAuthorizeAction(); var token = jsAuth.GetToken(); var nd = DateTime.Now - token.CreateDate; Log.Error(this.GetType().ToString(), token.access_token); Log.Error(this.GetType().ToString(), token.IsValid().ToString()); if (token.IsValid()) return jsAuth.GetJsApiTicket(token.access_token).ticket; return ""; } private string GetUrl() { string host = page.Request.Url.Host; string path = page.Request.Path; string queryString = page.Request.Url.Query; //This place should be noted that the complete url passed back to the WeChat background when the web page authorizes to obtain user information string url = "http://" + host + path + queryString; return url; } public string GetJsApiParameters() { Log.Debug(this.GetType().ToString(), "JsApi ::GetJsApiParam is processing..."); string parameters = ResultJsData.ToJson(); Log.Debug(this.GetType().ToString(), "Get JsApi : " + parameters); return parameters; } }}(2) JsAuthorizeAction.csWeChat JS-SDK related API call function
using Payment.WxWebHlper; using Payment.WxWebHlper.Results; using System; using WxPayAPI;namespace WxJsSDK{ public class JsAuthorizeAction { private static TokenResult Token = new TokenResult() { errcode = -1 }; private static JsApiTicketResult JsApiTicket = new JsApiTicketResult() { errcode = -1 }; public TokenResult GetToken() { Log.Error(this.GetType().ToString(), "GetToken"); if (!Token.IsValid()) { Token = GeTokenResult(); Log.Error(this.GetType().ToString(), Token.ToString()); } return Token; } /// <summary> /// // // </summary> /// <returns></returns> public TokenResult GeTokenResult() { var result = new TokenResult(); try { var webUtils = new WebUtils(); var url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", WxPayConfig.APPID, WxPayConfig.APPSECRET); var strRtn = webUtils.Get(url); result = Tools.JsonStringToObj<TokenResult>(strRtn); } catch (Exception ex) { Log.Error(this.GetType().ToString(), ex.Message); result = new TokenResult() { errcode = -1086 }; } return result; } /// <summary> /// // // </summary> /// <param name="token"></param> /// <returns></returns> public JsApiTicketResult GetJsApiTicket(string token) { Log.Error(this.GetType().ToString(), "GetJsApiTicket passed token:" + token); if (!JsApiTicket.IsValid()) { JsApiTicket = GetJsApiTicketResult(token); } return JsApiTicket; } /// <summary> /// // // </summary> /// <param name="token"></param> /// <returns></returns> public JsApiTicketResult GetJsApiTicketResult(string token) { JsApiTicketResult result; try { var webUtils = new WebUtils(); var url = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi", token); var strRtn = webUtils.Get(url); result = Tools.JsonStringToObj<JsApiTicketResult>(strRtn); } catch (Exception ex) { Log.Error(this.GetType().ToString(), ex.Message); result = new JsApiTicketResult() { errcode = -1086 }; } return result; } } public class JsApiTicketResult : ReturnResult { /// <summary> /// Constructor/// </summary> public JsApiTicketResult() { CreateDate = DateTime.Now; } /// <summary> /// // // </summary> public string ticket { get; set; } /// <summary> //// access_token interface call credential timeout, unit (seconds) /// </summary> public int expires_in { get; set; } /// <summary> //// Creation time//// </summary> public DateTime CreateDate { get; set; } /// <summary> /// Determine whether it is valid//// </summary> /// <returns></returns> public bool IsValid() { if (this.errcode != 0) return false; var nd = DateTime.Now - CreateDate; return nd.Seconds < 7200; } } public class TokenResult : ReturnResult { /// <summary> /// Constructor/// </summary> public TokenResult() { CreateDate = DateTime.Now; } /// <summary> /// The web authorization interface calls the credentials, note: this access_token is different from the access_token supported by the basics/// </summary> public string access_token { get; set; } /// <summary> //// The access_token interface call credentials timeout time, unit (seconds) /// </summary> public int expires_in { get; set; } /// <summary> /// Creation time//// </summary> public DateTime CreateDate { get; set; } /// <summary> /// Determine whether it is valid//// </summary> /// <returns></returns> public bool IsValid() { if (this.errcode != 0) return false; var nd = DateTime.Now - CreateDate; return nd.Seconds < 7200; } }}(3) WxJsData.cs WeChat JS-SDK parameter class
using LitJson; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; using System.Xml; using WxPayAPI;namespace WxJsSDK{ public class WxJsData { private SortedDictionary<string, object> m_values = new SortedDictionary<string, object>(); /** * Set the value of a certain field* @param key Field name* @param value Field value*/ public void SetValue(string key, object value) { m_values[key] = value; } /** * Get the value of a certain field based on the field name* @param key Field name* @return Field value corresponding to the key*/ public object GetValue(string key) { object o = null; m_values.TryGetValue(key, out o); return o; } /** * Determine whether a field has been set* @param key Field name* @return Return If the field key has been set, return true, otherwise false */ public bool IsSet(string key) { object o = null; m_values.TryGetValue(key, out o); if (null != o) return true; return false; } /** * @Convert Dictionary to xml * @return The converted xml string* @throws WxPayException **/ public string ToXml() { //It cannot be converted to xml format if (0 == m_values.Count) { Log.Error(this.GetType().ToString(), "WxPayData data is empty!"); throw new WxPayException("WxPayData data is empty!"); } string xml = "<xml>"; foreach (KeyValuePair<string, object> pair in m_values) { //The field value cannot be null, which will affect the subsequent process if (pair.Value == null) { Log.Error(this.GetType().ToString(), "WxPayData contains fields with value null!"); throw new WxPayException("WxPayData contains fields with value null!"); } if (pair.Value.GetType() == typeof(int) || pair.Value.GetType() == typeof(decimal)) { xml += "<" + pair.Key + ">" + pair.Value.ToString() + "</" + pair.Key + ">"; } else if (pair.Value.GetType() == typeof(string)) { xml += "<" + pair.Key + ">" + "<![CDATA[" + pair.Value + "]]></" + pair.Key + ">"; } else// Except for string and int types, you cannot contain other data types { Log.Error(this.GetType().ToString(), "WxPayData field data type error!"); throw new WxPayException("WxPayData field data type error!"); } } xml += "</xml>"; return xml; } /** * @Convert xml to WxPayData object and return data inside the object* @param string xml to be converted* @return Dictionary obtained by conversion * @throws WxPayException */ public SortedDictionary<string, object> FromXml(string xml) { if (string.IsNullOrEmpty(xml)) { Log.Error(this.GetType().ToString(), "It is not legal to convert an empty xml string to WxPayData!"); throw new WxPayException("It is not legal to convert an empty xml string to WxPayData!"); } XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xml); XmlNode xmlNode = xmlDoc.FirstChild;//Get root node <xml> XmlNodeList nodes = xmlNode.ChildNodes; foreach (XmlNode xn in nodes) { XmlElement xe = (XmlElement)xn; m_values[xe.Name] = xe.InnerText;//Get the key value pair of xml into the data inside WxPayData} try { //2015-06-29 The error is that there is no signature if (m_values["return_code"] != "SUCCESS") { return m_values; } CheckSign();//Verify the signature, if it does not pass, it will throw an exception} catch (WxPayException ex) { throw new WxPayException(ex.Message); } return m_values; } /** * @Dictionary format converted to url parameter format* @ return url format string, This string does not contain the sign field value*/ public string ToUrl() { string buff = ""; foreach (KeyValuePair<string, object> pair in m_values) { if (pair.Value == null) { Log.Error(this.GetType().ToString(), "WxPayData contains a field with a value of null!"); throw new WxPayException("WxPayData contains a field with a value of null!"); } if (pair.Key != "sign" && pair.Value.ToString() != "") { buff += pair.Key + "=" + pair.Value + "&"; } } buff = buff.Trim('&'); return buff; } /** * @Dictionary formatted to Json * @return json string data*/ public string ToJson() { string jsonStr = JsonMapper.ToJson(m_values); return jsonStr; } /** * @values formatted to the result that can be displayed on the web page (because the web page cannot directly output strings in xml format) */ public string ToPrintStr() { string str = ""; foreach (KeyValuePair<string, object> pair in m_values) { if (pair.Value == null) { Log.Error(this.GetType().ToString(), "WxPayData contains fields with value null!"); throw new WxPayException("WxPayData contains fields with value null!"); } str += string.Format("{0}={1}<br>", pair.Key, pair.Value.ToString()); } Log.Debug(this.GetType().ToString(), "Print in Web Page : " + str); return str; } /** * @Generate signature, see the signature generation algorithm for details* @return signature, the sign field does not participate in the signature*/ public string MakeSign() { //Convert url format string str = ToUrl(); //Add API after string KEY str += "&key=" + WxPayConfig.KEY; //MD5 encryption var md5 = MD5.Create(); var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); var sb = new StringBuilder(); foreach (byte b in bs) { sb.Append(b.ToString("x2")); } //All characters are converted to uppercase string result = sb.ToString().ToUpper(); return result; } public string MakeAppSign() { //Convert url format string str = ToUrl(); //Add API after string KEY str += "&key=" + WxPayConfig.KEYofAPP; //MD5 encryption var md5 = MD5.Create(); var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); var sb = new StringBuilder(); foreach (byte b in bs) { sb.Append(b.ToString("x2")); } //All characters are converted to uppercase string result = sb.ToString().ToUpper(); return result; } /** * * Check whether the signature is correct* Return true correctly, and an error throwing exception*/ public bool CheckSign() { //If no signature is set, skip detection if (!IsSet("sign")) { Log.Error(this.GetType().ToString(), "WxPayData signature exists but is not legal!"); throw new WxPayException("WxPayData signature exists but is not legal!"); } //If the signature is set but the signature is empty, an exception is thrown if (GetValue("sign") == null || GetValue("sign").ToString() == "") { Log.Error(this.GetType().ToString(), "WxPayData signature exists but is not legal!"); throw new WxPayException("WxPayData signature exists but is not legal!"); } //Get the received signature string return_sign = GetValue("sign").ToString(); //Calculate the new signature locally string cal_sign = MakeSign(); if (cal_sign == return_sign) { return true; } Log.Error(this.GetType().ToString(), "WxPayData signature verification error!"); throw new WxPayException("WxPayData signature verification error!"); } /** * @GetDictionary */ public SortedDictionary<string, object> GetValues() { return m_values; } }}Prompt information: For relevant analysis ideas, please refer to the official WeChat official account payment SDK, download address: https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=11_1.
This article has been compiled into "Summary of JavaScript WeChat Development Skills", and everyone is welcome to learn and read.
I recommend a tutorial on WeChat applets that are highly concerned now: The editor of "WeChat Mini Program Development Tutorial" has carefully compiled it for everyone, I hope you like it.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.