修改实现,待测试
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 dba7948..f733e98 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,8 @@
 
 import javax.persistence.*;
 
+import java.util.List;
+
 import static javax.persistence.FetchType.LAZY;
 
 @Entity
@@ -49,6 +51,9 @@
   @OneToOne(targetEntity = TSubjectdtl.class, mappedBy = "refno", fetch = LAZY)
   private TSubjectdtl subjectDtl;
 
+  @OneToMany(targetEntity = TDebitCreditDtl.class, mappedBy = "refno", fetch = LAZY)
+  private List<TDebitCreditDtl> details;
+
   public String getRefno() {
     return refno;
   }
@@ -133,4 +138,24 @@
   public TSubjectdtl getSubjectDtl() {
     return subjectDtl;
   }
+
+  public List<TDebitCreditDtl> getDetails() {
+    return details;
+  }
+
+  public void setPersonDtl(TPersondtl personDtl) {
+    this.personDtl = personDtl;
+  }
+
+  public void setShopDtl(TShopdtl shopDtl) {
+    this.shopDtl = shopDtl;
+  }
+
+  public void setSubjectDtl(TSubjectdtl subjectDtl) {
+    this.subjectDtl = subjectDtl;
+  }
+
+  public void setDetails(List<TDebitCreditDtl> details) {
+    this.details = details;
+  }
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/dao/ShopaccDao.java b/src/main/java/com/supwisdom/dlpay/framework/dao/ShopaccDao.java
index 73f6bdc..98effbe 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/dao/ShopaccDao.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/dao/ShopaccDao.java
@@ -31,7 +31,7 @@
   TShopacc findByShopid(Integer shopid);
 
   @Lock(LockModeType.PESSIMISTIC_WRITE)
-  @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="0")})
+  @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "0")})
   @Query("select a from TShopacc a where a.shopid=?1")
   TShopacc getShopaccWithLockNowait(Integer shopid);
 
@@ -46,4 +46,6 @@
   @Query("update TShopacc set shopname=?1 where shopaccno=?2")
   void updateShopnameByShopaccno(String shopname, String shopaccno);
 
+
+  TShopacc findByShopacc(String acc);
 }
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt b/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt
index 4902e84..4f06db8 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt
@@ -7,6 +7,7 @@
 import com.supwisdom.dlpay.api.bean.SupStatusRevResp
 import com.supwisdom.dlpay.api.bean.SupYktResp
 import com.supwisdom.dlpay.api.bean.WechatReqResp
+import com.supwisdom.dlpay.api.domain.TShopdtl
 import com.supwisdom.dlpay.api.domain.TUserdtl
 import com.supwisdom.dlpay.framework.util.*
 import com.supwisdom.dlpay.util.Code
@@ -234,7 +235,7 @@
             }
         }
 
-        fun CallCitizenCardPay(config: Map<String, String?>, paydtl: TUserdtl): CallBackResp {
+        fun CallCitizenCardPay(config: Map<String, String?>, paydtl: TShopdtl): CallBackResp {
             val resp = CallBackResp()
             // TODO: 代扣逻辑
             return resp
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 1d5953c..af1eefe 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
@@ -1,24 +1,25 @@
 package com.supwisdom.dlpay.api.controller
 
-import com.supwisdom.dlpay.api.AccountHolder
-import com.supwisdom.dlpay.api.CallService
-import com.supwisdom.dlpay.api.PersonTransBuilder
-import com.supwisdom.dlpay.api.bean.CitizenCardPayfinishParam
-import com.supwisdom.dlpay.api.bean.CitizenCardPayinitParam
-import com.supwisdom.dlpay.api.bean.QueryDtlResultParam
-import com.supwisdom.dlpay.api.bean.YktCardPayinitParam
+import com.supwisdom.dlpay.api.*
+import com.supwisdom.dlpay.api.bean.*
+import com.supwisdom.dlpay.api.domain.TAccount
 import com.supwisdom.dlpay.api.service.*
 import com.supwisdom.dlpay.exception.RequestParamCheckException
+import com.supwisdom.dlpay.exception.TransactionCheckException
 import com.supwisdom.dlpay.exception.TransactionException
 import com.supwisdom.dlpay.exception.TransactionProcessException
 import com.supwisdom.dlpay.framework.ResponseBodyBuilder
+import com.supwisdom.dlpay.framework.domain.TShopacc
 import com.supwisdom.dlpay.framework.service.CommonService
 import com.supwisdom.dlpay.framework.service.SystemUtilService
 import com.supwisdom.dlpay.framework.util.*
 import com.supwisdom.dlpay.util.ConstantUtil
 import com.supwisdom.dlpay.util.PaytypeUtil
+import org.apache.catalina.authenticator.SpnegoAuthenticator
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.ResponseEntity
+import org.springframework.security.core.Authentication
+import org.springframework.security.core.context.SecurityContextHolder
 import org.springframework.web.bind.annotation.*
 import javax.servlet.http.HttpServletRequest
 import javax.servlet.http.HttpServletResponse
@@ -41,11 +42,14 @@
     @Autowired
     lateinit var commonService: CommonService
 
+    @Autowired
+    lateinit var transactionService: TransactionService
+
     /**
      * 流水结果查询统一接口
      * */
     fun queryDtlResult(@RequestBody param: QueryDtlResultParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity<Any> {
-         try {
+        try {
             if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) {
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
                         .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误"))
@@ -57,7 +61,7 @@
                 personBalancePayService.getUserdtlByBillnoForUpdateNowait(param.billno!!, param.shopaccno!!)
             }
             val person = dtl.userid?.let { userService.findPersonByUserid(dtl.userid) }
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .data("refno", dtl.refno)
                     .data("amount", dtl.amount)
                     .data("paytype", dtl.paytype)
@@ -70,130 +74,185 @@
                     .success("查询成功"))
 
         } catch (ex: RequestParamCheckException) {
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .requestException(ex, "请求参数错误"))
         } catch (et: TransactionException) {
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .transException(et, "查询错误"))
         }
 
     }
 
