写着写着,越写越多,思绪写不下了,回头写在前面的话。此系统属个人创业项目,历时3个月,主要实现自助按摩椅、娃娃机、自动换币器功能,主要流程就是用户扫码二维码->授权获取用户信息->弹出H5界面选择相应服务->支付->控制硬件设备做对应操作。主要功能点如下:
1)微信、支付宝用户信息获取、保存会员信息。具体步骤见各自api文档,十分详细,同时坑也很多。
2)一码多付,微信公众号支付,支付宝支付,需按照步骤流程一步步走,一步步申请,设置,同时坑更多,有问题可随时沟通交流。
3)订单查询、收入明细、统计,充值管理等。
4)后台系统的账户、权限、统计信息、数据导出等,用shiro 控制。
5)设备的添加和维护,二维码的生成、代金券的生成、用户批量绑定代金券,合作商管理,加盟商管理等。
6)短信网关、邮件功能。
7)微信公众号对接,自动回复,客服消息,各种事件推送。
马上年终总结了,坐等年终大奖,也没多少时间写了,想到哪里就写点吧,有疑问的话可加qq:540769049 进行交流,根据大家疑问慢慢完善代码吧,请备注来由。
回头把二维码放出来,关注公众号后回复测试账号,就能体验系统各模块功能了,比这里啰里啰嗦简单粗暴。
一:业务需求
通过一个二维码完成多种第三方支付方式支付的需求:
商户打印一个静态的二维码,顾客用微信、支付宝扫这个二维码后,进入商户的一个付款页面,输入金额(或选择特定金额)后,完成支付,然后启动后续服务流程。
本demo实现一码多付(微信公众号、支付宝)支付后,控制按摩椅的业务需求。
二:业务实现
1.生成二维码
生成带有设备参数(唯一性)的二维码,用于用户扫码时定位具体的设备,用户支付成功后,开启后续服务。
一般建议生成二维码的url不要太长,长度越短则生成的二维码识别率越高。二维码url示例:http//xyxspace.com/m/123456
2.扫码识别
用户扫码时,可能会有许多种软件来扫,但目前只实现了微信、支付宝扫码支付。因此需要做识别扫码来源并在页面作出提示,引导用户用支微信、支付宝进行扫码。
用户用app扫商户的二维码后,其实是用app浏览器打开到商户的页面, 商户页面通过识别浏览器header中的user-agent来判断是哪个app打开的。
常见App浏览器的user-agent 识别关键字:
支付宝: AlipayClient
微信: MicroMessenger
如果识别到不包含上述关键信息,则跳转到错误提示页面,引导用户用微信、支付宝扫码。如下图:
微信、支付宝扫码成功后,会将设备mcode提交到你的服务端,保存在session中或放在下一步授权回调地址参数中。
3.技术实现
本demo使用springmvc+mybatis3.2后台框架,mysql5.7数据库,HTML5+css3.0+bootstrap前端页面,shiro 、ehcache 、druid等技术。
4.话不多说,开始撸代码......
1.扫码入口控制类:采用springmvc架构,用户扫码后到控制类;
1)识别二维码中的mcode,保存到session中。
2)判断用户是否登录,如果没有登录,根据APP类型,获取用户信息,作为会员信息保存到数据库。
3)如果已登录,跳转到价格页面。
/**
* 扫码入口控制类
*
*/
@Controller
@RequestMapping(value = "/m")
public class IndexController extends BaseController {
@Resource(name = "commonService")
private CommonService commonService;
@Resource(name = "indexService")
private IndexService indexService;
/**
* 扫码总入口
*
* @return ModelAndView
*/
@RequestMapping(value = "/3*")
public ModelAndView scaning() {
String url = request.getRequestURL().toString();
String mcode = url.substring(url.lastIndexOf("/") + 1);
session.setAttribute("mcode", mcode);
String id = "";
if (Constants.WEIXIN.equals(appType)) {// 来自微信
logger.info("微信扫码...");
id = (String) session.getAttribute("openid");
} else if (Constants.ALIPAY.equals(appType)) {// 来自支付宝
logger.info("支付宝扫码...");
id = (String) session.getAttribute("user_id");
}
if (StringUtils.isBlank(id)) {// session中未存在用户信息时,授权重新获取用户信息
return indexService.createRedirectURL(appType);
} else {
return commonService.trunView(id, mcode, basePath);// 跳转到首页价格页面
}
}
}
2.判断扫码APP类型
public static String IsWeixinOrAlipay(HttpServletRequest request) {
if (request != null) {
String userAgent = request.getHeader("user-agent");
if (StringUtils.isNotBlank(userAgent)) {
userAgent = userAgent.toLowerCase();
if (userAgent.indexOf("micromessenger") > -1) {// 微信客户端
return Constants.WEIXIN;
} else if (userAgent.indexOf("alipayclient") > -1) {
return Constants.ALIPAY;
}
}
}
return "other";
}
3.获取微信用户信息
1) 根本客户端类型生成对应授权url
public ModelAndView createRedirectURL(String appType) {
if (Constants.WEIXIN.equals(appType)) {// 微信客户端
String redirectUrl = OAuthManager.generateRedirectURI(WXConstants.REDIRECT_URI, WXConstants.SCOPE, WXConstants.STATE);
return new ModelAndView("redirect:" + redirectUrl);
} else if (Constants.ALIPAY.equals(appType)) {// 支付宝客户端
String redirectUrl = OAuthALiService.generateRedirectURI(AlipayConfig.REDIRECTURI, AlipayConfig.ALIPAY_SCOPE, AlipayConfig.STATE);
return new ModelAndView("redirect:" + redirectUrl);
} else {
ModelAndView mv = new ModelAndView();
mv.setViewName("view/index/unAllow");
return mv;
}
}
2)获取微信授权url
/**
* 网页授权获取用户基本信息
* <p>
* 参考<a href="http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html">开发文档</a>
* </p>
* Created by xuwen on 2015/12/11.
*/
public class OAuthManager {
private st