1新增支付服务

This commit is contained in:
fengjundan 2021-07-22 19:03:27 +08:00
parent 22794224a6
commit 3456fbdd43
26 changed files with 2628 additions and 0 deletions

View File

@ -112,6 +112,17 @@
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
</dependencies>

View File

@ -0,0 +1,59 @@
package com.ruoyi.common.core.constant;
import org.apache.http.client.HttpClient;
/**
* 常量
*/
public class WXPayConstants {
public enum SignType {
MD5, HMACSHA256
}
public static final String DOMAIN_API = "api.mch.weixin.qq.com";
public static final String DOMAIN_API2 = "api2.mch.weixin.qq.com";
public static final String DOMAIN_APIHK = "apihk.mch.weixin.qq.com";
public static final String DOMAIN_APIUS = "apius.mch.weixin.qq.com";
public static final String FAIL = "FAIL";
public static final String SUCCESS = "SUCCESS";
public static final String HMACSHA256 = "HMAC-SHA256";
public static final String MD5 = "MD5";
public static final String FIELD_SIGN = "sign";
public static final String FIELD_SIGN_TYPE = "sign_type";
public static final String WXPAYSDK_VERSION = "WXPaySDK/3.0.9";
public static final String USER_AGENT = WXPAYSDK_VERSION +
" (" + System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version") +
") Java/" + System.getProperty("java.version") + " HttpClient/" + HttpClient.class.getPackage().getImplementationVersion();
public static final String MICROPAY_URL_SUFFIX = "/pay/micropay";
public static final String UNIFIEDORDER_URL_SUFFIX = "/pay/unifiedorder";
public static final String ORDERQUERY_URL_SUFFIX = "/pay/orderquery";
public static final String REVERSE_URL_SUFFIX = "/secapi/pay/reverse";
public static final String CLOSEORDER_URL_SUFFIX = "/pay/closeorder";
public static final String REFUND_URL_SUFFIX = "/secapi/pay/refund";
public static final String REFUNDQUERY_URL_SUFFIX = "/pay/refundquery";
public static final String DOWNLOADBILL_URL_SUFFIX = "/pay/downloadbill";
public static final String REPORT_URL_SUFFIX = "/payitil/report";
public static final String SHORTURL_URL_SUFFIX = "/tools/shorturl";
public static final String AUTHCODETOOPENID_URL_SUFFIX = "/tools/authcodetoopenid";
// sandbox
public static final String SANDBOX_MICROPAY_URL_SUFFIX = "/sandboxnew/pay/micropay";
public static final String SANDBOX_UNIFIEDORDER_URL_SUFFIX = "/sandboxnew/pay/unifiedorder";
public static final String SANDBOX_ORDERQUERY_URL_SUFFIX = "/sandboxnew/pay/orderquery";
public static final String SANDBOX_REVERSE_URL_SUFFIX = "/sandboxnew/secapi/pay/reverse";
public static final String SANDBOX_CLOSEORDER_URL_SUFFIX = "/sandboxnew/pay/closeorder";
public static final String SANDBOX_REFUND_URL_SUFFIX = "/sandboxnew/secapi/pay/refund";
public static final String SANDBOX_REFUNDQUERY_URL_SUFFIX = "/sandboxnew/pay/refundquery";
public static final String SANDBOX_DOWNLOADBILL_URL_SUFFIX = "/sandboxnew/pay/downloadbill";
public static final String SANDBOX_REPORT_URL_SUFFIX = "/sandboxnew/payitil/report";
public static final String SANDBOX_SHORTURL_URL_SUFFIX = "/sandboxnew/tools/shorturl";
public static final String SANDBOX_AUTHCODETOOPENID_URL_SUFFIX = "/sandboxnew/tools/authcodetoopenid";
}

View File

@ -94,6 +94,15 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
return DateFormatUtils.format(now, "yyyy/MM/dd");
}
/**
* 日期路径 即年月日时分秒 如20180808010515
*/
public static final String timePath()
{
Date now = new Date();
return DateFormatUtils.format(now, YYYYMMDDHHMMSS);
}
/**
* 日期路径 即年// 如20180808
*/

View File

