支付宝充值
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/service/SourceTypeService.java b/payapi/src/main/java/com/supwisdom/dlpay/api/service/SourceTypeService.java
index c44f94e..ec075b6 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/api/service/SourceTypeService.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/service/SourceTypeService.java
@@ -52,6 +52,11 @@
   @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
   TSourceTypeCheckStatus saveOrUpdateSourceTypeCheckStatus(TSourceTypeCheckStatus s);
 
+  /**
+   * 根据支付类型获取参数配置
+   */
+  @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = true)
+  Map<String, String> getConfigByPaytype(String paytype) throws Exception;
 
 
 }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/service/impl/SourceTypeServiceImpl.java b/payapi/src/main/java/com/supwisdom/dlpay/api/service/impl/SourceTypeServiceImpl.java
index 1d618fa..f950b06 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/api/service/impl/SourceTypeServiceImpl.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/service/impl/SourceTypeServiceImpl.java
@@ -211,4 +211,23 @@
     return sourceTypeCheckDao.save(s);
   }
 
+
+  @Override
+  public Map<String, String> getConfigByPaytype(String paytype) throws Exception {
+    //step1: 判断系统支付能力是否启用
+    TSourceType tSourceType = sourceTypeDao.getBySourceType(paytype);
+    if (null == tSourceType) {
+      throw new TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统不支持支付方式[" + paytype + "]");
+    }
+    Map<String, String> result = new HashMap<>(0);
+    List<TSourceTypeConfig> list = sourceTypeConfigDao.getBySourceType(paytype);
+    if (!StringUtil.isEmpty(list)) {
+      for (TSourceTypeConfig config : list) {
+        if (config.getGlobalflag()) {
+          result.put(config.getConfigid(), config.getConfigValue()); //统用参数
+        }
+      }
+    }
+    return result;
+  }
 }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/util/PaytypeUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/util/PaytypeUtil.java
index 045e54c..e32d2f8 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/util/PaytypeUtil.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/util/PaytypeUtil.java
@@ -24,6 +24,8 @@
 
     public static final String CFG_ALIPAY_RETURNURL = "alipay.returnurl";
 
+    public static final String CFG_ALIPAY_RETURN = "return.url";
+
     /**
      * 微信支付,配置的KEY值
      */
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/alipay_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/alipay_service.kt
index 553f157..a167c2e 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/alipay_service.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/alipay_service.kt
@@ -22,6 +22,11 @@
 
     fun doNotify(param: Map<String, String>): AgentResponse<QrcodePayTrans>
 
+    fun doPayPrepay(transaction: TTransactionMain): AgentResponse<QrcodePayTrans>
+
+    fun doPayNotify(transaction: TTransactionMain?,param: Map<String, String>): AgentResponse<QrcodePayTrans>
+
+    fun doPayQuery(transaction: TTransactionMain): AgentResponse<QrcodePayTrans>
 }
 
 @Component("alipayAgent")
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/alipay_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/alipay_service_impl.kt
index 9dadacd..34cb902 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/alipay_service_impl.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/alipay_service_impl.kt
@@ -9,6 +9,7 @@
 import com.alipay.api.request.AlipayTradeAppPayRequest
 import com.alipay.api.request.AlipayTradePayRequest
 import com.alipay.api.request.AlipayTradeQueryRequest
+import com.alipay.api.request.AlipayTradeWapPayRequest
 import com.supwisdom.dlpay.RestTemplateConfig
 import com.supwisdom.dlpay.agent.AgentCode
 import com.supwisdom.dlpay.agent.AgentResponse
@@ -26,6 +27,7 @@
 import com.supwisdom.dlpay.util.PaytypeUtil
 import mu.KotlinLogging
 import org.springframework.stereotype.Service
+import java.util.*
 
 
 @Service
@@ -282,4 +284,119 @@
             }
         }
     }
