2017-07-15 00:54:57 snakeMoving 阅读数 3131
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27761 人正在学习 去看看 秦子恒

之前没有接触过微信开发,出来工作后第一份工作是做微信开发,我的任务只是写一个接口。

进入正题,微信开发,本文的微信开发是指微信公众号开发,本文从微信开发的最基础部分做一个简单的记录,并且附上自己写的一段代码。

openid:openid其实就是一个数据库主键,是腾讯为每个公众号的唯一标识

userinfo:其实就是用户信息,这些可以授权获取到的信息及其有限,就是用户名性别地址之类的

其实微信开发文档写得很清楚了,本人啰嗦了点所以记下来了

一般我们进入一个公众号,它可能会让我们授权,其实这样他就获取到我们的信息,他可以保存到数据库,作为会员信息,这样就省去了注册的一个步骤

首先获取授权这一步,其实是开发者后台获取用户code的一个手段,code可以干嘛?code可以作为一个钥匙,通过微信提供的接口,携带着开发者的appid和秘钥,以及code

就可以获取到用户的openid和accesstoken,其实获取到这2个没什么卵用,然后你可以利用openid和accesstoken通过另外一个接口获取到用户信息,这就有用啦。

以下附上自己写的菜得抠脚的代码,还忘个各位大佬完善一些细节

package wechat.Common;

/**
 * Created by sam on 2017/7/13.
 */

/**
 * 授权后重定向的回调链接地址,请使用urlEncode对链接进行处理
 * 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),
 * snsapi_userinfo (弹出授权页面可通过openid拿到昵称、性别、所在地。
 * 并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
 */
public class URLBean {
    public static final String appid = "这个写自己的";
    public static final String appsecret = "这个写自己的";
    public static final String GETCODE
            = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE#wechat_redirect";
    public static final String GETACCESSTOKENANDID
            = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
    public static final String REFRESHTOKEN
            = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN ";
    //需要用get访问,https协议
    public static final String USERINFO
            = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
    public static final String BASEURL = "/grant/getCode?visitUrl=VISIT";
    public static final String PROJECT_URL = "http://2691670703.tunnel.qydev.com/WeChat";
}
package wechat.Common;

import org.apache.log4j.Logger;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLEncoder;

/**
 * Created by sam on 2017/7/13. 
 */
public class WechatFilter implements Filter{

	private Logger logger = org.apache.log4j.Logger.getLogger(this.getClass());

    public void init(FilterConfig filterConfig) throws ServletException {
        //
    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;
        HttpSession session = request.getSession();
        String openId = (String) session.getAttribute("openid");
        String URL = request.getRequestURI();
        if(isNeedGrant(URL)){
			if(openId!=null){
				filterChain.doFilter(request,response);
			}else{
				String queryString = request.getQueryString();
				String redirect_url = "";
				if(queryString!=null) {
					redirect_url = request.getRequestURL().toString()+"?"+queryString;
				}else {
					redirect_url = request.getRequestURL().toString();
				}
				String url  = URLBean.PROJECT_URL+URLBean.BASEURL.replace("VISIT",URLEncoder.encode(redirect_url, "UTF-8"));
				String target = URLBean.GETCODE.
						replace("APPID",URLBean.appid).
						replace("SCOPE","snsapi_userinfo").
						replace("REDIRECT_URI", url);
				response.sendRedirect(target);
			}
		}else{
			filterChain.doFilter(request,response);
		}

    }

    public void destroy() {
        //
    }
	/**
	 * 需要判断是否拉取openid不然它会无限循环进来
	 */
	public boolean isNeedGrant(String url){
		//判断是否是正在走向我定义好的接口
//		if (url.contains("/grant/getCode")){
//			return true;
//		}
//		return false;
		return true;
	}
}
package wechat.Common;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import wechat.Entity.WeChatUser;
import wechat.Service.WeChatUserService;

import java.net.URLDecoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Created by sam on 2017/7/13.
 */
