测试交易流程
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 0e37a32..3713fe4 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TPersondtl.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TPersondtl.java
@@ -14,10 +14,10 @@
   @Column(name = "REFNO", nullable = false, length = 32)
   private String refno; //流水号
 
-  @Column(name = "ACCDATE", length = 8)
+  @Column(name = "ACCDATE", length = 8, nullable = false)
   private String accdate; //记账日期
 
-  @Column(name = "USERID", length = 32)
+  @Column(name = "USERID", length = 32, nullable = false)
   private String userid;  //用户ID,或账号
 
   @Column(name = "acccno", length = 32)
@@ -26,19 +26,19 @@
   @Column(name = "USERNAME", length = 200)
   private String userName;
 
-  @Column(name = "TRANSDATE", length = 8)
+  @Column(name = "TRANSDATE", length = 8, nullable = false)
   private String transdate;
 
-  @Column(name = "TRANSTIME", length = 6)
+  @Column(name = "TRANSTIME", length = 6, nullable = false)
   private String transtime;
 
-  @Column(name = "STATUS", length = 20)
+  @Column(name = "STATUS", length = 20, nullable = false)
   private String status;
 
   @Column(name = "BEFBAL", precision = 9, scale = 2)
   private Double befbal;
 
-  @Column(name = "amount", precision = 9, scale = 2)
+  @Column(name = "amount", precision = 9, scale = 2, nullable = false)
   private Double amount; //实际付款金额
 
   @Column(name = "PAYTYPE", length = 20)
@@ -47,7 +47,7 @@
   @Column(name = "PAYINFO", length = 200)
   private String payinfo; //记录支付信息备用字段
 
-  @Column(name = "TRANSCODE", precision = 4)
+  @Column(name = "TRANSCODE", precision = 4, nullable = false)
   private Integer transcode;
 
   @Column(name = "TRANSDESC", length = 240)
@@ -71,8 +71,8 @@
   @Column(name = "REVERSE_AMOUNT", precision = 9, scale = 2)
   private Double reverseAmount = 0D; //撤销金额填写
 
-  @Column(name = "TRADEFLAG", nullable = false, precision = 1)
-  private Integer tradeflag; //1-充值;2-消费
+  @Column(name = "TRADEFLAG", nullable = false, length = 10)
+  private String tradeflag; //deposit-充值;pay-消费
 
   @Column(name = "REMARK", length = 240)
   private String remark;
@@ -219,11 +219,11 @@
     this.reverseAmount = reverseAmount;
   }
 
