2016-05-25 15:45:04 u012012240 阅读数 3409
  • 微信支付开发-微信公众号开发12-微信开发php

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

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

  主要用途:主要用于session管理。在微信开发时,因为通过微信服务器转发,而丢失cookie和seesion,无法使用session,所以使用微信服务器post过来的openid当做sessionid ,openid是一个唯一不重复的,这样每个用户的状态是可以独立的
参考地址:http://www.ablanxue.com/shtml/201502/26386_1.shtml
参考文章比较乱,但给我带来了灵感。我的这个和他的基础相同,不相同的是:
1.我采用一个线程来管理session集合,减少内存消耗,session失效时间可能会多一秒
2.我session采用session创建时间,session保存时间

package com.fkhd.weixin.session;
/**
 * session键值对实体类
 */
public class SessionData {
	/**
	 * 键
	 */
	private String name;
	/**
	 * 值
	 */
	private Object value;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Object getValue() {
		return value;
	}
	public void setValue(Object value) {
		this.value = value;
	}

}
package com.fkhd.weixin.session;

import java.util.ArrayList;
import java.util.List;

/**
 * session实体类
 */
public class Session {
	/**
	 * 唯一标识
	 */
	private String openid;
	/**
	 * 创建时间
	 */
	private long createTime;  
	/**
	 * 有效时间
	 */
	private long validTime;
	/**
	 * 键值对集合 
	 */
	private List<SessionData> sessionDatas=new ArrayList<SessionData>();
	
	public String getOpenid() {
		return openid;
	}
	public void setOpenid(String openid) {
		this.openid = openid;
	}
	public long getCreateTime() {
		return createTime;
	}
	public void setCreateTime(long createTime) {
		this.createTime = createTime;
	}
	public long getValidTime() {
		return validTime;
	}
	public void setValidTime(long validTime) {
		this.validTime = validTime;
	}
	public List<SessionData> getSessionDatas() {
		return this.sessionDatas;
		
	}
	public void setSessionDatas(List<SessionData> sessionDatas) {
		this.sessionDatas=sessionDatas;
		} 
}
package com.fkhd.weixin.session;

import java.util.ArrayList;
import java.util.List;

/**
 * session集合
 */
public class SessionList {
	/**
	 * session集合
	 */
	public static List<Session> sessionList=new ArrayList<Session>();
	/**
	 * 查找session中是否有指定项
	 * @param openid session标识
	 * @return 若存在openid相同的session,返回在集合中对应的位置,若不存在返回-1
	 */
	public static int search(String openid){
		int size = sessionList.size(); 
		for ( int i=0 ; i<size ; i++){ 
			if ( sessionList.get(i).getOpenid().equals(openid)) 
				return i;
		}
		return -1;           
	}
	/**
	 * 移除session
	 */
	public static void remove(String openid) {
		int i = search(openid);
		if (i>=0)
			sessionList.remove(i);
	}
	/**
	 * 向session中存入数据
	 * @param name
	 * @param value
	 * @param openid
	 */
	public static void setSeesion(String name, Object value, String openid){
		System.out.println("setSeesion " + name + " " + value + " " + openid);
		int i = search(openid);
		if (i>=0){
			SessionData data = new SessionData();
			data.setName(name);
			data.setValue(value);
			sessionList.get(i).getSessionDatas().add(data);
		}
	} 
	/**
	 * 创建session 
	 * @param openid
	 */
	public static void setSeesion(String openid){
		System.out.println("setSeesion " + openid);
		int i = search(openid); 
		if (i<0){ 
			//建立线程 
			Session session = new Session();
			//两个小时会话
			session.setValidTime(120*60*1000);
			//当前时间戳
			session.setCreateTime(System.currentTimeMillis());
			//session唯一标识
			session.setOpenid(openid);
			//添加session
			sessionList.add(session);
		}
	}
	/**
	 * 根据name,获取session对象中键值对
	 * @param name
	 * @param openid
	 */
	public static Object getSession(String name, String openid){
		System.out.println("getData " + name + " " + openid);
		int i = search(openid); 
		if (i>=0) {
			SessionData sessionData=null;
			for (SessionData sData : sessionList.get(i).getSessionDatas()) {
				if (sData.getName().equals(name)) {
					sessionData=sData;
				}
			}
			if (sessionData!=null){
				Object value = sessionData.getValue();
				System.out.println(name + "值为 " + value);
				return value;
			} 
		}
		return null;
	}
	/**
	 * 根据name,移除session对象中键值对
	 * @param name
	 * @param openid
	 */
	public static void removeData(String name, String openid){
		int i = search(openid); 
		if (i>0){
			sessionList.get(i).getSessionDatas().remove(name);
		}
	}
}
package com.fkhd.weixin.session;