+
+    override fun doPayPrepay(transaction: TTransactionMain): AgentResponse<QrcodePayTrans> {
+        val config = sourceTypeService.getConfigByPaytype(TradeDict.PAYTYPE_ALIPAY);
+        val agentResponse = AgentResponse<QrcodePayTrans>()
+        if (checkCfg(config, agentResponse)) {
+            if (config[PaytypeUtil.CFG_ALIPAY_NOTIFY].isNullOrEmpty()) {
+                agentResponse.code = AgentCode.CONFIG_ERROR
+                agentResponse.agentCode = AgentResponse.AGENTCODE_FAIL
+                agentResponse.agentMsg = "支付宝相关配置为空"
+                logger.error { "支付宝异步通知地址未配置:${PaytypeUtil.CFG_ALIPAY_NOTIFY}" }
+            }
+            val alipayClient = createAlipayClient(config)
+            val request = AlipayTradeWapPayRequest();
+            var productCode = ""
+            //判断是否为H5
+            if (transaction.transCode == TradeCode.TRANSCODE_H5PAY) productCode = "QUICK_WAP_WAY"
+            request.bizModel = AlipayTradePayModel().apply {
+                this.outTradeNo = transaction.refno
+                this.subject = "点餐充值"
+                this.totalAmount = transaction.personDtl.amount.toString()
+                this.productCode = productCode
+            }
+            request.notifyUrl = config[PaytypeUtil.CFG_ALIPAY_NOTIFY] + transaction.refno
+            request.returnUrl = config[PaytypeUtil.CFG_ALIPAY_RETURN]
+            try {
+                /**
+                 * h5 支付方式
+                 * */
+                if (transaction.transCode == TradeCode.TRANSCODE_H5PAY) {
+                    val form = alipayClient.pageExecute(request).body
+                    //body 为Html
+                    agentResponse.agentBody = form
+                    agentResponse.code = AgentCode.REQUIRE_QUERY
+                } else {
+                    val response = alipayClient.sdkExecute(request)
+                    if (response.isSuccess) {
+                        agentResponse.agentRefno = response.tradeNo
+                        agentResponse.agentMsg = response.msg
+                        agentResponse.agentCode = response.code
+                        //body 为APP
+                        agentResponse.agentBody = response.body
+                    } else {
+                        agentResponse.code = AgentCode.FAIL
+                        agentResponse.agentMsg = response.msg
+                        agentResponse.agentCode = response.code
+                        logger.error { "支付宝:${response.code},${response.msg},${response.subCode},${response.subMsg}" }
+                    }
+                }
+            } catch (e: AlipayApiException) {
+                logger.error { "支付宝:${e.message}" }
+                agentResponse.code = AgentCode.FAIL
+            }
+        }
+        return agentResponse
+    }
+
+    override fun doPayNotify(transaction: TTransactionMain?,param: Map<String, String>): AgentResponse<QrcodePayTrans> {
+        val agentResponse = AgentResponse<QrcodePayTrans>()
+        if (transaction == null) {
+            agentResponse.code = AgentCode.REFNO_NOT_EXISTS
+            return agentResponse
+        }
+        if (transaction.status == TradeDict.DTL_STATUS_SUCCESS) {
+            agentResponse.code = AgentCode.SUCCESS
+            return agentResponse
+        }
+        val config = sourceTypeService.getConfigByPaytype(TradeDict.PAYTYPE_ALIPAY);
+        if (config[PaytypeUtil.CFG_ALIPAY_PUBLICKEY].isNullOrEmpty()) {
+            agentResponse.code = AgentCode.CONFIG_ERROR
+            return agentResponse
+        }
+        return when (AlipaySignature.rsaCheckV1(param,
+                config[PaytypeUtil.CFG_ALIPAY_PUBLICKEY], "UTF-8", "RSA2")) {
+            true -> {
+                //total amt 校验 map["total_amount"]
+                agentResponse.code = AgentCode.SUCCESS
+                agentResponse
+            }
+            false -> {
+                logger.error { "支付宝签名校验错误" }
+                agentResponse.code = AgentCode.FAIL
+                agentResponse
+            }
+        }
+    }
+
+    override fun doPayQuery(transaction: TTransactionMain): AgentResponse<QrcodePayTrans> {
+        val agentResponse = AgentResponse<QrcodePayTrans>()
+        val config = sourceTypeService.getConfigByPaytype(TradeDict.PAYTYPE_ALIPAY);
+        if (checkCfg(config, agentResponse)) {
+            val alipayClient = createAlipayClient(config)
+            val request = AlipayTradeQueryRequest()
+            request.bizModel = AlipayTradeQueryModel().apply {
+                this.outTradeNo = transaction.refno
+            }
+            val response = alipayClient.execute(request)
+            if (response.isSuccess) {
+                //check response.totalAmount
+                agentResponse.code = AgentCode.SUCCESS
+                agentResponse.agentMsg = response.msg
+                agentResponse.agentCode = response.code
+                when (response.tradeStatus) {
+                    "TRADE_SUCCESS", "TRADE_FINISHED" -> agentResponse.dtlStatus = DtlStatus.SUCCESS
+                    "TRADE_CLOSED" -> agentResponse.dtlStatus = DtlStatus.REFUND
+                    "WAIT_BUYER_PAY" -> agentResponse.dtlStatus = DtlStatus.WAIT
+                }
+            } else {
+                agentResponse.code = AgentCode.FAIL
+                agentResponse.agentMsg = response.msg
+                agentResponse.agentCode = response.code
+            }
+        }
+        return agentResponse
+    }
+
 }
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/wechat_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/wechat_service_impl.kt
index 50288b9..6084118 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/wechat_service_impl.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/wechat_service_impl.kt
@@ -6,11 +6,8 @@
 import com.supwisdom.dlpay.agent.domain.QrcodePayTrans
 import com.supwisdom.dlpay.agent.service.AgentServiceProxy
 import com.supwisdom.dlpay.agent.service.WechatService