-  public Integer getTradeflag() {
+  public String getTradeflag() {
     return tradeflag;
   }
 
-  public void setTradeflag(Integer tradeflag) {
+  public void setTradeflag(String tradeflag) {
     this.tradeflag = tradeflag;
   }
 
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 ad43a2f..2078c99 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java
@@ -21,13 +21,13 @@
   @Column(name = "shopname", length = 200)
   private String shopname;
 
-  @Column(name = "amount", scale = 2, precision = 15)
+  @Column(name = "amount", scale = 2, precision = 15, nullable = false)
   private Double amount;
 
-  @Column(name = "transdate", length = 8)
+  @Column(name = "transdate", length = 8, nullable = false)
   private String transDate;
 
-  @Column(name = "transtime", length = 6)
+  @Column(name = "transtime", length = 6, nullable = false)
   private String transTime;
 
   @Column(name = "tradecode", precision = 8)
@@ -42,7 +42,7 @@
   @Column(name = "status", length = 20)
   private String status;
 
-  @Column(name = "OPPOSITEACCNO", length = 20)
+  @Column(name = "OPPOSITEACCNO", length = 64)
   private String oppositeAccNo;
 
   @Column(name = "OPPOSITEACCNAME", length = 200)
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 76d767d..c60c621 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionMain.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionMain.java
@@ -54,7 +54,8 @@
   @JoinColumn(name = "refno", referencedColumnName = "refno")
   private TSubjectdtl subjectDtl;
 
-  @OneToMany(targetEntity = TDebitCreditDtl.class, mappedBy = "refno", fetch = LAZY)
+  @OneToMany(targetEntity = TDebitCreditDtl.class, fetch = LAZY)
+  @JoinColumn(name = "refno", referencedColumnName = "refno")
   private List<TDebitCreditDtl> details;
 
   public String getRefno() {
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 8769f1f..ed6db07 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
@@ -33,6 +33,9 @@
   public static final String DTL_STATUS_WIP = "wip";
   public static final String DTL_STATUS_NONE = "none";
 
+
+  public static final String TRADE_FLAG_DEPOSIT = "deposit";
+  public static final String TRADE_FLAG_PAY = "pay";
   /**
    * 交易借方
    */
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 af1eefe..0d8007a 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
@@ -220,20 +220,23 @@
                 }.person(account).apply {
                     amount = param.amount / 100.0
                     opposite = AccountProxy(shopacc)
+                    tradeflag = TradeDict.TRADE_FLAG_PAY
                     summary = "市民卡代扣消费"
                 }.and().shop(shopacc).apply {
                     amount = param.amount / 100.0
                     opposite = AccountProxy(account)
                     summary = "市民卡代扣消费"
-                }.and().addDebitCreditRecord(AccountProxy(subject), AccountProxy(shopacc),
+                }.and().addDebitCreditRecord(AccountProxy(subject), AccountProxy(account),
                         param.amount / 100.0, "市民卡代扣消费")
+                        .addDebitCreditRecord(AccountProxy(account), AccountProxy(shopacc),
+                                param.amount / 100.0, "市民卡代扣消费")
                         .also { builder ->
                             param.feelist?.forEach {
                                 //fixme: 科目 -> 商户 与个人无关
                                 val feeconfig = accountUtilServcie.readFeetype(it.feetype,
                                         TradeDict.PAYTYPE_CITIZEN_CARD)
-                                val subject = accountUtilServcie.readSubject(feeconfig.drsubjno)
-                                builder.addDebitCreditRecord(AccountProxy(subject), AccountProxy(shopacc),
+                                val subj = accountUtilServcie.readSubject(feeconfig.drsubjno)
+                                builder.addDebitCreditRecord(AccountProxy(subj), AccountProxy(shopacc),
                                         it.amount / 100.0, feeconfig.summary)
 
                             }
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 3d799c2..f8ece69 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
@@ -8,6 +8,7 @@
 import com.supwisdom.dlpay.api.service.PersonAccountService
 import com.supwisdom.dlpay.api.service.TransactionService
 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
@@ -55,12 +56,15 @@
     @Autowired
     lateinit var shopaccRepository: ShopaccRepositoryImpl
 
+    @Autowired
+    lateinit var systemUtilService: SystemUtilService
+
     private fun builderRecords(builder: TransactionBuilder, status: String): TTransactionMain {
         // 记录三方的交易流水(个人,商户,科目)
         try {
             val transaction = TTransactionMain().apply {
-                refno = "20000000000001"
-                accdate = "20190520"
+                refno = systemUtilService.refno
+                accdate = systemUtilService.accdate
             }
 
 
@@ -77,6 +81,7 @@
                     paytype = builder.person().paytype
                     payinfo = builder.person().payinfo
                     transcode = builder.transCode
+                    tradeflag = builder.person().tradeflag
                     oppositeAccNo = builder.person().opposite.getAccountNo()
                     oppositeAccName = builder.person().opposite.getAccountName()
                     this.status = status
@@ -104,7 +109,6 @@
                     this.status = status
                 }.also {
                     // save shopdtl
-                    shopdtlDao.save(it)
                     transaction.shopDtl = it
                     transaction.shop = true
                 }
@@ -124,7 +128,6 @@
                     this.oppositeAccName = builder.subject().opposite.getAccountName()
                     this.status = status
                 }.also {
-                    subjectdtlDao.save(it)
                     transaction.subjectDtl = it
                     transaction.subject = true
                 }
@@ -141,18 +144,15 @@
                     this.crsubjno = line.credit.getSubjectNo()
                     this.amount = line.amount
                     this.summary = line.summary
-                }.also {
-                    debitCreditDtlDao.save(it)
                 }
             }.apply {
                 transaction.details = this
             }
 
-            val details = debitCreditDtlDao.findByRefno(transaction.refno)
 
             if (builder.hasPerson()) {
-                sumBalanceFromDetails(details, builder.person().person.accno,
-                        Subject.SUBJNO_PERSONAL_DEPOSIT).also {
+                sumBalanceFromDetails(transaction.details, builder.person().person.accno,
+                        builder.person().person.subjno, "debit").also {
                     if (transaction.personDtl.amount != it) {
                         throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR,
                                 "输入金额错误,个人余额不符<${transaction.personDtl.amount}>")
@@ -161,8 +161,8 @@
             }
 
             if (builder.hasShop()) {
-                sumBalanceFromDetails(details, builder.shop().shopacc.shopaccno,
-                        Subject.SUBJNO_MACHANT_INCOME).also {
+                sumBalanceFromDetails(transaction.details, builder.shop().shopacc.shopaccno,
+                        builder.shop().shopacc.subjno, "both").also {
                     if (transaction.shopDtl.amount != it) {
                         throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR,
                                 "输入金额错误,商户余额不符<${transaction.shopDtl.amount}>")
@@ -171,8 +171,8 @@
             }
 
             if (builder.hasSubject()) {
-                sumBalanceFromDetails(details, builder.subject().subject.subjno,
-                        transaction.subjectDtl.subjectno).also {
+                sumBalanceFromDetails(transaction.details, builder.subject().subject.subjno,
+                        transaction.subjectDtl.subjectno, "both").also {
                     if (transaction.subjectDtl.amount != it) {
                         throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR,
                                 "输入金额错误,科目余额不符<${transaction.subjectDtl.amount}>")
@@ -196,16 +196,30 @@
     }
 
     private fun sumBalanceFromDetails(details: List<TDebitCreditDtl>,
-                                      accno: String, subjno: String): Double {
-        return details.sumByDouble { line ->
-            if (line.crsubjno == subjno && line.craccno == accno) {
+                                      accno: String, subjno: String,
+                                      debitOrCredit: String = "debit"): Double {
+
+        val debitAmount = details.sumByDouble { line ->
+            if (line.drsubjno == subjno && line.draccno == accno) {
                 line.amount
-            } else if (line.crsubjno == subjno && line.craccno == accno) {
-                -line.amount
             } else {
                 0.0
             }
         }
+        val creditAmount = details.sumByDouble { line ->
+            if (line.crsubjno == subjno && line.craccno == accno) {
+                line.amount
+            } else {
+                0.0
+            }
+        }
+        return when (debitOrCredit) {
+            "debit" -> debitAmount
+            "credit" -> creditAmount
+            "both" -> creditAmount - debitAmount
+            else -> throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR,
+                    "结算借贷方向余额错误")
+        }
     }
 
     override fun wip(refno: String): TTransactionMain {
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 20d93f8..847aab8 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
@@ -8,6 +8,7 @@
 import com.supwisdom.dlpay.framework.domain.TShopacc
 import com.supwisdom.dlpay.framework.domain.TSubject
 import com.supwisdom.dlpay.framework.util.Subject
+import com.supwisdom.dlpay.framework.util.TradeDict
 import com.supwisdom.dlpay.framework.util.TradeErrorCode
 
 open class SubTransactionBuilder(val parent: TransactionBuilder) {
@@ -31,6 +32,7 @@
     var amount: Double = 0.0
     var summary: String = ""
     var description: String = ""
+    var tradeflag : String = ""
     lateinit var opposite: AccountProxy<*>
 
 }
@@ -105,8 +107,6 @@
     var paytype: String = ""
     var payinfo: String = ""
     var outtradeno: String = "" //第三方流水号
-    val extendMap = mutableMapOf<String, String>() //存调第三方需要的参数信息,存数据库 TB_USERDTL_BUSINESS
-    val resultMap = mutableMapOf<String, String>() //存调第三方结果数据
 
     fun person(): PersonTranactionBuilder {
         return this.personBuilder
@@ -202,6 +202,7 @@
                 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消费"
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 58f6bf3..2137335 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt
@@ -11,7 +11,7 @@
 class ResponseBodyBuilder private constructor() {
     companion object {
         private const val INVALIDE_RETCODE = -0x7FFFFFFF
-        private val RESERVED_KEY = setOf("retcode", "retmsg", "exception")
+        private val RESERVED_KEY = setOf("retcode", "retmsg")
         private val LOGGER = KotlinLogging.logger {}
         fun create() = ResponseBodyBuilder()
     }
@@ -75,7 +75,7 @@
             throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "未设置返回码!")
         } else if (retCode != 0) {
             LOGGER.error("【 ==== ERROR ==== 】: " + Gson().toJson(this.respData))
-        }else{
+        } else {
             LOGGER.info("retcode=[0],retmsg=[$retMsg] return success!!! \n" + Gson().toJson(this.respData))
         }
         return this.respData.plus(mapOf("retcode" to retCode, "retmsg" to retMsg))
diff --git a/src/main/resources/db/migration/V1.3__init_data.sql b/src/main/resources/db/migration/V1.3__init_data.sql
new file mode 100644
index 0000000..f2b0d7d
--- /dev/null
+++ b/src/main/resources/db/migration/V1.3__init_data.sql
@@ -0,0 +1 @@
+Insert into TB_SUBJECT (SUBJNO,SUBJNAME,SUBJTYPE,BALFLAG,FSUBJNO,SUBJLEVEL,ENDFLAG,OPENDATE,DISPLAYFLAG) values ('112234','市民卡支付款',1,1,'1122',2,1,null,'y');
\ No newline at end of file