import java.util.ArrayList;
import java.util.List;

/**
 * 更新session集合状态
 */
public class SessionThread implements Runnable{ 
	public void run() { 
		while(true){
			//当前时间戳
			long currentTime=System.currentTimeMillis();
			//休眠1分钟
			try {
				if (SessionList.sessionList.isEmpty()){ 
					System.out.println("现在还没session,休息10分钟!");
					//休眠10分钟
					Thread.sleep(10*60*1000);
				}else {
					//用来装需要删除的元素
					List<Session> delList = new ArrayList<Session>();
					//遍历session集合,将时间戳到期的提出
					for (Session session : SessionList.sessionList) {
						//当前时间大于创建时间加保存时间的session移除
						if (currentTime>session.getCreateTime()+session.getValidTime()) {
							delList.add(session);
							System.out.println("要移除的session,openid为:"+session.getOpenid());
						}
					}
					//移除要删除的元素
					SessionList.sessionList.removeAll(delList);
					//休眠1分钟
					Thread.sleep(60*1000);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}


2018-02-03 09:43:54 yji534123343 阅读数 913
  • 微信支付开发-微信公众号开发12-微信开发php

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

    27840 人正在学习 去看看 秦子恒
一、微信开发的整体介绍
开放平台:https://open.weixin.qq.com/
公众平台:https://mp.weixin.qq.com/
1、微信开发的种类
①移动应用开发
支持微信的分享、收藏、支付三大功能,原生开发的人员去使用的开发类别
②网站应用开发
网站支持使用微信账号进行注册和登录,从而来实现:提高用户的留存率,方便不同账号的统一(结合unionId)
③公众账号开发


④公众账号第三方平台
优势在于免繁琐设置,方便小白用户去使用。


2、公众账号开发
①服务号
主要偏向于给用户提供查询服务(招商银行、麦当劳。。)
显示在好友列表,每个月只能群发4条消息


②订阅号
主要偏向于给用户提供资讯(朝闻天下、Web前端。。)
显示在订阅号文件夹内,每天都可以群发1条消息


③小程序
2017年1月9号 (2007年1月9号 推出iphone)
基于微信的平台,ui提供了很多组件,js提供了很多接口


(微信官方的小程序:小程序示例,包含了微信官方封装好的组件、以及封装好的接口)


目标:万物互联 (IOT),  二维码
开放范围:(不包含个人)
http://www.wxapp-union.com/forum.php?mod=viewthread&tid=495


https://mp.weixin.qq.com/debug/wxadoc/dev/index.html


数据存储和服务器:
两种解决方案 ①腾讯云(不到100) ②godaddy


④企业号
主要是建立起 企业与人的关系,提供信息、和企业相关的定制功能


温馨提示:
1)如果想简单的发送消息,达到宣传效果,建议可选择订阅号;
2)如果想进行商品销售,进行商品售卖,建议可申请服务号;
3)如果想用来管理内部企业员工、团队,对内使用,可申请企业号。
4)订阅号可通过微信认证资质审核通过后有一次升级为服务号的入口,升级成功后类型不可再变。
5)服务号不可变更成订阅号。


3、九大类高级接口


语音识别接口
客服接口
OAuth2.0 网页授权接口
生成带参数的二维码接口
获取用户地理位置接口
获取用户基本信息接口
获取关注者列表接口
用户分组接口
上传下载多媒体文件接口


+ 微信支付
(十大类接口的使用,必须是认证过的服务号和订阅号才能使用)




4、正式环境的搭建
(公众账号-》订阅号)


购买自己的域名(万网、dnsPod、godaddy)
购买申请主机空间(新浪云、阿里云、腾讯云、大米云、godaddy、aws)
注册订阅号
登录到订阅号管理接口、服务器的配置、调用10大类接口


5、测试环境的搭建
(公众账号-》订阅号)


主机空间(新浪云)
注册订阅号
登录到订阅号管理接口、服务器的配置、调用10大类接口


6、注册订阅号
①填写邮箱、密码
②到邮箱中激活账号
③选择类型
④登记信息(个人、组织、媒体、企业。。)
⑤填写公众号的信息(名称、介绍、头像)






二、个人订阅号(jssdk)


1、实现功能:统计页面被访问的次数


