From: Xia Kaixiang Date: Thu, 11 Jul 2019 10:14:34 +0000 (+0800) Subject: YnrccAgent X-Git-Tag: 1.0.0^2~68 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=0e37c1413aa70387077e2de4b84a9ad3292c7136;p=epayment%2Ffood_payapi.git YnrccAgent --- diff --git a/config/application-devel-agent.properties b/config/application-devel-agent.properties new file mode 100644 index 00000000..8b266ddb --- /dev/null +++ b/config/application-devel-agent.properties @@ -0,0 +1,6 @@ +############# YNRCC SOCKET ############### +ynrcc.socket.ip=127.0.0.1 +ynrcc.socket.port=8089 +## 超时时间(分钟) +ynrcc.socket.timeout = 10 +ynrcc.md5.key=80816b7947ed016bff8079557735006e \ No newline at end of file diff --git a/payapi/src/main/java/com/supwisdom/dlpay/util/YnrccUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/util/YnrccUtil.java new file mode 100644 index 00000000..1d2895b1 --- /dev/null +++ b/payapi/src/main/java/com/supwisdom/dlpay/util/YnrccUtil.java @@ -0,0 +1,46 @@ +package com.supwisdom.dlpay.util; + +import java.util.HashMap; +import java.util.Map; + + +public class YnrccUtil { + private static final String BANKCARD_BIND_TRANSCODE = "BC5510"; + private static final String BANKCARD_SIGN_TRANSCODE = "BC5511"; + private static final String BANKCARD_PAY_TRANSCODE = "BC5512"; + private static final String BANKCARD_PAYREFUND_TRANSCODE = "BC5513"; + private static final String BANKCARD_QUERYRESULT_TRANSCODE = "BC5514"; + private static final String BANKCARD_CHKFILE_TRANSCODE = "BC5515"; + + public static final String DLPAY_CATEGORIE = "C001"; //消费类别 + + public static final String DLPAY_SIGNTYPE_BUSSINESSKEY = "ynrcc.agent.signtype"; //农商行前置signtype + public static final String DLPAY_SIGNKEY_BUSSINESSKEY = "ynrcc.agent.signkey"; //农商行前置md5key + + public static final Map errcode = new HashMap<>(0); + static { + errcode.put("0000", "成功"); + errcode.put("0101", "手机号不一致"); + errcode.put("0102", "无预留手机号"); + errcode.put("0103", "证件类型不一致"); + errcode.put("0104", "证件号码不一致"); + errcode.put("0105", "户名不符"); + errcode.put("0106", "卡状态异常"); + errcode.put("0107", "无此卡号"); + errcode.put("0201", "未进行银行卡绑定"); + errcode.put("0202", "无效的交易类型"); + errcode.put("0301", "未签约"); + errcode.put("0302", "余额不足"); + errcode.put("0303", "MD5校验失败"); + errcode.put("0401", "原始流水不存在"); + errcode.put("0402", "原始流水未成功"); + errcode.put("0403", "原始流水已退款"); + errcode.put("4004", "商户账户余额不足"); + errcode.put("0405", "不在退款时间范围内"); + errcode.put("0406", "当日无交易明细"); + } + + + + +} diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt index dd978bb1..2397e3b1 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt @@ -6,10 +6,8 @@ import com.sun.jersey.api.client.ClientResponse import com.supwisdom.dlpay.api.bean.* import com.supwisdom.dlpay.api.domain.TPersondtl import com.supwisdom.dlpay.api.domain.TShopdtl -import com.supwisdom.dlpay.api.util.IDTypes import com.supwisdom.dlpay.framework.util.* import com.supwisdom.dlpay.util.Code -import com.supwisdom.dlpay.util.DlpayUtil import mu.KotlinLogging class CallBackResp { @@ -237,7 +235,7 @@ class CallService { } } - + /* /** * 大理农商行银行卡绑定 * */ @@ -615,6 +613,8 @@ class CallService { } } + */ + fun CallCitizenCardPay(config: Map, paydtl: TShopdtl): CallBackResp { val resp = CallBackResp() resp.retcode = "0" diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/dali_datasync_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/dali_datasync_api_controller.kt index 5b5c19cb..5f08635c 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/dali_datasync_api_controller.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/dali_datasync_api_controller.kt @@ -73,7 +73,7 @@ class DaliDatasyncApiController { return when(StringUtil.isEmpty(errlist)){ true -> ResponseEntity.ok(mapOf("retcode" to "0000", "retmsg" to "SUCCESS", "resultcode" to "0000", "resultmsg" to "")) - false -> ResponseEntity.ok(mapOf("retcode" to "0000", "retmsg" to "请求成功接收", "resultcode" to "0000", "resultmsg" to "明细数据处理有错", "data" to Gson().toJson(errlist))) + false -> ResponseEntity.ok(mapOf("retcode" to "0000", "retmsg" to "请求成功接收", "resultcode" to "4000", "resultmsg" to "明细数据处理有错", "data" to Gson().toJson(errlist))) } } catch (ex: RequestParamCheckException) { return ResponseEntity.ok(ResponseBodyBuilder.create() diff --git a/settings.gradle b/settings.gradle index 00adefdd..42be4811 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ rootProject.name = 'payapi' -include 'payapi', 'payapi-sdk', 'payapi-common' +include 'payapi', 'payapi-sdk', 'payapi-common', 'ynrcc-agent' diff --git a/ynrcc-agent/build.gradle b/ynrcc-agent/build.gradle new file mode 100644 index 00000000..4431bd60 --- /dev/null +++ b/ynrcc-agent/build.gradle @@ -0,0 +1,73 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '2.1.6.RELEASE' + id 'org.jetbrains.kotlin.jvm' version '1.3.31' + id 'org.jetbrains.kotlin.plugin.spring' version '1.3.31' + id "com.palantir.git-version" version "0.12.0-rc2" + id 'com.palantir.docker' version '0.22.1' +} + +apply plugin: 'java' +apply plugin: 'io.spring.dependency-management' + +payapiVersion = gitVersion() + +group = rootProject.group +version = '1' +sourceCompatibility = jdkVersion +def startClass = 'com.supwisdom.agent.YnrccAgentApplication' + +println("Build version: $payapiVersion") + +bootJar { + mainClassName = startClass + manifest { + attributes('YnrccAgent-Version': payapiVersion) + } +} + +jar { + baseName = 'YnrccAgent' +} + +docker { + name 'harbor.supwisdom.com/dali/ynrcc:' + version + println(jar.archivePath) + files jar.archivePath +} + +docker.dependsOn(jar) + +dependencies { + + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-autoconfigure' + implementation 'commons-codec:commons-codec:1.12' + implementation 'com.jcabi:jcabi-manifests:1.1' + implementation 'org.slf4j:slf4j-parent:1.7.26' + implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5' + implementation group: 'com.sun.jersey', name: 'jersey-client', version: '1.19' + implementation group: 'javax.servlet', name: 'jstl', version: '1.2' + implementation group: 'taglibs', name: 'standard', version: '1.1.2' + implementation group: 'commons-codec', name: 'commons-codec', version: '1.6' + implementation 'org.dom4j:dom4j:2.1.1' + + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'io.rest-assured:rest-assured:3.3.0' + testImplementation 'io.rest-assured:spring-mock-mvc:3.3.0' + testImplementation 'org.hamcrest:hamcrest:2.1' +} + +compileKotlin { + kotlinOptions { + freeCompilerArgs = ['-Xjsr305=strict'] + jvmTarget = jdkVersion + } +} + +compileTestKotlin { + kotlinOptions { + freeCompilerArgs = ['-Xjsr305=strict'] + jvmTarget = jdkVersion + } +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/BussinessException.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/BussinessException.java new file mode 100644 index 00000000..cad70230 --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/BussinessException.java @@ -0,0 +1,7 @@ +package com.supwisdom.agent.Util; + +public class BussinessException extends Exception { + public BussinessException(String message) { + super(message); + } +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/DateUtil.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/DateUtil.java new file mode 100644 index 00000000..b9f451f8 --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/DateUtil.java @@ -0,0 +1,361 @@ +package com.supwisdom.agent.Util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +public class DateUtil { + private static final Logger logger = LoggerFactory.getLogger(DateUtil.class); + public static final String DATE_FMT = "yyyyMMdd"; + public static final String TIME_FMT = "HHmmss"; + public static final String DATETIME_FMT = "yyyyMMddHHmmss"; + + /** + * Description: 返回一个当前时间 @return String 格式:yyyyMMddHHmmss @exception Modify + * History: + */ + public static String getNow() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + return sdf.format(new Date()); + } + + + /** + * Description: 根据类型返回一个当前时间 @param partten String @return String 格式:partten + */ + public static String getNow(String partten) { + SimpleDateFormat sdf = new SimpleDateFormat(partten); + return sdf.format(new Date()); + } + /* + * + * */ + public static String getNowInterDay(int intervalday) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + Date d = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(d.getTime()); + calendar.add(Calendar.DATE, intervalday); + return sdf.format(calendar.getTime()); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * Description: 得到一个特殊的时间 @param startTime String 格式:yyyyMMddHHmmss @param + * interval int 秒 @return String 格式:partten @exception Modify History: + */ + public static String getNewTime(String startTime, int interval) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + Date d = sdf.parse(startTime); + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(d.getTime()); + calendar.add(Calendar.SECOND, interval); + return sdf.format(calendar.getTime()); + } catch (ParseException e) { + return startTime; + } + } + + /** + * Description: 得到一个特殊的时间 @param startTime String 格式:partten @param + * interval int 秒 @return String 格式:partten @exception Modify History: + */ + public static String getNewTime(String startTime, int interval, String partten) { + try { + SimpleDateFormat sdf = new SimpleDateFormat(partten); + Date d = sdf.parse(startTime); + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(d.getTime()); + calendar.add(Calendar.SECOND, interval); + return sdf.format(calendar.getTime()); + } catch (ParseException e) { + return startTime; + } + } + + public static String getNewDay(String startDay, int intervalday) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + Date d = sdf.parse(startDay); + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(d.getTime()); + calendar.add(Calendar.DATE, intervalday); + return sdf.format(calendar.getTime()); + } catch (ParseException e) { + return startDay; + } + } + + /** + * 得到两个日期相差的天数 格式 yyyyMMdd @return diffdays = secondDay - firstDay + */ + public static long getIntervalDay(String firstDay, String secondDay) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + Date f = sdf.parse(firstDay); + Date s = sdf.parse(secondDay); + long time = s.getTime() - f.getTime(); + return time / (24 * 60 * 60 * 1000); + } catch (ParseException e) { + return 0; + } + } + + /** + * Description: 比较两个时间字符串的前后关系 @param firstTime String 格式:yyyyMMddHHmmss + * + * @param secondTime String 格式: yyyyMMddHHmmss @return int | + * firstTime=second int=0 | firstTime>secondTime int>0 | + * firstTimesecondTime int>0 | + * firstTimesecondTime + * int>0 | firstTime+seconds 2014-04-01 + * 中格式:201404011200 -> 2014-04-01 12:00 + * 长格式:20140401123025 -> 2014-04-01 12:30:25 + **/ + public static String parseToDateFormat(String str) { + switch (str.length()) { + case 8: + str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8); + break; + case 12: + str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8) + " " + str.substring(8, 10) + ":" + str.substring(10, 12); + break; + case 14: + str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8) + " " + str.substring(8, 10) + ":" + str.substring(10, 12) + ":" + str.substring(12, 14); + break; + default: + break; + } + return str; + } + + /** + * 解日期格式 + * 短格式:2014-04-01 -> 20140401 + * 中格式:2014-04-01 12:00 -> 201404011200 + * 长格式:2014-04-01 12:30:25 -> 20140401123025 + **/ + public static String unParseToDateFormat(String str) { + return str.replaceAll("-", "").replaceAll(" ", "").replaceAll(":", ""); + } + + /** + * 检验时间格式 + */ + public static boolean checkDatetimeValid(String datetime, String pattern) { + if (null == datetime) return false; + try { + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + Date d = sdf.parse(datetime); + return datetime.trim().equals(sdf.format(d)); + } catch (Exception e) { + } + return false; + } + + /** + * 获取指定日期是星期几 格式 yyyyMMdd + * MON|TUE|WED|THU|FRI|SAT|SUN + * 1 2 3 4 5 6 7 + */ + public static int getWeekday(String datestr) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + Calendar calendar = Calendar.getInstance(); + boolean isFirstSunday = (calendar.getFirstDayOfWeek() == Calendar.SUNDAY); //一周第一天是否为星期天 + Date d = sdf.parse(datestr); + calendar.setTimeInMillis(d.getTime()); + int weekDay = calendar.get(calendar.DAY_OF_WEEK); + if (isFirstSunday) { + weekDay = weekDay - 1; + if (weekDay == 0) { + weekDay = 7; + } + } + return weekDay; + } catch (Exception e) { + return -1; + } + } + + /** + * 获取指定日期 + */ + public static Date getSpecifyDate(String datestr, String pattern) { + try { + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + Date result = sdf.parse(datestr); + return result; + } catch (Exception e) { + return new Date(); + } + } + + public static Integer getLastDayOfMonth(Integer year, Integer month) { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, year); + cal.set(Calendar.MONTH, month - 1); + cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE)); + String str = new SimpleDateFormat("yyyyMMdd ").format(cal.getTime()).toString(); + Integer result = Integer.parseInt(str.substring(0, 4) + str.substring(4, 6) + str.substring(6, 8)); + return result; + } + + private static Date set(Date date, int calendarField, int amount) { + Calendar c = Calendar.getInstance(); + c.setLenient(false); + c.setTime(date); + c.add(calendarField, amount); + return c.getTime(); + } + + + public static Date setMinutes(Date date, int amount) { + return set(date, Calendar.MINUTE, amount); + } + + + public static long getNowSecond() { + Calendar calendar = Calendar.getInstance(); + return calendar.getTimeInMillis() / 1000; + } + + + public static String getUTCTime(Long timeInMillisSecond) { + Calendar time = Calendar.getInstance(); + SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); + fmt.setTimeZone(TimeZone.getTimeZone("UTC")); + time.setTimeInMillis(timeInMillisSecond); + return fmt.format(time.getTime()); + } + + public static String getUTCTime() { + return getUTCTime(System.currentTimeMillis()); + } + + public static int compareDay(Timestamp d1, Timestamp d2) { + Calendar cd1 = Calendar.getInstance(); + cd1.setTimeInMillis(d1.getTime()); + Calendar cd2 = Calendar.getInstance(); + cd2.setTimeInMillis(d2.getTime()); + + if (cd1.get(Calendar.YEAR) != cd2.get(Calendar.YEAR)) { + return cd1.compareTo(cd2); + } + + return Integer.compare(cd1.get(Calendar.DAY_OF_YEAR), cd2.get(Calendar.DAY_OF_YEAR)); + } + + public static Boolean sameDay(Timestamp d1, Timestamp d2) { + return (compareDay(d1, d2) == 0); + } +} diff --git a/payapi/src/main/java/com/supwisdom/dlpay/util/DlpayUtil.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/DlpayUtil.java similarity index 71% rename from payapi/src/main/java/com/supwisdom/dlpay/util/DlpayUtil.java rename to ynrcc-agent/src/main/java/com/supwisdom/agent/Util/DlpayUtil.java index 7f8bf3fc..4dbd2bb6 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/util/DlpayUtil.java +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/DlpayUtil.java @@ -1,4 +1,4 @@ -package com.supwisdom.dlpay.util; +package com.supwisdom.agent.Util; import org.dom4j.Document; import org.dom4j.Element; @@ -13,29 +13,12 @@ import java.util.Map; import java.util.Random; public class DlpayUtil { - public static final Map errcode = new HashMap<>(0); - - static { - errcode.put("0000", "成功"); - errcode.put("0101", "手机号不一致"); - errcode.put("0102", "无预留手机号"); - errcode.put("0103", "证件类型不一致"); - errcode.put("0104", "证件号码不一致"); - errcode.put("0105", "户名不符"); - errcode.put("0106", "卡状态异常"); - errcode.put("0107", "无此卡号"); - errcode.put("0201", "未进行银行卡绑定"); - errcode.put("0202", "无效的交易类型"); - errcode.put("0301", "未签约"); - errcode.put("0302", "余额不足"); - errcode.put("0303", "MD5校验失败"); - errcode.put("0401", "原始流水不存在"); - errcode.put("0402", "原始流水未成功"); - errcode.put("0403", "原始流水已退款"); - errcode.put("4004", "商户账户余额不足"); - errcode.put("0405", "不在退款时间范围内"); - errcode.put("0406", "当日无交易明细"); - } + public static final String OPTYPE_BINDCARD = "bindcard"; //绑定银行卡 + public static final String OPTYPE_SIGNCARD = "signcard"; //签(解)约银行卡 + public static final String OPTYPE_CARDPAY = "cardpay"; //代扣消费 + public static final String OPTYPE_PAYREFUND = "payrefund"; //消费退款 + public static final String OPTYPE_QUERYRESULT = "queryresult"; //消费结果查询 + public static final String OPTYPE_CHKDTL = "chkdtl"; //流水对账 /** * socket方式请求农商行 diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/ErrorCode.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/ErrorCode.java new file mode 100644 index 00000000..ecc83dc4 --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/ErrorCode.java @@ -0,0 +1,10 @@ +package com.supwisdom.agent.Util; + +public class ErrorCode { + public static final String SYSTEM_ERROR = "10000"; + + public static final String REQ_PARAM_ERROR = "20000"; + public static final String REQ_SIGN_ERROR = "21000"; + + public static final String BUSSINESS_ERROR = "30000"; +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/MD5.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/MD5.java new file mode 100644 index 00000000..aeea2f65 --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/MD5.java @@ -0,0 +1,96 @@ +package com.supwisdom.agent.Util; + +import java.security.MessageDigest; + +public class MD5 { + //十六进制下数字到字符的映射数组 + private final static String[] hexDigits = {"0", "1", "2", "3", "4", + "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; + + /** + * 把inputString加密 + */ + public static String generatePassword(String data, String salt) { + String enyptString = data + "{" + salt + "}"; + return encodeByMD5(enyptString); + } + + /** + * 验证输入的密码是否正确 + * + * @param password 加密后的密码 + * @param inputString 输入的字符串 + * @return 验证结果,TRUE:正确 FALSE:错误 + */ + public static boolean validatePassword(String password, String inputString) { + if (password.equals(encodeByMD5(inputString))) { + return true; + } else { + return false; + } + } + + /** + * 对字符串进行MD5加密 + */ + public static String encodeByMD5(String originString) { + if (originString != null) { + try { + //创建具有指定算法名称的信息摘要 + MessageDigest md = MessageDigest.getInstance("MD5"); + //使用指定的字节数组对摘要进行最后更新,然后完成摘要计算 + byte[] results = md.digest(originString.getBytes("UTF-8")); + //将得到的字节数组变成字符串返回 + String resultString = byteArrayToHexString(results); + return resultString.toUpperCase(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + return null; + } + + /** + * 转换字节数组为十六进制字符串 + * + * @param 字节数组 + * @return 十六进制字符串 + */ + private static String byteArrayToHexString(byte[] b) { + StringBuffer resultSb = new StringBuffer(); + for (int i = 0; i < b.length; i++) { + resultSb.append(byteToHexString(b[i])); + } + return resultSb.toString(); + } + + /** + * 将一个字节转化成十六进制形式的字符串 + */ + private static String byteToHexString(byte b) { + int n = b; + if (n < 0) + n = 256 + n; + int d1 = n / 16; + int d2 = n % 16; + return hexDigits[d1] + hexDigits[d2]; + } + + public static String encodeByMD5ForYnrcc(String originString) { + if (originString != null) { + try { + //创建具有指定算法名称的信息摘要 + MessageDigest md = MessageDigest.getInstance("MD5"); + //使用指定的字节数组对摘要进行最后更新,然后完成摘要计算 + byte[] results = md.digest(originString.getBytes("GBK")); + //将得到的字节数组变成字符串返回 + String resultString = byteArrayToHexString(results); + return resultString; + } catch (Exception ex) { + ex.printStackTrace(); + } + } + return null; + } + +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/RandomUtils.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/RandomUtils.java new file mode 100644 index 00000000..6883fba7 --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/RandomUtils.java @@ -0,0 +1,104 @@ +package com.supwisdom.agent.Util; + +import org.apache.commons.codec.binary.Base32; +import org.apache.commons.codec.binary.Hex; + +import java.security.SecureRandom; +import java.util.Random; + +/** + * 获取随机数类 + * + * @author yanhua_mao + * + */ +public class RandomUtils { + + /** + * 获取随机数 + * + * @param length + * 位数 + * @return 返回随机数 + */ + public static final String randomNumber(int length) { + char[] numbersAndLetters = null; + java.util.Random randGen = null; + if (length < 1) { + return null; + } + if (randGen == null) { + randGen = new java.util.Random(); + numbersAndLetters = ("0123456789").toCharArray(); + } + char[] randBuffer = new char[length]; + for (int i = 0; i < randBuffer.length; i++) { + randBuffer[i] = numbersAndLetters[randGen.nextInt(9)]; + } + return new String(randBuffer); + } + + /** + * 产生一个随机的字符串 + * + * @param 字符串长度 + * @return + */ + public static String getRandomString(int length) { + String base = "abcdefghijklmnopqrstuvwxyz234567"; + Random random = new Random(); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < length; i++) { + int number = random.nextInt(base.length()); + sb.append(base.charAt(number)); + } + return sb.toString(); + } + + public static String getSecureRandom() { + SecureRandom a = new SecureRandom(); + byte[] phonesecret = new byte[10]; + a.nextBytes(phonesecret); + + Base32 c = new Base32(); + String s = c.encodeAsString(phonesecret); + String savesecret = Hex.encodeHexString(phonesecret); + String result = s + "_" + savesecret; + return result; + } + + public static String getSecureRandomHex() { + SecureRandom a = new SecureRandom(); + byte[] phonesecret = new byte[10]; + a.nextBytes(phonesecret); + + String savesecret = Hex.encodeHexString(phonesecret); + return savesecret; + } + + /** + * + * @param length + * @return + */ + public static String getCharAndNumr(int length) { + String val = ""; + + Random random = new Random(); + for (int i = 0; i < length; i++) { + String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num"; // 输出字母还是数字 + + if ("char".equalsIgnoreCase(charOrNum)) // 字符串 + { + int choice = random.nextInt(2) % 2 == 0 ? 65 : 97; // 取得大写字母还是小写字母 + val += (char) (choice + random.nextInt(26)); + } else if ("num".equalsIgnoreCase(charOrNum)) // 数字 + { + val += String.valueOf(random.nextInt(10)); + } + } + + return val; + } + +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/StringUtil.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/StringUtil.java new file mode 100644 index 00000000..e5fe750a --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/StringUtil.java @@ -0,0 +1,170 @@ +package com.supwisdom.agent.Util; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class StringUtil { + /** + * 判断字符串是否为空 + */ + public static boolean isEmpty(String str) { + if (null == str || "".equals(str) || "".equals(str.trim())) { + return true; + } + return false; + } + + /** + * 判断List是否为空 + */ + public static boolean isEmpty(List list) { + if (null == list || list.size() <= 0) { + return true; + } + return false; + } + + public static boolean equalsIgnoreCase(String str1, String str2) { + return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2); + } + + public static boolean equals(String str1, String str2) { + return str1 == null ? str2 == null : str1.equals(str2); + } + + /** + * 手机号验证 + * + * @param str + * @return + */ + public static boolean isMobile(String str) { + Pattern p = Pattern.compile("^1[0-9]{10}$"); // 验证手机号 + Matcher m = p.matcher(str); + return m.matches(); + } + + /** + * 邮箱格式验证 + */ + public static boolean isEmail(String email) { + boolean ret = true; + Pattern pattern = Pattern.compile("^([a-zA-Z0-9]+[_|\\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\\.]?)*[a-zA-Z0-9]+\\.[a-zA-Z]{2,3}$"); + final Matcher mat = pattern.matcher(email); + if (!mat.find()) { + ret = false; + } + return ret; + } + + /** + * 身份证格式验证 + * + * @param str + * @return + */ + public static boolean isIdentity(String str) { + // 中国公民身份证格式:长度为15或18位,最后一位可以为字母 + Pattern pattern = Pattern.compile("(\\d{14}[0-9a-zA-Z])|(\\d{17}[0-9a-zA-Z])"); + final Matcher m = pattern.matcher(str); + return m.matches(); + } + + /** + * 除去数组中的空值和签名参数 + * + * @param sArray 签名参数组 + * @return 去掉空值与签名参数后的新签名参数组 + */ + public static Map paraFilter(Map sArray) { + Map result = new HashMap(); + if (sArray == null || sArray.size() <= 0) { + return result; + } + for (String key : sArray.keySet()) { + String value = sArray.get(key); + if (null == value || "".equals(value.trim()) || "null".equalsIgnoreCase(value.trim()) || key.equalsIgnoreCase("sign") || key.equalsIgnoreCase("sign_type")) { + continue; + } + result.put(key, value); + } + return result; + } + + /** + * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串 + * + * @param params 需要排序并参与字符拼接的参数组 + * @return 拼接后字符串 + */ + public static String createLinkString(Map params) { + + List keys = new ArrayList(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; + } + + public static boolean isCharAndNum(String inputStr) { + //有问题 + /*Pattern p = Pattern.compile("\\w+"); + Matcher m = p.matcher(inputStr); + if (m.matches()) { + // 除字母和数字外还包含其它字符 + return false; + } else { + return true; + }*/ + return true; + } + /** + * 手机号遮掩中间4位 + * */ + public static String phoneReplace(String phone){ + return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"); + } + + /** + * 邮箱只显示@前面的首位和末位 + * */ + public static String emailReplace(String s){ + return s.replaceAll("(\\w?)(\\w+)(\\w)(@\\w+\\.[a-z]+(\\.[a-z]+)?)", "$1****$3$4"); + } + + /** + * 名字显示姓 + * */ + public static String nameReplace(String s){ + return s.replaceAll("([\\d\\D]{1})(.*)", "$1**"); + } + + + /** + * 检验时间格式 + */ + public static boolean checkDatetimeValid(String datetime, String pattern) { + if (null == datetime) return false; + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern); + Date d = sdf.parse(datetime); + return datetime.trim().equals(sdf.format(d)); + } catch (Exception e) { + } + return false; + } + +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/XmlUtils.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/XmlUtils.java new file mode 100644 index 00000000..c4a3eb27 --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/Util/XmlUtils.java @@ -0,0 +1,75 @@ +package com.supwisdom.agent.Util; + +import org.dom4j.Document; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class XmlUtils { + public static String getObjectToXml(T object) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + + try { + JAXBContext context = JAXBContext.newInstance(object.getClass()); + // 将对象转变为xml Object------XML + // 指定对应的xml文件 + Marshaller marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_ENCODING, "gbk");//编码格式  + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);// 是否格式化生成的xml串 + marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);// 是否省略xml头信息 + + // 将对象转换为对应的XML文件 + marshaller.marshal(object, byteArrayOutputStream); + } catch (JAXBException e) { + + e.printStackTrace(); + } + // 转化为字符串返回 + String xmlContent = new String(byteArrayOutputStream.toByteArray(), + "gbk"); + return xmlContent; + } + + public static T getXmlToObject(String xmlContent, String charset, Class clazz) { + try { + JAXBContext context = JAXBContext.newInstance(clazz); + // xml转换为对象 XML------Object + InputStream inputStream; + try { + inputStream = new ByteArrayInputStream( + xmlContent.getBytes(charset)); + Unmarshaller um = context.createUnmarshaller(); + + return (T) um.unmarshal(inputStream); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } catch (JAXBException e) { + + e.printStackTrace(); + } + return null; + } + + public static Map parseXml(String xml) throws Exception { + Map map = new HashMap(); + Document document = DocumentHelper.parseText(xml); + Element root = document.getRootElement(); + List elementList = root.elements(); + for (Element e : elementList) + map.put(e.getName(), e.getText()); + return map; + } + +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/YnrccAgentApplication.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/YnrccAgentApplication.java new file mode 100644 index 00000000..8e1bb6e2 --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/YnrccAgentApplication.java @@ -0,0 +1,11 @@ +package com.supwisdom.agent; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class YnrccAgentApplication { + public static void main(String[] args) { + SpringApplication.run(YnrccAgentApplication.class, args); + } +} diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/bean/DlpayReq.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/DlpayReq.java similarity index 91% rename from payapi/src/main/java/com/supwisdom/dlpay/api/bean/DlpayReq.java rename to ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/DlpayReq.java index 0af068f4..8ef13f7d 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/api/bean/DlpayReq.java +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/DlpayReq.java @@ -1,6 +1,6 @@ -package com.supwisdom.dlpay.api.bean; +package com.supwisdom.agent.api.bean; -import com.supwisdom.dlpay.framework.util.MD5; +import com.supwisdom.agent.Util.MD5; public class DlpayReq { private static final String prefix = ""; @@ -13,6 +13,7 @@ public class DlpayReq { public static final String DLPAY_CATEGORIE = "C001"; //消费类别 + private String transcode; private String transdate; //交易日期 private String transtime; //交易时间 private String sn; //应用系统唯一流水号 @@ -40,7 +41,7 @@ public class DlpayReq { StringBuffer xml = new StringBuffer(); xml.append(prefix) .append("") - .append("").append(BANKCARD_BIND_TRANSCODE).append("") + .append("").append(transcode).append("") .append("").append(transdate).append("") .append("").append(transtime).append("") .append("").append(sn).append("") @@ -61,7 +62,7 @@ public class DlpayReq { StringBuffer xml = new StringBuffer(); xml.append(prefix) .append("") - .append("").append(BANKCARD_SIGN_TRANSCODE).append("") + .append("").append(transcode).append("") .append("").append(transdate).append("") .append("").append(transtime).append("") .append("").append(sn).append("") @@ -83,7 +84,7 @@ public class DlpayReq { StringBuffer xml = new StringBuffer(); xml.append(prefix) .append("") - .append("").append(BANKCARD_PAY_TRANSCODE).append("") + .append("").append(transcode).append("") .append("").append(transdate).append("") .append("").append(transtime).append("") .append("").append(sn).append("") @@ -96,7 +97,7 @@ public class DlpayReq { .append("").append(merchantName).append("") .append("").append(amount).append("") .append("").append(description).append("") - .append("").append(MD5.encodeByMD5ForDlpay(merchantBcno + bcNo + amount)).append("") + .append("").append(MD5.encodeByMD5ForYnrcc(merchantBcno + bcNo + amount)).append("") .append(""); return String.format("%08d", xml.toString().length()) + xml.toString(); } @@ -108,7 +109,7 @@ public class DlpayReq { StringBuffer xml = new StringBuffer(); xml.append(prefix) .append("") - .append("").append(BANKCARD_PAYREFUND_TRANSCODE).append("") + .append("").append(transcode).append("") .append("").append(transdate).append("") .append("").append(transtime).append("") .append("").append(sn).append("") @@ -126,7 +127,7 @@ public class DlpayReq { StringBuffer xml = new StringBuffer(); xml.append(prefix) .append("") - .append("").append(BANKCARD_QUERYRESULT_TRANSCODE).append("") + .append("").append(transcode).append("") .append("").append(transdate).append("") .append("").append(transtime).append("") .append("").append(sn).append("") @@ -142,7 +143,7 @@ public class DlpayReq { StringBuffer xml = new StringBuffer(); xml.append(prefix) .append("") - .append("").append(BANKCARD_CHKFILE_TRANSCODE).append("") + .append("").append(transcode).append("") .append("").append(transdate).append("") .append("").append(transtime).append("") .append("").append(sn).append("") @@ -279,4 +280,12 @@ public class DlpayReq { public void setChkdate(String chkdate) { this.chkdate = chkdate; } + + public String getTranscode() { + return transcode; + } + + public void setTranscode(String transcode) { + this.transcode = transcode; + } } diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/DlpayResp.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/DlpayResp.java new file mode 100644 index 00000000..7c18daf9 --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/DlpayResp.java @@ -0,0 +1,92 @@ +package com.supwisdom.agent.api.bean; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "root") +public class DlpayResp { + private String code; + private String message; + private String transdate; + private String transtime; + private String bankjourno; + private String captcha; + private String status; + private String filename; + + @XmlElement(name = "CODE") + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + @XmlElement(name = "MESSAGE") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @XmlElement(name = "TRANSDATE") + public String getTransdate() { + return transdate; + } + + public void setTransdate(String transdate) { + this.transdate = transdate; + } + + @XmlElement(name = "TRANSTIME") + public String getTranstime() { + return transtime; + } + + public void setTranstime(String transtime) { + this.transtime = transtime; + } + + @XmlElement(name = "BANKJOURNO") + public String getBankjourno() { + return bankjourno; + } + + public void setBankjourno(String bankjourno) { + this.bankjourno = bankjourno; + } + + @XmlElement(name = "CAPTCHA") + public String getCaptcha() { + return captcha; + } + + public void setCaptcha(String captcha) { + this.captcha = captcha; + } + + @XmlElement(name = "STATUS") + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + @XmlElement(name = "FILENAME") + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public String errPrint() { + return "error: code=[" + this.code + "],message=[" + this.message + "]"; + } +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java new file mode 100644 index 00000000..d414447b --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java @@ -0,0 +1,377 @@ +package com.supwisdom.agent.api.controller; + +import com.supwisdom.agent.Util.BussinessException; +import com.supwisdom.agent.Util.DlpayUtil; +import com.supwisdom.agent.Util.ErrorCode; +import com.supwisdom.agent.Util.StringUtil; +import com.supwisdom.agent.api.bean.DlpayReq; +import com.supwisdom.agent.api.bean.DlpayResp; +import com.supwisdom.agent.api.service.YnrccApiService; +import com.supwisdom.agent.api.service.YnrccParamCheckService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.ws.rs.FormParam; +import java.util.HashMap; +import java.util.Map; + + +@RestController +@RequestMapping("/ynrcc") +public class YnrccApiController { + @Autowired + private YnrccApiService ynrccApiService; + @Autowired + private YnrccParamCheckService ynrccParamCheckService; + + private static final Logger logger = LoggerFactory.getLogger(YnrccApiController.class); + + private boolean checkYnrccSign(Map params, DlpayResp resp) { + if (!ynrccParamCheckService.checkSign(params)) { + resp.setCode(ErrorCode.REQ_SIGN_ERROR); + resp.setMessage("签名错误"); + logger.error(resp.errPrint()); + return false; + } + return true; + } + + private void doSystemError(Exception e, DlpayResp resp) { + e.printStackTrace(); + resp.setCode(ErrorCode.SYSTEM_ERROR); + resp.setMessage(StringUtil.isEmpty(e.getMessage()) ? "业务处理异常" : e.getMessage()); + logger.error(resp.errPrint()); + } + + /** + * 绑定银行卡 + */ + @PostMapping("/bindcard") + public DlpayResp bindBankcard(@FormParam("transcode") String transcode, @FormParam("transdate") String transdate, + @FormParam("transtime") String transtime, @FormParam("refno") String refno, + @FormParam("bankcardno") String bankcardno, @FormParam("username") String username, + @FormParam("idtype") String idtype, @FormParam("idno") String idno, + @FormParam("phone") String phone, + @FormParam("sign_type") String sign_type, @FormParam("sign") String sign) { + DlpayResp resp = new DlpayResp(); + if (!ynrccParamCheckService.checkBindCardParam(transcode, transdate, transtime, refno, bankcardno, username, idtype, idno, phone, sign_type, sign, resp)) { + logger.error(resp.errPrint()); + return resp; + } + + Map params = new HashMap<>(0); + params.put("transcode", transcode); + params.put("transdate", transdate); + params.put("transtime", transtime); + params.put("refno", refno); + params.put("bankcardno", bankcardno); + params.put("username", username); + params.put("idtype", idtype); + params.put("idno", idno); + params.put("phone", phone); + params.put("sign_type", sign_type); + params.put("sign", sign); + if (!checkYnrccSign(params, resp)) { + return resp; + } + + try { + DlpayReq req = new DlpayReq(); + req.setTranscode(transcode); + req.setTransdate(transdate); + req.setTranstime(transtime); + req.setSn(refno); + req.setBcNo(bankcardno); + req.setName(username); + req.setIdType(idtype); + req.setIdNo(idno); + req.setPhone(phone); + return ynrccApiService.sendToYnrcc(DlpayUtil.OPTYPE_BINDCARD, req); + } catch (BussinessException be) { + resp.setCode(ErrorCode.BUSSINESS_ERROR); + resp.setMessage(be.getMessage()); + logger.error(resp.errPrint()); + return resp; + } catch (Exception e) { + doSystemError(e, resp); + return resp; + } + } + + /** + * 银行卡签约/解约 + */ + @PostMapping("/signcard") + public DlpayResp signBankcard(@FormParam("transcode") String transcode, @FormParam("transdate") String transdate, + @FormParam("transtime") String transtime, @FormParam("refno") String refno, + @FormParam("categorie") String categorie, @FormParam("transtype") String transtype, + @FormParam("bankcardno") String bankcardno, @FormParam("username") String username, + @FormParam("idtype") String idtype, @FormParam("idno") String idno, + @FormParam("phone") String phone, + @FormParam("sign_type") String sign_type, @FormParam("sign") String sign) { + DlpayResp resp = new DlpayResp(); + if (!ynrccParamCheckService.checkSignCardParam(transcode, transdate, transtime, refno, categorie, bankcardno, + username, idtype, idno, phone, transtype, sign_type, sign, resp)) { + logger.error(resp.errPrint()); + return resp; + } + + Map params = new HashMap<>(0); + params.put("transcode", transcode); + params.put("transdate", transdate); + params.put("transtime", transtime); + params.put("refno", refno); + params.put("categorie", categorie); + params.put("bankcardno", bankcardno); + params.put("username", username); + params.put("idtype", idtype); + params.put("idno", idno); + params.put("phone", phone); + params.put("transtype", transtype); + params.put("sign_type", sign_type); + params.put("sign", sign); + if (!checkYnrccSign(params, resp)) { + return resp; + } + + try { + DlpayReq req = new DlpayReq(); + req.setTranscode(transcode); + req.setTransdate(transdate); + req.setTranstime(transtime); + req.setSn(refno); + req.setCategorie(categorie); + req.setBcNo(bankcardno); + req.setName(username); + req.setIdType(idtype); + req.setIdNo(idno); + req.setPhone(phone); + req.setTransType(transtype); + return ynrccApiService.sendToYnrcc(DlpayUtil.OPTYPE_SIGNCARD, req); + } catch (BussinessException be) { + resp.setCode(ErrorCode.BUSSINESS_ERROR); + resp.setMessage(be.getMessage()); + logger.error(resp.errPrint()); + return resp; + } catch (Exception e) { + doSystemError(e, resp); + return resp; + } + } + + /** + * 银行卡代扣 + */ + @PostMapping("/cardpay") + public DlpayResp cardpay(@FormParam("transcode") String transcode, @FormParam("transdate") String transdate, + @FormParam("transtime") String transtime, @FormParam("refno") String refno, + @FormParam("categorie") String categorie, + @FormParam("bankcardno") String bankcardno, @FormParam("username") String username, + @FormParam("idtype") String idtype, @FormParam("idno") String idno, + @FormParam("merchant_bankcardno") String merchant_bankcardno, + @FormParam("merchant_bankaccname") String merchant_bankaccname, + @FormParam("amount") Integer amount, + @FormParam("description") String description, + @FormParam("sign_type") String sign_type, @FormParam("sign") String sign) { + DlpayResp resp = new DlpayResp(); + if (!ynrccParamCheckService.checkCardPayParam(transcode, transdate, transtime, refno, categorie, bankcardno, + username, idtype, idno, merchant_bankcardno, merchant_bankaccname, amount, description, sign_type, sign, resp)) { + logger.error(resp.errPrint()); + return resp; + } + + Map params = new HashMap<>(0); + params.put("transcode", transcode); + params.put("transdate", transdate); + params.put("transtime", transtime); + params.put("refno", refno); + params.put("categorie", categorie); + params.put("bankcardno", bankcardno); + params.put("username", username); + params.put("idtype", idtype); + params.put("idno", idno); + params.put("merchant_bankcardno", merchant_bankcardno); + params.put("merchant_bankaccname", merchant_bankaccname); + params.put("amount", String.valueOf(amount)); + params.put("description", description); + params.put("sign_type", sign_type); + params.put("sign", sign); + if (!checkYnrccSign(params, resp)) { + return resp; + } + + try { + DlpayReq req = new DlpayReq(); + req.setTranscode(transcode); + req.setTransdate(transdate); + req.setTranstime(transtime); + req.setSn(refno); + req.setCategorie(categorie); + req.setBcNo(bankcardno); + req.setName(username); +// req.setIdType(idtype); + req.setIdNo(idno); + req.setMerchantBcno(merchant_bankcardno); + req.setMerchantName(merchant_bankaccname); + req.setAmount(amount); + req.setDescription(description); + return ynrccApiService.sendToYnrcc(DlpayUtil.OPTYPE_CARDPAY, req); + } catch (BussinessException be) { + resp.setCode(ErrorCode.BUSSINESS_ERROR); + resp.setMessage(be.getMessage()); + logger.error(resp.errPrint()); + return resp; + } catch (Exception e) { + doSystemError(e, resp); + return resp; + } + } + + /** + * 银行卡代扣退款 + */ + @PostMapping("/cardpayrefund") + public DlpayResp cardpayRefund(@FormParam("transcode") String transcode, @FormParam("transdate") String transdate, + @FormParam("transtime") String transtime, @FormParam("refno") String refno, + @FormParam("refund_refno") String refundRefno, + @FormParam("amount") Integer amount, @FormParam("description") String description, + @FormParam("sign_type") String sign_type, @FormParam("sign") String sign) { + DlpayResp resp = new DlpayResp(); + if (!ynrccParamCheckService.checkPayRefundParam(transcode, transdate, transtime, refno, refundRefno, amount, description, sign_type, sign, resp)) { + logger.error(resp.errPrint()); + return resp; + } + + Map params = new HashMap<>(0); + params.put("transcode", transcode); + params.put("transdate", transdate); + params.put("transtime", transtime); + params.put("refno", refno); + params.put("refund_refno", refundRefno); + params.put("amount", String.valueOf(amount)); + params.put("description", description); + params.put("sign_type", sign_type); + params.put("sign", sign); + if (!checkYnrccSign(params, resp)) { + return resp; + } + + try { + DlpayReq req = new DlpayReq(); + req.setTranscode(transcode); + req.setTransdate(transdate); + req.setTranstime(transtime); + req.setSn(refno); + req.setOriSn(refundRefno); + req.setAmount(amount); + req.setDescription(description); + return ynrccApiService.sendToYnrcc(DlpayUtil.OPTYPE_PAYREFUND, req); + } catch (BussinessException be) { + resp.setCode(ErrorCode.BUSSINESS_ERROR); + resp.setMessage(be.getMessage()); + logger.error(resp.errPrint()); + return resp; + } catch (Exception e) { + doSystemError(e, resp); + return resp; + } + } + + /** + * 查询消费结果 + */ + @PostMapping("/queryresult") + public DlpayResp queryResult(@FormParam("transcode") String transcode, @FormParam("transdate") String transdate, + @FormParam("transtime") String transtime, @FormParam("refno") String refno, + @FormParam("orign_refno") String orignRefno, + @FormParam("sign_type") String sign_type, @FormParam("sign") String sign) { + DlpayResp resp = new DlpayResp(); + if (!ynrccParamCheckService.checkQueryResultParam(transcode, transdate, transtime, refno, orignRefno, sign_type, sign, resp)) { + logger.error(resp.errPrint()); + return resp; + } + + Map params = new HashMap<>(0); + params.put("transcode", transcode); + params.put("transdate", transdate); + params.put("transtime", transtime); + params.put("refno", refno); + params.put("orign_refno", orignRefno); + params.put("sign_type", sign_type); + params.put("sign", sign); + if (!checkYnrccSign(params, resp)) { + return resp; + } + + try { + DlpayReq req = new DlpayReq(); + req.setTranscode(transcode); + req.setTransdate(transdate); + req.setTranstime(transtime); + req.setSn(refno); + req.setOriSn(orignRefno); + return ynrccApiService.sendToYnrcc(DlpayUtil.OPTYPE_QUERYRESULT, req); + } catch (BussinessException be) { + resp.setCode(ErrorCode.BUSSINESS_ERROR); + resp.setMessage(be.getMessage()); + logger.error(resp.errPrint()); + return resp; + } catch (Exception e) { + doSystemError(e, resp); + return resp; + } + } + + /** + * 查询消费结果 + */ + @PostMapping("/checkdtl") + public DlpayResp checkDtl(@FormParam("transcode") String transcode, @FormParam("transdate") String transdate, + @FormParam("transtime") String transtime, @FormParam("refno") String refno, + @FormParam("checkdate") String checkdate, @FormParam("merchant_bankcardno") String merchant_bankcardno, + @FormParam("sign_type") String sign_type, @FormParam("sign") String sign) { + DlpayResp resp = new DlpayResp(); + if (!ynrccParamCheckService.checkChkfileParam(transcode, transdate, transtime, refno, checkdate, merchant_bankcardno, sign_type, sign, resp)) { + logger.error(resp.errPrint()); + return resp; + } + + Map params = new HashMap<>(0); + params.put("transcode", transcode); + params.put("transdate", transdate); + params.put("transtime", transtime); + params.put("refno", refno); + params.put("checkdate", checkdate); + params.put("merchant_bankcardno", merchant_bankcardno); + params.put("sign_type", sign_type); + params.put("sign", sign); + if (!checkYnrccSign(params, resp)) { + return resp; + } + + try { + DlpayReq req = new DlpayReq(); + req.setTranscode(transcode); + req.setTransdate(transdate); + req.setTranstime(transtime); + req.setSn(refno); + req.setChkdate(checkdate); + req.setMerchantBcno(merchant_bankcardno); + return ynrccApiService.sendToYnrcc(DlpayUtil.OPTYPE_CHKDTL, req); + } catch (BussinessException be) { + resp.setCode(ErrorCode.BUSSINESS_ERROR); + resp.setMessage(be.getMessage()); + logger.error(resp.errPrint()); + return resp; + } catch (Exception e) { + doSystemError(e, resp); + return resp; + } + } + + +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/service/YnrccApiService.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/service/YnrccApiService.java new file mode 100644 index 00000000..78241a10 --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/service/YnrccApiService.java @@ -0,0 +1,8 @@ +package com.supwisdom.agent.api.service; + +import com.supwisdom.agent.api.bean.DlpayReq; +import com.supwisdom.agent.api.bean.DlpayResp; + +public interface YnrccApiService { + DlpayResp sendToYnrcc(String optype, DlpayReq req) throws Exception; +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/service/YnrccParamCheckService.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/service/YnrccParamCheckService.java new file mode 100644 index 00000000..88b1fa87 --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/service/YnrccParamCheckService.java @@ -0,0 +1,27 @@ +package com.supwisdom.agent.api.service; + +import com.supwisdom.agent.api.bean.DlpayResp; + +import java.util.Map; + +public interface YnrccParamCheckService { + boolean checkBindCardParam(String transcode, String transdate, String transtime, String refno, + String bankcardno, String username, String idtype, String idno, + String phone, String sign_type, String sign, DlpayResp resp); + + boolean checkSign(Map param); + + boolean checkSignCardParam(String transcode, String transdate, String transtime, String refno, String categorie, String bankcardno, String username, + String idtype, String idno, String phone, String transtype, String sign_type, String sign, DlpayResp resp); + + boolean checkCardPayParam(String transcode, String transdate, String transtime, String refno, String categorie, String bankcardno, String username, + String idtype, String idno, String merchant_bankcardno, String merchant_bankaccname, Integer amount, String description, + String sign_type, String sign, DlpayResp resp); + + boolean checkPayRefundParam(String transcode, String transdate, String transtime, String refno, String refundRefno, Integer amount, String description, + String sign_type, String sign, DlpayResp resp); + + boolean checkQueryResultParam(String transcode, String transdate, String transtime, String refno, String orignRefno, String sign_type, String sign, DlpayResp resp); + + boolean checkChkfileParam(String transcode, String transdate, String transtime, String refno, String checkdate, String merchant_bankcardno, String sign_type, String sign, DlpayResp resp); +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/service/impl/YnrccApiServiceImpl.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/service/impl/YnrccApiServiceImpl.java new file mode 100644 index 00000000..3f55da79 --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/service/impl/YnrccApiServiceImpl.java @@ -0,0 +1,81 @@ +package com.supwisdom.agent.api.service.impl; + +import com.supwisdom.agent.Util.BussinessException; +import com.supwisdom.agent.Util.DlpayUtil; +import com.supwisdom.agent.Util.StringUtil; +import com.supwisdom.agent.Util.XmlUtils; +import com.supwisdom.agent.api.bean.DlpayReq; +import com.supwisdom.agent.api.bean.DlpayResp; +import com.supwisdom.agent.api.service.YnrccApiService; +import com.supwisdom.agent.config.YnrccSocketConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class YnrccApiServiceImpl implements YnrccApiService { + @Autowired + private YnrccSocketConfig ynrccSocketConfig; + + private static final Logger logger = LoggerFactory.getLogger(YnrccApiServiceImpl.class); + + @Override + public DlpayResp sendToYnrcc(String optype, DlpayReq req) throws Exception { + String ip = ynrccSocketConfig.getIp(); + Integer port = ynrccSocketConfig.getPort(); + int timeout = ynrccSocketConfig.getTimeout(); + if (StringUtil.isEmpty(ip) || null == port) { + throw new BussinessException("农商行Socket的IP和端口未配置"); + } + + String sendXml = null; + if (DlpayUtil.OPTYPE_BINDCARD.equals(optype)) { + //绑定银行卡 + sendXml = req.getBindCardXml(); + logger.error("请求【绑定银行卡】发送报文:\n" + sendXml); + + } else if (DlpayUtil.OPTYPE_SIGNCARD.equals(optype)) { + sendXml = req.getSignXml(); + logger.error("请求【银行卡签(解)约】发送报文:\n" + sendXml); + + } else if (DlpayUtil.OPTYPE_CARDPAY.equals(optype)) { + sendXml = req.getCardpayXml(); + logger.error("请求【银行卡代扣】发送报文:\n" + sendXml); + + } else if (DlpayUtil.OPTYPE_CARDPAY.equals(optype)) { + sendXml = req.getCardpayXml(); + logger.error("请求【银行卡代扣】发送报文:\n" + sendXml); + + } else if (DlpayUtil.OPTYPE_PAYREFUND.equals(optype)) { + sendXml = req.getPayRefundXml(); + logger.error("请求【代扣消费退款】发送报文:\n" + sendXml); + + } else if (DlpayUtil.OPTYPE_QUERYRESULT.equals(optype)) { + sendXml = req.getQueryResultXml(); + logger.error("请求【消费结果查询】发送报文:\n" + sendXml); + + } else if (DlpayUtil.OPTYPE_CHKDTL.equals(optype)) { + sendXml = req.getChkfileXml(); + logger.error("请求【获取对账单=" + req.getChkdate() + "】发送报文:\n" + sendXml); + + } else { + throw new BussinessException("请求类型[" + optype + "]错误!"); + } + + String returnXml = DlpayUtil.send(ip, port, timeout, sendXml); + logger.error("refno=[" + req.getSn() + "]返回报文:\n" + returnXml); + + if (StringUtil.isEmpty(returnXml)) { + throw new Exception("返回报文为空"); + } + + try { + DlpayResp resp = XmlUtils.getXmlToObject(returnXml, "GBK", DlpayResp.class); + return resp; + } catch (Exception e) { + throw new BussinessException("返回报文解析异常!"); + } + } + +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/service/impl/YnrccParamCheckServiceImpl.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/service/impl/YnrccParamCheckServiceImpl.java new file mode 100644 index 00000000..c490e1be --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/service/impl/YnrccParamCheckServiceImpl.java @@ -0,0 +1,232 @@ +package com.supwisdom.agent.api.service.impl; + +import com.supwisdom.agent.Util.ErrorCode; +import com.supwisdom.agent.Util.MD5; +import com.supwisdom.agent.Util.StringUtil; +import com.supwisdom.agent.api.bean.DlpayResp; +import com.supwisdom.agent.api.service.YnrccParamCheckService; +import com.supwisdom.agent.config.YnrccSocketConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Service +public class YnrccParamCheckServiceImpl implements YnrccParamCheckService { + @Autowired + private YnrccSocketConfig ynrccSocketConfig; + + private static final Logger logger = LoggerFactory.getLogger(YnrccParamCheckServiceImpl.class); + + private boolean checkYnrccBaseParam(String transcode, String transdate, String transtime, String refno, String sign_type, String sign, DlpayResp resp) { + if (StringUtil.isEmpty(transcode)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[报文业务类型为空]"); + return false; + } + if (!StringUtil.checkDatetimeValid(transdate, "yyyyMMdd")) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[交易日期错误]"); + return false; + } + if (!StringUtil.checkDatetimeValid(transtime, "HHmmss")) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[交易时间错误]"); + return false; + } + if (StringUtil.isEmpty(refno)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[业务请求交易流水号为空]"); + return false; + } + + if (StringUtil.isEmpty(sign_type)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[签名方式为空]"); + return false; + } + + if (StringUtil.isEmpty(sign)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[签名为空]"); + return false; + } + + return true; + } + + @Override + public boolean checkBindCardParam(String transcode, String transdate, String transtime, String refno, String bankcardno, String username, String idtype, String idno, String phone, String sign_type, String sign, DlpayResp resp) { + if (!checkYnrccBaseParam(transcode, transdate, transtime, refno, sign_type, sign, resp)) { + return false; + } + if (StringUtil.isEmpty(bankcardno)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[用户银行卡号为空]"); + return false; + } + if (StringUtil.isEmpty(username)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[用户名为空]"); + return false; + } + if (StringUtil.isEmpty(idtype)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[证件类型为空]"); + return false; + } + if (StringUtil.isEmpty(idno)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[证件号为空]"); + return false; + } + if (StringUtil.isEmpty(phone)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[手机号]"); + return false; + } + + return true; + } + + @Override + public boolean checkSign(Map param) { + String sign = param.get("sign"); + String signType = param.get("sign_type"); + if (!StringUtil.isEmpty(sign)) { + String signdata = StringUtil.createLinkString(StringUtil.paraFilter(param)); + logger.info(signdata); + + String calcSign = null; + String md5Key = ynrccSocketConfig.getMd5Key(); + if ("MD5".equalsIgnoreCase(signType)) { + calcSign = MD5.encodeByMD5(signdata + md5Key); //默认MD5 + } + + if (sign.equalsIgnoreCase(calcSign)) { + return true; + } + } + + return false; + } + + @Override + public boolean checkSignCardParam(String transcode, String transdate, String transtime, String refno, String categorie, String bankcardno, String username, + String idtype, String idno, String phone, String transtype, String sign_type, String sign, DlpayResp resp) { + if (!checkBindCardParam(transcode, transdate, transtime, refno, bankcardno, username, idtype, idno, phone, sign_type, sign, resp)) { + return false; + } + if (StringUtil.isEmpty(categorie)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[消费类别]"); + return false; + } + if (StringUtil.isEmpty(transtype)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[签约标志]"); + return false; + } + + return true; + } + + @Override + public boolean checkCardPayParam(String transcode, String transdate, String transtime, String refno, String categorie, String bankcardno, String username, String idtype, String idno, String merchant_bankcardno, String merchant_bankaccname, Integer amount, String description, String sign_type, String sign, DlpayResp resp) { + if (!checkYnrccBaseParam(transcode, transdate, transtime, refno, sign_type, sign, resp)) { + return false; + } + if (StringUtil.isEmpty(categorie)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[消费类别]"); + return false; + } + if (StringUtil.isEmpty(bankcardno)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[用户银行卡号为空]"); + return false; + } + if (StringUtil.isEmpty(username)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[用户名为空]"); + return false; + } +// if(StringUtil.isEmpty(idtype)){ +// resp.setCode(ErrorCode.REQ_PARAM_ERROR); +// resp.setMessage("请求参数错误[证件类型为空]"); +// return false; +// } + + if (StringUtil.isEmpty(idno)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[证件号为空]"); + return false; + } + if (StringUtil.isEmpty(merchant_bankcardno)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[商户银行卡号为空]"); + return false; + } + if (StringUtil.isEmpty(merchant_bankaccname)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[商户银行开户名为空]"); + return false; + } + if (null == amount) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[交易金额为空]"); + return false; + } + + return true; + } + + @Override + public boolean checkPayRefundParam(String transcode, String transdate, String transtime, String refno, String refundRefno, Integer amount, String description, + String sign_type, String sign, DlpayResp resp) { + if (!checkYnrccBaseParam(transcode, transdate, transtime, refno, sign_type, sign, resp)) { + return false; + } + if (StringUtil.isEmpty(refundRefno)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[原交易流水号为空]"); + return false; + } + if (null == amount) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[交易金额为空]"); + return false; + } + return true; + } + + @Override + public boolean checkQueryResultParam(String transcode, String transdate, String transtime, String refno, String orignRefno, String sign_type, String sign, DlpayResp resp) { + if (!checkYnrccBaseParam(transcode, transdate, transtime, refno, sign_type, sign, resp)) { + return false; + } + if (StringUtil.isEmpty(orignRefno)) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[原交易流水号为空]"); + return false; + } + return true; + } + + @Override + public boolean checkChkfileParam(String transcode, String transdate, String transtime, String refno, String checkdate, String merchant_bankcardno, String sign_type, String sign, DlpayResp resp) { + if (!checkYnrccBaseParam(transcode, transdate, transtime, refno, sign_type, sign, resp)) { + return false; + } + + if (StringUtil.checkDatetimeValid(checkdate,"yyyyMMdd")) { + resp.setCode(ErrorCode.REQ_PARAM_ERROR); + resp.setMessage("请求参数错误[对账日期]"); + return false; + } + + return true; + } +} diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/config/YnrccSocketConfig.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/config/YnrccSocketConfig.java new file mode 100644 index 00000000..e11398c7 --- /dev/null +++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/config/YnrccSocketConfig.java @@ -0,0 +1,32 @@ +package com.supwisdom.agent.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class YnrccSocketConfig { + @Value("${ynrcc.socket.ip}") + private String ip; + @Value("${ynrcc.socket.port}") + private Integer port; + @Value("${ynrcc.socket.timeout}") + private int timeout = 10; + @Value("${ynrcc.md5.key}") + private String md5Key; + + public String getIp() { + return ip; + } + + public Integer getPort() { + return port; + } + + public int getTimeout() { + return timeout; + } + + public String getMd5Key() { + return md5Key; + } +} diff --git a/ynrcc-agent/src/main/resources/application.properties b/ynrcc-agent/src/main/resources/application.properties new file mode 100644 index 00000000..167f4ace --- /dev/null +++ b/ynrcc-agent/src/main/resources/application.properties @@ -0,0 +1,36 @@ +#######################################springboot配置 start################################# +#spring.application.name=supwisdom.ynrcc.agent +#spring.cloud.consul.discovery.health-check-path=${management.context-path}/api/common/version +#spring.cloud.consul.discovery.health-check-interval=10s +#spring.cloud.consul.discovery.instanceId=${spring.application.name}:${spring.application.instance_id:${random.value}} +##################### 单库数据库配置 ############################## +#spring.jpa.show-sql=true +#s#pring.datasource.hikari.connection-timeout=60000 +#spring.datasource.hikari.maximum-pool-size=5 +#spring.jpa.hibernate.ddl-auto=update +##################### redis ############################## +#spring.redis.host=172.28.201.101 +#spring.redis.port=16379 +#spring.redis.password=kingstar +#spring.redis.database=0 + +# logging +logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n +logging.level.org.hibernate.SQL=debug +#################### JSP PAGE #################### +server.servlet.context-path=/ynrccagent +################## 全局字符编码设置 ###################### +spring.http.encoding.force=true +spring.http.encoding.charset=UTF-8 +spring.http.encoding.enabled=true +server.tomcat.uri-encoding=UTF-8 +################################################## +## quartz task scheduler +#dayend.settletask.cron = 0 0/2 * * * ? + +############# YNRCC SOCKET ############### +ynrcc.socket.ip=127.0.0.1 +ynrcc.socket.port=8089 +## 超时时间(分钟) +ynrcc.socket.timeout = 10 +ynrcc.md5.key=80816b7947ed016bff8079557735006e