合并develop分支,发布最新正式版

* art:证书类配置读取优化调整

* new:电商收付通二级商户进件

* art:微信服务商配置优化

* new:jsapi合单支付

* new:合单支付

* 🎨 #1733 微信支付服务商配置优化,增加服务商合单支付接口

* art:微信服务商配置优化

* new:jsapi合单支付

* new:合单支付

Co-authored-by: 曾浩 <epdcgsi@dingtalk.com>

* 🎨 优化代码

* 🎨 优化重构并统一公众号和小程序的spring boot starter部分配置类和属性

* 🎨 优化企业微信消息发送接口代码,引入moco模拟测试组件,方便测试代码

* 🎨 #1722 企业微信增加互联企业发送应用消息的接口,并重构消息相关类的包结构

* 🎨 优化代码,使用java8自带的Base64类

* 🐛 #1738 修复企业微信创建用户接口自定义字段缺失的问题

* 🎨 升级依赖的Spring Boot版本为最新,并优化部分代码

* 🔖  发布 3.9.1.B 测试版本

* 🎨 #1743 企业微信获取客户群详情接口增加unionId属性

获取客户群详情对象中 增加 unionId属性

* new:电商收付通普通支付

* 🆕 #1744 微信支付增加电商收付通-普通支付相关接口

* new:电商收付通普通支付

Co-authored-by: 曾浩 <epdcgsi@dingtalk.com>

* new:电商收付通支付回调处理

* new:电商收付通支付回调处理

* 🆕 #1749 微信支付增加电商收付通支付回调处理相关方法


* new:电商收付通支付回调处理

Co-authored-by: 曾浩 <epdcgsi@dingtalk.com>

* 🎨 #1752 微信支付电商收付通二级商户进件时店铺信息增加小程序appid字段

* 🎨 优化部分代码

* 电商收付通支付调整

* 🎨 电商收付通支付接口调整

经测试小程序支付时不能使用服务商的appId签名,故增加方法返回微信接口返回的结果。

* 🎨 #1756 解决wx-java-open-spring-boot-starter中Redisson实现缺少database设置的问题

* 🎨 #1753 小程序直播部分接口代码优化重构,对照官方文档补充新增参数

* 🎨 #1747 微信支付分回调通知对象类增加缺失参数:回调摘要summary

* 🆕 #1758 微信支付增加电商收付通服务商和二级商户余额查询接口

* 🆕 #1759 微信支付增加电商收付通请求分账接口

* 增加微信收付通请求分账接口

* 🆕 #1723 企业微信增加查询应用消息发送统计的接口

* 🔖 发布 3.9.2.B 测试版本

* 🆕 #1764 微信支付电商收付通增加请求分账回退接口

* 🐛 #1766 修复电商收付通请求分账结果类未添加相关注解的问题

* 微信收付通增加请求分账回退接口

* 修复请求分账结果未添加lombok注解

* fix:电商收付通回调通知测试

* 🆕 #1768 微信支付增加电商收付通完结分账和退款接口

* 微信收付通增加完结分账和退款接口

* 🆕 #1767 企业微信外部联系人增加修改客户备注信息的接口

* 🎨 优化部分代码

* 🎨 #1646 企业微信第三方应用(服务商)模块重构实现,并提供Router、Interceptor、Handler等接口

* 🎨 #1755 完善补充第三方平台小程序相关的部分错误码

* 🎨 优化企业微信群机器人发送消息的相关接口,提供无需提前设置webhookKey即可使用的重构方法

* 🆕 #1675 企业微信增加创建日历的接口,以及相关回调事件消息通知的支持

* 🔖 发布 3.9.3.B 测试版本

* new:电商收付通合单支付、普通支付查询

* new:电商收付通商户、平台提现

* fix:命名统一调整

* 🆕  #1772 电商收付通增加支付结果查询和提现的接口

* new:分账查询、退款通知

* new:修改结算账户、退款查询

* 🆕 #1775 微信支付电商收付通增加修改二级商户结算账户和退款查询的接口

* 🐛 #1777 XML工具类修复无法解析<ExtAttr><Item>这种节点数据的问题

