From: Tang Cheng Date: Fri, 19 Jul 2019 16:26:25 +0000 (+0800) Subject: 细化 qrcode 支付接口 X-Git-Tag: 1.0.0^2~12 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=39d56df24bfdd78abe847f6808dce46aaae8d80a;p=epayment%2Ffood_payapi.git 细化 qrcode 支付接口 --- diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/QrcodePayParam.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/QrcodePayParam.java index c5e3cefd..798ffedb 100644 --- a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/QrcodePayParam.java +++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/QrcodePayParam.java @@ -2,36 +2,46 @@ package com.supwisdom.dlpay.api.bean; import com.supwisdom.dlpay.api.APIRequestParam; import com.supwisdom.dlpay.api.annotation.Sign; +import com.supwisdom.dlpay.api.bean.groups.Confirm; +import com.supwisdom.dlpay.api.bean.groups.InitStep; +import com.supwisdom.dlpay.api.bean.groups.Query; import com.supwisdom.dlpay.api.exception.RequestParamCheckException; +import javax.validation.constraints.Min; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; public class QrcodePayParam extends APIRequestParam { @Sign + @NotNull(message = "订单号不能为空", groups = {Query.class, InitStep.class, Confirm.class}) private String billno; + @Sign - private String refno; + @NotNull(message = "商户号不能为空", groups = {Query.class, InitStep.class, Confirm.class}) + private String shopaccno; + @Sign - @NotEmpty(message = "支付码不能为空") + @NotEmpty(message = "支付码不能为空", groups = {InitStep.class}) private String qrcode; @Sign private String userid; + @Sign - @NotEmpty(message = "交易日期不能为空") + @NotEmpty(message = "交易日期不能为空", groups = {InitStep.class, Confirm.class}) private String transdate; + @Sign - @NotEmpty(message = "交易时间不能为空") + @NotEmpty(message = "交易时间不能为空", groups = {InitStep.class, Confirm.class}) private String transtime; + @Sign - @NotNull(message = "交易金额不能为空") + @NotNull(message = "交易金额不能为空", groups = Confirm.class) + @Min(value = 1L, message = "交易金额必须大于零", groups = Confirm.class) private Integer amount; - @Sign - private String shopaccno; @Sign - @NotNull + @NotNull(message = "必须指定是否匿名支付", groups = Confirm.class) private Boolean anonymous; public String getBillno() { @@ -42,14 +52,6 @@ public class QrcodePayParam extends APIRequestParam { this.billno = billno; } - public String getRefno() { - return refno; - } - - public void setRefno(String refno) { - this.refno = refno; - } - public String getQrcode() { return qrcode; } diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/QrcodePayResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/QrcodePayResponse.java index b6aae8f1..15b27b0e 100644 --- a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/QrcodePayResponse.java +++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/QrcodePayResponse.java @@ -2,9 +2,13 @@ package com.supwisdom.dlpay.api.bean; public class QrcodePayResponse extends ApiResponse { private String refno; + private String accdate; private String userid; private Boolean anonymous; private Integer amount; + private String sourceType; + private String paydesc; + private boolean requireQuery; public String getRefno() { return refno; @@ -37,4 +41,36 @@ public class QrcodePayResponse extends ApiResponse { public void setAmount(Integer amount) { this.amount = amount; } + + public String getSourceType() { + return sourceType; + } + + public void setSourceType(String sourceType) { + this.sourceType = sourceType; + } + + public String getPaydesc() { + return paydesc; + } + + public void setPaydesc(String paydesc) { + this.paydesc = paydesc; + } + + public boolean isRequireQuery() { + return requireQuery; + } + + public void setRequireQuery(boolean requireQuery) { + this.requireQuery = requireQuery; + } + + public String getAccdate() { + return accdate; + } + + public void setAccdate(String accdate) { + this.accdate = accdate; + } } diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/groups/Confirm.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/groups/Confirm.java new file mode 100644 index 00000000..dc0dc0f3 --- /dev/null +++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/groups/Confirm.java @@ -0,0 +1,4 @@ +package com.supwisdom.dlpay.api.bean.groups; + +public interface Confirm { +} diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/groups/InitStep.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/groups/InitStep.java new file mode 100644 index 00000000..95806918 --- /dev/null +++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/groups/InitStep.java @@ -0,0 +1,4 @@ +package com.supwisdom.dlpay.api.bean.groups; + +public interface InitStep { +} diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/groups/Query.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/groups/Query.java new file mode 100644 index 00000000..90669fa6 --- /dev/null +++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/bean/groups/Query.java @@ -0,0 +1,4 @@ +package com.supwisdom.dlpay.api.bean.groups; + +public interface Query { +} diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/dao/QrcodePayTransDao.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/dao/QrcodePayTransDao.java index 9cc67303..2f75c01a 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/agent/dao/QrcodePayTransDao.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/dao/QrcodePayTransDao.java @@ -1,16 +1,20 @@ package com.supwisdom.dlpay.agent.dao; import com.supwisdom.dlpay.agent.domain.QrcodePayTrans; +import org.springframework.data.jpa.repository.Lock; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; +import javax.persistence.LockModeType; + @Repository public interface QrcodePayTransDao extends CrudRepository { QrcodePayTrans findByRefnoAndTenantid(String refno, String tenantid); - QrcodePayTrans findByAgentMerchIdAndHostdateAndBillnoAAndTenantid(String mechid, String host, - String billno, String tenantid); + @Lock(LockModeType.OPTIMISTIC) + QrcodePayTrans findByAgentMerchIdAndHostdateAndBillnoAndTenantid(String mechid, String host, + String billno, String tenantid); void deleteByRefnoAndTenantid(String refno, String tenantid); } diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/domain/QrcodePayTrans.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/domain/QrcodePayTrans.java index a6619a41..96f8b06b 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/agent/domain/QrcodePayTrans.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/domain/QrcodePayTrans.java @@ -34,6 +34,9 @@ public class QrcodePayTrans { @Column(name = "agent_user_id", length = 200) private String agentUserId; + @Column(name = "agent_refno", length = 64) + private String agentRefno; + @Column(name = "qrcode", length = 256) @NotNull private String qrcode; @@ -50,8 +53,13 @@ public class QrcodePayTrans { private String userid; @NotNull - @Column(name = "create_time") - private Timestamp create_time; + @Column(name = "createTime") + private Timestamp createTime; + + @Column(name = "update_time") + @NotNull + @Version + private Timestamp updateTime; @NotNull @Column(name = "tenantid", length = 20) @@ -84,12 +92,12 @@ public class QrcodePayTrans { this.qrcode = qrcode; } - public Timestamp getCreate_time() { - return create_time; + public Timestamp getCreateTime() { + return createTime; } - public void setCreate_time(Timestamp create_time) { - this.create_time = create_time; + public void setCreateTime(Timestamp createTime) { + this.createTime = createTime; } public String getTenantid() { @@ -155,4 +163,20 @@ public class QrcodePayTrans { public void setUserid(String userid) { this.userid = userid; } + + public String getAgentRefno() { + return agentRefno; + } + + public void setAgentRefno(String agentRefno) { + this.agentRefno = agentRefno; + } + + public Timestamp getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Timestamp updateTime) { + this.updateTime = updateTime; + } } diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/service/AgentServiceProxy.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/service/AgentServiceProxy.java index 37b76cde..8f2809db 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/agent/service/AgentServiceProxy.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/service/AgentServiceProxy.java @@ -32,7 +32,7 @@ public class AgentServiceProxy { } public QrcodePayTrans qrcodePayTransFindByMerchIdAndBillno(String merchid, String billno) { - return qrcodeTransDao.findByAgentMerchIdAndHostdateAndBillnoAAndTenantid(merchid, + return qrcodeTransDao.findByAgentMerchIdAndHostdateAndBillnoAndTenantid(merchid, systemUtilService.getSysdatetime().getHostdate(), billno, TenantContext.getTenantSchema()); } diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceType.java b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceType.java index 1a27f325..8d09f927 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceType.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceType.java @@ -2,7 +2,6 @@ package com.supwisdom.dlpay.api.domain; import com.supwisdom.dlpay.framework.domain.DictionaryTable; import org.hibernate.annotations.GenericGenerator; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import javax.persistence.*; import javax.validation.constraints.NotNull; @@ -50,6 +49,9 @@ public class TSourceType implements DictionaryTable, Serializable { @NotNull private Boolean checkable; // 是否需要清算 + @Column(name = "asset_subjno") + private @NotNull String assetSubjno; + @Column(name = "PAYDESC", length = 200) private String paydesc; @@ -146,4 +148,12 @@ public class TSourceType implements DictionaryTable, Serializable { public void setSourceTypeId(String sourceTypeId) { this.sourceTypeId = sourceTypeId; } + + public @NotNull String getAssetSubjno() { + return assetSubjno; + } + + public void setAssetSubjno(@NotNull String assetSubjno) { + this.assetSubjno = assetSubjno; + } } diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java index cc1b344f..6c554a8e 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java @@ -2,19 +2,19 @@ package com.supwisdom.dlpay.framework.util; /** * 交易码、交易类型 - * */ + */ public class TradeCode { 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_CITIZENCARD_PAY = 3010; //市民卡代扣消费 + public static final int TRANSCODE_YKTCARD_PAY = 3020; //一卡通支付 - public static final int TRANSCODE_WECHAT=1001; + public static final int TRANSCODE_WECHAT = 1001; + // QRcode 聚合支付 + public static final int TRANSCODE_QRCODE = 1002; public static final int TRANSCODE_ERCHARGE = 3500; //账户充值 - - } 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 fdf77bb3..6a6a75e9 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 @@ -6,18 +6,20 @@ import com.supwisdom.dlpay.agent.domain.QrcodePayTrans import com.supwisdom.dlpay.agent.service.AgentServiceProxy import com.supwisdom.dlpay.api.* import com.supwisdom.dlpay.api.bean.* +import com.supwisdom.dlpay.api.bean.groups.Confirm +import com.supwisdom.dlpay.api.bean.groups.InitStep +import com.supwisdom.dlpay.api.domain.TSourceType import com.supwisdom.dlpay.api.service.* import com.supwisdom.dlpay.exception.TransactionCheckException import com.supwisdom.dlpay.framework.ResponseBodyBuilder import com.supwisdom.dlpay.framework.service.SystemUtilService import com.supwisdom.dlpay.framework.util.* +import org.apache.commons.lang3.StringUtils import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.ApplicationContext import org.springframework.http.ResponseEntity -import org.springframework.web.bind.annotation.PostMapping -import org.springframework.web.bind.annotation.RequestBody -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController +import org.springframework.validation.annotation.Validated +import org.springframework.web.bind.annotation.* import javax.validation.Valid @RestController @@ -442,8 +444,9 @@ class ConsumeAPIController { .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "交易扣费失败")) } - @PostMapping("/qrcode/init") - fun qrcodePayAuth(@RequestBody param: QrcodePayParam): ResponseEntity { + @RequestMapping("/qrcode/init", method = [RequestMethod.POST, RequestMethod.GET]) + fun qrcodePayInit(@Validated(InitStep::class) @RequestBody param: QrcodePayParam): ResponseEntity { + // 1. 检查 qrcode val qrcode = agentServiceProxy.qrcodeMatch(param.qrcode) ?: return ResponseEntity.ok(ResponseBodyBuilder.create() .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, "未识别的支付码")) @@ -452,7 +455,13 @@ class ConsumeAPIController { ?: return ResponseEntity.ok(ResponseBodyBuilder.create() .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, "不支持的支付方式<${qrcode.sourceType}>")) - + if (sourceType.assetSubjno.isEmpty() + || !StringUtils.isNumeric(sourceType.assetSubjno)) { + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, + "支付方式<${qrcode.sourceType}>未配置科目号")) + } + // 2. 记录 qrcode 交易明细表 val qrcodeTrans = agentServiceProxy.qrcodePayTransSaveOrUpdate( QrcodePayTrans().apply { this.agentMerchId = param.shopaccno @@ -460,21 +469,25 @@ class ConsumeAPIController { this.qrcode = param.qrcode }) + // 3. 查询用户身份 val service = createAgentService(qrcode.sourceType) - val agentResp = service.auth(qrcodeTrans.agentMerchId, qrcodeTrans.billno) - + // 4. 重新读取 qrcode 交易明细表,以获取 service.auth 查询后的结果数据 + val qrcodeTransResp = agentServiceProxy.qrcodePayTransFindByMerchIdAndBillno(qrcodeTrans.agentMerchId, + qrcodeTrans.billno) + val apiResp = QrcodePayResponse().also { + it.sourceType = sourceType.sourceType + it.paydesc = qrcodeSummary(sourceType) + } return when (agentResp.code) { AgentCode.SUCCESS -> { - val qrcodeTransResp = agentServiceProxy.qrcodePayTransFindByMerchIdAndBillno(qrcodeTrans.agentMerchId, - qrcodeTrans.billno) if (!sourceType.anonymousEnable && qrcodeTransResp.isAnonymous) { ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, + .fail(apiResp, TradeErrorCode.BUSINESS_DEAL_ERROR, "支付方式<${qrcode.sourceType}> 不支持匿名支付")) } else { ResponseEntity.ok(ResponseBodyBuilder.create() - .success(QrcodePayResponse().also { + .success(apiResp.also { it.anonymous = qrcodeTransResp.isAnonymous it.userid = qrcodeTransResp.agentUserId })) @@ -483,207 +496,130 @@ class ConsumeAPIController { AgentCode.NOT_SUPPORT -> { if (!sourceType.anonymousEnable) { ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, + .fail(apiResp, TradeErrorCode.BUSINESS_DEAL_ERROR, "支付方式<${qrcode.sourceType}> 不支持匿名支付")) } else { ResponseEntity.ok(ResponseBodyBuilder.create() - .success(QrcodePayResponse().also { - it.anonymous = true + .success(apiResp.also { + it.anonymous = qrcodeTransResp.isAnonymous })) } } else -> { ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, + .fail(apiResp, TradeErrorCode.BUSINESS_DEAL_ERROR, "第三方身份错误,<${agentResp.agentMsg}")) } } } + private fun qrcodeSummary(st: TSourceType): String = st.paydesc + "扫码付" + @PostMapping("/qrcodepay/confirm") - fun qrcodePayInit(@Valid @RequestBody param: QrcodePayParam): ResponseEntity { + fun qrcodePayConfirm(@Validated(Confirm::class) @RequestBody param: QrcodePayParam): ResponseEntity { //1. 交易检查 + val apiResponse = QrcodePayResponse() val qrcodeTrans = agentServiceProxy.qrcodePayTransFindByMerchIdAndBillno(param.shopaccno, param.billno) ?: return ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, "未找到billno")) + .fail(apiResponse, TradeErrorCode.BUSINESS_DEAL_ERROR, "未找到billno")) if (qrcodeTrans.refno.isNotEmpty()) { return ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, "该交易已确认,请查询结果")) + .fail(apiResponse, TradeErrorCode.BUSINESS_DEAL_ERROR, "该交易已确认,请查询结果")) } if (qrcodeTrans.qrcode != param.qrcode && param.qrcode.isNotEmpty()) { val qrcode = agentServiceProxy.qrcodeMatch(param.qrcode) ?: return ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, "未识别的支付码")) + .fail(apiResponse, TradeErrorCode.BUSINESS_DEAL_ERROR, "未识别的支付码")) if (qrcodeTrans.sourceType != qrcode.sourceType) { return ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, "支付码不符")) + .fail(apiResponse, TradeErrorCode.BUSINESS_DEAL_ERROR, "支付码不符")) } qrcodeTrans.qrcode = param.qrcode } val sourceType = sourceTypeService.getBySourceType(qrcodeTrans.sourceType) ?: return ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, + .fail(apiResponse, TradeErrorCode.BUSINESS_DEAL_ERROR, "不支持的支付方式<${qrcodeTrans.sourceType}>")) if (!sourceType.anonymousEnable && qrcodeTrans.isAnonymous) { return ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, + .fail(apiResponse, TradeErrorCode.BUSINESS_DEAL_ERROR, "支付方式<${qrcodeTrans.sourceType}>不支持匿名支付")) } //2. 初始化交易流水 + // sourcetype 资产类科目 + val stSubject = accountUtilServcie.readSubject(sourceType.assetSubjno) + // build 交易明细 val builder = TransactionBuilder().apply { - setTransInfo(param.transdate, param.transtime, TradeCode.TRANSCODE_WECHAT, qrcodeTrans.sourceType) + setTransInfo(param.transdate, param.transtime, TradeCode.TRANSCODE_QRCODE, qrcodeTrans.sourceType) setOutTransInfo(qrcodeTrans.agentMerchId, qrcodeTrans.billno) } val shopacc = accountUtilServcie.readShopbyShopaccno(qrcodeTrans.agentMerchId) + val amount = param.amount / 100.0 builder.shop(shopacc).apply { - setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_IN) + setAmount(amount, TradeDict.TRADE_FLAG_IN) } if (qrcodeTrans.isAnonymous) { builder.anonymous().apply { - setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_OUT) - } + setAmount(amount, TradeDict.TRADE_FLAG_OUT) + setOpposite(shopacc.shopaccno, shopacc.shopname) + }.and() // 匿名消费时,借 科目 , è´· 商户 + .addDebitCreditRecord(AccountProxy(stSubject), AccountProxy(shopacc), + amount, qrcodeSummary(sourceType)) } else { val account = accountUtilServcie.readAccount(qrcodeTrans.userid) builder.person(account).apply { - setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_OUT) + setAmount(amount, TradeDict.TRADE_FLAG_OUT) + setOpposite(shopacc.shopaccno, shopacc.shopname) }.and().shop().apply { setOpposite(account.accno, account.accname) - } + }.and() // 实名消费时, 1. 借 科目, è´· 个人账户 ;2. 借 个人账户 è´· 商户 + .addDebitCreditRecord(AccountProxy(stSubject), AccountProxy(account), + amount, qrcodeSummary(sourceType)) + .addDebitCreditRecord(AccountProxy(account), AccountProxy(shopacc), + amount, qrcodeSummary(sourceType)) } - val transaction = builder.person().apply { - setOpposite(shopacc.shopaccno, shopacc.shopname) - }.and().init(transactionService) + // 同一个客户ID + billno 是唯一索引,如果重复请求不能保存 + val transaction = builder.init(transactionService) + + // qrcode 交易明细表记录 refno qrcodeTrans.refno = transaction.refno + // 保存失败,可能客户端重复请求,导致前序交易已完成 agentServiceProxy.qrcodePayTransSaveOrUpdate(qrcodeTrans) //3. 调用第三方支付 transactionService.wip(transaction.refno) val service = createAgentService(qrcodeTrans.sourceType) - val response = service.pay(transaction) + apiResponse.apply { + refno = transaction.refno + accdate = transaction.accdate + isRequireQuery = false + anonymous = qrcodeTrans.isAnonymous + } + val response = service.pay(transaction) return when (response.code) { AgentCode.SUCCESS -> { transactionService.success(transaction.refno) ResponseEntity.ok(ResponseBodyBuilder.create() - .success(QrcodePayResponse().also { - it.refno = transaction.refno - })) + .success(apiResponse)) } AgentCode.REQUIRE_QUERY -> { ResponseEntity.ok(ResponseBodyBuilder.create() - .success(QrcodePayResponse().also { - it.refno = transaction.refno + .success(apiResponse.also { + it.isRequireQuery = true })) } else -> { transactionService.fail(transaction.refno, response.agentMsg) ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, + .fail(apiResponse, TradeErrorCode.BUSINESS_DEAL_ERROR, "第三方身份错误,<${response.agentMsg}")) } } } - -// ============================================== // -// -// @GetMapping("/account/payinit") -// fun accountPayInit(userid: String, amount: Int, manageFee: Int): ResponseEntity { -// val dtl = PersonTransBuilder.newBuilder(accountUtilServcie) -// .setTransDatetime("20190411", "112311") -// .enableOverdraft(false) -// .addDetail(AccountHolder.person(userid), -// AccountHolder.shop("12323"), -// amount / 100.0, "") -// .addDetail(AccountHolder.person(userid), AccountHolder.transType(301), -// manageFee / 100.0, "") -// .done(personBalancePayService, false) -// -// return ResponseEntity.ok(dtl) -// } -// -// @GetMapping("/account/payfinish") -// fun accountPayFinish(refno: String): ResponseEntity { -// val dtl = PersonTransBuilder.newBuilder(accountUtilServcie) -// .done(refno, TradeDict.DTL_STATUS_SUCCESS, personBalancePayService) -// return ResponseEntity.ok(dtl) -// } - - -// -// /** -// * 微信支付 -// * wechattype -// * qrcode-扫微信二维码支付 -// * app-原生app微信支付 -// * mp-微信公众号支付 -// * h5-微信h5支付 -// * -// * */ -// @PostMapping("/wechat/payinit") -// fun wechatPayInit(userid: String, amount: Int, manageFee: Int, -// stuempno: String, shopid: String, transdate: String, transtime: String, -// outtradeno: String, payinfo: String, feetype: String, -// wechattype: String, realip: String?, qrcode: String?, openid: String?): ResponseEntity { -// return try { -// val paytype = paytypeService.getBySourceType(PaytypeUtil.WECHAT) -// if (paytype == null || ConstantUtil.ENABLE_YES != paytype.enable) { -// ResponseEntity.ok(ResponseBodyBuilder.create() -// .fail(1, "支付方式未开启")) -// } -// val person = userService.findByThirdUniqueIdenty(stuempno) -// val dtl = PersonTransBuilder.newBuilder(accountUtilServcie) -// .setTransDatetime(transdate, transtime) -// .selectPaytype(PaytypeUtil.WECHAT, payinfo) -// .setOuttradeno(outtradeno) -// .also { -// if (null != person) it.setOwner(person) -// } -// .tryLock(true) -// .setTransinfo(TradeCode.TRANSCODE_WECHAT, "微信支付") -// .chooseTradetype(Tradetype.CONSUME) -// .also { -// when (feetype) { -// TradeDict.FEETYPE_CONSUME_MEALER -> { -// it.addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_WECHAT), -// AccountHolder.shop(shopid), -// amount / 100.0, "微信支付") -// .addDetail(AccountHolder.transType(TranstypeCode.TT_CONSUUME_MANAGE_FEE) -// .with(AccountHolder.shop(shopid)), -// manageFee / 100.0) -// } -// TradeDict.FEETYPE_CONSUME_DISCOUNT -> { -// it.addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_WECHAT), -// AccountHolder.shop(shopid), -// (amount - manageFee) / 100.0, "微信支付") -// .addDetail(AccountHolder.subject(Subject.SUBJNO_CONSUME_DISCOUNT), -// AccountHolder.shop(shopid), -// manageFee / 100.0, "优惠折扣") -// } -// else -> { -// it.addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_WECHAT), -// AccountHolder.shop(shopid), -// amount / 100.0, "微信支付") -// } -// } -// }.done(personBalancePayService, false) -// val code = CallService.callWechatPay(paytypeService.getSourceTypeConfigBySourceType(PaytypeUtil.WECHAT), -// dtl, DateUtil.getNow(), wechattype, realip, qrcode, openid) -// if (code.retcode == "0") { -// ResponseEntity.ok(ResponseBodyBuilder.create() -// .data("refno", dtl.refno) -// .success()) -// } else { -// ResponseEntity.ok(ResponseBodyBuilder.create() -// .fail(TradeErrorCode.TRANSACTION_NOT_EXISTS, "交易请求失败-${code.retcode}")) -// } -// } catch (e: TransactionException) { -// ResponseEntity.ok(ResponseBodyBuilder.create() -// .transException(e, "交易初始化异常")) -// } -// } } \ No newline at end of file diff --git a/payapi/src/main/resources/data.sql b/payapi/src/main/resources/data.sql index 31b965a9..f1d7f88d 100644 --- a/payapi/src/main/resources/data.sql +++ b/payapi/src/main/resources/data.sql @@ -439,23 +439,23 @@ VALUES (30, '6602', 2, 'y', 1, NULL, 20190430, 1, '管理费收入', 6, '{tenant INSERT INTO "tb_sourcetype" ("sourcetype_id", "sourcetype", "checkable", "paydesc", "enable", "charge_enable", -"consume_enable", "anonymous_enable", "reversable", "tenantid") -VALUES ('D3820D49DACA49199E36537F6719665F', 'citizenCard', 't', '大理市民卡', 't', 'f', 't', 'f', 't', '{tenantid}'); +"consume_enable", "anonymous_enable", "reversable", "asset_subjno", "tenantid") +VALUES ('D3820D49DACA49199E36537F6719665F', 'citizenCard', 't', '大理市民卡', 't', 'f', 't', 'f', 't', '112234', '{tenantid}'); INSERT INTO "tb_sourcetype" ("sourcetype_id", "sourcetype", "checkable", "paydesc", "enable", "charge_enable", -"consume_enable", "anonymous_enable", "reversable", "tenantid") -VALUES ('0997477F40904AD1A2E37FD15345CE00', 'balance', 'f', '账户余额', 't', 'f', 't', 'f', 't', '{tenantid}'); +"consume_enable", "anonymous_enable", "reversable", "asset_subjno","tenantid") +VALUES ('0997477F40904AD1A2E37FD15345CE00', 'balance', 'f', '账户余额', 't', 'f', 't', 'f', 't', '-', '{tenantid}'); INSERT INTO "tb_sourcetype" ("sourcetype_id", "sourcetype", "checkable", "paydesc", "enable", "charge_enable", -"consume_enable", "anonymous_enable", "reversable", "tenantid") -VALUES ('F0CA47ADC0F24DFCA0D95DF4136CC2D0', 'thirdpart', 'f', '其他第三方支付', 't', 't', 'f', 'f', 'f', '{tenantid}'); +"consume_enable", "anonymous_enable", "reversable", ""asset_subjno",tenantid") +VALUES ('F0CA47ADC0F24DFCA0D95DF4136CC2D0', 'thirdpart', 'f', '其他第三方支付', 't', 't', 'f', 'f', 'f','-', '{tenantid}'); INSERT INTO "tb_sourcetype" ("sourcetype_id", "sourcetype", "checkable", "paydesc", "enable", "charge_enable", -"consume_enable", "anonymous_enable", "reversable", "tenantid") -VALUES ('F5B344726FA24BD896E70DEE3D3F46CA', 'swyktv5', 't', '一卡通支付', 't', 't', 't', 't', 't', '{tenantid}'); +"consume_enable", "anonymous_enable", "reversable", "asset_subjno","tenantid") +VALUES ('F5B344726FA24BD896E70DEE3D3F46CA', 'swyktv5', 't', '一卡通支付', 't', 't', 't', 't', 't','-', '{tenantid}'); INSERT INTO "tb_sourcetype" ("sourcetype_id", "sourcetype", "checkable", "paydesc", "enable", "charge_enable", -"consume_enable", "anonymous_enable", "reversable", "tenantid") -VALUES ('28EE54CD3B044CC197D6C5B0E309F8B8', 'alipay', 't', '支付宝', 't', 't', 't', 't', 'f', '{tenantid}'); +"consume_enable", "anonymous_enable", "reversable", "asset_subjno","tenantid") +VALUES ('28EE54CD3B044CC197D6C5B0E309F8B8', 'alipay', 't', '支付宝', 't', 't', 't', 't', 'f', '112230', '{tenantid}'); INSERT INTO "tb_sourcetype" ("sourcetype_id", "sourcetype", "checkable", "paydesc", "enable", "charge_enable", -"consume_enable", "anonymous_enable", "reversable", "tenantid") -VALUES ('DAEF88B54B684347B2B83940C38C7671', 'wechat', 't', '微信支付', 't', 't', 't', 't', 'f', '{tenantid}'); +"consume_enable", "anonymous_enable", "reversable", "asset_subjno","tenantid") +VALUES ('DAEF88B54B684347B2B83940C38C7671', 'wechat', 't', '微信支付', 't', 't', 't', 't', 'f', '112231', '{tenantid}'); -- 支付方式 INSERT INTO TB_SOURCETYPE_CONFIG (ID, SOURCETYPE,CONFIGID,CONFIG_NAME,CONFIG_VALUE,GLOBALFLAG, "tenantid") @@ -503,6 +503,8 @@ VALUES (1, '支付中心', 0, 0, 'normal', '20190517', '{tenantid}'); INSERT INTO "tb_transcode" ("transcode", "transname", "tenantid") VALUES (3010, '市民卡代扣', '{tenantid}'); INSERT INTO "tb_transcode" ("transcode", "transname", "tenantid") +VALUES (1002, '支付码聚合付', '{tenantid}'); +INSERT INTO "tb_transcode" ("transcode", "transname", "tenantid") VALUES (3500, '账户充值', '{tenantid}'); INSERT INTO "tb_dictionary" ("id", "dictval", "dicttype", "dictcaption", "dicttypename", "tenantid") @@ -571,9 +573,9 @@ VALUES (29, 'canteen', 'dtltypeList', '食堂就餐', '流水类型', '{tenantid INSERT INTO "tb_dictionary" ("id", "dictval", "dicttype", "dictcaption", "dicttypename", "tenantid") VALUES (30, 'shopmarket', 'dtltypeList', '商超消费', '流水类型', '{tenantid}'); -INSERT INTO QRCODE_PATTERN(ID, PATTERN, SOURCETYPE, TENANTID) +INSERT INTO TB_QRCODE_PATTERN(ID, PATTERN, SOURCETYPE, TENANTID) VALUES(1, '28\d{16}', 'alipay', '{tenantid}'); -INSERT INTO QRCODE_PATTERN(ID, PATTERN, SOURCETYPE, TENANTID) -VALUES(1, '13\d{16}', 'wechatpay', '{tenantid}'); +INSERT INTO TB_QRCODE_PATTERN(ID, PATTERN, SOURCETYPE, TENANTID) +VALUES(2, '13\d{16}', 'wechatpay', '{tenantid}'); ---------------------------------------------------- commit; \ No newline at end of file