提交git
This commit is contained in:
81
uling-gateway/package.xml
Normal file
81
uling-gateway/package.xml
Normal file
@ -0,0 +1,81 @@
|
||||
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
|
||||
|
||||
<!--
|
||||
assembly 打包配置更多配置可参考官司方文档:
|
||||
http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html
|
||||
-->
|
||||
|
||||
<id>release</id>
|
||||
|
||||
<!--
|
||||
设置打包格式,可同时设置多种格式,常用格式有:dir、zip、tar、tar.gz
|
||||
dir 格式便于在本地测试打包结果
|
||||
zip 格式便于 windows 系统下解压运行
|
||||
tar、tar.gz 格式便于 linux 系统下解压运行
|
||||
-->
|
||||
<formats>
|
||||
<!-- <format>dir</format> -->
|
||||
<format>zip</format>
|
||||
<!-- <format>tar.gz</format> -->
|
||||
</formats>
|
||||
|
||||
<!-- 打 zip 设置为 true 时,会在 zip 包中生成一个根目录,打 dir 时设置为 false 少层目录 -->
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
|
||||
<fileSets>
|
||||
<!-- src/main/resources 全部 copy 到 config 目录下 -->
|
||||
<fileSet>
|
||||
<directory>${basedir}/src/main/resources</directory>
|
||||
<includes>
|
||||
<include>*.txt</include>
|
||||
<include>*.ini</include>
|
||||
<include>*.xml</include>
|
||||
<include>*.properties</include>
|
||||
</includes>
|
||||
<outputDirectory>config</outputDirectory>
|
||||
</fileSet>
|
||||
|
||||
<fileSet>
|
||||
<directory>${basedir}/src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>*.txt</exclude>
|
||||
<exclude>*.ini</exclude>
|
||||
<exclude>*.xml</exclude>
|
||||
<exclude>*.properties</exclude>
|
||||
</excludes>
|
||||
<outputDirectory>webapp</outputDirectory>
|
||||
</fileSet>
|
||||
|
||||
<fileSet>
|
||||
<directory>${basedir}/target/classes/webapp</directory>
|
||||
<outputDirectory>webapp</outputDirectory>
|
||||
</fileSet>
|
||||
<!-- src/main/webapp 全部 copy 到 webapp 目录下 -->
|
||||
<fileSet>
|
||||
<directory>${basedir}/src/main/webapp</directory>
|
||||
<outputDirectory>webapp</outputDirectory>
|
||||
</fileSet>
|
||||
|
||||
<!-- 项目根下面的脚本文件 copy 到根目录下 -->
|
||||
<fileSet>
|
||||
<directory>${basedir}</directory>
|
||||
<outputDirectory></outputDirectory>
|
||||
<!-- 脚本文件在 linux 下的权限设为 755,无需 chmod 可直接运行 -->
|
||||
<fileMode>755</fileMode>
|
||||
<includes>
|
||||
<include>*.sh</include>
|
||||
<include>*.bat</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
<!-- 依赖的 jar 包 copy 到 lib 目录下 -->
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<outputDirectory>lib</outputDirectory>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
|
||||
</assembly>
|
||||
105
uling-gateway/pom.xml
Normal file
105
uling-gateway/pom.xml
Normal file
@ -0,0 +1,105 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>cc.uling</groupId>
|
||||
<artifactId>uling</artifactId>
|
||||
<version>1.0</version>
|
||||
</parent>
|
||||
<artifactId>uling-gateway</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>gateway</name>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>cc.uling</groupId>
|
||||
<artifactId>uling-system</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cc.uling</groupId>
|
||||
<artifactId>uling-yc-service</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<!-- **/* 打包代码生成器的模板文件 -->
|
||||
<include>**/*.tp</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.*</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
|
||||
<resource>
|
||||
<directory>src/main/webapp</directory>
|
||||
<includes>
|
||||
<include>**/*.*</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<encoding>UTF-8</encoding>
|
||||
<!-- java8 保留参数名编译参数 -->
|
||||
<compilerArgument>-parameters</compilerArgument>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
<!--单模块打包 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<recompressZippedFiles>false</recompressZippedFiles>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
<descriptors>
|
||||
<descriptor>package.xml</descriptor>
|
||||
</descriptors>
|
||||
<outputDirectory>${project.build.directory}/</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
8
uling-gateway/readme
Normal file
8
uling-gateway/readme
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
cd /Users/chenzigui/Workspaces/Projects/AbroadPaymentSystem/java/uling-gateway
|
||||
|
||||
mvn clean package
|
||||
|
||||
#测试服
|
||||
scp /Users/chenzigui/Workspaces/Projects/AbroadPaymentSystem/java/uling-gateway/target/uling-gateway.zip \
|
||||
root@43.134.84.111:/home/
|
||||
@ -0,0 +1,10 @@
|
||||
package cc.uling.pay.gateway;
|
||||
|
||||
import io.jboot.app.JbootApplication;
|
||||
|
||||
public class YCGatewayApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
JbootApplication.run(args);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,80 @@
|
||||
package cc.uling.pay.gateway;
|
||||
|
||||
import cc.uling.common.interceptor.AccessInterceptor;
|
||||
import cc.uling.common.utils.HttpUtils;
|
||||
import cc.uling.pay.gateway.interceptor.GatewayExceptionInterceptor;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.jfinal.config.Constants;
|
||||
import com.jfinal.config.Interceptors;
|
||||
import com.jfinal.handler.Handler;
|
||||
import com.jfinal.kit.PropKit;
|
||||
import com.jfinal.plugin.cron4j.Cron4jPlugin;
|
||||
import io.jboot.Jboot;
|
||||
import io.jboot.aop.jfinal.JfinalHandlers;
|
||||
import io.jboot.aop.jfinal.JfinalPlugins;
|
||||
import io.jboot.core.listener.JbootAppListener;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Date;
|
||||
|
||||
@Slf4j
|
||||
public class YCGatewayListener implements JbootAppListener {
|
||||
|
||||
@Override
|
||||
public void onInit() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginConfig(JfinalPlugins plugins) {
|
||||
plugins.add(new Cron4jPlugin(PropKit.use("task.properties")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConstantConfig(Constants constants) {
|
||||
constants.setDevMode(true);
|
||||
constants.setInjectDependency(true);
|
||||
constants.setInjectSuperClass(true);
|
||||
constants.setMaxPostSize(100 * 1024 * 1024);// 最大支持 100M 文件上传
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onInterceptorConfig(Interceptors interceptors) {
|
||||
interceptors.addGlobalActionInterceptor(new AccessInterceptor());
|
||||
interceptors.addGlobalActionInterceptor(new GatewayExceptionInterceptor());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onHandlerConfig(JfinalHandlers handlers) {
|
||||
JbootAppListener.super.onHandlerConfig(handlers);
|
||||
handlers.add(new Handler() {
|
||||
@Override
|
||||
public void handle(String target, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, boolean[] booleans) {
|
||||
log.info("fetch|{}|request|{}", HttpUtils.getIpAddress(httpServletRequest), target);
|
||||
try {
|
||||
next.handle(target, httpServletRequest, httpServletResponse, booleans);
|
||||
} catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
throw GatewayException.BAD_REQUEST;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
log.info("YCGateway|onStart...{}|{}", Jboot.configValue("jboot.app.mode"), DateUtil.formatDateTime(new Date()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
log.info("YCGateway|onStop...{}", Jboot.configValue("jboot.app.mode"));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package cc.uling.pay.gateway.constants;
|
||||
|
||||
public interface ApiConst {
|
||||
|
||||
String api = "/v1";
|
||||
|
||||
String api_orders = api + "/orders";
|
||||
|
||||
|
||||
String XClientID = "X-Client-ID";
|
||||
|
||||
String XTimestamp = "X-Timestamp";
|
||||
|
||||
|
||||
String XSignature = "X-Signature";
|
||||
|
||||
/**
|
||||
* 失败
|
||||
*/
|
||||
String error = "error";
|
||||
|
||||
/**
|
||||
* 成功
|
||||
*/
|
||||
String success = "success";
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package cc.uling.pay.gateway.controller;
|
||||
|
||||
import cc.uling.common.base.BaseController;
|
||||
import cc.uling.common.manager.AsyncManager;
|
||||
import cc.uling.common.utils.StringUtil;
|
||||
import cc.uling.pay.gateway.GateRes;
|
||||
import cc.uling.pay.gateway.GatewayException;
|
||||
import cc.uling.pay.gateway.constants.ApiConst;
|
||||
import cc.uling.pay.gateway.manager.DataManager;
|
||||
import com.jfinal.aop.Aop;
|
||||
import com.payment.expanded.ApiDemo;
|
||||
import com.web.gen.model.MchInfo;
|
||||
import com.web.gen.model.PayOrder;
|
||||
import io.jboot.Jboot;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class AbController extends BaseController {
|
||||
|
||||
protected static Map<String, PayOrder> mDoingOrders = new ConcurrentHashMap<>();
|
||||
|
||||
public void renderFail(GatewayException exception) {
|
||||
getResponse().setStatus(exception.getStatusCode());
|
||||
renderJson(GateRes.fail(exception.getErrorCode(), exception.getErrorMsg()));
|
||||
}
|
||||
|
||||
public Map<String, String> getParams() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
Enumeration<String> names = getRequest().getParameterNames();
|
||||
while (names.hasMoreElements()) {
|
||||
String name = names.nextElement();
|
||||
map.put(name, getPara(name));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
//查询支付中的订单
|
||||
protected void queryOrder(PayOrder order) {
|
||||
String mode = Jboot.configValue("jboot.app.mode");
|
||||
String platOrderNo = order.getPayOrderId();
|
||||
if (!mDoingOrders.containsKey(platOrderNo)) {
|
||||
mDoingOrders.put(platOrderNo, order);
|
||||
try {
|
||||
AsyncManager.me().execute(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
String server = Aop.get(DataManager.class).getApiServer(mode);
|
||||
MchInfo mchInfo = (MchInfo) getRequest().getAttribute(ApiConst.XClientID);
|
||||
String requestUrl = server + "/api/expanded/transactions";
|
||||
ApiDemo.queryPayOrder(requestUrl, mchInfo.getMchNo(), mchInfo.getSecretKey(), platOrderNo);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
mDoingOrders.remove(platOrderNo);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected <T> T getService(String ifCode, Class<T> clazz) {
|
||||
T service = null;
|
||||
String extName = clazz.getSimpleName().substring(1);
|
||||
String className = clazz.getPackage().getName() + "." + ifCode + "." + StringUtil.capitalizeFirstLetter(ifCode) + extName; // 类的全限定名
|
||||
try {
|
||||
Class<? extends T> targetClazz = (Class<? extends T>) Class.forName(className);
|
||||
service = Aop.get(targetClazz);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return service;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,106 @@
|
||||
package cc.uling.pay.gateway.controller;
|
||||
|
||||
import cc.uling.common.constant.ResponseCode;
|
||||
import cc.uling.common.enums.PayOrderStatus;
|
||||
import cc.uling.common.utils.HttpUtils;
|
||||
import cc.uling.common.utils.StringUtil;
|
||||
import cc.uling.pay.gateway.*;
|
||||
import cc.uling.pay.gateway.constants.ApiConst;
|
||||
import cc.uling.pay.gateway.interceptor.SHA256SignInterceptor;
|
||||
import cc.uling.pay.gateway.manager.DataManager;
|
||||
import cc.uling.pay.gateway.protocol.Converter;
|
||||
import cc.uling.service.BizPayOrderDetailService;
|
||||
import cc.uling.web.config.ProjectConfig;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.jfinal.aop.Aop;
|
||||
import com.jfinal.aop.Before;
|
||||
import com.jfinal.core.paragetter.Para;
|
||||
import com.payment.expanded.ApiDemo;
|
||||
import com.web.gen.model.MchInfo;
|
||||
import com.web.gen.model.PayOrder;
|
||||
import com.web.gen.service.PayOrderService;
|
||||
import io.jboot.Jboot;
|
||||
import io.jboot.db.model.Columns;
|
||||
import io.jboot.web.controller.annotation.RequestMapping;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Before(SHA256SignInterceptor.class)
|
||||
@RequestMapping(value = ApiConst.api_orders)
|
||||
public class IndexController extends AbController {
|
||||
|
||||
|
||||
public void index() {
|
||||
String platOrderId = getPara();
|
||||
if (StringUtil.isEmpty(platOrderId)) {
|
||||
throw GatewayException.MissingParam("transaction_id");
|
||||
}
|
||||
|
||||
String dbName = ProjectConfig.isSandbox() ? ProjectConfig.SANDBOX : ProjectConfig.PROD;
|
||||
MchInfo mchInfo = (MchInfo) getRequest().getAttribute(ApiConst.XClientID);
|
||||
|
||||
log.info("查询{}订单[{}]", dbName, platOrderId);
|
||||
PayOrder payOrder = Aop.get(PayOrderService.class).findByColumns(dbName, Columns.create("pay_order_id", platOrderId).eq("mch_no", mchInfo.getMchNo()));
|
||||
|
||||
if (null == payOrder) {
|
||||
throw GatewayException.NOT_FOUND;
|
||||
}
|
||||
|
||||
if (ObjectUtil.equals(payOrder.getStatus(), PayOrderStatus.PAYING)) {
|
||||
queryOrder(payOrder);
|
||||
}
|
||||
GateRes res = Converter.getOrderDetails(payOrder);
|
||||
renderJson(res);
|
||||
}
|
||||
|
||||
|
||||
public void checkout(@Valid @Para("") CreatePayOrderRQ bizRQ) {
|
||||
if (null == bizRQ) {
|
||||
throw GatewayException.BAD_REQUEST;
|
||||
}
|
||||
bizRQ.check();
|
||||
if (StringUtil.isEmpty(bizRQ.getClient_ip())) {
|
||||
bizRQ.setClient_ip(HttpUtils.getIpAddress(getRequest()));
|
||||
}
|
||||
String dbName = ProjectConfig.isSandbox() ? ProjectConfig.SANDBOX : ProjectConfig.PROD;
|
||||
MchInfo mchInfo = (MchInfo) getRequest().getAttribute(ApiConst.XClientID);
|
||||
|
||||
PayOrder payOrder = Aop.get(PayOrderService.class).findByColumns(dbName, Columns.create("mch_order_no", bizRQ.getOrder_id()).eq("mch_no", mchInfo.getMchNo()));
|
||||
|
||||
if (null != payOrder) {
|
||||
throw new GatewayException(ResponseCode.UNPROCESSABLE, ErrorCode.UNPROCESSABLE, "request.fail.exists.order_id", bizRQ.getOrder_id());
|
||||
}
|
||||
|
||||
|
||||
Aop.get(BizPayOrderDetailService.class).saveOrUpdate(getRequest(), bizRQ, mchInfo);
|
||||
String mode = Jboot.configValue("jboot.app.mode");
|
||||
try {
|
||||
Map<String, Object> dataMap = bizRQ.toMap(mchInfo, getRequest().getHeader(ApiConst.XClientID));
|
||||
String server = Aop.get(DataManager.class).getApiServer(mode);
|
||||
String requestUrl = server + "/api/expanded/transactions/create";
|
||||
log.warn("requestUrl:{}\n", requestUrl);
|
||||
String json = ApiDemo.doRequest(requestUrl, mchInfo.getMchNo(), mchInfo.getSecretKey(), dataMap);
|
||||
|
||||
log.warn("requestUrl:{}|response:" + json, requestUrl);
|
||||
if (StringUtil.isNotEmpty(json)) {
|
||||
OrderInfoRes res = Converter.getOrderDetails(json, bizRQ);
|
||||
renderJson(res);
|
||||
} else {
|
||||
throw GatewayException.SYSTEM_ERROR;
|
||||
}
|
||||
} catch (GatewayException e) {
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
throw GatewayException.SYSTEM_ERROR;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw GatewayException.SYSTEM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,214 @@
|
||||
package cc.uling.pay.gateway.demo;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
public class ApiClient {
|
||||
|
||||
// private static final String APP_ID = "123456"; // Application ID
|
||||
// private static final String MERCHANT_KEY = "MDEyMzQ1Njc4OQ=="; // Merchant secret key
|
||||
// private static final String BASE_URL = "https://api.wireupay.com"; // API base URL
|
||||
|
||||
private static final String APP_ID = "M9ILKMMYR2YNQXJMP2"; // Application ID
|
||||
private static final String MERCHANT_KEY = "HCAIwL4LPwRiI7z81Lig66IF43="; // Merchant secret key
|
||||
private static final String BASE_URL = "https://sandbox.wireupay.com"; // API base URL
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
// query("123456");
|
||||
create(getBizParams());
|
||||
}
|
||||
|
||||
private static Map<String, String> getBizParams() {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("amount", "100.4");
|
||||
params.put("currency", "USD");
|
||||
params.put("payment_method", "checkout");
|
||||
params.put("order_id", "23435435");
|
||||
// params.put("client_ip", "11.11.11.11");
|
||||
params.put("callback_url", "https://api.deepnudes.com/callback");
|
||||
params.put("product_name", "coins");
|
||||
return params;
|
||||
}
|
||||
|
||||
public static void create(Map<String, String> params) {
|
||||
try {
|
||||
String requestUrl = BASE_URL + "/v1/orders/checkout";
|
||||
String response = doRequest(requestUrl, APP_ID, MERCHANT_KEY, "POST", params);
|
||||
System.out.println(response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void query(String orderNo) {
|
||||
try {
|
||||
String requestUrl = BASE_URL + "/v1/orders/" + orderNo;
|
||||
String response = doRequest(requestUrl, APP_ID, MERCHANT_KEY, "GET", null);
|
||||
System.out.println(response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String doRequest(String requestUrl, String clientId, String mchKey, String httpMethod, Map<String, String> params) {
|
||||
String response = null;
|
||||
try {
|
||||
String timestamp = System.currentTimeMillis() + "";
|
||||
String signature = generateApiSignature(mchKey,
|
||||
httpMethod,
|
||||
timestamp,
|
||||
clientId, params);
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("X-Client-ID", clientId);
|
||||
headers.put("X-Timestamp", timestamp);
|
||||
headers.put("X-Signature", signature);
|
||||
response = sendRequest(httpMethod, requestUrl, params, headers);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
public static String sendRequest(String method, String url,
|
||||
Map<String, String> params,
|
||||
Map<String, String> headers) throws IOException {
|
||||
String response = null;
|
||||
HttpURLConnection connection = null;
|
||||
|
||||
try {
|
||||
URL requestUrl = new URL(url);
|
||||
connection = (HttpURLConnection) requestUrl.openConnection();
|
||||
connection.setRequestMethod(method);
|
||||
connection.setConnectTimeout(10000);
|
||||
connection.setReadTimeout(10000);
|
||||
if (headers != null) {
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
connection.setRequestProperty(header.getKey(), header.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (!"GET".equalsIgnoreCase(method) && params != null && !params.isEmpty()) {
|
||||
connection.setDoOutput(true);
|
||||
try (OutputStream os = connection.getOutputStream()) {
|
||||
byte[] postData = buildFormData(params).getBytes(StandardCharsets.UTF_8);
|
||||
os.write(postData);
|
||||
os.flush();
|
||||
}
|
||||
}
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
try {
|
||||
InputStream es = null;
|
||||
try {
|
||||
es = connection.getInputStream();
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
|
||||
if (es == null) {
|
||||
try {
|
||||
es = connection.getErrorStream();
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
if (es != null) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(es, StandardCharsets.UTF_8));
|
||||
response = reader.lines().collect(Collectors.joining("\n"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
private static String buildFormData(Map<String, String> params) throws UnsupportedEncodingException {
|
||||
return params.entrySet().stream()
|
||||
.map(e -> {
|
||||
try {
|
||||
return URLEncoder.encode(e.getKey(), "UTF-8") + "=" +
|
||||
URLEncoder.encode(e.getValue(), "UTF-8");
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
})
|
||||
.collect(Collectors.joining("&"));
|
||||
}
|
||||
|
||||
|
||||
public static String generateApiSignature(
|
||||
String apiSecret,
|
||||
String httpMethod,
|
||||
String timestamp,
|
||||
String merchantId, Map<String, String> params) throws SecurityException {
|
||||
try {
|
||||
// 1. Construct the base string
|
||||
String sortedParams = sortParams(params);
|
||||
|
||||
String baseString = String.format("%s\n%s\n%s\n%s",
|
||||
httpMethod,
|
||||
timestamp,
|
||||
merchantId,
|
||||
sortedParams);
|
||||
System.out.println("baseString="+baseString);
|
||||
// 2. Calculate HMAC-SHA256 1
|
||||
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
|
||||
SecretKeySpec secretKey = new SecretKeySpec(
|
||||
apiSecret.getBytes(StandardCharsets.UTF_8),
|
||||
"HmacSHA256");
|
||||
sha256_HMAC.init(secretKey);
|
||||
byte[] hashBytes = sha256_HMAC.doFinal(baseString.getBytes(StandardCharsets.UTF_8));
|
||||
// 3. Return hexadecimal result
|
||||
return bytesToHex(hashBytes);
|
||||
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String sortParams(Map<String, String> params) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (null != params && !params.isEmpty()) {
|
||||
List<String> keys = new ArrayList<>(params.keySet());
|
||||
Collections.sort(keys);
|
||||
for (String key : keys) {
|
||||
sb.append(key).append("=").append(params.get(key)).append("&");
|
||||
}
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String bytesToHex(byte[] bytes) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
result.append(String.format("%02x", b));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,267 @@
|
||||
package cc.uling.pay.gateway.demo;
|
||||
|
||||
import cc.uling.pay.gateway.ApiSignatureGenerator;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
public class ApiClient0 {
|
||||
|
||||
private static final String APP_ID = "123456"; // Application ID
|
||||
private static final String MERCHANT_KEY = "MDEyMzQ1Njc4OQ==";
|
||||
private static final String BASE_URL = "http://localhost:8094"; // API base URL
|
||||
|
||||
// private static final String APP_ID = "MLAUQBHFO9GIVPNVR2"; // Application ID
|
||||
// private static final String MERCHANT_KEY = "jAVc3/bO4enU5/G5+VtSJg=="; // Merchant secret key
|
||||
// private static final String BASE_URL = "https://sandbox.wireupay.com"; // API base URL
|
||||
|
||||
public static void main(String[] args) {
|
||||
// query("123456");
|
||||
create(getBizParams());
|
||||
|
||||
// callback();
|
||||
}
|
||||
|
||||
private static Map<String, String> getBizParams() {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("amount", "1.00");
|
||||
params.put("currency", "USD");
|
||||
params.put("payment_method", "checkout");
|
||||
params.put("order_id", "ts"+System.currentTimeMillis());
|
||||
params.put("client_ip", "127.0.0.1");
|
||||
params.put("callback_url", "https://same.website.com/pay/notify/mch");
|
||||
params.put("return_url", "https://same.website.com/pay/notify/mch");
|
||||
params.put("product_name", "GoodGame");
|
||||
return params;
|
||||
}
|
||||
|
||||
public static void create(Map<String, String> params) {
|
||||
try {
|
||||
String requestUrl = BASE_URL + "/v1/orders/checkout";
|
||||
String response = doRequest(requestUrl, APP_ID, MERCHANT_KEY, "POST", params);
|
||||
System.out.println(response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void query(String orderNo) {
|
||||
try {
|
||||
String requestUrl = BASE_URL + "/v1/orders/" + orderNo;
|
||||
String response = doRequest(requestUrl, APP_ID, MERCHANT_KEY, "GET", null);
|
||||
System.out.println(response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String doRequest(String requestUrl, String clientId, String mchKey, String httpMethod, Map<String, String> params) {
|
||||
String response = null;
|
||||
try {
|
||||
String timestamp = System.currentTimeMillis() + "";
|
||||
// String timestamp = "654321";
|
||||
String signature = generateApiSignature(mchKey,
|
||||
httpMethod,
|
||||
timestamp,
|
||||
clientId, params);
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("X-Client-ID", clientId);
|
||||
headers.put("X-Timestamp", timestamp);
|
||||
headers.put("X-Signature", signature);
|
||||
System.out.println("signature:" + signature);
|
||||
response = sendRequest(httpMethod, requestUrl, params, headers);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void callback(){
|
||||
String requestUrl = "http://localhost:8001";
|
||||
// String mchKey = "HCVGWclr9qZc315pO1p2sAszJ3=";
|
||||
String mchKey = "MDEyMzQ1Njc4OQ==";
|
||||
|
||||
String timestamp = System.currentTimeMillis() + "";
|
||||
|
||||
String requestBody = "{\"data\":{\"transaction_id\":\"W17465264771601854\",\"amount\":\"130.00\",\"payment_status\":\"captured\",\"currency\":\"USD\",\"order_id\":\"01JTJHE6E7SSZF36DQ8J7G0N58\"},\"event\":\"PAYMENT.CAPTURE.COMPLETED\"}";
|
||||
|
||||
String baseString = timestamp + "&" + requestBody;
|
||||
|
||||
String signature = ApiSignatureGenerator.generateApiSignature(mchKey, baseString);
|
||||
|
||||
// System.out.println("signature:" + signature);
|
||||
|
||||
HttpRequest post = HttpUtil.createPost(requestUrl)
|
||||
.header("X-Timestamp", timestamp)
|
||||
.header("X-Signature", signature)
|
||||
.body(requestBody);
|
||||
HttpResponse response = post.execute();
|
||||
|
||||
String res = response.body();
|
||||
System.out.println("response:\n" +res);
|
||||
|
||||
|
||||
|
||||
// if (StringUtil.isNotBlank(res)) {
|
||||
// String aaa = ApiSignatureGenerator.generateApiSignature(res, mchKey);
|
||||
// System.out.println(aaa);
|
||||
// System.out.println(signature);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String sendRequest(String method, String url,
|
||||
Map<String, String> params,
|
||||
Map<String, String> headers) throws IOException {
|
||||
String response = null;
|
||||
HttpURLConnection connection = null;
|
||||
|
||||
try {
|
||||
URL requestUrl = new URL(url);
|
||||
connection = (HttpURLConnection) requestUrl.openConnection();
|
||||
connection.setRequestMethod(method);
|
||||
|
||||
// connection.setRequestMethod("POST");
|
||||
// connection.setRequestProperty("Content-Type", "application/json");
|
||||
// connection.setRequestProperty("Accept", "application/json");
|
||||
|
||||
connection.setConnectTimeout(10000);
|
||||
connection.setReadTimeout(10000);
|
||||
if (headers != null) {
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
connection.setRequestProperty(header.getKey(), header.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (!"GET".equalsIgnoreCase(method) && params != null && !params.isEmpty()) {
|
||||
connection.setDoOutput(true);
|
||||
try (OutputStream os = connection.getOutputStream()) {
|
||||
byte[] postData = buildFormData(params).getBytes(StandardCharsets.UTF_8);
|
||||
os.write(postData);
|
||||
os.flush();
|
||||
// JSON
|
||||
// byte[] input = JSON.toJSONString(params).getBytes(StandardCharsets.UTF_8);
|
||||
// os.write(input, 0, input.length);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
try {
|
||||
InputStream es = null;
|
||||
try {
|
||||
es = connection.getInputStream();
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
|
||||
if (es == null) {
|
||||
try {
|
||||
es = connection.getErrorStream();
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
if (es != null) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(es, StandardCharsets.UTF_8));
|
||||
response = reader.lines().collect(Collectors.joining("\n"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
private static String buildFormData(Map<String, String> params) throws UnsupportedEncodingException {
|
||||
return params.entrySet().stream()
|
||||
.map(e -> {
|
||||
try {
|
||||
return URLEncoder.encode(e.getKey(), "UTF-8") + "=" +
|
||||
URLEncoder.encode(e.getValue(), "UTF-8");
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
})
|
||||
.collect(Collectors.joining("&"));
|
||||
}
|
||||
|
||||
|
||||
public static String generateApiSignature(
|
||||
String apiSecret,
|
||||
String httpMethod,
|
||||
String timestamp,
|
||||
String merchantId, Map<String, String> params) throws SecurityException {
|
||||
try {
|
||||
// 1. Construct the base string
|
||||
String sortedParams = sortParams(params);
|
||||
|
||||
String baseString = String.format("%s\n%s\n%s\n%s",
|
||||
httpMethod,
|
||||
timestamp,
|
||||
merchantId,
|
||||
sortedParams);
|
||||
|
||||
System.out.println("baseString:\n"+baseString);
|
||||
// 2. Calculate HMAC-SHA256
|
||||
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
|
||||
SecretKeySpec secretKey = new SecretKeySpec(
|
||||
apiSecret.getBytes(StandardCharsets.UTF_8),
|
||||
"HmacSHA256");
|
||||
sha256_HMAC.init(secretKey);
|
||||
byte[] hashBytes = sha256_HMAC.doFinal(baseString.getBytes(StandardCharsets.UTF_8));
|
||||
// 3. Return hexadecimal result
|
||||
return bytesToHex(hashBytes);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String sortParams(Map<String, String> params) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (null != params && !params.isEmpty()) {
|
||||
List<String> keys = new ArrayList<>(params.keySet());
|
||||
Collections.sort(keys);
|
||||
for (String key : keys) {
|
||||
sb.append(key).append("=").append(params.get(key)).append("&");
|
||||
}
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String bytesToHex(byte[] bytes) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
result.append(String.format("%02x", b));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package cc.uling.pay.gateway.interceptor;
|
||||
|
||||
import cc.uling.common.utils.DateUtils;
|
||||
import cc.uling.common.utils.HttpUtils;
|
||||
import cc.uling.common.utils.ThreadContext;
|
||||
import cc.uling.pay.gateway.GatewayException;
|
||||
import cc.uling.pay.gateway.controller.AbController;
|
||||
import com.jfinal.aop.Interceptor;
|
||||
import com.jfinal.aop.Invocation;
|
||||
import io.jboot.components.valid.ValidException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.ValidationException;
|
||||
|
||||
@Slf4j
|
||||
public class GatewayExceptionInterceptor implements Interceptor {
|
||||
|
||||
@Override
|
||||
public void intercept(Invocation inv) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
ThreadContext.set("lang", "en");
|
||||
AbController controller = (AbController) inv.getController();
|
||||
try {
|
||||
print(inv.getActionKey(), controller.getRequest());
|
||||
inv.invoke();
|
||||
} catch (ValidException | ValidationException e) {
|
||||
e.printStackTrace();
|
||||
String msg = e.getMessage();
|
||||
// checkValidException(inv, msg);
|
||||
} catch (GatewayException e) {
|
||||
log.info("{}业务执行错误!{}", inv.getMethodName(), e.getMessage());
|
||||
controller.renderFail(e);
|
||||
} catch (RuntimeException e) {
|
||||
String msg = e.getMessage();
|
||||
log.info("Raw\n|{}|\n", inv.getController().getRawData());
|
||||
log.info("{}/{}()运行错误!{}", inv.getController().getClass().getCanonicalName(), inv.getMethodName(), msg);
|
||||
e.printStackTrace();
|
||||
controller.renderFail(GatewayException.SYSTEM_ERROR);
|
||||
} catch (Exception e) {
|
||||
log.info("{}/{}()执行错误!{}", inv.getController().getClass().getCanonicalName(), inv.getMethodName(), e.getMessage());
|
||||
e.printStackTrace();
|
||||
controller.renderFail(GatewayException.SYSTEM_ERROR);
|
||||
} finally {
|
||||
long endTime = System.currentTimeMillis();
|
||||
log.info("{}|{}|cost|{}", inv.getController().getClass().getCanonicalName(), inv.getMethodName(), DateUtils.formatTime(endTime - startTime));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void print(String tag, HttpServletRequest request) {
|
||||
log.warn("{}\n{}", tag, null != request ? HttpUtils.getRequestInfo(request) : "");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
package cc.uling.pay.gateway.interceptor;
|
||||
|
||||
import cc.uling.common.constant.ResponseCode;
|
||||
import cc.uling.pay.gateway.ApiSignatureGenerator;
|
||||
import cc.uling.pay.gateway.ErrorCode;
|
||||
import cc.uling.pay.gateway.GatewayException;
|
||||
import cc.uling.pay.gateway.constants.ApiConst;
|
||||
import cc.uling.pay.gateway.controller.AbController;
|
||||
import cc.uling.pay.gateway.manager.DataManager;
|
||||
import com.jfinal.aop.Aop;
|
||||
import com.jfinal.aop.Interceptor;
|
||||
import com.jfinal.aop.Invocation;
|
||||
import com.web.gen.model.MchInfo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class SHA256SignInterceptor implements Interceptor {
|
||||
@Override
|
||||
public void intercept(Invocation invocation) {
|
||||
AbController controller = (AbController) invocation.getController();
|
||||
HttpServletRequest request = controller.getRequest();
|
||||
String clientId = request.getHeader(ApiConst.XClientID);
|
||||
String timestamp = request.getHeader(ApiConst.XTimestamp);
|
||||
String signature = request.getHeader(ApiConst.XSignature);
|
||||
if (StringUtils.isEmpty(clientId)) {
|
||||
throw GatewayException.MissingParam(ApiConst.XClientID);
|
||||
}
|
||||
if (StringUtils.isEmpty(timestamp)) {
|
||||
throw GatewayException.MissingParam(ApiConst.XTimestamp);
|
||||
}
|
||||
if (StringUtils.isEmpty(signature)) {
|
||||
throw GatewayException.MissingParam(ApiConst.XSignature);
|
||||
}
|
||||
String method = request.getMethod().toUpperCase();
|
||||
Map<String, String> params = controller.getParams();
|
||||
MchInfo mchInfo = Aop.get(DataManager.class).findMchInfoByAppId(clientId);
|
||||
String sysSign = ApiSignatureGenerator.generateApiSignature(mchInfo.getSecretKey(), method, timestamp, clientId, params);
|
||||
|
||||
if (!signature.equals(sysSign)) {
|
||||
String body = controller.getRawData();
|
||||
if (params.isEmpty() && StringUtils.isNotEmpty(body)) {
|
||||
log.warn("body|" + body);
|
||||
throw new GatewayException(ResponseCode.UNPROCESSABLE, ErrorCode.SIGN_ERROR, "request.params.post.error");
|
||||
}
|
||||
|
||||
log.warn("error|" + sysSign + "!=" + signature);
|
||||
throw GatewayException.SIGN_ERROR;
|
||||
}
|
||||
|
||||
request.setAttribute(ApiConst.XClientID, mchInfo);
|
||||
invocation.invoke();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package cc.uling.pay.gateway.manager;
|
||||
|
||||
import cc.uling.common.utils.StringUtil;
|
||||
import cc.uling.pay.gateway.GatewayException;
|
||||
import com.jfinal.aop.Aop;
|
||||
import com.web.gen.model.MchInfo;
|
||||
import com.web.gen.service.MchInfoService;
|
||||
import com.web.gen.service.SysConfigService;
|
||||
import io.jboot.aop.annotation.Bean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Bean
|
||||
public class DataManager {
|
||||
|
||||
public MchInfo findMchInfoByAppId(String appId) {
|
||||
MchInfo mchInfo = Aop.get(MchInfoService.class).findByAppId(appId);
|
||||
if (mchInfo == null) {
|
||||
throw GatewayException.UNAUTHORIZED;
|
||||
}
|
||||
return mchInfo;
|
||||
}
|
||||
|
||||
|
||||
public String getApiServer(String mode) {
|
||||
String host = Aop.get(SysConfigService.class).getPayGatewayHost();
|
||||
if (StringUtil.isBlank(host)) {
|
||||
log.warn("| has not set " + mode + " pay gateway host!");
|
||||
throw GatewayException.SYSTEM_ERROR;
|
||||
}
|
||||
return host;
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
package cc.uling.pay.gateway.protocol;
|
||||
|
||||
import cc.uling.common.constant.ResponseCode;
|
||||
import cc.uling.common.enums.YesOrNo;
|
||||
import cc.uling.common.utils.StringUtil;
|
||||
import cc.uling.pay.gateway.*;
|
||||
import cc.uling.pay.gateway.constants.ApiConst;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.web.gen.model.PayOrder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class Converter {
|
||||
|
||||
|
||||
public static OrderInfoRes getOrderDetails(String json, CreatePayOrderRQ bizRQ) {
|
||||
OrderInfoRes res = new OrderInfoRes();
|
||||
try {
|
||||
JSONObject jsonObject = JSON.parseObject(json);
|
||||
int code = jsonObject.getIntValue("code");
|
||||
if (code == ResponseCode.SUCCESS) {
|
||||
res.setStatus(ApiConst.success);
|
||||
JSONObject dataObject = jsonObject.getJSONObject("data");
|
||||
if (dataObject != null) {
|
||||
res.setOrder_id(dataObject.getString("merOrderNo"));
|
||||
res.setTransaction_id(dataObject.getString("payOrderId"));
|
||||
res.setAmount(bizRQ.getAmount());
|
||||
res.setCurrency(bizRQ.getCurrency());
|
||||
res.setPayment_details(dataObject.getString("message"));
|
||||
res.setPayment_status(Convert.getPaymentStatus(dataObject.getIntValue("state")));
|
||||
|
||||
Map<String, String> actionMap = new HashMap<String, String>();
|
||||
if (dataObject.getIntValue("payType") == YesOrNo.YES && !StringUtil.isEmpty(dataObject.getString("payUrl"))) {
|
||||
actionMap.put("type", "redirect");
|
||||
actionMap.put("url", dataObject.getString("payUrl"));
|
||||
} else {
|
||||
actionMap.put("type", "none");
|
||||
}
|
||||
res.setNext_action(actionMap);
|
||||
}
|
||||
} else {
|
||||
if (code == ResponseCode.ERROR) {
|
||||
code = ResponseCode.UNPROCESSABLE;
|
||||
}
|
||||
GatewayException exception = new GatewayException(code, getErrorCode(code));
|
||||
exception.setErrorMsg(jsonObject.getString("msg"));
|
||||
throw exception;
|
||||
}
|
||||
} catch (GatewayException e) {
|
||||
log.info("here is the GatewayException|" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.info("here is the exception|" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
throw GatewayException.SYSTEM_ERROR;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static OrderInfoRes getOrderDetails(PayOrder order) {
|
||||
OrderInfoRes res = new OrderInfoRes();
|
||||
try {
|
||||
res.setOrder_id(order.getMchOrderNo());
|
||||
res.setTransaction_id(order.getPayOrderId());
|
||||
res.setCurrency(order.getCurrency());
|
||||
res.setAmount(new BigDecimal(order.getAmount()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
|
||||
res.setRefunds(null);
|
||||
res.setRefunded_amount(null);
|
||||
res.setPayment_status(Convert.getPaymentStatus(order.getStatus()));
|
||||
res.setPayment_details(order.getErrMsg());
|
||||
} catch (GatewayException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw GatewayException.SYSTEM_ERROR;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
public static String getErrorCode(int code) {
|
||||
if (code == ResponseCode.BAD_REQUEST) {
|
||||
return ErrorCode.INVALID_REQUEST;
|
||||
} else if (code == ResponseCode.SYSTEM_ERROR) {
|
||||
return ErrorCode.SYSTEM_ERROR;
|
||||
} else if (code == ResponseCode.UNAUTHORIZED) {
|
||||
return ErrorCode.AUTHENTICATION_FAILURE;
|
||||
} else if (code == ResponseCode.FORBIDDEN) {
|
||||
return ErrorCode.NOT_AUTHORIZED;
|
||||
} else if (code == ResponseCode.NOT_FOUND) {
|
||||
return ErrorCode.RESOURCE_NOT_FOUND;
|
||||
} else if (code == ResponseCode.ERROR) {
|
||||
return ErrorCode.UNPROCESSABLE;
|
||||
}
|
||||
return ApiConst.error;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package cc.uling.pay.gateway.timer;
|
||||
|
||||
public class LogTimer implements Runnable{
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
package cc.uling.pay.gateway.utils;
|
||||
|
||||
public class ApiHelper {
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package cc.uling.pay.gateway.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SignUtil {
|
||||
|
||||
public static String getBaseString(String method, String timestamp, String clientId) {
|
||||
return MessageFormat.format("{0}\n{1}\n{2}", method, timestamp, clientId);
|
||||
}
|
||||
|
||||
public static String sortParams(Map<String, String> params) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (null != params) {
|
||||
List<String> keys = new ArrayList<>(params.keySet());
|
||||
Collections.sort(keys);
|
||||
for (String key : keys) {
|
||||
sb.append(key).append("=").append(params.get(key)).append("&");
|
||||
}
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
1
uling-gateway/src/main/resources/banner.txt
Normal file
1
uling-gateway/src/main/resources/banner.txt
Normal file
@ -0,0 +1 @@
|
||||
YCGateway
|
||||
14
uling-gateway/src/main/resources/i18n_en_US.properties
Normal file
14
uling-gateway/src/main/resources/i18n_en_US.properties
Normal file
@ -0,0 +1,14 @@
|
||||
request.bad=Request is not well-formed, syntactically incorrect, or violates schema.
|
||||
request.forbidden=Authorization failed due to insufficient permissions.
|
||||
request.unauthorized=Client authentication failed.
|
||||
request.failed=failed
|
||||
request.succeeded=succeeded
|
||||
request.res.not_exist=The specified resource does not exist.
|
||||
request.system.error=Internal server error has occurred.
|
||||
request.sign.error=Signature verification failed.
|
||||
#
|
||||
request.param.missing={0} is missing.
|
||||
request.param.invalid={0} is invalid.
|
||||
#
|
||||
request.fail.exists.order_id=Order [{0}] already exists.
|
||||
request.params.post.error=Please pass parameters as a form instead of a body
|
||||
13
uling-gateway/src/main/resources/jboot-dev.properties
Normal file
13
uling-gateway/src/main/resources/jboot-dev.properties
Normal file
@ -0,0 +1,13 @@
|
||||
# Product DB
|
||||
jboot.datasource.prod.type=mysql
|
||||
jboot.datasource.prod.url=jdbc:mysql://61.171.32.114:3306/yc_system_db?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
|
||||
jboot.datasource.prod.user=root
|
||||
jboot.datasource.prod.password=MyNewPass4!
|
||||
|
||||
|
||||
# SandBox
|
||||
jboot.datasource.sandbox.type=mysql
|
||||
jboot.datasource.sandbox.url=jdbc:mysql://localhost:3306/yc_system_sandbox_db?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
|
||||
jboot.datasource.sandbox.user=root
|
||||
jboot.datasource.sandbox.password=123456
|
||||
jboot.datasource.sandbox.table=yc_pay_order
|
||||
13
uling-gateway/src/main/resources/jboot-test.properties
Normal file
13
uling-gateway/src/main/resources/jboot-test.properties
Normal file
@ -0,0 +1,13 @@
|
||||
# Product DB
|
||||
jboot.datasource.prod.type=mysql
|
||||
jboot.datasource.prod.url=jdbc:mysql://61.171.32.114:3306/yc_system_db?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
|
||||
jboot.datasource.prod.user=root
|
||||
jboot.datasource.prod.password=MyNewPass4!
|
||||
|
||||
|
||||
# SandBox
|
||||
jboot.datasource.sandbox.type=mysql
|
||||
jboot.datasource.sandbox.url=jdbc:mysql://localhost:3306/yc_system_sandbox_db?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
|
||||
jboot.datasource.sandbox.user=root
|
||||
jboot.datasource.sandbox.password=123456
|
||||
jboot.datasource.sandbox.table=yc_pay_order
|
||||
9
uling-gateway/src/main/resources/jboot.properties
Normal file
9
uling-gateway/src/main/resources/jboot.properties
Normal file
@ -0,0 +1,9 @@
|
||||
#jboot dev,test,product
|
||||
jboot.app.mode=dev
|
||||
jboot.app.name=YCGateway
|
||||
jboot.app.version=1.0.0
|
||||
#
|
||||
jboot.model.idCacheEnable = false
|
||||
#undertow
|
||||
undertow.port=8094
|
||||
undertow.host=0.0.0.0
|
||||
183
uling-gateway/src/main/resources/logback.xml
Normal file
183
uling-gateway/src/main/resources/logback.xml
Normal file
@ -0,0 +1,183 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<!-- 级别从高到低 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL -->
|
||||
<!-- 日志输出规则 根据当前ROOT 级别,日志输出时,级别高于root默认的级别时 会输出 -->
|
||||
<!-- 以下 每个配置的 filter 是过滤掉输出文件里面,会出现高级别文件,依然出现低级别的日志信息,通过filter 过滤只记录本级别的日志 -->
|
||||
<!-- scan 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 -->
|
||||
<!-- scanPeriod 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
|
||||
<!-- debug 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
|
||||
<configuration scan="true" scanPeriod="60 seconds"
|
||||
debug="false">
|
||||
|
||||
<!-- 动态日志级别 -->
|
||||
<jmxConfigurator />
|
||||
|
||||
<!-- 定义日志文件 输出位置 -->
|
||||
<property name="log_dir" value="logs" />
|
||||
|
||||
<!-- 日志最大的历史 30天 -->
|
||||
<property name="maxHistory" value="30" />
|
||||
|
||||
<!-- ConsoleAppender 控制台输出日志 -->
|
||||
<appender name="console"
|
||||
class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<!-- 设置日志输出格式 -->
|
||||
<pattern>
|
||||
%d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%logger{25}:%L] - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- ERROR级别日志 -->
|
||||
<!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 RollingFileAppender -->
|
||||
<appender name="ERROR"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 过滤器,只记录WARN级别的日志 -->
|
||||
<!-- 果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 设置过滤级别 -->
|
||||
<level>ERROR</level>
|
||||
<!-- 用于配置符合过滤条件的操作 -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 用于配置不符合过滤条件的操作 -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<!-- 最常用的滚动策略,它根据时间来制定滚动策略.既负责滚动也负责出发滚动 -->
|
||||
<rollingPolicy
|
||||
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!--日志输出位置 可相对、和绝对路径 -->
|
||||
<fileNamePattern>
|
||||
${log_dir}/error/%d{yyyy-MM-dd}/logs.log
|
||||
</fileNamePattern>
|
||||
<!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件假设设置每个月滚动,且<maxHistory>是6, 则只保存最近6个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除 -->
|
||||
<maxHistory>${maxHistory}</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>
|
||||
<!-- 设置日志输出格式 -->
|
||||
%d{yyyy-MM-dd HH:mm:ss} [%-5level] %logger - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
|
||||
<!-- WARN级别日志 appender -->
|
||||
<appender name="WARN"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 过滤器,只记录WARN级别的日志 -->
|
||||
<!-- 果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 设置过滤级别 -->
|
||||
<level>WARN</level>
|
||||
<!-- 用于配置符合过滤条件的操作 -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 用于配置不符合过滤条件的操作 -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<rollingPolicy
|
||||
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!--日志输出位置 可相对、和绝对路径 -->
|
||||
<fileNamePattern>${log_dir}/warn/%d{yyyy-MM-dd}/logs.log
|
||||
</fileNamePattern>
|
||||
<maxHistory>${maxHistory}</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level] %logger - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
|
||||
<!-- INFO级别日志 appender -->
|
||||
<appender name="INFO"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>INFO</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<rollingPolicy
|
||||
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log_dir}/info/%d{yyyy-MM-dd}/logs.log
|
||||
</fileNamePattern>
|
||||
<maxHistory>${maxHistory}</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level] %logger - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
|
||||
<!-- DEBUG级别日志 appender -->
|
||||
<appender name="DEBUG"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>DEBUG</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<rollingPolicy
|
||||
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log_dir}/debug/%d{yyyy-MM-dd}/logs.log
|
||||
</fileNamePattern>
|
||||
<maxHistory>${maxHistory}</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level] %logger - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
|
||||
<!-- TRACE级别日志 appender -->
|
||||
<appender name="TRACE"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>TRACE</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<rollingPolicy
|
||||
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log_dir}/trace/%d{yyyy-MM-dd}/logs.log
|
||||
</fileNamePattern>
|
||||
<maxHistory>${maxHistory}</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level] %logger - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 按包名区分日志级别 -->
|
||||
<logger name="org.jboss" level="WARN" />
|
||||
<logger name="org.xnio" level="ERROR" />
|
||||
<logger name="io.undertow" level="ERROR" />
|
||||
<logger name="com.zaxxer" level="ERROR" />
|
||||
<logger name="io.swagger" level="ERROR" />
|
||||
<logger name="org.hibernate.validator" level="WARN" />
|
||||
<logger name="org.redisson" level="WARN" />
|
||||
<logger name="org.apache.zookeeper" level="WARN" />
|
||||
<logger name="io.netty" level="WARN" />
|
||||
<logger name="org.quartz" level="ERROR" />
|
||||
|
||||
<!--控制台日志 -->
|
||||
<root level="debug">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
<!-- root级别 DEBUG -->
|
||||
<root>
|
||||
<!-- 打印debug级别日志及以上级别日志 -->
|
||||
<level value="DEBUG" />
|
||||
<!-- 控制台输出 -->
|
||||
<appender-ref ref="console" />
|
||||
<!-- 文件输出 -->
|
||||
<appender-ref ref="ERROR" />
|
||||
<appender-ref ref="INFO" />
|
||||
<appender-ref ref="WARN" />
|
||||
<appender-ref ref="DEBUG" />
|
||||
<appender-ref ref="TRACE" />
|
||||
</root>
|
||||
</configuration>
|
||||
21
uling-gateway/src/main/resources/task.properties
Normal file
21
uling-gateway/src/main/resources/task.properties
Normal file
@ -0,0 +1,21 @@
|
||||
#\u5F00\u542F\u7684\u4EFB\u52A1\u5217\u8868\u201C,\u201D\u9694\u5F00
|
||||
cron4j=log
|
||||
log.cron=* * * * *
|
||||
log.class=cc.uling.pay.gateway.timer.LogTimer
|
||||
log.desc=\u65E5\u5FD7\u8F93\u51FA
|
||||
log.enable=true
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
# cron \u8868\u8FBE\u5F0F\u7531\u4E94\u90E8\u5206\u7EC4\u6210\uFF1A\u5206 \u65F6 \u5929 \u6708 \u5468
|
||||
# \u5206 \uFF1A\u4ECE 0 \u5230 59
|
||||
# \u65F6 \uFF1A\u4ECE 0 \u5230 23
|
||||
# \u5929 \uFF1A\u4ECE 1 \u5230 31\uFF0C\u5B57\u6BCD L \u53EF\u4EE5\u8868\u793A\u6708\u7684\u6700\u540E\u4E00\u5929
|
||||
# \u6708 \uFF1A\u4ECE 1 \u5230 12\uFF0C\u53EF\u4EE5\u522B\u540D\uFF1Ajan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov" and "dec"
|
||||
# \u5468 \uFF1A\u4ECE 0 \u5230 6\uFF0C0 \u8868\u793A\u5468\u65E5\uFF0C6 \u8868\u793A\u5468\u516D\uFF0C\u53EF\u4EE5\u4F7F\u7528\u522B\u540D\uFF1A "sun", "mon", "tue", "wed", "thu", "fri" and "sat"
|
||||
# \u6570\u5B57 n\uFF1A\u8868\u793A\u4E00\u4E2A\u5177\u4F53\u7684\u65F6\u95F4\u70B9\uFF0C\u4F8B\u5982 5 * * * * \u8868\u793A 5 \u5206\u8FD9\u4E2A\u65F6\u95F4\u70B9\u65F6\u6267\u884C
|
||||
# \u9017\u53F7 , \uFF1A\u8868\u793A\u6307\u5B9A\u591A\u4E2A\u6570\u503C\uFF0C\u4F8B\u5982 3,5 * * * * \u8868\u793A 3 \u548C 5 \u5206\u8FD9\u4E24\u4E2A\u65F6\u95F4\u70B9\u6267\u884C
|
||||
# \u51CF\u53F7 -\uFF1A\u8868\u793A\u8303\u56F4\uFF0C\u4F8B\u5982 1-3 * * * * \u8868\u793A 1 \u5206\u30012 \u5206\u518D\u5230 3 \u5206\u8FD9\u4E09\u4E2A\u65F6\u95F4\u70B9\u6267\u884C
|
||||
# \u661F\u53F7 *\uFF1A\u8868\u793A\u6BCF\u4E00\u4E2A\u65F6\u95F4\u70B9\uFF0C\u4F8B\u5982 * * * * * \u8868\u793A\u6BCF\u5206\u949F\u6267\u884C\uFF0C*/2 * * * * \u8868\u793A 2 \u5206\u949F\u6267\u884C\u4E00\u6B21
|
||||
# \u9664\u53F7 /\uFF1A\u8868\u793A\u6307\u5B9A\u4E00\u4E2A\u503C\u7684\u589E\u52A0\u5E45\u5EA6\u3002\u4F8B\u5982 n/m\u8868\u793A\u4ECE n \u5F00\u59CB\uFF0C\u6BCF\u6B21\u589E\u52A0 m \u7684\u65F6\u95F4\u70B9\u6267\u884C
|
||||
7
uling-gateway/src/main/webapp/WEB-INF/web.xml
Normal file
7
uling-gateway/src/main/webapp/WEB-INF/web.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<!DOCTYPE web-app PUBLIC
|
||||
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
|
||||
"http://java.sun.com/dtd/web-app_2_3.dtd" >
|
||||
|
||||
<web-app>
|
||||
<display-name>Archetype Created Web Application</display-name>
|
||||
</web-app>
|
||||
5
uling-gateway/src/main/webapp/index.jsp
Normal file
5
uling-gateway/src/main/webapp/index.jsp
Normal file
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
<h2>Hello World!</h2>
|
||||
</body>
|
||||
</html>
|
||||
45
uling-gateway/start.sh
Normal file
45
uling-gateway/start.sh
Normal file
@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
|
||||
MAIN_CLASS=cc.uling.pay.gateway.YCGatewayApplication
|
||||
COMMAND="$1"
|
||||
|
||||
if [[ "$COMMAND" != "start" ]] && [[ "$COMMAND" != "stop" ]] && [[ "$COMMAND" != "restart" ]]; then
|
||||
COMMAND="restart"
|
||||
fi
|
||||
|
||||
# 生成 class path 值
|
||||
APP_BASE_PATH=$(cd `dirname $0`; pwd)
|
||||
CP=${APP_BASE_PATH}/config:${APP_BASE_PATH}/lib/*
|
||||
|
||||
function start()
|
||||
{
|
||||
# 运行为后台进程,并在控制台输出信息
|
||||
# java -Djava.awt.headless=true -Xverify:none ${JAVA_OPTS} -cp ${CP} ${MAIN_CLASS} &
|
||||
|
||||
# 运行为后台进程,并且不在控制台输出信息
|
||||
# nohup java -Djava.awt.headless=true -Xverify:none ${JAVA_OPTS} -cp ${CP} ${MAIN_CLASS} >/dev/null 2>&1 &
|
||||
|
||||
# 运行为后台进程,并且将信息输出到 output.log 文件
|
||||
nohup java -Djava.awt.headless=true -Xverify:none ${JAVA_OPTS} -cp ${CP} ${MAIN_CLASS} >> output.log 2>&1 &
|
||||
#tail -f /dev/null
|
||||
|
||||
# 运行为非后台进程,多用于开发阶段,快捷键 ctrl + c 可停止服务
|
||||
# 当以此方式在Docker下启动时,由于是后台进程,无前台进程,Docker容器启动后会马上退出,
|
||||
# 需加命令tail -f /dev/null,就可以保持你的容器一直在前台运行
|
||||
# 或者使用以下的非后台进程运行
|
||||
# java -Djava.awt.headless=true -Xverify:none ${JAVA_OPTS} -cp ${CP} ${MAIN_CLASS}
|
||||
}
|
||||
|
||||
function stop()
|
||||
{
|
||||
kill `pgrep -f ${APP_BASE_PATH}` 2>/dev/null
|
||||
}
|
||||
|
||||
if [[ "$COMMAND" == "start" ]]; then
|
||||
start
|
||||
elif [[ "$COMMAND" == "stop" ]]; then
|
||||
stop
|
||||
else
|
||||
stop
|
||||
start
|
||||
fi
|
||||
151
uling-gateway/uling-gateway.iml
Normal file
151
uling-gateway/uling-gateway.iml
Normal file
@ -0,0 +1,151 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/webapp" type="java-resource" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="uling-system" />
|
||||
<orderEntry type="module" module-name="uling-framework" />
|
||||
<orderEntry type="library" name="Maven: cn.hutool:hutool-jwt:5.8.27" level="project" />
|
||||
<orderEntry type="library" name="Maven: cn.hutool:hutool-json:5.8.27" level="project" />
|
||||
<orderEntry type="library" name="Maven: cn.hutool:hutool-core:5.8.27" level="project" />
|
||||
<orderEntry type="library" name="Maven: cn.hutool:hutool-crypto:5.8.27" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.10.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.quartz-scheduler:quartz:2.3.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.15" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP-java7:2.4.13" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: cloud.tianai.captcha:tianai-captcha:1.5.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.swagger:swagger-core:1.5.21" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.21" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.21" level="project" />
|
||||
<orderEntry type="module" module-name="uling-yc-service" />
|
||||
<orderEntry type="module" module-name="uling-common" />
|
||||
<orderEntry type="library" name="Maven: com.github.oshi:oshi-core:6.5.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.java.dev.jna:jna:5.14.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.java.dev.jna:jna-platform:5.14.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.zxing:javase:3.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.zxing:core:3.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.beust:jcommander:1.48" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.jai-imageio:jai-imageio-core:1.3.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.redisson:redisson:3.12.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.45.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.45.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.45.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-resolver-dns:4.1.45.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-codec-dns:4.1.45.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.45.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.cache:cache-api:1.0.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.3.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.reactivex.rxjava2:rxjava:2.2.17" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jodd:jodd-bean:5.0.13" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jodd:jodd-core:5.0.13" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.sun.mail:javax.mail:1.6.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpmime:4.3.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.httpcomponents:fluent-hc:4.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-httpclient:commons-httpclient:3.0.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: junit:junit:3.8.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.alibaba:easyexcel:4.0.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.alibaba:easyexcel-core:4.0.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.alibaba:easyexcel-support:3.3.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.11.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.ehcache:ehcache:3.9.11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:5.2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.poi:poi:5.2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-lite:5.2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:5.1.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.21" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.07" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
|
||||
<orderEntry type="module" module-name="uling-components" />
|
||||
<orderEntry type="library" name="Maven: com.rabbitmq:amqp-client:5.11.0" level="project" />
|
||||
<orderEntry type="module" module-name="uling-api-demo" />
|
||||
<orderEntry type="library" name="Maven: io.jboot:jboot:3.15.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.jfinal:jfinal:5.0.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.jfinal:cos:2022.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.jfinal:jfinal-undertow:3.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.undertow:undertow-core:2.2.18.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jboss.xnio:xnio-api:3.8.7.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.wildfly.common:wildfly-common:1.5.4.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.wildfly.client:wildfly-client-config:1.0.1.Final" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.jboss.xnio:xnio-nio:3.8.7.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jboss.threads:jboss-threads:3.1.0.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.undertow:undertow-servlet:2.2.18.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: cglib:cglib:3.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.ow2.asm:asm:7.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.undertow:undertow-websockets-jsr:2.2.18.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jboss.spec.javax.websocket:jboss-websocket-api_1.1_spec:2.0.0.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.30" level="project" />
|
||||
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.49" level="project" />
|
||||
<orderEntry type="library" name="Maven: de.ruedigermoeller:fst:2.57" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.objenesis:objenesis:2.5.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.javassist:javassist:3.29.0-GA" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.83" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.guava:guava:31.1-jre" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.12.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.11.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: it.sauronsoftware.cron4j:cron4j:2.2.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jsoup:jsoup:1.14.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.ben-manes.caffeine:caffeine:2.9.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.21.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.2.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.3.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.glassfish:javax.el:3.0.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.dropwizard.metrics:metrics-core:4.2.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.dropwizard.metrics:metrics-servlets:4.2.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.dropwizard.metrics:metrics-json:4.2.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.helger:profiler:1.1.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.dropwizard.metrics:metrics-healthchecks:4.2.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.dropwizard.metrics:metrics-jvm:4.2.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: c3p0:c3p0:0.9.1.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.alibaba:druid:1.0.21" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.4.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: redis.clients:jedis:3.2.0" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.16" level="project" />
|
||||
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
|
||||
<orderEntry type="library" name="Maven: log4j:log4j:1.2.17" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-core:2.23.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.23.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
|
||||
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.8.29" level="project" />
|
||||
<orderEntry type="library" name="Maven: pro.fessional:kaptcha:2.3.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.jhlabs:filters:2.0.235-1" level="project" />
|
||||
<orderEntry type="library" name="Maven: eu.bitwalker:UserAgentUtils:1.19" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
Reference in New Issue
Block a user