增加 inapp 接口
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/InAppPayParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/InAppPayParam.java
new file mode 100644
index 0000000..9b7ecf9
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/InAppPayParam.java
@@ -0,0 +1,53 @@
+package com.supwisdom.dlpay.api.bean;
+
+import com.supwisdom.dlpay.api.APIRequestParam;
+import com.supwisdom.dlpay.api.annotation.StringList;
+import com.supwisdom.dlpay.api.annotation.TransDate;
+import com.supwisdom.dlpay.api.annotation.TransTime;
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Positive;
+
+@Setter
+@Getter
+public class InAppPayParam extends APIRequestParam {
+
+  @NotNull
+  @StringList(value = {"h5", "native"})
+  private String inAppType;
+
+  @NotNull
+  @StringList(value = {"shop", "person"})
+  private String recipientType;
+
+  @NotNull
+  private String sourceType;
+
+  private String userid;
+
+  private String merchno;
+
+  @Positive(message = "金额不合法")
+  private Integer totalAmount;
+
+  private String describe;
+
+  @TransDate
+  private String transDate;
+
+  @TransTime
+  private String transTime;
+
+  @NotNull
+  private String billno;
+
+  @Override
+  public boolean checkParam() throws RequestParamCheckException {
+    return true;
+  }
+
+
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/InAppPayResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/InAppPayResponse.java
new file mode 100644
index 0000000..8858860
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/InAppPayResponse.java
@@ -0,0 +1,18 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class InAppPayResponse extends ApiResponse {
+  private String refno;
+
+  private Integer actuallyAmount;
+
+  private String externalRefno;
+
+  private String message;
+
+  private String status;
+}
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/TransactionQueryResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/TransactionQueryResponse.java
new file mode 100644
index 0000000..95e7fbd
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/TransactionQueryResponse.java
@@ -0,0 +1,18 @@
+package com.supwisdom.dlpay.api.bean;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class TransactionQueryResponse extends ApiResponse {
+  private String refno;
+
+  private String accdate;
+
+  private String status;
+
+  private String hostdate;
+
+  private String hosttime;
+}
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/charge_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/charge_api_controller.kt
index 5f31477..65c6e6e 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/charge_api_controller.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/charge_api_controller.kt
@@ -146,7 +146,7 @@
 
     @PostMapping("/merchant/init")
     fun merchantDepositInit(@RequestBody @Valid param: MerchantDepositParam, auth: Authentication):
-            ResponseEntity<Any> {
+            ResponseEntity<MerchantDepositResponse> {
         val response = MerchantDepositResponse()
         val account = when {
             param.userid.isNotBlank() -> {
@@ -209,7 +209,7 @@
 
     @PostMapping("/merchant/confirm")
     fun merchantDepositConfirm(@RequestBody @Valid param: MerchantDepositParam, auth: Authentication):
-            ResponseEntity<Any> {
+            ResponseEntity<MerchantDepositResponse> {
         val response = MerchantDepositResponse()
         val transaction = transactionService.success(param.refno)
         response.apply {
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
index ac73959..52f0529 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
@@ -461,7 +461,7 @@
 
     @RequestMapping("/qrcode/init", method = [RequestMethod.POST, RequestMethod.GET])
     fun qrcodePayInit(@Validated(InitAction::class) @RequestBody param: QrcodePayParam)
-            : ResponseEntity<ApiResponse> {
+            : ResponseEntity<QrcodePayResponse> {
         val apiResp = QrcodePayResponse()
         // 1. 检查 qrcode
         val qrcode = agentServiceProxy.qrcodeMatch(param.qrcode)
@@ -507,9 +507,9 @@
             AgentCode.SUCCESS -> {
                 val qrcodeTransResp = agentResp.payload
                 if (!sourceType.anonymousEnable && qrcodeTransResp.isAnonymous) {
-                    ResponseEntity.ok(ResponseBodyBuilder.create()
-                            .fail(apiResp, TradeErrorCode.BUSINESS_DEAL_ERROR,
-                                    "支付方式<${qrcode.sourceType}> 不支持匿名支付"))
+                    ResponseBodyBuilder.failEntity(apiResp,
+                            TradeErrorCode.BUSINESS_DEAL_ERROR,
+                            "支付方式<${qrcode.sourceType}> 不支持匿名支付")
                 } else {
                     ResponseEntity.ok(ResponseBodyBuilder.create()
                             .success(apiResp.also {
@@ -521,20 +521,17 @@
             AgentCode.NOT_SUPPORT -> {
                 val qrcodeTransResp = agentResp.payload
                 if (!sourceType.anonymousEnable) {
-                    ResponseEntity.ok(ResponseBodyBuilder.create()
-                            .fail(apiResp, TradeErrorCode.BUSINESS_DEAL_ERROR,
-                                    "支付方式<${qrcode.sourceType}> 不支持匿名支付"))
+                    ResponseBodyBuilder.failEntity(apiResp, TradeErrorCode.BUSINESS_DEAL_ERROR,
+                            "支付方式<${qrcode.sourceType}> 不支持匿名支付")
                 } else {
-                    ResponseEntity.ok(ResponseBodyBuilder.create()
-                            .success(apiResp.also {
-                                it.anonymous = qrcodeTransResp.isAnonymous
-                            }))
+                    ResponseBodyBuilder.successEntity(apiResp.also {
+                        it.anonymous = qrcodeTransResp.isAnonymous
+                    })
                 }
             }
             else -> {
-                ResponseEntity.ok(ResponseBodyBuilder.create()
-                        .fail(apiResp, TradeErrorCode.BUSINESS_DEAL_ERROR,
-                                "第三方身份错误,<${agentResp.agentMsg}"))
+                ResponseBodyBuilder.failEntity(apiResp, TradeErrorCode.BUSINESS_DEAL_ERROR,
+                        "第三方身份错误,<${agentResp.agentMsg}")
             }
         }
     }
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/transaction_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/transaction_controller.kt
new file mode 100644
index 0000000..f0846af
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/transaction_controller.kt
@@ -0,0 +1,54 @@
+package com.supwisdom.dlpay.api.controller
+
+import com.supwisdom.dlpay.api.bean.InAppPayParam
+import com.supwisdom.dlpay.api.bean.InAppPayResponse
+import com.supwisdom.dlpay.api.bean.TransactionQueryResponse
+import com.supwisdom.dlpay.api.service.TransactionServiceProxy
+import com.supwisdom.dlpay.framework.ResponseBodyBuilder
+import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.multitenant.TenantContextHolder
+import org.springframework.http.HttpStatus
+import org.springframework.http.ResponseEntity
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.PathVariable
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RestController
+import javax.validation.Valid
+
+
+@RestController("/api/transaction")
+class TransactionController(private val transactionServiceProxy: TransactionServiceProxy,
+                            private val systemUtilService: SystemUtilService) {
+
+    @GetMapping("/query")
+    fun queryTransaction(refno: String): ResponseEntity<*> {
+        val tranaction = transactionServiceProxy.findTransactionByRefno(refno)
+                ?: return ResponseBodyBuilder.fail(HttpStatus.NOT_FOUND, "未找到流水")
+        if (tranaction.tenantid != TenantContextHolder.getContext().tenant.id) {
+            return ResponseBodyBuilder.fail(HttpStatus.CONFLICT, "未找到流水")
+        }
+
+        return ResponseBodyBuilder.successEntity(TransactionQueryResponse().apply {
+            this.refno = tranaction.refno
+            accdate = tranaction.accdate
+            status = tranaction.status
+            hostdate = systemUtilService.sysdatetime.hostdate
+            hosttime = systemUtilService.sysdatetime.hosttime
+        }, "成功")
+    }
+
+    @PostMapping("/inapp/payinit")
+    fun inAppPayInit(@Valid param: InAppPayParam): ResponseEntity<InAppPayResponse> {
+        val response = InAppPayResponse()
+        return ResponseBodyBuilder.successEntity(response)
+    }
+}
+
+@RestController("/api/notify")
+class TransactionNotifyController {
+
+    @PostMapping("/inapp/alipay/{tenant}")
+    fun inAppPayCallback(@PathVariable("tenant") tenant: String): ResponseEntity<Any> {
+        TODO("")
+    }
+}
\ No newline at end of file
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 fc1d886..4facb76 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
@@ -169,7 +169,8 @@
     }
 
     @PostMapping("/biz_init")
-    fun userBizInit(@RequestBody @Validated(InitAction::class) request: CardBizParam): ResponseEntity<Any> {
+    fun userBizInit(@RequestBody @Validated(InitAction::class) request: CardBizParam)
+            : ResponseEntity<CardBizResponse> {
         val builder = TransactionBuilder().apply {
             setTransInfo(request.transdate, request.transtime, TradeCode.TRANSCODE_CARD_BIZ, "internal")
             setOutTransInfo(request.operid, request.operSeqno)
@@ -284,7 +285,8 @@
     }
 
     @PostMapping("/biz_confirm")
-    fun userBizConfirm(@RequestBody @Validated(ConfirmAction::class) request: CardBizParam): ResponseEntity<Any> {
+    fun userBizConfirm(@RequestBody @Validated(ConfirmAction::class) request: CardBizParam)
+            : ResponseEntity<CardBizResponse> {
         val transaction = transactionService.success(request.refno)
         val response = CardBizResponse().apply {
             accdate = transaction.accdate
@@ -297,7 +299,8 @@
     }
 
     @PostMapping("/biz_refund_init")
-    fun userBizRefundInit(@RequestBody @Validated(InitAction::class) request: CardBizRefundParam): ResponseEntity<Any> {
+    fun userBizRefundInit(@RequestBody @Validated(InitAction::class) request: CardBizRefundParam)
+            : ResponseEntity<CardBizResponse> {
         val result = CardBizResponse()
         val originTrans = transactionService.findTransactionByRefno(request.originRefno)
                 ?: return ResponseBodyBuilder.failEntity(result, TradeErrorCode.TRANSACTION_NOT_EXISTS,
@@ -332,7 +335,7 @@
     }
 
     @PostMapping("/biz_refund")
-    fun userBizRefund(refno: String): ResponseEntity<Any> {
+    fun userBizRefund(refno: String): ResponseEntity<CardBizResponse> {
         val result = CardBizResponse()
         val transaction = transactionService.success(refno)
         result.apply {
@@ -348,7 +351,7 @@
     }
 
     @GetMapping("/biz_query")
-    fun userBizQuery(refno: String): ResponseEntity<Any> {
+    fun userBizQuery(refno: String): ResponseEntity<CardBizResponse> {
         val transaction = transactionService.findTransactionByRefno(refno)
                 ?: throw TransactionCheckException(TradeErrorCode.TRANSACTION_NOT_EXISTS
                         , "交易不存在")
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt
index c9d61a1..8614d23 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt
@@ -8,6 +8,7 @@
 import com.supwisdom.dlpay.exception.TransactionException
 import com.supwisdom.dlpay.framework.util.TradeErrorCode
 import mu.KotlinLogging
+import org.springframework.http.HttpStatus
 import org.springframework.http.ResponseEntity
 
 
@@ -18,13 +19,21 @@
         private val LOGGER = KotlinLogging.logger {}
         fun create() = ResponseBodyBuilder()
 
-        fun successEntity(bean: ApiResponse, msg: String? = null): ResponseEntity<Any> {
+        fun <T : ApiResponse> successEntity(bean: T, msg: String? = null): ResponseEntity<T> {
             return ResponseEntity.ok(create().success(bean, msg))
         }
 
-        fun failEntity(bean: ApiResponse, code: Int, msg: String): ResponseEntity<Any> {
+        fun <T : ApiResponse> failEntity(bean: T, code: Int, msg: String): ResponseEntity<T> {
             return ResponseEntity.ok(create().fail(bean, code, msg))
         }
+
+        fun <T> fail(status: HttpStatus, bean: T): ResponseEntity<*> {
+            return ResponseEntity.status(status).body(bean)
+        }
+
+        fun fail(status: HttpStatus, msg: String): ResponseEntity<*> {
+            return ResponseEntity.status(status).body(msg)
+        }
     }
 
     private var retCode = INVALIDE_RETCODE
@@ -47,7 +56,7 @@
         return build()
     }
 
-    fun success(bean: ApiResponse, msg: String? = null): ApiResponse {
+    fun <T : ApiResponse> success(bean: T, msg: String? = null): T {
         bean.retcode = 0
         bean.retmsg = msg ?: "成功"
         return bean
@@ -62,7 +71,7 @@
         return build()
     }
 
-    fun fail(bean: ApiResponse, code: Int, msg: String): ApiResponse {
+    fun <T : ApiResponse> fail(bean: T, code: Int, msg: String): T {
         if (code == 0) {
             throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "错误码未正确定义")
         }