* 🎨 WxMpMessageRouter增加构造方法

* 🎨 升级依赖jodd-http版本,并修复不兼容代码

* 🎨 优化GraalProcessor代码

* #1782 微信支付修复分账回退查询接口签名错误的问题

Co-authored-by: lmh <lmh@weiyian.com>

* 🆕 #1774 企业微信增加系统审批事件推送的事件常量

* 🎨 优化代码

* 🎨 #1785 公众号 spring boot starter 模块增加接口自定义主机地址和redis sentinel的配置

* 🔖  发布 3.9.4.B 测试版本

* fix:字段错误

* 🆕 #1789 微信支付电商收付通增加下载账单的接口

* 🆕 #1793 企业微信添加应用管理的设置工作台自定义展示模块 

Co-authored-by: sysong <sysong@chutianyun.gov.cn>

* 🎨 优化公众号Spring Boot Starter的redisTemplate注入等代码

* 🎨 优化代码,提供toString方法,避免某些情况下出现的问题

* 🆕 #1675 企业微信增加更新、查询和删除日历的接口

* 🆕 #1686 微信公众号增加对话能力(原导购助手)部分接口,如添加顾问、获取顾问信息等

* 🆕 #1686 微信公众号增加对话能力(原导购助手)部分接口,如修改顾问、删除顾问、获取顾问列表等

* 🎨 #1797 企业微信配置客户联系「联系我」方式接口返回增加二维码链接字段

新增联系我二维码链接,仅在scene为2时返回

* 🎨 优化部分代码,重构OAuth2网页授权、网页登录等相关接口,方便接入open模块

* 🐛  修复字段错误

Co-authored-by: 曾浩 <epdcgsi@dingtalk.com>

* 🆕 #1725 微信支付分增加免确认模式(预授权方式)相关接口支持

* 🆕 #1806 开放平台增加第三方平台代公众号实现复用公众号资料快速创建小程序的接口

* 🆕 微信开发平台模块增加OAuth2相关接口(网页授权、网页登录等)的实现

* 🎨 优化部分代码,明确出错信息

* 🔖 发布 3.9.5.B 测试版本

* 🆕 #1817 企业微信增加批量获取外部联系人详情的接口,同时修复外部联系人中listGroupChat参数失效问题

* 🎨 优化代码,实现序列化接口

* 🎨 #1820 优化更新getTicket方法,调整锁调用时机避免并发问题

* Fix:调整获取相关票据的锁处理时机

* Fix:更新票据,锁之后,再次检查是否有效,避免并发同时进入多次重置票据

Co-authored-by: weiwei.xing <weiwei.xing@nplusgroup.com>

* Update CONTRIBUTING.md

* 🆕 #1814 微信支付解析扫码支付回调通知增加签名类型的重载方法

* 🔖 发布 3.9.6.B 测试版本

* 🎨 重构部分包结构

* 🎨 #1827 微信支付分相关接口优化

1. 将原有请求模型类中一些基础数据类型改为对应的包装类,因为在用户没有显式set的情况下,这些基础数据类型序列化为json时也会以默认值的形式作为参数传到微信端,造成微信端返回错误。
2. 微信支付分相关的回调数据处理方法加上签名验证。
3. 增加方法授权/解除授权服务回调数据处理

* 🎨 #1832 微信支付电商收付通增加查询提现状态的接口

* 🐛 #1824 微信支付修复分账回退接口结果错误码解析错误的问题

* 🎨 #1834 微信会员卡基本信息类增加缺少字段 use_limit

* 🐛 #1828 修复企业微信第三方应用消息路由相关方法参数错误的问题

* 🆕 #1831 生成小程序二维码的相关接口增加指定文件路径参数的重载方法

* 🔖 发布 3.9.7.B 测试版本

* 🎨 #1848 刷卡支付接口响应结果类增加服务商调用时的返回字段

* 🎨 增加点注释

* 🎨 #1849 企业微信外部联系人相关接口重构,优化重复代码,同时获取客户详情接口返回增加标签id字段

* 🎨 Update javadoc for WxMaQrcodeService.java

* 🐛 #1852 修复个性化菜单clientPlatformType字段的反序列化问题