@ -0,0 +1,280 @@
package com.ruoyi.common.core.utils;
import org.dom4j.DocumentHelper;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.*;
public class PayUtils {
/**
* 获取当前机器的ip
*
* @return String
*/
public static String getLocalIp(){
InetAddress ia=null;
String localip = null;
try {
ia=ia.getLocalHost();
localip=ia.getHostAddress();
} catch (Exception e) {
e.printStackTrace();
}
return localip;
}
/**
* Map转换为 Xml
*
* @param map
* @return Xml
* @throws Exception
*/
public static String mapToXml(Map<String, String> map) throws Exception {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
//防止XXE攻击
documentBuilderFactory.setXIncludeAware(false);
documentBuilderFactory.setExpandEntityReferences(false);
DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
org.w3c.dom.Document document = documentBuilder.newDocument();
org.w3c.dom.Element root = document.createElement("xml");
document.appendChild(root);
for (String key: map.keySet()) {
String value = map.get(key);
if (value == null) {
value = "";
}
value = value.trim();
org.w3c.dom.Element filed = document.createElement(key);
filed.appendChild(document.createTextNode(value));
root.appendChild(filed);
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);
String output = writer.getBuffer().toString();
try {
writer.close();
}
catch (Exception ex) {
}
return output;
}
/**
* 创建签名Sign
*
* @param key
* @param parameters
* @return
*/
public static String createSign(Map<String,String> parameters,String key){
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();
Iterator<?> it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
if(entry.getValue() != null || !"".equals(entry.getValue())) {
String v = String.valueOf(entry.getValue());
if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
}
sb.append("key=" + key);
String sign = StringUtils.md5(sb.toString()).toUpperCase();
return sign;
}
/**
* XML转换为Map
*
* @param strXML
* @return Map
* @throws Exception
*/
public static Map<String, Object> getMapFromXML(String strXML) throws Exception {
try {
Map<String, Object> data = new HashMap<String, Object>();
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
//防止XXE攻击
documentBuilderFactory.setXIncludeAware(false);
documentBuilderFactory.setExpandEntityReferences(false);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
org.w3c.dom.Document doc = documentBuilder.parse(stream);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int idx = 0; idx < nodeList.getLength(); ++idx) {
Node node = nodeList.item(idx);
if (node.getNodeType() == Node.ELEMENT_NODE) {
org.w3c.dom.Element element = (org.w3c.dom.Element) node;
data.put(element.getNodeName(), element.getTextContent());
}
}
try {
stream.close();
} catch (Exception ex) {
ex.printStackTrace();
}
return data;
} catch (Exception ex) {
throw ex;
}
}
/**
* 生成随机数
*
* @return
*/
public static String makeUUID(int len) {
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, len);
}
/**
* 获取当前的Timestamp
*
* @return
*/
public static String getCurrentTimeStamp() {
return Long.toString(System.currentTimeMillis()/1000);
}
/**
* 获取当前的时间
* @return
*/
public static long getCurrentTimestampMs() {
return System.currentTimeMillis();
}
/**
* 生成订单号
*
* @return
*/
public static String generateOrderNo() {
SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
return sdf.format(new Date())+makeUUID(16);
}
/**
* 获取当前工程url
*
* @param request
* @return
*/
public static String getCurrentUrl(HttpServletRequest request){
return request.getScheme() +"://" + request.getServerName() + ":" +request.getServerPort() +request.getContextPath();
}
/**
* Xml字符串转换为Map
*
* @param xmlStr
* @return
*/
public static Map<String,Object> xmlStrToMap(String xmlStr){
try {
Map map = new HashMap();
org.dom4j.Document document = DocumentHelper.parseText(xmlStr);
org.dom4j.Element nodeElement = document.getRootElement();
List node = nodeElement.elements();
for (Iterator it = node.iterator(); it.hasNext();) {
org.dom4j.Element elm = (org.dom4j.Element) it.next();
map.put(elm.getName(), elm.getText());
elm = null;
}
return map;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 转换金额型到整型
* @param money
* @return
*/
public static String moneyToIntegerStr(Double money){
BigDecimal decimal = new BigDecimal(money);
int amount = decimal.multiply(new BigDecimal(100))
.setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
return String.valueOf(amount);
}
/**
* 除去数组中的空值和签名参数
* @param sArray 签名参数组
* @return 去掉空值与签名参数后的新签名参数组
*/
public static Map<String, String> paraFilter(Map<String, String> sArray) {
Map<String, String> result = new HashMap<String, String>();
if (sArray == null || sArray.size() <= 0) {
return result;
}
for (String key : sArray.keySet()) {
String value = sArray.get(key);
if (value == null || value.equals("") || key.equalsIgnoreCase("sign")
|| key.equalsIgnoreCase("sign_type")) {
continue;
}
result.put(key, value);
}
return result;
}
/**
* 把数组所有元素排序并按照参数=参数值的模式用&字符拼接成字符串
* @param params 需要排序并参与字符拼接的参数组
* @return 拼接后字符串
*/
public static String createLinkString(Map<String, String> params) {
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
String prestr = "";
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
if (i == keys.size() - 1) {//拼接时不包括最后一个&字符
prestr = prestr + key + "=" + value;
} else {
prestr = prestr + key + "=" + value + "&";
}
}
return prestr;
}
}

View File

