改进消费接口,支持了退款业务
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/annotation/TransDate.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/annotation/TransDate.java
new file mode 100644
index 0000000..612d6f2
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/annotation/TransDate.java
@@ -0,0 +1,22 @@
+package com.supwisdom.dlpay.api.annotation;
+
+
+import com.supwisdom.dlpay.api.validator.TransDateValidator;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.*;
+
+@Constraint(validatedBy = {TransDateValidator.class})
+@Documented
+@Target({ElementType.METHOD, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TransDate {
+ String message() default "交易日期格式错误";
+
+ Class<?>[] groups() default {};
+
+ Class<? extends Payload>[] payload() default {};
+
+ String value() default "";
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/annotation/TransTime.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/annotation/TransTime.java
new file mode 100644
index 0000000..ddb74c2
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/annotation/TransTime.java
@@ -0,0 +1,22 @@
+package com.supwisdom.dlpay.api.annotation;
+
+
+import com.supwisdom.dlpay.api.validator.TransTimeValidator;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.*;
+
+@Constraint(validatedBy = {TransTimeValidator.class})
+@Documented
+@Target({ElementType.METHOD, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TransTime {
+ String message() default "交易时间格式错误";
+
+ Class<?>[] groups() default {};
+
+ Class<? extends Payload>[] payload() default {};
+
+ String value() default "";
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/CardBizParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/CardBizParam.java
index dd83c93..8c43519 100644
--- a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/CardBizParam.java
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/CardBizParam.java
@@ -2,6 +2,8 @@
import com.sun.java.swing.action.CancelAction;
import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.TransDate;
+import com.supwisdom.dlpay.api.annotation.TransTime;
import com.supwisdom.dlpay.api.bean.groups.ConfirmAction;
import com.supwisdom.dlpay.api.bean.groups.InitAction;
import com.supwisdom.dlpay.api.bean.groups.QueryAction;
@@ -15,10 +17,10 @@
private @NotNull(message = "操作员流水号不能为空", groups = {InitAction.class, ConfirmAction.class, QueryAction.class}) String operSeqno;
- @NotNull(groups = {InitAction.class})
+ @TransDate(groups = {InitAction.class})
private String transdate;
- @NotNull(groups = {InitAction.class})
+ @TransTime(groups = {InitAction.class})
private String transtime;
private String userid;
@@ -43,7 +45,7 @@
@NotNull(message = "交易摘要不能为空", groups = {InitAction.class})
private String summary;
- @NotNull(message = "记账日期不能为空", groups = {ConfirmAction.class, CancelAction.class, QueryAction.class})
+ @TransDate(message = "记账日期不能为空", groups = {ConfirmAction.class, CancelAction.class, QueryAction.class})
private String accdate;
@NotNull(message = "交易参考号不能为空", groups = {ConfirmAction.class, CancelAction.class, QueryAction.class})
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/CardBizRefundParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/CardBizRefundParam.java
new file mode 100644
index 0000000..70f4656
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/CardBizRefundParam.java
@@ -0,0 +1,83 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.TransDate;
+import com.supwisdom.dlpay.api.annotation.TransTime;
+import com.supwisdom.dlpay.api.bean.groups.ConfirmAction;
+import com.supwisdom.dlpay.api.bean.groups.InitAction;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+
+import javax.validation.constraints.NotNull;
+
+public class CardBizRefundParam extends APIRequestParam {
+ @NotNull(message = "操作员号不能空", groups = {InitAction.class})
+ private String operid;
+
+ @NotNull(message = "操作员流水号不能为空", groups = {InitAction.class})
+ private String operSeqno;
+
+ @NotNull(message = "原始流水参考号不能为空", groups = {InitAction.class, ConfirmAction.class})
+ private String originRefno;
+
+ @NotNull(message = "退款总金额不能为空", groups = {InitAction.class})
+ private Integer totalAmount;
+
+ @TransDate(groups = {InitAction.class})
+ private String transdate;
+
+ @TransTime(groups = {InitAction.class})
+ private String transtime;
+
+ public String getOperid() {
+ return operid;
+ }
+
+ public void setOperid(String operid) {
+ this.operid = operid;
+ }
+
+ public String getOperSeqno() {
+ return operSeqno;
+ }
+
+ public void setOperSeqno(String operSeqno) {
+ this.operSeqno = operSeqno;
+ }
+
+ public String getOriginRefno() {
+ return originRefno;
+ }
+
+ public void setOriginRefno(String originRefno) {
+ this.originRefno = originRefno;
+ }
+
+ public Integer getTotalAmount() {
+ return totalAmount;
+ }
+
+ public void setTotalAmount(Integer totalAmount) {
+ this.totalAmount = totalAmount;
+ }
+
+ public String getTransdate() {
+ return transdate;
+ }
+
+ public void setTransdate(String transdate) {
+ this.transdate = transdate;
+ }
+
+ public String getTranstime() {
+ return transtime;
+ }
+
+ public void setTranstime(String transtime) {
+ this.transtime = transtime;
+ }
+
+ @Override
+ public boolean checkParam() throws RequestParamCheckException {
+ return true;
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/CardBizResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/CardBizResponse.java
index c54a3ee..704c809 100644
--- a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/CardBizResponse.java
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/CardBizResponse.java
@@ -14,6 +14,8 @@
private Integer accountBal;
+ private String transStatus;
+
public String getRefno() {
return refno;
}
@@ -46,4 +48,12 @@
public void setAccountBal(Integer accountBal) {
this.accountBal = accountBal;
}
+
+ public String getTransStatus() {
+ return transStatus;
+ }
+
+ public void setTransStatus(String transStatus) {
+ this.transStatus = transStatus;
+ }
}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/validator/TransDateValidator.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/validator/TransDateValidator.java
new file mode 100644
index 0000000..cb5b243
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/validator/TransDateValidator.java
@@ -0,0 +1,30 @@
+package com.supwisdom.dlpay.api.validator;
+
+import com.supwisdom.dlpay.api.annotation.TransDate;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+
+public class TransDateValidator implements ConstraintValidator<TransDate, String> {
+
+ @Override
+ public boolean isValid(String value, ConstraintValidatorContext context) {
+ if (value == null || value.isEmpty()) {
+ return false;
+ }
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+ try {
+ sdf.parse(value);
+ return true;
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ @Override
+ public void initialize(TransDate constraintAnnotation) {
+ }
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/validator/TransTimeValidator.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/validator/TransTimeValidator.java
new file mode 100644
index 0000000..96ac618
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/validator/TransTimeValidator.java
@@ -0,0 +1,31 @@
+package com.supwisdom.dlpay.api.validator;
+
+import com.supwisdom.dlpay.api.annotation.TransTime;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+
+public class TransTimeValidator implements ConstraintValidator<TransTime, String> {
+
+ @Override
+ public boolean isValid(String value, ConstraintValidatorContext context) {
+ if (value == null || value.isEmpty()) {
+ return false;
+ }
+ SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
+
+ try {
+ sdf.parse(value);
+ return true;
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ @Override
+ public void initialize(TransTime constraintAnnotation) {
+ }
+}
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 1b1bcd7..e761f70 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
@@ -31,9 +31,12 @@
@PostMapping("/api/user/biz_confirm")
CardBizResponse bizConfirm(@RequestBody CardBizParam param);
+ @PostMapping("/api/user/biz_refund_init")
+ CardBizResponse bizRefundInit(@RequestBody CardBizRefundParam param);
+
@PostMapping("/api/user/biz_refund")
- CardBizResponse bizRefund(@RequestBody CardBizParam param);
+ CardBizResponse bizRefund(String refno);
@PostMapping("/api/user/biz_query")
- CardBizResponse bizQuery(@RequestBody CardBizParam param);
+ CardBizResponse bizQuery(String refno);
}
diff --git a/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/CitizenCardPayProxyTest.java b/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/CitizenCardPayProxyTest.java
index cad5c82..1916f7a 100644
--- a/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/CitizenCardPayProxyTest.java
+++ b/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/CitizenCardPayProxyTest.java
@@ -38,6 +38,8 @@
private final static String appid = "700001";
private final static String secret = "d6dd7f0d4551419d8d11736d0f28df0d";
+ private final static String operid = "1001";
+
@Autowired
private ApiLoginProxy apiLoginProxy;
@@ -235,7 +237,7 @@
CardBizParam param = new CardBizParam();
param.setTransdate(DateUtil.getNow("yyyyMMdd"));
param.setTranstime(DateUtil.getNow("HHmmss"));
- param.setOperid("1001");
+ param.setOperid(operid);
param.setOperSeqno(param.getTransdate() + param.getTranstime());
param.setTotalAmount(10000);
param.setCapitalSubjno("112201");
@@ -265,6 +267,26 @@
+ ", account " + response.getAccountBal() / 100.0
+ ", description " + response.getDescription() + " summary " + response.getRetmsg());
+
+ CardBizRefundParam refundParam = new CardBizRefundParam();
+ refundParam.setOperid(operid);
+ refundParam.setTransdate(DateUtil.getNow("yyyyMMdd"));
+ refundParam.setTranstime(DateUtil.getNow("HHmmss"));
+ refundParam.setOperSeqno(refundParam.getTransdate() + refundParam.getTranstime() + "9");
+ refundParam.setTotalAmount(10000);
+ refundParam.setOriginRefno(response.getRefno());
+ response = userProxy.bizRefundInit(refundParam);
+ assertThat("user card biz refund init " + response.getRetcode() + response.getRetmsg() + response.getException(),
+ response.getRetcode(), equalTo(0));
+
+ System.out.println("biz refund init accdate " + response.getAccdate() + " , refno " + response.getRefno()
+ + ", description " + response.getDescription() + " summary " + response.getRetmsg());
+
+ response = userProxy.bizRefund(response.getRefno());
+
+ System.out.println("biz refund accdate " + response.getAccdate() + " , refno " + response.getRefno()
+ + ", account " + response.getAccountBal() / 100.0
+ + ", description " + response.getDescription() + " summary " + response.getRetmsg());
}
@Test
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 1fda9f0..19f5064 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt
@@ -115,9 +115,9 @@
@Around("restcontroller() && postmapping() && args(@RequestBody body, ..)")
@Throws(Throwable::class)
- fun logPostMethods(joinPoint: ProceedingJoinPoint, body: Any): Any {
+ fun logPostMethods(joinPoint: ProceedingJoinPoint, body: Any?): Any {
return try {
- if (body is APIRequestParam) {
+ if (body != null && body is APIRequestParam) {
//TenantContext.setTenantSchema(body.tenantid)
body.checkParam()
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 432a84f..bc8b341 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
@@ -6,8 +6,10 @@
import com.supwisdom.dlpay.api.bean.groups.InitAction
import com.supwisdom.dlpay.api.exception.RequestParamCheckException
import com.supwisdom.dlpay.api.service.*
+import com.supwisdom.dlpay.exception.TransactionCheckException
import com.supwisdom.dlpay.exception.TransactionException
import com.supwisdom.dlpay.framework.ResponseBodyBuilder
+import com.supwisdom.dlpay.framework.tenant.TenantContext
import com.supwisdom.dlpay.framework.util.Subject
import com.supwisdom.dlpay.framework.util.TradeCode
import com.supwisdom.dlpay.framework.util.TradeDict
@@ -279,6 +281,7 @@
accdate = transaction.accdate
refno = transaction.refno
description = builder.description
+ transStatus = transaction.status
}
return ResponseBodyBuilder.successEntity(result, "${request.summary}初始化成功")
}
@@ -291,17 +294,81 @@
refno = transaction.refno
description = transaction.personDtl.transdesc
accountBal = (transaction.personDtl.aftbal * 100).roundToInt()
+ transStatus = transaction.status
}
return ResponseBodyBuilder.successEntity(response, "${request.summary}确认成功")
}
+ @PostMapping("/biz_refund_init")
+ fun userBizRefundInit(@RequestBody @Validated(InitAction::class) request: CardBizRefundParam): ResponseEntity<Any> {
+ val result = CardBizResponse()
+ val originTrans = transactionService.findTransactionByRefno(request.originRefno)
+ ?: return ResponseBodyBuilder.failEntity(result, TradeErrorCode.TRANSACTION_NOT_EXISTS,
+ "退款原交易参考号不存在")
+ if (originTrans.tenantid != TenantContext.getTenantSchema()) {
+ return ResponseBodyBuilder.failEntity(result, TradeErrorCode.INPUT_DATA_ERROR,
+ "退款交易参考号租户错误")
+ }
+
+ if (!originTrans.person) {
+ return ResponseBodyBuilder.failEntity(result, TradeErrorCode.INPUT_DATA_ERROR,
+ "指定交易流水没有个人交易明细,无法退款")
+ }
+
+ val builder = TransactionBuilder().apply {
+ this.setTransInfo(request.transdate, request.transtime, TradeCode.TRANSCODE_CARD_BIZ,
+ "balance")
+ this.setOutTransInfo(request.operid, request.operSeqno)
+ }
+ val transaction = builder.refundInit(request.originRefno, request.totalAmount / 100.0,
+ transactionService)
+
+ result.apply {
+ refno = transaction.refno
+ accdate = transaction.accdate
+ transStatus = transaction.status
+ if (transaction.person) {
+ description = transaction.personDtl.transdesc
+ }
+ }
+ return ResponseBodyBuilder.successEntity(result, "初始化成功")
+ }
+
@PostMapping("/biz_refund")
- fun userBizRefund(@RequestBody @Valid request: CardBizParam): ResponseEntity<Any> {
- return ResponseEntity.ok(ResponseBodyBuilder.create().success())
+ fun userBizRefund(@RequestBody refno: String): ResponseEntity<Any> {
+ val result = CardBizResponse()
+ val transaction = transactionService.success(refno)
+ result.apply {
+ this.refno = transaction.refno
+ accdate = transaction.accdate
+ transStatus = transaction.status
+ if (transaction.person) {
+ description = transaction.personDtl.transdesc
+ accountBal = (transaction.personDtl.aftbal * 100.0).roundToInt()
+ }
+ }
+ return ResponseBodyBuilder.failEntity(result, TradeErrorCode.INPUT_DATA_ERROR, "未实现")
}
@GetMapping("/biz_query")
- fun userBizQuery(@RequestBody @Valid request: CardBizParam): ResponseEntity<Any> {
- return ResponseEntity.ok(ResponseBodyBuilder.create().success())
+ fun userBizQuery(@RequestBody refno: String): ResponseEntity<Any> {
+ val transaction = transactionService.findTransactionByRefno(refno)
+ ?: throw TransactionCheckException(TradeErrorCode.TRANSACTION_NOT_EXISTS
+ , "交易不存在")
+ val result = CardBizResponse()
+ if (transaction.tenantid != TenantContext.getTenantSchema()) {
+ return ResponseBodyBuilder.failEntity(result, TradeErrorCode.INPUT_DATA_ERROR,
+ "非本租户交易参考号")
+ }
+ result.apply {
+ this.refno = transaction.refno
+ accdate = transaction.accdate
+ if (transaction.person) {
+ description = transaction.personDtl.transdesc
+ accountBal = (transaction.personDtl.aftbal * 100.0).roundToInt()
+ }
+ transStatus = transaction.status
+ }
+ return ResponseBodyBuilder.successEntity(result)
}
}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt
index 6fe6933..e7589f1 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt
@@ -2,6 +2,7 @@
import com.supwisdom.dlpay.api.ShopAccBalanceAsyncTask
import com.supwisdom.dlpay.api.TransactionBuilder
+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.TradeErrorCode
@@ -69,6 +70,9 @@
@Autowired
private lateinit var kafkaSendMsgService: KafkaSendMsgService
+ @Autowired
+ private lateinit var transactionMainDao: TransactionMainDao
+
fun init(builder: TransactionBuilder): TTransactionMain {
try {
@@ -143,4 +147,7 @@
}
}
+ fun findTransactionByRefno(refno: String): TTransactionMain? {
+ return transactionMainDao.findByRefno(refno)
+ }
}