Merge tag '1.0.32' into develop
农商行快捷支付
diff --git a/config/application-devel-pg-xkx.properties b/config/application-devel-pg-xkx.properties
index e03fe08..390649f 100644
--- a/config/application-devel-pg-xkx.properties
+++ b/config/application-devel-pg-xkx.properties
@@ -12,7 +12,12 @@
spring.datasource.password=123456
database.dbtype=postgresql
+# logging settings
+spring.jpa.show-sql = false
logging.level.org.hibernate.SQL=ERROR
+logging.level.com.mascloud=ERROR
+logging.level.root=info
+
# Redis settings
spring.redis.host=localhost
spring.redis.port=6379
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/UserMessageData.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/UserMessageData.java
new file mode 100644
index 0000000..666c677
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/UserMessageData.java
@@ -0,0 +1,20 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class UserMessageData {
+ private String msgid; //tb_msg的id
+ private String content; //tb_msg的content
+ private String lastupdate; //tb_msg的lastupdate
+ private String refno; //tb_msg的refno
+ private String transdesc; //refno对应流水的交易描述
+ private Double amount; //refno对应流水的交易金额
+ private String userid; //tb_msg的userid
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/UserQueryMessageParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/UserQueryMessageParam.java
new file mode 100644
index 0000000..d9a01e3
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/UserQueryMessageParam.java
@@ -0,0 +1,28 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotEmpty;
+
+@Getter
+@Setter
+public class UserQueryMessageParam extends APIRequestParam {
+ @Sign
+ @NotEmpty(message = "用户ID不能为空")
+ private String userid;
+
+ @Sign
+ private Integer pageNo; //可以为空,默认1
+
+ @Sign
+ private Integer pageSize; //可以为空,默认10
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ return true;
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/UserQueryMessageResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/UserQueryMessageResponse.java
new file mode 100644
index 0000000..b5e4028
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/UserQueryMessageResponse.java
@@ -0,0 +1,20 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class UserQueryMessageResponse extends ApiResponse {
+ private int pageNo = 1;
+ private int pageSize = 10;
+ private int totalCount = 0;
+ private int totalPages = 0;
+ private List<UserMessageData> data;
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayConfirmParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayConfirmParam.java
new file mode 100644
index 0000000..0b5851f
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayConfirmParam.java
@@ -0,0 +1,31 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Getter
+@Setter
+public class YnrccPayConfirmParam extends APIRequestParam {
+ @Sign
+ @NotBlank(message = "交易参考号不能为空")
+ private String refno;
+
+ @Sign
+ @NotBlank(message = "参数Plain不能为空")
+ private String plain; //农商行快捷支付参数
+
+ @Sign
+ @NotBlank(message = "参数Signature不能为空")
+ private String signature; //农商行快捷支付参数
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ return true;
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayConfirmResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayConfirmResponse.java
new file mode 100644
index 0000000..a9241c4
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayConfirmResponse.java
@@ -0,0 +1,18 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.*;
+
+import java.util.Map;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString
+public class YnrccPayConfirmResponse extends ApiResponse {
+ private String refno;
+ private String billno;
+ private Double amount;
+
+ private Map<String, String> data; //农商行快捷支付返回字段
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayLimitModifyParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayLimitModifyParam.java
new file mode 100644
index 0000000..bd6e000
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayLimitModifyParam.java
@@ -0,0 +1,40 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+
+@Getter
+@Setter
+public class YnrccPayLimitModifyParam extends APIRequestParam {
+ @Sign
+ @NotBlank(message = "用户ID不能为空")
+ private String userid;
+
+ @Sign
+ @NotBlank(message = "银行卡号不能为空")
+ private String bankcardno;
+
+ @Sign
+ @NotBlank(message = "签约商户不能为空")
+ private String shopaccno;
+
+ @Sign
+ @Min(value = 0L, message = "错误的单次限额")
+ private Integer singlelimit; //单次限额。单位:分
+
+ @Sign
+ @Min(value = 0L, message = "错误的单日限额")
+ private Integer daylimit; //日限额。单位:分
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ return true;
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayLimitModifyResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayLimitModifyResponse.java
new file mode 100644
index 0000000..04607b4
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayLimitModifyResponse.java
@@ -0,0 +1,13 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.*;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString
+public class YnrccPayLimitModifyResponse extends ApiResponse {
+ private Integer singlelimit; //单次限额。单位:分
+ private Integer daylimit; //日限额。单位:分
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayOrderParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayOrderParam.java
new file mode 100644
index 0000000..a497a13
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayOrderParam.java
@@ -0,0 +1,57 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import com.supwisdom.dlpay.api.util.DateUtil;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Positive;
+
+@Getter
+@Setter
+public class YnrccPayOrderParam extends APIRequestParam {
+ @Sign
+ @NotBlank(message = "用户唯一号不能为空")
+ private String userid; //用户userid
+
+ @Sign
+ @NotBlank(message = "银行卡号不能为空")
+ private String bankcardno;
+
+ @Sign
+ @NotBlank(message = "对接系统唯一订单号不能为空")
+ private String billno;
+
+ @Sign
+ @NotNull(message = "交易金额不能为空")
+ @Positive(message = "交易金额必须大于零")
+ private Integer amount;
+
+ @Sign
+ @NotBlank(message = "请指定交易商户")
+ private String shopaccno;
+
+ @Sign
+ @NotBlank(message = "交易日期不能为空")
+ private String transdate;
+ @Sign
+ @NotBlank(message = "交易时间不能为空")
+ private String transtime;
+
+ @Sign
+ @NotBlank(message = "流水类型不能为空")
+ private String dtltype;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT))
+ throw new RequestParamCheckException("交易日期错误[yyyyMMdd]");
+ if (!DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT))
+ throw new RequestParamCheckException("交易时间错误[HHmmss]");
+ return true;
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayOrderResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayOrderResponse.java
new file mode 100644
index 0000000..c93e2cc
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayOrderResponse.java
@@ -0,0 +1,18 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.*;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString
+public class YnrccPayOrderResponse extends ApiResponse {
+ private String refno; //核心平台流水号
+ private String billno; //订单号
+ private Double amount; //支付金额
+
+ //农商行快捷支付参数
+ private String plain;
+ private String signature;
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayRefundParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayRefundParam.java
new file mode 100644
index 0000000..73095ce
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayRefundParam.java
@@ -0,0 +1,52 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import com.supwisdom.dlpay.api.util.DateUtil;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Getter
+@Setter
+public class YnrccPayRefundParam extends APIRequestParam {
+ @Sign
+ private String refno;
+ @Sign
+ private String billno;
+ @Sign
+ private String shopaccno;
+
+ @Sign
+ @Min(value = 0L, message = "错误的退款金额")
+ private Integer refundAmount;
+
+ @Sign
+ @NotBlank(message = "撤销或退款流水号不能为空")
+ private String requestbillno;
+ @Sign
+ @NotBlank(message = "交易日期不能为空")
+ private String transdate;
+ @Sign
+ @NotBlank(message = "交易时间不能为空")
+ private String transtime;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ if (StringUtils.isEmpty(refno) && (StringUtils.isEmpty(billno) || StringUtils.isEmpty(shopaccno))) {
+ throw new RequestParamCheckException("原流水唯一号不能为空");
+ }
+ if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT)) {
+ throw new RequestParamCheckException("交易日期错误[yyyyMMdd]");
+ }
+ if (!DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT)) {
+ throw new RequestParamCheckException("交易时间错误[HHmmss]");
+ }
+ return true;
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayRefundResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayRefundResponse.java
new file mode 100644
index 0000000..975abde
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayRefundResponse.java
@@ -0,0 +1,14 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class YnrccPayRefundResponse extends ApiResponse {
+ private String refundRefno; //退款流水号
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignApplyParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignApplyParam.java
new file mode 100644
index 0000000..da80b3a
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignApplyParam.java
@@ -0,0 +1,31 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+
+@Getter
+@Setter
+public class YnrccPaySignApplyParam extends APIRequestParam {
+ @Sign
+ @NotBlank(message = "用户ID不能为空")
+ private String userid;
+
+ @Sign
+ @NotBlank(message = "银行卡号不能为空")
+ private String bankcardno;
+
+ @Sign
+ @NotBlank(message = "签约商户不能为空")
+ private String shopaccno;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ return true;
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignApplyResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignApplyResponse.java
new file mode 100644
index 0000000..4d43405
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignApplyResponse.java
@@ -0,0 +1,20 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class YnrccPaySignApplyResponse extends ApiResponse {
+ private String signNo; //签约号
+ private boolean authSign = false; //是否授权签约
+
+ //农商行快捷支付参数
+ private String plain;
+ private String signature;
+ private YnrccPaySignUserData signUserData;
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignCancelParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignCancelParam.java
new file mode 100644
index 0000000..9d83baf
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignCancelParam.java
@@ -0,0 +1,31 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+
+@Getter
+@Setter
+public class YnrccPaySignCancelParam extends APIRequestParam {
+ @Sign
+ @NotBlank(message = "用户ID不能为空")
+ private String userid;
+
+ @Sign
+ @NotBlank(message = "银行卡号不能为空")
+ private String bankcardno;
+
+ @Sign
+ @NotBlank(message = "签约商户不能为空")
+ private String shopaccno;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ return true;
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignCancelResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignCancelResponse.java
new file mode 100644
index 0000000..2911c4e
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignCancelResponse.java
@@ -0,0 +1,12 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.*;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString
+public class YnrccPaySignCancelResponse extends ApiResponse {
+ private String signNo; //签约号
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignConfirmParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignConfirmParam.java
new file mode 100644
index 0000000..aa85cb6
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignConfirmParam.java
@@ -0,0 +1,32 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+@Getter
+@Setter
+public class YnrccPaySignConfirmParam extends APIRequestParam {
+ @Sign
+ @NotBlank(message = "签约号不能为空")
+ private String signNo; //申请时返回的签约号
+
+ @Sign
+ @NotBlank(message = "参数Plain不能为空")
+ private String plain; //农商行快捷支付参数
+
+ @Sign
+ @NotBlank(message = "参数Signature不能为空")
+ private String signature; //农商行快捷支付参数
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ return true;
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignConfirmResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignConfirmResponse.java
new file mode 100644
index 0000000..dfc871c
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignConfirmResponse.java
@@ -0,0 +1,16 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.*;
+
+import java.util.Map;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+public class YnrccPaySignConfirmResponse extends ApiResponse {
+ private String signNo;
+
+ private Map<String, String> data; //农商行快捷支付返回字段
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignInfo.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignInfo.java
new file mode 100644
index 0000000..785d556
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignInfo.java
@@ -0,0 +1,19 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class YnrccPaySignInfo {
+ private String signNo; //申请时返回的签约号
+ private String bankcardno; //签约银行卡号
+ private String shopaccno; //核心平台商户账号
+ private String shopname; //核心平台商户名称
+ private String signtime; //签约时间 yyyyMMddHHmmss
+ private String userid; //核心平台用户ID
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignListQueryParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignListQueryParam.java
new file mode 100644
index 0000000..3a923d9
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignListQueryParam.java
@@ -0,0 +1,26 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.commons.lang3.StringUtils;
+
+@Getter
+@Setter
+public class YnrccPaySignListQueryParam extends APIRequestParam {
+ @Sign
+ private String userid; //可二选一
+
+ @Sign
+ private String bankcardno; //可二选一
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ if (StringUtils.isEmpty(userid) && StringUtils.isEmpty(bankcardno)) {
+ throw new RequestParamCheckException("未指定要查询的签约用户!");
+ }
+ return true;
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignListQueryResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignListQueryResponse.java
new file mode 100644
index 0000000..526f979
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignListQueryResponse.java
@@ -0,0 +1,14 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.*;
+
+import java.util.List;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+public class YnrccPaySignListQueryResponse extends ApiResponse {
+ private List<YnrccPaySignInfo> data;
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignQueryParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignQueryParam.java
new file mode 100644
index 0000000..d18e016
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignQueryParam.java
@@ -0,0 +1,31 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+
+@Getter
+@Setter
+public class YnrccPaySignQueryParam extends APIRequestParam {
+ @Sign
+ @NotBlank(message = "用户ID不能为空")
+ private String userid;
+
+ @Sign
+ @NotBlank(message = "银行卡号不能为空")
+ private String bankcardno;
+
+ @Sign
+ @NotBlank(message = "签约商户不能为空")
+ private String shopaccno;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ return true;
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignQueryResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignQueryResponse.java
new file mode 100644
index 0000000..e3a30fa
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignQueryResponse.java
@@ -0,0 +1,12 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.*;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+public class YnrccPaySignQueryResponse extends ApiResponse {
+ private boolean signFlag = false; //是否已签约,默认:否
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignUserData.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignUserData.java
new file mode 100644
index 0000000..0ff52b8
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPaySignUserData.java
@@ -0,0 +1,17 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class YnrccPaySignUserData {
+ private String name; //姓名
+ private String idType; //证件类型
+ private String idNo; //证件号码
+ private String acNo; //支付账号
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayThirdAuthParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayThirdAuthParam.java
new file mode 100644
index 0000000..5f225e4
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayThirdAuthParam.java
@@ -0,0 +1,30 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.Sign;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+
+@Getter
+@Setter
+public class YnrccPayThirdAuthParam extends APIRequestParam {
+ @Sign
+ @NotBlank(message = "第三方服务标识不能为空")
+ private String thirdservice;
+
+ @Sign
+ @NotBlank(message = "用户ID不能为空")
+ private String userid;
+
+ @Sign
+ @NotBlank(message = "银行卡号不能为空")
+ private String bankcardno;
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ return true;
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayThirdAuthResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayThirdAuthResponse.java
new file mode 100644
index 0000000..fce24e5
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayThirdAuthResponse.java
@@ -0,0 +1,15 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.*;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+public class YnrccPayThirdAuthResponse extends ApiResponse{
+ private String thirdService;
+ private YnrccPayThirdAuthUser user;
+ private String sdkConfigData;
+ private String access2ServiceData;
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayThirdAuthUser.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayThirdAuthUser.java
new file mode 100644
index 0000000..75c2245
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/YnrccPayThirdAuthUser.java
@@ -0,0 +1,17 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+public class YnrccPayThirdAuthUser {
+ private String name; //姓名
+ private String idNo; //证件号
+ private String phone; //手机号
+ private String acNo; //银行卡号
+}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ConsumePropxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ConsumePropxy.java
index 62584f7..9eb32fb 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ConsumePropxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ConsumePropxy.java
@@ -24,4 +24,16 @@
@PostMapping("/qrcodequery")
DoorQrcodeResponse qrcodequery(@RequestBody DoorQRCodeParam param);
+
+ @PostMapping("/ynrccpay/order")
+ YnrccPayOrderResponse ynrccPayOrder(@RequestBody YnrccPayOrderParam param);
+
+ @PostMapping("/ynrccpay/confirm")
+ YnrccPayConfirmResponse ynrccPayConfirm(@RequestBody YnrccPayConfirmParam param);
+
+ @PostMapping("/ynrccpay/refund")
+ YnrccPayRefundResponse ynrccPayRefund(@RequestBody YnrccPayRefundParam param);
+
+ @PostMapping("/ynrccpay/thirdAuth")
+ YnrccPayThirdAuthResponse ynrccPayThirdAuth(@RequestBody YnrccPayThirdAuthParam param);
}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/TransactionProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/TransactionProxy.java
index 570587a..5d6be32 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/TransactionProxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/TransactionProxy.java
@@ -15,4 +15,7 @@
@PostMapping("/api/consume/queryresult")
QueryTransDtlResponse queryDtlResult(@RequestBody QueryDtlResultParam param);
+
+ @PostMapping("/api/consume/thirdquery")
+ QueryTransDtlResponse queryDtlResultByThird(@RequestBody QueryDtlResultParam param);
}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/UserProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/UserProxy.java
index 341b604..13c5018 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/UserProxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/UserProxy.java
@@ -91,4 +91,25 @@
@PostMapping("/api/user/queryCitizenCard")
DoorQrcodeResponse queryCitizenCard(@RequestParam("uid") String uid);
+
+ @PostMapping("/api/user/ynrccpaySignQuery")
+ YnrccPaySignQueryResponse queryYnrccPaySign(@RequestBody YnrccPaySignQueryParam param);
+
+ @PostMapping("/api/user/ynrccpaySignApply")
+ YnrccPaySignApplyResponse applyYnrccPaySign(@RequestBody YnrccPaySignApplyParam param);
+
+ @PostMapping("/api/user/ynrccpaySignConfirm")
+ YnrccPaySignConfirmResponse confirmYnrccPaySign(@RequestBody YnrccPaySignConfirmParam param);
+
+ @PostMapping("/api/user/ynrccpaySignCancel")
+ YnrccPaySignCancelResponse cancelYnrccPaySign(@RequestBody YnrccPaySignCancelParam param);
+
+ @PostMapping("/api/user/ynrccpayModifyLimit")
+ YnrccPayLimitModifyResponse modifyYnrccPayLimit(@RequestBody YnrccPayLimitModifyParam param);
+
+ @PostMapping("/api/user/queryMessage")
+ UserQueryMessageResponse queryUserMessage(@RequestBody UserQueryMessageParam param);
+
+ @PostMapping("/api/user/ynrccpaySignList")
+ YnrccPaySignListQueryResponse queryYnrccPaySignList(@RequestBody YnrccPaySignListQueryParam param);
}
diff --git a/payapi/build.gradle b/payapi/build.gradle
index d7eb36a..c6061a2 100644
--- a/payapi/build.gradle
+++ b/payapi/build.gradle
@@ -115,6 +115,11 @@
// implementation files('libs/ojdbc6.jar')
implementation 'commons-dbcp:commons-dbcp:1.4'
implementation 'commons-beanutils:commons-beanutils:1.9.3'
+ implementation files('libs/ynrcc-openapi-sdk-1.1.2-RELEASE.jar')
+
+ //大理农商行sdk需求jar
+ implementation 'cn.hutool:hutool-crypto:5.4.7'
+ implementation 'org.bouncycastle:bcprov-jdk15on:1.64'
implementation 'log4j:log4j:1.2.17'
implementation 'com.alibaba:fastjson:1.2.60'
diff --git a/payapi/libs/ynrcc-openapi-sdk-1.1.2-RELEASE.jar b/payapi/libs/ynrcc-openapi-sdk-1.1.2-RELEASE.jar
new file mode 100644
index 0000000..c3d54ee
--- /dev/null
+++ b/payapi/libs/ynrcc-openapi-sdk-1.1.2-RELEASE.jar
Binary files differ
diff --git a/payapi/sql/update-210106.sql b/payapi/sql/update-210106.sql
new file mode 100644
index 0000000..513f317
--- /dev/null
+++ b/payapi/sql/update-210106.sql
@@ -0,0 +1,58 @@
+-- 农商行网关支付
+INSERT INTO "tb_sourcetype" ("sourcetype_id", "sourcetype", "checkable", "paydesc", "enable", "charge_enable", "consume_enable", "anonymous_enable", "reversable", "pay_subjno", "deposite_subjno", "tplusn", "start_chktime", "tenantid")
+VALUES ('B837FFDD20C0CA07E05011AC03000113', 'ynrccpay', 't', '农商行网关支付', 't', 'f', 't', 'f', 't', '112235', '-', 1, null, '{tenantid}');
+commit;
+
+--新加农商行支付款
+INSERT INTO "tb_subject" ("subjid","subjno", "balflag", "displayflag", "endflag", "fsubjno", "opendate", "subjlevel", "subjname", "subjtype", "tenantid")
+VALUES (33, '112235', 1, 'y', 1, '1122', '20210106', 2, '农商行支付款', 1, '{tenantid}');
+commit;
+
+-- ----------------------------
+-- Table structure for tb_ynrccpay_sign
+-- ----------------------------
+CREATE TABLE tb_ynrccpay_sign (
+ id varchar(32) NOT NULL,
+ bankcardno varchar(32) NOT NULL,
+ shopaccno varchar(10) NOT NULL,
+ userid varchar(32) NOT NULL,
+ status varchar(10) NOT NULL,
+ sign_flag bool NOT NULL,
+ customer_sign_no varchar(60),
+ sign_time varchar(14),
+ cancel_time varchar(14),
+ remark varchar(600),
+ createtime varchar(14)
+);
+ALTER TABLE tb_ynrccpay_sign ADD CONSTRAINT tb_ynrccpay_sign_pkey PRIMARY KEY (id);
+CREATE INDEX idx1_ynrccpay_sign ON tb_ynrccpay_sign(bankcardno,shopaccno,status);
+
+INSERT INTO "tb_transcode" ("transcode_id", "transcode", "transname", "tenantid")
+VALUES (4, 3050, '农商行网关快捷支付', '{tenantid}');
+commit;
+
+
+INSERT INTO "public"."tb_sourcetype_config"("id", "config_name", "config_value", "configid", "globalflag", "sourcetype", "tenantid") VALUES ('26', '农商行网关支付商户号', NULL, 'ynrcc.netpay.Mer_Id', 'f', 'ynrccpay', '{tenantid}');
+INSERT INTO "public"."tb_sourcetype_config"("id", "config_name", "config_value", "configid", "globalflag", "sourcetype", "tenantid") VALUES ('27', '农商行网关支付商户名', NULL, 'ynrcc.netpay.Mer_IdName', 'f', 'ynrccpay', '{tenantid}');
+INSERT INTO "public"."tb_sourcetype_config"("id", "config_name", "config_value", "configid", "globalflag", "sourcetype", "tenantid") VALUES ('28', '农商行网关支付回调地址', NULL, 'ynrcc.netpay.MerURL', 'f', 'ynrccpay', '{tenantid}');
+INSERT INTO "public"."tb_sourcetype_config"("id", "config_name", "config_value", "configid", "globalflag", "sourcetype", "tenantid") VALUES ('25', '农商行网关支付地址', 'https://ebank.ynrcc.com/pweb/%s?LoginType=C&_locale=zh_CN&BankId=9999', 'ynrcc.netpay.URL', 't', 'ynrccpay', '{tenantid}');
+commit;
+
+CREATE TABLE tb_ynrccpay_thirdapp (
+ id varchar(32) NOT NULL,
+ mch_id varchar(20) NOT NULL,
+ mch_name varchar(200),
+ app_id varchar(60) NOT NULL,
+ token varchar(20) NOT NULL,
+ pubkey varchar(200) NOT NULL,
+ enable bool NOT NULL,
+ remark varchar(200)
+);
+ALTER TABLE tb_ynrccpay_thirdapp ADD CONSTRAINT tb_ynrccpay_thirdapp_pkey PRIMARY KEY (id);
+
+-- 测试环境或正式环境插入相应配置
+INSERT INTO "public"."tb_ynrccpay_thirdapp"("id", "mch_id", "mch_name", "app_id", "token", "pubkey", "enable", "remark")
+VALUES ('test', '1002010472001', '大理市信息化发展有限责任公司', '318D34955996AA035F3047939EA655FF', 'J6upjifWdQfRj3eh', '043AAF09775EC7EEEAAA2C66773F61BF18CE4D2DDDCBFFF43249113D849AD3FF4F8951889E8BF759EC80AF2EEA7473F9FEE97A7DE0B284FFD3312BD5021061F172', 't', '测试环境配置');
+--INSERT INTO "public"."tb_ynrccpay_thirdapp"("id", "mch_id", "mch_name", "app_id", "token", "pubkey", "enable", "remark")
+--VALUES ('dev', '1002010472001', '大理市信息化发展有限责任公司', '5FE60D156754432BAC1789AF35EEA592', 'Cg3Ue7mdkWv9g5mK', '0484D7043D24F3AC19E3F7CA03A166C2F813BCFE2141CB0E8559214A23E7A8DFDC9B4C1E9D9FBE9456621373652B145DDB91BD6DD484E8F04870560E7A16F5AB2C', 't', '生产环境配置');
+commit;
\ No newline at end of file
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentResponse.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentResponse.java
index 149c3ae..caa0ce4 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentResponse.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentResponse.java
@@ -1,5 +1,7 @@
package com.supwisdom.dlpay.agent;
+import java.util.Map;
+
public class AgentResponse<T> {
public static final String AGENTCODE_SUCCESS = "0";
@@ -13,6 +15,7 @@
private DtlStatus dtlStatus;
private T payload;
+ private Map<String,String> params;
public String getAgentBody() {
return agentBody;
@@ -70,6 +73,14 @@
this.payload = payload;
}
+ public Map<String, String> getParams() {
+ return params;
+ }
+
+ public void setParams(Map<String, String> params) {
+ this.params = params;
+ }
+
public AgentResponse() {
}
}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/ConcatUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/ConcatUtil.java
new file mode 100644
index 0000000..1315114
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/ConcatUtil.java
@@ -0,0 +1,30 @@
+package com.supwisdom.dlpay.agent.ynrccpay;
+
+public class ConcatUtil {
+ private String delimiter;
+ private StringBuilder builder;
+
+ public ConcatUtil(String delimiter) {
+ if (delimiter == null) {
+ throw new RuntimeException("Delimiter must not be null");
+ }
+ this.delimiter = delimiter;
+ builder = new StringBuilder();
+ }
+
+ public ConcatUtil add(String field) {
+ if (field == null) {
+ throw new RuntimeException("added value must not be null");
+ }
+ if (builder.length() > 0) {
+ builder.append(this.delimiter);
+ }
+ builder.append(field);
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return builder.toString();
+ }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayChkfile.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayChkfile.java
new file mode 100644
index 0000000..1690847
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayChkfile.java
@@ -0,0 +1,138 @@
+package com.supwisdom.dlpay.agent.ynrccpay;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 农商行快捷支付对账单
+ * 4
+ * ZF01|20210308|20201225161726|20210308151427000066|5607894487|10020104721000000001||0.01|156|0|0.01||20201225161726000115
+ * ZF01|20210308|20210308161616|20210308140757000064|5607894462|10020104721000000001||0.01|156|0|0.01||20210113170353000126
+ * ZF01|20210308|20210308181818|20210308150900000065|5607894483|10020104721000000001||0.01|156|0|0.01||20201225110202000098
+ * ZF02|20210308|20210308152004|114075700006420210308152004|20210308140757000064|10020104721000000001||0.01|156|0|0.01||
+ * */
+public class YnrccPayChkfile {
+
+ private String payFlag; //交易代码:ZF01-支付;ZF02-退款
+ private String clearDate; //清算日期
+ private String transDateTime; //交易时间 yyyyMMddHHmmss
+ private String billNo; //商户订单号
+ private String agentRefno; //银行流水号
+ private String merchantNo; //商户号
+ private String termNo; //终端号
+ private String amount; //交易金额,单位:元
+ private String currencyType; //币种 156-人民币
+ private String feeAmount; //手续费,单位:元
+ private String diffAmount; //交易金额与手续费金额的差值(交易金额-手续费金额),单位:元
+ private String remark1; //备注1
+ private String remark2; //备注2
+
+ public static final String PAY = "ZF01";
+ public static final String REFUND = "ZF02";
+ public static final List<String> HEADER = Arrays.asList("payFlag", "clearDate", "transDateTime", "billNo", "agentRefno",
+ "merchantNo", "termNo", "amount", "currencyType", "feeAmount", "diffAmount", "remark1", "remark2");
+
+ public String getPayFlag() {
+ return payFlag;
+ }
+
+ public void setPayFlag(String payFlag) {
+ this.payFlag = payFlag;
+ }
+
+ public String getClearDate() {
+ return clearDate;
+ }
+
+ public void setClearDate(String clearDate) {
+ this.clearDate = clearDate;
+ }
+
+ public String getTransDateTime() {
+ return transDateTime;
+ }
+
+ public void setTransDateTime(String transDateTime) {
+ this.transDateTime = transDateTime;
+ }
+
+ public String getBillNo() {
+ return billNo;
+ }
+
+ public void setBillNo(String billNo) {
+ this.billNo = billNo;
+ }
+
+ public String getAgentRefno() {
+ return agentRefno;
+ }
+
+ public void setAgentRefno(String agentRefno) {
+ this.agentRefno = agentRefno;
+ }
+
+ public String getMerchantNo() {
+ return merchantNo;
+ }
+
+ public void setMerchantNo(String merchantNo) {
+ this.merchantNo = merchantNo;
+ }
+
+ public String getTermNo() {
+ return termNo;
+ }
+
+ public void setTermNo(String termNo) {
+ this.termNo = termNo;
+ }
+
+ public String getAmount() {
+ return amount;
+ }
+
+ public void setAmount(String amount) {
+ this.amount = amount;
+ }
+
+ public String getCurrencyType() {
+ return currencyType;
+ }
+
+ public void setCurrencyType(String currencyType) {
+ this.currencyType = currencyType;
+ }
+
+ public String getFeeAmount() {
+ return feeAmount;
+ }
+
+ public void setFeeAmount(String feeAmount) {
+ this.feeAmount = feeAmount;
+ }
+
+ public String getDiffAmount() {
+ return diffAmount;
+ }
+
+ public void setDiffAmount(String diffAmount) {
+ this.diffAmount = diffAmount;
+ }
+
+ public String getRemark1() {
+ return remark1;
+ }
+
+ public void setRemark1(String remark1) {
+ this.remark1 = remark1;
+ }
+
+ public String getRemark2() {
+ return remark2;
+ }
+
+ public void setRemark2(String remark2) {
+ this.remark2 = remark2;
+ }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayCommonResp.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayCommonResp.java
new file mode 100644
index 0000000..8c9f27d
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayCommonResp.java
@@ -0,0 +1,22 @@
+package com.supwisdom.dlpay.agent.ynrccpay;
+
+public class YnrccPayCommonResp {
+ private String Plain;
+ private String Signature;
+
+ public String getPlain() {
+ return Plain;
+ }
+
+ public void setPlain(String plain) {
+ Plain = plain;
+ }
+
+ public String getSignature() {
+ return Signature;
+ }
+
+ public void setSignature(String signature) {
+ Signature = signature;
+ }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayResp.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayResp.java
new file mode 100644
index 0000000..71f9200
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayResp.java
@@ -0,0 +1,185 @@
+package com.supwisdom.dlpay.agent.ynrccpay;
+
+public class YnrccPayResp {
+ private String code; //ZF0000 表示成功
+ private String message;
+
+ private String plain;
+ private String signature;
+
+ private String TransId;
+ private String Mer_Id;
+ private String TransSeqNo;
+
+ //退款
+ private String OrgTransAmt;
+ private String TransAmount;
+ private String MerchantSeqNo;
+
+ //查询
+ private String OrgTransId; //ZF01 - 支付; ZF02 - 退货
+ private String OrderNo; //订单号
+ private String Amount; //交易金额
+ private String Amount1; //已退货金额
+ private String FeeAmt; //手续费金额
+ private String CurrencyType; //币种
+ private String PpDateTime; //支付系统交易时间
+ private String ClearingDate; //清算日期
+ private String TransStatus; //交易状态 00 - 交易成功; 01 - 交易失败; 02 - 撤消成功; 03 - 部分退货; 04 - 全部退货; 99 - 交易超时
+
+ public String error() {
+ return "code=[" + this.code + "],message=[" + this.message + "]";
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getPlain() {
+ return plain;
+ }
+
+ public void setPlain(String plain) {
+ this.plain = plain;
+ }
+
+ public String getSignature() {
+ return signature;
+ }
+
+ public void setSignature(String signature) {
+ this.signature = signature;
+ }
+
+ public String getTransId() {
+ return TransId;
+ }
+
+ public void setTransId(String transId) {
+ TransId = transId;
+ }
+
+ public String getMer_Id() {
+ return Mer_Id;
+ }
+
+ public void setMer_Id(String mer_Id) {
+ Mer_Id = mer_Id;
+ }
+
+ public String getTransSeqNo() {
+ return TransSeqNo;
+ }
+
+ public void setTransSeqNo(String transSeqNo) {
+ TransSeqNo = transSeqNo;
+ }
+
+ public String getTransStatus() {
+ return TransStatus;
+ }
+
+ public void setTransStatus(String transStatus) {
+ TransStatus = transStatus;
+ }
+
+ public String getOrgTransAmt() {
+ return OrgTransAmt;
+ }
+
+ public void setOrgTransAmt(String orgTransAmt) {
+ OrgTransAmt = orgTransAmt;
+ }
+
+ public String getTransAmount() {
+ return TransAmount;
+ }
+
+ public void setTransAmount(String transAmount) {
+ TransAmount = transAmount;
+ }
+
+ public String getMerchantSeqNo() {
+ return MerchantSeqNo;
+ }
+
+ public void setMerchantSeqNo(String merchantSeqNo) {
+ MerchantSeqNo = merchantSeqNo;
+ }
+
+ public String getOrgTransId() {
+ return OrgTransId;
+ }
+
+ public void setOrgTransId(String orgTransId) {
+ OrgTransId = orgTransId;
+ }
+
+ public String getOrderNo() {
+ return OrderNo;
+ }
+
+ public void setOrderNo(String orderNo) {
+ OrderNo = orderNo;
+ }
+
+ public String getAmount() {
+ return Amount;
+ }
+
+ public void setAmount(String amount) {
+ Amount = amount;
+ }
+
+ public String getAmount1() {
+ return Amount1;
+ }
+
+ public void setAmount1(String amount1) {
+ Amount1 = amount1;
+ }
+
+ public String getFeeAmt() {
+ return FeeAmt;
+ }
+
+ public void setFeeAmt(String feeAmt) {
+ FeeAmt = feeAmt;
+ }
+
+ public String getCurrencyType() {
+ return CurrencyType;
+ }
+
+ public void setCurrencyType(String currencyType) {
+ CurrencyType = currencyType;
+ }
+
+ public String getPpDateTime() {
+ return PpDateTime;
+ }
+
+ public void setPpDateTime(String ppDateTime) {
+ PpDateTime = ppDateTime;
+ }
+
+ public String getClearingDate() {
+ return ClearingDate;
+ }
+
+ public void setClearingDate(String clearingDate) {
+ ClearingDate = clearingDate;
+ }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayUtil.java
new file mode 100644
index 0000000..ce51759
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayUtil.java
@@ -0,0 +1,89 @@
+package com.supwisdom.dlpay.agent.ynrccpay;
+
+
+import com.google.gson.Gson;
+import com.supwisdom.dlpay.agent.AgentCode;
+import com.supwisdom.dlpay.agent.citizencard.YnrccRespCode;
+import org.springframework.data.util.Pair;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class YnrccPayUtil {
+ public static final String GATEWAY = "ynrcc.netpay.URL";
+ public static final String MER_ID = "ynrcc.netpay.Mer_Id";
+ public static final String MER_NAME = "ynrcc.netpay.Mer_IdName";
+ public static final String MER_URL = "ynrcc.netpay.MerURL";
+
+ public static final String chkFileDelimiter = "|";
+ public static final String SUCCESS = "ZF0000";
+ public static final String WAIT_FOR_QUERY = "ZF0098"; //等待查询结果
+ public static final String NO_RECORDS_TODAY = "ZF0101"; //当日无交易明细
+
+
+ public static String toJson(Object obj) {
+ if (null == obj) return "";
+ Gson gson = new Gson();
+ return gson.toJson(obj);
+ }
+
+ public static final List<Pair<AgentCode, YnrccRespCode>> errcode = new ArrayList<>(0);
+
+ static {
+ errcode.add(Pair.of(AgentCode.SUCCESS, new YnrccRespCode("ZF0000", "交易成功")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0001", "本机构无权查看机构的信息")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0003", "无效商户")));
+ errcode.add(Pair.of(AgentCode.SERVER_INTERNAL_ERROR, new YnrccRespCode("ZF0006", "网络不通")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0012", "无效交易")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0013", "无效金额")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0014", "无效卡号")));
+ errcode.add(Pair.of(AgentCode.REFNO_NOT_EXISTS, new YnrccRespCode("ZF0020", "原订单信息不存在")));
+ errcode.add(Pair.of(AgentCode.SERVER_INTERNAL_ERROR, new YnrccRespCode("ZF0022", "交易异常")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0030", "终端上送数据格式错")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0041", "账号被冻结或挂失")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0042", "无此帐户")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0048", "该客户号已关闭快速支付")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0049", "签约已撤消或冻结")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0050", "没有签约协议支付")));
+ errcode.add(Pair.of(AgentCode.SHORT_OF_BALANCE, new YnrccRespCode("ZF0051", "余额不足")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0055", "密码错误")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0058", "不允许商户进行的交易")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0061", "超出商户金额限制")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0062", "退货金额超限")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0063", "上笔交易正在处理中,现交易被拒绝")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0064", "原始交易金额不匹配")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0065", "超出取款限制次数")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0067", "不允许多次退货")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0075", "超出密码输入次数")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0077", "商户状态错误")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0082", "卡号已经被注销了")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0084", "账号不存在")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0085", "银联支付号被注销了")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0086", "身份证号不匹配")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0087", "无效证件号码")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0088", "简单密码")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0092", "上笔交易正在处理中")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0093", "违法交易,无法完成")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0094", "重复交易")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0096", "系统内部错")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0097", "无效终端,柜员号不存在")));
+ errcode.add(Pair.of(AgentCode.REQUIRE_QUERY, new YnrccRespCode("ZF0098", "交易超时,请查询")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0099", "支付密码不允许为空")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF00EI", "找不到机构号")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF00EB", "(商户)机构设置错误")));
+
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF00A0", "成功接收订单")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF00A1", "支付方取消订单")));
+ errcode.add(Pair.of(AgentCode.REFNO_NOT_EXISTS, new YnrccRespCode("ZF0101", "无相关数据")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0214", "平台已冻结或已注销")));
+
+ //自定义错误 ZExxxx
+ errcode.add(Pair.of(AgentCode.CONFIG_ERROR, new YnrccRespCode("ZE0001", "系统参数未配置")));
+ errcode.add(Pair.of(AgentCode.COMMON_ERROR, new YnrccRespCode("ZE0002", "签名计算错误")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZE0097", "请求农商行网关快捷支付返回数据有误")));
+ errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZE0098", "请求农商行网关快捷支付返回数据为空")));
+ errcode.add(Pair.of(AgentCode.SERVER_INTERNAL_ERROR, new YnrccRespCode("ZE0099", "请求农商行网关快捷支付httpStatus非200")));
+ }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/CardDao.java b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/CardDao.java
index 4b3ace3..dfe5630 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/CardDao.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/CardDao.java
@@ -32,4 +32,10 @@
List<TCard> findCitizencardByCardphyidWithoutOldId(String cardphyid, String oldId);
TCard getById(String id);
+
+ @Query("select count(t.id) from TCard t where t.status='normal' and t.cardtype='bankcard' and t.cardno=?1 ")
+ int countByBankCardNo(String bankcardno);
+
+ @Query("select count(t.id) from TCard t where t.status='normal' and t.cardtype='bankcard' and t.cardno=?1 and t.userid=?2 ")
+ int countByBankCardNoAndUserid(String bankcardno, String userid);
}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/ShopSourceTypeConfigDao.java b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/ShopSourceTypeConfigDao.java
index e861165..9c59a82 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/ShopSourceTypeConfigDao.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/ShopSourceTypeConfigDao.java
@@ -14,4 +14,7 @@
@Query("select a from TShopSourceTypeConfig a where a.shopaccno=?1 and a.sourceType=?2 and a.configid=?3 ")
TShopSourceTypeConfig getShopSourceTypeConfigById(String shopaccno, String sourceType, String configid);
+
+ @Query("select distinct a.shopaccno from TShopSourceTypeConfig a where a.sourceType=?1 order by a.shopaccno ")
+ List<String> getSourcetypeBindShopaccnos(String sourceType);
}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/TransactionMainDao.java b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/TransactionMainDao.java
index b72f8d2..10a3139 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/TransactionMainDao.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/TransactionMainDao.java
@@ -8,6 +8,7 @@
import javax.persistence.LockModeType;
import javax.persistence.QueryHint;
+import java.util.List;
public interface TransactionMainDao extends CrudRepository<TTransactionMain, String> {
@@ -28,4 +29,12 @@
@Query("select min(t.accdate) from TTransactionMain t where t.sourceType=?1 ")
String findMinAccdateBySourcetype(String sourcetype);
+
+ @Query("from TTransactionMain t where t.reverseRefno=?1 and t.status='success' order by t.refno ")
+ List<TTransactionMain> findByRefundSuccessTransdtl(String refno);
+
+ @Query("from TTransactionMain t where t.reverseRefno=?1 order by t.refno ")
+ List<TTransactionMain> findByRefundTransdtl(String refno);
+
+
}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/service/SourceTypeService.java b/payapi/src/main/java/com/supwisdom/dlpay/api/service/SourceTypeService.java
index 8e4048b..0e81d21 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/api/service/SourceTypeService.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/service/SourceTypeService.java
@@ -52,4 +52,7 @@
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
TSourceTypeCheckStatus saveOrUpdateSourceTypeCheckStatus(TSourceTypeCheckStatus s);
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = true)
+ List<String> getShopaccnoBySourcetype(String sourcetype);
+
}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/service/impl/SourceTypeServiceImpl.java b/payapi/src/main/java/com/supwisdom/dlpay/api/service/impl/SourceTypeServiceImpl.java
index 62c471f..f0bd529 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/api/service/impl/SourceTypeServiceImpl.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/service/impl/SourceTypeServiceImpl.java
@@ -11,6 +11,7 @@
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -210,4 +211,10 @@
}
return sourceTypeCheckDao.save(s);
}
+
+ @Override
+ public List<String> getShopaccnoBySourcetype(String sourcetype) {
+ List<String> list = shopSourceTypeConfigDao.getSourcetypeBindShopaccnos(sourcetype);
+ return list != null ? list : new ArrayList<String>(0);
+ }
}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/YnrccPaySignDao.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/YnrccPaySignDao.java
new file mode 100644
index 0000000..752bba4
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/YnrccPaySignDao.java
@@ -0,0 +1,37 @@
+package com.supwisdom.dlpay.citizencard.dao;
+
+import com.supwisdom.dlpay.citizencard.domain.TYnrccPaySign;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface YnrccPaySignDao extends JpaRepository<TYnrccPaySign, String> {
+ @Query("from TYnrccPaySign t where t.bankcardno=?1 and t.shopaccno=?2 and t.status='normal'")
+ TYnrccPaySign getUserSign(String bankcardno, String shopaccno);
+
+ @Query("select count(t.id) from TYnrccPaySign t where t.bankcardno=?1 and t.shopaccno<>?2 and t.status='normal' and t.signFlag is true ")
+ int countByBankcardnoAndSignStatus(String bankcardno, String shopaccno);
+
+ @Query("from TYnrccPaySign t where t.bankcardno=?1 and t.shopaccno<>?2 and t.status='normal' and t.signFlag is true")
+ List<TYnrccPaySign> queryOtherShopSign(String bankcardno, String shopaccno);
+
+ TYnrccPaySign getById(String id);
+
+ @Query("from TYnrccPaySign t where t.userid=?1 and t.status='normal' and t.signFlag is true")
+ List<TYnrccPaySign> queryActiveSignsByUserid(String userid);
+
+ @Query("from TYnrccPaySign t where t.bankcardno=?1 and t.status='normal' and t.signFlag is true")
+ List<TYnrccPaySign> queryActiveSignsByBankcardno(String bankcardno);
+
+ @Query("from TYnrccPaySign t where t.userid=?1 and t.bankcardno=?2 and t.status='normal' and t.signFlag is true")
+ List<TYnrccPaySign> queryActiveSignsByUseridAndBankcardno(String userid, String bankcardno);
+
+ @Query("select count(t.id) from TYnrccPaySign t where t.bankcardno=?1 and t.status='normal' ")
+ int countByBankcardno(String bankcardno);
+
+ @Query("select count(t.id) from TYnrccPaySign t where t.bankcardno=?1 and t.userid=?2 and t.status='normal' ")
+ int countByBankcardnoAndUserid(String bankcardno, String userid);
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/YnrccPayThirdappDao.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/YnrccPayThirdappDao.java
new file mode 100644
index 0000000..f20a8c4
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/YnrccPayThirdappDao.java
@@ -0,0 +1,12 @@
+package com.supwisdom.dlpay.citizencard.dao;
+
+import com.supwisdom.dlpay.citizencard.domain.TYnrccPayThirdapp;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+public interface YnrccPayThirdappDao extends JpaRepository<TYnrccPayThirdapp, String> {
+ @Query("from TYnrccPayThirdapp t where t.enable is true ")
+ List<TYnrccPayThirdapp> queryYnrccPayThirdConfig();
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/domain/TYnrccPaySign.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/domain/TYnrccPaySign.java
new file mode 100644
index 0000000..b286057
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/domain/TYnrccPaySign.java
@@ -0,0 +1,134 @@
+package com.supwisdom.dlpay.citizencard.domain;
+
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "TB_YNRCCPAY_SIGN",
+ indexes = {@Index(name = "idx1_ynrccpay_sign", columnList = "bankcardno,shopaccno,status")})
+public class TYnrccPaySign {
+ @Id
+ @GenericGenerator(name = "midGenerator", strategy = "uuid")
+ @GeneratedValue(generator = "midGenerator")
+ @Column(name = "id", nullable = false, length = 32)
+ private String id;
+
+ @Column(name="bankcardno", nullable = false, length = 32)
+ private String bankcardno;
+
+ @Column(name="shopaccno", nullable = false, length = 10)
+ private String shopaccno;
+
+ @Column(name="userid", nullable = false, length = 32)
+ private String userid;
+
+ @Column(name="status", nullable = false, length = 10)
+ private String status;
+
+ @Column(name="sign_flag", nullable = false, length = 10)
+ private boolean signFlag;
+
+ @Column(name="customer_sign_no", length = 60)
+ private String customerSignNo;
+
+ @Column(name="sign_time", length = 14)
+ private String signTime;
+
+ @Column(name="cancel_time", length = 14)
+ private String cancelTime;
+
+ @Column(name="remark", length = 600)
+ private String remark;
+
+ @Column(name="createtime", length = 14)
+ private String createtime;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getBankcardno() {
+ return bankcardno;
+ }
+
+ public void setBankcardno(String bankcardno) {
+ this.bankcardno = bankcardno;
+ }
+
+ public String getShopaccno() {
+ return shopaccno;
+ }
+
+ public void setShopaccno(String shopaccno) {
+ this.shopaccno = shopaccno;
+ }
+
+ public String getUserid() {
+ return userid;
+ }
+
+ public void setUserid(String userid) {
+ this.userid = userid;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public boolean isSignFlag() {
+ return signFlag;
+ }
+
+ public void setSignFlag(boolean signFlag) {
+ this.signFlag = signFlag;
+ }
+
+ public String getCustomerSignNo() {
+ return customerSignNo;
+ }
+
+ public void setCustomerSignNo(String customerSignNo) {
+ this.customerSignNo = customerSignNo;
+ }
+
+ public String getSignTime() {
+ return signTime;
+ }
+
+ public void setSignTime(String signTime) {
+ this.signTime = signTime;
+ }
+
+ public String getCancelTime() {
+ return cancelTime;
+ }
+
+ public void setCancelTime(String cancelTime) {
+ this.cancelTime = cancelTime;
+ }
+
+ public String getRemark() {
+ return remark;
+ }
+
+ public void setRemark(String remark) {
+ this.remark = remark;
+ }
+
+ public String getCreatetime() {
+ return createtime;
+ }
+
+ public void setCreatetime(String createtime) {
+ this.createtime = createtime;
+ }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/domain/TYnrccPayThirdapp.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/domain/TYnrccPayThirdapp.java
new file mode 100644
index 0000000..b4ef460
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/domain/TYnrccPayThirdapp.java
@@ -0,0 +1,118 @@
+package com.supwisdom.dlpay.citizencard.domain;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * 大理农商行快捷支付第三方中间缴费业务
+ * 对接参数配置表
+ * */
+@Entity
+@Table(name = "TB_YNRCCPAY_THIRDAPP")
+public class TYnrccPayThirdapp {
+
+ @Id
+ @Column(name = "id", unique = true, nullable = false, length = 32)
+ private String id;
+
+ @Column(name = "mch_id", nullable = false, length = 20)
+ private String mchId;
+
+ @Column(name = "mch_name", nullable = false, length = 200)
+ private String mchName;
+
+ @Column(name = "app_id", nullable = false, length = 60)
+ private String appId;
+
+ @Column(name = "token", nullable = false, length = 20)
+ private String token;
+
+ @Column(name = "pubkey", nullable = false, length = 200)
+ private String pubkey;
+
+ @Column(name = "enable", nullable = false, length = 20)
+ private boolean enable;
+
+ @Column(name = "remark", length = 200)
+ private String remark;
+
+ public TYnrccPayThirdapp() {
+ }
+
+ public TYnrccPayThirdapp(String id, String mchId, String mchName, String appId, String token, String pubkey, boolean enable, String remark) {
+ this.id = id;
+ this.mchId = mchId;
+ this.mchName = mchName;
+ this.appId = appId;
+ this.token = token;
+ this.pubkey = pubkey;
+ this.enable = enable;
+ this.remark = remark;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getMchId() {
+ return mchId;
+ }
+
+ public void setMchId(String mchId) {
+ this.mchId = mchId;
+ }
+
+ public String getMchName() {
+ return mchName;
+ }
+
+ public void setMchName(String mchName) {
+ this.mchName = mchName;
+ }
+
+ public String getAppId() {
+ return appId;
+ }
+
+ public void setAppId(String appId) {
+ this.appId = appId;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ public String getPubkey() {
+ return pubkey;
+ }
+
+ public void setPubkey(String pubkey) {
+ this.pubkey = pubkey;
+ }
+
+ public boolean isEnable() {
+ return enable;
+ }
+
+ public void setEnable(boolean enable) {
+ this.enable = enable;
+ }
+
+ public String getRemark() {
+ return remark;
+ }
+
+ public void setRemark(String remark) {
+ this.remark = remark;
+ }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/task/CitizencardCheckConfirmTask.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/task/CitizencardCheckConfirmTask.java
index 3cb0417..08d4e17 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/task/CitizencardCheckConfirmTask.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/task/CitizencardCheckConfirmTask.java
@@ -15,7 +15,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@@ -36,7 +35,8 @@
@Scheduled(cron = "${citizencard.confirm.chkdtl.cron}")
@SchedulerLock(name = "CitizencardChkClearConfirmTask", lockAtMostForString = "PT10M")
public void doConfirmCitizenCardChkdtlTask() {
- try { long t1 = System.currentTimeMillis();
+ try {
+ long t1 = System.currentTimeMillis();
if (null == TenantContext.getTenantSchema()) TenantContext.setTenantSchema(Constants.DEFAULT_TENANTID);
TBusinesspara businessParam = systemUtilService.getBusinessValueForUpdateNowait(ConstantUtil.BUSINESS_CITIZENCARD_CLEARDATE);
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/PageRes.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/PageRes.java
new file mode 100644
index 0000000..03467f9
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/PageRes.java
@@ -0,0 +1,51 @@
+package com.supwisdom.dlpay.framework.util;
+
+import java.util.List;
+
+public class PageRes<T> {
+ private int pageNo = 1;
+ private int pageSize = 10;
+ private int totalCount = 0;
+ private int totalPages = 0;
+ private List<T> data;
+
+ public int getPageNo() {
+ return pageNo;
+ }
+
+ public void setPageNo(int pageNo) {
+ this.pageNo = pageNo;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ public void setPageSize(int pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ public int getTotalCount() {
+ return totalCount;
+ }
+
+ public void setTotalCount(int totalCount) {
+ this.totalCount = totalCount;
+ }
+
+ public int getTotalPages() {
+ return totalPages;
+ }
+
+ public void setTotalPages(int totalPages) {
+ this.totalPages = totalPages;
+ }
+
+ public List<T> getData() {
+ return data;
+ }
+
+ public void setData(List<T> data) {
+ this.data = data;
+ }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java
index e11c171..179f6cf 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java
@@ -78,6 +78,11 @@
*/
public static final String SUBJNO_PAY_CITIZEN_CARD = "112234";
+ /**
+ * 应收账款 - 农商行网关快捷支付
+ */
+ public static final String SUBJNO_YNRCC_NETPAY = "112235";
+
//======================= 负债类 =====================//
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java
index d1a85b8..587c400 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java
@@ -13,6 +13,8 @@
public static final int TRANSCODE_ALIPAY = 3040;//支付宝支付
+ public static final int TRANSCODE_YNRCC_NETPAY = 3050;//农商行网关快捷支付
+
// QRcode 聚合支付
public static final int TRANSCODE_QRCODE = 1002;
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
index 161b1c7..ae9aafe 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
@@ -81,6 +81,7 @@
public static final String PAYTYPE_CITIZEN_CARD = "citizenCard"; //市民卡
public static final String PAYTYPE_YKT_CARD = "yktpay"; //一卡通
public static final String PAYTYPE_OTHER_THIRDPART = "thirdpart"; //其他第三方
+ public static final String PAYTYPE_YNRCC_PAY="ynrccpay"; //农商行网关快捷支付
public static final String PAYTYPE_APP = "APP"; //app内支付
public static final String PAYTYPE_H5 = "H5"; //H5内支付
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
index 84a951e..fab8949 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java
@@ -130,6 +130,8 @@
public static final int NO_DEAL_EEROR = 30005; // 无交易记录
+ public static final int BUSINESS_USER_NO_SIGN = 30006; // 用户未签约
+
//============= 交易错误 ============//
public static final int CARD_NOT_EXISTS = 40000; //卡不存在
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/system/service/UserMessageService.java b/payapi/src/main/java/com/supwisdom/dlpay/system/service/UserMessageService.java
new file mode 100644
index 0000000..842b9d9
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/system/service/UserMessageService.java
@@ -0,0 +1,11 @@
+package com.supwisdom.dlpay.system.service;
+
+import com.supwisdom.dlpay.api.bean.UserMessageData;
+import com.supwisdom.dlpay.framework.util.PageRes;
+import org.springframework.transaction.annotation.Transactional;
+
+public interface UserMessageService {
+ @Transactional(rollbackFor = Exception.class, readOnly = true)
+ PageRes<UserMessageData> queryMessageByUserid(String userid, int pageNo, int pageSize);
+
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/system/service/impl/UserMessageServiceImpl.java b/payapi/src/main/java/com/supwisdom/dlpay/system/service/impl/UserMessageServiceImpl.java
new file mode 100644
index 0000000..b5fa9ce
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/system/service/impl/UserMessageServiceImpl.java
@@ -0,0 +1,49 @@
+package com.supwisdom.dlpay.system.service.impl;
+
+import com.supwisdom.dlpay.api.bean.UserMessageData;
+import com.supwisdom.dlpay.framework.util.PageRes;
+import com.supwisdom.dlpay.framework.util.PageResult;
+import com.supwisdom.dlpay.framework.util.StringUtil;
+import com.supwisdom.dlpay.system.bean.CitizenCardShowBean;
+import com.supwisdom.dlpay.system.service.UserMessageService;
+import org.hibernate.query.internal.NativeQueryImpl;
+import org.hibernate.transform.Transformers;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class UserMessageServiceImpl implements UserMessageService {
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ @Override
+ public PageRes<UserMessageData> queryMessageByUserid(String userid, int pageNo, int pageSize) {
+ StringBuffer querySql = new StringBuffer("select a.msgid,a.content,a.lastupdate,a.refno,b.transdesc,b.amount,a.userid " +
+ " from tb_msg a left join tb_persondtl b on a.refno=b.refno where a.userid=:userid order by a.lastupdate desc");
+ StringBuffer countSql = new StringBuffer("select count(a.msgid) as cnt " +
+ " from tb_msg a left join tb_persondtl b on a.refno=b.refno where a.userid=:userid ");
+
+ Query query = entityManager.createNativeQuery(querySql.toString());
+ Query countQuery = entityManager.createNativeQuery(countSql.toString());
+ query.setParameter("userid", userid.trim());
+ countQuery.setParameter("userid", userid.trim());
+ query.setFirstResult((pageNo - 1) * pageSize);
+ query.setMaxResults(pageSize); //分页显示
+ query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(UserMessageData.class));
+ List<UserMessageData> list = query.getResultList();
+ BigInteger cnt = (BigInteger) countQuery.getSingleResult();
+ PageRes<UserMessageData> page = new PageRes<>();
+ page.setPageNo(pageNo);
+ page.setPageSize(pageSize);
+ page.setTotalCount(cnt == null ? 0 : cnt.intValue());
+ page.setTotalPages(page.getTotalCount() % page.getPageSize() > 0 ? (page.getTotalCount() / page.getPageSize() + 1) : (page.getTotalCount() / page.getPageSize()));
+ page.setData(list == null ? new ArrayList<>(0) : list);
+ return page;
+ }
+}
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/ynrcc_netpay_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/ynrcc_netpay_service_impl.kt
new file mode 100644
index 0000000..d8b5af1
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/ynrcc_netpay_service_impl.kt
@@ -0,0 +1,433 @@
+package com.supwisdom.dlpay.agent.service.impl
+
+import com.csii.ynrcc.open.api.pay.YNRCCFastGateWayPayApi
+import com.csii.ynrcc.open.api.service.User
+import com.csii.ynrcc.open.api.service.YNRCCOpenServiceApi
+import com.google.gson.Gson
+import com.supwisdom.dlpay.agent.service.YnrccNetPayService
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayCommonResp
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayResp
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayUtil
+import com.supwisdom.dlpay.api.domain.TPerson
+import com.supwisdom.dlpay.api.service.SourceTypeService
+import com.supwisdom.dlpay.exception.TransactionProcessException
+import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.*
+import mu.KotlinLogging
+import org.springframework.http.HttpEntity
+import org.springframework.http.HttpHeaders
+import org.springframework.http.MediaType
+import org.springframework.http.converter.StringHttpMessageConverter
+import org.springframework.stereotype.Service
+import org.springframework.util.LinkedMultiValueMap
+import org.springframework.util.MultiValueMap
+import org.springframework.web.client.RestTemplate
+import java.net.URLDecoder
+import java.nio.charset.StandardCharsets
+
+@Service
+class YnrccNetPayServiceImpl(val restTemplate: RestTemplate,
+ val systemUtilService: SystemUtilService,
+ val sourceTypeService: SourceTypeService) : YnrccNetPayService {
+ private val logger = KotlinLogging.logger { }
+
+ override fun doAnalysisSignature(shopaccno: String, plain: String, signature: String): Map<String, String> {
+ val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, true)
+ val data = YNRCCFastGateWayPayApi.verify(signature, plain) /* 调SDK验证签名 */
+ val merId = config[YnrccPayUtil.MER_ID]
+ if (!merId.isNullOrEmpty() && merId != data["Mer_Id"]) {
+ throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "参数[Mer_Id]不匹配!")
+ }
+ return data
+ }
+
+ override fun doApplyYnrccPaySign(shopaccno: String): YnrccPayResp {
+ val resp = YnrccPayResp()
+ val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, false)
+ val merId = config[YnrccPayUtil.MER_ID]
+ val merUrl = config[YnrccPayUtil.MER_URL]
+ if (merId.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[Mer_Id]"
+ logger.error(resp.error())
+ return resp
+ }
+ if (merUrl.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[MerURL]"
+ logger.error(resp.error())
+ return resp
+ }
+
+ val params = hashMapOf<String, String>()
+ params["TransId"] = "IFSR"
+ params["Mer_Id"] = merId.trim()
+ params["MerURL"] = merUrl.trim()
+ params["PAY_MODE"] = "QS"
+
+ //调SDK生成签名
+ val signData = YNRCCFastGateWayPayApi.sign(params)
+ if (signData["Plain"].isNullOrEmpty() || signData["Signature"].isNullOrEmpty()) {
+ resp.code = "ZE0002"
+ resp.message = "签名计算错误!"
+ logger.error("签名后[Plain]和[Signature]参数为空!")
+ return resp
+ }
+
+ resp.code = YnrccPayUtil.SUCCESS
+ resp.message = "SUCCESS"
+ resp.plain = signData["Plain"]
+ resp.signature = signData["Signature"]
+ return resp
+ }
+
+ override fun doApplyAuthYnrccPaySign(shopaccno: String, oldCustomerSignNo: String): YnrccPayResp {
+ val resp = YnrccPayResp()
+ val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, false)
+ val merId = config[YnrccPayUtil.MER_ID]
+ if (merId.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[Mer_Id]"
+ logger.error(resp.error())
+ return resp
+ }
+
+ val params = hashMapOf<String, String>()
+ params["TransId"] = "IFSR"
+ params["Mer_Id"] = merId.trim()
+ params["CustomerSignNo"] = oldCustomerSignNo.trim()
+ params["PAY_MODE"] = "QS"
+
+ //调SDK生成签名
+ val signData = YNRCCFastGateWayPayApi.sign(params)
+ if (signData["Plain"].isNullOrEmpty() || signData["Signature"].isNullOrEmpty()) {
+ resp.code = "ZE0002"
+ resp.message = "签名计算错误!"
+ logger.error("签名后[Plain]和[Signature]参数为空!")
+ return resp
+ }
+
+ resp.code = YnrccPayUtil.SUCCESS
+ resp.message = "SUCCESS"
+ resp.plain = signData["Plain"]
+ resp.signature = signData["Signature"]
+ return resp
+ }
+
+ override fun doCancelYnrccPaySign(shopaccno: String, customerSignNo: String): YnrccPayResp {
+ val resp = YnrccPayResp()
+ val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, false)
+ val gateWay = config[YnrccPayUtil.GATEWAY]
+ val merId = config[YnrccPayUtil.MER_ID]
+ if (gateWay.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[网关地址]"
+ logger.error(resp.error())
+ return resp
+ }
+ if (merId.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[Mer_Id]"
+ logger.error(resp.error())
+ return resp
+ }
+
+ val url = String.format(gateWay, "PayGateFastPayCancelSign.do") //赋予接口名
+ val params = hashMapOf<String, String>()
+ params["TransId"] = "IFCR"
+ params["Mer_Id"] = merId.trim()
+ params["CustomerSignNo"] = customerSignNo
+ params["PAY_MODE"] = "Q"
+
+ val signData = YNRCCFastGateWayPayApi.sign(params) //调SDK生成签名
+ val plain = signData["Plain"]
+ val signature = signData["Signature"]
+ if (plain.isNullOrEmpty() || signature.isNullOrEmpty()) {
+ resp.code = "ZE0002"
+ resp.message = "签名计算错误!"
+ logger.error(resp.error())
+ return resp
+ }
+
+ val result = postForm(url, plain, signature, "解约") //发起表单提交
+ resp.code = result["RespCode"]
+ resp.message = result["RespDesc"]
+ if (YnrccPayUtil.SUCCESS == result["RespCode"]) {
+ resp.transId = result["TransId"]
+ resp.mer_Id = result["Mer_Id"]
+ } else {
+ logger.error(resp.error())
+ }
+ return resp
+ }
+
+ private fun error(code: String, message: String): Map<String, String> {
+ val error = hashMapOf<String, String>()
+ error["RespCode"] = code
+ error["RespDesc"] = message
+ return error
+ }
+
+ private fun postForm(url: String, plain: String, signature: String, opt:String): Map<String,String> {
+ val httpHeaders = HttpHeaders()
+ httpHeaders.contentType = MediaType.APPLICATION_FORM_URLENCODED //Form表单提交
+ val requestParams = LinkedMultiValueMap<String, String>()
+ requestParams.add("Plain", plain);
+ requestParams.add("Signature", signature)
+ val httpEntity = HttpEntity<MultiValueMap<String, String>>(requestParams, httpHeaders)
+ restTemplate.messageConverters[1] = StringHttpMessageConverter(StandardCharsets.UTF_8) //UTF-8接收
+
+ logger.info("农商行网关快捷支付请求【$opt】:\nurl=[$url]\nPlain=[$plain]\nSignature=[$signature]")
+ val result = restTemplate.postForEntity(url, httpEntity, String::class.java)
+ if (200 == result.statusCodeValue) {
+ //请求成功
+ logger.info("农商行网关快捷支付请求【$opt】返回:\nurl=[$url]\nResponse Body=[" + result.body + "]")
+ val resJson = Gson().fromJson(result.body, YnrccPayCommonResp::class.java)
+ if (null == resJson || StringUtil.isEmpty(resJson.plain) || StringUtil.isEmpty(resJson.signature)) {
+ return error("ZE0098", "请求农商行网关【$opt】返回数据为空!")
+ }
+
+ val resData = when ("对账" == opt) {
+ true -> YNRCCFastGateWayPayApi.verify(resJson.signature, URLDecoder.decode(resJson.plain,"UTF-8")) //对账需先解码
+ false -> YNRCCFastGateWayPayApi.verify(resJson.signature, resJson.plain) //调SDK验证签名
+ }
+ logger.info("农商行网关快捷支付请求【$opt】返回:\nurl=[$url]\nResponse Plain=[" + YnrccPayUtil.toJson(resData) + "]")
+ val respCode = resData["RespCode"]?.trim()?.replace("\r\n", "")
+ return if (YnrccPayUtil.SUCCESS == respCode) {
+ resData["RespCode"] = respCode
+ resData["RespDesc"] = "SUCCESS"
+ resData
+ } else {
+ val errmsg = YnrccPayUtil.errcode.firstOrNull {
+ it.second.code == respCode
+ }?.second?.msg
+ resData["RespCode"] = respCode
+ resData["RespDesc"] = "$respCode $errmsg" //设置失败信息
+ resData
+ }
+ } else {
+ return error("ZE0099","请求农商行网关【$opt】失败!http status=[${result.statusCodeValue}]")
+ }
+ }
+
+ override fun doYnrccPayInit(shopaccno: String, refno: String, amount: Int, transDateTime: String, productInfo: String, extData: String, custname: String, email: String, customerSignNo: String): YnrccPayResp {
+ val resp = YnrccPayResp()
+ val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, false)
+ val merId = config[YnrccPayUtil.MER_ID]
+ val merIdName = config[YnrccPayUtil.MER_NAME]
+ val merUrl = config[YnrccPayUtil.MER_URL]
+ if (merId.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[Mer_Id]"
+ logger.error(resp.error())
+ return resp
+ }
+ if (merIdName.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[Mer_IdName]"
+ logger.error(resp.error())
+ return resp
+ }
+ if (merUrl.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[MerURL]"
+ logger.error(resp.error())
+ return resp
+ }
+
+ val params = hashMapOf<String, String>()
+ params["TransId"] = "IFPR"
+ params["Mer_Id"] = merId.trim()
+ params["Mer_IdName"] = merIdName
+ params["OrderNo"] = refno
+ params["Amount"] = MoneyUtil.formatYuanToString(amount / 100.0)
+ params["OrderDateTime"] = transDateTime
+ params["CurrencyType"] = "156"
+ params["CustomerName"] = custname
+ params["ProductInfo"] = productInfo
+ params["CustomerEMail"] = email
+ params["CustomerSignNo"] = customerSignNo
+ params["MerURL"] = merUrl
+ params["MsgExt"] = extData
+ params["PAY_MODE"] = "QS"
+
+ //调SDK生成签名
+ val signData = YNRCCFastGateWayPayApi.sign(params)
+ if (signData["Plain"].isNullOrEmpty() || signData["Signature"].isNullOrEmpty()) {
+ resp.code = "ZE0002"
+ resp.message = "签名计算错误!"
+ logger.error("签名后[Plain]和[Signature]参数为空!")
+ return resp
+ }
+
+ resp.code = YnrccPayUtil.SUCCESS
+ resp.message = "SUCCESS"
+ resp.plain = signData["Plain"]
+ resp.signature = signData["Signature"]
+ return resp
+ }
+
+ override fun doYnrccPayRefund(shopaccno: String, orignRefno: String, amount: Int, orignTransDate: String): YnrccPayResp {
+ val resp = YnrccPayResp()
+ val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, false)
+ val gateWay = config[YnrccPayUtil.GATEWAY]
+ val merId = config[YnrccPayUtil.MER_ID]
+ if (gateWay.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[网关地址]"
+ logger.error(resp.error())
+ return resp
+ }
+ if (merId.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[Mer_Id]"
+ logger.error(resp.error())
+ return resp
+ }
+
+ val url = String.format(gateWay, "MerchantWithdraw.do") //赋予接口名
+ val params = hashMapOf<String, String>()
+ params["TransId"] = "IPSR"
+ params["Mer_Id"] = merId.trim()
+ params["OrgMerchantSeqNo"] = orignRefno
+ params["Amount"] = MoneyUtil.formatYuanToString(amount / 100.0)
+ params["OrgMerchantDate"] = orignTransDate
+ params["PAY_MODE"] = "Q"
+
+ val signData = YNRCCFastGateWayPayApi.sign(params) //调SDK生成签名
+ val plain = signData["Plain"]
+ val signature = signData["Signature"]
+ if (plain.isNullOrEmpty() || signature.isNullOrEmpty()) {
+ resp.code = "ZE0002"
+ resp.message = "签名计算错误!"
+ logger.error(resp.error())
+ return resp
+ }
+
+ val result = postForm(url, plain, signature, "退款") //发起表单提交
+ resp.code = result["RespCode"]
+ resp.message = result["RespDesc"]
+ if (YnrccPayUtil.SUCCESS == result["RespCode"]) {
+ resp.transId = result["TransId"]
+ resp.mer_Id = result["Mer_Id"]
+ resp.orgTransAmt = result["OrgTransAmt"]
+ resp.transAmount = result["TransAmount"]
+ resp.merchantSeqNo = result["MerchantSeqNo"]
+ resp.transSeqNo = result["TransSeqNo"]
+ } else {
+ logger.error(resp.error())
+ }
+ return resp
+ }
+
+ override fun doQueryYnrccPayResult(shopaccno: String, orignRefno: String, orignTransDate: String): YnrccPayResp {
+ val resp = YnrccPayResp()
+ val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, false)
+ val gateWay = config[YnrccPayUtil.GATEWAY]
+ val merId = config[YnrccPayUtil.MER_ID]
+ val merIdName = config[YnrccPayUtil.MER_NAME]
+ if (gateWay.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[网关地址]"
+ logger.error(resp.error())
+ return resp
+ }
+ if (merId.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[Mer_Id]"
+ logger.error(resp.error())
+ return resp
+ }
+ if (merIdName.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[Mer_IdName]"
+ logger.error(resp.error())
+ return resp
+ }
+
+ val url = String.format(gateWay, "QueryMerchantEpay.do") //赋予接口名
+ val params = hashMapOf<String, String>()
+ params["TransId"] = "IQSR"
+ params["Mer_Id"] = merId.trim()
+ params["Mer_IdName"] = merIdName.trim()
+ params["OrderNo"] = orignRefno
+ params["OrderDate"] = orignTransDate
+ params["PAY_MODE"] = "Q"
+
+ val signData = YNRCCFastGateWayPayApi.sign(params) //调SDK生成签名
+ val plain = signData["Plain"]
+ val signature = signData["Signature"]
+ if (plain.isNullOrEmpty() || signature.isNullOrEmpty()) {
+ resp.code = "ZE0002"
+ resp.message = "签名计算错误!"
+ logger.error(resp.error())
+ return resp
+ }
+
+ val result = postForm(url, plain, signature, "结果查询") //发起表单提交
+ resp.code = result["RespCode"]
+ resp.message = result["RespDesc"]
+ if (YnrccPayUtil.SUCCESS == result["RespCode"]) {
+ resp.transId = result["TransId"]
+ resp.mer_Id = result["Mer_Id"]
+ resp.orgTransId = result["OrgTransId"]
+ resp.orderNo = result["OrderNo"]
+ resp.amount = result["Amount"]
+ resp.amount1 = result["Amount1"]
+ resp.feeAmt = result["FeeAmt"]
+ resp.currencyType = result["CurrencyType"]
+ resp.transSeqNo = result["TransSeqNo"]
+ resp.ppDateTime = result["PpDateTime"]
+ resp.clearingDate = result["ClearingDate"]
+ resp.transStatus = result["TransStatus"]
+ } else {
+ logger.error(resp.error())
+ }
+ return resp
+ }
+
+ override fun doQueryYnrccPayChkfile(checkDate: String, shopaccno: String): YnrccPayResp {
+ val resp = YnrccPayResp()
+ val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, false)
+ val gateWay = config[YnrccPayUtil.GATEWAY]
+ val merId = config[YnrccPayUtil.MER_ID]
+ if (gateWay.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[网关地址]"
+ logger.error(resp.error())
+ return resp
+ }
+ if (merId.isNullOrEmpty()) {
+ resp.code = "ZE0001"
+ resp.message = "系统参数未配置[Mer_Id]"
+ logger.error(resp.error())
+ return resp
+ }
+
+ val url = String.format(gateWay, "MerchantCheckFileQry.do") //赋予接口名
+ val params = hashMapOf<String, String>()
+ params["TransId"] = "IDFR"
+ params["Mer_Id"] = merId.trim()
+ params["ClearDate"] = checkDate
+ params["PAY_MODE"] = "Q"
+
+ val signData = YNRCCFastGateWayPayApi.sign(params) //调SDK生成签名
+ val plain = signData["Plain"]
+ val signature = signData["Signature"]
+ if (plain.isNullOrEmpty() || signature.isNullOrEmpty()) {
+ resp.code = "ZE0002"
+ resp.message = "签名计算错误!"
+ logger.error(resp.error())
+ return resp
+ }
+
+ val result = postForm(url, plain, signature, "对账") //发起表单提交
+ resp.code = result["RespCode"]
+ resp.message = result["RespDesc"]
+ if (YnrccPayUtil.SUCCESS == result["RespCode"]) {
+ resp.plain = result["FileContent"] //对账单
+ }
+ return resp
+ }
+
+}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/ynrcc_netpay_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/ynrcc_netpay_service.kt
new file mode 100644
index 0000000..2510ab4
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/ynrcc_netpay_service.kt
@@ -0,0 +1,107 @@
+package com.supwisdom.dlpay.agent.service
+
+import com.supwisdom.dlpay.agent.AgentCode
+import com.supwisdom.dlpay.agent.AgentPayService
+import com.supwisdom.dlpay.agent.AgentResponse
+import com.supwisdom.dlpay.agent.DtlStatus
+import com.supwisdom.dlpay.agent.citizencard.YnrccRespCode
+import com.supwisdom.dlpay.agent.citizencard.YnrccUtil
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayResp
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayUtil
+import com.supwisdom.dlpay.api.dao.TransactionMainDao
+import com.supwisdom.dlpay.api.domain.TTransactionMain
+import com.supwisdom.dlpay.exception.TransactionProcessException
+import com.supwisdom.dlpay.framework.util.MoneyUtil
+import com.supwisdom.dlpay.framework.util.TradeErrorCode
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Component
+
+interface YnrccNetPayService {
+ fun doAnalysisSignature(shopaccno: String, plain: String, signature: String): Map<String, String>
+
+ fun doApplyYnrccPaySign(shopaccno: String): YnrccPayResp //首次签约
+
+ fun doApplyAuthYnrccPaySign(shopaccno: String, oldCustomerSignNo: String): YnrccPayResp //授权签约
+
+ fun doCancelYnrccPaySign(shopaccno: String, customerSignNo: String): YnrccPayResp
+
+ fun doYnrccPayInit(shopaccno: String, refno: String, amount: Int, transDateTime: String, productInfo: String,
+ extData: String, custname: String, email: String, customerSignNo: String): YnrccPayResp
+
+ fun doYnrccPayRefund(shopaccno: String, orignRefno: String, amount: Int, orignTransDate: String): YnrccPayResp
+
+ fun doQueryYnrccPayResult(shopaccno: String, orignRefno: String, orignTransDate: String): YnrccPayResp
+
+ fun doQueryYnrccPayChkfile(checkDate: String, shopaccno: String): YnrccPayResp
+}
+
+@Component("ynrccpayAgent")
+class YnrccNetPayAgent: AgentPayService<DtlStatus>{
+ @Autowired
+ private lateinit var ynrccNetPayService: YnrccNetPayService
+ @Autowired
+ lateinit var transactionMainDao: TransactionMainDao
+
+ private fun agentCode(code: String, msg: String?): org.springframework.data.util.Pair<AgentCode, YnrccRespCode> {
+ return YnrccPayUtil.errcode.firstOrNull {
+ it.second.code == code
+ }?.let {
+ org.springframework.data.util.Pair.of(it.first, YnrccRespCode(
+ code, it.second.msg.replace("{message}", msg ?: "未知")
+ ))
+ } ?: org.springframework.data.util.Pair.of(AgentCode.COMMON_ERROR,
+ YnrccRespCode(code, msg ?: "未知"))
+ }
+
+ override fun auth(agentid: String?, billno: String?): AgentResponse<DtlStatus> {
+ return AgentResponse<DtlStatus>().apply {
+ this.code = AgentCode.NOT_SUPPORT
+ }
+ }
+
+ override fun pay(transaction: TTransactionMain): AgentResponse<DtlStatus> {
+ return AgentResponse<DtlStatus>().apply {
+ this.code = AgentCode.NOT_SUPPORT //fixme:支付由客户端发起,服务端无支付逻辑
+ }
+ }
+
+ override fun cancel(transaction: TTransactionMain): AgentResponse<DtlStatus> {
+ return refund(transaction)
+ }
+
+ override fun refund(transaction: TTransactionMain): AgentResponse<DtlStatus> {
+ val originalDtl = transactionMainDao.findByRefno(transaction.reverseRefno)?:
+ throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "原始流水<${transaction.reverseRefno}>不存在")
+
+ //fixme:必须找原流水获取下单日期
+ val resp = ynrccNetPayService.doYnrccPayRefund(transaction.shopDtl.shopaccno, transaction.reverseRefno,
+ MoneyUtil.YuanToFen(transaction.personDtl.amount), originalDtl.shopDtl.accdate)
+ return AgentResponse<DtlStatus>().also {
+ val code = agentCode(resp.code, resp.message)
+ it.code = code.first
+ it.agentCode = code.second.code
+ it.agentMsg = code.second.msg
+ it.agentRefno = resp.transSeqNo
+ }
+ }
+
+ override fun query(transaction: TTransactionMain): AgentResponse<DtlStatus> {
+ val resp = ynrccNetPayService.doQueryYnrccPayResult(transaction.shopDtl.shopaccno, transaction.refno, transaction.shopDtl.accdate)
+
+ return AgentResponse<DtlStatus>().also {
+ val code = agentCode(resp.code, resp.message)
+ it.code = code.first
+ it.agentCode = code.second.code
+ it.agentMsg = code.second.msg
+ it.agentRefno = resp.transSeqNo
+ it.dtlStatus = when (resp.transStatus) {
+// 00 - 交易成功 01 - 交易失败 02 - 撤消成功 03 - 部分退货 04 - 全部退货 99 - 交易超时
+ "00" -> DtlStatus.SUCCESS
+ "03" -> DtlStatus.PARTIAL_REFUND
+ "04" -> DtlStatus.REFUND
+ else -> DtlStatus.FAIL
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/ynrccpay_checkfile_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/ynrccpay_checkfile_service.kt
new file mode 100644
index 0000000..21fc8c1
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/ynrccpay_checkfile_service.kt
@@ -0,0 +1,226 @@
+package com.supwisdom.dlpay.agent.service
+
+import com.supwisdom.dlpay.agent.AgentCode
+import com.supwisdom.dlpay.agent.AgentResponse
+import com.supwisdom.dlpay.agent.CheckFileProvider
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayChkfile
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayUtil
+import com.supwisdom.dlpay.api.domain.TSourceTypeCheckStatus
+import com.supwisdom.dlpay.api.domain.TTransactionChkfile
+import com.supwisdom.dlpay.api.service.SourceTypeService
+import com.supwisdom.dlpay.api.service.TransactionReconciliationService
+import com.supwisdom.dlpay.exception.TransactionException
+import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.StringUtil
+import com.supwisdom.dlpay.framework.util.TradeDict
+import com.supwisdom.dlpay.util.ConstantUtil
+import mu.KotlinLogging
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Component
+import java.io.BufferedReader
+import java.io.ByteArrayInputStream
+import java.io.InputStreamReader
+import java.nio.charset.Charset
+
+@Component("ynrccpayCheckFileProvider")
+class YnrccpayCheckFileProvider : CheckFileProvider {
+ @Autowired
+ private lateinit var systemUtilService: SystemUtilService
+ @Autowired
+ private lateinit var transactionReconciliationService: TransactionReconciliationService
+ @Autowired
+ private lateinit var sourceTypeService: SourceTypeService
+ @Autowired
+ private lateinit var ynrccNetPayService:YnrccNetPayService
+
+ private val logger = KotlinLogging.logger { }
+
+ override fun acquireCheckFile(checkStatus: TSourceTypeCheckStatus): AgentResponse<TSourceTypeCheckStatus> {
+ try {
+ val billDate = checkStatus.checkAccdate
+ logger.info("【农商行网关快捷支付】对账单下载:download checkdate=【$billDate】")
+
+ val chkfile: TTransactionChkfile = transactionReconciliationService
+ .getTransactionChkfile(billDate, checkStatus.sourceType)?.let { file ->
+ when (file.status) {
+ ConstantUtil.CHKFILE_STATUS_INIT -> file //初始化直接返回
+ ConstantUtil.CHKFILE_STATUS_ERROR -> reinitCheckFile(file) //错误或未对账的直接重新拉取
+ else -> {
+ when (checkStatus.forceRecheck) {
+ true -> reinitCheckFile(file) //对账已完成但强制重新对账
+ false -> {
+ if (file.status == ConstantUtil.CHKFILE_STATUS_UNCHECK) {
+ file
+ } else {
+ throw TransactionException(-1, "【农商行网关快捷支付】该天[$billDate]已对账完成")
+ }
+ } //对账已完成报错
+ }
+ }
+ }
+ }
+ ?: transactionReconciliationService.saveInitTransactionChkfile(billDate, checkStatus.sourceType)
+
+ if (chkfile.status == ConstantUtil.CHKFILE_STATUS_UNCHECK) {
+ return successDownload("[$billDate]日对账数据已入库成功", checkStatus)
+ }
+
+ val fileDataList = ArrayList<YnrccPayChkfile>(0)
+ val shopaccList = sourceTypeService.getShopaccnoBySourcetype(TradeDict.PAYTYPE_YNRCC_PAY) //所有开通快捷支付的商户
+ for (shopacc in shopaccList) {
+ val resp = ynrccNetPayService.doQueryYnrccPayChkfile(billDate, shopacc)
+ when (resp.code) {
+ YnrccPayUtil.SUCCESS -> {
+ //成功
+ BufferedReader(InputStreamReader(resp.plain?.byteInputStream(Charset.forName("UTF-8")))).use { reader ->
+ val totalCnt = reader.readLine()?.trim()?.toInt() //总条目数
+ var records = 0
+ while (true) {
+ val line = reader.readLine() ?: break
+ if (line.isEmpty()) continue
+ val columns = line.split(YnrccPayUtil.chkFileDelimiter)
+ val bean = YnrccPayChkfile()
+ try {
+ StringUtil.transforToBean(YnrccPayChkfile.HEADER, columns, bean)
+ }catch (etr:Exception){
+ throw TransactionException(97, "商户[$shopacc]对账单下载[$billDate]文件明细解析错误!${etr.message}")
+ }
+ fileDataList.add(bean)
+ records++
+ }
+ if (totalCnt != records) {
+ throw TransactionException(97, "商户[$shopacc]对账单下载[$billDate]文件总交易笔数和明细不符!")
+ }
+ }
+ }
+ YnrccPayUtil.NO_RECORDS_TODAY -> {
+ //fixme:当日无交易明细
+ }
+ else -> {
+ //报错,退出对账单拉取
+ logger.error("农商行网关快捷支付商户[$shopacc]对账单下载[$billDate]报错:${resp.message}")
+ chkfile.status = ConstantUtil.CHKFILE_STATUS_ERROR
+ chkfile.remark = "商户[$shopacc]请求获取对账文件报错:${resp.message}"
+ transactionReconciliationService.saveOrUpdateTransactionChkfile(chkfile)
+
+ //失败,直接返回
+ return AgentResponse<TSourceTypeCheckStatus>().also {
+ it.code = AgentCode.FAIL
+ it.agentMsg = chkfile.remark
+ it.payload = sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus.apply {
+ this.remark = chkfile.remark
+ })
+ }
+ }
+ }
+ }
+
+ if(fileDataList.isEmpty()){
+ //当日无交易明细,也创建空记录
+ transactionReconciliationService.doSuccessTransactionChkfile(chkfile, "请求银行返回:当日无交易明细")
+ //成功
+ return successDownload("当日无交易明细", checkStatus.apply {
+ this.chkfileUrl = "none"
+ })
+ }
+
+ //保存对账单
+ val failcnt = doBatchSaveYnrccPayCheckDetails(chkfile, fileDataList)
+ if (failcnt > 0) {
+ chkfile.status = ConstantUtil.CHKFILE_STATUS_ERROR
+ chkfile.remark = "对账单数据存在保存失败记录,请手动核对对账单数据"
+ transactionReconciliationService.saveOrUpdateTransactionChkfile(chkfile)
+
+ return AgentResponse<TSourceTypeCheckStatus>().also {
+ it.code = AgentCode.FAIL
+ it.agentMsg = chkfile.remark
+ it.payload = sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus.apply {
+ this.checkFileOk = false
+ this.chkfileUrl = "none"
+ this.remark = chkfile.remark
+ })
+ }
+ }
+
+ //成功
+ transactionReconciliationService.doSuccessTransactionChkfile(chkfile, "对账单数据下载成功")
+ return successDownload("[$billDate]日对账数据入库成功", checkStatus.apply {
+ this.chkfileUrl = "none"
+ })
+
+ } catch (et: TransactionException) {
+ return AgentResponse<TSourceTypeCheckStatus>().also {
+ it.code = AgentCode.FAIL
+ it.agentMsg = et.message
+ it.agentCode = "${et.code()}"
+ it.payload = sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus.apply {
+ this.remark = et.message
+ })
+ }
+ }
+
+ }
+
+ override fun queryCheckFile(checkStatus: TSourceTypeCheckStatus?): AgentResponse<TSourceTypeCheckStatus> {
+ return AgentResponse<TSourceTypeCheckStatus>().also {
+ it.code = AgentCode.SUCCESS
+ it.agentMsg = "OK"
+ it.payload = checkStatus
+ }
+ }
+
+ override fun downloadCheckFile(checkStatus: TSourceTypeCheckStatus?): AgentResponse<TSourceTypeCheckStatus> {
+ return AgentResponse<TSourceTypeCheckStatus>().also {
+ it.code = AgentCode.SUCCESS
+ it.agentMsg = "OK"
+ it.payload = checkStatus
+ }
+ }
+
+ private fun reinitCheckFile(chkfile: TTransactionChkfile): TTransactionChkfile {
+ transactionReconciliationService.deleteTransactionChkdtls(chkfile.id) //删除明细
+ return transactionReconciliationService.saveOrUpdateTransactionChkfile(chkfile.apply {
+ this.status = ConstantUtil.CHKFILE_STATUS_INIT
+ this.result = ConstantUtil.CHKFILE_RESULT_NONE
+ this.remark = null
+ this.othercnt = 0
+ this.otheramt = 0.00
+ this.localcnt = 0
+ this.localamt = 0.00
+ }) //初始化chkfile
+ }
+
+ private fun successDownload(message: String, checkStatus: TSourceTypeCheckStatus): AgentResponse<TSourceTypeCheckStatus> {
+ return AgentResponse<TSourceTypeCheckStatus>().also {
+ it.code = AgentCode.SUCCESS
+ it.agentMsg = message
+ it.payload = sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus.apply {
+ this.checkFileOk = true
+ this.remark = message
+ })
+ }
+ }
+
+ private fun doBatchSaveYnrccPayCheckDetails(chkfile: TTransactionChkfile, list: ArrayList<YnrccPayChkfile>): Int {
+ try {
+ transactionReconciliationService.doBatchSaveYnrccPayTransactionChkDtl(chkfile, list)
+ return 0 //批量保存成功,无失败
+ } catch (e1: Exception) {
+ }
+
+ //批量保存有异常,逐笔保存
+ var failcnt = 0
+ var index = 1
+ for (bean in list) {
+ try {
+ transactionReconciliationService.saveYnrccPayTransactionChkDtl(chkfile, bean, index++)
+ } catch (e2: Exception) {
+ failcnt++
+ e2.printStackTrace()
+ continue
+ }
+ }
+ return failcnt
+ }
+
+}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt
index 19f5064..03827e5 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt
@@ -48,6 +48,7 @@
.exception(undeclared.code(), undeclared, "业务处理错误"))
}
+ ex.printStackTrace()
return ResponseEntity.ok().body(ResponseBodyBuilder.create()
.exception(TradeErrorCode.BUSINESS_DEAL_ERROR, undeclared, "业务处理报错"))
}
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/async_tasks.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/async_tasks.kt
index f01d870..fd77c55 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/async_tasks.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/async_tasks.kt
@@ -7,6 +7,7 @@
import com.supwisdom.dlpay.api.domain.TShopdtl
import com.supwisdom.dlpay.api.domain.TTransactionMain
import com.supwisdom.dlpay.api.repositories.ShopaccService
+import com.supwisdom.dlpay.api.service.ConsumePayService
import com.supwisdom.dlpay.api.service.DtlQueryResultService
import com.supwisdom.dlpay.api.service.TransactionServiceProxy
import com.supwisdom.dlpay.exception.TransactionException
@@ -123,6 +124,9 @@
@Autowired
private lateinit var systemUtilService: SystemUtilService
+ @Autowired
+ lateinit var consumePayService: ConsumePayService
+
@Async("queryAgentPayResult")
fun queryResult(transaction: TTransactionMain, qcnt: Int) {
try {
@@ -148,31 +152,41 @@
transaction.sourceType + "Agent")
logger.info("refno=[${transaction.refno}]开始第" + (qcnt + 1) + "次查询支付结果:")
+ var endFlag = false
val resp = service.query(transaction)
when (resp.code) {
AgentCode.SUCCESS -> {
//查询成功
when (resp.dtlStatus) {
- DtlStatus.SUCCESS ->
+ DtlStatus.SUCCESS -> {
+ endFlag = true
transactionService.success(transaction.refno, resp.agentRefno, false) //流水成功
+ }
DtlStatus.REFUND -> {
//流水已退款 TODO:流水成功后才退款,无查询原成功流水逻辑
+ endFlag = true
logger.error("refno=[${transaction.refno}]查询结果为:已退款!!!")
return
}
DtlStatus.PARTIAL_REFUND -> {
//流水已部分退款 TODO:暂无逻辑
+ endFlag = true
logger.error("refno=[${transaction.refno}]查询结果为:已部分退款!!!")
return
}
else -> {
//流水失败
+ endFlag = true
transactionService.fail(transaction.refno, "查询流水状态为交易失败")
}
}
}
- AgentCode.REFNO_NOT_EXISTS ->
- transactionService.fail(transaction.refno, "银行流水不存在") //银行返回流水不存在
+ AgentCode.REFNO_NOT_EXISTS -> {
+ if(TradeDict.REVERSE_FLAG_NONE == transaction.reverseType) {
+ endFlag = true
+ transactionService.fail(transaction.refno, "银行流水不存在") //银行返回流水不存在
+ }
+ }
AgentCode.REQUIRE_QUERY -> {
queryResult(transaction, qcnt + 1) //查询次数加1
}
@@ -181,6 +195,36 @@
logger.error("查询refno=[${transaction.refno}]流水结果返回失败:code=[${resp.agentCode}],message=[${resp.agentMsg}]")
}
}
+
+ //fixme: 撤销或退款可能不需要传商户订单号,必须查询原流水状态
+ if (!endFlag && (TradeDict.REVERSE_FLAG_CANCEL == transaction.reverseType || TradeDict.REVERSE_FLAG_REFUND == transaction.reverseType)) {
+ consumePayService.getTransactionMainDtl(transaction.reverseRefno, null, null)?.let {
+ val origResp = service.query(it) //冲正流水,只能查询原始流水是否为退款状态
+ when (origResp.code) {
+ AgentCode.SUCCESS ->{
+ when (origResp.dtlStatus) {
+ DtlStatus.SUCCESS ->
+ transactionService.fail(transaction.refno, "查询确认退款失败!") //原始流水还是成功状态,则退款流水必定失败!!!
+ DtlStatus.REFUND -> {
+ //流水已退款
+ transactionService.success(transaction.refno, origResp.agentRefno, false) //TODO: 确保这条原始流水只有一笔全额冲正流水成功!!!
+ }
+ DtlStatus.PARTIAL_REFUND -> {
+ //流水已部分退款 TODO:暂无逻辑
+ }
+ else -> {
+ //流水失败 无逻辑
+ }
+ }
+ }
+ else -> {
+ //其他都重新查
+ queryResult(transaction, qcnt + 1) //查询次数加1
+ }
+ }
+ }
+ }
+
} catch (ex: Exception) {
ex.printStackTrace()
}
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
index 21edbe8..5c3163c 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
@@ -5,6 +5,8 @@
import com.supwisdom.dlpay.api.exception.RequestParamCheckException
import com.supwisdom.dlpay.framework.util.*
import com.supwisdom.dlpay.util.DesUtil
+import java.util.*
+import kotlin.collections.ArrayList
class DaliDatasyncParam {
var app_id: String = ""
@@ -85,4 +87,59 @@
var errmsg: String = ""
}
+/**
+ * 农商行推送线下签约数据报文
+ * */
+class YnrccSendSignInfoParam {
+ var appId: String = ""
+ var bankCardNo: String = ""
+ var idType: String = ""
+ var idNo: String = ""
+ var phone: String = ""
+ var signStatus: String = ""
+ var timestamp: String = ""
+ var signType: String = ""
+ var sign: String = ""
+
+ fun checkParam(): Boolean {
+ if (StringUtil.isEmpty(appId)) {
+ throw RequestParamCheckException("请求参数错误[应用ID为空]")
+ }
+ if(StringUtil.isEmpty(bankCardNo)){
+ throw RequestParamCheckException("请求参数错误[银行卡号为空]")
+ }
+ if (StringUtil.isEmpty(idType)) {
+ throw RequestParamCheckException("请求参数错误[证件类型为空]")
+ }
+ if (StringUtil.isEmpty(idNo)) {
+ throw RequestParamCheckException("请求参数错误[证件号码为空]")
+ }
+ if (StringUtil.isEmpty(phone)) {
+ throw RequestParamCheckException("请求参数错误[手机号为空]")
+ }
+ if (StringUtil.isEmpty(phone)) {
+ throw RequestParamCheckException("请求参数错误[手机号为空]")
+ }
+ if(!listOf("Y","N").contains(signStatus)){
+ throw RequestParamCheckException("请求参数错误[签约状态(Y/N)]")
+ }
+ if (!DateUtil.checkDatetimeValid(timestamp, DateUtil.DATETIME_FMT)) {
+ throw RequestParamCheckException("请求参数错误[时间戳]")
+ }
+ if (StringUtil.isEmpty(signType)
+ || !"HmacSHA256".equals(signType, true)) {
+ throw RequestParamCheckException("请求参数错误[签名算法]")
+ }
+ if (StringUtil.isEmpty(sign)) {
+ throw RequestParamCheckException("请求参数错误[签名为空]")
+ }
+ return true
+ }
+
+ fun checkSign(key: String): Boolean {
+ val signData ="appId=$appId&bankCardNo=$bankCardNo&idType=$idType&idNo=$idNo&phone=$phone&signStatus=$signStatus×tamp=$timestamp"
+ return sign.equals(HmacUtil.HMACSHA256(signData, key), true)
+ }
+}
+
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
index 692be0c..da34d6d 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
@@ -11,12 +11,11 @@
import com.supwisdom.dlpay.api.bean.groups.InitAction
import com.supwisdom.dlpay.api.domain.TSourceType
import com.supwisdom.dlpay.api.service.*
-import com.supwisdom.dlpay.api.util.Constants
import com.supwisdom.dlpay.exception.TransactionCheckException
import com.supwisdom.dlpay.framework.ResponseBodyBuilder
import com.supwisdom.dlpay.framework.service.SystemUtilService
-import com.supwisdom.dlpay.framework.tenant.TenantContext
import com.supwisdom.dlpay.framework.util.*
+import mu.KotlinLogging
import org.apache.commons.lang3.StringUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.ApplicationContext
@@ -59,6 +58,11 @@
@Autowired
private lateinit var qrCodeService: QRCodeService
+ @Autowired
+ private lateinit var ynrccNetPayBusinessService: YnrccNetPayBusinessService
+
+ private val logger = KotlinLogging.logger { }
+
/**
* ============================================================================
* 消费流水结果查询统一接口
@@ -838,5 +842,254 @@
})
}
+ /**
+ * ============================================================================
+ * 农商行网关快捷支付【初始化下单】
+ * ============================================================================
+ * */
+ @PostMapping("/ynrccpay/order")
+ fun ynrccPayOrder(@Valid @RequestBody param: YnrccPayOrderParam): ResponseEntity<Any> {
+ val userSign = ynrccNetPayBusinessService.queryUserYnrccPaySignInfo(param.bankcardno, param.shopaccno)
+ if (null == userSign || !userSign.isSignFlag || StringUtil.isEmpty(userSign.customerSignNo)) {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.BUSINESS_USER_NO_SIGN, "用户未签约农商行网关快捷支付!"))
+ }
+ val person = userService.findOnePersonByUserid(param.userid)
+ if (person.userid != userSign.userid) {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.INPUT_DATA_ERROR, "银行卡持有人错误!"))
+ }
+ val dtlType = consumePayService.getDtltypeDictionary(param.dtltype, Dictionary.DTLTYPES)
+ if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_YNRCC_PAY)) {
+ val account = accountUtilServcie.readAccount(person.userid)
+ val shopacc = accountUtilServcie.readShopbyShopaccno(param.shopaccno)
+ val subject = accountUtilServcie.readSubject(Subject.SUBJNO_YNRCC_NETPAY)
+ val transaction = TransactionBuilder().apply {
+ setTransInfo(param.transdate, param.transtime,
+ TradeCode.TRANSCODE_YNRCC_NETPAY,
+ TradeDict.PAYTYPE_YNRCC_PAY)
+ setOutTransInfo(shopacc.shopaccno, param.billno)
+ operator(param.shopaccno, TradeDict.OPERTYPE_SHOP)
+ payinfo = userSign.customerSignNo //存放签约协议号
+ description = dtlType.dictcaption
+ dtltype = param.dtltype
+ }.person(account).apply {
+ setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_OUT)
+ setOpposite(AccountProxy(shopacc))
+ }.and().shop(shopacc).apply {
+ setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_IN)
+ setOpposite(AccountProxy(account))
+ }.and().addDebitCreditRecord(AccountProxy(subject), AccountProxy(account),
+ param.amount / 100.0, dtlType.dictcaption)
+ .addDebitCreditRecord(AccountProxy(account), AccountProxy(shopacc),
+ param.amount / 100.0, dtlType.dictcaption)
+ .also {
+// param.feelist?.also {
+// TODO("feelist 费用清单暂无!")
+// }
+ }.init(transactionService)
+
+ //创建初始化流水后,返回客户端sdk需要的支付参数
+ val resp = ynrccNetPayBusinessService.doYnrccPayInit(transaction, userSign)
+
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success(resp, "交易初始化成功"))
+ }
+
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<农商行网关快捷支付>"))
+ }
+
+ /**
+ * ============================================================================
+ * 农商行网关快捷支付【下单支付确认】
+ * ============================================================================
+ * */
+ @PostMapping("/ynrccpay/confirm")
+ fun ynrccPayConfirm(@Valid @RequestBody param: YnrccPayConfirmParam): ResponseEntity<Any> {
+ val dtl = transactionService.wip(param.refno)
+ val resp = ynrccNetPayBusinessService.doYnrccPayConfirm(dtl, param.plain, param.signature)
+ val ret = YnrccPayConfirmResponse(dtl.refno,dtl.outTradeNo,dtl.shopDtl.amount,resp.params)
+ when (resp.code) {
+ AgentCode.SUCCESS ->
+ transactionService.success(dtl.refno, resp.agentRefno, false).let {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success(ret, "交易确认成功"))
+ }
+ AgentCode.REQUIRE_QUERY -> {
+ //去查询
+ agentQueryResultTask.queryResult(dtl, 0)
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(ret, TradeErrorCode.WAIT_QUERY_RESULT, "请查询支付结果"))
+ }
+ else -> //失败
+ transactionService.fail(param.refno, resp.agentMsg).let {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(ret, TradeErrorCode.BUSINESS_DEAL_ERROR, "交易扣费失败-${resp.agentMsg}"))
+ }
+ }
+ }
+
+ /**
+ * ============================================================================
+ * 农商行网关快捷支付【退款】
+ * ============================================================================
+ * */
+ @PostMapping("/ynrccpay/refund")
+ fun ynrccPayRefund(@Valid @RequestBody param: YnrccPayRefundParam): ResponseEntity<Any> {
+ consumePayService.getTransactionMainDtl(param.refno, param.billno, param.shopaccno)?.let { mainDtl ->
+ if (mainDtl.sourceType.isNotEmpty()) {
+ //判断能否冲正
+ if (mainDtl.shop) {
+ consumePayService.checkCanReverse(mainDtl.sourceType, mainDtl.shopDtl.shopaccno)
+ } else {
+ consumePayService.checkCanReverse(mainDtl.sourceType)
+ }
+ } else {
+ throw TransactionCheckException(TradeErrorCode.TRANSDTL_STATUS_ERROR,
+ "该笔交易未定义sourcetype, 不支持退款")
+ }
+
+ val builder = TransactionBuilder().apply {
+ setTransInfo(param.transdate, param.transtime, mainDtl.transCode, mainDtl.sourceType)
+ setOutTransInfo(mainDtl.outId, param.requestbillno)
+ }
+ val refundTrans = builder.refundInit(mainDtl.refno, param.refundAmount / 100.0, transactionService)
+
+ transactionService.wip(refundTrans.refno)
+ val service = createAgentService<Any>(mainDtl.sourceType)
+ val resp = service.refund(refundTrans)
+ when (resp.code) {
+ AgentCode.SUCCESS -> {
+ transactionService.success(refundTrans.refno, resp.agentRefno, false)
+
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success(YnrccPayRefundResponse(refundTrans.refno), "交易退款成功"))
+ }
+ AgentCode.REQUIRE_QUERY -> {
+ //待查询
+ agentQueryResultTask.queryResult(refundTrans, 0)
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(YnrccPayRefundResponse(refundTrans.refno),
+ TradeErrorCode.WAIT_QUERY_RESULT, "请查询退款结果"))
+ }
+ else -> transactionService.fail(refundTrans.refno,
+ "${resp.agentCode}-${resp.agentMsg}").let {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(YnrccPayRefundResponse(refundTrans.refno),
+ TradeErrorCode.BUSINESS_DEAL_ERROR, "退款失败!${resp.agentMsg}"))
+ }
+ }
+
+ } ?: return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.TRANSACTION_NOT_EXISTS, "流水不存在"))
+ }
+
+ /**
+ * ============================================================================
+ * 直接调第三方查询流水结果 (通用)
+ * ============================================================================
+ * */
+ @PostMapping("/thirdquery")
+ fun queryDtlResultByThird(@Valid @RequestBody param: QueryDtlResultParam): ResponseEntity<Any> {
+ consumePayService.getTransactionMainDtl(param.refno, param.billno, param.shopaccno)?.let {
+ if (TradeDict.DTL_STATUS_SUCCESS == it.status || TradeDict.DTL_STATUS_FAIL == it.status) {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success(QueryTransDtlResponse(it.refno, it.outTradeNo, it.shopDtl.amount,
+ it.status, it.sourceType, it.personDtl.payinfo, it.reverseFlag,
+ it.shopDtl.transdesc,it.personDtl.remark), "查询成功"))
+ }
+
+ //发往第三方查询
+ var endFlag = false
+ val service = ApplicationUtil.findAgentPayService<Any>(applicationContext, it.sourceType + "Agent")
+ val resp = service.query(it)
+ when (resp.code) {
+ AgentCode.SUCCESS -> {
+ //查询成功
+ when (resp.dtlStatus) {
+ DtlStatus.SUCCESS -> {
+ endFlag = true
+ transactionService.success(it.refno, resp.agentRefno, false) //流水成功
+ }
+ DtlStatus.REFUND -> {
+ //流水已退款 TODO:流水成功后才退款,无查询原成功流水逻辑
+ }
+ DtlStatus.PARTIAL_REFUND -> {
+ //流水已部分退款 TODO:暂无逻辑
+ }
+ else -> {
+ //流水失败
+ endFlag = true
+ transactionService.fail(it.refno, "查询流水状态为交易失败")
+ }
+ }
+ }
+ AgentCode.REFNO_NOT_EXISTS -> {
+ if(TradeDict.REVERSE_FLAG_NONE == it.reverseType){
+ endFlag = true
+ transactionService.fail(it.refno, "银行流水不存在") //银行返回流水不存在
+ }
+ }
+ AgentCode.REQUIRE_QUERY -> {
+ //流水无结果 TODO: 还需继续查询
+ }
+ else -> {
+ //其他明确错误,查询失败
+ logger.error("向第三方查询 refno=[${it.refno}]流水结果返回失败:code=[${resp.agentCode}],message=[${resp.agentMsg}]")
+ }
+ }
+
+ //TODO: 撤销或退款可能不需要传商户订单号,必须查询原流水状态
+ if (!endFlag && (TradeDict.REVERSE_FLAG_CANCEL == it.reverseType || TradeDict.REVERSE_FLAG_REFUND == it.reverseType)) {
+ consumePayService.getTransactionMainDtl(it.reverseRefno, null, null)?.let { origDtl ->
+ val origResp = service.query(origDtl) //有冲正流水,原流水必定是成功流水。判断原流水状态是否为退款状态
+ when (origResp.code) {
+ AgentCode.SUCCESS -> {
+ when (origResp.dtlStatus) {
+ DtlStatus.SUCCESS ->
+ transactionService.fail(it.refno, "查询确认退款失败!") //原始流水还是成功状态,则退款流水必定失败!!!
+ DtlStatus.REFUND -> {
+ //流水已退款
+ transactionService.success(it.refno, origResp.agentRefno, false) //TODO: 确保这条原始流水只有一笔全额冲正流水成功!!!
+ }
+ DtlStatus.PARTIAL_REFUND -> {
+ //流水已部分退款 TODO:暂无逻辑
+ }
+ else -> {
+ //流水失败 无逻辑
+ }
+ }
+ }
+ else -> {
+ logger.error("向第三方查询 refno=[${it.refno}]冲正流水结果,原始流水支付状态查询返回失败:code=[${origResp.agentCode}],message=[${origResp.agentMsg}]")
+ }
+ }
+ }
+ }
+
+ return queryDtlResult(param) //直接查询逻辑
+
+ } ?: return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.TRANSACTION_NOT_EXISTS, "流水不存在")
+ )
+ }
+
+ /**
+ * ============================================================================
+ * 农商行网关快捷支付【第三方开放能力】
+ * ============================================================================
+ * */
+ @PostMapping("/ynrccpay/thirdAuth")
+ fun ynrccPayThirdAuth(@Valid @RequestBody param: YnrccPayThirdAuthParam): ResponseEntity<Any> {
+ val ret = ynrccNetPayBusinessService.doYnrccPayThirdAuth(param.thirdservice,param.bankcardno,param.userid)
+ return if (ret.retcode == 0) {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success(ret, "成功"))
+ } else {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(ret.retcode, ret.retmsg))
+ }
+ }
}
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 ee0d97a..d017f6e 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
@@ -4,6 +4,7 @@
import com.supwisdom.dlpay.api.bean.DaliDatasyncDetail
import com.supwisdom.dlpay.api.bean.DaliDatasyncErrorDetail
import com.supwisdom.dlpay.api.bean.DaliDatasyncParam
+import com.supwisdom.dlpay.api.bean.YnrccSendSignInfoParam
import com.supwisdom.dlpay.api.exception.RequestParamCheckException
import com.supwisdom.dlpay.api.service.DaliDatasyncService
import com.supwisdom.dlpay.framework.ResponseBodyBuilder
@@ -247,5 +248,39 @@
}
}
+ /**
+ * ============================================================================
+ * 大理卡管系统推送市民卡信息同步接口
+ * ============================================================================
+ * */
+ @PostMapping("/signsync")
+ fun daliDatasync(@RequestBody param: YnrccSendSignInfoParam): ResponseEntity<Any> {
+ try{
+ if (TenantContext.getTenantSchema() == null) TenantContext.setTenantSchema(Constants.DEFAULT_TENANTID) //fixme: tenantid设置
+ param.checkParam()
+ val appid = systemUtilService.getSysparaValue(2022)
+ val appkey = systemUtilService.getSysparaValue(2023)
+ if (StringUtil.isEmpty(appid) || StringUtil.isEmpty(appkey)) {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(1000, "系统参数未配置"))
+ } else if (appid != param.appId) {
+ throw RequestParamCheckException("请求参数错误[应用ID错误]")
+ }
+ if (!param.checkSign(appkey)) {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(2002, "签名错误"))
+ }
+
+ return ResponseEntity.ok(mapOf("retcode" to "0000", "retmsg" to "SUCCESS"))
+ }catch (ex: RequestParamCheckException) {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(2001, ex.message ?: "请求参数错误"))
+ }catch (e:Exception){
+ e.printStackTrace()
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(4000, "系统业务处理异常"))
+ }
+
+ }
}
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt
index 047cf60..cb55dad 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt
@@ -19,6 +19,7 @@
import com.supwisdom.dlpay.mobile.service.MobileApiService
import com.supwisdom.dlpay.system.bean.LevelBean
import com.supwisdom.dlpay.system.service.PointsService
+import com.supwisdom.dlpay.system.service.UserMessageService
import org.apache.commons.beanutils.BeanUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.ResponseEntity
@@ -26,6 +27,8 @@
import org.springframework.web.bind.annotation.*
import java.net.URLDecoder
import kotlin.math.roundToInt
+import javax.validation.Valid
+
@RestController
@RequestMapping("/api/user")
@@ -52,11 +55,12 @@
private lateinit var citizencardPayService: CitizencardPayService
@Autowired
private lateinit var qrcodeService: QRCodeService
-
-
@Autowired
private lateinit var transactionService: TransactionServiceProxy
-
+ @Autowired
+ private lateinit var ynrccNetPayBusinessService: YnrccNetPayBusinessService
+ @Autowired
+ private lateinit var userMessageService: UserMessageService
@PostMapping("/open")
fun openAccount(@RequestBody param: OpenUserParam): ResponseEntity<Any> {
@@ -665,4 +669,122 @@
.fail(ret.retcode, ret.retmsg))
}
}
+
+ /**
+ * 查询用户消息
+ * */
+ @PostMapping("/queryMessage")
+ fun queryUserMessage(@Valid @RequestBody param: UserQueryMessageParam): ResponseEntity<Any> {
+ val userid = param.userid ?: throw RequestParamCheckException("用户ID不能为空")
+ val pageNo = param.pageNo ?: 1
+ val pageSize = param.pageSize ?: 10
+ val page = userMessageService.queryMessageByUserid(userid, pageNo, pageSize)
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success(UserQueryMessageResponse().apply {
+ this.pageNo = page.pageNo
+ this.pageSize = page.pageSize
+ this.totalCount = page.totalCount
+ this.totalPages = page.totalPages
+ this.data = page.data
+ }, "success")
+ )
+ }
+
+ /**
+ * ============================================================================
+ * 农商行快捷支付【签约状态查询】
+ * ============================================================================
+ * */
+ @PostMapping("/ynrccpaySignQuery")
+ fun queryYnrccPaySign(@Valid @RequestBody param: YnrccPaySignQueryParam): ResponseEntity<Any> {
+ val signFlag = ynrccNetPayBusinessService.checkUserYnrccPaySignStatus(param.userid,param.bankcardno,param.shopaccno)
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success(YnrccPaySignQueryResponse(signFlag), "查询成功"))
+ }
+
+ /**
+ * ============================================================================
+ * 农商行快捷支付【签约列表查询】
+ * ============================================================================
+ * */
+ @PostMapping("/ynrccpaySignList")
+ fun queryYnrccPaySignList(@Valid @RequestBody param: YnrccPaySignListQueryParam): ResponseEntity<Any> {
+ val resp = ynrccNetPayBusinessService.doQueryYnrccPaySignList(param.userid, param.bankcardno)
+ return if (0 == resp.retcode) {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success(resp, "success"))
+ } else {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(resp.retcode, resp.retmsg))
+ }
+ }
+
+ /**
+ * ============================================================================
+ * 农商行快捷支付【签约申请】
+ * ============================================================================
+ * */
+ @PostMapping("/ynrccpaySignApply")
+ fun applyYnrccPaySign(@Valid @RequestBody param: YnrccPaySignApplyParam): ResponseEntity<Any> {
+ val resp = ynrccNetPayBusinessService.applyUserYnrccPaySign(param)
+ return if (0 == resp.retcode) {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success(resp, "success"))
+ } else {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(resp.retcode, resp.retmsg))
+ }
+ }
+
+ /**
+ * ============================================================================
+ * 农商行快捷支付【签约确认】
+ * ============================================================================
+ * */
+ @PostMapping("/ynrccpaySignConfirm")
+ fun confirmYnrccPaySign(@Valid @RequestBody param: YnrccPaySignConfirmParam): ResponseEntity<Any> {
+ val resp = ynrccNetPayBusinessService.confirmUserYnrccPaySign(param)
+ return if (0 == resp.retcode) {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success(resp, "success"))
+ } else {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(resp.retcode, resp.retmsg))
+ }
+ }
+
+ /**
+ * ============================================================================
+ * 农商行快捷支付【解约】
+ * ============================================================================
+ * */
+ @PostMapping("/ynrccpaySignCancel")
+ fun cancelYnrccPaySign(@Valid @RequestBody param:YnrccPaySignCancelParam):ResponseEntity<Any>{
+ val resp = ynrccNetPayBusinessService.cancelUserYnrccPaySign(param)
+ return if (0 == resp.retcode) {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success(resp, "success"))
+ } else {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(resp.retcode, resp.retmsg))
+ }
+ }
+
+ /**
+ * ============================================================================
+ * 农商行快捷支付【修改限额】
+ * ============================================================================
+ * */
+ @PostMapping("/ynrccpayModifyLimit")
+ fun modifyYnrccPayLimit(@Valid @RequestBody param:YnrccPayLimitModifyParam):ResponseEntity<Any>{
+ val success=false
+ if(success){
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success(YnrccPayLimitModifyResponse(), "success"))
+ }
+
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "暂无业务逻辑"))
+
+ }
}
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_reconciliation_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_reconciliation_service_impl.kt
index 9937a31..8292e63 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_reconciliation_service_impl.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_reconciliation_service_impl.kt
@@ -1,6 +1,7 @@
package com.supwisdom.dlpay.api.service.impl
import com.supwisdom.dlpay.agent.citizencard.YnrccUtil
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayChkfile
import com.supwisdom.dlpay.api.bean.YnrccChkfileBean
import com.supwisdom.dlpay.api.dao.PersondtlDao
import com.supwisdom.dlpay.api.dao.TransactionChkdtlDao
@@ -9,6 +10,7 @@
import com.supwisdom.dlpay.api.domain.TSourceTypeCheckStatus
import com.supwisdom.dlpay.api.domain.TTransactionChkdtl
import com.supwisdom.dlpay.api.domain.TTransactionChkfile
+import com.supwisdom.dlpay.api.domain.TTransactionMain
import com.supwisdom.dlpay.api.service.SourceTypeService
import com.supwisdom.dlpay.api.service.TransactionReconciliationService
import com.supwisdom.dlpay.api.service.TransactionServiceProxy
@@ -305,4 +307,72 @@
transactionChkfileDao.save(chkfile)
return sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus)
}
+
+ override fun doBatchSaveYnrccPayTransactionChkDtl(chkfile: TTransactionChkfile, list: ArrayList<YnrccPayChkfile>): Boolean {
+ var idx=1
+ for (bean in list) {
+ saveYnrccPayTransactionChkDtl(chkfile, bean, idx++)
+ }
+ return true
+ }
+
+ override fun saveYnrccPayTransactionChkDtl(chkfile: TTransactionChkfile, bean: YnrccPayChkfile, idx:Int): TTransactionChkdtl {
+ return when(bean.payFlag){
+ YnrccPayChkfile.PAY->{
+ transactionChkdtlDao.save(TTransactionChkdtl().apply {
+ this.chkfileId = chkfile.id
+ this.accdate = chkfile.accdate
+ this.sourcetype = chkfile.sourcetype
+ this.recordno = idx
+ this.amount = -1 * bean.amount.toDouble()
+ this.otherRefno = bean.agentRefno
+ this.localRefno = bean.billNo
+ this.otherAccdate = bean.clearDate
+ this.transtype = "pay"
+ this.otherStatus = "success"
+ this.remark = null
+ this.extdata = "农商行网关快捷支付"
+ this.chkresult = ConstantUtil.CHKDTL_CHKRESULT_UNCHECK
+ this.resolved = ConstantUtil.CHKDTL_RESOLVED_NONE
+ this.lastsaved = systemUtilService.sysdatetime.sysdate
+ this.tenantid = TenantContext.getTenantSchema()
+ })
+ }
+ YnrccPayChkfile.REFUND->{
+ val refno = bean.agentRefno //商户订单号
+ var localRefno = bean.billNo
+ val refundSuccessList = transactionMainDao.findByRefundSuccessTransdtl(refno)
+ if (null != refundSuccessList && refundSuccessList.size > 0) {
+ localRefno = refundSuccessList[0].refno //成功的退款流水
+ } else {
+ val refundTransdtlList = transactionMainDao.findByRefundTransdtl(refno)
+ if (null != refundTransdtlList && refundTransdtlList.size > 0) {
+ localRefno = refundTransdtlList[0].refno //第一笔退款的流水
+ }
+ }
+
+ transactionChkdtlDao.save(TTransactionChkdtl().apply {
+ this.chkfileId = chkfile.id
+ this.accdate = chkfile.accdate
+ this.sourcetype = chkfile.sourcetype
+ this.recordno = idx
+ this.amount = bean.amount.toDouble()
+ this.otherRefno = bean.billNo
+ this.localRefno = localRefno
+ this.otherAccdate = bean.clearDate
+ this.transtype = "refund"
+ this.otherStatus = "success"
+ this.remark = null
+ this.extdata = "农商行网关快捷支付退款[${bean.agentRefno}]"
+ this.chkresult = ConstantUtil.CHKDTL_CHKRESULT_UNCHECK
+ this.resolved = ConstantUtil.CHKDTL_RESOLVED_NONE
+ this.lastsaved = systemUtilService.sysdatetime.sysdate
+ this.tenantid = TenantContext.getTenantSchema()
+ })
+ }
+ else -> {
+ throw TransactionException(97, "不能识别对账单明细中交易代码[${bean.payFlag}]!")
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/ynrcc_netpay_business_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/ynrcc_netpay_business_service.kt
new file mode 100644
index 0000000..bd6be6c
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/ynrcc_netpay_business_service.kt
@@ -0,0 +1,387 @@
+package com.supwisdom.dlpay.api.service.impl
+
+import com.csii.ynrcc.open.api.service.User
+import com.csii.ynrcc.open.api.service.YNRCCOpenServiceApi
+import com.supwisdom.dlpay.agent.AgentCode
+import com.supwisdom.dlpay.agent.AgentResponse
+import com.supwisdom.dlpay.agent.DtlStatus
+import com.supwisdom.dlpay.agent.citizencard.YnrccRespCode
+import com.supwisdom.dlpay.agent.service.YnrccNetPayService
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayResp
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayUtil
+import com.supwisdom.dlpay.api.bean.*
+import com.supwisdom.dlpay.api.dao.CardDao
+import com.supwisdom.dlpay.api.dao.PersonDao
+import com.supwisdom.dlpay.api.domain.TTransactionMain
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException
+import com.supwisdom.dlpay.api.service.SourceTypeService
+import com.supwisdom.dlpay.api.service.TransactionService
+import com.supwisdom.dlpay.api.service.YnrccNetPayBusinessService
+import com.supwisdom.dlpay.api.types.IDTypes
+import com.supwisdom.dlpay.citizencard.dao.YnrccPaySignDao
+import com.supwisdom.dlpay.citizencard.dao.YnrccPayThirdappDao
+import com.supwisdom.dlpay.citizencard.domain.TYnrccPaySign
+import com.supwisdom.dlpay.exception.TransactionProcessException
+import com.supwisdom.dlpay.framework.dao.ShopaccDao
+import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.MoneyUtil
+import com.supwisdom.dlpay.framework.util.StringUtil
+import com.supwisdom.dlpay.framework.util.TradeDict
+import com.supwisdom.dlpay.framework.util.TradeErrorCode
+import com.supwisdom.dlpay.util.ConstantUtil
+import mu.KotlinLogging
+import org.springframework.stereotype.Service
+import java.util.ArrayList
+
+@Service
+class YnrccNetPayBusinessServiceImpl(val personDao: PersonDao,
+ val shopaccDao: ShopaccDao,
+ val ynrccPaySignDao: YnrccPaySignDao,
+ val cardDao: CardDao,
+ val ynrccPayThirdappDao: YnrccPayThirdappDao,
+ val transactionService: TransactionService,
+ val systemUtilService: SystemUtilService,
+ val sourceTypeService: SourceTypeService,
+ val ynrccNetPayService: YnrccNetPayService) : YnrccNetPayBusinessService {
+ private val logger = KotlinLogging.logger { }
+
+ override fun checkUserYnrccPaySignStatus(userid: String, bankcardno: String, shopaccno: String): Boolean {
+ logger.info("查询签约状态:userid=[$userid],bankcardno=[$bankcardno],shopaccno=[$shopaccno]")
+ val person = personDao.findByUserid(userid)
+ ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "用户<$userid>不存在")
+ val shopacc = shopaccDao.findByShopaccno(shopaccno)
+ ?: throw TransactionProcessException(TradeErrorCode.SHOP_NOT_EXISTS, "商户<$shopaccno>不存在")
+ if (sourceTypeService.checkShopSourceType(shopacc.shopaccno, TradeDict.PAYTYPE_YNRCC_PAY, false)) {
+ val paySign = ynrccPaySignDao.getUserSign(bankcardno, shopacc.shopaccno)
+ if (null != paySign) {
+ if (person.userid != paySign.userid) {
+ throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "银行卡持有人错误!")
+ }
+
+ return paySign.isSignFlag
+ }
+ }
+ return false
+ }
+
+ override fun applyUserYnrccPaySign(param: YnrccPaySignApplyParam): YnrccPaySignApplyResponse {
+ logger.info("申请签约参数:" + YnrccPayUtil.toJson(param))
+ val resp = YnrccPaySignApplyResponse()
+ val person = personDao.findByUserid(param.userid?.trim())
+ ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "用户<${param.userid}>不存在")
+ val shopacc = shopaccDao.findByShopaccno(param.shopaccno?.trim())
+ ?: throw TransactionProcessException(TradeErrorCode.SHOP_NOT_EXISTS, "商户<${param.shopaccno}>不存在")
+ val bankCard = cardDao.findCardByCardnoAndCardtype(param.bankcardno.trim(), ConstantUtil.CARDTYPE_BANKCARD)
+ if (null != bankCard && person.userid != bankCard.userid) {
+ resp.retcode = 99
+ resp.retmsg = "银行卡持有人错误!"
+ return resp
+ }
+ val idType = IDTypes.findByValue(person.idtype)
+ if (idType < 0) {
+ resp.retcode = 99
+ resp.retmsg = "证件类型未识别[${person.idtype}]!"
+ return resp
+ }
+ sourceTypeService.checkShopSourceType(shopacc.shopaccno, TradeDict.PAYTYPE_YNRCC_PAY, false)
+
+ var userSign = ynrccPaySignDao.getUserSign(param.bankcardno, shopacc.shopaccno) ?: TYnrccPaySign().apply {
+ this.bankcardno = param.bankcardno.trim()
+ this.shopaccno = shopacc.shopaccno
+ this.userid = person.userid
+ this.status = TradeDict.STATUS_NORMAL
+ this.isSignFlag = false
+ this.createtime = systemUtilService.sysdatetime.hostdatetime
+ }
+ if (person.userid != userSign.userid) {
+ resp.retcode = 99
+ resp.retmsg = "银行卡持有人不匹配!"
+ return resp
+ } else if (userSign.isSignFlag) {
+ resp.retcode = 99
+ resp.retmsg = "该卡已签约!"
+ return resp
+ }
+
+ var isAuthSign = false
+ var signDataResp = YnrccPayResp()
+ val existSigns = ynrccPaySignDao.queryOtherShopSign(param.bankcardno, shopacc.shopaccno)
+ if (null != existSigns && existSigns.size > 0) {
+ //已签约过,则是授权签约
+ logger.info("进入授权签约申请!")
+ isAuthSign = true
+ val oldCustomerSignNo = existSigns[0].customerSignNo
+ signDataResp = ynrccNetPayService.doApplyAuthYnrccPaySign(shopacc.shopaccno, oldCustomerSignNo) //授权签约
+ } else {
+ //首次签约
+ signDataResp = ynrccNetPayService.doApplyYnrccPaySign(shopacc.shopaccno) //初次签约
+ }
+ if (YnrccPayUtil.SUCCESS != signDataResp.code) {
+ resp.retcode = 99
+ resp.retmsg = signDataResp.message
+ return resp
+ }
+
+ if (StringUtil.isEmpty(userSign.id)) {
+ ynrccPaySignDao.save(userSign) //新创建的保存申请记录
+ }
+
+ resp.retcode = 0
+ resp.retmsg = "success"
+ resp.signNo = userSign.id
+ resp.isAuthSign = isAuthSign
+ resp.plain = signDataResp.plain
+ resp.signature = signDataResp.signature
+ resp.signUserData = YnrccPaySignUserData().apply {
+ this.name = person.name
+ this.idType = idType.toString()
+ this.idNo = person.idno
+ this.acNo = userSign.bankcardno
+ }
+ logger.info("申请签约返回:" + YnrccPayUtil.toJson(resp))
+ return resp
+ }
+
+ override fun confirmUserYnrccPaySign(param: YnrccPaySignConfirmParam): YnrccPaySignConfirmResponse {
+ logger.info("确认签约参数:" + YnrccPayUtil.toJson(param))
+ val userSign = ynrccPaySignDao.getById(param.signNo.toString())
+ ?: throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "签约申请记录<${param.signNo}>不存在!")
+
+ val data = ynrccNetPayService.doAnalysisSignature(userSign.shopaccno, param.plain, param.signature)
+ logger.info("签约确认:" + YnrccPayUtil.toJson(data))
+ val respCode = data["RespCode"]
+ if (YnrccPayUtil.SUCCESS != respCode) {
+ val errmsg = YnrccPayUtil.errcode.firstOrNull {
+ it.second.code == respCode
+ }?.second?.msg
+ throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "$respCode $errmsg")
+ }
+
+ //签约成功
+// if (data["CustomerAcNo"] != userSign.bankcardno) {
+// throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "支付账号与签约号不匹配!") // CustomerAcNo 是脱敏返回的,不判断。 6210****6743
+// }
+ if (userSign.isSignFlag && data["CustomerSignNo"] != userSign.customerSignNo) {
+ throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "用户已签约且快捷支付协议号不一致!")
+ }
+
+ if (!userSign.isSignFlag) {
+ userSign.isSignFlag = true
+ userSign.customerSignNo = data["CustomerSignNo"]?.trim()
+ userSign.signTime = systemUtilService.sysdatetime.hostdatetime
+ ynrccPaySignDao.save(userSign)
+ }
+
+ return YnrccPaySignConfirmResponse().apply {
+ this.retcode = 0
+ this.retmsg = "success"
+ this.signNo = userSign.id
+ this.data = data
+ }
+ }
+
+ override fun cancelUserYnrccPaySign(param: YnrccPaySignCancelParam): YnrccPaySignCancelResponse {
+ logger.info("申请解约参数:" + YnrccPayUtil.toJson(param))
+ val userSign = ynrccPaySignDao.getUserSign(param.bankcardno.trim(), param.shopaccno)
+ ?: throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "签约记录不存在或已解约!")
+ if (userSign.userid != param.userid) {
+ throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "持卡人错误!")
+ } else if (!userSign.isSignFlag) {
+ throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "该卡还未签约,不能解约!")
+ }
+
+ val resp = YnrccPaySignCancelResponse()
+ val cancelResp = ynrccNetPayService.doCancelYnrccPaySign(userSign.shopaccno, userSign.customerSignNo)
+ if (YnrccPayUtil.SUCCESS == cancelResp.code) {
+ //解约成功
+ userSign.status = TradeDict.STATUS_CLOSED
+ userSign.isSignFlag = false
+ userSign.cancelTime = systemUtilService.sysdatetime.hostdatetime
+ ynrccPaySignDao.save(userSign)
+
+ resp.retcode = 0
+ resp.retmsg = "success"
+ resp.signNo = userSign.id
+ return resp
+ }
+
+ resp.retcode = 99
+ resp.retmsg = cancelResp.message
+ return resp
+ }
+
+ override fun queryUserYnrccPaySign(bankcardno: String, shopaccno: String): TYnrccPaySign {
+ return ynrccPaySignDao.getUserSign(bankcardno.trim(), shopaccno.trim())
+ ?: throw RequestParamCheckException("银行卡签约记录不存在!")
+ }
+
+ override fun queryUserYnrccPaySignInfo(bankcardno: String, shopaccno: String): TYnrccPaySign? {
+ return ynrccPaySignDao.getUserSign(bankcardno.trim(), shopaccno.trim())
+ }
+
+ override fun doYnrccPayInit(transdtl: TTransactionMain, userSign: TYnrccPaySign): YnrccPayOrderResponse {
+ if (StringUtil.isEmpty(transdtl.refno) || null == transdtl.shopDtl || null == transdtl.shopDtl.amount) {
+ throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "流水初始化错误!")
+ } else if (TradeDict.DTL_STATUS_SUCCESS == transdtl.status) {
+ throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "非初始化交易流水!")
+ } else if (TradeDict.PAYTYPE_YNRCC_PAY != transdtl.sourceType || transdtl.shopDtl.shopaccno != userSign.shopaccno || transdtl.shopDtl.payInfo != userSign.customerSignNo) {
+ throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "交易流水与签约信息不符!")
+ }
+
+ val refno = transdtl.refno
+ val shopaccno = transdtl.shopDtl.shopaccno
+ val amount = MoneyUtil.YuanToFen(transdtl.shopDtl.amount)
+ val hosttime = systemUtilService.sysdatetime.hosttime
+ val transDateTime = "${transdtl.shopDtl.accdate}$hosttime" //下单日期(记账日期,退款时用到)+下单时间
+ val billno = transdtl.outTradeNo //billno放附加信息
+ val productInfo = "农商行网关快捷支付[${transdtl.shopDtl.transdesc}]"; //商品描述
+ val person = personDao.findByUserid(userSign.userid)
+ ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "用户不存在!")
+ val orderResp = ynrccNetPayService.doYnrccPayInit(shopaccno, refno, amount, transDateTime,
+ productInfo, billno, person.name, person.email, userSign.customerSignNo)
+
+ if (YnrccPayUtil.SUCCESS != orderResp.code) {
+ throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, orderResp.message)
+ }
+
+ val resp = YnrccPayOrderResponse()
+ resp.retcode = 0
+ resp.retmsg = "success"
+ resp.refno = refno
+ resp.billno = billno
+ resp.amount = transdtl.shopDtl.amount
+ resp.plain = orderResp.plain
+ resp.signature = orderResp.signature
+
+ logger.info("下单返回:" + YnrccPayUtil.toJson(resp))
+ return resp
+ }
+
+ override fun doYnrccPayConfirm(transaction: TTransactionMain, plain: String, signature: String): AgentResponse<DtlStatus> {
+ logger.info("支付确认参数: refno=[${transaction.refno}],plain=[$plain],signature=[$signature]")
+ if (TradeDict.DTL_STATUS_SUCCESS == transaction.status) {
+ throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水已入账!")
+ }
+
+ val data = ynrccNetPayService.doAnalysisSignature(transaction.shopDtl.shopaccno, plain, signature)
+ logger.info("支付确认:" + YnrccPayUtil.toJson(data))
+ val respCode = data["RespCode"]?.trim()
+ val orderNo = data["OrderNo"]?.trim()
+ val payAmt = data["Amount"]?.trim()
+ val tradeNo = data["TransSeqNo"]?.trim()
+ if (transaction.refno != orderNo) {
+ throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "流水号错误,非此笔流水的确认信息!")
+ } else if (transaction.shopDtl.amount != payAmt?.toDouble()) {
+ throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "支付金额与流水交易金额不匹配!")
+ }
+
+ val agentCode = YnrccPayUtil.errcode.firstOrNull {
+ it.second.code == respCode
+ } ?: org.springframework.data.util.Pair.of(AgentCode.COMMON_ERROR,
+ YnrccRespCode(respCode, "未知错误[$respCode]"))
+
+ return AgentResponse<DtlStatus>().also {
+ it.code = agentCode.first
+ it.agentCode = agentCode.second.code
+ it.agentMsg = agentCode.first.message() + "-" + agentCode.second.msg
+ it.agentRefno = tradeNo
+ it.params = data
+ }
+ }
+
+ override fun doQueryYnrccPaySignList(userid: String?, bankcardno: String?): YnrccPaySignListQueryResponse {
+ val resp = YnrccPaySignListQueryResponse()
+ val signList = when (userid.isNullOrBlank()) {
+ true -> ynrccPaySignDao.queryActiveSignsByBankcardno(bankcardno?.trim())
+ false -> when (bankcardno.isNullOrBlank()) {
+ true -> ynrccPaySignDao.queryActiveSignsByUserid(userid?.trim())
+ false -> ynrccPaySignDao.queryActiveSignsByUseridAndBankcardno(userid?.trim(), bankcardno?.trim())
+ }
+ }
+ if (signList.isNullOrEmpty()) {
+ resp.retcode = 99
+ resp.retmsg = "无签约信息"
+ return resp
+ }
+
+ val data = ArrayList<YnrccPaySignInfo>()
+ for (sign in signList) {
+ data.add(YnrccPaySignInfo().apply {
+ this.signNo = sign.id
+ this.bankcardno = sign.bankcardno
+ this.shopaccno = sign.shopaccno
+ this.shopname = shopaccDao.getByShopaccno(sign.shopaccno)?.shopname ?: ""
+ this.signtime = sign.signTime
+ this.userid = sign.userid
+ })
+ }
+
+ resp.retcode = 0
+ resp.retmsg = "success"
+ resp.data = data
+ return resp
+ }
+
+ override fun doYnrccPayThirdAuth(thirdSrv: String, bankcardno: String, userid: String): YnrccPayThirdAuthResponse {
+ logger.info("中间缴费请求参数:thirdSrv=[$thirdSrv],bankcardno=[$bankcardno],userid=[$userid]")
+ val resp = YnrccPayThirdAuthResponse()
+ resp.retcode = 99
+
+ val thirdConfs = ynrccPayThirdappDao.queryYnrccPayThirdConfig()
+ if (null == thirdConfs || thirdConfs.isEmpty()) {
+ resp.retcode = 99
+ resp.retmsg = "中间缴费对接参数未配置!"
+ return resp
+ } else if (thirdConfs.size != 1) {
+ resp.retcode = 99
+ resp.retmsg = "中间缴费对接参数未指定!"
+ return resp
+ }
+
+ val config = thirdConfs[0] //获取配置信息(第三方服务标识thirdSrv暂时无用)
+ var handler = YNRCCOpenServiceApi.getInstance(config.mchId, config.appId, config.token, config.pubkey)
+ //获取客户端sdk配置信息
+ val sdkConfigData = handler.getSDKConfigData()
+
+ //获取客户端SDK访问开放服务所需参数
+ val person = personDao.findByUserid(userid)
+ ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "用户不存在!")
+ if (person.mobile.isNullOrBlank()) {
+ resp.retcode = 99
+ resp.retmsg = "用户手机号为空!"
+ return resp
+ }
+ //fixme: 判断bankcard是否该userid所有
+ if (ynrccPaySignDao.countByBankcardno(bankcardno?.trim()) > 0) {
+ if (ynrccPaySignDao.countByBankcardnoAndUserid(bankcardno?.trim(), person.userid) < 1) {
+ resp.retcode = 99
+ resp.retmsg = "银行卡持有人错误!"
+ return resp
+ }
+ } else if (cardDao.countByBankCardNo(bankcardno?.trim()) > 0) {
+ if (cardDao.countByBankCardNoAndUserid(bankcardno?.trim(), person.userid) < 1) {
+ resp.retcode = 99
+ resp.retmsg = "银行卡持有人错误!"
+ return resp
+ }
+ }
+
+// val user = User("测试", "420117198802234181", "13584821704", "623100095486551526") //测试User
+ val user = User(person.name, person.idno, person.mobile, bankcardno)
+ val access2ServiceData = handler.getAccess2ServiceData(user)
+
+ resp.retcode = 0
+ resp.retmsg = "success"
+ resp.thirdService = thirdSrv
+ resp.user = YnrccPayThirdAuthUser().apply {
+ this.name = user.name
+ this.idNo = user.idNo
+ this.phone = user.phone
+ this.acNo = user.acNo
+ }
+ resp.sdkConfigData = sdkConfigData
+ resp.access2ServiceData = access2ServiceData
+ logger.info("中间缴费成功返回:" + YnrccPayUtil.toJson(resp))
+ return resp
+ }
+}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_reconciliation_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_reconciliation_service.kt
index d7ce27d..5c4e132 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_reconciliation_service.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_reconciliation_service.kt
@@ -1,5 +1,6 @@
package com.supwisdom.dlpay.api.service
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayChkfile
import com.supwisdom.dlpay.api.bean.YnrccChkfileBean
import com.supwisdom.dlpay.api.domain.TSourceTypeCheckStatus
import com.supwisdom.dlpay.api.domain.TTransactionChkdtl
@@ -65,6 +66,10 @@
@Transactional(rollbackFor = [Exception::class])
fun doConfirmChkfileStatus(chkfile: TTransactionChkfile, checkStatus: TSourceTypeCheckStatus): TSourceTypeCheckStatus
+ @Transactional(rollbackFor = [Exception::class])
+ fun doBatchSaveYnrccPayTransactionChkDtl(chkfile: TTransactionChkfile, list: ArrayList<YnrccPayChkfile>): Boolean
+ @Transactional(rollbackFor = [Exception::class])
+ fun saveYnrccPayTransactionChkDtl(chkfile: TTransactionChkfile, bean: YnrccPayChkfile, idx: Int): TTransactionChkdtl
}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/ynrcc_netpay_business_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/ynrcc_netpay_business_service.kt
new file mode 100644
index 0000000..4884f07
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/ynrcc_netpay_business_service.kt
@@ -0,0 +1,40 @@
+package com.supwisdom.dlpay.api.service
+
+import com.supwisdom.dlpay.agent.AgentResponse
+import com.supwisdom.dlpay.agent.DtlStatus
+import com.supwisdom.dlpay.api.bean.*
+import com.supwisdom.dlpay.api.domain.TTransactionMain
+import com.supwisdom.dlpay.citizencard.domain.TYnrccPaySign
+import org.springframework.transaction.annotation.Transactional
+
+interface YnrccNetPayBusinessService {
+ @Transactional(rollbackFor = [Exception::class], readOnly = true)
+ fun checkUserYnrccPaySignStatus(userid: String, bankcardno: String, shopaccno: String): Boolean
+
+ @Transactional(rollbackFor = [Exception::class])
+ fun applyUserYnrccPaySign(param: YnrccPaySignApplyParam): YnrccPaySignApplyResponse
+
+ @Transactional(rollbackFor = [Exception::class])
+ fun confirmUserYnrccPaySign(param: YnrccPaySignConfirmParam): YnrccPaySignConfirmResponse
+
+ @Transactional(rollbackFor = [Exception::class])
+ fun cancelUserYnrccPaySign(param: YnrccPaySignCancelParam): YnrccPaySignCancelResponse
+
+ @Transactional(rollbackFor = [Exception::class], readOnly = true)
+ fun queryUserYnrccPaySign(bankcardno: String, shopaccno: String): TYnrccPaySign
+
+ @Transactional(rollbackFor = [Exception::class], readOnly = true)
+ fun queryUserYnrccPaySignInfo(bankcardno: String, shopaccno: String): TYnrccPaySign?
+
+ @Transactional(rollbackFor = [Exception::class], readOnly = true)
+ fun doYnrccPayInit(transdtl: TTransactionMain, userSign: TYnrccPaySign): YnrccPayOrderResponse
+
+ @Transactional(rollbackFor = [Exception::class])
+ fun doYnrccPayConfirm(transaction: TTransactionMain, plain: String, signature: String): AgentResponse<DtlStatus>
+
+ @Transactional(rollbackFor = [Exception::class])
+ fun doQueryYnrccPaySignList(userid: String?, bankcardno: String?): YnrccPaySignListQueryResponse
+
+ @Transactional(rollbackFor = [Exception::class])
+ fun doYnrccPayThirdAuth(thirdSrv: String, bankcardno: String, userid: String): YnrccPayThirdAuthResponse
+}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/controller/framework_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/controller/framework_controller.kt
index a55845f..c5e603c 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/controller/framework_controller.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/controller/framework_controller.kt
@@ -1,17 +1,24 @@
package com.supwisdom.dlpay.framework.controller
+import com.google.gson.Gson
import com.jcabi.manifests.Manifests
+import com.supwisdom.dlpay.agent.service.YnrccNetPayService
import com.supwisdom.dlpay.api.bean.ApiVersionResponse
import com.supwisdom.dlpay.framework.ResponseBodyBuilder
+import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/api/common")
class AboutController {
+ @Autowired
+ lateinit var ynrccNetPayService: YnrccNetPayService
+
@GetMapping("/version")
fun version(): ResponseEntity<Any> {
return try {
@@ -24,4 +31,27 @@
.success(ApiVersionResponse("unknown")))
}
}
+
+ /**
+ * 查看农商行快捷支付对账单
+ * */
+ @GetMapping("/ynrccpaychkfile")
+ fun testYnrccpayChkfile(
+ @RequestParam("accdate") accdate: String,
+ @RequestParam("shopaccno") shopaccno: String
+ ): ResponseEntity<Any> {
+ return try {
+ val resp = ynrccNetPayService.doQueryYnrccPayChkfile(accdate, shopaccno)
+
+ ResponseEntity.ok(
+ ResponseBodyBuilder.create()
+ .success(Gson().toJson(resp))
+ )
+ } catch (e: IllegalArgumentException) {
+ ResponseEntity.ok(
+ ResponseBodyBuilder.create()
+ .fail(99, "throw exception!")
+ )
+ }
+ }
}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/domain/TBMobileUser.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/domain/TBMobileUser.kt
index 339e607..0fc534c 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/domain/TBMobileUser.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/domain/TBMobileUser.kt
@@ -6,7 +6,6 @@
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.userdetails.UserDetails
import javax.persistence.*
-import javax.validation.constraints.NotNull
@Entity
@Table(name = "TB_MOBILE_USER",indexes = [Index(name = "mobile_user_loginid_idx", columnList = "loginid", unique = true)])
@@ -54,8 +53,7 @@
* 登录id
* */
- @Column(name = "loginid", length = 64)
- @NotNull
+ @Column(name = "loginid", nullable = false, length = 64)
var loginid: String = ""
/**
diff --git a/payapi/src/main/resources/payment_merchant.properties b/payapi/src/main/resources/payment_merchant.properties
new file mode 100644
index 0000000..871bd53
--- /dev/null
+++ b/payapi/src/main/resources/payment_merchant.properties
@@ -0,0 +1,14 @@
+development=no
+# \u8BC1\u4E66\u8DEF\u5F84,\u5FC5\u987B\u6307\u5B9A\u670D\u52A1\u5668\u7AEF\u8BC1\u4E66\u5BB9\u5668\u7EDD\u5BF9\u8DEF\u5F84
+#cafile=D:/ynrcc_test/merchant.jks
+cafile=config/merchant.jks
+# \u8BC1\u4E66\u5E93\u5BC6\u7801
+store_password=111111
+# \u7528\u4E8E\u5546\u6237\u7B7E\u540D\u7684\u79D8\u94A5\u522B\u540D
+#key_alias=merchant_key
+key_alias=ynrcc
+# \u79D8\u94A5\u5BC6\u7801
+#key_password=881220
+key_password=111111
+# \u9A8C\u7B7E\u79D8\u94A5\u522B\u540D
+alias_paygate=alias_paygate
\ No newline at end of file