|
@@ -3,11 +3,11 @@ package com.ruoyi.system.service.impl;
|
|
|
|
|
|
|
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
import com.ruoyi.common.core.domain.AjaxResult;
|
|
|
import com.ruoyi.common.exception.ServiceException;
|
|
|
-import com.ruoyi.system.domain.wx.WxPayOrderReqVo;
|
|
|
-import com.ruoyi.system.domain.wx.WxPayRespVo;
|
|
|
-import com.ruoyi.system.domain.wx.WxPayV3Bean;
|
|
|
+import com.ruoyi.common.utils.sign.Base64;
|
|
|
+import com.ruoyi.system.domain.wx.*;
|
|
|
import com.ruoyi.system.service.IWxPayService;
|
|
|
import com.wechat.pay.java.core.Config;
|
|
|
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
|
@@ -20,7 +20,11 @@ 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 org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import utils.AppletDecryptDataUtil;
|
|
|
+import utils.HttpClientUtils;
|
|
|
import utils.WxPayUtil;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
@@ -41,6 +45,20 @@ import static com.wechat.pay.java.core.http.Constant.*;
|
|
|
@Service
|
|
|
public class WxPayServiceImpl implements IWxPayService {
|
|
|
|
|
|
+ private final String JSCODE_SESSION_API = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 小程序appId
|
|
|
+ */
|
|
|
+ @Value("${wx.appId}")
|
|
|
+ private String appId;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 小程序密钥
|
|
|
+ */
|
|
|
+ @Value("${wx.appSecret}")
|
|
|
+ private String appSecret;
|
|
|
+
|
|
|
@Resource
|
|
|
private WxPayV3Bean wxPayV3Bean;
|
|
|
/**
|
|
@@ -164,4 +182,75 @@ public class WxPayServiceImpl implements IWxPayService {
|
|
|
System.out.println("获取微信支付回调失败");
|
|
|
}
|
|
|
}
|
|
|
+ /**
|
|
|
+ * 根据code获取小程序openid和unionid
|
|
|
+ *
|
|
|
+ * @param form
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public AppletSessionDTO jscode2Session(AppletLoginForm form) {
|
|
|
+ // 获取openId和sessionKey
|
|
|
+ JSONObject result;
|
|
|
+ try {
|
|
|
+ String requestUrl = JSCODE_SESSION_API.replace("APPID", appId)
|
|
|
+ .replace("SECRET", appSecret)
|
|
|
+ .replace("JSCODE", form.getCode().trim());
|
|
|
+
|
|
|
+ String jsonStr = HttpClientUtils.doGet(requestUrl);
|
|
|
+ result = JSONObject.parseObject(jsonStr);
|
|
|
+ if (StringUtils.isEmpty(result.toString())) {
|
|
|
+ throw new RuntimeException("错误");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new RuntimeException("错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ int errcode = result.getIntValue("errcode");
|
|
|
+ if (errcode != 0) {
|
|
|
+ String errmsg = result.getString("errmsg");
|
|
|
+ throw new RuntimeException("获取小程序授权错误信息, " + errmsg);
|
|
|
+ }
|
|
|
+ // 获取openId,unionId,sessionKey
|
|
|
+ AppletSessionDTO appletSession = new AppletSessionDTO();
|
|
|
+ appletSession.setOpenId(result.getString("openid"));
|
|
|
+ // unionId有可能是空
|
|
|
+ appletSession.setUnionId(result.getString("unionid"));
|
|
|
+ appletSession.setSessionKey(result.getString("session_key"));
|
|
|
+ String phoneNumber = getPhoneNumber(form, appletSession);
|
|
|
+ appletSession.setPhoneNumber(phoneNumber);
|
|
|
+ return appletSession;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 手机号解密
|
|
|
+ */
|
|
|
+ private static String getPhoneNumber(AppletLoginForm form, AppletSessionDTO appletSession) {
|
|
|
+
|
|
|
+ // 解密文件
|
|
|
+ String encryptedData = form.getEncryptedData();
|
|
|
+ // 解密向量
|
|
|
+ String iv = form.getIv();
|
|
|
+ // 加密秘钥
|
|
|
+ byte[] dataByte = Base64.decode(encryptedData);
|
|
|
+ // session_key
|
|
|
+ byte[] keyByte = Base64.decode(appletSession.getSessionKey());
|
|
|
+ // 偏移量
|
|
|
+ byte[] ivByte = Base64.decode(iv);
|
|
|
+ JSONObject result;
|
|
|
+ try {
|
|
|
+ result = AppletDecryptDataUtil.decryptData(keyByte, ivByte, dataByte);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ assert result != null;
|
|
|
+ String purePhoneNumber = result.getString("purePhoneNumber");
|
|
|
+ if (null == purePhoneNumber || purePhoneNumber.isEmpty()) {
|
|
|
+ throw new RuntimeException("获取手机号失败");
|
|
|
+ }
|
|
|
+ return purePhoneNumber;
|
|
|
+ }
|
|
|
}
|