From: Xia Kaixiang Date: Fri, 10 May 2019 10:13:55 +0000 (+0800) Subject: 交易细节修改 X-Git-Tag: 1.0.0^2~227 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=0e6c606fd4a4c24ecd0783cdce5bf0a14d7d952b;p=epayment%2Ffood_payapi.git 交易细节修改 --- diff --git a/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlBusinessDao.java b/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlBusinessDao.java new file mode 100644 index 00000000..347e79ae --- /dev/null +++ b/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlBusinessDao.java @@ -0,0 +1,10 @@ +package com.supwisdom.dlpay.api.dao; + +import com.supwisdom.dlpay.api.domain.TUserdtlBusiness; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserdtlBusinessDao extends JpaRepository { + TUserdtlBusiness getByRefno(String refno); +} diff --git a/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlDao.java b/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlDao.java index 72181db6..007cff7d 100644 --- a/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlDao.java +++ b/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlDao.java @@ -27,4 +27,6 @@ public interface UserdtlDao extends JpaRepository { @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="0")}) @Query("select dtl from TUserdtl dtl where dtl.outtradeno = ?1 and dtl.shopaccno=?2 ") TUserdtl findByBillnoForUpdateNowait(String billno,String shopaccno); + + TUserdtl findByOuttradenoAndShopaccno(String outtradeno,String shopaccno); } diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TPaytype.java b/src/main/java/com/supwisdom/dlpay/api/domain/TPaytype.java index be801038..088cb9e7 100644 --- a/src/main/java/com/supwisdom/dlpay/api/domain/TPaytype.java +++ b/src/main/java/com/supwisdom/dlpay/api/domain/TPaytype.java @@ -16,13 +16,13 @@ public class TPaytype { private String enable; @Column(name = "CHARGE_ENABLE", nullable = false, length = 10) - private String chargeEnable; + private String chargeEnable; //充值总开关 @Column(name = "CONSUME_ENABLE",nullable = false, length = 10) - private String consumeEnable; + private String consumeEnable; //消费总开关 @Column(name = "ANONYMOUS_ENABLE", nullable = false, length = 10) - private String anonymousEnable; + private String anonymousEnable; //匿名消费总开关 @Column(name = "PAYDESC", length = 200) private String paydesc; diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TShopPaytype.java b/src/main/java/com/supwisdom/dlpay/api/domain/TShopPaytype.java index cb4662e4..a9b95f1e 100644 --- a/src/main/java/com/supwisdom/dlpay/api/domain/TShopPaytype.java +++ b/src/main/java/com/supwisdom/dlpay/api/domain/TShopPaytype.java @@ -15,13 +15,13 @@ public class TShopPaytype { private String paytype; @Column(name = "CONSUME_ENABLE", nullable = false, length = 10) - private String consumeEnable; + private String consumeEnable; //该商户下,此支付方式能否消费 @Column(name = "ANONYMOUS_ENABLE", nullable = false, length = 10) - private String anonymousEnable; + private String anonymousEnable; //该商户下,此支付方式能否匿名消费 @Column(name = "REVERSE_ENABLE", nullable = false, length = 10) - private String reverseEnable; + private String reverseEnable; //该商户下,此支付方式能否冲正 @Column(name = "CREATETIME", length = 14) private String createtime; diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtlBusiness.java b/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtlBusiness.java index cb5e67c6..42ed8ca1 100644 --- a/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtlBusiness.java +++ b/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtlBusiness.java @@ -29,7 +29,7 @@ public class TUserdtlBusiness { this.jsonContent = jsonContent; } - public TUserdtlBusiness(String refno, Map map) { + public TUserdtlBusiness(String refno, Map map) { this.refno = refno; if (null == map || map.isEmpty()) { this.jsonContent = ""; @@ -54,10 +54,10 @@ public class TUserdtlBusiness { this.jsonContent = jsonContent; } - public Map getContentMap() { - Map map = new HashMap<>(0); + public Map getContentMap() { + Map map = new HashMap<>(0); if (!StringUtil.isEmpty(this.jsonContent)) - map = gsonUtil.fromJson(this.jsonContent, new TypeToken>() { + map = gsonUtil.fromJson(this.jsonContent, new TypeToken>() { }.getType()); return map; } diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java b/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java index 5c51c26a..20cd9221 100644 --- a/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java +++ b/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java @@ -4,8 +4,11 @@ package com.supwisdom.dlpay.framework.util; * 交易码、交易类型 * */ public class TradeCode { - public static final int TRANSCODE_PAY = 3000; - public static final int TRANSCODE_YKTPAY=1000; + public static final int TRANSCODE_BALANCE_PAY = 3000; //账户余额支付 + public static final int TRANSCODE_CITIZENCARD_PAY=3010; //市民卡代扣消费 + public static final int TRANSCODE_YKTCARD_PAY=3020; //一卡通支付 + + public static final int TRANSCODE_WECHAT=1001; diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java b/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java index a8139c9e..336239e0 100644 --- a/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java +++ b/src/main/java/com/supwisdom/dlpay/framework/util/TradeErrorCode.java @@ -99,6 +99,12 @@ public class TradeErrorCode { * */ public static final int FEETYPE_NOT_EXISTS = 10018; + /** + * 费用类别不支持 + * */ + public static final int FEETYPE_NOT_NOSUPPORT = 10019; + + /** * 请求参数错误 * */ diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt b/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt index d02ba577..4902e84c 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt @@ -23,8 +23,8 @@ class CallBackResp { class CallService { companion object { - fun callYktPay(config: Map, paydtl: TUserdtl, time: String, stuempno: String, yktshopid: String, devphyid: String?): BaseResp { - val code = BaseResp() + fun callYktPay(config: Map, paydtl: TUserdtl, time: String, stuempno: String, yktshopid: String, devphyid: String?): CallBackResp { + val code = CallBackResp() val appid = config["appid"] if (appid.isNullOrEmpty()) { code.retcode = "1" diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt b/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt index 414da8e6..f498fee8 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt @@ -212,6 +212,42 @@ class CitizenCardPayfinishParam : APIRequestParam() { } } +class YktCardPayinitParam : APIRequestParam() { + @Sign + var uid: String? = null //未注册,可能不传 + @Sign + var shopaccno: String = "" //必传 + @Sign + var amount: Int = 0 //必传 + + var feelist: List? = null //TODO: 怎么拼接签名字符串?? + @Sign + var billno: String = "" //必传 + @Sign + var transdate: String = "" //必传 + @Sign + var transtime: String = "" //必传 + @Sign + var stuempno: String = "" //必传 + @Sign + var yktshopid: String? = null + @Sign + var devphyid: String? = null + + fun checkParam(): Boolean { + + if (StringUtil.isEmpty(shopaccno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "请指定交易商户") + if (amount <= 0) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "交易金额必须大于零") + if (StringUtil.isEmpty(billno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "对接系统唯一订单号不能为空") + if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "交易日期错误[yyyyMMdd]") + if (!DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "交易时间错误[HHmmss]") + if (StringUtil.isEmpty(stuempno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "一卡通唯一号不能为空") + if(!StringUtil.isEmpty(yktshopid) && !NumberUtil.isDigits(yktshopid)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "一卡通商户号非整数") + + return true + } +} + diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/comsume_builder.kt b/src/main/kotlin/com/supwisdom/dlpay/api/comsume_builder.kt index 2c1555c2..ff29e998 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/comsume_builder.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/comsume_builder.kt @@ -86,6 +86,7 @@ class PersonTransBuilder private constructor(accUitl: AccountUtilServcie) { lateinit var refno: String lateinit var status: String lateinit var shopaccno: String + val extendMap = mutableMapOf() //存调第三方需要的参数信息 val resultMap = mutableMapOf() //存调第三方结果数据 var transcode = 0 @@ -167,6 +168,15 @@ class PersonTransBuilder private constructor(accUitl: AccountUtilServcie) { return this } + fun addExtendParam(key: String, value: String): PersonTransBuilder { + this.extendMap.plus(mapOf(key to value)) + return this + } + + fun addExtendParam(param: Map): PersonTransBuilder { + this.extendMap.plus(param) + return this + } fun addResult(key: String, value: String): PersonTransBuilder { this.resultMap.plus(mapOf(key to value)) return this 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 a35b8cef..066e43c8 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 @@ -6,9 +6,11 @@ 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.service.* import com.supwisdom.dlpay.exception.RequestParamCheckException import com.supwisdom.dlpay.exception.TransactionException +import com.supwisdom.dlpay.exception.TransactionProcessException import com.supwisdom.dlpay.framework.ResponseBodyBuilder import com.supwisdom.dlpay.framework.service.CommonService import com.supwisdom.dlpay.framework.service.SystemUtilService @@ -78,7 +80,75 @@ class ConsumeController { } /** - * 市民卡交易初始化 + * ============================================================================ + * 账户【余额支付】 + * ============================================================================ + * */ + @PostMapping("/balance/pay") + fun balancePay(@RequestBody param: CitizenCardPayinitParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity { + return try { + if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) { + 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}>不支持") + } + + } + } + .done(personBalancePayService) + + ResponseEntity.ok(ResponseBodyBuilder.create() + .data("refno", dtl.refno) + .data("amount", dtl.amount) + .success("交易成功")) + } + + ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<账户余额>")) + + } catch (ex: RequestParamCheckException) { + ResponseEntity.ok(ResponseBodyBuilder.create() + .requestException(ex, "请求参数错误")) + } catch (et: TransactionException) { + ResponseEntity.ok(ResponseBodyBuilder.create() + .transException(et, "业务处理错误")) + } + } + + + + /** + * ============================================================================ + * 市民卡【交易初始化】 + * ============================================================================ * */ @PostMapping("/citizencard/payinit") fun citizencardPayinit(@RequestBody param: CitizenCardPayinitParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity { @@ -93,7 +163,7 @@ class ConsumeController { val dtl = PersonTransBuilder.newBuilder(accountUtilServcie) .chooseTradetype(Tradetype.CONSUME) //消费 .setOwner(person) //记名 - .setTransinfo(TradeCode.TRANSCODE_PAY, "支付交易") + .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), @@ -101,6 +171,7 @@ class ConsumeController { 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)) @@ -128,7 +199,9 @@ class ConsumeController { } /** - * 市民卡交易确认 + * ============================================================================ + * 市民卡【交易确认】 + * ============================================================================ * */ @PostMapping("/citizencard/payfinish") fun citizencardPayinit(@RequestBody param: CitizenCardPayfinishParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity { @@ -141,7 +214,7 @@ class ConsumeController { var dtl = PersonTransBuilder.newBuilder(accountUtilServcie) .setRefno(param.refno) .wip(personBalancePayService) - val code = CallService.CallCitizenCardPay(consumePayService.getPaytypeConfig(TradeDict.PAYTYPE_CITIZEN_CARD, "shopaccno"), dtl) + val code = CallService.CallCitizenCardPay(consumePayService.getPaytypeConfig(TradeDict.PAYTYPE_CITIZEN_CARD, dtl.shopaccno), dtl) if (code.retcode == "0") { dtl = PersonTransBuilder.newBuilder(accountUtilServcie) .setRefno(param.refno) @@ -171,47 +244,58 @@ class ConsumeController { } } + + /** - * 账户余额支付 + * ============================================================================ + * 一卡通支付【交易初始化】 + * ============================================================================ * */ - @PostMapping("/balance/pay") - fun balancePay(@RequestBody param: CitizenCardPayinitParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity { + @PostMapping("/ykt/payinit") + fun yktPayInit(@RequestBody param: YktCardPayinitParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity { return try { if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) { ResponseEntity.ok(ResponseBodyBuilder.create() .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误")) } - val person = userService.findPersonByIdentityCheckStatus(param.cardNo) - if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_BALANCE)) { + val person = param.uid?.let { userService.findByThirdUniqueIdenty(it) } ?: null //没注册,可能匿名? + if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_YKT_CARD, person==null)) { val dtl = PersonTransBuilder.newBuilder(accountUtilServcie) .chooseTradetype(Tradetype.CONSUME) //消费 - .setOwner(person) //记名 - .setTransinfo(TradeCode.TRANSCODE_PAY, "支付交易") + .also { + if (null != person) it.setOwner(person) + } + .setTransinfo(TradeCode.TRANSCODE_YKTCARD_PAY, "一卡通支付") .setTransDatetime(param.transdate, param.transtime) //交易时间 - .selectPaytype(TradeDict.PAYTYPE_BALANCE, param.cardNo) - .addDetail(AccountHolder.person(person.userid), + .selectPaytype(TradeDict.PAYTYPE_YKT_CARD, param.stuempno) + .addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_YKT), AccountHolder.shop(param.shopaccno), - param.amount / 100.0, "账户余额消费") + param.amount / 100.0, "一卡通支付") .also { builder -> param.feelist?.forEach { - builder.addDetail(AccountHolder.feetype(it.feetype, TradeDict.PAYTYPE_BALANCE) + //fixme: 科目 -> 商户 与个人无关 + builder.addDetail(AccountHolder.feetype(it.feetype, TradeDict.PAYTYPE_YKT_CARD) .with(AccountHolder.shop(param.shopaccno)) - .with(AccountHolder.person(person.userid)) + .with(AccountHolder.subject(Subject.SUBJNO_PAY_YKT)) , it.amount / 100.0) } } - .done(personBalancePayService) + .addExtendParam("stuempno", param.stuempno) + .addExtendParam("yktshopid", param.yktshopid ?: "") + .addExtendParam("devphyid", param.devphyid ?: "") + //.addExtendParam(param.extendmap) //fixme: 保存调一卡通附加参数 (是否直接传附加参数map) + .init(personBalancePayService) ResponseEntity.ok(ResponseBodyBuilder.create() .data("refno", dtl.refno) .data("amount", dtl.amount) - .success("交易成功")) + .success("交易初始化成功")) + } ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<账户余额>")) - + .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<一卡通支付>")) } catch (ex: RequestParamCheckException) { ResponseEntity.ok(ResponseBodyBuilder.create() .requestException(ex, "请求参数错误")) @@ -221,51 +305,47 @@ class ConsumeController { } } + /** - * 一卡通支付 + * ============================================================================ + * 一卡通支付【交易确认】 + * ============================================================================ * */ - @PostMapping("/ykt/payinit") - fun yktPayInit(@RequestBody param: CitizenCardPayinitParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity { + @PostMapping("/ykt/payfinish") + fun yktPayFinish(@RequestBody param:CitizenCardPayfinishParam,request: HttpServletRequest,response: HttpServletResponse): ResponseEntity { return try { if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) { ResponseEntity.ok(ResponseBodyBuilder.create() .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误")) } - var person = userService.findByThirdUniqueIdenty(param.cardNo) //可能匿名? - if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_YKT_CARD, person==null)) { - val dtl = PersonTransBuilder.newBuilder(accountUtilServcie) - .chooseTradetype(Tradetype.CONSUME) //消费 - .also { - if(null!=person) it.setOwner(person) - } - .setTransinfo(TradeCode.TRANSCODE_PAY, "支付交易") - .setTransDatetime(param.transdate, param.transtime) //交易时间 - .selectPaytype(TradeDict.PAYTYPE_YKT_CARD, param.cardNo) - .addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_YKT), - AccountHolder.shop(param.shopaccno), - param.amount / 100.0, "一卡通支付") - .also { builder -> - param.feelist?.forEach { - builder.addDetail(AccountHolder.feetype(it.feetype, TradeDict.PAYTYPE_YKT_CARD) - .with(AccountHolder.shop(param.shopaccno)) - .with(AccountHolder.subject(Subject.SUBJNO_PAY_YKT)) - , it.amount / 100.0) - } - } - .init(personBalancePayService) + var dtl = PersonTransBuilder.newBuilder(accountUtilServcie) + .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), + dtl, DateUtil.getNow(), extendMap["stuempno"]!!, extendMap["yktshopid"]!!, extendMap["devphyid"]) + if (code.retcode == "0") { + dtl = PersonTransBuilder.newBuilder(accountUtilServcie) + .setRefno(param.refno) + .addResult(code.data) + .success(personBalancePayService) //流水置成功 ResponseEntity.ok(ResponseBodyBuilder.create() .data("refno", dtl.refno) - .data("amount", dtl.amount) - .success("交易初始化成功")) - + .data("billno", dtl.outtradeno) + .success()) + } else { + PersonTransBuilder.newBuilder(accountUtilServcie) + .setRefno(param.refno) + .addResult("errmsg", code.retmsg!!) + .finish(personBalancePayService, TradeDict.DTL_STATUS_FAIL) //流水置成功 + ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "交易扣费失败-${code.retmsg}")) } - ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<一卡通支付>")) - } catch (ex: RequestParamCheckException) { + }catch (ex: RequestParamCheckException) { ResponseEntity.ok(ResponseBodyBuilder.create() .requestException(ex, "请求参数错误")) } catch (et: TransactionException) { @@ -299,31 +379,7 @@ class ConsumeController { // } -// -// @PostMapping("/ykt/payfinish") -// fun yktPayFinish(refno: String, yktshopid: String, devphyid: String?): ResponseEntity { -// return try { -// val dtl = personBalancePayService.wip(refno) -// val person = userService.findPersonByUserid(dtl.userid) -// val code = CallService.callYktPay(paytypeService.getPaytypeConfigByPaytype(PaytypeUtil.YKTPAY), -// dtl, DateUtil.getNow(), "", yktshopid, devphyid) -// if (code.retcode == "0") { -// PersonTransBuilder.newBuilder(accountUtilServcie) -// .done(dtl.refno, TradeDict.DTL_STATUS_SUCCESS, personBalancePayService) -// ResponseEntity.ok(ResponseBodyBuilder.create() -// .data("refno", dtl.refno) -// .success()) -// } else { -// PersonTransBuilder.newBuilder(accountUtilServcie) -// .done(dtl.refno, TradeDict.DTL_STATUS_FAIL, personBalancePayService) -// ResponseEntity.ok(ResponseBodyBuilder.create() -// .fail(TradeErrorCode.TRANSACTION_NOT_EXISTS, "交易请求失败-${code.retcode}")) -// } -// } catch (e: TransactionException) { -// ResponseEntity.ok(ResponseBodyBuilder.create() -// .transException(e, "交易确认失败")) -// } -// } + // // /** // * 微信支付 diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/consume_pay_service.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/consume_pay_service.kt index a81b21a0..54d84753 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/service/consume_pay_service.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/consume_pay_service.kt @@ -9,4 +9,7 @@ interface ConsumePayService{ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) fun getPaytypeConfig(paytype: String, shopaccno: String, anonymousflag: Boolean? = false, ignoreStatus: Boolean? = false): Map + + @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) + fun getUserdtlExtendParamMap(refno: String): Map } \ No newline at end of file diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/Consume_pay_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/Consume_pay_service_impl.kt index 6f361556..3c40253f 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/Consume_pay_service_impl.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/Consume_pay_service_impl.kt @@ -1,9 +1,10 @@ package com.supwisdom.dlpay.api.service.impl -import com.supwisdom.dlpay.api.dao.PaytypeConfigDao import com.supwisdom.dlpay.api.dao.PaytypeDao import com.supwisdom.dlpay.api.dao.ShopPaytypeConfigDao import com.supwisdom.dlpay.api.dao.ShopPaytypeDao +import com.supwisdom.dlpay.api.dao.UserdtlBusinessDao +import com.supwisdom.dlpay.api.domain.TUserdtlBusiness import com.supwisdom.dlpay.api.service.ConsumePayService import com.supwisdom.dlpay.exception.TransactionProcessException import com.supwisdom.dlpay.framework.util.TradeErrorCode @@ -19,6 +20,8 @@ class ConsumePayServiceImpl: ConsumePayService{ lateinit var shopPaytypeDao: ShopPaytypeDao @Autowired lateinit var shopPaytypeConfigDao: ShopPaytypeConfigDao + @Autowired + lateinit var userdtlBusinessDao: UserdtlBusinessDao override fun checkShopPaytype(shopaccno: String, paytype: String, anonymousflag: Boolean?): Boolean{ paytypeDao.getByPaytype(paytype).let { @@ -53,6 +56,7 @@ class ConsumePayServiceImpl: ConsumePayService{ if (null == it) { throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统不支持支付方式[$paytype]") } else { + //对账取配置时不关心状态,不能报错 if (true != ignoreStatus && (ConstantUtil.ENABLE_YES != it.enable || ConstantUtil.ENABLE_YES != it.consumeEnable)) { throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统未启用支付方式[$paytype]消费") } @@ -66,6 +70,7 @@ class ConsumePayServiceImpl: ConsumePayService{ if (null == it) { throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "该商户[$shopaccno]未启用支付方式[$paytype]") } else { + //对账取配置时不关心状态,不能报错 if (true != ignoreStatus && ConstantUtil.ENABLE_YES != it.consumeEnable) { throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "该商户[$shopaccno]未启用支付方式[$paytype]") } @@ -85,4 +90,10 @@ class ConsumePayServiceImpl: ConsumePayService{ } } ?: throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "该商户[$shopaccno]的支付方式[$paytype]未配置参数") } + + override fun getUserdtlExtendParamMap(refno: String): Map { + return userdtlBusinessDao.getByRefno(refno)?.let { + it.contentMap + } ?: mutableMapOf() + } } \ No newline at end of file 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 7ef63a53..a322f11a 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 @@ -3,22 +3,20 @@ package com.supwisdom.dlpay.api.service.impl import com.supwisdom.dlpay.api.PersonTransBuilder import com.supwisdom.dlpay.api.dao.AccountDao import com.supwisdom.dlpay.api.dao.DebitCreditDtlDao +import com.supwisdom.dlpay.api.dao.UserdtlBusinessDao import com.supwisdom.dlpay.api.dao.UserdtlDao import com.supwisdom.dlpay.api.domain.TAccount import com.supwisdom.dlpay.api.domain.TDebitCreditDtl import com.supwisdom.dlpay.api.domain.TUserdtl +import com.supwisdom.dlpay.api.domain.TUserdtlBusiness import com.supwisdom.dlpay.api.service.AccountUtilServcie import com.supwisdom.dlpay.api.service.PersonBalancePayService import com.supwisdom.dlpay.exception.TransactionException import com.supwisdom.dlpay.exception.TransactionProcessException -import com.supwisdom.dlpay.framework.dao.FeetypeConfigDao -import com.supwisdom.dlpay.framework.dao.ShopaccDao -import com.supwisdom.dlpay.framework.dao.SubjectDao -import com.supwisdom.dlpay.framework.dao.TranstypeDao +import com.supwisdom.dlpay.framework.dao.* import com.supwisdom.dlpay.framework.domain.TFeetypeConfig import com.supwisdom.dlpay.framework.domain.TShopacc import com.supwisdom.dlpay.framework.domain.TSubject -import com.supwisdom.dlpay.framework.domain.TTranstype import com.supwisdom.dlpay.framework.service.SystemUtilService import com.supwisdom.dlpay.framework.util.* import org.hibernate.exception.LockTimeoutException @@ -44,7 +42,6 @@ class AccountUtilServcieImpl : AccountUtilServcie { @Autowired lateinit var feetypeConfigDao: FeetypeConfigDao - override fun readAccountForUpdateNowait(userid: String): TAccount { return try { accountDao.getByUseridForUpdateNowait(userid) @@ -88,6 +85,9 @@ class PersonBalancePayServiceImpl : PersonBalancePayService { @Autowired lateinit var accountDao: AccountDao + @Autowired + lateinit var userdtlBusinessDao: UserdtlBusinessDao + @PersistenceContext lateinit var em: EntityManager @@ -129,11 +129,6 @@ class PersonBalancePayServiceImpl : PersonBalancePayService { ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "交易参考号<$refno>不存在") } - private fun checkOuttradenoExist(outtradeno: String): Boolean { -// TODO("判断 outtradeno 重复发起") - return false - } - private fun doDealAccount(accno: String, amount: Double, overdraft: Boolean): TAccount { val account = getlockAccount(accno) if (account.tacCheck()) @@ -158,7 +153,21 @@ class PersonBalancePayServiceImpl : PersonBalancePayService { } override fun init(builder: PersonTransBuilder): TUserdtl { - val userdtl = TUserdtl() + //判断第三方流水号重复 标准:shopaccno + outtradeno 唯一? + var userdtl = userdtlDao.findByOuttradenoAndShopaccno(builder.outtradeno, builder.shopaccno) //加锁? + if (null != userdtl) { + if (TradeDict.DTL_STATUS_INIT != userdtl.status) { + throw TransactionProcessException(TradeErrorCode.OUTTRADENO_ALREADY_EXISTS, "外部流水号重复") //非初始化状态,直接报错 + } + //fixme: 判断是同一笔交易重发(标准??) 是->已初始化直接返回;否 -> 报错:外部流水号重复 + if(builder.amount == userdtl.amount && builder.paytype == userdtl.paytype && builder.transDate == userdtl.transdate && builder.transTime==userdtl.transtime){ + return userdtl // 交易日期,时间重发时是否会变?? + }else{ + throw TransactionProcessException(TradeErrorCode.OUTTRADENO_ALREADY_EXISTS, "外部流水号重复") + } + } + + userdtl = TUserdtl() // 新建流水 userdtl.refno = systemUtilService.refno userdtl.accdate = systemUtilService.accdate userdtl.userid = builder.person.userid @@ -176,20 +185,18 @@ class PersonBalancePayServiceImpl : PersonBalancePayService { userdtl.payinfo = builder.payinfo userdtl.transcode = builder.transcode if (StringUtil.isEmpty(builder.description)) { - userdtl.transdesc = systemUtilService.getTranscodeName(builder.transcode, null); + userdtl.transdesc = systemUtilService.getTranscodeName(builder.transcode, null) } else { userdtl.transdesc = builder.description } userdtl.outtradeno = builder.outtradeno + userdtl.shopaccno = builder.shopaccno // userdtl.operid = when (builder.tradetype) { Tradetype.RECHARGE -> userdtl.tradeflag = 1 Tradetype.CONSUME -> userdtl.tradeflag = 2 } userdtl.createtime = systemUtilService.sysdatetime.hostdatetime - if (checkOuttradenoExist(userdtl.outtradeno)) { - throw TransactionProcessException(TradeErrorCode.OUTTRADENO_ALREADY_EXISTS, "外部流水号重复") - } userdtl.amount = builder.amount userdtl.status = TradeDict.DTL_STATUS_INIT @@ -208,6 +215,11 @@ class PersonBalancePayServiceImpl : PersonBalancePayService { debitCreditDtlDao.save(this) } } + + if(builder.extendMap.isNotEmpty()){ + userdtlBusinessDao.save(TUserdtlBusiness(userdtl.refno, builder.extendMap)) //保存参数 + } + return userdtl } diff --git a/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt b/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt index 894ad77e..02934579 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt @@ -74,7 +74,9 @@ class ResponseBodyBuilder private constructor() { if (retCode == INVALIDE_RETCODE) { throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "未设置返回码!") } else if (retCode != 0) { - LOGGER.error(Gson().toJson(this.respData)) + LOGGER.error("【 ==== ERROR ==== 】: " + Gson().toJson(this.respData)) + }else{ + LOGGER.info("retcode=[0],retmsg=[$retMsg] return success!!! \n" + Gson().toJson(this.respData)) } return this.respData.plus(mapOf("retcode" to retCode, "retmsg" to retMsg)) }