@ -4,6 +4,8 @@ import com.ruoyi.common.core.text.StrFormatter;
import org.springframework.util.AntPathMatcher;
import java.beans.PropertyDescriptor;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -507,4 +509,21 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
}
return false;
}
public static String md5(String str) {
try {
// 生成一个MD5加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算md5函数
md.update(str.getBytes());
// digest()最后确定返回md5 hash值返回值为8位字符串因为md5 hash值是16位的hex值实际上就是8位的字符
// BigInteger函数则将8位的字符串转换成16位hex值用字符串来表示得到字符串形式的hash值
//一个byte是八位二进制也就是2位十六进制字符2的8次方等于16的2次方
return new BigInteger(1, md.digest()).toString(16).toUpperCase();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,298 @@
package com.ruoyi.common.core.utils;
import com.ruoyi.common.core.constant.WXPayConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.*;
/**
* 微信工具类
*/
public class WXPayUtil {
private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final Random RANDOM = new SecureRandom();
/**
* XML格式字符串转换为Map
*
* @param strXML XML字符串
* @return XML数据转换后的Map
* @throws Exception
*/
public static Map<String, String> xmlToMap(String strXML) throws Exception {
try {
Map<String, String> data = new HashMap<String, String>();
DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder();
InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
org.w3c.dom.Document doc = documentBuilder.parse(stream);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int idx = 0; idx < nodeList.getLength(); ++idx) {
Node node = nodeList.item(idx);
if (node.getNodeType() == Node.ELEMENT_NODE) {
org.w3c.dom.Element element = (org.w3c.dom.Element) node;
data.put(element.getNodeName(), element.getTextContent());
}
}
try {
stream.close();
} catch (Exception ex) {
// do nothing
}
return data;
} catch (Exception ex) {
WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
throw ex;
}
}
/**
* 将Map转换为XML格式的字符串
*
* @param data Map类型数据
* @return XML格式的字符串
* @throws Exception
*/
public static String mapToXml(Map<String, String> data) throws Exception {
org.w3c.dom.Document document = WXPayXmlUtil.newDocument();
org.w3c.dom.Element root = document.createElement("xml");
document.appendChild(root);
for (String key : data.keySet()) {
String value = data.get(key);
if (value == null) {
value = "";
}
value = value.trim();
org.w3c.dom.Element filed = document.createElement(key);
filed.appendChild(document.createTextNode(value));
root.appendChild(filed);
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);
String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
try {
writer.close();
} catch (Exception ex) {
}
return output;
}
/**
* 生成带有 sign XML 格式字符串
*
* @param data Map类型数据
* @param key API密钥
* @return 含有sign字段的XML
*/
public static String generateSignedXml(final Map<String, String> data, String key) throws Exception {
return generateSignedXml(data, key, WXPayConstants.SignType.MD5);
}
/**
* 生成带有 sign XML 格式字符串
*
* @param data Map类型数据
* @param key API密钥
* @param signType 签名类型
* @return 含有sign字段的XML
*/
public static String generateSignedXml(final Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
String sign = generateSignature(data, key, signType);
data.put(WXPayConstants.FIELD_SIGN, sign);
return mapToXml(data);
}
/**
* 判断签名是否正确
*
* @param xmlStr XML格式数据
* @param key API密钥
* @return 签名是否正确
* @throws Exception
*/
public static boolean isSignatureValid(String xmlStr, String key) throws Exception {
Map<String, String> data = xmlToMap(xmlStr);
if (!data.containsKey(WXPayConstants.FIELD_SIGN)) {
return false;
}
String sign = data.get(WXPayConstants.FIELD_SIGN);
return generateSignature(data, key).equals(sign);
}
/**
* 判断签名是否正确必须包含sign字段否则返回false使用MD5签名
*
* @param data Map类型数据
* @param key API密钥
* @return 签名是否正确
* @throws Exception
*/
public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {
return isSignatureValid(data, key, WXPayConstants.SignType.MD5);
}
/**
* 判断签名是否正确必须包含sign字段否则返回false
*
* @param data Map类型数据
* @param key API密钥
* @param signType 签名方式
* @return 签名是否正确
* @throws Exception
*/
public static boolean isSignatureValid(Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
if (!data.containsKey(WXPayConstants.FIELD_SIGN)) {
return false;
}
String sign = data.get(WXPayConstants.FIELD_SIGN);
return generateSignature(data, key, signType).equals(sign);
}
/**
* 生成签名
*
* @param data 待签名数据
* @param key API密钥
* @return 签名
*/
public static String generateSignature(final Map<String, String> data, String key) throws Exception {
return generateSignature(data, key, WXPayConstants.SignType.MD5);
}
/**
* 生成签名. 注意若含有sign_type字段必须和signType参数保持一致
*
* @param data 待签名数据
* @param key API密钥
* @param signType 签名方式
* @return 签名
*/
public static String generateSignature(final Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
Set<String> keySet = data.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (k.equals(WXPayConstants.FIELD_SIGN)) {
continue;
}
if (data.get(k).trim().length() > 0) // 参数值为空则不参与签名
sb.append(k).append("=").append(data.get(k).trim()).append("&");
}
sb.append("key=").append(key);
if (WXPayConstants.SignType.MD5.equals(signType)) {
return MD5(sb.toString()).toUpperCase();
} else if (WXPayConstants.SignType.HMACSHA256.equals(signType)) {
return HMACSHA256(sb.toString(), key);
} else {
throw new Exception(String.format("Invalid sign_type: %s", signType));
}
}
/**
* 获取随机字符串 Nonce Str
*
* @return String 随机字符串
*/
public static String generateNonceStr() {
char[] nonceChars = new char[32];
for (int index = 0; index < nonceChars.length; ++index) {
nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
}
return new String(nonceChars);
}
/**
* 生成 MD5
*
* @param data 待处理数据
* @return MD5结果
*/
public static String MD5(String data) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] array = md.digest(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
}
/**
* 生成 HMACSHA256
*
* @param data 待处理数据
* @param key 密钥
* @return 加密结果
* @throws Exception
*/
public static String HMACSHA256(String data, String key) throws Exception {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
}
/**
* 日志
*
* @return
*/
public static Logger getLogger() {
Logger logger = LoggerFactory.getLogger("wxpay java sdk");
return logger;
}
/**
* 获取当前时间戳单位秒
*
* @return
*/
public static long getCurrentTimestamp() {
return System.currentTimeMillis() / 1000;
}
/**
* 获取当前时间戳单位毫秒
*
* @return
*/
public static long getCurrentTimestampMs() {
return System.currentTimeMillis();
}
}