-import com.supwisdom.dlpay.api.bean.BaseResp
 import com.supwisdom.dlpay.api.bean.WechatReqResp
 import com.supwisdom.dlpay.api.dao.PersonIdentityDao
-import com.supwisdom.dlpay.api.dao.ShopSourceTypeConfigDao
-import com.supwisdom.dlpay.api.dao.SourceTypeConfigDao
 import com.supwisdom.dlpay.api.domain.TTransactionMain
 import com.supwisdom.dlpay.api.service.ConsumePayService
 import com.supwisdom.dlpay.api.service.SourceTypeService
@@ -24,7 +21,6 @@
 import org.springframework.stereotype.Service
 import org.springframework.web.client.RestTemplate
 import java.nio.charset.StandardCharsets
-import java.util.HashMap
 
 
 @Service
@@ -166,7 +162,7 @@
                 this.mch_id = config[PaytypeUtil.CFG_WECHAT_MECHID]
                 this.key = config[PaytypeUtil.CFG_WECHAT_MECHKEY]
                 this.out_trade_no = transaction.refno
-                this.total_fee = MoneyUtil.YuanToFen(transaction.shopDtl.amount)
+                this.total_fee = MoneyUtil.YuanToFen(transaction.personDtl.amount)
                 this.spbill_create_ip = trans.spip
                 this.body = transaction.shopDtl.payInfo
                 this.notify_url = StringUtil.urlAppend(config[PaytypeUtil.CFG_WECHAT_NOTIFY], transaction.tenantid)