* 🎨 补充完善单元测试

* 🐛 #1856 【微信支付】修复电商收付通查询退款状态的接口地址

* 🎨 #1857 【企业微信】获取获取部门成员详情接口返回值增加第三方应用专有的open_userid字段

* 🔖 发布 3.9.8.B 测试版本

* 🎨 修复out_trade_no 字段命名不规范问题

Co-authored-by: vcpgfw <zhaopf@xtkg.com>

* 📝  add more cases

* 🐛 #1861【微信支付】支付分后付费项目请求类的amount属性改为Integer,允许为空

* 🐛 #1864 【微信支付】WxPayConfig类的hashCode和equals方法移除 verifier 字段

* 🆕 #1863 【小程序】增加删除直播间、编辑直播间、获取直播间推流地址、获取直播间分享二维码等接口

* 🎨 #1867【企业微信】优化完善第三方应用的接入代码

* 🆕 #1869 【小程序】增加管理直播间小助手的相关接口

* 🆕 #1868 【微信支付】增加通用上传图片接口,支持传入流和文件名参数

* 🎨 优化代码,部分类增加序列化接口实现

* 🎨 增加点单元测试示例代码

* 🔖 发布 3.9.9.B 测试版本

* ⬆️ 升级xstream版本

* ⬆️ Bump xstream