+    private fun consumeMealer(param: CitizenCardPayinitParam, builder: TransactionBuilder,
+                              feetype: ConsumeFeetype, person: TAccount, shop: TShopacc) {
+        val feetypeConfig = accountUtilServcie.readFeetype(TradeDict.FEETYPE_CONSUME_MEALER,
+                TradeDict.PAYTYPE_BALANCE)
+        val amount = feetype.amount / 100.0
+        when (feetypeConfig.crsubjno) {
+            shop.subjno -> {
+                builder.addDebitCreditRecord(AccountProxy(person), AccountProxy(shop),
+                        amount, feetypeConfig.summary)
+                        .shop().also {
+                            it.amount += amount
+                        }
+            }
+            else -> {
+                val subject = accountUtilServcie.readSubject(feetypeConfig.crsubjno)
+                builder.addDebitCreditRecord(AccountProxy(person), AccountProxy(subject),
+                        amount, feetypeConfig.summary)
+            }
+        }
+
+    }
+
+    private fun consumeDiscount(param: CitizenCardPayinitParam, builder: TransactionBuilder,
+                                feetype: ConsumeFeetype, person: TAccount, shop: TShopacc) {
+        val feetypeConfig = accountUtilServcie.readFeetype(TradeDict.FEETYPE_CONSUME_MEALER,
+                TradeDict.PAYTYPE_BALANCE)
+        val amount = feetype.amount / 100.0
+        when (feetypeConfig.drsubjno) {
+            shop.subjno -> {
+                builder.addDebitCreditRecord(AccountProxy(shop), AccountProxy(person),
+                        amount, feetypeConfig.summary)
+            }
+            else -> {
+                val subject = accountUtilServcie.readSubject(feetypeConfig.drsubjno)
+                builder.addDebitCreditRecord(AccountProxy(subject), AccountProxy(shop),
+                        amount, feetypeConfig.summary)
+            }
+        }
+    }
+
     /**
      * ============================================================================
      *                           账户【余额支付】
      * ============================================================================
      * */
     @PostMapping("/balance/pay")