分析:
①存储需要持久保存的数据
数据库、文件系统、内存中:fileSystem
②读写过程
读:file_get_contents($fileUrl);
写:file_put_contents($fileUrl,$content);


需要apache启动


2、新浪云storage


通过bucket管理我们的文件,如何访问?
saestor:// testbucket/count.txt




3、jsSDK的使用步骤
①绑定域名
②引入js文件
③注入接口(将使用接口的名称,写在config方法中jsAPIList这个数组中)
④在ready中调用接口
⑤在error中处理失败的异常情况






sample.zip有4个文件,
前两个文件都是用来存储数据的,jssdk.php进行网络请求以及数据的读写操作,sample.php文件主要完成接口的注入和调用


jssdk.php封装了2个方法get_php_file、set_php_file,如果部署在服务端,写文件会出现权限拒绝的问题。
①将存储文件 放到新浪云的bucket中
②修改读写文件的路径为 saestor://bucketName/**.php




require subscribe 需要订阅测试账号。




三、版本控制工具(git)


1、版本控制
记录一个或者多个文件内容变化,以便于未来查询指定的版本信息。


svn 集中式/git  分布式
①防止代码的丢失
②团队协作
③版本还原
④更好的管理代码


2、git介绍
用于代码的版本控制,使用方式:命令行/图形化


git(分布式版本控制工具)与github(托管开源项目的网站,托管项目的方式采用的是git)


3、自己使用git将项目上传到github


①申请github的账号 
https://github.com/
注册账号,在选择计划的时候选择continue,在编辑经验时选择skip跳过。
②去邮件激活账号
③start project 只需要指定repository的名称,点击create去创建。


④安装git
一路next,最后点击install安装 取消所有的勾选就可以了。
⑤启动git
到所有程序中,找到git,找到gitbash,点击启动


⑥基础命令
ls (list) 查看当前目录下的文件
clear 清除当前的屏幕信息
pwd (print the work directory)显示当前目录
mkdir web1609 在当前的路径中创建一个叫做web1609的目录
cd web1609 (change directory)
touch a.txt 创建一个叫做a.txt的一个文件


通过电脑中的文件系统找到文件,写上了hello git.


git的用法


git init 初始化仓库
git status 查看仓库的状态
git add a.txt 将a.txt添加到代码仓库
git commit -m '第一次提交'     添加到缓存区


配置上传到github上的用户信息:
git config --global user.name "web1609best"
git config --global user.email "web1609@vip.163.com"


设置完账号之后,重新提交到缓存区:
git commit -m '第一次提交'     添加到缓存区


将本地的代码设置它推送到github上的地址:
git remote add origin https://github.com/web1609best/web1609.git


将当前目录的git仓库推送到github对应的origin地址的master分支
git push origin master

















2015-07-04 14:25:41 wyx100 阅读数 13822
  • 微信支付开发-微信公众号开发12-微信开发php

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

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

问题现象:在微信开放平台上开发,访问的时候, 提示redirect_uri 参数错误

解决办法:添加回调域


1.登录公众号-开发者中心-功能服务-网页账号

公众号平台:https://mp.weixin.qq.com/



2.修改域名(不是url,是域名)


格式如下:

test.sina.com

注意,不是http://test.sina.com  没有http://

2016-11-15 11:38:46 qq_24091555 阅读数 20068
  • 微信支付开发-微信公众号开发12-微信开发php

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

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

           由于项目需要,需要接触微信开发,并要调用微信的JS-SDK里面的接口。

       因为经验缺乏,我百度一下关于微信开发的资料,但收集的资料都不尽人意。网上的主流的微信开发是采用PHP开发的,而本人学的Java。所以对PHP微信开发只能看懂思路。更有的是,网上一些微信开发视频,也是和PHP有关的,关于用Java开发的甚少。

       无奈之下,我只好苦啃微信开发文档。大家都知道,微信官方给的开发文档真的有点那个啥,一个功能实现非要分几个地方来说,看完这块,又得点击另一个页面看完另一块,甚是麻烦。这样的设定也让我走了好多坑。

但功夫不负有心,在研究透了微信开发文档之后,我顺利在在项目中完成微信开发。现在我将微信开发的经验分享一下,希望对大家有所帮助。

       微信JS-SDK是微信公众号平台面向网页开发这提供基于微信内的网页开发工具包。接口大类分为:基础接口、分享接口、图像接口、音频接口、智能接口、设备信息、地址位置、摇一摇周边、界面操作、微信扫一扫、微信小店、微信卡劵和微信支付。一般使用频率高的就是分享接口、地理微信、微信扫一扫和微信支付。

