我這里采用了第三方的依賴,目前是最火的微信開發(fā)工具吧,WxJava
引入相關(guān)依賴
<dependency> <groupId>com.github.binarywanggroupId> <artifactId>weixin-java-payartifactId> <version>4.1.0version> dependency>
配置application.yml
# ----------------------系統(tǒng)配置# 業(yè)務(wù)配置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 { /** * 設(shè)置微信公眾號(hào)或者小程序等的appid */ private String appId; private String secret; /** * 微信支付商戶號(hào) */ private String mchId; /** * 微信支付商戶密鑰 */ private String mchKey; /** * 服務(wù)商模式下的子商戶公眾賬號(hào)ID,普通模式請(qǐng)不要配置,請(qǐng)?jiān)谂渲梦募袑?duì)應(yīng)項(xiàng)刪除 */ private String subAppId; /** * 服務(wù)商模式下的子商戶號(hào),普通模式請(qǐng)不要配置,最好是請(qǐng)?jiān)谂渲梦募袑?duì)應(yīng)項(xiàng)刪除 */ private String subMchId; /** * apiclient_cert.p12文件的絕對(duì)路徑,或者如果放在項(xiàng)目中,請(qǐng)以classpath:開頭指定 */ private String keyPath; /** * 支付回調(diào)地址 */ 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())); // 可以指定是否使用沙箱環(huán)境 payConfig.setUseSandboxEnv(false); WxPayService wxPayService = new WxPayServiceImpl(); wxPayService.setConfig(payConfig); return wxPayService; }}
相關(guān)實(shí)體類,都可以使用json的map格式來處理,我這里是個(gè)人習(xí)慣
import lombok.Data;import lombok.experimental.Accessors;/** * 接口調(diào)用憑證 * 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; /** * 憑證有效時(shí)間,單位:秒。目前是7200秒之內(nèi)的值。 */ 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())) { // 解析電話號(hào)碼 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("手機(jī)號(hào)碼解密失敗"); } // 根據(jù)openId查詢是否存在這個(gè)用戶 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("手機(jī)號(hào)已被注冊(cè)"); } else if (Validator.isNotEmpty(user.getPhonenumber()) && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) { return AjaxResult.error("手機(jī)號(hào)已被使用"); } user.setCreateBy(SecurityUtils.getUsername()); user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); // 默認(rèn)給角色用戶 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) { // 更新用戶信息:這里查詢出的一個(gè)信息,可能是openId、userName、phonenumber三個(gè)字段其中某個(gè)查出來的 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
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/123142.html
摘要:優(yōu)雅解決微信小程序授權(quán)登錄需要觸發(fā)聊一聊最近的一個(gè)項(xiàng)目,這個(gè)項(xiàng)目是一個(gè)收書售書的小程序,有商城專欄信息發(fā)布論壇等功能。微信不會(huì)把的有效期告知開發(fā)者。 優(yōu)雅解決微信小程序授權(quán)登錄需要button觸發(fā) 聊一聊最近的一個(gè)項(xiàng)目,這個(gè)項(xiàng)目是一個(gè)收書、售書的小程序,有商城、專欄、信息發(fā)布論壇等功能。雖然不是面向所有用戶,但要求無論用戶是否授權(quán)都皆可使用,但同時(shí)也要求部分功能對(duì)不授權(quán)的用戶限制開放。...
摘要:傳統(tǒng)的網(wǎng)頁編程采用的三劍客來實(shí)現(xiàn),在微信小程序中同樣有三劍客。觀察者模式不難實(shí)現(xiàn),重點(diǎn)是如何在微信小程序中搭配其特有的生命周期來使用。交互事件傳統(tǒng)的事件傳遞類型有冒泡型與捕獲型,微信小程序中自然也有。 本文由作者鄒永勝授權(quán)網(wǎng)易云社區(qū)發(fā)布。 簡介為了更好的展示我們即時(shí)通訊SDK強(qiáng)悍的能力,網(wǎng)易云信IM SDK微信小程序DEMO的開發(fā)就提上了日程。用產(chǎn)品的話說就是: 云信 IM 小程序 S...
摘要:注沒有在微信開放平臺(tái)做開發(fā)者資質(zhì)認(rèn)證的就不要浪費(fèi)時(shí)間了,沒認(rèn)證無法獲取,認(rèn)證費(fèi)用元年,微信授權(quán)登錄流程第一步獲取用戶臨時(shí)登錄憑證第二步獲取加密過的數(shù)據(jù)和解密參數(shù)第三步把步驟一二中的傳到開發(fā)者自己服務(wù)端第三步服務(wù)端獲取到之后用方法請(qǐng)求如下微信 注:沒有在微信開放平臺(tái)做開發(fā)者資質(zhì)認(rèn)證的就不要浪費(fèi)時(shí)間了,沒認(rèn)證無法獲取unionId,認(rèn)證費(fèi)用300元/年,emmmm.... 微信授權(quán)登錄流程...
摘要:總結(jié)本文以微信小程序常規(guī)的發(fā)布流程為切入點(diǎn),循序漸進(jìn)地介紹了如何集成實(shí)現(xiàn)微信小程序預(yù)覽上傳功能。 showImg(https://raw.githubusercontent.com/yingye/Blog/master/images/wechat-jenkins.png); 本文首發(fā)于 https://github.com/yingye/Blo... ,歡迎各位關(guān)注我的Blog,正文以...
閱讀 3810·2021-11-12 10:34
閱讀 2824·2021-09-22 15:14
閱讀 793·2019-08-30 15:53
閱讀 3207·2019-08-30 12:53
閱讀 1296·2019-08-29 18:32
閱讀 2775·2019-08-29 16:41
閱讀 1071·2019-08-26 13:40
閱讀 1816·2019-08-23 18:07