-    fun balancePay(@RequestBody param: CitizenCardPayinitParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity<Any> {
-         try {
-            if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) {
+    fun balancePay(@RequestBody param: CitizenCardPayinitParam, authentication: Authentication): ResponseEntity<Any> {
+        try {
+            if (param.checkParam() && param.checkSign(commonService.getSecretByAppid(authentication.name))) {
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
                         .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误"))
             }
 
             val person = userService.findPersonByIdentityCheckStatus(param.cardNo)
             if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_BALANCE)) {
-                val dtl = PersonTransBuilder.newBuilder(accountUtilServcie)
-                        .chooseTradetype(Tradetype.CONSUME) //消费
-                        .setOwner(person) //记名
-                        .setTransinfo(TradeCode.TRANSCODE_BALANCE_PAY, "账户余额支付")
-                        .setTransDatetime(param.transdate, param.transtime) //交易时间
-                        .selectPaytype(TradeDict.PAYTYPE_BALANCE, param.cardNo)
-                        .addDetail(AccountHolder.person(person.userid),
-                                AccountHolder.shop(param.shopaccno),
-                                param.amount / 100.0, "账户余额消费")
-                        .also { builder ->
-                            param.feelist?.forEach {
-                                when(it.feetype){
-                                    TradeDict.FEETYPE_CONSUME_MEALER -> {
-                                        if (it.amount <= 0) {
-                                            throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "费用类别<${it.feetype}>的金额不能为负")
-                                        }
-                                        builder.addDetail(AccountHolder.feetype(it.feetype, TradeDict.PAYTYPE_BALANCE)
-                                                .with(AccountHolder.shop(param.shopaccno))
-                                                .with(AccountHolder.person(person.userid))
-                                                , it.amount / 100.0)
-                                    }
-                                    TradeDict.FEETYPE_CONSUME_DISCOUNT->{
-                                        TODO("折扣逻辑暂缺")
-                                    }
-                                    else -> throw TransactionProcessException(TradeErrorCode.FEETYPE_NOT_NOSUPPORT, "费用类别<${it.feetype}>不支持")
-                                }
+                val account = accountUtilServcie.readAccount(person.userid)
+                val shopacc = accountUtilServcie.readShopbyAccno(param.shopaccno)
 
-                            }
+                val builder = TransactionBuilder().apply {
+                    transDate = param.transdate
+                    transTime = param.transtime
+                    paytype = TradeDict.PAYTYPE_BALANCE
+                    transCode = TradeCode.TRANSCODE_BALANCE_PAY
+                }.person(account).apply {
+                    description = "账户余额支付"
+                    summary = "账户余额消费"
+                    amount = param.amount / 100.0
+                    opposite = AccountProxy(shopacc)
+                }.and().shop(shopacc).apply {
+                    summary = "账户余额消费"
+                    amount = param.amount / 100.0
+                    opposite = AccountProxy(account)
+                }.and()
+
+                param.feelist?.forEach {
+                    when (it.feetype) {
+                        TradeDict.FEETYPE_CONSUME_MEALER -> {
+                            consumeMealer(param, builder, it, account, shopacc)
                         }
-                        .done(personBalancePayService)
+                        TradeDict.FEETYPE_CONSUME_DISCOUNT -> {
+                            consumeDiscount(param, builder, it, account, shopacc)
+                        }
+                        else -> throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+                                "支付费率清单不支持feetype<${it.feetype}>")
+                    }
+                }
+
+                val dtl = builder.init(transactionService)
+                transactionService.success(dtl.refno)
 
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
                         .data("refno", dtl.refno)
-                        .data("amount", dtl.amount)
+                        .data("amount", dtl.personDtl.amount)
                         .success("交易成功"))
             }
 
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<账户余额>"))
 
         } catch (ex: RequestParamCheckException) {
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .requestException(ex, "请求参数错误"))
         } catch (et: TransactionException) {
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .transException(et, "业务处理错误"))
         }
     }
 
 
-
     /**
      * ============================================================================
      *                           市民卡【交易初始化】
      * ============================================================================
      * */
     @PostMapping("/citizencard/payinit")