接下来,我将主要讲解如何调用微信分享接口。

第一步,准备内网映射工具,ngrok。不清楚这个的同学可以去百度一下。https://ngrok.com为ngrok官网。要进行微信开发,内网映射工具是不可少。毕竟,我们程序员进行开发,要测试开发的产品是否能用,都先在自己的电脑跑一下。但由于ngrok的服务器在外国的,鉴于天朝的墙太高,访问可能不稳定。所以我推荐的是国内的natapp,免费和收费的都有,服务毕竟稳定可靠,只不过要想自定义二级域名就得交费成为VIP咯。

第二步,配置JS接口安全域名。登录要进行开发的公众号,点击公众设置--->功能设置。设置JS接口安全域名,要注意三点:①填写域名前面不需加上http://,例如你的域名是http://test.com,直接填写test.com即可;②域名默认80端口,只支持80和443端口,所以域名后面不能添加端口号。③该域名为你调用微信JS-SDK接口域名。

第三步,引用JS文件。在需要调用JS接口的页面引入http://res.wx.qq.com/open/js/jweixin-1.0.0.js 。


第四步,通过config接口注入权限验证配置 。具体参数有什么用处,在截图都有注释讲解。其中jsApiList为我们要使用的接口,我在下面共引用了五个接口,分别为微信好友分享、QQ好友分享、腾讯微博分享、QQ空间分享和朋友圈分享。调用的都是分享的接口。至于其他接口列表,可以去微信开发文档那浏览一下。这里就不详说。

        第五步,在服务器生成相关参数传到调用JS-SDK页面,完成授权。这是最重要的一步。如上图所示,appId,timestamp,nonceStr,signature都为必填参数。下面我将会详细说说如何生成这些参数并传回页面。

appId为开发的微信公众号的AppID(应用ID),我们可以在登录微信公众号,在开发选项中点击基本配置来查看。

timestamp为系统生成的时间戳。


nonceStr为服务器随机生成的字符串。



signature为微信JS-SDK使用权限算法。在生成signature之前,我们要拿到jsapi_ticket。官方文档是这样解释的:


我们要注意三个地方。jsapi_ticket要缓存两个小时,每过两个小时,向微信那边请求一次。获取jsapi_ticket要通过access_token。那么我们该如何获取access_token呢?


从文档可以看出,access_token需要AppID和AppSercet两个参数。而且access_token和jsapi_ticket一样,有效期皆为两小时。这就要求我们服务器要缓存access_token和jsapi_ticket,当有效期一过,就重新请求。有的人采用是用数据库来存取这两个参数,而我采用的是用Quartz定时器。关于Quartz定时器的使用,可浏览我上篇博客《SSH与Quartz集成》,里面有关于Quartz的使用方法。

AppSercet可在与APPID同一页面获取。接下来,调用接口,获取access_token。



接下来,我们用access_token去获取jsapi_ticket。


获取jsapi_ticket,就可以进行生成签名。在此之前,先看一下官方文档的签名算法。



用代码实现。


第六步,传生成的参数给网页。



第七步,调用已授权的JS接口。


第八步,利用微信Web开发者工具调试,看看是否授权成功。(微信web开发者工具可在微信开发下载)。



2018-05-09 15:04:57 qq_38455201 阅读数 12872
  • 微信支付开发-微信公众号开发12-微信开发php

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

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

我们在做微信开发的时候,有一个很重要的就是通过openid获取用户的详细信息,包含昵称,头像,省,市,区的信息,但是现在移动时代,很多人追求个性,在名字当中大量使用火星文或者表情符。(本人实际测试过一个20w+用户的公众号,昵称,省市区的信息都有可能包含特殊字符,暂时不了解为什么省市区都出现特殊字符的情况)这给微信开发带来了一些问题,我们在获取昵称之后保存到mysql数据库当中去就会出现错误。

下面三种解决办法:

1.取到了用户的昵称,把含有特殊字符的信息过滤掉然后进保存,好处是简单,坏处是会损失昵称细节,在非常不严格的情况下,才能够使用。

nickname.replaceAll("[\ue000-\uefff]","");

2.对mysql进行特殊设置,好处是你设置了好了之后可以一劳永逸的解决问题,坏处是可能会影响mysql的性能,并且假如你的数据库,表已经建立好,修改起来比较麻烦。

第一步:找到你的mysql的配置文件,一般叫my.cnf,打开之后全局搜索 character 关键词,可以搜索出很包含这个字符的信息,这个是设置字符编码的,让他们的值都等于utf8mb4,例如:default-character-set=utf8mb4。