@Controller
@RequestMapping("/grant")
public class Grant {
	private Logger logger = Logger.getLogger(this.getClass());
	@Autowired
	private WeChatUserService weChatUserService;
	//Illegal character in scheme name at index 0
    @RequestMapping("/getCode")
    public void getCode(HttpServletRequest HttpServletRequest, 
    		HttpServletResponse httpServletResponse)throws Exception{
        //这里拉取code,然后重定向到获取openId和accessToken的地址
    	HttpSession httpSession =  HttpServletRequest.getSession();
    	String code = HttpServletRequest.getParameter("code");
    	String redirect_url = HttpServletRequest.getParameter("visitUrl");
    	redirect_url = URLDecoder.decode(redirect_url,"UTF-8");
    	String url = URLBean.GETACCESSTOKENANDID.replace("APPID", URLBean.appid).
    			replace("SECRET", URLBean.appsecret).replace("CODE", code);
    	String resp = HttpClientUtil.doGet(url);
    	AccessTokenOpenId ao = JsonUtils.jsonToPojo(resp, AccessTokenOpenId.class);
    	String openId = ao.getOpenid();
    	httpSession.setAttribute("openid", openId);
    	WeChatUser chatUser = weChatUserService.getWeChatUserByOpenId(openId);
    	if(chatUser==null) {
    		String userinfojson = HttpClientUtil.doGet(URLBean.USERINFO
    				.replace("ACCESS_TOKEN",ao.getAccess_token()).replace("OPENID", ao.getOpenid()));
    		chatUser = JsonUtils.jsonToPojo(userinfojson, WeChatUser.class);
    		weChatUserService.insert(chatUser);
    	}
    	httpSession.setAttribute("user",chatUser);
    	httpServletResponse.sendRedirect(URLDecoder.decode(redirect_url, "UTF-8"));//跳转用户最原始访问的连接
    }
 
}
里面有一些需要完善的地方,需要各位大佬自己修改一下,我写不出优雅的代码,就这样吧,仅此记录而已 --Sam

2019-04-22 22:07:02 Aero_K 阅读数 1239
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27761 人正在学习 去看看 秦子恒

如上图

从最新的微信小程序开发文档中查阅,通过微信小程序接口 wx.getLocation() 依然不能够直接获取到用户具体城市信息。本文写的主要是如何通过从微信API获取的经纬度信息转化为具体的城市街道信息。

首先如果开发者想要获取用户当前的位置,地理信息等,需要先在app.json中配置permission字段,如果用wepy开发的话,需在app.wpy做相应的配置:如下