-    fun citizencardPayinit(@RequestBody param: CitizenCardPayinitParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity<Any> {
-         try {
-            if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) {
+    fun citizencardPayinit(@RequestBody param: CitizenCardPayinitParam, authenticateAction: Authentication): ResponseEntity<Any> {
+        try {
+            if (param.checkParam() && param.checkSign(commonService.getSecretByAppid(authenticateAction.name))) {
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
                         .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误"))
             }
 
             val person = userService.findPersonByIdentityCheckStatus(param.cardNo)
             if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_CITIZEN_CARD)) {
-                val dtl = PersonTransBuilder.newBuilder(accountUtilServcie)
-                        .chooseTradetype(Tradetype.CONSUME) //消费
-                        .setOwner(person) //记名
-                        .setTransinfo(TradeCode.TRANSCODE_CITIZENCARD_PAY, "市民卡代扣消费")
-                        .setTransDatetime(param.transdate, param.transtime) //交易时间
-                        .selectPaytype(TradeDict.PAYTYPE_CITIZEN_CARD, param.cardNo)
-                        .addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_CITIZEN_CARD),
-                                AccountHolder.shop(param.shopaccno),
-                                param.amount / 100.0, "市民卡代扣消费")
+
+                val account = accountUtilServcie.readAccount(person.userid)
+                val shopacc = accountUtilServcie.readShopbyAccno(param.shopaccno)
+                val subject = accountUtilServcie.readSubject(Subject.SUBJNO_PAY_CITIZEN_CARD)
+                val transaction = TransactionBuilder().apply {
+                    transCode = TradeCode.TRANSCODE_CITIZENCARD_PAY
+                    transDate = param.transdate
+                    transTime = param.transtime
+                    paytype = TradeDict.PAYTYPE_CITIZEN_CARD
+                    payinfo = "市民卡代扣消费"
+                }.person(account).apply {
+                    amount = param.amount / 100.0
+                    opposite = AccountProxy(shopacc)
+                    summary = "市民卡代扣消费"
+                }.and().shop(shopacc).apply {
+                    amount = param.amount / 100.0
+                    opposite = AccountProxy(account)
+                    summary = "市民卡代扣消费"
+                }.and().addDebitCreditRecord(AccountProxy(subject), AccountProxy(shopacc),
+                        param.amount / 100.0, "市民卡代扣消费")
                         .also { builder ->
                             param.feelist?.forEach {
                                 //fixme: 科目 -> 商户 与个人无关
-                                builder.addDetail(AccountHolder.feetype(it.feetype, TradeDict.PAYTYPE_CITIZEN_CARD)
-                                        .with(AccountHolder.shop(param.shopaccno))
-                                        .with(AccountHolder.subject(Subject.SUBJNO_PAY_CITIZEN_CARD))
-                                        , it.amount / 100.0)
+                                val feeconfig = accountUtilServcie.readFeetype(it.feetype,
+                                        TradeDict.PAYTYPE_CITIZEN_CARD)
+                                val subject = accountUtilServcie.readSubject(feeconfig.drsubjno)
+                                builder.addDebitCreditRecord(AccountProxy(subject), AccountProxy(shopacc),
+                                        it.amount / 100.0, feeconfig.summary)
+
                             }
-                        }
-                        .init(personBalancePayService)
+                        }.init(transactionService)
 
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
-                        .data("refno", dtl.refno)
-                        .data("amount", dtl.amount)
+                        .data("refno", transaction.refno)
+                        .data("amount", transaction.shopDtl.amount)
                         .success("交易初始化成功"))
             }
 
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
 
         } catch (ex: RequestParamCheckException) {
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .requestException(ex, "请求参数错误"))
         } catch (et: TransactionException) {
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .transException(et, "业务处理错误"))
         }
     }
@@ -204,48 +263,41 @@
      * ============================================================================
      * */
     @PostMapping("/citizencard/payfinish")
-    fun citizencardPayinit(@RequestBody param: CitizenCardPayfinishParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity<Any> {
-         try {
-            if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) {
+    fun citizencardPayinit(@RequestBody param: CitizenCardPayfinishParam, authentication: Authentication): ResponseEntity<Any> {
+        try {
+            if (param.checkParam() && param.checkSign(commonService.getSecretByAppid(authentication.name))) {
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
                         .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误"))
             }
 
-            var dtl = PersonTransBuilder.newBuilder(accountUtilServcie)
-                    .setRefno(param.refno)
-                    .wip(personBalancePayService)
-            val code = CallService.CallCitizenCardPay(consumePayService.getPaytypeConfig(TradeDict.PAYTYPE_CITIZEN_CARD, dtl.shopaccno), dtl)
-            if (code.retcode == "0") {
-                dtl = PersonTransBuilder.newBuilder(accountUtilServcie)
-                        .setRefno(param.refno)
-                        .addResult(code.data)
-                        .success(personBalancePayService) //流水置成功
-
-                return ResponseEntity.ok(ResponseBodyBuilder.create()
-                        .data("refno", dtl.refno)
-                        .data("billno", dtl.outtradeno)
-                        .success())
-            } else {
-                PersonTransBuilder.newBuilder(accountUtilServcie)
-                        .setRefno(param.refno)
-                        .addResult("errmsg", code.retmsg!!)
-                        .finish(personBalancePayService, TradeDict.DTL_STATUS_FAIL) //流水置成功
-
-                return ResponseEntity.ok(ResponseBodyBuilder.create()
-                        .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "交易扣费失败-${code.retmsg}"))
+            val code = transactionService.wip(param.refno).let {
+                CallService.CallCitizenCardPay(
+                        consumePayService.getPaytypeConfig(TradeDict.PAYTYPE_CITIZEN_CARD, it.shopDtl.shopaccno),
+                        it.shopDtl)
             }
-
+            if (code.retcode == "0") {
+                transactionService.success(param.refno).let {
+                    return ResponseEntity.ok(ResponseBodyBuilder.create()
+                            .data("refno", it.refno)
+                            .data("billno", it.outTradeNo)
+                            .success("交易确认成功"))
+                }
+            } else {
+                transactionService.fail(param.refno).let {
+                    return ResponseEntity.ok(ResponseBodyBuilder.create()
+                            .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "交易扣费失败-${code.retmsg}"))
+                }
+            }
         } catch (ex: RequestParamCheckException) {
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .requestException(ex, "请求参数错误"))
         } catch (et: TransactionException) {
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .transException(et, "业务处理错误"))
         }
     }
 
 