@@ -359,20 +355,18 @@
 
     override fun dopayInit(transaction: TTransactionMain): AgentResponse<QrcodePayTrans> {
         val agentResponse = AgentResponse<QrcodePayTrans>()
-        //H5 支付
-        //   val trans = agentServiceProxy.qrcodePayTransFindByRefno(transaction.refno)
-        // agentResponse.payload = trans
+        val config = sourceTypeService.getConfigByPaytype(TradeDict.PAYTYPE_WECHAT);
         val bean = WechatReqResp().apply {
-            this.appid = "wx03d12be843cdadd9"
-            this.mch_id = "1513444041"
-            this.key = "3VVhvjD2F0kHzayrjgLM81qcz39FgAv1"
+            this.appid = config[PaytypeUtil.CFG_WECHAT_APPID]
+            this.mch_id = config[PaytypeUtil.CFG_WECHAT_MECHID]
+            this.key = config[PaytypeUtil.CFG_WECHAT_MECHKEY]
             this.out_trade_no = transaction.refno
-            this.total_fee = 1
-            this.spbill_create_ip = "14.23.150.211"
-            this.body = "充值测试"
-            this.notify_url = "http://ykt.supwisdom.com:10201/payapi/api/notify/inapp/wechat/100010/${transaction.refno}"
+            this.total_fee = (Math.round(transaction.personDtl.amount * 100) as Number).toInt()
+            this.spbill_create_ip = "123.12.12.123"
+            this.body = transaction.personDtl.transdesc
+            this.notify_url = config[PaytypeUtil.CFG_WECHAT_NOTIFY] + transaction.refno
             this.trade_type = "MWEB"
-            this.scene_info = "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \" https://pay.qq.com\",\"wap_name\": \"微信支付\"}}"
+            this.scene_info = "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"" + config[PaytypeUtil.CFG_WECHAT_NOTIFY] + "\",\"wap_name\": \"微信支付\"}}"
         }
         bean.generaSign()
         val xml = bean.generaXML()
@@ -418,11 +412,12 @@
 
     override fun doPayQuery(transaction: TTransactionMain): AgentResponse<QrcodePayTrans> {
         val agentResponse = AgentResponse<QrcodePayTrans>()
+        val config = sourceTypeService.getConfigByPaytype(TradeDict.PAYTYPE_WECHAT);
         //H5 支付
         val bean = WechatReqResp().apply {
-            this.appid = "wx03d12be843cdadd9"
-            this.mch_id = "1513444041"
-            this.key = "3VVhvjD2F0kHzayrjgLM81qcz39FgAv1"
+            this.appid = config[PaytypeUtil.CFG_WECHAT_APPID]
+            this.mch_id = config[PaytypeUtil.CFG_WECHAT_MECHID]
+            this.key = config[PaytypeUtil.CFG_WECHAT_MECHKEY]
             this.out_trade_no = transaction.refno
         }
         bean.generalQuerySign()
@@ -475,8 +470,8 @@
         }
         val temp = StringUtil.paraFilter(param)
         var signStr = StringUtil.createLinkString(temp)
-        //     val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_WECHAT, transaction.shopDtl.shopaccno, false, false)
-        val key = "3VVhvjD2F0kHzayrjgLM81qcz39FgAv1"
+        val config = sourceTypeService.getConfigByPaytype(TradeDict.PAYTYPE_WECHAT);
+        val key = config[PaytypeUtil.CFG_WECHAT_MECHKEY]
         signStr += "&key=$key"
         val signRet = MD5.encodeByMD5(signStr)
         logger.error("*******signStr=$signStr")
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/inapp_alipay.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/inapp_alipay.kt
index 3066b64..6905ad9 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/inapp_alipay.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/inapp_alipay.kt
@@ -1,8 +1,12 @@
 package com.supwisdom.dlpay.agent.service
 
+import com.supwisdom.dlpay.agent.AgentCode
 import com.supwisdom.dlpay.agent.AgentResponse
 import com.supwisdom.dlpay.agent.InAppPayService
+import com.supwisdom.dlpay.api.domain.TShopdtl
 import com.supwisdom.dlpay.api.domain.TTransactionMain
+import com.supwisdom.dlpay.api.service.TransactionServiceProxy
+import mu.KotlinLogging
 import org.springframework.stereotype.Component
 import javax.servlet.http.HttpServletRequest
 
@@ -11,16 +15,50 @@
 }
 
 @Component("alipayInAppAgent")