第二步:修改表列的字符集,把你现有表的字符集全部改为utf8mb4编码。

第三步:JDBC数据库连接

jdbc:mysql://localhost:3306/mediamall?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true

3.也是我现在采用的方法,就是把nickname查出来,然后对nickname进行编码,编码完成之后保存到数据库当中。这样做的好处是不会损失细节,方便操作,只需要对数据进行一行代码的编码,坏处是直接用navicat打开表的时候nickname就看不懂了,并且在用到nickname的时候一定要记得先进行解码。

 import org.apache.commons.codec.binary.Base64;
 String nickname = jsonObject.getString("nickname");//jsonObject对象是查询出来的用户信息转化为json对象,用的是阿里巴巴的fastjson
 //进行编码
 nickname =Base64.encodeBase64String(nickname.getBytes("UTF-8"));
 //进行解码
 nickname = new String(Base64.decodeBase64(nickname),"UTF-8");

假如数据需要在HTML页面进行Base64编码和解码,可以用上下面的方法:

        /**
         * Base64 encode / decode
         */
        function Base64() {
            // private property
            _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

            // public method for encoding
            this.encode = function (input) {
                var output = "";
                var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
                var i = 0;
                input = _utf8_encode(input);
                while (i < input.length) {
                    chr1 = input.charCodeAt(i++);
                    chr2 = input.charCodeAt(i++);
                    chr3 = input.charCodeAt(i++);
                    enc1 = chr1 >> 2;
                    enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                    enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                    enc4 = chr3 & 63;
                    if (isNaN(chr2)) {
                        enc3 = enc4 = 64;
                    } else if (isNaN(chr3)) {
                        enc4 = 64;
                    }
                    output = output +
                        _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
                        _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
                }
                return output;
            }

            // public method for decoding
            this.decode = function (input) {
                var output = "";
                var chr1, chr2, chr3;
                var enc1, enc2, enc3, enc4;
                var i = 0;
                input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
                while (i < input.length) {
                    enc1 = _keyStr.indexOf(input.charAt(i++));
                    enc2 = _keyStr.indexOf(input.charAt(i++));
                    enc3 = _keyStr.indexOf(input.charAt(i++));
                    enc4 = _keyStr.indexOf(input.charAt(i++));
                    chr1 = (enc1 << 2) | (enc2 >> 4);
                    chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                    chr3 = ((enc3 & 3) << 6) | enc4;
                    output = output + String.fromCharCode(chr1);
                    if (enc3 != 64) {
                        output = output + String.fromCharCode(chr2);
                    }
                    if (enc4 != 64) {
                        output = output + String.fromCharCode(chr3);
                    }
                }
                output = _utf8_decode(output);
                return output;
            }

            // private method for UTF-8 encoding
            _utf8_encode = function (string) {
                string = string.replace(/\r\n/g, "\n");
                var utftext = "";
                for (var n = 0; n < string.length; n++) {
                    var c = string.charCodeAt(n);
                    if (c < 128) {
                        utftext += String.fromCharCode(c);
                    } else if ((c > 127) && (c < 2048)) {
                        utftext += String.fromCharCode((c >> 6) | 192);
                        utftext += String.fromCharCode((c & 63) | 128);
                    } else {
                        utftext += String.fromCharCode((c >> 12) | 224);
                        utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                        utftext += String.fromCharCode((c & 63) | 128);
                    }

                }
                return utftext;
            }

            // private method for UTF-8 decoding
            _utf8_decode = function (utftext) {
                var string = "";
                var i = 0;
                var c = c1 = c2 = 0;
                while (i < utftext.length) {
                    c = utftext.charCodeAt(i);
                    if (c < 128) {
                        string += String.fromCharCode(c);
                        i++;
                    } else if ((c > 191) && (c < 224)) {
                        c2 = utftext.charCodeAt(i + 1);
                        string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                        i += 2;
                    } else {
                        c2 = utftext.charCodeAt(i + 1);
                        c3 = utftext.charCodeAt(i + 2);
                        string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                        i += 3;
                    }
                }
                return string;
            }
        }
//1.加密  
var str = '需要加解密的内容';  
var base = new Base64();  
var result = base.encode(str);   
  
//2.解密  
var result2 = base.decode(result);  
以上是我的个人总结,推荐大家使用第三种方式,对数据进行编码然后保存,需要使用对数据进行解码,这样不会损失细节,也不影响数据库当中的其他数据。



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