-
     /**
      * ============================================================================
      *                           一卡通支付【交易初始化】
@@ -253,14 +305,14 @@
      * */
     @PostMapping("/ykt/payinit")
     fun yktPayInit(@RequestBody param: YktCardPayinitParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity<Any> {
-         try {
+        try {
             if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) {
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
                         .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误"))
             }
 
             val person = param.uid?.let { userService.findByThirdUniqueIdenty(it) } //没注册,可能匿名?
-            if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_YKT_CARD, person==null)) {
+            if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_YKT_CARD, person == null)) {
                 val dtl = PersonTransBuilder.newBuilder(accountUtilServcie)
                         .chooseTradetype(Tradetype.CONSUME) //消费
                         .also {
@@ -294,13 +346,13 @@
 
             }
 
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<一卡通支付>"))
         } catch (ex: RequestParamCheckException) {
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .requestException(ex, "请求参数错误"))
         } catch (et: TransactionException) {
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .transException(et, "业务处理错误"))
         }
     }
@@ -312,8 +364,8 @@
      * ============================================================================
      * */
     @PostMapping("/ykt/payfinish")
-    fun yktPayFinish(@RequestBody param:CitizenCardPayfinishParam,request: HttpServletRequest,response: HttpServletResponse): ResponseEntity<Any> {
-         try {
+    fun yktPayFinish(@RequestBody param: CitizenCardPayfinishParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity<Any> {
+        try {
             if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) {
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
                         .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误"))
@@ -323,7 +375,7 @@
                     .setRefno(param.refno)
                     .wip(personBalancePayService)
             val extendMap = consumePayService.getUserdtlExtendParamMap(dtl.refno)
-            val code = CallService.callYktPay(consumePayService.getPaytypeConfig(TradeDict.PAYTYPE_YKT_CARD, dtl.shopaccno, dtl.userid==null),
+            val code = CallService.callYktPay(consumePayService.getPaytypeConfig(TradeDict.PAYTYPE_YKT_CARD, dtl.shopaccno, dtl.userid == null),
                     dtl, DateUtil.getNow(), extendMap["stuempno"]!!, extendMap["yktshopid"]!!, extendMap["devphyid"])
             if (code.retcode == "0") {
                 dtl = PersonTransBuilder.newBuilder(accountUtilServcie)
@@ -345,11 +397,11 @@
                         .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "交易扣费失败-${code.retmsg}"))
             }
 
-        }catch (ex: RequestParamCheckException) {
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+        } catch (ex: RequestParamCheckException) {
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .requestException(ex, "请求参数错误"))
         } catch (et: TransactionException) {
-             return ResponseEntity.ok(ResponseBodyBuilder.create()
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .transException(et, "业务处理错误"))
         }
     }
@@ -379,7 +431,6 @@
 //    }
 
 
-
 //
 //    /**
 //     * 微信支付
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/pay_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/pay_service_impl.kt
index a322f11..ad6f053 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/pay_service_impl.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/pay_service_impl.kt
@@ -64,6 +64,11 @@
                 ?: throw TransactionProcessException(TradeErrorCode.SHOP_NOT_EXISTS, "商户<$shopId>不存在")
     }
 
+    override fun readShopbyAccno(shopacc: String): TShopacc {
+        return shopaccDao.findByShopacc(shopacc)
+                ?: throw TransactionProcessException(TradeErrorCode.SHOP_NOT_EXISTS, "商户<$shopacc>不存在")
+    }
+
     override fun readSubject(subjno: String): TSubject {
         return subjectDao.findBySubjno(subjno)
                 ?: throw TransactionProcessException(TradeErrorCode.SUBJECT_NOT_EXISTS, "科目<$subjno>不存在")
@@ -160,9 +165,9 @@
                 throw TransactionProcessException(TradeErrorCode.OUTTRADENO_ALREADY_EXISTS, "外部流水号重复") //非初始化状态,直接报错
             }
             //fixme: 判断是同一笔交易重发(标准??)  是->已初始化直接返回;否 -> 报错:外部流水号重复
