初步测试交易记账流程
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TPersondtl.java b/src/main/java/com/supwisdom/dlpay/api/domain/TPersondtl.java
index 3713fe4..376b528 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TPersondtl.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TPersondtl.java
@@ -77,12 +77,6 @@
@Column(name = "REMARK", length = 240)
private String remark;
- @Column(name = "CREATETIME", length = 14)
- private String createtime; //创建时间
-
- @Column(name = "ENDTIME", length = 14)
- private String endtime; //支付结束时间
-
public String getRefno() {
return refno;
}
@@ -235,22 +229,6 @@
this.remark = remark;
}
- public String getCreatetime() {
- return createtime;
- }
-
- public void setCreatetime(String createtime) {
- this.createtime = createtime;
- }
-
- public String getEndtime() {
- return endtime;
- }
-
- public void setEndtime(String endtime) {
- this.endtime = endtime;
- }
-
public String getUserName() {
return userName;
}
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java b/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java
index 2078c99..14dcb5d 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java
@@ -39,6 +39,9 @@
@Column(name = "payinfo", length = 200)
private String payInfo;
+ @Column(name = "tradeflag", length = 6)
+ private String tradeflag;
+
@Column(name = "status", length = 20)
private String status;
@@ -151,4 +154,12 @@
public void setTradeCode(Integer tradeCode) {
this.tradeCode = tradeCode;
}
+
+ public String getTradeflag() {
+ return tradeflag;
+ }
+
+ public void setTradeflag(String tradeflag) {
+ this.tradeflag = tradeflag;
+ }
}
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionMain.java b/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionMain.java
index c60c621..6c7507d 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionMain.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionMain.java
@@ -4,6 +4,7 @@
import javax.persistence.*;
+import java.sql.Timestamp;
import java.util.List;
import static javax.persistence.FetchType.LAZY;
@@ -39,22 +40,28 @@
@Column(name = "outid", length = 60)
private String outId;
+ @Column(name = "create_time")
+ private Timestamp createTime;
+
+ @Column(name = "end_time")
+ private Timestamp endTime;
+
@Column(name = "reverse_flag", nullable = false, length = 10)
private String reverseFlag = "none";
- @OneToOne(targetEntity = TPersondtl.class, fetch = LAZY)
+ @OneToOne(targetEntity = TPersondtl.class, fetch = LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "refno", referencedColumnName = "refno")
private TPersondtl personDtl;
- @OneToOne(targetEntity = TShopdtl.class, fetch = LAZY)
+ @OneToOne(targetEntity = TShopdtl.class, fetch = LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "refno", referencedColumnName = "refno")
private TShopdtl shopDtl;
- @OneToOne(targetEntity = TSubjectdtl.class, fetch = LAZY)
+ @OneToOne(targetEntity = TSubjectdtl.class, fetch = LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "refno", referencedColumnName = "refno")
private TSubjectdtl subjectDtl;
- @OneToMany(targetEntity = TDebitCreditDtl.class, fetch = LAZY)
+ @OneToMany(targetEntity = TDebitCreditDtl.class, fetch = LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "refno", referencedColumnName = "refno")
private List<TDebitCreditDtl> details;
@@ -162,4 +169,20 @@
public void setDetails(List<TDebitCreditDtl> details) {
this.details = details;
}
+
+ public Timestamp getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Timestamp createTime) {
+ this.createTime = createTime;
+ }
+
+ public Timestamp getEndTime() {
+ return endTime;
+ }
+
+ public void setEndTime(Timestamp endTime) {
+ this.endTime = endTime;
+ }
}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java b/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
index ed6db07..c786dea 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
@@ -1,5 +1,7 @@
package com.supwisdom.dlpay.framework.util;
+import org.jetbrains.annotations.Nullable;
+
public class TradeDict {
/**
* 状态:
@@ -34,8 +36,8 @@
public static final String DTL_STATUS_NONE = "none";
- public static final String TRADE_FLAG_DEPOSIT = "deposit";
- public static final String TRADE_FLAG_PAY = "pay";
+ public static final String TRADE_FLAG_OUT = "out";
+ public static final String TRADE_FLAG_IN = "in";
/**
* 交易借方
*/
@@ -65,4 +67,14 @@
public static final String PAYTYPE_RECHARGE_COUPON = "coupon"; // 充值优惠
public static final String PAYTYPE_RECHARGE_SERVICEFEE = "servicefee"; //收服务费
+
+ /**
+ * reverse flag
+ * - none : 无
+ * - cancel : 冲正
+ * - reverse : 手工撤销
+ */
+ public static final String REVERSE_FLAG_NONE = "none";
+ public static final String REVERSE_FLAG_CANCEL = "cancel";
+ public static final String REVERSE_FLAG_REVERSE = "reverse";
}
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt b/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt
index 4f06db8..3a03934 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt
@@ -237,6 +237,7 @@
fun CallCitizenCardPay(config: Map<String, String?>, paydtl: TShopdtl): CallBackResp {
val resp = CallBackResp()
+ resp.retcode = "0"
// TODO: 代扣逻辑
return resp
}
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt b/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt
index 47eb043..f96ba95 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/advices.kt
@@ -1,10 +1,26 @@
package com.supwisdom.dlpay.api
+import com.supwisdom.dlpay.framework.ResponseBodyBuilder
+import com.supwisdom.dlpay.framework.util.TradeErrorCode
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.aspectj.lang.annotation.Pointcut
+import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Component
+import org.springframework.web.bind.annotation.ExceptionHandler
+import org.springframework.web.bind.annotation.RestControllerAdvice
+
+
+@RestControllerAdvice
+class RestControllerAdvice {
+
+ @ExceptionHandler
+ fun handleException(ex: Exception): ResponseEntity<Any> {
+ return ResponseEntity.ok().body(ResponseBodyBuilder.create()
+ .exception(TradeErrorCode.BUSINESS_DEAL_ERROR, ex.cause))
+ }
+}
@Component
@Aspect
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
index 0d8007a..bfa6eac 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
@@ -217,15 +217,19 @@
transTime = param.transtime
paytype = TradeDict.PAYTYPE_CITIZEN_CARD
payinfo = "市民卡代扣消费"
+ outId = shopacc.shopaccno
+ outtradeno = param.billno
}.person(account).apply {
amount = param.amount / 100.0
opposite = AccountProxy(shopacc)
- tradeflag = TradeDict.TRADE_FLAG_PAY
+ description = "市民卡代扣消费"
summary = "市民卡代扣消费"
+ tradeOut()
}.and().shop(shopacc).apply {
amount = param.amount / 100.0
opposite = AccountProxy(account)
summary = "市民卡代扣消费"
+ tradeIn()
}.and().addDebitCreditRecord(AccountProxy(subject), AccountProxy(account),
param.amount / 100.0, "市民卡代扣消费")
.addDebitCreditRecord(AccountProxy(account), AccountProxy(shopacc),
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/repositories/repository_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/repositories/repository_impl.kt
index 5c557d3..21d0324 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/repositories/repository_impl.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/repositories/repository_impl.kt
@@ -62,7 +62,7 @@
?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS,
"交易流水<${dtl.refno}>商户账户不存在")
- val query = entityManager.createQuery("update TShopacc c set c.balance=c.balance-?1" +
+ val query = entityManager.createQuery("update TShopacc c set c.balance=c.balance+?1" +
" where c.shopaccno=?2 and c.balance=?3")
query.setParameter(1, amount)
.setParameter(2, dtl.shopaccno)
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt
index f8ece69..4e355cf 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt
@@ -5,52 +5,28 @@
import com.supwisdom.dlpay.api.domain.*
import com.supwisdom.dlpay.api.repositories.ShopaccRepositoryImpl
import com.supwisdom.dlpay.api.repositories.TAccountRepositoryImpl
-import com.supwisdom.dlpay.api.service.PersonAccountService
import com.supwisdom.dlpay.api.service.TransactionService
+import com.supwisdom.dlpay.exception.TransactionCheckException
import com.supwisdom.dlpay.exception.TransactionProcessException
import com.supwisdom.dlpay.framework.service.SystemUtilService
-import com.supwisdom.dlpay.framework.util.Subject
import com.supwisdom.dlpay.framework.util.TradeDict
import com.supwisdom.dlpay.framework.util.TradeErrorCode
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.sql.SQLException
-import javax.transaction.Transactional
+import java.sql.Timestamp
-open class PersonAccountServiceImpl : PersonAccountService {
- @Transactional
- override fun recalcBalance(account: TAccount, amount: Double) {
- TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
- }
-}
-
@Service
class TransactionServiceImpl : TransactionService {
- companion object {
- val INIT_DTL_STATUS = setOf(TradeDict.DTL_STATUS_INIT, TradeDict.DTL_STATUS_WIP)
- }
-
@Autowired
lateinit var transactionMainDao: TransactionMainDao
@Autowired
- lateinit var accoutDao: AccountDao
-
- @Autowired
lateinit var persondtlDao: PersondtlDao
@Autowired
- lateinit var shopdtlDao: ShopdtlDao
-
- @Autowired
- lateinit var subjectdtlDao: SubjectdtlDao
-
- @Autowired
- lateinit var debitCreditDtlDao: DebitCreditDtlDao
-
- @Autowired
lateinit var accountRepository: TAccountRepositoryImpl
@Autowired
@@ -59,12 +35,91 @@
@Autowired
lateinit var systemUtilService: SystemUtilService
+ private fun preCheck(builder: TransactionBuilder) {
+ if (builder.outId.isNotEmpty() && builder.outtradeno.isEmpty()) {
+ throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "第三方账号未指定第三方流水号")
+ }
+
+ if (builder.transDate.length != 8 || builder.transTime.length != 6) {
+ throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "交易发生日期错误")
+ }
+
+ if (builder.transCode <= 0) {
+ throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "交易码错误")
+ }
+
+ if (builder.hasPerson()) {
+ builder.person().also {
+ if (!it.hasOpposite()) {
+ throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "个人交易对方账户未设置")
+ }
+ if (it.payinfo.isEmpty() || it.paytype.isEmpty()) {
+ throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "个人交易信息未设置")
+ }
+ when (it.tradeFlag()) {
+ TradeDict.TRADE_FLAG_IN -> {
+ throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "不支持的交易")
+ }
+ TradeDict.TRADE_FLAG_OUT -> {
+ if (builder.reverseFlag != TradeDict.REVERSE_FLAG_NONE && it.amount > 0) {
+ throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "消费冲正交易,余额不能大于0")
+ } else if (builder.reverseFlag == TradeDict.REVERSE_FLAG_NONE && it.amount < 0) {
+ throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "消费交易,余额不能小于0")
+ }
+ }
+ else -> {
+ throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "个人交易方向未设置")
+ }
+ }
+
+ }
+ }
+
+ if (builder.hasShop()) {
+ builder.shop().also {
+ if (!it.hasOpposite()) {
+ throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "商户交易对方账户未设置")
+ }
+ when (it.tradeFlag()) {
+ TradeDict.TRADE_FLAG_IN -> {
+ if (it.amount < 0) {
+ throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "商户收入交易金额不能小于0")
+ }
+ }
+ TradeDict.TRADE_FLAG_OUT -> {
+ if (it.amount > 0) {
+ throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "商户支出交易金额不能小于0")
+ }
+ }
+ else -> throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+ "商户交易方向未设置")
+ }
+ }
+ }
+ }
+
private fun builderRecords(builder: TransactionBuilder, status: String): TTransactionMain {
- // 记录三方的交易流水(个人,商户,科目)
try {
+ preCheck(builder)
+ // 记录三方的交易流水(个人,商户,科目)
val transaction = TTransactionMain().apply {
refno = systemUtilService.refno
accdate = systemUtilService.accdate
+ outTradeNo = builder.outtradeno
+ outId = builder.outId
+ createTime = Timestamp(systemUtilService.sysdatetime.sysdate.time)
}
@@ -73,17 +128,25 @@
this.refno = transaction.refno
this.accdate = transaction.accdate
userid = builder.person().person.userid
+ accountNo = builder.person().person.accno
userName = builder.person().person.accname
+ outtradeno = builder.outtradeno
transdate = builder.transDate
transtime = builder.transTime
befbal = builder.person().person.availbal
- amount = builder.person().amount
+ amount = if (builder.person().tradeFlag() == TradeDict.TRADE_FLAG_IN) {
+ builder.person().amount
+ } else {
+ -builder.person().amount
+ }
paytype = builder.person().paytype
payinfo = builder.person().payinfo
transcode = builder.transCode
- tradeflag = builder.person().tradeflag
+ tradeflag = builder.person().tradeFlag()
+ transdesc = builder.person().description
oppositeAccNo = builder.person().opposite.getAccountNo()
oppositeAccName = builder.person().opposite.getAccountName()
+ reverseFlag = builder.reverseFlag
this.status = status
}.also {
// save persondtl
@@ -102,6 +165,12 @@
this.transDate = builder.transDate
this.transTime = builder.transTime
this.tradeCode = builder.transCode
+ amount = if (builder.shop().tradeFlag() == TradeDict.TRADE_FLAG_IN) {
+ builder.shop().amount
+ } else {
+ -builder.shop().amount
+ }
+ this.tradeflag = builder.shop().tradeFlag()
this.shopaccno = builder.shop().shopacc.shopaccno
this.shopname = builder.shop().shopacc.shopname
this.oppositeAccNo = builder.shop().opposite.getAccountNo()
@@ -151,8 +220,9 @@
if (builder.hasPerson()) {
+ val dc = getDebitOrCredit(builder.person().tradeFlag())
sumBalanceFromDetails(transaction.details, builder.person().person.accno,
- builder.person().person.subjno, "debit").also {
+ builder.person().person.subjno, 2, dc).also {
if (transaction.personDtl.amount != it) {
throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR,
"输入金额错误,个人余额不符<${transaction.personDtl.amount}>")
@@ -161,8 +231,9 @@
}
if (builder.hasShop()) {
+ val dc = getDebitOrCredit(builder.shop().tradeFlag())
sumBalanceFromDetails(transaction.details, builder.shop().shopacc.shopaccno,
- builder.shop().shopacc.subjno, "both").also {
+ builder.shop().shopacc.subjno, 2, dc).also {
if (transaction.shopDtl.amount != it) {
throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR,
"输入金额错误,商户余额不符<${transaction.shopDtl.amount}>")
@@ -172,7 +243,9 @@
if (builder.hasSubject()) {
sumBalanceFromDetails(transaction.details, builder.subject().subject.subjno,
- transaction.subjectDtl.subjectno, "both").also {
+ transaction.subjectDtl.subjectno,
+ builder.subject().subject.balflag,
+ "both").also {
if (transaction.subjectDtl.amount != it) {
throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR,
"输入金额错误,科目余额不符<${transaction.subjectDtl.amount}>")
@@ -180,6 +253,7 @@
}
}
+ transaction.status = status
transactionMainDao.save(transaction)
return transaction
} catch (ex: SQLException) {
@@ -187,6 +261,14 @@
}
}
+ private fun getDebitOrCredit(tradeFlag: String): String {
+ return when (tradeFlag) {
+ TradeDict.TRADE_FLAG_IN -> "credit"
+ TradeDict.TRADE_FLAG_OUT -> "debit"
+ else -> "both"
+ }
+ }
+
override fun init(builder: TransactionBuilder): TTransactionMain {
return builderRecords(builder, TradeDict.DTL_STATUS_INIT)
}
@@ -197,6 +279,7 @@
private fun sumBalanceFromDetails(details: List<TDebitCreditDtl>,
accno: String, subjno: String,
+ balanceFlag: Int,
debitOrCredit: String = "debit"): Double {
val debitAmount = details.sumByDouble { line ->
@@ -214,57 +297,64 @@
}
}
return when (debitOrCredit) {
- "debit" -> debitAmount
- "credit" -> creditAmount
+ "debit" -> {
+ if (balanceFlag == 2) debitAmount * -1.0 else debitAmount
+ }
+ "credit" -> {
+ if (balanceFlag == 2) creditAmount else creditAmount * -1.0
+ }
"both" -> creditAmount - debitAmount
else -> throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR,
"结算借贷方向余额错误")
}
}
- override fun wip(refno: String): TTransactionMain {
- val transaction = transactionMainDao.findById(refno).let {
- if (it.isPresent) it.get() else null
- } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水<$refno>参考号错误")
-
- if (transaction.status != TradeDict.DTL_STATUS_INIT) {
- throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水<$refno>状态错误")
- }
+ private fun updateRecordStatus(transaction: TTransactionMain, status: String) {
if (transaction.person) {
- persondtlDao.findById(refno).let {
- if (!it.isPresent) it.get() else null
- }?.also {
- if (it.status != TradeDict.DTL_STATUS_INIT) {
- throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "个人流水<$refno>状态错误")
+ transaction.personDtl?.also {
+ if (it.status != transaction.status) {
+ throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED,
+ "个人流水<${transaction.refno}>状态错误")
}
- it.status = TradeDict.DTL_STATUS_WIP
- persondtlDao.save(it)
- } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "个人流水<$refno>不存在")
+ it.status = status
+ } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
+ "个人流水<${transaction.refno}>不存在")
}
if (transaction.shop) {
- shopdtlDao.findById(refno).let {
- if (it.isPresent) it.get() else null
- }?.also {
- if (it.status != TradeDict.DTL_STATUS_INIT) {
- throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "商户流水<$refno>状态错误")
+ transaction.shopDtl?.also {
+ if (it.status != transaction.status) {
+ throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED,
+ "商户流水<${transaction.refno}>状态错误")
}
- it.status = TradeDict.DTL_STATUS_WIP
- shopdtlDao.save(it)
- } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "商户流水<$refno>不存在")
+ it.status = status
+ } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
+ "商户流水<${transaction.refno}>不存在")
}
if (transaction.subject) {
- subjectdtlDao.findById(refno).let {
- if (it.isPresent) it.get() else null
- }?.also {
- if (it.status != TradeDict.DTL_STATUS_INIT) {
- throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "科目流水<$refno>状态错误")
+ transaction.subjectDtl?.also {
+ if (it.status != transaction.status) {
+ throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED,
+ "科目流水<${transaction.refno}>状态错误")
}
- it.status = TradeDict.DTL_STATUS_WIP
- subjectdtlDao.save(it)
- } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "科目流水<$refno>不存在")
+ it.status = status
+ } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
+ "科目流水<${transaction.refno}>不存在")
}
+ transaction.status = status
+ }
+
+ override fun wip(refno: String): TTransactionMain {
+ val transaction = transactionMainDao.findByRefnoForUpdate(refno)
+ ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水<$refno>参考号错误")
+
+ if (transaction.status != TradeDict.DTL_STATUS_INIT
+ && transaction.status != TradeDict.DTL_STATUS_WIP) {
+ throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水<$refno>状态错误")
+ }
+
+ updateRecordStatus(transaction, TradeDict.DTL_STATUS_WIP)
transactionMainDao.save(transaction)
return transaction
}
@@ -278,7 +368,8 @@
throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水<$refno>状态错误")
}
- transaction.status = TradeDict.DTL_STATUS_FAIL
+ updateRecordStatus(transaction, TradeDict.DTL_STATUS_FAIL)
+ transaction.endTime = Timestamp(systemUtilService.sysdatetime.sysdate.time)
transactionMainDao.save(transaction)
return transaction
}
@@ -292,25 +383,35 @@
if (transaction.status in errorStatus) {
throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水<$refno>状态错误")
}
- transaction.status = TradeDict.DTL_STATUS_FAIL
+ transaction.status = TradeDict.DTL_STATUS_SUCCESS
if (transaction.person) {
// update account balance
transaction.personDtl?.let {
- accountRepository.recalcAccountBalance(it, it.amount, false)
+ if (accountRepository.recalcAccountBalance(it, it.amount, false) != 1) {
+ throw TransactionProcessException(TradeErrorCode.ACCOUNT_TRADE_BUSY,
+ "个人账户交易冲突")
+ }
} ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
"个人流水<${transaction.refno}>不存在")
+ transaction.personDtl.status = TradeDict.DTL_STATUS_SUCCESS
}
if (transaction.shop) {
// update shop balance
transaction.shopDtl?.let {
- shopaccRepository.recalcShopBalance(it, it.amount, false)
+ if (shopaccRepository.recalcShopBalance(it, it.amount, false) != 1) {
+ throw TransactionProcessException(TradeErrorCode.ACCOUNT_TRADE_BUSY,
+ "商户账户交易冲突")
+ }
} ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
"商户流水<${transaction.refno}>不存在")
+ transaction.shopDtl.status = TradeDict.DTL_STATUS_SUCCESS
}
if (transaction.subject) {
// update subject balance
}
+
+ transaction.endTime = Timestamp(systemUtilService.sysdatetime.sysdate.time)
transactionMainDao.save(transaction)
return transaction
}
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt b/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
index 847aab8..40abd48 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
@@ -22,9 +22,34 @@
return if (field.isEmpty()) parent.payinfo else field
}
+
+ lateinit var opposite: AccountProxy<*>
+
+ fun hasOpposite(): Boolean {
+ return this::opposite.isInitialized
+ }
+
fun and(): TransactionBuilder {
return parent
}
+
+ private var balanceInOut: String = ""
+
+ fun tradeIn(): SubTransactionBuilder {
+ this.balanceInOut = TradeDict.TRADE_FLAG_IN
+ return this
+ }
+
+ fun tradeOut(): SubTransactionBuilder {
+ this.balanceInOut = TradeDict.TRADE_FLAG_OUT
+ return this
+ }
+
+ fun tradeFlag(): String {
+ return this.balanceInOut
+ }
+
+
}
class PersonTranactionBuilder(parent: TransactionBuilder, val person: TAccount)
@@ -32,8 +57,6 @@
var amount: Double = 0.0
var summary: String = ""
var description: String = ""
- var tradeflag : String = ""
- lateinit var opposite: AccountProxy<*>
}
@@ -41,14 +64,12 @@
: SubTransactionBuilder(parent) {
var amount: Double = 0.0
var summary: String = ""
- lateinit var opposite: AccountProxy<*>
}
class SubjectTransactionBuilder(parent: TransactionBuilder, val subject: TSubject)
: SubTransactionBuilder(parent) {
var amount: Double = 0.0
var summary: String = ""
- lateinit var opposite: AccountProxy<*>
}
@@ -107,6 +128,8 @@
var paytype: String = ""
var payinfo: String = ""
var outtradeno: String = "" //第三方流水号
+ var outId: String = ""
+ var reverseFlag: String = "none"
fun person(): PersonTranactionBuilder {
return this.personBuilder
@@ -181,73 +204,3 @@
return transactionService.wip(this)
}
}
-
-class TransactionExample {
- companion object {
- fun exampleInit(accountUtilServcie: AccountUtilServcie,
- service: TransactionService,
- userid: String, shopid: Int, amount: Int, manageFee: Int,
- transDate: String, transTime: String, payType: String) {
-
- val person = accountUtilServcie.readAccount(userid)
- val shop = accountUtilServcie.readShopAcc(shopid)
-
- val builder = TransactionBuilder().apply {
- this.transDate = transDate
- this.transTime = transTime
- this.transCode = 3001
- this.payinfo = "POS消费"
- this.paytype = payType
- }.person(person).apply {
- this.amount = (amount + manageFee) / 100.0 // 金额考虑减和加
- this.summary = "POS消费"
- this.opposite = AccountProxy(shop)
- this.tradeflag = TradeDict.TRANS_DIRECTION_CREDIT
- }.and().shop(shop).apply {
- this.amount = amount / 100.0 // 金额考虑减和加
- this.summary = "POS消费"
- this.opposite = AccountProxy(person)
- }.and()
-
- if (payType == "balance") {
- builder.addDebitCreditRecord(AccountProxy(person), AccountProxy(shop),
- amount / 100.0, "POS消费")
- if (manageFee > 0) {
- val subject = accountUtilServcie.readSubject("2001")
- builder.subject(subject).apply {
- this.amount = manageFee / 100.0 // 金额考虑减和加
- this.summary = "POS消费搭伙费"
- this.opposite = AccountProxy(person)
- }.and().addDebitCreditRecord(AccountProxy(person), AccountProxy(subject), manageFee / 100.0,
- "POS消费搭伙费")
- }
- } else if (payType == "wechat") {
- accountUtilServcie.readSubject(Subject.SUBJNO_PAY_WECHAT).also {
- builder.addDebitCreditRecord(AccountProxy(it), AccountProxy(person),
- (amount + manageFee) / 100.0, "微信转账")
- .addDebitCreditRecord(AccountProxy(person), AccountProxy(shop),
- amount / 100.0, "微信支付消费")
- }
-
- if (manageFee > 0) {
- accountUtilServcie.readSubject("2001").also {
- builder.subject(it).apply {
- this.amount = manageFee / 100.0 // 金额考虑减和加
- this.summary = "微信支付消费搭伙费"
- this.opposite = AccountProxy(person)
- }.and().addDebitCreditRecord(AccountProxy(person), AccountProxy(it), manageFee / 100.0,
- "微信支付消费搭伙费")
- }
- }
- } else {
- throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "不支持的支付方式")
- }
- val result = builder.init(service)
- println(result.refno)
- }
-
- fun exampleConfirm(refno: String, transactionService: TransactionService) {
- transactionService.success(refno)
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt b/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt
index 2137335..b35904b 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt
@@ -50,6 +50,12 @@
return build()
}
+ fun exception(code: Int, cause: Throwable?, msg: String? = null): Map<String, Any> {
+ data("exception", cause?.message ?: "unkonw excpetion")
+ result(code, msg)
+ return build()
+ }
+
fun transException(exception: TransactionException, msg: String): Map<String, Any> {
data("exception", exception.message!!)
result(exception.code(), "$msg - [${exception.message}]")