1.手动退费接口位置调整

2.医共体认证功能测试完成.
debug
王绍全 1 day ago
parent 06d53b2204
commit 10f9323c73
  1. 34
      src/main/java/com/ynxbd/common/TestA.java
  2. 13
      src/main/java/com/ynxbd/common/action/test/TestAction.java
  3. 6
      src/main/java/com/ynxbd/wx/wxfactory/AesWxHelper.java
  4. 125
      src/main/java/com/ynxbd/wx/wxfactory/WxAuthHelper.java

@ -1,28 +1,17 @@
package com.ynxbd.common; package com.ynxbd.common;
import com.alibaba.fastjson.JSONObject;
import com.ynxbd.common.bean.pay.PEISOrderInfo;
import com.ynxbd.common.helper.common.Base64Helper;
import com.ynxbd.common.helper.common.JsonHelper;
import com.ynxbd.common.helper.http.OkHttpHelper;
import com.ynxbd.common.result.JsonResult;
import com.ynxbd.common.result.Result;
import com.ynxbd.wx.config.WeChatConfig;
import com.ynxbd.wx.utils.DesEncryptHelper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.util.HashMap;
import java.util.Map;
@Slf4j @Slf4j
public class TestA { public class TestA {
public static void main(String[] args) throws UnsupportedEncodingException { public static void main(String[] args) throws UnsupportedEncodingException {
// String a = ""; // String a = "";
// String s = DesEncryptHelper.deCode(a); // String s = DesEncryptHelper.deCode(a);
// System.out.println(s); // System.out.println(s);
@ -36,25 +25,6 @@ public class TestA {
// .build(); // .build();
// log.info("[认证请求转发] resp:[{}]", requestBody); // log.info("[认证请求转发] resp:[{}]", requestBody);
// log.info("[认证请求转发] resp:[{}]", JsonHelper.toJsonString(requestBody)); // log.info("[认证请求转发] resp:[{}]", JsonHelper.toJsonString(requestBody));
// String data = OkHttpHelper.postFormStr("http://slxlfwsy.slxrmyy.cn/wx/wx_auth/is_auth", map -> {
// map.put("token", null);
// map.put("state", "aHR0cCUzQSUyRiUyRnNseGxmd3N5LnNseHJteXkuY24lMkZ3eCUyRndlYiUyRnJlZy1yZXNlcnZlLmh0bWwlMjMlMkY=");
// map.put("isUserInfo", false);
// map.put("enuId", false);
// map.put("protocolState", 0);
// }, null);
// String data = OkHttpHelper.post("http://www.slxrmyy.cn/wx/wx_auth/is_auth", requestBody);
// JSONObject jsonObject = JsonHelper.parseObject(data);
// System.out.println(JsonHelper.toJsonString(jsonObject));
//
// String state = "aHR0cCUzQSUyRiUyRnNseGxmd3N5LnNseHJteXkuY24lMkZ3eCUyRndlYiUyRnJlZy1yZXNlcnZlLmh0bWwlMjMlMkY=";
// String decode = URLDecoder.decode(Base64Helper.decode(state), "UTF-8");
// System.out.println(decode);
} }

@ -2,12 +2,16 @@ package com.ynxbd.common.action.test;
import com.ynxbd.common.action.base.BaseAction; import com.ynxbd.common.action.base.BaseAction;
import com.ynxbd.common.helper.common.DateHelper; import com.ynxbd.common.helper.common.DateHelper;
import com.ynxbd.common.helper.http.OkHttpHelper;
import com.ynxbd.common.result.Result; import com.ynxbd.common.result.Result;
import com.ynxbd.common.result.ResultEnum; import com.ynxbd.common.result.ResultEnum;
import com.ynxbd.common.result.ServiceException; import com.ynxbd.common.result.ServiceException;
import com.ynxbd.wx.config.WeChatConfig;
import com.ynxbd.wx.wxfactory.AesWxHelper;
import com.ynxbd.wx.wxfactory.WxPayHelper; import com.ynxbd.wx.wxfactory.WxPayHelper;
import com.ynxbd.wx.wxfactory.medical.WxMedConfig; import com.ynxbd.wx.wxfactory.medical.WxMedConfig;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.Namespace;
@ -28,12 +32,16 @@ public class TestAction extends BaseAction {
private static int i = 0; private static int i = 0;
@Action("refund_test") public synchronized void refund_handle() {
public Result refund_test() throws ServiceException {
if (i == 0) { if (i == 0) {
i++; i++;
// WxPayHelper.refund("", "", new BigDecimal("0.900"), new BigDecimal("0.900"), "手动退费"); // WxPayHelper.refund("", "", new BigDecimal("0.900"), new BigDecimal("0.900"), "手动退费");
} }
}
@Action("refund_test")
public Result refund_test() throws ServiceException {
refund_handle();
return Result.success(); return Result.success();
} }
@ -98,7 +106,6 @@ public class TestAction extends BaseAction {
} }
// @Action("lock") // @Action("lock")
// public String lock() { // public String lock() {
// return Result.success(update()); // return Result.success(update());

@ -15,6 +15,12 @@ public class AesWxHelper extends AesHelper {
return encryptHex(data, KEY, IV); return encryptHex(data, KEY, IV);
} }
/**
*
* @param data 加密的数据
* @param isDataNotNull 加密数据是否不允许为空
* @return
*/
public static String encode(String data, boolean isDataNotNull) { public static String encode(String data, boolean isDataNotNull) {
if (isDataNotNull && ObjectUtils.isEmpty(data)) { if (isDataNotNull && ObjectUtils.isEmpty(data)) {
return null; return null;

@ -19,36 +19,43 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Date; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j @Slf4j
public class WxAuthHelper { public class WxAuthHelper {
private static final int SESSION_MAX_INACTIVE_INTERVAL = 60 * 60; // session最大存活时间 1H private static final int SESSION_MAX_INACTIVE_INTERVAL = 60 * 60; // session最大存活时间 1H
private static final String P_PREFIX = "_@"; // 前缀
private static final String P_SUFFIX = ":"; // 后缀
private static final String AUTH_SESSION_ID_NAME = "SID";
private static final String UNION_ID_NAME = "UID";
public static String auth(HttpServletRequest request, HttpServletResponse response, boolean isUserInfo) { public static String auth(HttpServletRequest request, HttpServletResponse response, boolean isUserInfo) {
String code = request.getParameter("code"); String code = request.getParameter("code");
String state = request.getParameter("state"); // base64 String state = request.getParameter("state"); // base64
String params = request.getParameter("params"); Map<String, String> paramsMap = getParamsMap(request.getParameter("p"));
log.info("[授权] code={}, state={}, params={}", code, state, params); log.info("[授权] code={}, state={}, paramsMap={}", code, state, JsonHelper.toJsonString(paramsMap));
try { try {
state = state == null ? "" : URLDecoder.decode(Base64Helper.decode(state), "UTF-8"); state = state == null ? "" : URLDecoder.decode(Base64Helper.decode(state), "UTF-8");
String enUnionId = null; String enUnionId = paramsMap.get(UNION_ID_NAME);
String authSessionId = null; String enAuthSessionId = paramsMap.get(AUTH_SESSION_ID_NAME);
String authSessionId = AesWxHelper.decode(enAuthSessionId);
if (!ObjectUtils.isEmpty(params)) {
int index = params.indexOf("@SID="); paramsMap.get(AUTH_SESSION_ID_NAME);
if (index == -1) index = params.indexOf("%40SID="); // 防止数据转义失败
if (index != -1) { // if (!ObjectUtils.isEmpty(params)) {
enUnionId = params.substring(0, index); // int index = params.indexOf("@" + AUTH_SESSION_ID_NAME + ":");
authSessionId = params.substring(index); // if (index == -1) index = params.indexOf("%40" + AUTH_SESSION_ID_NAME + ":"); // 防止数据转义失败
authSessionId = AesWxHelper.decode(authSessionId); // if (index != -1) {
} // enUnionId = params.substring(0, index);
} // authSessionId = params.substring(index);
log.info("[授权-解码] enUnionId={}, authSessionId={}, state={}", enUnionId, authSessionId, state); // authSessionId = AesWxHelper.decode(authSessionId);
// }
// }
log.info("[授权-解码] enUnionId={}, enAuthSessionId={}, authSessionId={}, state={}", enUnionId, enAuthSessionId, authSessionId, state);
SnsOath2AccessToken snsToken = WxFactory.Base.OAuth().oauth2AccessToken(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, code); SnsOath2AccessToken snsToken = WxFactory.Base.OAuth().oauth2AccessToken(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, code);
log.info("[授权-用户]snsToken={}", JsonHelper.toJsonString(snsToken)); log.info("[授权-用户]snsToken={}", JsonHelper.toJsonString(snsToken));
@ -127,15 +134,15 @@ public class WxAuthHelper {
String token = request.getParameter("token"); // 前端缓存 String token = request.getParameter("token"); // 前端缓存
String state = request.getParameter("state"); String state = request.getParameter("state");
String isUserInfo = request.getParameter("isUserInfo"); String isUserInfo = request.getParameter("isUserInfo");
// String protocolState = request.getParameter("protocolState"); String UID = ParamHelper.filterParamNull(request.getParameter(UNION_ID_NAME), "");
String enUID = ParamHelper.filterParamNull(request.getParameter("enUID"), "");
String deState = URLDecoder.decode(Base64Helper.decode(state), "UTF-8"); String deState = URLDecoder.decode(Base64Helper.decode(state), "UTF-8");
String authSessionId = null; String authSessionId = null;
if (WeChatConfig.IS_ENABLE_GMC && WeChatConfig.IS_GMC_SERVER && !isPayOAuth) { // 开启医共体开关 & 是医共体主服务器 & 不是支付授权 if (WeChatConfig.IS_ENABLE_GMC && WeChatConfig.IS_GMC_SERVER && !isPayOAuth) { // 开启医共体开关 & 是医共体主服务器 & 不是支付授权
authSessionId = AesWxHelper.decode(request.getHeader("AID")); authSessionId = AesWxHelper.decode(request.getHeader(AUTH_SESSION_ID_NAME));
} }
log.info("[is_auth]token={}, state={}, isUserInfo={}, authSessionId={}, enUID={}, deState={}", token, state, isUserInfo, authSessionId, enUID, deState); log.warn("[授权is_auth] token={}, state={}, isUserInfo={}, authSessionId={}, UID={}, deState={}", token, state, isUserInfo, authSessionId, UID, deState);
if (WeChatConfig.IS_ENABLE_GMC && !WeChatConfig.IS_GMC_SERVER && !isPayOAuth) { // 开启医共体开关 & 不是医共体主服务器 & 不是支付授权 if (WeChatConfig.IS_ENABLE_GMC && !WeChatConfig.IS_GMC_SERVER && !isPayOAuth) { // 开启医共体开关 & 不是医共体主服务器 & 不是支付授权
try { // 请求转发 try { // 请求转发
String serverDomain = WeChatConfig.getDomain(false, false); String serverDomain = WeChatConfig.getDomain(false, false);
@ -151,11 +158,10 @@ public class WxAuthHelper {
params.put("token", token); params.put("token", token);
params.put("state", state); params.put("state", state);
params.put("isUserInfo", isUserInfo); params.put("isUserInfo", isUserInfo);
params.put("enuId", enUID); params.put(UNION_ID_NAME, UID);
// params.put("protocolState", protocolState);
}, headers -> { }, headers -> {
if (!ObjectUtils.isEmpty(sessionId)) { if (!ObjectUtils.isEmpty(sessionId)) {
headers.add("AID", AesWxHelper.encode(sessionId)); headers.add(AUTH_SESSION_ID_NAME, AesWxHelper.encode(WeChatConfig.APP_ID + ":" + sessionId));
} }
}); });
Result result = Result.dataToResult(data, true); Result result = Result.dataToResult(data, true);
@ -206,17 +212,17 @@ public class WxAuthHelper {
Object sessionOpenId = session.getAttribute("openid"); Object sessionOpenId = session.getAttribute("openid");
String openid = sessionOpenId == null ? null : sessionOpenId.toString(); String openid = sessionOpenId == null ? null : sessionOpenId.toString();
log.info("[微信认证]获取 openid={}, authSessionId={}", openid, authSessionId); log.info("[微信认证] openid={}, authSessionId={}", openid, authSessionId);
if (!ObjectUtils.isEmpty(authSessionId) && ObjectUtils.isEmpty(openid)) { if (!ObjectUtils.isEmpty(authSessionId) && ObjectUtils.isEmpty(openid)) {
openid = WxCacheHelper.getOpenIdByAIDCache(authSessionId); openid = WxCacheHelper.getOpenIdByAIDCache(authSessionId);
log.info("[微信AID认证]openid={}", openid); log.warn("[微信AID认证]openid={}", openid);
} }
if (openid != null) { if (openid != null) {
log.info("[微信认证]openid={}", openid); log.info("[微信认证]openid={}", openid);
User user = WxCacheHelper.getCacheUser(openid); User user = WxCacheHelper.getCacheUser(openid);
if (user == null) { if (user == null) {
return Result.success(getAuthUrl(request, state, isFindUserInfo, enUID, authSessionId)); return Result.success(getAuthUrl(request, state, isFindUserInfo, UID, authSessionId));
} else { } else {
if (ObjectUtils.isEmpty(openid)) { if (ObjectUtils.isEmpty(openid)) {
openid = user.getOpenid(); // sessionId认证openid补充 openid = user.getOpenid(); // sessionId认证openid补充
@ -225,7 +231,7 @@ public class WxAuthHelper {
if (isFindUserInfo) { // 更换授权模式,需更新信息 if (isFindUserInfo) { // 更换授权模式,需更新信息
if (user.getNickName() == null || user.getAvatar() == null) { if (user.getNickName() == null || user.getAvatar() == null) {
return Result.success(getAuthUrl(request, state, true, enUID, authSessionId)); return Result.success(getAuthUrl(request, state, true, UID, authSessionId));
} }
} }
@ -242,12 +248,12 @@ public class WxAuthHelper {
return Result.success(map); return Result.success(map);
} }
return Result.success(getAuthUrl(request, state, isFindUserInfo, enUID, authSessionId)); return Result.success(getAuthUrl(request, state, isFindUserInfo, UID, authSessionId));
} }
private static final String OAUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WeChatConfig.APP_ID + "&redirect_uri="; private static final String OAUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WeChatConfig.APP_ID + "&redirect_uri=";
private static String getAuthUrl(HttpServletRequest request, String state, boolean isFindUserInfo, String enUID, String SID) { private static String getAuthUrl(HttpServletRequest request, String state, boolean isFindUserInfo, String UID, String SID) {
// StringBuffer url = request.getRequestURL(); // StringBuffer url = request.getRequestURL();
// String baseUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getServletContext().getContextPath()).append("/").toString(); // String baseUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getServletContext().getContextPath()).append("/").toString();
if (state == null) { if (state == null) {
@ -257,23 +263,25 @@ public class WxAuthHelper {
String api = isFindUserInfo ? "u_auth" : "b_auth"; String api = isFindUserInfo ? "u_auth" : "b_auth";
String scope = isFindUserInfo ? "snsapi_userinfo" : "snsapi_base"; String scope = isFindUserInfo ? "snsapi_userinfo" : "snsapi_base";
String enSID = ""; UID = toURLParam(UNION_ID_NAME, UID);
String enSID = toURLParam(AUTH_SESSION_ID_NAME, AesWxHelper.encode(SID, true));
String params = enSID + UID;
try { try {
enSID = (SID == null ? "" : ("%40SID=" + URLEncoder.encode(AesWxHelper.encode(SID), "UTF-8"))); params = ObjectUtils.isEmpty(params) ? "" : URLEncoder.encode(params, "UTF-8");
log.warn("[认证链接参数] params={}", params);
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage()); log.error(e.getMessage());
} }
log.info("[认证链接] enSID={}, SID={}", enSID, SID);
state = OAUTH_URL + WeChatConfig.getBaseURL(WeChatConfig.HAS_HTTPS_BY_BASE_URL || isHttpsWithProxy(request)) + state = OAUTH_URL + WeChatConfig.getBaseURL(WeChatConfig.HAS_HTTPS_BY_BASE_URL || isHttpsWithProxy(request)) +
"wx_auth/" + api + "wx_auth/" + api +
"?state=" + state + "?p=" + params +
"&response_type=code" + "&response_type=code" +
"&scope=" + scope + "&forcePopup=true" + "&scope=" + scope +
"&params=" + (enUID == null ? "" : enUID) + "&forcePopup=true" +
enSID + "&state=" + state + // state位置固定
"#wechat_redirect"; "#wechat_redirect";
log.warn("[认证授权链接]state={}", state);
return Base64Helper.encode(state); return Base64Helper.encode(state);
} }
@ -289,6 +297,41 @@ public class WxAuthHelper {
return request.isSecure(); return request.isSecure();
} }
public static String toURLParam(String key, String val) {
if (ObjectUtils.isEmpty(val)) return "";
return P_PREFIX + key + P_SUFFIX + val;
}
public static Map<String, String> getParamsMap(String params) {
Map<String, String> paramsMap = new HashMap<>();
try {
if (ObjectUtils.isEmpty(params)) {
return paramsMap;
}
params = URLDecoder.decode(params, "UTF-8");
String[] paramsArr = params.split(P_PREFIX);
String key, val;
String[] keyValueArr;
for (String paramItem : paramsArr) {
if (paramItem.isEmpty()) {
continue;
}
keyValueArr = paramItem.split(P_SUFFIX, 2); // 分割成最多两部分
if (keyValueArr.length == 2) {
key = keyValueArr[0];
val = keyValueArr[1];
val = ParamHelper.filterParamNull(val, null);
if (val != null) {
paramsMap.put(key, val);
}
}
}
} catch (Exception e) {
log.error(e.getMessage());
}
return paramsMap;
}
// // 医共体开启 & 不是支付授权 // // 医共体开启 & 不是支付授权
// private static boolean isAuthGMC(boolean isPayOAuth) { // private static boolean isAuthGMC(boolean isPayOAuth) {

Loading…
Cancel
Save