View File

@ -0,0 +1,31 @@
package com.ruoyi.common.core.utils;
import org.w3c.dom.Document;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
/**
* 2018/7/3
*/
public final class WXPayXmlUtil {
public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
documentBuilderFactory.setXIncludeAware(false);
documentBuilderFactory.setExpandEntityReferences(false);
return documentBuilderFactory.newDocumentBuilder();
}
public static Document newDocument() throws ParserConfigurationException {
return newDocumentBuilder().newDocument();
}
}

View File

@ -14,6 +14,7 @@
<module>xhpc-power-pile</module>
<module>xhpc-charging-station</module>
<module>xhpc-user</module>
<module>xhpc-payment</module>
</modules>
<artifactId>xhpc-modules</artifactId>

33
xhpc-modules/xhpc-payment/.gitignore vendored Normal file
View File

@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

View File

@ -0,0 +1,118 @@
/*
* Copyright 2007-present the original author or authors.
*
* 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
*
* https://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.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;
public class MavenWrapperDownloader {
private static final String WRAPPER_VERSION = "0.5.6";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if (mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if (mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if (!outputFile.getParentFile().exists()) {
if (!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
String username = System.getenv("MVNW_USERNAME");
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
}

Binary file not shown.

View File

@ -0,0 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

310
xhpc-modules/xhpc-payment/mvnw vendored Normal file
View File

@ -0,0 +1,310 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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
#
# https://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.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget "$jarUrl" -O "$wrapperJarPath"
else
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

182
xhpc-modules/xhpc-payment/mvnw.cmd vendored Normal file
View File

@ -0,0 +1,182 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>xhpc-modules</artifactId>
<version>3.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xhpc-payment</artifactId>
<description>
账号服务
</description>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- RuoYi Common DataSource -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datasource</artifactId>
</dependency>
<!-- RuoYi Common DataScope -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datascope</artifactId>
</dependency>
<!-- 支付宝sdk -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>${alipay.sdk}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.4.0</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,21 @@
package com.xhpc.payment;
import com.ruoyi.common.security.annotation.EnableCustomConfig;
import com.ruoyi.common.security.annotation.EnableRyFeignClients;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/*@EnableCustomConfig*/
@EnableRyFeignClients
@EnableFeignClients
@SpringBootApplication
@MapperScan("com.xhpc.payment.mapper")
public class PaymentApplication {
public static void main(String[] args) {
SpringApplication.run(PaymentApplication.class, args);
}
}

View File