-            if(builder.amount == userdtl.amount && builder.paytype == userdtl.paytype && builder.transDate == userdtl.transdate && builder.transTime==userdtl.transtime){
+            if (builder.amount == userdtl.amount && builder.paytype == userdtl.paytype && builder.transDate == userdtl.transdate && builder.transTime == userdtl.transtime) {
                 return userdtl // 交易日期,时间重发时是否会变??
-            }else{
+            } else {
                 throw TransactionProcessException(TradeErrorCode.OUTTRADENO_ALREADY_EXISTS, "外部流水号重复")
             }
         }
@@ -216,7 +221,7 @@
             }
         }
 
-        if(builder.extendMap.isNotEmpty()){
+        if (builder.extendMap.isNotEmpty()) {
             userdtlBusinessDao.save(TUserdtlBusiness(userdtl.refno, builder.extendMap)) //保存参数
         }
 
@@ -305,11 +310,11 @@
         return wip(builder.refno)
     }
 
-    override fun finish(builder: PersonTransBuilder): TUserdtl{
+    override fun finish(builder: PersonTransBuilder): TUserdtl {
         return finish(builder.refno, builder.status, builder.resultMap)
     }
 
-    override fun getUserdtlForUpdateNowait(refno: String): TUserdtl{
+    override fun getUserdtlForUpdateNowait(refno: String): TUserdtl {
         return try {
             userdtlDao.findByRefnoForUpdateNowait(refno)
                     ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "交易参考号<$refno>流水不存在")
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 ebf7118..3d799c2 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
@@ -1,7 +1,6 @@
 package com.supwisdom.dlpay.api.service.impl
 
 import com.supwisdom.dlpay.api.TransactionBuilder
-import com.supwisdom.dlpay.api.TransactionResult
 import com.supwisdom.dlpay.api.dao.*
 import com.supwisdom.dlpay.api.domain.*
 import com.supwisdom.dlpay.api.repositories.ShopaccRepositoryImpl
@@ -56,19 +55,19 @@
     @Autowired
     lateinit var shopaccRepository: ShopaccRepositoryImpl
 
-    private fun builderRecords(builder: TransactionBuilder, status: String): TransactionResult {
+    private fun builderRecords(builder: TransactionBuilder, status: String): TTransactionMain {
         // 记录三方的交易流水(个人,商户,科目)
         try {
-            val result = TransactionResult("20000000000001", "20190520")
             val transaction = TTransactionMain().apply {
-                this.refno = result.refno
-                this.accdate = result.accdate
+                refno = "20000000000001"
+                accdate = "20190520"
             }
 
+
             if (builder.hasPerson()) {
                 TPersondtl().apply {
-                    this.refno = result.refno
-                    this.accdate = result.accdate
+                    this.refno = transaction.refno
+                    this.accdate = transaction.accdate
                     userid = builder.person().person.userid
                     userName = builder.person().person.accname
                     transdate = builder.transDate
@@ -84,14 +83,14 @@
                 }.also {
                     // save persondtl
                     persondtlDao.save(it)
-                    result.persondtl = it
+                    transaction.personDtl = it
                     transaction.person = true
                 }
             }
             if (builder.hasShop()) {
                 TShopdtl().apply {
-                    this.refno = result.refno
-                    this.accdate = result.accdate
+                    this.refno = transaction.refno
+                    this.accdate = transaction.accdate
                     this.amount = builder.shop().amount
                     this.payInfo = builder.shop().payinfo
                     this.payType = builder.shop().paytype
@@ -106,15 +105,15 @@
                 }.also {
                     // save shopdtl
                     shopdtlDao.save(it)
-                    result.shopdtl = it
+                    transaction.shopDtl = it
                     transaction.shop = true
                 }
             }
             if (builder.hasSubject()) {
                 // save subjectdtl
                 TSubjectdtl().apply {
-                    this.refno = result.refno
-                    this.accdate = result.accdate
+                    this.refno = transaction.refno
+                    this.accdate = transaction.accdate
                     this.amount = builder.subject().amount
                     this.payInfo = builder.subject().payinfo
                     this.payType = builder.subject().paytype
@@ -126,15 +125,15 @@
                     this.status = status
                 }.also {
                     subjectdtlDao.save(it)
-                    result.subjectdtl = it
+                    transaction.subjectDtl = it
                     transaction.subject = true
                 }
             }
 
-            builder.getAllDetails().forEach { line ->
+            builder.getAllDetails().map { line ->
                 TDebitCreditDtl().apply {
-                    this.refno = result.refno
-                    this.accdate = result.accdate
+                    this.refno = transaction.refno
+                    this.accdate = transaction.accdate
                     this.seqno = line.seqno
                     this.draccno = line.debit.getAccountNo()
                     this.drsubjno = line.debit.getSubjectNo()
@@ -144,18 +143,19 @@
                     this.summary = line.summary
                 }.also {
                     debitCreditDtlDao.save(it)
-                    result.debitCreditLines.add(it)
                 }
+            }.apply {
+                transaction.details = this
             }
 
-            val details = debitCreditDtlDao.findByRefno(result.refno)
+            val details = debitCreditDtlDao.findByRefno(transaction.refno)
 
             if (builder.hasPerson()) {
                 sumBalanceFromDetails(details, builder.person().person.accno,
                         Subject.SUBJNO_PERSONAL_DEPOSIT).also {
-                    if (result.persondtl.amount != it) {
+                    if (transaction.personDtl.amount != it) {
                         throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR,
-                                "输入金额错误,个人余额不符<${result.persondtl.amount}>")
+                                "输入金额错误,个人余额不符<${transaction.personDtl.amount}>")
                     }
                 }
             }
@@ -163,35 +163,35 @@
             if (builder.hasShop()) {
                 sumBalanceFromDetails(details, builder.shop().shopacc.shopaccno,
                         Subject.SUBJNO_MACHANT_INCOME).also {
-                    if (result.shopdtl.amount != it) {
+                    if (transaction.shopDtl.amount != it) {
                         throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR,
-                                "输入金额错误,商户余额不符<${result.shopdtl.amount}>")
+                                "输入金额错误,商户余额不符<${transaction.shopDtl.amount}>")
                     }
                 }
             }
 
             if (builder.hasSubject()) {
                 sumBalanceFromDetails(details, builder.subject().subject.subjno,
-                        result.subjectdtl.subjectno).also {
-                    if (result.subjectdtl.amount != it) {
+                        transaction.subjectDtl.subjectno).also {
+                    if (transaction.subjectDtl.amount != it) {
                         throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR,
-                                "输入金额错误,科目余额不符<${result.subjectdtl.amount}>")
+                                "输入金额错误,科目余额不符<${transaction.subjectDtl.amount}>")
                     }
                 }
             }
 
             transactionMainDao.save(transaction)
-            return result
+            return transaction
         } catch (ex: SQLException) {
             throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, ex.message)
         }
     }
 
-    override fun init(builder: TransactionBuilder): TransactionResult {
+    override fun init(builder: TransactionBuilder): TTransactionMain {
         return builderRecords(builder, TradeDict.DTL_STATUS_INIT)
     }
 
-    override fun wip(builder: TransactionBuilder): TransactionResult {
+    override fun wip(builder: TransactionBuilder): TTransactionMain {
         return builderRecords(builder, TradeDict.DTL_STATUS_WIP)
     }
 
@@ -208,7 +208,7 @@
         }
     }
 
-    override fun wip(refno: String) {
+    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>参考号错误")
@@ -252,9 +252,10 @@
             } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "科目流水<$refno>不存在")
         }
         transactionMainDao.save(transaction)