permission: {
  "scope.userLocation": {
     "desc": "你的位置信息将用于小程序位置接口的效果展示"
  }

第二步:进入页面,调用wx.getSetting拿到用户的授权情况。

第三步:调用wx.getLocation API 获取返回的经纬度,速度等信息

第四步:因为微信没有将经纬度直接转换为地理位置,因此这里需要通过借助微信位置服务,或者百度地图开放平台的全球逆地址编码。(这里本人利用的是百度开放平台,这里ak码是需要向百度地图开放平台获取的~,请求时填入相应的ak码,经纬度等信息。

第五步:用户进入页面的时候,可在页面的onShow方法中执行wx.getLocation让用户进行相应的授权,以后每次进入该页面时,通过wx.getSetting接口,返回用户授权具体信息。

具体代码如下:

onShow() {
    this._getUserLocation();
}
  _getUserLocation () {
    var self = this
    wx.getSetting({
      success: (res) => {
        console.log('用户授权情况', res)
        //未授权
        if(res.authSetting['scope.userLocation'] !== undefined &&     
         res.authSetting['scope.userLocation'] !== true) {
          wx.showModal({
            title: '请求授权当前位置',
            content: '需要获取您的地理位置,请确认授权',
            success: function (res) {
              console.log(res)
              if(res.cancel){
                wx.showToast({
                  title: '拒绝授权',
                  icon: 'none',
                  duration: 1000
                })
              } else if (res.confirm) { //确认授权, 通过wx.openSetting发起授权请求
                wx.openSetting({
                  success: function (res) {
                    if(res.authSetting["scope.userLocation"] == true) {
                      wx.showModal({
                        title: '授权成功',
                        icon: 'success',
                        duration: 1000
                      })
                      self._getCityLocation()
                    } else {
                      wx.showModal({
                        title: '授权失败',
                        icon: 'none',
                        duration: 1000
                      })
                    }
                  }
                })
              }
            }
          })
        } else if (res.authSetting['scope.userLocation'] == undefined) {
          self._getCityLocation()
          console.log('这个为undefined')
        } else {
          console.log('授权成功')
          self._getCityLocation()
        }
      }
    })
  }
  _getCityLocation(){
    let self = this
    wx.getLocation({
      type: 'wgx84',
      success: (res) => {
        let latitude = res.latitude
        let longitude = res.longitude
        let speed = res.speed
        wx.request({
          url: 'http://api.map.baidu.com/geocoder/v2/?ak=Vh0ALNzHjjEm5RP0Ie16dlBhZbdEQip9&location=' + res.latitude + ',' + res.longitude + '&output=json',
          data: {},
          header: { 'Content-type': 'application/json' },
          success: function (ops){ 
            console.log(ops)
            self.address = ops.data.result.addressComponent.city + 
            ops.data.result.addressComponent.district
          },
          fail: function (resq) {
            wx.showModal({
              title: '信息提示',
              content: '请求失败',
              showCancel: false,
              confirmColor: '#f37938'
            });
          }
        })
      },
      fail: (res) => {
        wx.showModal({
          title: '信息提示',
          content: '请求失败',
          showCancel: false,
          comfirmColor: '#f37938'
        })
      }
    })
  }

效果如下

用户首次进入页面时会先先请求用户授权地理位置权限

用户拒绝授权后

用户拒绝授权后再次进入该页面:

用户同意授权后:

 

2018-06-19 17:22:29 qq_35200894 阅读数 1660
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27761 人正在学习 去看看 秦子恒

这个功能是基于微信JSSDK开发的需要使用微信打开页面,结合前一篇微信网页授权发红包开发的

微信js-sdk官方开发文档  https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

这里我只记录一席定位以及坐标转换的方法

1、直接上js代码:

 <script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>//微信js

  <script src="http://map.qq.com/api/js?v=2.exp"></script>//腾讯地图js

<script >

  wx.config({
        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: '<%=appid%>', // 必填,公众号的唯一标识
        timestamp: '<%=timestamp%>', // 必填,生成签名的时间戳
        nonceStr: '<%=nonceStr%>', // 必填,生成签名的随机串
        signature: '<%=signature%>',// 必填,签名
        jsApiList: ['checkJsApi', 'openLocation', 'getLocation','chooseWXPay'] // 必填,需要使用的JS接口列表
    });
    wx.checkJsApi({
        jsApiList: ['getLocation'], // 需要检测的JS接口列表,所有JS接口列表见附录2,  
        success: function (res) {
            if (res.checkResult.getLocation == false) {
                alert('你的微信版本太低,不支持微信JS接口,请升级到最新的微信版本!');
                return;
            }
        }
    });
    var latitude;
    var longitude;
    var speed;
    var accuracy;
    var geocoder = null;
    wx.ready(function () {
        // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
        geocoder = new qq.maps.Geocoder({
            complete: function (result) {
                alert(result.detail.address);
            }
        });
        ///获取地理坐标并转换成位置信息
        wx.getLocation({
            type: 'gcj02',
            success: function (res) {
                latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90    
                longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。    
                speed = res.speed; // 速度,以米/每秒计    
                accuracy = res.accuracy; // 位置精度  
                var latLng = new qq.maps.LatLng(latitude, longitude);
                geocoder.getAddress(latLng);
            },
            cancel: function (res) {
                alert('未能获取地理位置');
            }
        });

    });  

</script>


2、只有三个字符串需要后台处理一下

       timestamp: '<%=timestamp%>', // 必填,生成签名的时间戳
        nonceStr: '<%=nonceStr%>', // 必填,生成签名的随机串
        signature: '<%=signature%>',// 必填,签名
后端代码:
 var jssdkUiPackage = JSSDKHelper.GetJsSdkUiPackage(appid, secret, Request.Url.AbsoluteUri);
            timestamp = jssdkUiPackage.Timestamp;
            nonceStr = jssdkUiPackage.NonceStr;
            signature = jssdkUiPackage.Signature;
这个方法具体代码:
 /// <summary>
        /// 获取给UI使用的JSSDK信息包
        /// </summary>
        /// <param name="appId"></param>
        /// <param name="appSecret"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public static JSSDKPackage GetJsSdkUiPackage(string appId, string appSecret, string url)
        {
            //获取时间戳
            var timestamp = GetTimestamp();
            //获取随机码
            string nonceStr = GetNoncestr();
            //获取签名
            string signature = JSSDKHelper.GetSignature(ticket, nonceStr, timestamp, url);
            //返回信息包
            return new JSSDKPackage(appId, timestamp, nonceStr, signature, ticket);
        }
  /// <summary>
        /// 获取时间戳
        /// </summary>
        /// <returns></returns>
        public static string GetTimestamp()
        {
            //var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            //return Convert.ToInt64(ts.TotalSeconds).ToString();
            var ts = DateTimeHelper.GetWeixinDateTime(DateTime.Now);
            return ts.ToString();
        }
 /// <summary>
        /// 获取随机字符串
        /// </summary>
        /// <returns></returns>
        public static string GetNoncestr()
        {
            return EncryptHelper.GetMD5(Guid.NewGuid().ToString(), "UTF-8");
        }
 /// <smmary>
        /// 获取JS-SDK权限验证的签名Signature
        /// </summary>
        /// <param name="ticket"></param>
        /// <param name="noncestr"></param>
        /// <param name="timestamp"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string GetSignature(string ticket, string noncestr, string timestamp, string url)
        {
            var parameters = new Hashtable();
            parameters.Add("jsapi_ticket", ticket);
            parameters.Add("noncestr", noncestr);
            parameters.Add("timestamp", timestamp);
            parameters.Add("url", url);
            return CreateSha1(parameters);
        }
 /// <summary>
        /// sha1加密
        /// </summary>
        /// <returns></returns>
        private static string CreateSha1(Hashtable parameters)
        {
            var sb = new StringBuilder();
            var akeys = new ArrayList(parameters.Keys);
            akeys.Sort(ASCIISort.Create());
            foreach (var k in akeys)
            {
                if (parameters[k] != null)
                {
                    var v = (string)parameters[k];
                    if (sb.Length == 0)
                    {
                        sb.Append(k + "=" + v);
                    }
                    else
                    {
                        sb.Append("&" + k + "=" + v);
                    }
                }
            }

            return EncryptHelper.GetSha1(sb.ToString());
        }

2016-11-14 16:18:34 u013803499 阅读数 5709
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27761 人正在学习 去看看 秦子恒

由于微信小程序没有方法可以获得当前用户所在城市的信息,所以需要调用方法来获取城市信息,用了两个方法去发送请求并返回城市信息
1.

@Controller
public class WechatLocationManager {

    private Logger logger = LoggerFactory.getLogger(WechatLocationManager.class);

    @RequestMapping(value = "/wechat/getcity", method = RequestMethod.POST)
    @ResponseBody
    public String getCity( @RequestBody Map<String, String> location) {
        String local = location.get("location");
        System.out.println(local);
        String latitude = local.substring(0, local.indexOf(','));
        String longitude = local.substring(local.indexOf(',') + 1);
        logger.debug("纬度:{}", latitude);
        logger.debug("经度:{}", longitude);
        String url = "http://api.map.baidu.com/geocoder/v2/?ak=2IBKO6GVxbYZvaR2mf0GWgZE&output=json&pois=0" +
            "&location=" + latitude + "," + longitude;
        HttpURLConnection connection = null;
        BufferedReader reader = null;
        try {
            URL getUrl = new URL(url);
            connection = (HttpURLConnection) getUrl.openConnection();
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            connection.connect();
            reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
            StringBuilder builder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                builder.append(line);
            }
            if (logger.isDebugEnabled())
                logger.debug(builder.toString());
            return JSONObject.fromObject(builder.toString());
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                connection.disconnect();
            }
        }
        return obj;
    }
}