-class AlipayInAppServcie : InAppPayService<AlipayInAppResponse> {
-    override fun init(transation: TTransactionMain?): AgentResponse<AlipayInAppResponse> {
-        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+class AlipayInAppServcie(private val alipayService: AlipayService,
+                         private val transactionServiceProxy: TransactionServiceProxy) : InAppPayService<TTransactionMain> {
+    private val logger = KotlinLogging.logger { }
+    override fun init(transation: TTransactionMain): AgentResponse<TTransactionMain> {
+        val alipayInAppResponse = AgentResponse<TTransactionMain>()
+        val agentResponse = alipayService.doPayPrepay(transation)
+        logger.debug { agentResponse }
+        alipayInAppResponse.agentBody = agentResponse.agentBody
+        alipayInAppResponse.agentCode = AgentCode.PAYINITSUCCESS.value();
+        return alipayInAppResponse;
     }
 
-    override fun notify(refno: String, request: HttpServletRequest): AgentResponse<AlipayInAppResponse>? {
-        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    override fun notify(refno: String, request: HttpServletRequest): AgentResponse<TTransactionMain>? {
+        val alipayInAppResponse = AgentResponse<TTransactionMain>()
+        val map = mutableMapOf<String, String>()
+        val paramNames = request.parameterNames
+        while (paramNames.hasMoreElements()) {
+            val paramName = paramNames.nextElement() as String
+            val paramValues = request.getParameterValues(paramName)
+            if (paramValues.size == 1) {
+                val paramValue = paramValues[0]
+                if (paramValue.isNotEmpty()) {
+                    map[paramName] = paramValue
+                    logger.error("$paramName=$paramValue")
+                }
+            }
+        }
+        val transation = transactionServiceProxy.findTransactionByRefno(refno)
+        val resp = alipayService.doPayNotify(transation,map)
+         if (resp.code == AgentCode.SUCCESS) {
+            alipayInAppResponse.payload = transactionServiceProxy.success(refno)
+            alipayInAppResponse.agentBody = "success"
+        } else {
+            alipayInAppResponse.payload = transactionServiceProxy.fail(refno, resp.agentMsg)
+            alipayInAppResponse.agentBody = "failure"
+        }
+        return alipayInAppResponse
     }
 
-    override fun query(transation: TTransactionMain?): AgentResponse<AlipayInAppResponse> {
-        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    override fun query(transation: TTransactionMain): AgentResponse<TTransactionMain> {
+        val alipayInAppResponse = AgentResponse<TTransactionMain>()
+        val agentResponse = alipayService.doPayQuery(transation)
+        alipayInAppResponse.copyFrom(agentResponse)
+                .payload = transation
+        return alipayInAppResponse
     }
 }
\ No newline at end of file
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
index 5710c4a..09697b5 100644
--- 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
@@ -93,15 +93,15 @@
     @PostMapping("/inapp/payinit")
     fun inAppPayInit(@Valid @RequestBody param: InAppPayParam): ResponseEntity<*> {
         val response = InAppPayResponse()
-        if (transactionContainer.count() > 100) {
+       /* if (transactionContainer.count() > 100) {
             return ResponseBodyBuilder.internalServerError("第三方请求异常")
-        }
+        }*/
         val sourceType = sourceTypeService.getBySourceType(param.sourceType)
                 ?: return ResponseBodyBuilder.badRequest("source type <${param.sourceType}> 不存在")
 
         val agent = agentPayServiceContext.findInAppPayService<Any>(sourceType.sourceType)
                 ?: return ResponseBodyBuilder.badRequest("不支持支付方式<${sourceType.sourceType}>")
-        sourceType.depositeSubjno = "112211";
+        sourceType.depositeSubjno = "112211";  //缓存查询redis没值,暂时写死
         val subject = accountUtilServcie.readSubject(sourceType.depositeSubjno)
 
         val tradeCode = when (param.inAppType) {
@@ -109,14 +109,15 @@
             "native" -> TradeCode.TRANSCODE_APPPAY
             else -> return ResponseBodyBuilder.badRequest("app typ <${param.inAppType}> 不支持")
         }
-
+        if(param.description==null){
+            param.description = "描述为空"
+        }
         val builder = TransactionBuilder()
                 .setTransInfo(param.transDate, param.transTime, tradeCode, sourceType.sourceType)
                 .setOutTransInfo(TenantContextHolder.getContext().tenant.id, param.billno)
                 .apply {
-                    param.description = "H5充值";
                     description = param.description
-                    dtltype = "recharge"   //必须的参数
+                    dtltype = param.summary
                 }
         val amount = param.totalAmount / 100.0
         when (param.recipientType) {