+        return transaction
     }
 
-    override fun fail(refno: String) {
+    override fun fail(refno: String): TTransactionMain {
         val transaction = transactionMainDao.findByRefnoForUpdate(refno)
                 ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水<$refno>参考号错误")
 
@@ -265,10 +266,11 @@
 
         transaction.status = TradeDict.DTL_STATUS_FAIL
         transactionMainDao.save(transaction)
+        return transaction
     }
 
 
-    override fun success(refno: String) {
+    override fun success(refno: String): TTransactionMain {
         val transaction = transactionMainDao.findByRefnoForUpdate(refno)
                 ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水<$refno>参考号错误")
 
@@ -296,5 +298,6 @@
             // update subject balance
         }
         transactionMainDao.save(transaction)
+        return transaction
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/pay_service.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/pay_service.kt
index 568d9bb..ba07cda 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/service/pay_service.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/pay_service.kt
@@ -20,6 +20,8 @@
 
     fun readShopAcc(shopId: Int): TShopacc
 
+    fun readShopbyAccno(shpoacc: String): TShopacc
+
     fun readSubject(subjno: String): TSubject
 
     fun readFeetype(feetype: String, paytype: String): TFeetypeConfig
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt
index 8872f33..e8cdd79 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt
@@ -1,26 +1,26 @@
 package com.supwisdom.dlpay.api.service
 
 import com.supwisdom.dlpay.api.TransactionBuilder
-import com.supwisdom.dlpay.api.TransactionResult
 import com.supwisdom.dlpay.api.domain.TAccount
+import com.supwisdom.dlpay.api.domain.TTransactionMain
 import org.springframework.transaction.annotation.Propagation
 import org.springframework.transaction.annotation.Transactional
 
 interface TransactionService {
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
-    fun init(builder: TransactionBuilder): TransactionResult
+    fun init(builder: TransactionBuilder): TTransactionMain
 
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
-    fun wip(refno: String)
+    fun wip(refno: String): TTransactionMain
 
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
-    fun wip(builder: TransactionBuilder): TransactionResult
+    fun wip(builder: TransactionBuilder): TTransactionMain
 
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
-    fun fail(refno: String)
+    fun fail(refno: String): TTransactionMain
 
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
-    fun success(refno: String)
+    fun success(refno: String): TTransactionMain
 }
 
 interface PersonAccountService {
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 68c639a..20d93f8 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
@@ -1,6 +1,7 @@
 package com.supwisdom.dlpay.api
 
-import com.supwisdom.dlpay.api.domain.*
+import com.supwisdom.dlpay.api.domain.TAccount
+import com.supwisdom.dlpay.api.domain.TTransactionMain
 import com.supwisdom.dlpay.api.service.AccountUtilServcie
 import com.supwisdom.dlpay.api.service.TransactionService
 import com.supwisdom.dlpay.exception.TransactionCheckException
@@ -29,6 +30,7 @@
     : SubTransactionBuilder(parent) {
     var amount: Double = 0.0
     var summary: String = ""
+    var description: String = ""
     lateinit var opposite: AccountProxy<*>
 
 }
@@ -171,26 +173,15 @@
         return debitCreditLines.toList()
     }
 
-    fun init(transactionService: TransactionService): TransactionResult {
+    fun init(transactionService: TransactionService): TTransactionMain {
         return transactionService.init(this)
     }
 
-    fun wip(transactionService: TransactionService): TransactionResult {
+    fun wip(transactionService: TransactionService): TTransactionMain {
         return transactionService.wip(this)
     }
 }
 
-class TransactionResult(val refno: String, val accdate: String) {
-
-    lateinit var persondtl: TPersondtl
-
-    lateinit var shopdtl: TShopdtl
-
-    lateinit var subjectdtl: TSubjectdtl
-
-    var debitCreditLines = mutableListOf<TDebitCreditDtl>()
-}
-
 class TransactionExample {
     companion object {
         fun exampleInit(accountUtilServcie: AccountUtilServcie,
diff --git a/src/main/kotlin/com/supwisdom/dlpay/framework/service/framework_service.kt b/src/main/kotlin/com/supwisdom/dlpay/framework/service/framework_service.kt
index 99161e3..d400aaa 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/framework/service/framework_service.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/framework/service/framework_service.kt
@@ -1,13 +1,14 @@
 package com.supwisdom.dlpay.framework.service
 
-import com.supwisdom.dlpay.api.bean.ConsumeFeetype
 import javax.servlet.http.HttpServletRequest
 
-interface CommonService{
+interface CommonService {
     fun getSystemVersion(): String
 
     fun getRequestAppid(request: HttpServletRequest): String
 
     fun getAppidSecretByRequest(request: HttpServletRequest): String
 
+    fun getSecretByAppid(appid: String): String
+
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/framework/service/impl/framework_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/framework/service/impl/framework_service_impl.kt
index 56f2586..32c6d92 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/framework/service/impl/framework_service_impl.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/framework/service/impl/framework_service_impl.kt
@@ -33,11 +33,11 @@
     }
 
     override fun getSystemVersion(): String {
-        try {
-            return Manifests.read("Payapi-Version") ?: "version 1.0"
+        return try {
+            Manifests.read("Payapi-Version") ?: "version 1.0"
         } catch (ex: Exception) {
 //            ex.printStackTrace()
-            return "unknown"
+            "unknown"
         }
     }
 
@@ -56,7 +56,11 @@
     }
 
     override fun getAppidSecretByRequest(request: HttpServletRequest): String {
-        return apiClientDao.findByAppid(getRequestAppid(request)).let {
+        return getSecretByAppid(getRequestAppid(request))
+    }
+
+    override fun getSecretByAppid(appid: String): String {
+        return apiClientDao.findByAppid(appid).let {
             if (null != it)
                 it.secret
             else