我这里采用了第三方的依赖,目前是最火的微信开发工具吧,WxJava
引入相关依赖
<dependency> <groupId>com.github.binarywanggroupId> <artifactId>weixin-java-payartifactId> <version>4.1.0version> dependency>
配置application.yml
# ----------------------系统配置# 业务配置pay-platform: # 微信 wx: pay: appId: secret: mchId: mchKey: keyPath: notifyUrl:
属性类
import lombok.Data;import org.springframework.boot.context.properties.ConfigurationProperties;/** * wxpay pay properties. * * @author Binary Wang */@Data@ConfigurationProperties(prefix = "pay-platform.wx.pay")public class WxPayProperties { /** * 设置微信公众号或者小程序等的appid */ private String appId; private String secret; /** * 微信支付商户号 */ private String mchId; /** * 微信支付商户密钥 */ private String mchKey; /** * 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除 */ private String subAppId; /** * 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除 */ private String subMchId; /** * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定 */ private String keyPath; /** * 支付回调地址 */ private String notifyUrl;}
属性配置类
import com.github.binarywang.wxpay.config.WxPayConfig;import com.github.binarywang.wxpay.service.WxPayService;import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;import lombok.AllArgsConstructor;import org.apache.commons.lang3.StringUtils;import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * @author Binary Wang */@Configuration@ConditionalOnClass(WxPayService.class)@EnableConfigurationProperties(WxPayProperties.class)@AllArgsConstructorpublic class WxPayConfiguration { private WxPayProperties properties; @Bean @ConditionalOnMissingBean public WxPayService wxService() { WxPayConfig payConfig = new WxPayConfig(); payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId())); payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId())); payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey())); payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId())); payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId())); payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath())); // 可以指定是否使用沙箱环境 payConfig.setUseSandboxEnv(false); WxPayService wxPayService = new WxPayServiceImpl(); wxPayService.setConfig(payConfig); return wxPayService; }}
相关实体类,都可以使用json的map格式来处理,我这里是个人习惯
import lombok.Data;import lombok.experimental.Accessors;/** * 接口调用凭证 * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html * * @author Tellsea * @date 2021/05/20 */@Data@Accessors(chain = true)public class AccessToken { private String accessToken; /** * 凭证有效时间,单位:秒。目前是7200秒之内的值。 */ private Integer expiresIn; private Integer errCode; private String errMsg;}
import lombok.Data;import lombok.experimental.Accessors;/** * code换取openId * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html * * @author Tellsea * @date 2021/05/20 */@Data@Accessors(chain = true)public class Code2Session { private String openId; private String sessionKey; private String unionId; private Integer errCode; private String errMsg;}
import lombok.Data;import lombok.experimental.Accessors;/** * 微信登录 * * @author Tellsea * @date 2021/05/19 */@Data@Accessors(chain = true)public class WeiXinLogin { private String code; private String encryptedData; private String iv; private String nickName; private String avatarUrl; private Integer gender;}
lombok.Data;import lombok.experimental.Accessors;/** * 微信 token * * @author Tellsea * @date 2021/05/20 */@Data@Accessors(chain = true)public class WeiXinToken { public static String token;}
控制层
package com.ruoyi.business.appuser.controller;import cn.hutool.core.lang.Validator;import com.alibaba.fastjson.JSONObject;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;import com.ruoyi.business.appuser.service.WeiXinService;import com.ruoyi.business.appuser.vo.wx.Code2Session;import com.ruoyi.business.appuser.vo.wx.OrderInfo;import com.ruoyi.business.appuser.vo.wx.WeiXinLogin;import com.ruoyi.common.constant.Constants;import com.ruoyi.common.constant.UserConstants;import com.ruoyi.common.core.domain.AjaxResult;import com.ruoyi.common.core.domain.entity.SysUser;import com.ruoyi.common.core.domain.model.LoginUser;import com.ruoyi.common.utils.SecurityUtils;import com.ruoyi.common.utils.ServletUtils;import com.ruoyi.framework.web.service.SysLoginService;import com.ruoyi.framework.web.service.SysPermissionService;import com.ruoyi.framework.web.service.TokenService;import com.ruoyi.system.service.ISysUserService;import com.zhhy.tool.utils.IntegerUtils;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import lombok.extern.slf4j.Slf4j;import org.apache.commons.codec.binary.Base64;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.util.CollectionUtils;import org.springframework.web.bind.annotation.*;import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import java.nio.charset.StandardCharsets;import java.security.spec.AlgorithmParameterSpec;import java.util.List;import java.util.Set;/** * @author Tellsea * @date 2021/11/09 */@Slf4j@Api(value = "微信API", tags = {"微信API"})@RestController@RequestMapping("/au/weiXin")public class AuWeiXinController { @Autowired private ISysUserService userService; @Autowired private SysLoginService loginService; @Autowired private WeiXinService weiXinService; @Autowired private SysPermissionService permissionService; @Autowired private TokenService tokenService; @ApiOperation("微信用户登录") @PostMapping("login") public AjaxResult login(@RequestBody WeiXinLogin dto) { Code2Session code2Session = weiXinService.code2Session(dto.getCode()); if (StringUtils.isNotEmpty(code2Session.getOpenId())) { // 解析电话号码 String phoneNumber; byte[] byEncrypdata = Base64.decodeBase64(dto.getEncryptedData()); byte[] byIvdata = Base64.decodeBase64(dto.getIv()); byte[] bySessionkey = Base64.decodeBase64(code2Session.getSessionKey()); AlgorithmParameterSpec ivSpec = new IvParameterSpec(byIvdata); try { SecretKeySpec keySpec = new SecretKeySpec(bySessionkey, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); String phoneResult = new String(cipher.doFinal(byEncrypdata), StandardCharsets.UTF_8); JSONObject phoneObject = JSONObject.parseObject(phoneResult); phoneNumber = phoneObject.getString("phoneNumber"); } catch (Exception e) { e.printStackTrace(); return AjaxResult.error("手机号码解密失败"); } // 根据openId查询是否存在这个用户 List<SysUser> list = userService.list(new LambdaQueryWrapper<SysUser>().eq(SysUser::getOpenId, code2Session.getOpenId()) .or().eq(SysUser::getUserName, phoneNumber).or().eq(SysUser::getPhonenumber, phoneNumber)); AjaxResult ajax = AjaxResult.success(); if (CollectionUtils.isEmpty(list)) { // 添加新用户 String defaultPassword = "111111"; SysUser user = new SysUser() .setOpenId(code2Session.getOpenId()) .setUserName(phoneNumber) .setNickName(dto.getNickName()) .setDeptId(0L) .setPassword(defaultPassword) .setPhonenumber(phoneNumber) .setAvatar(dto.getAvatarUrl()); if (IntegerUtils.eq(dto.getGender(), 0)) { user.setSex("2"); } else if (IntegerUtils.eq(dto.getGender(), 1)) { user.setSex("0"); } else if (IntegerUtils.eq(dto.getGender(), 2)) { user.setSex("1"); } if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName()))) { return AjaxResult.error("手机号已被注册"); } else if (Validator.isNotEmpty(user.getPhonenumber()) && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) { return AjaxResult.error("手机号已被使用"); } user.setCreateBy(SecurityUtils.getUsername()); user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); // 默认给角色用户 user.setRoleIds(new Long[]{1L}); userService.insertUser(user); String token = loginService.login(user.getUserName(), defaultPassword); ajax.put(Constants.TOKEN, token); return ajax; } else if (list.size() == 1) { // 更新用户信息:这里查询出的一个信息,可能是openId、userName、phonenumber三个字段其中某个查出来的 SysUser sysUser = list.get(0); sysUser.setNickName(dto.getNickName()); sysUser.setAvatar(dto.getAvatarUrl()); if (IntegerUtils.eq(dto.getGender(), 0)) { sysUser.setSex("2"); } else if (IntegerUtils.eq(dto.getGender(), 1)) { sysUser.setSex("0"); } else if (IntegerUtils.eq(dto.getGender(), 2)) { sysUser
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/123142.html
摘要:优雅解决微信小程序授权登录需要触发聊一聊最近的一个项目,这个项目是一个收书售书的小程序,有商城专栏信息发布论坛等功能。微信不会把的有效期告知开发者。 优雅解决微信小程序授权登录需要button触发 聊一聊最近的一个项目,这个项目是一个收书、售书的小程序,有商城、专栏、信息发布论坛等功能。虽然不是面向所有用户,但要求无论用户是否授权都皆可使用,但同时也要求部分功能对不授权的用户限制开放。...
摘要:传统的网页编程采用的三剑客来实现,在微信小程序中同样有三剑客。观察者模式不难实现,重点是如何在微信小程序中搭配其特有的生命周期来使用。交互事件传统的事件传递类型有冒泡型与捕获型,微信小程序中自然也有。 本文由作者邹永胜授权网易云社区发布。 简介为了更好的展示我们即时通讯SDK强悍的能力,网易云信IM SDK微信小程序DEMO的开发就提上了日程。用产品的话说就是: 云信 IM 小程序 S...
摘要:注没有在微信开放平台做开发者资质认证的就不要浪费时间了,没认证无法获取,认证费用元年,微信授权登录流程第一步获取用户临时登录凭证第二步获取加密过的数据和解密参数第三步把步骤一二中的传到开发者自己服务端第三步服务端获取到之后用方法请求如下微信 注:没有在微信开放平台做开发者资质认证的就不要浪费时间了,没认证无法获取unionId,认证费用300元/年,emmmm.... 微信授权登录流程...
摘要:总结本文以微信小程序常规的发布流程为切入点,循序渐进地介绍了如何集成实现微信小程序预览上传功能。 showImg(https://raw.githubusercontent.com/yingye/Blog/master/images/wechat-jenkins.png); 本文首发于 https://github.com/yingye/Blo... ,欢迎各位关注我的Blog,正文以...
阅读 3766·2021-11-12 10:34
阅读 2795·2021-09-22 15:14
阅读 763·2019-08-30 15:53
阅读 3164·2019-08-30 12:53
阅读 1260·2019-08-29 18:32
阅读 2740·2019-08-29 16:41
阅读 1042·2019-08-26 13:40
阅读 1778·2019-08-23 18:07