feat: 新增虚拟支付订单与网盘链接检测功能
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
package com.ruoyi.common.wx;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 微信小程序虚拟支付配置。
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "wx.miniapp.virtual-pay")
|
||||
public class VirtualPayConfig
|
||||
{
|
||||
/** 是否启用虚拟支付。 */
|
||||
private boolean enabled;
|
||||
|
||||
/** 虚拟支付 OfferId。 */
|
||||
private String offerId;
|
||||
|
||||
/** 虚拟支付现网 AppKey。 */
|
||||
private String appKey;
|
||||
|
||||
/** 0-正式环境,1-沙箱环境。 */
|
||||
private int env = 0;
|
||||
|
||||
/** 小程序消息推送 Token,用于校验支付通知。 */
|
||||
private String callbackToken;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.ruoyi.common.wx;
|
||||
|
||||
/**
|
||||
* 微信 code2Session 的服务端结果。该对象禁止返回给客户端。
|
||||
*/
|
||||
public class WxCodeSession
|
||||
{
|
||||
private final String openId;
|
||||
private final String sessionKey;
|
||||
|
||||
public WxCodeSession(String openId, String sessionKey)
|
||||
{
|
||||
this.openId = openId;
|
||||
this.sessionKey = sessionKey;
|
||||
}
|
||||
|
||||
public String getOpenId()
|
||||
{
|
||||
return openId;
|
||||
}
|
||||
|
||||
public String getSessionKey()
|
||||
{
|
||||
return sessionKey;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.ruoyi.common.wx;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 仅在服务端使用小程序临时 code 换取 OpenID 与 session_key。
|
||||
*/
|
||||
@Service
|
||||
public class WxCodeSessionService
|
||||
{
|
||||
private static final String CODE_TO_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session";
|
||||
|
||||
private final WxPayConfig wxPayConfig;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final OkHttpClient httpClient;
|
||||
|
||||
public WxCodeSessionService(WxPayConfig wxPayConfig, ObjectMapper objectMapper)
|
||||
{
|
||||
this.wxPayConfig = wxPayConfig;
|
||||
this.objectMapper = objectMapper;
|
||||
this.httpClient = new OkHttpClient.Builder()
|
||||
.connectTimeout(5, TimeUnit.SECONDS)
|
||||
.readTimeout(8, TimeUnit.SECONDS)
|
||||
.build();
|
||||
}
|
||||
|
||||
public WxCodeSession exchange(String code)
|
||||
{
|
||||
if (StringUtils.isBlank(code))
|
||||
{
|
||||
throw new ServiceException("微信登录凭证不能为空");
|
||||
}
|
||||
if (StringUtils.isAnyBlank(wxPayConfig.getAppid(), wxPayConfig.getSecret()))
|
||||
{
|
||||
throw new ServiceException("微信小程序 AppID 或 Secret 未配置");
|
||||
}
|
||||
|
||||
HttpUrl url = HttpUrl.parse(CODE_TO_SESSION_URL).newBuilder()
|
||||
.addQueryParameter("appid", wxPayConfig.getAppid())
|
||||
.addQueryParameter("secret", wxPayConfig.getSecret())
|
||||
.addQueryParameter("js_code", code)
|
||||
.addQueryParameter("grant_type", "authorization_code")
|
||||
.build();
|
||||
Request request = new Request.Builder().url(url).get().build();
|
||||
|
||||
try (Response response = httpClient.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful() || response.body() == null)
|
||||
{
|
||||
throw new ServiceException("微信登录服务暂不可用");
|
||||
}
|
||||
JsonNode result = objectMapper.readTree(response.body().string());
|
||||
if (result.path("errcode").asInt(0) != 0)
|
||||
{
|
||||
throw new ServiceException("微信登录失败:" + result.path("errmsg").asText("未知错误"));
|
||||
}
|
||||
String openId = result.path("openid").asText();
|
||||
String sessionKey = result.path("session_key").asText();
|
||||
if (StringUtils.isAnyBlank(openId, sessionKey))
|
||||
{
|
||||
throw new ServiceException("微信登录结果不完整");
|
||||
}
|
||||
return new WxCodeSession(openId, sessionKey);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ServiceException("调用微信登录服务失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user