2.第二个方法是根据项目中提供的发送请求的方法去发送并接受返回的信息

private static final String LOCATION_URL = "http://api.map.baidu.com/geocoder/v2/";
    private static final Map<String, String> LOCATION_INPUT = new ConcurrentHashMap<String,String>(){
        {
            put("ak", "2IBKO6GVxbYZvaR2mf0GWgZE");
            put("output", "json");
            put("pois","0");
        }
    };

    @RequestMapping(value = "/wechat/city", method = RequestMethod.POST)
    @ResponseBody
    public String getCity(@RequestBody Map<String, String> location) {
        String local = location.get("location");
        System.out.println(local);
        String latitude = local.substring(0, local.indexOf(','));
        String longitude = local.substring(local.indexOf(',') + 1);
        logger.debug("纬度:{}", latitude);
        logger.debug("经度:{}", longitude);
        LOCATION_INPUT.put("location", local);
        String obj = HttpClientUtils.doGetWithHeader(null, LOCATION_URL, LOCATION_INPUT, null, "utf-8", null);
        return obj;
    }

这里记录一下doGet方法去处理请求的

public static String doGet(CloseableHttpClient client, String url, Map<String, String> params, String charset, String userAgent, Map<String, String> heads) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        CloseableHttpResponse response = null;
        try {
            if (params != null && !params.isEmpty()) {
                List<NameValuePair> pairs = new ArrayList<>(params.size());
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
                url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset));
            }
            HttpGet httpGet = new HttpGet(url);
            if (StringUtils.isNotBlank(userAgent)) {
                httpGet.addHeader(HTTP.USER_AGENT, userAgent);
            }
            if (heads != null && !heads.isEmpty()) {
                for (Map.Entry<String, String> entry : heads.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        httpGet.addHeader(entry.getKey(),value);
                    }
                }
            }
            response = client.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpGet.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, charset);
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (null != response) {
                try {
                    response.close();
                } catch (Exception ex) {
                    logger.error("close response has error.");
                }
            }
        }
    }
2017-11-06 15:09:10 qq_35713752 阅读数 2534
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27761 人正在学习 去看看 秦子恒

 有问题可以扫码加我微信,有偿解决问题。承接小程序开发。

微信小程序开发交流qq群   173683895  、 526474645 ;

正文:

// 获取用户当前位置的名称和城市 util.js

function location() {
  // 实例化腾讯位置服务里面微信小程序JS SDK的API核心类 地址http://lbs.qq.com/qqmap_wx_jssdk/qqmapwx.html
  var qqmapsdk = new qqmap({
    key: '开发密钥(key
  });
  return new Promise((resolve) => {
    wx.getLocation({
      type: 'wgs84',
      success: function(res) {
        qqmapsdk.reverseGeocoder({
          location: {
            latitude: res.latitude,
            longitude: res.longitude
          },
          success: function(res) {
            const address = res.result.address
            resolve(address)
          },
          fail() {
            resolve('')
          }
        })
      }
    })
  })
}

module.exports = {
  location: location

}

//index.js

const util = require("../../utils/util.js")

onLoad: function () {

    util.location().then(function (data) {

        console.log(data)

    })

}

 

 

微信开发

阅读数 34

没有更多推荐了,返回首页