diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
index c857bd1..f9692af 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
@@ -1,8 +1,10 @@
package com.ruoyi;
+import com.cyl.wechat.WechatPayData;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
/**
* 启动程序
@@ -13,6 +15,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
exclude = {DataSourceAutoConfiguration.class},
scanBasePackages = {"com.ruoyi", "com.cyl"}
)
+@EnableConfigurationProperties(WechatPayData.class)
public class RuoYiApplication {
public static void main(String[] args) {
// System.setProperty("spring.devtools.restart.enabled", "false");
diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml
index 9e41d8a..f3d9e32 100644
--- a/ruoyi-admin/src/main/resources/application-druid.yml
+++ b/ruoyi-admin/src/main/resources/application-druid.yml
@@ -45,6 +45,11 @@ aliyun:
wechat:
appId: 你的微信服务号信息
secret: 你的微信服务号信息
+ merchantId:
+ privateKeyPath:
+ merchantSerialNumber:
+ apiV3key:
+ notifyUrl:
sms:
enabled: true
# 阿里云 dysmsapi.aliyuncs.com
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index dbb6af2..9378180 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -161,6 +161,12 @@ extra:
redirect: ""
scheduling:
enabled: true
+http-pool:
+ connection-request-timeout: 10000
+ connection-timeout: 10000
+ socket-timeout: 10000
+ max-per-route: 200
+ max-total: 200
gen:
# 作者
author:
diff --git a/ruoyi-admin/src/main/resources/wechatpay/apiclient_cert.p12 b/ruoyi-admin/src/main/resources/wechatpay/apiclient_cert.p12
new file mode 100644
index 0000000..2cc1411
Binary files /dev/null and b/ruoyi-admin/src/main/resources/wechatpay/apiclient_cert.p12 differ
diff --git a/ruoyi-admin/src/main/resources/wechatpay/apiclient_cert.pem b/ruoyi-admin/src/main/resources/wechatpay/apiclient_cert.pem
new file mode 100644
index 0000000..e5d21be
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/wechatpay/apiclient_cert.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEKzCCAxOgAwIBAgIUW0mbrKuZqAqNv3ZTP/ylJOrmuIAwDQYJKoZIhvcNAQEL
+BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
+FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
+Q0EwHhcNMjMwNzEwMDMwMDA2WhcNMjgwNzA4MDMwMDA2WjCBhDETMBEGA1UEAwwK
+MTY0MDE2NTIyOTEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTAwLgYDVQQL
+DCfoi4/lt57or5rkuI7kuZDkv6Hmga/mioDmnK/mnInpmZDlhazlj7gxCzAJBgNV
+BAYMAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBALrELkqmSy8PkSk3KL3eNwQKm08xvIsrk3KKuyS7YrulQaKmqfvn
+Nh0qXfgFYCqOKlV6VBEAxSRfsNq1/NsVCa5ZGcrcHlf0iC22p81w0W0TTT4LzfRj
+tuobO/uhLhtHHaWxyVdloRirHEl5xXREvI6xstjEEG5vYyIFxR2Aufpv6e20FpZ3
+G3KiTSRFoSSHMJjOoPEeGd6nAzueqGGjdGcxNHl/a9HDyYcRMeIO9k1Wd1gcwwpu
+vinELhB1ojpzO6UekAzjM4g7QD2aAibmb0/Q+4hFw7xXOrOElt0hjKcoG+hZGlFL
+xjLCC+Z/xbLEz1jtH7mAdUG/g2Ls4pr470UCAwEAAaOBuTCBtjAJBgNVHRMEAjAA
+MAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0cDovL2V2
+Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUwREJD
+MDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0MjJFMTJC
+MjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUAA4IBAQBK
+udnDDPqczbrX8RmKcw5rixMyM5toyMtqNR1pfkWCG2QP2PmNTYBARO2tW2DZtWZm
+eLuUXZVE12FnIkEQQ65JmDEEvz8PwTSQIPCcObHUGKuj5dFWswzYEWMsqIdPfGK+
+Teb294FsTRiElDMkpt3pmYkGVxFwsAfSFZM/9Gl45HdagD4RHfvRDgB8WGx6azxX
+w/kn8CHJqLEJtbPer8cGFCih0v0LfLCy4MEHb0Si0PWoEmecTE3DtXK5gEKLFlEy
+g1Gb16LW1eEGwyfqcUmwXDE3aamL4RpxjZgzIagvsqVfPn7nDiw6fFf78Ya0ClVx
+ImJDoCe+5aH652BNZXWD
+-----END CERTIFICATE-----
diff --git a/ruoyi-admin/src/main/resources/wechatpay/apiclient_key.pem b/ruoyi-admin/src/main/resources/wechatpay/apiclient_key.pem
new file mode 100644
index 0000000..e6953ab
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/wechatpay/apiclient_key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC6xC5KpksvD5Ep
+Nyi93jcECptPMbyLK5Nyirsku2K7pUGipqn75zYdKl34BWAqjipVelQRAMUkX7Da
+tfzbFQmuWRnK3B5X9IgttqfNcNFtE00+C830Y7bqGzv7oS4bRx2lsclXZaEYqxxJ
+ecV0RLyOsbLYxBBub2MiBcUdgLn6b+nttBaWdxtyok0kRaEkhzCYzqDxHhnepwM7
+nqhho3RnMTR5f2vRw8mHETHiDvZNVndYHMMKbr4pxC4QdaI6czulHpAM4zOIO0A9
+mgIm5m9P0PuIRcO8VzqzhJbdIYynKBvoWRpRS8Yywgvmf8WyxM9Y7R+5gHVBv4Ni
+7OKa+O9FAgMBAAECggEAKlMzOm+dMjkQ6Io7jWvChAPzVmsrE074x0hxSM2+fk/h
+I/8pHpEzTkC/sulk9b/qEBz82C2Yf7m/1pDPkMafvwcqNTLVHZGpGtL+DCy5CUMK
+ijkan3vJhBxP56KLVFs1eMtlmYzKiVCdxHj4KnU5Vg0nPsCQCLbtfFRaa2k0vHAl
+LpaC+HG/nFMewTC9NBcfu+IMzs5miUgvWpkAVXvq4WcJq+ACsnc2rzDlEa7ZNaNR
+3CtHCj+f7Yhnt+U+IImIGLeh2Z1wR7dCxnuAQ02W0pWl8pIUmrL8m9LwRrgL1Rje
+Fp1DXTXKlCl3oHELz9qHfJ06K2r5laCqMV2s6esTgQKBgQDfNnev21ydMe7F6NaO
+0s1Xb4Btl9NSiCEoTjdt/w2rCFdvu0YsgutaB0J4rk2Jeyp7MlHiYkUn1X/dJlMX
+/P/hmgtnnFJotIvHFl3nHem8l10mB+MYCeI65uDOvEcXoGV+jMTZd4wzJlSC/uio
+UbsWf7ykHMW8M77fbzncY5MOiQKBgQDWMzU0NfRdVE3Y7c7vfJr2jMPhkB5ai5Cr
+PK+kCbVKALR79C4aPaUM3RmYaG61NPaylw1+czv1YxWvtiHidiGAM3t/18qbKicf
+SQxqe4uFAXWMafopThPLw9KGq0sSjOs9DDt8CIscAzAs9ykj2DT2khfAeqZdwjDo
+CVnWKtmL3QKBgQDRYMNGd2tZnPQQO0e/82dgpBwBMVCt8zm/GBeQm5YToCB8k1vQ
+9wGTkom8sCvVUW5Y36vFwk6CfheRt5hsQQs5cQlPqGf5BZq0JnvxBrMxD3715KIV
+83d9rwKjiiLZu8BYw+0G3MfrVwIhWsGc2gW3phyqiL7GundKGYhZ/iF8mQKBgATd
+BMg6sWGtGFdkjt5BJgOTDp+Adi/4G0DID/TZg5Q6j96AnMtbuvOf0YT0Wg8jNLa5
+V0UXuLTJmyRyLjLGG9ydTqCIdcEwI9NCBVYll/VdIx4dCeEGNMzblVwZZ4r0SCMK
+tA8M4puwNtfOhNCbiBhRGNj17/ERB6s9Cx0hu+7BAoGAV3nfA3JACh30oStpZQab
+CY3JJvqIFINGk1h8cY9yjlI/g6WXw6ACtIVhvy9bEOkSFgtMdCFWVLC/E836p2Qo
+38J4DLiXszt+4y8PFviVszVFZIRkHOOluRXSedDmPteu4bQCCXO4MCzC502PKcyM
+X38MmpqzqQxZoe5PbwJENR0=
+-----END PRIVATE KEY-----
diff --git a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ServiceTest.java b/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ServiceTest.java
index 6562ff6..e0ad6c7 100644
--- a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ServiceTest.java
+++ b/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ServiceTest.java
@@ -6,6 +6,9 @@ import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import com.cyl.manager.ums.service.MemberCartService;
+import com.cyl.wechat.WechatAuthService;
+import com.cyl.wechat.WechatPayService;
+import com.cyl.wechat.response.WechatUserAuth;
import com.ruoyi.RuoYiApplication;
import com.ruoyi.common.config.properties.SmsProperties;
import com.ruoyi.common.core.sms.AliyunSmsTemplate;
@@ -21,6 +24,7 @@ import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.Map;
+import java.util.UUID;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = RuoYiApplication.class)
@@ -73,4 +77,18 @@ public class ServiceTest {
long id = snowflake.nextId();
System.out.println("id:" + id);
}
+
+ @Autowired
+ private WechatPayService wechatPayService;
+ @Autowired
+ private WechatAuthService wechatAuthService;
+ @Test
+ public void test5(){
+// String code = "0611P2Ga1D8QCF0CVuJa1qNUJa11P2GL";
+// WechatUserAuth userToken = wechatAuthService.getUserToken(code);
+ String openId="oUA8I6lDdwSfz-EwR4284dU3KOYw";
+ String res = wechatPayService.jsapiPay(UUID.randomUUID().toString().substring(0,30), "测试支付", 1, openId);
+ System.out.println(res);
+
+ }
}
diff --git a/ruoyi-mall/pom.xml b/ruoyi-mall/pom.xml
index 08a3b55..30f6a37 100644
--- a/ruoyi-mall/pom.xml
+++ b/ruoyi-mall/pom.xml
@@ -23,6 +23,11 @@
ruoyi-system
${ruoyi.version}
+
+ com.github.wechatpay-apiv3
+ wechatpay-java
+ 0.2.9
+
com.baomidou
mybatis-plus-boot-starter
diff --git a/ruoyi-mall/src/main/java/com/cyl/config/RestTemplateConfig.java b/ruoyi-mall/src/main/java/com/cyl/config/RestTemplateConfig.java
new file mode 100644
index 0000000..1788a6d
--- /dev/null
+++ b/ruoyi-mall/src/main/java/com/cyl/config/RestTemplateConfig.java
@@ -0,0 +1,73 @@
+package com.cyl.config;
+
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.ClientHttpRequestFactory;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+ //从连接池获取连接的超时时间,一般设置为较短;
+ @Value("${http-pool.connection-request-timeout}")
+ private int connectionRequestTimeout;
+
+ //连接超时时间
+ @Value("${http-pool.connection-timeout}")
+ private int connectionTimeout;
+
+ //完成连接后,socket通信超时时间
+ @Value("${http-pool.socket-timeout}")
+ private int socketTimeout;
+
+ //单host(可以理解为单域名)最大并发数
+ @Value("${http-pool.max-per-route}")
+ private int maxPerRoute;
+
+ //连接池最大连接数
+ @Value("${http-pool.max-total}")
+ private int maxTotal;
+
+ @Bean
+ public RestTemplate restTemplate() {
+ return new RestTemplate(httpRequestFactory());
+ }
+
+ @Bean
+ public ClientHttpRequestFactory httpRequestFactory() {
+ return new HttpComponentsClientHttpRequestFactory(httpClient());
+ }
+
+ @Bean
+ public HttpClient httpClient() {
+ Registry registry = RegistryBuilder.create()
+ .register("http", PlainConnectionSocketFactory.getSocketFactory())
+ .register("https", SSLConnectionSocketFactory.getSocketFactory())
+ .build();
+ PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
+ //设置整个连接池最大连接数 根据自己的场景决定
+ connectionManager.setMaxTotal(maxTotal);
+ //路由是对maxTotal的细分
+ connectionManager.setDefaultMaxPerRoute(maxPerRoute);
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setSocketTimeout(socketTimeout)//服务器返回数据(response)的时间,超过该时间抛出read timeout
+ .setConnectTimeout(connectionTimeout)//连接上服务器(握手成功)的时间,超出该时间抛出connect timeout
+ .setConnectionRequestTimeout(connectionRequestTimeout)//从连接池中获取连接的超时时间,超过该时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
+ .build();
+ return HttpClientBuilder.create()
+ .setDefaultRequestConfig(requestConfig)
+ .setConnectionManager(connectionManager)
+ .build();
+ }
+}
diff --git a/ruoyi-mall/src/main/java/com/cyl/wechat/WechatAuthService.java b/ruoyi-mall/src/main/java/com/cyl/wechat/WechatAuthService.java
new file mode 100644
index 0000000..1b9de51
--- /dev/null
+++ b/ruoyi-mall/src/main/java/com/cyl/wechat/WechatAuthService.java
@@ -0,0 +1,44 @@
+package com.cyl.wechat;
+
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
+import com.cyl.wechat.response.WechatUserAuth;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+@Slf4j
+public class WechatAuthService {
+
+ @Autowired
+ private RestTemplate restTemplate;
+
+ public WechatUserAuth getUserToken(String code) {
+ Map params = new HashMap<>();
+ params.put("APPID", WechatPayData.appId);
+ params.put("SECRET", WechatPayData.secret);
+ params.put("CODE", code);
+ ResponseEntity responseEntity = restTemplate.getForEntity(
+ "https://api.weixin.qq.com/sns/oauth2/access_token?appid={APPID}&secret={SECRET}&code={CODE}&grant_type=authorization_code",
+ String.class, params);
+ String body = responseEntity.getBody();
+ try {
+ WechatUserAuth object = JSON.parseObject(body, WechatUserAuth.class);
+ if (object == null) {
+ log.error("获取user wechat accesstoken失败");
+ return null;
+ }
+ log.info("get user wechat accesstoken:{}",JSONUtil.toJsonStr(object));
+ return object;
+ } catch (Exception e) {
+ log.info("get user wechat accesstoken error",e);
+ }
+ return null;
+ }
+}
diff --git a/ruoyi-mall/src/main/java/com/cyl/wechat/WechatPayConfig.java b/ruoyi-mall/src/main/java/com/cyl/wechat/WechatPayConfig.java
new file mode 100644
index 0000000..6cd53ef
--- /dev/null
+++ b/ruoyi-mall/src/main/java/com/cyl/wechat/WechatPayConfig.java
@@ -0,0 +1,27 @@
+package com.cyl.wechat;
+
+import com.wechat.pay.java.core.Config;
+import com.wechat.pay.java.core.RSAAutoCertificateConfig;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+
+public class WechatPayConfig {
+
+ private static Config wechatPayConfig;
+
+ private WechatPayConfig(){}
+
+ public static Config getInstance() {
+
+
+ if (wechatPayConfig == null) {
+ wechatPayConfig = new RSAAutoCertificateConfig.Builder()
+ .merchantId(WechatPayData.merchantId)
+ .privateKeyFromPath(WechatPayConfig.class.getResource(WechatPayData.privateKeyPath).getPath())
+ .merchantSerialNumber(WechatPayData.merchantSerialNumber)
+ .apiV3Key(WechatPayData.apiV3key)
+ .build();
+ }
+ return wechatPayConfig;
+ }
+}
diff --git a/ruoyi-mall/src/main/java/com/cyl/wechat/WechatPayData.java b/ruoyi-mall/src/main/java/com/cyl/wechat/WechatPayData.java
new file mode 100644
index 0000000..f4dc49d
--- /dev/null
+++ b/ruoyi-mall/src/main/java/com/cyl/wechat/WechatPayData.java
@@ -0,0 +1,49 @@
+package com.cyl.wechat;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "wechat")
+public class WechatPayData {
+
+ /** 商户号 */
+ public static String appId;
+ public static String secret;
+ public static String merchantId;
+ /** 商户API私钥路径 */
+ public static String privateKeyPath;
+ /** 商户证书序列号 */
+ public static String merchantSerialNumber;
+ /** 商户APIV3密钥 */
+ public static String apiV3key;
+ public static String notifyUrl;
+
+ public void setAppId(String appId) {
+ WechatPayData.appId = appId;
+ }
+
+ public void setSecret(String secret) {
+ WechatPayData.secret = secret;
+ }
+
+ public void setMerchantId(String merchantId) {
+ WechatPayData.merchantId = merchantId;
+ }
+
+ public void setPrivateKeyPath(String privateKeyPath) {
+ WechatPayData.privateKeyPath = privateKeyPath;
+ }
+
+ public void setMerchantSerialNumber(String merchantSerialNumber) {
+ WechatPayData.merchantSerialNumber = merchantSerialNumber;
+ }
+
+ public void setApiV3key(String apiV3key) {
+ WechatPayData.apiV3key = apiV3key;
+ }
+
+ public void setNotifyUrl(String notifyUrl) {
+ WechatPayData.notifyUrl = notifyUrl;
+ }
+}
diff --git a/ruoyi-mall/src/main/java/com/cyl/wechat/WechatPayService.java b/ruoyi-mall/src/main/java/com/cyl/wechat/WechatPayService.java
new file mode 100644
index 0000000..9d062c8
--- /dev/null
+++ b/ruoyi-mall/src/main/java/com/cyl/wechat/WechatPayService.java
@@ -0,0 +1,41 @@
+package com.cyl.wechat;
+
+import com.wechat.pay.java.service.payments.jsapi.JsapiService;
+import com.wechat.pay.java.service.payments.jsapi.model.Amount;
+import com.wechat.pay.java.service.payments.jsapi.model.Payer;
+import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
+import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Service
+@Slf4j
+public class WechatPayService {
+
+ public static final JsapiService service = new JsapiService.Builder().config(WechatPayConfig.getInstance()).build();
+
+ /**
+ * jsapi下单
+ * @param orderNo 订单号
+ * @param desc 订单描述
+ * @param totalAmount 总金额,单位:分
+ * @param openId 用户openid
+ * @return prepay_id
+ */
+ public String jsapiPay(String orderNo,String desc,Integer totalAmount,String openId){
+ PrepayRequest prepayRequest = new PrepayRequest();
+ prepayRequest.setAppid(WechatPayData.appId);
+ prepayRequest.setMchid(WechatPayData.merchantId);
+ prepayRequest.setDescription(desc);
+ prepayRequest.setOutTradeNo(orderNo);
+ prepayRequest.setNotifyUrl(WechatPayData.notifyUrl);
+ Amount amount = new Amount();
+ amount.setTotal(totalAmount);
+ prepayRequest.setAmount(amount);
+ Payer payer = new Payer();
+ payer.setOpenid(openId);
+ prepayRequest.setPayer(payer);
+ PrepayResponse response = service.prepay(prepayRequest);
+ return response.getPrepayId();
+ }
+}
diff --git a/ruoyi-mall/src/main/java/com/cyl/wechat/response/WechatUserAuth.java b/ruoyi-mall/src/main/java/com/cyl/wechat/response/WechatUserAuth.java
new file mode 100644
index 0000000..b659482
--- /dev/null
+++ b/ruoyi-mall/src/main/java/com/cyl/wechat/response/WechatUserAuth.java
@@ -0,0 +1,13 @@
+package com.cyl.wechat.response;
+
+import lombok.Data;
+
+@Data
+public class WechatUserAuth {
+
+ private String access_token;
+ private Integer expires_in;
+ private String refresh_token;
+ private String openid;
+ private String scope;
+}
\ No newline at end of file