Bumps [xstream](https://github.com/x-stream/xstream) from 1.4.10-java7 to 1.4.13-java7.
- [Release notes](https://github.com/x-stream/xstream/releases)
- [Commits](https://github.com/x-stream/xstream/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* 🆕 #1873 【企业微信】第三方应用增加网页授权登陆获取访问用户身份和获取访问用户敏感信息的接口

* 🐛 修复字段错误问题

* 🐛 #1883【公众号】修复卡券导入code接口错误的返回类型

* 🎨 规范变量名

* 🆕  #1885 【微信支付】电商收付通增加资金账单下载的接口

* 🆕 #1866 【小程序】 增加提审素材上传接口请求执行器

* 🎨 重构规范小程序部分代码包结构

* 🎨 #1888【企业微信】补充完善OA审批回调事件消息部分字段缺失的问题

* 🆕 #1746: 【企业微信】第三方应用增加授权配置接口,同时增加向员工付款的接口

* 🎨 #1886 【小程序】创建直播间接口增加二维码地址字段

* 🔖 发布 4.0.0 正式版本

Co-authored-by: 曾浩 <epdcgsi@dingtalk.com>
Co-authored-by: cloudX <epdcgsi@163.com>
Co-authored-by: Boris <borisbao@users.noreply.github.com>
Co-authored-by: f00lish <f00lish@qq.com>
Co-authored-by: TomLiu <tomliuchangsha@hotmail.com>
Co-authored-by: giveme0101 <xiajun94@qq.com>
Co-authored-by: lmh <991564110@qq.com>
Co-authored-by: lmh <lmh@weiyian.com>
Co-authored-by: Dream2Land <346570926@qq.com>
Co-authored-by: amhere <songshiyu555@163.com>
Co-authored-by: sysong <sysong@chutianyun.gov.cn>
Co-authored-by: 静宏 <acvrock.cn@gmail.com>
Co-authored-by: spvycf <545997765@qq.com>
Co-authored-by: alucardxh <alucardxh@163.com>
Co-authored-by: jn老A <sytu_xww@163.com>
Co-authored-by: weiwei.xing <weiwei.xing@nplusgroup.com>
Co-authored-by: winter <winter4666@foxmail.com>
Co-authored-by: gentryhuang <gentryhuang.xw@gmail.com>
Co-authored-by: Kidwind <Kidwind@gmail.com>
Co-authored-by: zacks <zacksleo@gmail.com>
Co-authored-by: wcc1433 <37837522+wcc1433@users.noreply.github.com>
Co-authored-by: Pancras <coder.zpf@gmail.com>
Co-authored-by: vcpgfw <zhaopf@xtkg.com>
Co-authored-by: JoeWoo <xjoewoo@gmail.com>
Co-authored-by: 微同科技 <30375770+lipengjun92@users.noreply.github.com>
Co-authored-by: xworks <jzqlin@gmail.com>
Co-authored-by: GaoMinzhu <31923767+GaoMinzhu@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: huangxm129 <40385667+huangxm129@users.noreply.github.com>
Co-authored-by: ly8388 <49558207+ly8388@users.noreply.github.com>
Co-authored-by: yangyh22 <9944784+yangyh22@users.noreply.github.com>
Co-authored-by: Gyv12345 <gyv12345@163.com>
Co-authored-by: LinXiaoHuChong <louisquiet@gmail.com>
This commit is contained in:
Binary Wang
2020-11-29 23:54:57 +08:00
committed by GitHub
parent 0bb343dfda
commit d2f5adcb40
423 changed files with 16627 additions and 2385 deletions

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>3.9.0</version>
<version>4.0.0</version>
</parent>
<artifactId>weixin-java-open</artifactId>
@ -122,7 +122,7 @@
<version>3.5.1</version>
<configuration>
<annotationProcessors>
cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor
com.github.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor
</annotationProcessors>
<annotationProcessorPaths>
<path>

View File

@ -2,8 +2,7 @@ package me.chanjar.weixin.open.api;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.open.bean.WxOpenCreateResult;
import me.chanjar.weixin.open.bean.WxOpenGetResult;
import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate;
@ -133,7 +132,7 @@ public interface WxOpenComponentService {
* @param appid the appid
* @return the wx mp service by appid
*/
WxMpService getWxMpServiceByAppid(String appid);
WxOpenMpService getWxMpServiceByAppid(String appid);
/**
* 获取指定appid的开放平台小程序服务继承一般小程序服务能力.
@ -332,7 +331,7 @@ public interface WxOpenComponentService {
* @return the wx mp o auth 2 access token
* @throws WxErrorException the wx error exception
*/
WxMpOAuth2AccessToken oauth2getAccessToken(String appid, String code) throws WxErrorException;
WxOAuth2AccessToken oauth2getAccessToken(String appid, String code) throws WxErrorException;
/**
* Check signature boolean.
@ -353,7 +352,7 @@ public interface WxOpenComponentService {
* @return the wx mp o auth 2 access token
* @throws WxErrorException the wx error exception
*/
WxMpOAuth2AccessToken oauth2refreshAccessToken(String appid, String refreshToken) throws WxErrorException;
WxOAuth2AccessToken oauth2refreshAccessToken(String appid, String refreshToken) throws WxErrorException;
/**
* Oauth 2 build authorization url string.

View File

@ -0,0 +1,47 @@
package me.chanjar.weixin.open.api;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.open.bean.mp.FastRegisterResult;
/**
* <pre>
* 微信开放平台代公众号实现服务能力
* https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489144594_DhNoV&token=&lang=zh_CN
* </pre>
* <p>
* Created by zpf on 2020/10/15
*/
public interface WxOpenMpService extends WxMpService {
/**
* 取复用公众号快速注册小程序的授权链接.
*/
String URL_FAST_REGISTER_AUTH = "https://mp.weixin.qq.com/cgi-bin/fastregisterauth?appid=%s&component_appid=%s&copy_wx_verify=%s&redirect_uri=%s";
/**
* 复用公众号快速注册小程序
*/
String API_FAST_REGISTER = "https://api.weixin.qq.com/cgi-bin/account/fastregister";
/**
* 取复用公众号快速注册小程序的授权链接
* https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/fast_registration_of_mini_program.html
*
* @param redirectUri 用户扫码授权后MP 扫码页面将跳转到该地址(注:1.链接需 urlencode 2.Host 需和第三方平台在微信开放平台上面填写的登 录授权的发起页域名一致)
* @param copyWxVerify 是否复用公众号的资质进行微信认证,可空,默认false
* @return 返回授权链接 注意由于微信开放平台限制此链接直接使用后端301重定向微信会报错必须是在第三方平台所在域名的页面的html或js触发跳转才能成功
*/
String getFastRegisterAuthUrl(String redirectUri, Boolean copyWxVerify);
/**
* 复用公众号快速注册小程序
* 注意:调用本接口的第三方平台必须是已经全网发布的,否则微信会报-1服务器繁忙错误然后再报ticket无效错误并且接口的使用次数会增加同时还会生成一个废小程序
* https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/fast_registration_of_mini_program.html
*
* @param ticket 公众号扫码授权的凭证(公众平台扫码页面回跳到第三方平台时携带)
* @return 返回授权码, 然后请使用第三方平台的sdk获得授权, 参考: WxOpenService.getWxOpenComponentService().getQueryAuth( fastRegisterResult.getAuthorizationCode() );
* @throws WxErrorException the wx error exception
*/
FastRegisterResult fastRegister(String ticket) throws WxErrorException;
}

View File

@ -8,12 +8,13 @@ import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.error.WxRuntimeException;
import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.common.util.json.GsonParser;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.open.api.*;
import me.chanjar.weixin.open.bean.*;
import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo;
@ -36,14 +37,14 @@ import java.util.concurrent.locks.Lock;
public class WxOpenComponentServiceImpl implements WxOpenComponentService {
private static final Map<String, WxOpenMaService> WX_OPEN_MA_SERVICE_MAP = new ConcurrentHashMap<>();
private static final Map<String, WxMpService> WX_OPEN_MP_SERVICE_MAP = new ConcurrentHashMap<>();
private static final Map<String, WxOpenMpService> WX_OPEN_MP_SERVICE_MAP = new ConcurrentHashMap<>();
private static final Map<String, WxOpenFastMaService> WX_OPEN_FAST_MA_SERVICE_MAP = new ConcurrentHashMap<>();
private final WxOpenService wxOpenService;
@Override
public WxMpService getWxMpServiceByAppid(String appId) {
WxMpService wxMpService = WX_OPEN_MP_SERVICE_MAP.get(appId);
public WxOpenMpService getWxMpServiceByAppid(String appId) {
WxOpenMpService wxMpService = WX_OPEN_MP_SERVICE_MAP.get(appId);
if (wxMpService == null) {
synchronized (WX_OPEN_MP_SERVICE_MAP) {
wxMpService = WX_OPEN_MP_SERVICE_MAP.get(appId);
@ -381,10 +382,10 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
WxOpenAuthorizerAccessToken wxOpenAuthorizerAccessToken = WxOpenAuthorizerAccessToken.fromJson(responseContent);
config.updateAuthorizerAccessToken(appId, wxOpenAuthorizerAccessToken);
config.updateAuthorizerRefreshToken(appId,wxOpenAuthorizerAccessToken.getAuthorizerRefreshToken());
config.updateAuthorizerRefreshToken(appId, wxOpenAuthorizerAccessToken.getAuthorizerRefreshToken());
return config.getAuthorizerAccessToken(appId);
} catch (InterruptedException e) {
throw new RuntimeException(e);
throw new WxRuntimeException(e);
} finally {
if (locked) {
lock.unlock();
@ -393,10 +394,10 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
}
@Override
public WxMpOAuth2AccessToken oauth2getAccessToken(String appId, String code) throws WxErrorException {
public WxOAuth2AccessToken oauth2getAccessToken(String appId, String code) throws WxErrorException {
String url = String.format(OAUTH2_ACCESS_TOKEN_URL, appId, code, getWxOpenConfigStorage().getComponentAppId());
String responseContent = get(url);
return WxMpOAuth2AccessToken.fromJson(responseContent);
return WxOAuth2AccessToken.fromJson(responseContent);
}
@Override
@ -405,10 +406,10 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
}
@Override
public WxMpOAuth2AccessToken oauth2refreshAccessToken(String appId, String refreshToken) throws WxErrorException {
public WxOAuth2AccessToken oauth2refreshAccessToken(String appId, String refreshToken) throws WxErrorException {
String url = String.format(OAUTH2_REFRESH_TOKEN_URL, appId, refreshToken, getWxOpenConfigStorage().getComponentAppId());
String responseContent = get(url);
return WxMpOAuth2AccessToken.fromJson(responseContent);
return WxOAuth2AccessToken.fromJson(responseContent);
}
@Override
@ -488,7 +489,7 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
result = maService.post(requestUrl, param.toString());
return result;
default:
throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("appIdType类型异常").build());
throw new WxErrorException("appIdType类型异常");
}
}

View File

@ -4,7 +4,7 @@ import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import me.chanjar.weixin.common.error.WxErrorException;

View File

@ -1,15 +1,22 @@
package me.chanjar.weixin.open.api.impl;
import com.google.common.collect.ImmutableMap;
import lombok.SneakyThrows;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.open.api.WxOpenComponentService;
import me.chanjar.weixin.open.api.WxOpenMpService;
import me.chanjar.weixin.open.bean.mp.FastRegisterResult;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Objects;
/**
* @author <a href="https://github.com/007gzs">007</a>
*/
public class WxOpenMpServiceImpl extends WxMpServiceImpl {
public class WxOpenMpServiceImpl extends WxMpServiceImpl implements WxOpenMpService {
private WxOpenComponentService wxOpenComponentService;
private WxMpConfigStorage wxMpConfigStorage;
private String appId;
@ -31,4 +38,18 @@ public class WxOpenMpServiceImpl extends WxMpServiceImpl {
return wxOpenComponentService.getAuthorizerAccessToken(appId, forceRefresh);
}
@SneakyThrows
@Override
public String getFastRegisterAuthUrl(String redirectUri, Boolean copyWxVerify) {
String copyInfo = Objects.equals(copyWxVerify, false) ? "0" : "1";
String componentAppId = wxOpenComponentService.getWxOpenConfigStorage().getComponentAppId();
String encoded = URLEncoder.encode(redirectUri, "UTF-8");
return String.format(URL_FAST_REGISTER_AUTH, appId, componentAppId, copyInfo, encoded);
}
@Override
public FastRegisterResult fastRegister(String ticket) throws WxErrorException {
String json = post(API_FAST_REGISTER, ImmutableMap.of("ticket", ticket));
return FastRegisterResult.fromJson(json);
}
}

View File

@ -0,0 +1,79 @@
package me.chanjar.weixin.open.api.impl;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.error.WxRuntimeException;
import me.chanjar.weixin.common.service.WxOAuth2Service;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.URIUtil;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.OAuth2.*;
/**
* oauth2接口实现.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* @date 2020-10-19
*/
@AllArgsConstructor
public class WxOpenOAuth2ServiceImpl extends WxOpenServiceImpl implements WxOAuth2Service {
private final String appId;
private final String appSecret;
@Override
public String buildAuthorizationUrl(String redirectUri, String scope, String state) {
return String.format(CONNECT_OAUTH2_AUTHORIZE_URL.getUrl(null),
this.appId, URIUtil.encodeURIComponent(redirectUri), scope, StringUtils.trimToEmpty(state));
}
private WxOAuth2AccessToken getOAuth2AccessToken(String url) throws WxErrorException {
return WxOAuth2AccessToken.fromJson(this.get(url, null));
}
@Override
public WxOAuth2AccessToken getAccessToken(String code) throws WxErrorException {
return this.getAccessToken(this.appId, this.appSecret, code);
}
@Override
public WxOAuth2AccessToken getAccessToken(String appId, String appSecret, String code) throws WxErrorException {
return this.getOAuth2AccessToken(String.format(OAUTH2_ACCESS_TOKEN_URL.getUrl(null), appId, appSecret, code));
}
@Override
public WxOAuth2AccessToken refreshAccessToken(String refreshToken) throws WxErrorException {
String url = String.format(OAUTH2_REFRESH_TOKEN_URL.getUrl(null), this.appId, refreshToken);
return this.getOAuth2AccessToken(url);
}
@Override
public WxOAuth2UserInfo getUserInfo(WxOAuth2AccessToken token, String lang) throws WxErrorException {
if (lang == null) {
lang = "zh_CN";
}
String url = String.format(OAUTH2_USERINFO_URL.getUrl(null), token.getAccessToken(), token.getOpenId(), lang);
return WxOAuth2UserInfo.fromJson(this.get(url, null));
}
@Override
public boolean validateAccessToken(WxOAuth2AccessToken token) {
String url = String.format(OAUTH2_VALIDATE_TOKEN_URL.getUrl(null), token.getAccessToken(), token.getOpenId());
try {
SimpleGetRequestExecutor.create(this).execute(url, null, WxType.MP);
} catch (IOException e) {
throw new WxRuntimeException(e);
} catch (WxErrorException e) {
return false;
}
return true;
}
}

View File

@ -3,6 +3,7 @@ package me.chanjar.weixin.open.api.impl;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.error.WxRuntimeException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.open.api.WxOpenComponentService;
@ -56,7 +57,7 @@ public abstract class WxOpenServiceAbstractImpl<H, P> implements WxOpenService,
return null;
} catch (IOException e) {
this.log.error("\n【请求地址】: {}\n【请求参数】{}\n【异常信息】{}", uri, data, e.getMessage());
throw new RuntimeException(e);
throw new WxRuntimeException(e);
}
}
}

View File

@ -4,6 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxRuntimeException;
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
@ -149,7 +150,7 @@ public class WxOpenXmlMessage implements Serializable {
return fromEncryptedXml(IOUtils.toString(is, StandardCharsets.UTF_8),
wxOpenConfigStorage, timestamp, nonce, msgSignature);
} catch (IOException e) {
throw new RuntimeException(e);
throw new WxRuntimeException(e);
}
}
}

View File

@ -0,0 +1,39 @@
package me.chanjar.weixin.open.bean.mp;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import java.io.Serializable;
/**
* 复用公众号资料快速注册小程序结果
*
* @author someone
*/
@Data
public class FastRegisterResult implements Serializable {
private static final long serialVersionUID = 9046726183433147089L;
/**
* 小程序AppId
*/
@SerializedName("appid")
private String appId;
/**
* 授权码,然后请使用第三方平台的sdk获得授权, 参考: WxOpenService.getWxOpenComponentService().getQueryAuth( this.getAuthorizationCode() );
*/
@SerializedName("authorization_code")
private String authorizationCode;
/**
* 是否与公众号关联成功
*/
@SerializedName("is_wx_verify_succ")
private Boolean isWxVerifySucc;
public static FastRegisterResult fromJson(String json) {
return WxGsonBuilder.create().fromJson(json, FastRegisterResult.class);
}
}

View File

@ -19,6 +19,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
/**
@ -49,7 +50,7 @@ public class MaQrCodeJoddHttpRequestExecutor extends MaQrCodeRequestExecutor<Htt
request.withConnectionProvider(requestHttp.getRequestHttpClient());
HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());
String contentTypeHeader = response.header("Content-Type");
if (MimeTypes.MIME_TEXT_PLAIN.equals(contentTypeHeader)) {
String responseContent = response.bodyText();

View File

@ -38,7 +38,7 @@ public abstract class MaQrCodeRequestExecutor<H, P> implements RequestExecutor<F
case OK_HTTP:
return new MaQrCodeOkhttpRequestExecutor(requestHttp);
default:
throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("不支持的http框架").build());
throw new WxErrorException("不支持的http框架");
}
}

View File

@ -0,0 +1,51 @@
package me.chanjar.weixin.open.api.impl;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
/**
* 单元测试.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* @date 2020-10-19
*/
public class WxOpenOAuth2ServiceImplTest {
private final WxOpenOAuth2ServiceImpl service = new WxOpenOAuth2ServiceImpl("123", "");
@BeforeTest
public void init() {
this.service.setWxOpenConfigStorage(new WxOpenInMemoryConfigStorage());
}
@Test
public void testBuildAuthorizationUrl() {
this.service.buildAuthorizationUrl("", "", "");
}
@Test
public void testGetAccessToken() throws WxErrorException {
this.service.getAccessToken("a");
}
@Test
public void testTestGetAccessToken() throws WxErrorException {
this.service.getAccessToken("", "", "");
}
@Test
public void testRefreshAccessToken() throws WxErrorException {
this.service.refreshAccessToken("");
}
@Test
public void testGetUserInfo() throws WxErrorException {
this.service.getUserInfo(new WxOAuth2AccessToken(), "");
}
@Test
public void testValidateAccessToken() {
this.service.validateAccessToken(new WxOAuth2AccessToken());
}
}