From c06ed6cf340e5cf5a48ceae61b1d86ca430dab0d Mon Sep 17 00:00:00 2001 From: fengjundan <1436525664@qq.com> Date: Fri, 23 Jul 2021 18:55:28 +0800 Subject: [PATCH] =?UTF-8?q?1=E6=96=B0=E5=A2=9E=E5=BE=AE=E4=BF=A1=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E5=AE=9D=E6=94=AF=E4=BB=98=E5=92=8C=E8=BD=AC=E8=B4=A6?= =?UTF-8?q?=E5=88=B0=E8=B4=A6=E5=8F=B7=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-common/ruoyi-common-core/pom.xml | 2 +- .../common/core/listener/ConfigListener.java | 57 +++ .../ruoyi/common/core/utils/HttpUtils.java | 409 ++++++++++++++++++ xhpc-modules/xhpc-payment/pom.xml | 11 + .../controller/AlipayPaymentController.java | 167 +++++++ .../controller/WxPaymentController.java | 227 ++++------ .../src/main/resources/apiclient_cert.p12 | Bin 0 -> 2710 bytes .../src/main/resources/bootstrap.yml | 8 +- .../mapper/XhpcRechargeOrderMapper.xml | 4 +- xhpc-modules/xhpc-user/pom.xml | 11 + .../controller/XhpcAppUserController.java | 98 +++++ .../src/main/resources/bootstrap.yml | 8 + 12 files changed, 867 insertions(+), 135 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/listener/ConfigListener.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java create mode 100644 xhpc-modules/xhpc-payment/src/main/java/com/xhpc/payment/controller/AlipayPaymentController.java create mode 100644 xhpc-modules/xhpc-payment/src/main/resources/apiclient_cert.p12 diff --git a/ruoyi-common/ruoyi-common-core/pom.xml b/ruoyi-common/ruoyi-common-core/pom.xml index b9e9a487..253d6492 100644 --- a/ruoyi-common/ruoyi-common-core/pom.xml +++ b/ruoyi-common/ruoyi-common-core/pom.xml @@ -121,7 +121,7 @@ org.apache.httpcomponents httpclient - 4.3.5 + 4.5.11 diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/listener/ConfigListener.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/listener/ConfigListener.java new file mode 100644 index 00000000..ec66cac7 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/listener/ConfigListener.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.ruoyi.common.core.listener; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import java.util.HashMap; +import java.util.Map; + +/** + * ServletContext监听器 + * + * @author stylefeng + * @Date 2018/2/22 21:07 + */ +public class ConfigListener implements ServletContextListener { + + private static Map conf = new HashMap<>(); + + public static Map getConf() { + return conf; + } + + @Override + public void contextDestroyed(ServletContextEvent arg0) { + conf.clear(); + } + + @Override + public void contextInitialized(ServletContextEvent evt) { + ServletContext sc = evt.getServletContext(); + + //项目发布,当前运行环境的绝对路径 + conf.put("realPath", sc.getRealPath("/").replaceFirst("/", "")); + + //servletContextPath,默认"" + conf.put("contextPath", sc.getContextPath()); + + //微信证书路径 + conf.put("certPath", sc.getRealPath("/static/cert/apiclient_cert.p12")); + } + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java new file mode 100644 index 00000000..a6512016 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java @@ -0,0 +1,409 @@ +package com.ruoyi.common.core.utils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +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.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.util.EntityUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.*; + +/** + * http相关操作 + * + * @author fengjundan on 2018/5/12. + */ +public class HttpUtils { + + /** + * 连接池管理 + */ + private static PoolingHttpClientConnectionManager poolConnManager = null; + + private static Logger logger = LogManager.getLogger(HttpUtils.class); + + private static CloseableHttpClient httpClient = null; + /** + * 请求器的配置 + */ + private static RequestConfig requestConfig; + + + static { + try { + System.out.println("httpClient~~~开始"); + SSLContextBuilder builder = new SSLContextBuilder(); + builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); + // 配置同时支持 HTTP 和 HTPPS + Registry socketFactoryRegistry = RegistryBuilder.create().register( + "http", PlainConnectionSocketFactory.getSocketFactory()).register( + "https", sslsf).build(); + // 初始化连接管理器 + poolConnManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + // 将最大连接数增加到200 + poolConnManager.setMaxTotal(200); + // 设置最大路由 + poolConnManager.setDefaultMaxPerRoute(2); + // 根据默认超时限制初始化requestConfig + int socketTimeout = 100000; + int connectTimeout = 100000; + int connectionRequestTimeout = 100000; + requestConfig = RequestConfig.custom().setConnectionRequestTimeout( + connectionRequestTimeout).setSocketTimeout(socketTimeout).setConnectTimeout( + connectTimeout).build(); + // 初始化httpClient + httpClient = getConnection(); + System.out.println("初始化HttpClient~~~结束"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static CloseableHttpClient getConnection() { + CloseableHttpClient closeableHttpClient = HttpClients.custom() + // 设置连接池管理 + .setConnectionManager(poolConnManager) + // 设置请求配置 + .setDefaultRequestConfig(requestConfig) + // 设置重试次数 + .setRetryHandler(new DefaultHttpRequestRetryHandler(0, false)) + .build(); + return closeableHttpClient; + } + + + /** + * get请求 + * + * @param url 请求地址 + * @return + * @author fengjundan + * @date 2018/5/12 + */ + public static String get(String url) { + HttpGet httpGet = new HttpGet(url); + CloseableHttpResponse response = null; + try { + response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + String result = EntityUtils.toString(entity); + return result; + } catch (Exception e) { + e.printStackTrace(); + } finally { + destroy(httpGet, response); + } + return null; + } + + /** + * get请求(带header) + * + * @author fengjundan + * @date 2019/12/30 11:45 + */ + public static String get(String url, Map headers) { + HttpGet httpGet = new HttpGet(url); + CloseableHttpResponse response = null; + try { + if (headers != null && headers.size() > 0) { + for (String key : headers.keySet()) { + httpGet.setHeader(key, StringUtils.valueOf(headers.get(key))); + } + } + response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + String result = EntityUtils.toString(entity); + return result; + } catch (Exception e) { + e.printStackTrace(); + } finally { + destroy(httpGet, response); + } + return null; + } + + + /** + * post请求 + * + * @param url 请求地址 + * @param params json格式的参数数据 + * @return + * @author fengjundan + * @date 2018/6/2 + */ + public static String post(String url, String params) { + HttpPost httpPost = new HttpPost(url); + if (!StringUtils.isNull(params)) { + StringEntity stringEntity = new StringEntity(params, ContentType.APPLICATION_JSON); + httpPost.setEntity(stringEntity); + } + CloseableHttpResponse response = null; + try { + response = httpClient.execute(httpPost); + if (response != null && response.getStatusLine().getStatusCode() == 200) { + HttpEntity entity = response.getEntity(); + String result = EntityUtils.toString(entity, "UTF-8"); + return result; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + destroy(httpPost, response); + } + return null; + } + + /** + * post body请求 + * + * @param url 请求地址 + * @param params json格式的参数数据 + * @return + * @author fengjundan + * @date 2018/6/2 + */ + public static String postBody(String url, String params) { + HttpPost httpPost = new HttpPost(url); + if (!StringUtils.isNull(params)) { + StringEntity stringEntity = new StringEntity(params, ContentType.APPLICATION_JSON); + httpPost.setEntity(stringEntity); + } + CloseableHttpResponse response = null; + try { + httpPost.setHeader("Content-Type", "application/json"); + response = httpClient.execute(httpPost); + if (response != null && response.getStatusLine().getStatusCode() == 200) { + HttpEntity entity = response.getEntity(); + String result = EntityUtils.toString(entity, "UTF-8"); + return result; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + destroy(httpPost, response); + } + return null; + } + + /** + * post body请求 (带header) + * + * @author fengjundan + * @date 2019/12/30 10:10 + */ + public static String postBody(String url, String params, Map headers) { + HttpPost httpPost = new HttpPost(url); + if (!StringUtils.isNull(params)) { + StringEntity stringEntity = new StringEntity(params, ContentType.APPLICATION_JSON); + httpPost.setEntity(stringEntity); + } + CloseableHttpResponse response = null; + try { + if (headers != null && headers.size() > 0) { + for (String key : headers.keySet()) { + httpPost.setHeader(key, StringUtils.valueOf(headers.get(key))); + } + } + httpPost.setHeader("Content-Type", "application/json"); + response = httpClient.execute(httpPost); + if (response != null && response.getStatusLine().getStatusCode() == 200) { + HttpEntity entity = response.getEntity(); + String result = EntityUtils.toString(entity, "UTF-8"); + return result; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + destroy(httpPost, response); + } + return null; + } + + /** + * post body请求 + * + * @param url 请求地址 + * @param jsonObject json参数 + * @return + * @author fengjundan + * @date 2018/6/28 + */ + public static String postBody(String url, JSONObject jsonObject) { + if (jsonObject == null) { + return null; + } + return postBody(url, jsonObject.toJSONString()); + } + + + /** + * post请求 + * + * @param url 请求地址 + * @return + * @author fengjundan + * @date 2018/6/2 + */ + public static String post(String url) { + return post(url, ""); + } + + /** + * post请求 + * + * @param url 请求地址 + * @param jsonObject json格式的参数数据 + * @return + * @author fengjundan + * @date 2018/6/2 + */ + public static String post(String url, JSONObject jsonObject) { + if (jsonObject != null) { + return post(url, jsonObject.toJSONString()); + } else { + return post(url, ""); + } + } + + /** + * post请求 + * + * @param url 请求地址 + * @param jsonArray JSONArray格式的参数数据 + * @return + * @author fengjundan + * @date 2018/6/2 + */ + public static String post(String url, JSONArray jsonArray) { + if (jsonArray != null) { + return post(url, jsonArray.toJSONString()); + } else { + return post(url, ""); + } + } + + /** + * post请求 + * @param url 请求地址 + * @param map map请求参数 + * @author fengjundan + * @date 2018/6/2 + * @return public static String post(String url, Map map){ + if(map != null){ + String params = JSON.toJSONString(map); + return post(url, params); + } else{ + return post(url, ""); + } + }*/ + + /** + * post请求 + * + * @param url 请求地址 + * @param list list格式的参数数据 + * @return + * @author fengjundan + * @date 2018/6/2 + */ + public static String post(String url, List> list) { + if (list != null) { + String params = JSON.toJSONString(list); + return post(url, params); + } else { + return post(url, ""); + } + } + + + /** + * 释放资源 + * + * @return + * @author fengjundan + * @date 2018/6/2 + */ + private static void destroy(HttpRequestBase httpRequestBase, CloseableHttpResponse response) { + try { + if (response != null) { + response.close(); + } + if (httpRequestBase != null) { + httpRequestBase.releaseConnection(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * post请求 + * + * @param url 请求地址 + * @param map map请求参数 + * @return + * @author fengjundan + * @date 2018/6/2 + */ + public static String post(String url, Map map, Map headers) { + HttpPost httpPost = new HttpPost(url); + if (map != null && map.size() > 0) { + List postData = new ArrayList<>(); + Set set = map.keySet(); + Iterator iterator = set.iterator(); + while (iterator.hasNext()) { + String key = iterator.next(); + String value = StringUtils.valueOf(map.get(key)); + postData.add(new BasicNameValuePair(key, value)); + } + CloseableHttpResponse response = null; + try { + httpPost.setEntity(new UrlEncodedFormEntity(postData, "utf-8")); + if (headers != null && headers.size() > 0) { + for (String key : headers.keySet()) { + httpPost.setHeader(key, StringUtils.valueOf(headers.get(key))); + } + } + response = httpClient.execute(httpPost); + if (response.getStatusLine().getStatusCode() == 200) { + //获取响应实体 + String result = EntityUtils.toString(response.getEntity(), "utf-8"); + return result; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + destroy(httpPost, response); + } + } + return null; + } + + +} diff --git a/xhpc-modules/xhpc-payment/pom.xml b/xhpc-modules/xhpc-payment/pom.xml index 003d4a32..b7dcbdd1 100644 --- a/xhpc-modules/xhpc-payment/pom.xml +++ b/xhpc-modules/xhpc-payment/pom.xml @@ -78,6 +78,17 @@ ${project.artifactId} + + + src/main/resources + + + src/main/java + + **/*.xml + + + org.springframework.boot diff --git a/xhpc-modules/xhpc-payment/src/main/java/com/xhpc/payment/controller/AlipayPaymentController.java b/xhpc-modules/xhpc-payment/src/main/java/com/xhpc/payment/controller/AlipayPaymentController.java new file mode 100644 index 00000000..65ce94f7 --- /dev/null +++ b/xhpc-modules/xhpc-payment/src/main/java/com/xhpc/payment/controller/AlipayPaymentController.java @@ -0,0 +1,167 @@ +package com.xhpc.payment.controller; + +import com.alibaba.fastjson.JSONObject; +import com.alipay.api.AlipayApiException; +import com.alipay.api.AlipayClient; +import com.alipay.api.CertAlipayRequest; +import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.internal.util.AlipaySignature; +import com.alipay.api.request.AlipayFundTransUniTransferRequest; +import com.alipay.api.request.AlipayTradeCreateRequest; +import com.alipay.api.response.AlipayFundTransUniTransferResponse; +import com.alipay.api.response.AlipayTradeCreateResponse; +import com.ruoyi.common.core.utils.DateUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; + + +@RestController +@RequestMapping("/alipay") +@Api(value = "支付宝支付接口", tags = "支付宝支付接口") +public class AlipayPaymentController { + + @Autowired + private Environment environment; + + /** + * 新版本的支付方式 + * + * @return + */ + @GetMapping("/payment") + @ApiOperation(value = "微信支付", notes = "传入order") + private String newPay() throws Exception { + + String orderNumber = "alipay" + DateUtils.timePath(); + + AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", environment.getProperty("ALIPAYAPPID"), environment.getProperty("ALIPAYPRIVATEKEY"), "json", "utf-8", environment.getProperty("ALIPAYPUBLICKEY"), "RSA2"); + AlipayTradeCreateRequest request = new AlipayTradeCreateRequest(); + JSONObject json = new JSONObject(); + String out_trade_no = orderNumber; + //订单号 + json.put("out_trade_no", out_trade_no); + //金额 这里的金额是以元为单位的可以不转换但必须是字符串 + json.put("total_amount", "0.01"); + //描述 + json.put("subject", "测试"); + //用户唯一标识id 这里必须使用buyer_id 参考文档 + json.put("buyer_id", "123"); + //对象转化为json字符串 + String jsonStr = json.toString(); + //商户通过该接口进行交易的创建下单 + request.setBizContent(jsonStr); + request.setNotifyUrl("https://cdz.project2.tingsun.net/alipay/notifyUrl");//回调地址 + try { + //使用的是execute + AlipayTradeCreateResponse response = alipayClient.execute(request); + String trade_no = response.getTradeNo();//获取返回的tradeNO。 + } catch (AlipayApiException e) { + e.printStackTrace(); + } + return ""; + } + + /** + * 2 * 支付宝服务器异步通知url + * 3 * @throws Exception + * 4 + */ + @RequestMapping(value = "/notifyUrl") + public void notifyUrl(HttpServletRequest request) throws Exception { + + + //获取支付宝发送过来的信息 + Map params = new HashMap(); + Map requestParams = request.getParameterMap(); + //循环获取到所有的值 + for (String str : requestParams.keySet()) { + String name = str; + String[] values = (String[]) requestParams.get(name); + String valueStr = ""; + for (int i = 0; i < values.length; i++) { + valueStr = (i == values.length - 1) ? valueStr + values[i] + : valueStr + values[i] + ","; + } + //乱码解决,这段代码在出现乱码时使用 + valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); + params.put(name, valueStr); + } + //调用SDK验证签名 + boolean signVerified = AlipaySignature.rsaCheckV1(params, environment.getProperty("ALIPAYPUBLICKEY"), "", "RSA2"); + //boolean类型signVerified为true时 则验证成功 + if (signVerified) { + //获取到支付的状态 TRADE_SUCCESS则支付成功 + String trade_status = request.getParameter("trade_status"); + if (trade_status.equals("TRADE_SUCCESS")) { + System.out.println("支付成功"); + } else { + System.out.println("支付失败"); + } + } + //签名验证失败 + else { + System.out.println(AlipaySignature.getSignCheckContentV1(params)); + } + } + + /** + * 25 * 支付宝转账到用户账号 + * 26 * @throws IOException + * 27 + */ + @GetMapping(value = "/enterpriseCheckOut") + public void toHtml() throws AlipayApiException { + + String orderNumber = "alipay" + DateUtils.timePath(); + + String filePath = this.getClass().getResource("/").getPath() + "证书名字"; + System.out.println(filePath); + CertAlipayRequest certAlipayRequest = new CertAlipayRequest(); + certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do"); + certAlipayRequest.setAppId(environment.getProperty("ALIPAYAPPID")); + certAlipayRequest.setPrivateKey(environment.getProperty("ALIPAYPRIVATEKEY"));//密钥 + certAlipayRequest.setFormat("json"); + certAlipayRequest.setCharset("UTF-8"); + certAlipayRequest.setSignType("RSA2"); + certAlipayRequest.setCertPath(filePath + "appCertPublicKey.crt");//应用证书 + certAlipayRequest.setAlipayPublicCertPath(filePath + "alipayCertPublicKey_RSA2.crt");//支付证书 + certAlipayRequest.setRootCertPath(filePath + "alipayRootCert.crt"); + DefaultAlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); + AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest(); + //价格 + Double money = 0.01; + //转账标题 + String order_title = "支付宝提现"; + //支付宝会员id + String identity = "123"; + //实名信息 + String name = ""; + request.setBizContent("{" + + "\"out_biz_no\":\"201806300001\"," + + + "\"trans_amount\":" + money + "," + + "\"product_code\":\"TRANS_ACCOUNT_NO_PWD\"," + + "\"biz_scene\":\"DIRECT_TRANSFER\"," + + "\"order_title\":\"" + order_title + "\"," + + "\"payee_info\":{" + + "\"identity\":\"" + identity + "\"," + + "\"identity_type\":\"ALIPAY_USER_ID \"," + + " }," + + " }"); + AlipayFundTransUniTransferResponse response = alipayClient.certificateExecute(request); + if (response.isSuccess()) { + System.out.println("调用成功"); + } else { + System.out.println("调用失败"); + } + } +} diff --git a/xhpc-modules/xhpc-payment/src/main/java/com/xhpc/payment/controller/WxPaymentController.java b/xhpc-modules/xhpc-payment/src/main/java/com/xhpc/payment/controller/WxPaymentController.java index 477137aa..29299d12 100644 --- a/xhpc-modules/xhpc-payment/src/main/java/com/xhpc/payment/controller/WxPaymentController.java +++ b/xhpc-modules/xhpc-payment/src/main/java/com/xhpc/payment/controller/WxPaymentController.java @@ -1,16 +1,25 @@ package com.xhpc.payment.controller; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.ruoyi.common.core.constant.HttpStatus; +import com.ruoyi.common.core.listener.ConfigListener; import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.HttpUtils; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.WXPayUtil; import com.ruoyi.common.core.web.domain.AjaxResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContexts; +import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -29,14 +38,11 @@ import java.net.URLConnection; import java.security.KeyStore; import java.security.SecureRandom; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; -/** - * 微信支付 - * author:yuyang - * Date:2020/4/8 - * Time:16:30 - */ @RestController @RequestMapping("/wx") @Api(value = "微信支付接口", tags = "微信支付接口") @@ -54,23 +60,22 @@ public class WxPaymentController { @GetMapping("/payment") @ApiOperation(value = "微信支付", notes = "传入order") - public Object getWXunifiedorder(HttpServletRequest servletRequest) { - AjaxResult responseData = new AjaxResult(); + public AjaxResult payment(HttpServletRequest servletRequest) throws Exception { String openid = servletRequest.getParameter("openid"); if (StringUtils.isNull(openid)) { - return responseData.error(HttpStatus.BAD_REQUEST, "openid不能为空"); + return AjaxResult.error(HttpStatus.BAD_REQUEST, "openid不能为空"); } //总金额(是)订单总金额,单位为分 String doubleValue = servletRequest.getParameter("doubleValue"); if (StringUtils.isNull(doubleValue)) { - return responseData.error(HttpStatus.BAD_REQUEST, "充值金额不能为空"); + return AjaxResult.error(HttpStatus.BAD_REQUEST, "充值金额不能为空"); } - Double amount = Double.parseDouble(doubleValue); - String orderNumber = "wx"+ DateUtils.timePath(); + Double amount = Double.parseDouble(doubleValue) * 100; + String orderNumber = "wx" + DateUtils.timePath(); //此次生成充值订单 // OrderVO orderInfo = orderService.selectOrderNumber(orderNumber); if (0.0 == amount) { - return responseData.error(HttpStatus.BAD_REQUEST, "充值金额不能为0"); + return AjaxResult.error(HttpStatus.BAD_REQUEST, "充值金额不能为0"); } //附加数据(否) String attach = attachYu(StringUtils.valueOf("123456"), StringUtils.valueOf(amount), null, orderNumber); @@ -92,7 +97,7 @@ public class WxPaymentController { //发送请求 PrintWriter out = null; BufferedReader in = null; - String result = ""; + StringBuffer result = new StringBuffer(); try { URL realUrl = new URL(environment.getProperty("WXPAYUNIFIEDORDER")); // 打开和URL之间的连接 @@ -111,11 +116,12 @@ public class WxPaymentController { // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 + in = new BufferedReader( new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { - result += line; + result.append(line); System.out.println(result); } } catch (Exception e) { @@ -136,9 +142,9 @@ public class WxPaymentController { } //app //Map sign = createSign(result, 1, orderInfo.getId(), environment.getProperty("KEY"), doubleValue, remarks); - Map sign = createSign(result, 1); - responseData.success(sign); - return responseData; + // Map sign = createSign(result, 1); + Map map = WXPayUtil.xmlToMap(result.toString()); + return AjaxResult.success(map); } @@ -315,14 +321,6 @@ public class WxPaymentController { * @return * @throws Exception */ - /* public int addOrUpdatePaymentRecord(Long orderId, String transactionId) throws Exception { - Order order = orderMapper.selectById(orderId); - String userId = StringUtils.valueOf(order.getUserId()); - User user = userMapper.getUserVo(userId); - order.setPrepayId(transactionId); - orderMapper.updateById(order); - return 0; - }*/ public int paymentCallback(Map map) throws Exception { String result_code = map.get("result_code"); String return_code = map.get("return_code"); @@ -346,6 +344,7 @@ public class WxPaymentController { */ @RequestMapping("/paymentCallback") public Object payNotify(HttpServletRequest request, HttpServletResponse response) { + System.out.println("+++++++++进入回调"); try { ServletInputStream in = null; BufferedReader reader = null; @@ -369,7 +368,7 @@ public class WxPaymentController { e.printStackTrace(); } } - content.toString(); + System.out.println("+++++++++" + content.toString()); //将xml转换成map Map map = WXPayUtil.xmlToMap(content.toString()); String return_code = map.get("return_code"); @@ -401,132 +400,45 @@ public class WxPaymentController { return null; } - /** - * 生成xml格式 添加参数时,按照abcd26个字母顺序添加 - * - * @param tradeNo 微信单号 - * @param out_refund_no 退款单号 - * @param total_fee 总金额 - * @param refund_fee 退款金额 - * @param refund_desc 退款原因 - * @return - */ - private String createOutXMLParam(String tradeNo, String out_refund_no, String total_fee, String refund_fee, String refund_desc) { - HashMap map = new HashMap<>(); - //随机字符串 - String nonceStr = WXPayUtil.generateNonceStr(); - map.put("appid", environment.getProperty("APPID")); - //商户id - map.put("mch_id", environment.getProperty("MCHID")); - //随机字符串 - map.put("nonce_str", nonceStr); - //商户退款单号 一个订单唯一 - map.put("out_refund_no", tradeNo); - //退款原因 - map.put("refund_desc", refund_desc); - //退款金额 - map.put("refund_fee", refund_fee); - //订单金额 - map.put("total_fee", total_fee); - //微信订单号 - map.put("transaction_id", out_refund_no); - String xml = ""; - try { - String signature = WXPayUtil.generateSignature(map, environment.getProperty("KEY")); - map.put("sign", signature); - xml = WXPayUtil.mapToXml(map); - } catch (Exception e) { - e.printStackTrace(); - } - return xml; - } - /** - * 加载证书 - * - * @param certPath 证书位置 - * @throws Exception - */ - private CloseableHttpClient initCert(String certPath) throws Exception { - String path = "apiclient_cert.p12"; - //File file = new File(this.getClass().getResource("/").getPath()+path); - File file = new File("/www/wwwroot/msjd.project2.tingsun.net/" + path); - // 证书密码,默认为商户ID - String key = environment.getProperty("MCHID"); - // 指定读取证书格式为PKCS12 - KeyStore keyStore = KeyStore.getInstance("PKCS12"); - // 读取本机存放的PKCS12证书文件 - FileInputStream instream = new FileInputStream(file); - try { - // 指定PKCS12的密码(商户ID) - keyStore.load(instream, key.toCharArray()); - } finally { - instream.close(); - } - SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build(); - SSLConnectionSocketFactory sslsf = - new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, - SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); - return HttpClients.custom().setSSLSocketFactory(sslsf).build(); - } - /** - * 修改退款订单 - * @param orderId - * @param transactionId - * @return - * @throws Exception - */ - /* public int addOrUpdate(Long orderId, String transactionId) throws Exception { - Order order = orderMapper.selectById(orderId); - String userId = StringUtils.valueOf(order.getUserId()); - User user = userMapper.getUserVo(userId); - order.setPrepayId(transactionId); - orderMapper.updateById(order); - return 0; - }*/ /** * 企业退款 * * @return */ -/* @GetMapping("/enterpriseCheckOut") + @GetMapping("/enterpriseCheckOut") @ApiOperation(value = "企业退款", notes = "传入order") - public Object enterpriseCheckOut(HttpServletRequest servletRequest) { - String orderNumber = servletRequest.getParameter("orderNumber"); - String openid = servletRequest.getParameter("openid"); + public Object enterpriseCheckOut(String openid, double amount) { String reason = "退款申请"; - return enterpriseOut(orderNumber, openid, reason); + return enterpriseOut(amount, openid, reason); } - public Object enterpriseOut(String orderNumber, String openid, String reason) { - OrderVO orderInfo = orderService.selectOrderNumber(orderNumber); - - String retreat = StringUtils.valueOf(map.get("retreat")); - if (StringUtils.validatorEmpty(retreat)) { - return new SuccessResponseData(ResponseConstants.NOT_EXISTING, "订单金额出错"); - } + public Object enterpriseOut(double amount, String openid, String reason) { + //生成退款订单 + //OrderVO orderInfo = orderService.selectOrderNumber(orderNumber); + String orderOutNumber = "wxOut" + DateUtils.timePath(); CloseableHttpClient httpClient = null; try { //证书的地址 ConfigListener.getConf().get("certPath"); - httpClient = initCert(ConfigListener.getConf().get("certPath")); + httpClient = initCert(); } catch (Exception e) { e.printStackTrace(); } //退款金额单位为分 - Double value = Double.valueOf(retreat) * 100; + Double value = amount * 100; Integer refund_fee = value.intValue(); if (refund_fee <= 0) { - return new SuccessResponseData(ResponseConstants.NOT_EXISTING, "订单金额出错"); + return "订单金额出错"; } String result = ""; HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"); AjaxResult successResponseData = new AjaxResult(); - StringEntity postEntity = new StringEntity(creatXMLParam(orderInfo.getPrepayId(), refund_fee.toString(), reason, openid), "UTF-8"); + StringEntity postEntity = new StringEntity(creatXMLParam(orderOutNumber, refund_fee.toString(), reason, openid), "UTF-8"); httpPost.addHeader("Content-Type", "text/xml"); httpPost.setEntity(postEntity); try { @@ -545,10 +457,40 @@ public class WxPaymentController { } finally { httpPost.abort(); } - return parseXml(result, successResponseData, orderInfo.getId(), Double.valueOf(retreat)); - }*/ + return parseXml(result, successResponseData, "orderId", amount); + } + /** + * 加载证书 + * + * @param 证书位置 + * @throws Exception + */ + private CloseableHttpClient initCert() throws Exception { + String path = "apiclient_cert.p12"; + File file = new File(this.getClass().getResource("/").getPath() + path); + //线上地址 + //File file = new File("/www/wwwroot/msjd.project2.tingsun.net/" + path); + // 证书密码,默认为商户ID + String key = environment.getProperty("MCHID"); + // 指定读取证书格式为PKCS12 + KeyStore keyStore = KeyStore.getInstance("PKCS12"); + // 读取本机存放的PKCS12证书文件 + FileInputStream instream = new FileInputStream(file); + try { + // 指定PKCS12的密码(商户ID) + keyStore.load(instream, key.toCharArray()); + } finally { + instream.close(); + } + SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build(); + SSLConnectionSocketFactory sslsf = + new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, + SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + return HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } + /** * 生成xml格式 添加参数时,按照abcd26个字母顺序添加 * @@ -602,14 +544,15 @@ public class WxPaymentController { * @param jsonObject json对象 * @return */ -/* private AjaxResult parseXml(String result, AjaxResult jsonObject, Long id, Double refundMoney) { + private AjaxResult parseXml(String result, AjaxResult jsonObject, String id, Double amount) { try { Map map = WXPayUtil.xmlToMap(result); String return_code = map.get("return_code"); if ("FAIL".equals(return_code)) { jsonObject.error(map.get("return_msg")); } else { - orderService.checkOut(id, refundMoney); + //退款成功修改订单 + //orderService.checkOut(id, amount); jsonObject.success(map); } } catch (Exception e) { @@ -617,5 +560,27 @@ public class WxPaymentController { e.printStackTrace(); } return jsonObject; - }*/ + } + + @GetMapping("/payment1") + @ApiOperation(value = "微信支付", notes = "传入order") + public AjaxResult payment1() { + JSONObject jsonObject = new JSONObject(); + JSONObject amount = new JSONObject(); + JSONObject payer = new JSONObject(); + String orderNumber = "wx" + DateUtils.timePath(); + jsonObject.put("mchid", environment.getProperty("MCHID")); + jsonObject.put("out_trade_no", orderNumber); + jsonObject.put("appid", environment.getProperty("APPID")); + jsonObject.put("description", "微信支付"); + jsonObject.put("notify_url", environment.getProperty("SERVERDOMAIN")); + amount.put("total", 1); + amount.put("currency", "CNY"); + jsonObject.put("amount", amount); + payer.put("openid", "ot6ul4rpKdrLdeu8EgXNiQyxV-yU"); + jsonObject.put("payer", payer); + String result = HttpUtils.postBody("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi", jsonObject); + JSONObject json = JSON.parseObject(result); + return AjaxResult.success(json); + } } diff --git a/xhpc-modules/xhpc-payment/src/main/resources/apiclient_cert.p12 b/xhpc-modules/xhpc-payment/src/main/resources/apiclient_cert.p12 new file mode 100644 index 0000000000000000000000000000000000000000..e006e0e32753b57f4946e2e7bffcbde01f710c13 GIT binary patch literal 2710 zcmY+EX*3j!8pp@X7>o?EmUYb7_oapGGs8@lWF}!S_9ZVx*_SlNRwPW>HAt4MS<5ok zkbM^tq9T$tQLpPg=ib}BAO7b#&+q@7=i^U_3{3_yfRxBk8wiU`G&cGN8v_#qjSMvb zlcBg1j8P(kyZ=-W8X4Shf@**afRj=7r(sYMgh2oO;S>Wz2?k~!zJIxH!|X=|5XcOO zAcG^Y7mSND&Mt2D0B$gjmrD(9YAqXQzsfV18aYj@Mh=&dPt!Mb{Ew&Y+}^fwl80)( z_sIAG@Yd^>Q54z_1IUjk5?tk{)S0Pu?J{=`! z>yPtp7^Oz+6lNCf{c?f_nGTpvUB|U$c`vh@;&)P|aOv=$8y?TL?LoBc6m^%pkdfr!a+V*2kn(Mce7yVmm7UIVxCE>LA1G6C%H2o_-SMyj{2sY8TGN{^8v|gwWc4qh^Tef?H*^K|V4ef-WxlT+P_Cw4?rW zy*XibURj>=lLOs^qXuKUckmhC0+L#n+8A;(Z~wdMw7cAgL&}`*=rU=)aMwc{9?k0; z_#uQHRe#SoIpQ1&Y)(^Ko@<)aeBW9k=9>*)mDd9+Bv5q}a(ulcfwC(OdotKp_@m}d~|+G%Z%O_b@1%nYU42xFmj>C{_2%VzbX zoNx~G!B^#j?>lmpCI#Uhj#DNbhmZCPdzRnfmcJ%&u3uH8y`d~bY1%Bfl4R|}BVi{UH zF`WQZ7^D{J8vr#F0QNC9X5C~{&LwSF<+y>Vh+eZ1^i@>szV)+1HTp^tg)y_I-U%QQ zlgk^RpPZZ~4m33Hj5uj|qY&4v)Z+eyV;F3aeXm%?lsb#=P{( zHN-L#ABB-(!(8J+m`RGmJnzospZ$Vrb}QA@ZZoHvve;G>XliZ`*TbeCIOUhQ>SSOc z7DZO~FhiZFfSj4|G2u#~)JX=>*Iig+ZdJRcQsbLz?F9h=cdCmVtISM-b)`FbUP>^g z=Mjjc+|igX&$gs3w`(kU>WiGxV!Fjy<@~r}dAV~`N#pTL%ggS6J08j{oAGum;cM1Q z>P0p z?c!l+qv1bR1Czl$a7hHr5n;S?Fe#Ji+D1q?(#RyZ%#{vpRSW0ZXfL7oulL5^EEs+& zRmslPRl*q%@AOUACmm=l^P4864^1y*zOnQ;`Pp%Zt@k;x-xXqv$GQ0kiN_NqbfZmg zFCP?b1?rVtb7;xbuH7^cI9t_w#xD)Nx7nGrEzC8!NrDuR3jn^`#a%;!5A$K2J zn3BTF$HUKw^pec^6rXo>7U#zY&+CyJt4JSWqqo1+RgG;?uZn=L#p%Bg^dOPy#F-NG zR}J1bHYZ(xs#yq$_N}@I#?QJt%ZJ|nQA#-Gn*ra|Lw?XLWHUd?$Xh3@66nB$UKrBz z!j}glTDh2;W3!jc1b;YxVk9gfgF1k`y}L)7F(04Al{c02T$(Vg>{B%N~ zgw|)5>&vDY!{BXT))3OIKE+R2FMp6uU$&H2=4rYpqV>C%>Ws44ioD)y(zIFMSvbM1 zm(9>8)~=aVEIzSa4P()J&aGpp=N7{he$@Y&BPmrk=rcA=Sr=ISrYy;}g3>t^IkcDJ zz2K>=Pz@laGBfEp2DBaF)Uvu^aG^(dP z-j|ZTo4fGK$C1wonELO21IfC{?r}9bJP%H$EJN-ZEwVxA6oe(>{wi0=yDi>f)JnS%##n9uXIke!FTw$ssh4fuzFFk z4g|QTw1Ir^WB)xDGAo*Dl$Kux5Pk0!zW0dThGnF!7mJFWY-{CD$yyo(TQq|8_U1B#aV@-pDH+ z%#NM8g@3qUXk>74=@O_O;u*`D%_D_X7&ZH9#1_p8C3V*)O$T4gkq1PFO>vY(yFasM zLAnn8B?D5I5ccYMYPs5&eXTmMJ`M(L-LPs43mT6RMeN~;&U3Hy=0W`fyRIXksY|)X z(o8Kp2_C*nQ8HH)Y}S{WTg*~$p0z#3BCYuNZH{$P?uQAsx=pIZ98t&0)X*kD(?age zS74iJlSJ&a!sC5iFE0W1$-g)pyG?GBEX7L2lieS(>#P+ti*Y$#5h^_22M~~yKCj|u zD$vEd|FV2BKGDys#azfG z?(t{YF@_LhFTq>W+J*%c<+xd|b3Ga5jfveY!XNDcma>`BYuQ;V@o4+dLp;7*81aDE`RtsKb@kQx+ZI_o1WlqE<1utg!$idw|~l&Z4&!k zMP-YFX*n&SQ@TDlAlYPYbB`Tb@GUop<&sIxO!P?xw5qq;=gue;Zf!Vb925C zv9Fcic+bKbf*m__YnfDp3@EAoIpS895JmzB02hEa;1<9E5CjkfpiVYlz#V`G!1W|f zC-e@$MM+)>uEYXil!bwSXBh!tZW?DUWw)njUlG=o`O_#-v2awk2h7~R0ti}D%YXDQ Dh-2#b literal 0 HcmV?d00001 diff --git a/xhpc-modules/xhpc-payment/src/main/resources/bootstrap.yml b/xhpc-modules/xhpc-payment/src/main/resources/bootstrap.yml index 648ff1b1..c596f5c4 100644 --- a/xhpc-modules/xhpc-payment/src/main/resources/bootstrap.yml +++ b/xhpc-modules/xhpc-payment/src/main/resources/bootstrap.yml @@ -43,4 +43,10 @@ KEY: "sichuanxianghuakejiyouxiangongsi" #微信小程序支付地址 WXPAYUNIFIEDORDER: "https://api.mch.weixin.qq.com/pay/unifiedorder" #支付回调地址 -SERVERDOMAIN: "https://cdz.project2.tingsun.net/wx/paymentCallback" \ No newline at end of file +SERVERDOMAIN: "https://cdz.project2.tingsun.net/wx/paymentCallback" +#支付宝公钥 +ALIPAYPUBLICKEY: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjHDksTgZTpf0wh7oeTVRp0h3SqzTM2smjEJnx9jF1+q3WSXLRB4OzSzq7VsJ/szcyK10ZGO5PxeQ4u9GAG/U+7xhs7ei1cJB/Er55Sg9SbjfkTpwlDv181UJCRJJ/IAcqyqezwTpB8e2trYmHKovUdt0KR9/tVkGa7hsNd5GfxTOUaAFc3zADqRVM+wGimtG0NYfOF2f8tkmBEAiMMLKq5pbAnHU723a1cm/nfVp7gvXfsnO0k2GvRuHzb8mxIhWLiAnwdK9gEu5za/jWxo/xIvf2sdJPYdWj+yfyzA2e1fJkx4uRUzX31CXxZvP2/tfEcnTdI0gxN+OH2eAMiPVswIDAQAB"; +#支付宝私钥 +ALIPAYPRIVATEKEY: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCw3YH8KMvE7yH6C/rgnbXjml5NMvCcRNl+tbR9QEjl/9AdDIZaYvlQ72oKiOIk7GmDh3sB0YmiFnTcCj7cmKpZd2wLEP0nwwxTGTbBXi1bo/wQUI1a/mNA8rYZfwxfQZ07E28M2kMB+PE29clu+xo8TtjgiX7jofzEyQfES1uZMMDNLA+1cAYc0ZYo0NCJYEFpXm5SJHauC5+biQnOte49EbmzoXuYRap2RBf6suHEflAEgovk9L+hfPelXKG88lQNtg4w6jzNYRcuBa3IZlTJbLPGxH35eCMu0UGpa5EyH/nK+QrycESvEOfJ60urIU5FmOB2ikly2bgLLXZ43oedAgMBAAECggEBAKWt2qYsUTYaDOn/bvQayNh9Mvl+TocUt+lKrdjm72MFUB7mLLVfIc3/eIaF09Ji5DSiJUh+0T9VagL2VgyvtmQ4yq1TLNKilFkDtZdOcY72/pkJ3GDxDGk68/rOWPiirnc4rT6M91hRqySg+iFMeDcmZWNxabwzcmWlK/Fl5liJD03WNEuUNKE5qD9lQwgJEH9x8XxOtfgTk84UPoscOkHTsK7rhgcagbqT6q40DMfqzjoE0BxdTHAtuXbkhWP49UHFMzyilTbk/fQhpxngqnTXsnS8R8gzg/r5xFmss88yVTWCcjonjkBQGuyuyXIgEHhIrAt8WwXHODqlnttglMECgYEA+bE2G6zKoeQ4ZMmCgj9s894BB8dwtY3u4veM/F2g7b1qt6gh6KCRb+yHv0sOUCVLGsc6mbh/pcw2Ply68ZRleysAog7tAnNIw3YQJtYM1+5To9dCElq0oLBCU8szYgvIrwla00uHFkovrspn4HCwVDmJyQC3Dk9zICP44RlXCyMCgYEAtVVQ4c/mTtkym0iy10YY1HskWiOwAjb0/VnTkXsclePfX/ld3EfUwCeRn93ANhm7Fql8emiU9K5nTx1n/erGhT4AyzMLf3/y4KhIJRa+4dhae6J0W3Sd9oZOnXUiC0WsVxEMVn2BIa9HMFaKdyrKGiu2Vmzqn0Y39xpjPzwrrj8CgYB1MpmMCeGedUmG/RJ14iFYocZoCVO8097hx4H0XloP3M1/YLpxvxQkrafVwPv54FdNPWAjEPdRMfXv9YSFqbqsQjXs2waiFMx9eigAoo2quKGnkHzhspN/rNulCwaWKaPLjJ+F97hzXOTerQBu11XcYplqsBw76kzGNDw4I7W4cwKBgGkAHxay6PyNXnV2kkB/kY8wQyuC8L9HjXNK2WyrajENQ2JypjwQyAwAnZ2BrXRmT+ReffrvphlNB/tS3s20bgHnllQTmbvZng0ixKvdUOi7/CENP+1ZSMLgoJMiqXT3gkTkVU2b3PNhaIqAAivg9ihTWYEQDofuBCgs+n06XVzHAoGAcJKdJR2PPMIkfS7zHec02pZGLiC1mvxQx4rjKKT+OvIyD98KipWCDXieYKseqN2V6EjZE/Nhekpi2Bybhrm8iSQoiJilwaQ33DoBYCnW/pjfwxVLM7ch3fQGsOxJMFLcEC8KLu2k/nZkTGCrfJzmcB9ODA2pfaVXfTA57KIPxuk="; +#支付宝appid +ALIPAYAPPID: "2021002156615717"; \ No newline at end of file diff --git a/xhpc-modules/xhpc-payment/src/main/resources/mapper/XhpcRechargeOrderMapper.xml b/xhpc-modules/xhpc-payment/src/main/resources/mapper/XhpcRechargeOrderMapper.xml index 21083fa3..8fcc7474 100644 --- a/xhpc-modules/xhpc-payment/src/main/resources/mapper/XhpcRechargeOrderMapper.xml +++ b/xhpc-modules/xhpc-payment/src/main/resources/mapper/XhpcRechargeOrderMapper.xml @@ -20,7 +20,7 @@ - + INSERT INTO xhpc_recharge_order @@ -106,7 +106,7 @@ - + UPDATE xhpc_recharge_order user_id = #{userId}, diff --git a/xhpc-modules/xhpc-user/pom.xml b/xhpc-modules/xhpc-user/pom.xml index 26623541..1ff1ea0a 100644 --- a/xhpc-modules/xhpc-user/pom.xml +++ b/xhpc-modules/xhpc-user/pom.xml @@ -78,6 +78,17 @@ ${project.artifactId} + + + src/main/resources + + + src/main/java + + **/*.xml + + + org.springframework.boot diff --git a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/controller/XhpcAppUserController.java b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/controller/XhpcAppUserController.java index 57c9a20c..8625d0ea 100644 --- a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/controller/XhpcAppUserController.java +++ b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/controller/XhpcAppUserController.java @@ -1,19 +1,33 @@ package com.xhpc.user.controller; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.request.AlipaySystemOauthTokenRequest; import com.alipay.api.response.AlipaySystemOauthTokenResponse; import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.utils.HttpUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.sign.Base64; import com.ruoyi.common.core.web.controller.BaseController; import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.page.TableDataInfo; import com.xhpc.user.service.IXhpcAppUserUserService; import io.swagger.annotations.ApiOperation; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.*; +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; import javax.servlet.http.HttpServletRequest; +import java.security.AlgorithmParameters; +import java.security.Security; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -29,6 +43,9 @@ public class XhpcAppUserController extends BaseController { @Autowired private IXhpcAppUserUserService iXhpcAppUserUserService; + @Autowired + private Environment environment; + /** * C端用户详情 */ @@ -110,6 +127,87 @@ public class XhpcAppUserController extends BaseController { return iXhpcAppUserUserService.voluntaryLogin(map); } + /* + * TODO 获取微信权限标识 openid ,session_key,unionid + * @author fjd + * @date 2020-06-24 10:07 + */ + @PostMapping("/jscode2session") + @ApiOperation(value = "获取微信权限标识", notes = "jsCode") + public Object jsCode(String jsCode, String encryptedData, String iv) { + if (null == jsCode) { + return "信息不完整"; + } + String url = environment.getProperty("WXGETJSCODE") + jsCode + "&grant_type=authorization_code"; + String result = HttpUtils.get(url); + JSONObject json = JSON.parseObject(result); + if (null != json) { + String openid = json.getString("openid"); + String sessionKey = json.getString("session_key"); + if (StringUtils.isNull(openid)) { + return "openid获取失败"; + } + if (StringUtils.isNull(sessionKey)) { + return "sessionKey获取失败"; + } + + Map map = new HashMap<>(16); + map.put("openid", openid); + JSONObject jsonObject = new JSONObject(); + if ((!"".equals(encryptedData) && encryptedData != null) && (!"".equals(iv) && iv != null)) { + jsonObject = getPhoneNumber(encryptedData, sessionKey, iv); + if (StringUtils.isNull(jsonObject)) { + map.put("name", jsonObject.get("nickName")); + map.put("sex", jsonObject.get("gender")); + map.put("avatar", jsonObject.get("avatarUrl")); + map.put("phone", jsonObject.get("purePhoneNumber")); + } + } + return map; + } + return "openid获取失败"; + } + + /* + * TODO 微信获取手机号 + * @author fjd + * @date 2020-06-24 11:23 + */ + public JSONObject getPhoneNumber(String encryptedData, String sessionKey, String iv) { + try { + // 被加密的数据 + byte[] dataByte = Base64.decode(encryptedData); + // 加密秘钥 + byte[] keyByte = Base64.decode(sessionKey); + // 偏移量 + byte[] ivByte = Base64.decode(iv); + // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 + int base = 16; + if (keyByte.length % base != 0) { + int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0); + byte[] temp = new byte[groups * base]; + Arrays.fill(temp, (byte) 0); + System.arraycopy(keyByte, 0, temp, 0, keyByte.length); + keyByte = temp; + } + // 初始化 + Security.addProvider(new BouncyCastleProvider()); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); + SecretKeySpec spec = new SecretKeySpec(keyByte, "AES"); + AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES"); + parameters.init(new IvParameterSpec(ivByte)); + cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化 + byte[] resultByte = cipher.doFinal(dataByte); + if (null != resultByte && resultByte.length > 0) { + String result = new String(resultByte, "UTF-8"); + return JSONObject.parseObject(result); + } + } catch (Exception e) { + } + return null; + } + + /** * 支付宝授权 */ diff --git a/xhpc-modules/xhpc-user/src/main/resources/bootstrap.yml b/xhpc-modules/xhpc-user/src/main/resources/bootstrap.yml index 1a40ab4f..92e0f767 100644 --- a/xhpc-modules/xhpc-user/src/main/resources/bootstrap.yml +++ b/xhpc-modules/xhpc-user/src/main/resources/bootstrap.yml @@ -27,3 +27,11 @@ spring: # 共享配置 shared-configs: - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +#获取微信openid地址 +WXGETJSCODE: "https://api.weixin.qq.com/sns/jscode2session?appid=wxd0a48e00319ef8a7&secret=e26d9088b58e24af69411d5933cece47&js_code=" +#支付宝公钥 +ALIPAYPUBLICKEY: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjHDksTgZTpf0wh7oeTVRp0h3SqzTM2smjEJnx9jF1+q3WSXLRB4OzSzq7VsJ/szcyK10ZGO5PxeQ4u9GAG/U+7xhs7ei1cJB/Er55Sg9SbjfkTpwlDv181UJCRJJ/IAcqyqezwTpB8e2trYmHKovUdt0KR9/tVkGa7hsNd5GfxTOUaAFc3zADqRVM+wGimtG0NYfOF2f8tkmBEAiMMLKq5pbAnHU723a1cm/nfVp7gvXfsnO0k2GvRuHzb8mxIhWLiAnwdK9gEu5za/jWxo/xIvf2sdJPYdWj+yfyzA2e1fJkx4uRUzX31CXxZvP2/tfEcnTdI0gxN+OH2eAMiPVswIDAQAB"; +#支付宝私钥 +ALIPAYPRIVATEKEY: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCw3YH8KMvE7yH6C/rgnbXjml5NMvCcRNl+tbR9QEjl/9AdDIZaYvlQ72oKiOIk7GmDh3sB0YmiFnTcCj7cmKpZd2wLEP0nwwxTGTbBXi1bo/wQUI1a/mNA8rYZfwxfQZ07E28M2kMB+PE29clu+xo8TtjgiX7jofzEyQfES1uZMMDNLA+1cAYc0ZYo0NCJYEFpXm5SJHauC5+biQnOte49EbmzoXuYRap2RBf6suHEflAEgovk9L+hfPelXKG88lQNtg4w6jzNYRcuBa3IZlTJbLPGxH35eCMu0UGpa5EyH/nK+QrycESvEOfJ60urIU5FmOB2ikly2bgLLXZ43oedAgMBAAECggEBAKWt2qYsUTYaDOn/bvQayNh9Mvl+TocUt+lKrdjm72MFUB7mLLVfIc3/eIaF09Ji5DSiJUh+0T9VagL2VgyvtmQ4yq1TLNKilFkDtZdOcY72/pkJ3GDxDGk68/rOWPiirnc4rT6M91hRqySg+iFMeDcmZWNxabwzcmWlK/Fl5liJD03WNEuUNKE5qD9lQwgJEH9x8XxOtfgTk84UPoscOkHTsK7rhgcagbqT6q40DMfqzjoE0BxdTHAtuXbkhWP49UHFMzyilTbk/fQhpxngqnTXsnS8R8gzg/r5xFmss88yVTWCcjonjkBQGuyuyXIgEHhIrAt8WwXHODqlnttglMECgYEA+bE2G6zKoeQ4ZMmCgj9s894BB8dwtY3u4veM/F2g7b1qt6gh6KCRb+yHv0sOUCVLGsc6mbh/pcw2Ply68ZRleysAog7tAnNIw3YQJtYM1+5To9dCElq0oLBCU8szYgvIrwla00uHFkovrspn4HCwVDmJyQC3Dk9zICP44RlXCyMCgYEAtVVQ4c/mTtkym0iy10YY1HskWiOwAjb0/VnTkXsclePfX/ld3EfUwCeRn93ANhm7Fql8emiU9K5nTx1n/erGhT4AyzMLf3/y4KhIJRa+4dhae6J0W3Sd9oZOnXUiC0WsVxEMVn2BIa9HMFaKdyrKGiu2Vmzqn0Y39xpjPzwrrj8CgYB1MpmMCeGedUmG/RJ14iFYocZoCVO8097hx4H0XloP3M1/YLpxvxQkrafVwPv54FdNPWAjEPdRMfXv9YSFqbqsQjXs2waiFMx9eigAoo2quKGnkHzhspN/rNulCwaWKaPLjJ+F97hzXOTerQBu11XcYplqsBw76kzGNDw4I7W4cwKBgGkAHxay6PyNXnV2kkB/kY8wQyuC8L9HjXNK2WyrajENQ2JypjwQyAwAnZ2BrXRmT+ReffrvphlNB/tS3s20bgHnllQTmbvZng0ixKvdUOi7/CENP+1ZSMLgoJMiqXT3gkTkVU2b3PNhaIqAAivg9ihTWYEQDofuBCgs+n06XVzHAoGAcJKdJR2PPMIkfS7zHec02pZGLiC1mvxQx4rjKKT+OvIyD98KipWCDXieYKseqN2V6EjZE/Nhekpi2Bybhrm8iSQoiJilwaQ33DoBYCnW/pjfwxVLM7ch3fQGsOxJMFLcEC8KLu2k/nZkTGCrfJzmcB9ODA2pfaVXfTA57KIPxuk="; +#支付宝appid +ALIPAYAPPID: "2021002156615717"; \ No newline at end of file