From: yunpeng.ma Date: Wed, 18 Mar 2020 05:50:09 +0000 (+0800) Subject: 支付宝充值 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=5c91cc31ba891f03060471f9cb1a17019f59b497;p=epayment%2Ffood_payapi.git 支付宝充值 --- 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 c44f94e5..ec075b6e 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 @@ public interface SourceTypeService { @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) TSourceTypeCheckStatus saveOrUpdateSourceTypeCheckStatus(TSourceTypeCheckStatus s); + /** + * 根据支付类型获取参数配置 + */ + @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = true) + Map 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 1d618fa4..f950b062 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 @@ public class SourceTypeServiceImpl implements SourceTypeService { return sourceTypeCheckDao.save(s); } + + @Override + public Map getConfigByPaytype(String paytype) throws Exception { + //step1: 判断系统支付能力是否启用 + TSourceType tSourceType = sourceTypeDao.getBySourceType(paytype); + if (null == tSourceType) { + throw new TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统不支持支付方式[" + paytype + "]"); + } + Map result = new HashMap<>(0); + List 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 045e54c9..e32d2f85 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 class PaytypeUtil { 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 553f157c..a167c2e6 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 @@ interface AlipayService { fun doNotify(param: Map): AgentResponse + fun doPayPrepay(transaction: TTransactionMain): AgentResponse + + fun doPayNotify(transaction: TTransactionMain?,param: Map): AgentResponse + + fun doPayQuery(transaction: TTransactionMain): AgentResponse } @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 9dadacd3..34cb902a 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.internal.util.AlipaySignature 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.framework.util.TradeDict import com.supwisdom.dlpay.util.PaytypeUtil import mu.KotlinLogging import org.springframework.stereotype.Service +import java.util.* @Service @@ -282,4 +284,119 @@ class AlipayServiceImpl(val sourceTypeService: SourceTypeService, } } } + + override fun doPayPrepay(transaction: TTransactionMain): AgentResponse { + val config = sourceTypeService.getConfigByPaytype(TradeDict.PAYTYPE_ALIPAY); + val agentResponse = AgentResponse() + 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): AgentResponse { + val agentResponse = AgentResponse() + 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 { + val agentResponse = AgentResponse() + 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 50288b90..6084118a 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.DtlStatus 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.http.converter.StringHttpMessageConverter 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 @@ class WechatServiceImpl(val sourceTypeService: SourceTypeService, 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 @@ class WechatServiceImpl(val sourceTypeService: SourceTypeService, override fun dopayInit(transaction: TTransactionMain): AgentResponse { val agentResponse = AgentResponse() - //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 @@ class WechatServiceImpl(val sourceTypeService: SourceTypeService, override fun doPayQuery(transaction: TTransactionMain): AgentResponse { val agentResponse = AgentResponse() + 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 @@ class WechatServiceImpl(val sourceTypeService: SourceTypeService, } 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 3066b645..6905ad9a 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 @@ class AlipayInAppResponse { } @Component("alipayInAppAgent") -class AlipayInAppServcie : InAppPayService { - override fun init(transation: TTransactionMain?): AgentResponse { - 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 { + private val logger = KotlinLogging.logger { } + override fun init(transation: TTransactionMain): AgentResponse { + val alipayInAppResponse = AgentResponse() + 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? { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + override fun notify(refno: String, request: HttpServletRequest): AgentResponse? { + val alipayInAppResponse = AgentResponse() + val map = mutableMapOf() + 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 { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + override fun query(transation: TTransactionMain): AgentResponse { + val alipayInAppResponse = AgentResponse() + 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 5710c4ad..09697b57 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 @@ class TransactionController(private val transactionServiceProxy: TransactionServ @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(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 @@ class TransactionController(private val transactionServiceProxy: TransactionServ "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) {