@ -0,0 +1,621 @@
package com.xhpc.payment.controller;
import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.utils.DateUtils;
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.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.net.ssl.SSLContext;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 微信支付
* author:yuyang
* Date:2020/4/8
* Time:16:30
*/
@RestController
@RequestMapping("/wx")
@Api(value = "微信支付接口", tags = "微信支付接口")
public class WxPaymentController {
private static final Logger logger = LoggerFactory.getLogger(WxPaymentController.class);
private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final Random RANDOM = new SecureRandom();
@Autowired
private Environment environment;
@GetMapping("/payment")
@ApiOperation(value = "微信支付", notes = "传入order")
public Object getWXunifiedorder(HttpServletRequest servletRequest) {
AjaxResult responseData = new AjaxResult();
String openid = servletRequest.getParameter("openid");
if (StringUtils.isNull(openid)) {
return responseData.error(HttpStatus.BAD_REQUEST, "openid不能为空");
}
//总金额()订单总金额单位为分
String doubleValue = servletRequest.getParameter("doubleValue");
if (StringUtils.isNull(doubleValue)) {
return responseData.error(HttpStatus.BAD_REQUEST, "充值金额不能为空");
}
Double amount = Double.parseDouble(doubleValue);
String orderNumber = "wx"+ DateUtils.timePath();
//此次生成充值订单
// OrderVO orderInfo = orderService.selectOrderNumber(orderNumber);
if (0.0 == amount) {
return responseData.error(HttpStatus.BAD_REQUEST, "充值金额不能为0");
}
//附加数据()
String attach = attachYu(StringUtils.valueOf("123456"), StringUtils.valueOf(amount), null, orderNumber);
//商品描述()
String body = "用户充值";
//商户订单号()
String outTradeNo = orderNumber;
int Fee = amount.intValue();
//终端ip()
String spbillCreateIp = getRemoteLoginUserIp(servletRequest);
//交易类型()
String tradeType = "JSAPI";
Date date = new Date();
//微信过期时间格式
SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMddHHmmss");
//过期时间半个小时
Date expireTime = new Date(date.getTime() + 5 * 60 * 1000);
String timeStr = format1.format(expireTime);
//发送请求
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(environment.getProperty("WXPAYUNIFIEDORDER"));
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("Content-Type", "text/xml");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
out.print(createXMLParam(Fee, attach, tradeType, spbillCreateIp, outTradeNo, body, timeStr, environment.getProperty("SERVERDOMAIN"), environment.getProperty("APPID"), environment.getProperty("MCHID"), environment.getProperty("KEY"), openid));
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
System.out.println(result);
}
} catch (Exception e) {
e.printStackTrace();
}
//使用finally块来关闭输出流输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
//app
//Map<String, String> sign = createSign(result, 1, orderInfo.getId(), environment.getProperty("KEY"), doubleValue, remarks);
Map<String, String> sign = createSign(result, 1);
responseData.success(sign);
return responseData;
}
/**
* 生成签名
*
* @param result xml格式字符串
* @param pageType 页面类型 1-APP 2-PC
* @return
*/
public Map<String, String> createSign(String result, Integer pageType) {
try {
Map<String, String> map = WXPayUtil.xmlToMap(result);
String return_code = map.get("return_code");
if ("FAIL".equals(return_code)) {
return null;
} else {
if (pageType == 1) {
//我这里是手动拼接的 可以使用微信具类生成签名
String nonceStr = WXPayUtil.generateNonceStr();
Map<String, String> map1 = new HashMap<>();
map1.put("money", map.get("doubleValue"));
map1.put("appid", map.get("appid"));
map1.put("prepayId", map.get("prepay_id"));
map1.put("noncestr", nonceStr);
map1.put("nonceStr", nonceStr + "\",\"packageValue\":" + "\"Sign=WXPay\"");
map1.put("package", "Sign=WXPay");
map1.put("partnerid", map.get("mch_id"));
Long time = System.currentTimeMillis();
String timeStr = time.toString().substring(0, time.toString().length() - 3);
map1.put("timestamp", timeStr);
map1.put("sign", map.get("sign"));
map1.put("url", map.get("code_url"));
map1.put("key", environment.getProperty("KEY"));
return map1;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 生成xml格式参数
* 注释的是使用微信工具类生成的xml格式 添加参数时按照abcd26个字母顺序添加
*
* @param total_fee 支付金额
* @param attach 自定义参数
* @param trade_type 交易类型
* @param ip 终端ip地址
* @param out_trade_no 交易订单号
* @param body 交易信息
* @param timeExpire 交易过期时间
* @param WXNotifyUrl 微信支付回调地址
* @param appid 应用ID
* @param mch_id 商户号
* @param key 添加key值
* @return
*/
public String createXMLParam(Integer total_fee, String attach, String trade_type, String ip, String out_trade_no, String body, String timeExpire, String WXNotifyUrl, String appid, String mch_id, String key, String openid) {
String param = "";
String nonce_str = generateNonceStr();
String notify_url = WXNotifyUrl;
String spbill_create_ip = ip;
//应用ID
param += "appid=" + appid;
//附加数据 回调时可以获取
param += "&attach=" + attach;
//body 商品描述
param += "&body=" + body;
//商户号
param += "&mch_id=" + mch_id;
//随机字符串
param += "&nonce_str=" + nonce_str;
//回调地址
param += "&notify_url=" + notify_url;
if ("JSAPI".equals(trade_type)) {
//用户openid
param += "&openid=" + openid;
}
//商户订单号
param += "&out_trade_no=" + out_trade_no;
//终端IP
param += "&spbill_create_ip=" + spbill_create_ip;
//交易结束时间
param += "&time_expire=" + timeExpire;
//总金额
param += "&total_fee=" + total_fee;
//支付类型
param += "&trade_type=" + trade_type;
//生成签名 添加key值
String stringSignTemp = param + "&key=" + key;
//签名 不参与签名 默认MD5算法
String sign = StringUtils.md5(stringSignTemp);
String xmlString = "<xml>\n" +
" <appid>" + appid + "</appid>\n" +
" <attach>" + attach + "</attach>\n" +
" <body>" + body + "</body>\n" +
" <mch_id>" + mch_id + "</mch_id>\n" +
" <nonce_str>" + nonce_str + "</nonce_str>\n" +
" <notify_url>" + notify_url + "</notify_url>\n";
if ("JSAPI".equals(trade_type)) {
xmlString += " <openid>" + openid + "</openid>\n";
}
xmlString +=
" <out_trade_no>" + out_trade_no + "</out_trade_no>\n" +
" <spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>\n" +
" <time_expire>" + timeExpire + "</time_expire>\n" +
" <total_fee>" + total_fee + "</total_fee>\n" +
" <trade_type>" + trade_type + "</trade_type>\n" +
" <sign>" + sign + "</sign>\n" +
"</xml> ";
return xmlString;
}
//附加参数
public String attachYu(String id, String money, String payStyle, String out_trade_no) {
// 发送请求参数 业务参数
StringBuilder attachSB = new StringBuilder();
attachSB.append(",{\"customerId\":" + id);
attachSB.append(",\"money\":\"" + money + "\"");
attachSB.append(",\"out_trade_no\":\"" + out_trade_no + "\"}");
String attach = attachSB.substring(1);
return attach;
}
/**
* 获取随机字符串 Nonce Str
*
* @return String 随机字符串
*/
public String generateNonceStr() {
char[] nonceChars = new char[32];
for (int index = 0; index < nonceChars.length; ++index) {
nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
}
return new String(nonceChars);
}
//获取终端ip
public String getRemoteLoginUserIp(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
System.out.println("THE REAL IPS IS:" + ip);
if (ip != null && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
return ip;
}
/**
* 修改支付订单
*
* @param
* @param
* @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<String, String> map) throws Exception {
String result_code = map.get("result_code");
String return_code = map.get("return_code");
String out_trade_no = map.get("out_trade_no");
String openid = map.get("openid");
String transaction_id = map.get("transaction_id");
int flag = 0;
//支付订单编号
/*OrderVO order = orderMapper.selectOrderNumber(out_trade_no);
if (null != order) {
//检验是否需要再次回调刷新数据
//TODO 微信后台回调刷新订单支付状态等相关业务
addOrUpdatePaymentRecord(order.getId(), transaction_id);
}*/
return flag;
}
/**
* 回调Api
*/
@RequestMapping("/paymentCallback")
public Object payNotify(HttpServletRequest request, HttpServletResponse response) {
try {
ServletInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try {
in = request.getInputStream();
reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
String itemStr = "";// 作为输出字符串的临时串用于判断是否读取完毕
while (null != (itemStr = reader.readLine())) {
content.append(itemStr);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != reader)
reader.close();
if (null != in)
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
content.toString();
//将xml转换成map
Map<String, String> map = WXPayUtil.xmlToMap(content.toString());
String return_code = map.get("return_code");
//自定义参数 为json格式的字符串
//如果返回成功
if ("SUCCESS".equals(return_code)) {
//将自定义参数转换成JSONObject对象处理业务逻辑
paymentCallback(map);
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/xml; charset=utf-8");
PrintWriter out = null;
try {
out = response.getWriter();
out.print("<xml>\n" +
" <return_code><![CDATA[SUCCESS]]></return_code>\n" +
" <return_msg><![CDATA[OK]]></return_msg>\n" +
"</xml>\n");
out.close();
return null;
} catch (IOException e) {
e.printStackTrace();
}
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<String, String> 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")
@ApiOperation(value = "企业退款", notes = "传入order")
public Object enterpriseCheckOut(HttpServletRequest servletRequest) {
String orderNumber = servletRequest.getParameter("orderNumber");
String openid = servletRequest.getParameter("openid");
String reason = "退款申请";
return enterpriseOut(orderNumber, 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, "订单金额出错");
}
CloseableHttpClient httpClient = null;
try {
//证书的地址
ConfigListener.getConf().get("certPath");
httpClient = initCert(ConfigListener.getConf().get("certPath"));
} catch (Exception e) {
e.printStackTrace();
}
//退款金额单位为分
Double value = Double.valueOf(retreat) * 100;
Integer refund_fee = value.intValue();
if (refund_fee <= 0) {
return new SuccessResponseData(ResponseConstants.NOT_EXISTING, "订单金额出错");
}
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");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.setEntity(postEntity);
try {
HttpResponse response = null;
try {
response = httpClient.execute(httpPost);
} catch (IOException e) {
e.printStackTrace();
}
HttpEntity entity = response.getEntity();
try {
result = EntityUtils.toString(entity, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
} finally {
httpPost.abort();
}
return parseXml(result, successResponseData, orderInfo.getId(), Double.valueOf(retreat));
}*/
/**
* 生成xml格式 添加参数时按照abcd26个字母顺序添加
*
* @param openid 用户openid
* @param partner_trade_no 商户退款单号
* @param amount 退款金额
* @param refund_desc 退款原因
* @return
*/
private String creatXMLParam(String partner_trade_no, String amount, String refund_desc, String openid) {
String param = "";
//随机字符串
String nonceStr = WXPayUtil.generateNonceStr();
//退款金额
param += "amount=" + amount;
//校验用户姓名选项
param += "&check_name=" + "NO_CHECK";
//退款原因
param += "&desc=" + refund_desc;
param += "&mch_appid=" + environment.getProperty("APPID");
//商户id
param += "&mchid=" + environment.getProperty("MCHID");
//随机字符串
param += "&nonce_str=" + nonceStr;
//用户openid
param += "&openid=" + openid;
//商户退款单号 一个订单唯一
param += "&partner_trade_no=" + partner_trade_no;
//生成签名 添加key值
String stringSignTemp = param + "&key=" + environment.getProperty("KEY");
//签名 不参与签名 默认MD5算法
String sign = StringUtils.md5(stringSignTemp);
String xmlString = "<xml>\n" +
" <amount>" + amount + "</amount>\n" +
" <check_name>" + "NO_CHECK" + "</check_name>\n" +
" <desc>" + refund_desc + "</desc>\n" +
" <mch_appid>" + environment.getProperty("APPID") + "</mch_appid>\n" +
" <mchid>" + environment.getProperty("MCHID") + "</mchid>\n" +
" <nonce_str>" + nonceStr + "</nonce_str>\n" +
" <openid>" + openid + "</openid>\n" +
" <partner_trade_no>" + partner_trade_no + "</partner_trade_no>\n" +
" <sign>" + sign + "</sign>\n" +
"</xml> ";
return xmlString;
}
/**
* 解析xml字符串
*
* @param result 请求后的结果
* @param jsonObject json对象
* @return
*/
/* private AjaxResult parseXml(String result, AjaxResult jsonObject, Long id, Double refundMoney) {
try {
Map<String, String> 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);
jsonObject.success(map);
}
} catch (Exception e) {
jsonObject.error(e.getMessage());
e.printStackTrace();
}
return jsonObject;
}*/
}

View File

@ -0,0 +1,120 @@
package com.xhpc.payment.domain;
import com.ruoyi.common.core.web.domain.BaseEntity;
import java.math.BigDecimal;
/**
* @description 充值订单 xhpc_recharge_order
* @author
* @date 2021-07-22
*/
public class XhpcRechargeOrder extends BaseEntity {
/**
* 充值订单id
*/
private Long rechargeOrderId;
/**
* 用户id
*/
private Long userId;
/**
* 微信支付订单号
*/
private String prepayId;
/**
* 支付宝订单编号
*/
private String alipayNumber;
/**
* 充值金额
*/
private BigDecimal amount;
/**
* 充值渠道1微信 2支付宝
*/
private Integer type;
/**
* 状态0待支付 1充值成功2充值失败
*/
private Integer status;
/**
* 删除标志0代表存在 2代表删除
*/
private Integer delFlag;
public Long getRechargeOrderId() {
return rechargeOrderId;
}
public void setRechargeOrderId(Long rechargeOrderId) {
this.rechargeOrderId = rechargeOrderId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getPrepayId() {
return prepayId;
}
public void setPrepayId(String prepayId) {
this.prepayId = prepayId;
}
public String getAlipayNumber() {
return alipayNumber;
}
public void setAlipayNumber(String alipayNumber) {
this.alipayNumber = alipayNumber;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
}

View File

@ -0,0 +1,42 @@
package com.xhpc.payment.mapper;
import com.xhpc.payment.domain.XhpcRechargeOrder;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* 充值订单信息 数据层
*
* @author ruoyi
*/
public interface XhpcRechargeOrderMapper {
/**
* 新增 充值订单信息
*
* @param xhpcRechargeOrder 充值订单信息
* @return 结果
*/
public int insert(XhpcRechargeOrder xhpcRechargeOrder);
/**
* 修改充值订单信息
*
* @param xhpcRechargeOrder 充值订单信息
* @return 结果
*/
public int update(XhpcRechargeOrder xhpcRechargeOrder);
/**
* 查询充值订单详情
*
* @param rechargeOrderId 充值订单id
* @return 结果
*/
public Map<String, Object> info(@Param("rechargeOrderId") Long rechargeOrderId);
}

View File

@ -0,0 +1,37 @@
package com.xhpc.payment.service;
import com.xhpc.payment.domain.XhpcRechargeOrder;
import java.util.Map;
/**
* 充值订单信息 服务层
*
* @author ruoyi
*/
public interface IXhpcRechargeOrderService {
/**
* 更新 充值订单
*
* @param xhpcRechargeOrder 充值订单
*/
public int update(XhpcRechargeOrder xhpcRechargeOrder);
/**
* 充值订单详情
*
* @param appUserId 充值订单id
* @return 结果
*/
public Map<String, Object> info(Long appUserId);
/**
* 新增 充值订单
* @param openid
* @param amount
* @return
*/
public XhpcRechargeOrder add(String openid,double amount);
}

View File

@ -0,0 +1,58 @@
package com.xhpc.payment.service.impl;
import com.xhpc.payment.domain.XhpcRechargeOrder;
import com.xhpc.payment.mapper.XhpcRechargeOrderMapper;
import com.xhpc.payment.service.IXhpcRechargeOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* 充值订单信息 服务层
*
* @author ruoyi
*/
@Service
public class XhpcRechargeOrderServiceImpl implements IXhpcRechargeOrderService {
@Autowired
private XhpcRechargeOrderMapper xhpcRechargeOrderMapper;
/**
* 更新 充值订单
*
* @param xhpcRechargeOrder 充值订单
*/
@Override
public int update(XhpcRechargeOrder xhpcRechargeOrder) {
return xhpcRechargeOrderMapper.update(xhpcRechargeOrder);
}
/**
* 充值订单详情
*
* @param appUserId 充值订单id
* @return 结果
*/
@Override
public Map<String, Object> info(Long appUserId) {
return xhpcRechargeOrderMapper.info(appUserId);
}
/**
* 新增 充值订单
* @param openid
* @param amount
* @return
*/
@Override
public XhpcRechargeOrder add(String openid,double amount) {
XhpcRechargeOrder xhpcRechargeOrder = new XhpcRechargeOrder();
xhpcRechargeOrderMapper.insert(xhpcRechargeOrder);
return xhpcRechargeOrder;
}
}

View File

@ -0,0 +1,10 @@
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}
_ __ _ _
(_) / _|(_)| |
_ __ _ _ ___ _ _ _ ______ | |_ _ | | ___
| '__|| | | | / _ \ | | | || ||______|| _|| || | / _ \
| | | |_| || (_) || |_| || | | | | || || __/
|_| \__,_| \___/ \__, ||_| |_| |_||_| \___|
__/ |
|___/

View File

@ -0,0 +1,46 @@
ppsvc:
server: 0.0.0.0
port: 8888
# Tomcat
server:
port: 9802
# Spring
spring:
application:
# 应用名称
name: xhpc-payment
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 118.24.137.203:8848
config:
# 配置中心地址
server-addr: 118.24.137.203:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
##获取微信openid地址
WXGETJSCODE: "https://api.weixin.qq.com/sns/jscode2session?appid=wxb14ef93e9b7901f3&secret=b5c5672141b5930c30a1abee95a2dcbf&js_code="
##阿里云身份证验证地址
VERIFYCARD: "http://idenauthen.market.alicloudapi.com/idenAuthentication"
#阿里云身份证验证地址appcode
APPCODE: "APPCODE e26d9088b58e24af69411d5933cece47"
#小程序appid
APPID: "wxd0a48e00319ef8a7"
#小程序绑定商户id
MCHID: "1514355771"
#商户后台设置的key
KEY: "sichuanxianghuakejiyouxiangongsi"
#微信小程序支付地址
WXPAYUNIFIEDORDER: "https://api.mch.weixin.qq.com/pay/unifiedorder"
#支付回调地址
SERVERDOMAIN: "https://cdz.project2.tingsun.net/wx/paymentCallback"

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/xphc-power-pile"/>
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.xhpc" level="info"/>
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn"/>
<root level="info">
<appender-ref ref="console"/>
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info"/>
<appender-ref ref="file_error"/>
</root>
</configuration>

View File

@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xhpc.payment.mapper.XhpcRechargeOrderMapper">
<resultMap type="com.xhpc.payment.domain.XhpcRechargeOrder" id="XhpcRechargeOrderResult">
<result column="recharge_order_id" property="rechargeOrderId" />
<result column="user_id" property="userId" />
<result column="prepay_id" property="prepayId" />
<result column="alipay_number" property="alipayNumber" />
<result column="amount" property="amount" />
<result column="type" property="type" />
<result column="status" property="status" />
<result column="del_flag" property="delFlag" />
<result column="create_time" property="createTime" />
<result column="create_by" property="createBy" />
<result column="update_time" property="updateTime" />
<result column="update_by" property="updateBy" />
<result column="remark" property="remark" />
</resultMap>
<insert id="insert" parameterType="com.xhpc.user.domain.XhpcAppUser">
INSERT INTO xhpc_recharge_order
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="null != rechargeOrderId and '' != rechargeOrderId">
recharge_order_id,
</if>
<if test="null != userId and '' != userId">
user_id,
</if>
<if test="null != prepayId and '' != prepayId">
prepay_id,
</if>
<if test="null != alipayNumber and '' != alipayNumber">
alipay_number,
</if>
<if test="null != amount and '' != amount">
amount,
</if>
<if test="null != type and '' != type">
type,
</if>
<if test="null != status and '' != status">
status,
</if>
<if test="null != delFlag and '' != delFlag">
del_flag,
</if>
<if test="null != createTime and '' != createTime">
create_time,
</if>
<if test="null != createBy and '' != createBy">
create_by,
</if>
<if test="null != updateTime and '' != updateTime">
update_time,
</if>
<if test="null != updateBy and '' != updateBy">
update_by,
</if>
<if test="null != remark and '' != remark">
remark
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="null != rechargeOrderId and '' != rechargeOrderId">
#{rechargeOrderId},
</if>
<if test="null != userId and '' != userId">
#{userId},
</if>
<if test="null != prepayId and '' != prepayId">
#{prepayId},
</if>
<if test="null != alipayNumber and '' != alipayNumber">
#{alipayNumber},
</if>
<if test="null != amount and '' != amount">
#{amount},
</if>
<if test="null != type and '' != type">
#{type},
</if>
<if test="null != status and '' != status">
#{status},
</if>
<if test="null != delFlag and '' != delFlag">
#{delFlag},
</if>
<if test="null != createTime and '' != createTime">
#{createTime},
</if>
<if test="null != createBy and '' != createBy">
#{createBy},
</if>
<if test="null != updateTime and '' != updateTime">
#{updateTime},
</if>
<if test="null != updateBy and '' != updateBy">
#{updateBy},
</if>
<if test="null != remark and '' != remark">
#{remark}
</if>
</trim>
</insert>
<update id="update" parameterType="com.xhpc.user.domain.XhpcInternetUser">
UPDATE xhpc_recharge_order
<set>
<if test="null != userId and '' != userId">user_id = #{userId},</if>
<if test="null != prepayId and '' != prepayId">prepay_id = #{prepayId},</if>
<if test="null != alipayNumber and '' != alipayNumber">alipay_number = #{alipayNumber},</if>
<if test="null != amount and '' != amount">amount = #{amount},</if>
<if test="null != type and '' != type">type = #{type},</if>
<if test="null != status and '' != status">status = #{status},</if>
<if test="null != delFlag and '' != delFlag">del_flag = #{delFlag},</if>
<if test="null != createTime and '' != createTime">create_time = #{createTime},</if>
<if test="null != createBy and '' != createBy">create_by = #{createBy},</if>
<if test="null != updateTime and '' != updateTime">update_time = #{updateTime},</if>
<if test="null != updateBy and '' != updateBy">update_by = #{updateBy},</if>
<if test="null != remark and '' != remark">remark = #{remark}</if>
</set>
WHERE recharge_order_id = #{rechargeOrderId}
</update>
<select id="info" parameterType="java.lang.Long" resultType="java.util.Map">
select *
from xhpc_recharge_order
WHERE del_flag = 0 and recharge_order_id = #{rechargeOrderId}
</select>
</mapper>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<util:map id="serviceLogics">
<entry key="01" value-ref="RegisterLogic"/>
<entry key="03" value-ref="HBLogic"/>
<entry key="05" value-ref="RateModelValidateLogic"/>
<entry key="09" value-ref="RateModelRequestLogic"/>
</util:map>
</beans>