From a780011bff342130fb7c269dc06fdef2fbe23cd0 Mon Sep 17 00:00:00 2001 From: Tang Cheng Date: Fri, 19 Jul 2019 20:33:08 +0800 Subject: [PATCH] =?utf8?q?=E5=AE=9E=E7=8E=B0qrcode=E8=81=9A=E5=90=88?= =?utf8?q?=E6=94=AF=E4=BB=98=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../dlpay/api/bean/QrcodePayParam.java | 33 +++- .../com/supwisdom/dlpay/agent/AgentCode.java | 1 + .../dlpay/agent/AgentPayService.java | 2 + .../dlpay/agent/dao/QrcodePatternDao.java | 3 + .../dlpay/agent/dao/QrcodePayTransDao.java | 3 + .../dlpay/agent/domain/QrcodePattern.java | 12 ++ .../dlpay/agent/domain/QrcodePayTrans.java | 83 ++++++++- .../agent/service/AgentServiceProxy.java | 25 +-- .../impl/QrcodePatternServiceImpl.java | 8 +- .../dlpay/agent/service/alipay_service.kt | 7 + .../dlpay/agent/service/balance_service.kt | 6 + .../agent/service/citizencard_service.kt | 6 + .../dlpay/agent/service/swykt_service.kt | 7 + .../dlpay/agent/service/wanxiao_service.kt | 7 + .../dlpay/agent/service/weichat_service.kt | 7 + .../api/controller/consume_api_controller.kt | 161 ++++++++++++++++-- .../service/impl/transaction_service_impl.kt | 14 +- .../dlpay/api/transaction_builder.kt | 21 ++- payapi/src/main/resources/data.sql | 5 +- 19 files changed, 368 insertions(+), 43 deletions(-) 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 d7eecb2d..c5e3cefd 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 @@ -14,7 +14,10 @@ public class QrcodePayParam extends APIRequestParam { private String refno; @Sign @NotEmpty(message = "支付码不能为空") - private String qrcoode; + private String qrcode; + + @Sign + private String userid; @Sign @NotEmpty(message = "交易日期不能为空") private String transdate; @@ -27,6 +30,10 @@ public class QrcodePayParam extends APIRequestParam { @Sign private String shopaccno; + @Sign + @NotNull + private Boolean anonymous; + public String getBillno() { return billno; } @@ -43,12 +50,12 @@ public class QrcodePayParam extends APIRequestParam { this.refno = refno; } - public String getQrcoode() { - return qrcoode; + public String getQrcode() { + return qrcode; } - public void setQrcoode(String qrcoode) { - this.qrcoode = qrcoode; + public void setQrcode(String qrcode) { + this.qrcode = qrcode; } public String getTransdate() { @@ -83,6 +90,22 @@ public class QrcodePayParam extends APIRequestParam { this.shopaccno = shopaccno; } + public Boolean getAnonymous() { + return anonymous; + } + + public void setAnonymous(Boolean anonymous) { + this.anonymous = anonymous; + } + + public String getUserid() { + return userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } + @Override public boolean checkParam() throws RequestParamCheckException { return true; diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentCode.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentCode.java index 66c15796..950f3381 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentCode.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentCode.java @@ -9,6 +9,7 @@ public enum AgentCode { REQUIRE_QUERY("require_query", "交易未完成,请查询"), WAIT_NOTIFY("wait_notify", "交易已发起,等待通知"), SHORT_OF_BALANCE("short_of_balance", "余额不足"), + NOT_SUPPORT("not_support", "不支持功能"), COMMON_ERROR("common_error", "其它错误"); AgentCode(String code, String msg) { diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentPayService.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentPayService.java index 5ba80d6e..9b10dfc1 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentPayService.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentPayService.java @@ -3,6 +3,8 @@ package com.supwisdom.dlpay.agent; import com.supwisdom.dlpay.api.domain.TTransactionMain; public interface AgentPayService { + AgentResponse auth(String agentid, String billno); + AgentResponse pay(TTransactionMain transaction); AgentResponse cancel(TTransactionMain transaction); diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/dao/QrcodePatternDao.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/dao/QrcodePatternDao.java index 54da64e1..d63e9d07 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/agent/dao/QrcodePatternDao.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/dao/QrcodePatternDao.java @@ -3,5 +3,8 @@ package com.supwisdom.dlpay.agent.dao; import com.supwisdom.dlpay.agent.domain.QrcodePattern; import org.springframework.data.repository.CrudRepository; +import java.util.List; + public interface QrcodePatternDao extends CrudRepository { + List findByTenantid(String tenantid); } 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 1db85a80..9cc67303 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 @@ -9,5 +9,8 @@ import org.springframework.stereotype.Repository; public interface QrcodePayTransDao extends CrudRepository { QrcodePayTrans findByRefnoAndTenantid(String refno, String tenantid); + QrcodePayTrans findByAgentMerchIdAndHostdateAndBillnoAAndTenantid(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/QrcodePattern.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/domain/QrcodePattern.java index 2949c61b..c74bbd37 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/agent/domain/QrcodePattern.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/domain/QrcodePattern.java @@ -20,6 +20,10 @@ public class QrcodePattern { @NotNull private String pattern; + @Column(name = "tenantid", length = 20) + @NotNull + private String tenantid; + public Integer getId() { return id; } @@ -43,4 +47,12 @@ public class QrcodePattern { public void setPattern(String pattern) { this.pattern = pattern; } + + public String getTenantid() { + return tenantid; + } + + public void setTenantid(String tenantid) { + this.tenantid = 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 e5ccb696..a6619a41 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 @@ -7,26 +7,59 @@ import java.sql.Timestamp; @Entity @Table(name = "tb_qrcode_pay_trans", indexes = {@Index(name = "qrcode_pay_trans_idx", columnList = "qrcode, sourcetype"), - @Index(name = "qrcode_pay_trans_idx2", columnList = "tenantid")}) + @Index(name = "qrcode_pay_trans_idx2", columnList = "agent_merch_id, billno, tenantid", unique = true), + @Index(name = "qrcode_pay_trans_idx3", columnList = "agent_merch_id, billno")}) public class QrcodePayTrans { @Id + @SequenceGenerator(name = "qrcode_pay_trans_id", sequenceName = "SEQ_QRCODE_PAY_TRANS", allocationSize = 1, initialValue = 1) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "qrcode_pay_trans_id") + @Column(name = "id") + private int id; + + @Column(name = "agent_merch_id", length = 30) + @NotNull + private String agentMerchId; + + @Column(name = "billno", length = 32) + @NotNull + private String billno; + + @Column(name = "hostdate", length = 8) @NotNull + private String hostdate; + + @Column(name = "refno", length = 32) private String refno; + @Column(name = "agent_user_id", length = 200) private String agentUserId; + @Column(name = "qrcode", length = 256) @NotNull private String qrcode; + + @Column(name = "anonymous") + @NotNull + private boolean anonymous; + @Column(name = "sourcetype", length = 30) @NotNull private String sourceType; + + @Column(name = "userid", length = 40) + private String userid; + @NotNull @Column(name = "create_time") private Timestamp create_time; + @NotNull @Column(name = "tenantid", length = 20) private String tenantid; + public QrcodePayTrans() { + } + public String getRefno() { return refno; } @@ -74,4 +107,52 @@ public class QrcodePayTrans { public void setSourceType(String sourceType) { this.sourceType = sourceType; } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getAgentMerchId() { + return agentMerchId; + } + + public void setAgentMerchId(String agentMerchId) { + this.agentMerchId = agentMerchId; + } + + public String getBillno() { + return billno; + } + + public void setBillno(String billno) { + this.billno = billno; + } + + public String getHostdate() { + return hostdate; + } + + public void setHostdate(String hostdate) { + this.hostdate = hostdate; + } + + public boolean isAnonymous() { + return anonymous; + } + + public void setAnonymous(boolean anonymous) { + this.anonymous = anonymous; + } + + public String getUserid() { + return userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } } 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 d3fb4f4b..37b76cde 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 @@ -3,6 +3,7 @@ package com.supwisdom.dlpay.agent.service; import com.supwisdom.dlpay.agent.dao.QrcodePayTransDao; import com.supwisdom.dlpay.agent.domain.QrcodePattern; import com.supwisdom.dlpay.agent.domain.QrcodePayTrans; +import com.supwisdom.dlpay.framework.service.SystemUtilService; import com.supwisdom.dlpay.framework.tenant.TenantContext; import org.springframework.stereotype.Service; @@ -14,28 +15,32 @@ import java.util.regex.Pattern; @Service public class AgentServiceProxy { - private final QrcodePayTransDao alipayTransDao; + private final QrcodePayTransDao qrcodeTransDao; private final QrcodePatternService qrcodePatternService; + private final SystemUtilService systemUtilService; - public AgentServiceProxy(QrcodePayTransDao alipayTransDao, - QrcodePatternService qrcodePatternService) { - this.alipayTransDao = alipayTransDao; + public AgentServiceProxy(QrcodePayTransDao qrcodeTransDao, + QrcodePatternService qrcodePatternService, + SystemUtilService systemUtilService) { + this.qrcodeTransDao = qrcodeTransDao; this.qrcodePatternService = qrcodePatternService; + this.systemUtilService = systemUtilService; } public QrcodePayTrans qrcodePayTransFindByRefno(String refno) { - return alipayTransDao.findByRefnoAndTenantid(refno, TenantContext.getTenantSchema()); + return qrcodeTransDao.findByRefnoAndTenantid(refno, TenantContext.getTenantSchema()); + } + + public QrcodePayTrans qrcodePayTransFindByMerchIdAndBillno(String merchid, String billno) { + return qrcodeTransDao.findByAgentMerchIdAndHostdateAndBillnoAAndTenantid(merchid, + systemUtilService.getSysdatetime().getHostdate(), billno, TenantContext.getTenantSchema()); } public QrcodePayTrans qrcodePayTransSaveOrUpdate(QrcodePayTrans bean) { if (bean.getTenantid().isEmpty()) { bean.setTenantid(TenantContext.getTenantSchema()); } - return alipayTransDao.save(bean); - } - - public void qrcodePayTransDelete(String refno) { - alipayTransDao.deleteByRefnoAndTenantid(refno, TenantContext.getTenantSchema()); + return qrcodeTransDao.save(bean); } public QrcodePattern qrcodeMatch(String code) { diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/service/impl/QrcodePatternServiceImpl.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/service/impl/QrcodePatternServiceImpl.java index d2ad3919..2d7ad9f5 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/agent/service/impl/QrcodePatternServiceImpl.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/service/impl/QrcodePatternServiceImpl.java @@ -3,11 +3,11 @@ package com.supwisdom.dlpay.agent.service.impl; import com.supwisdom.dlpay.agent.dao.QrcodePatternDao; import com.supwisdom.dlpay.agent.domain.QrcodePattern; import com.supwisdom.dlpay.agent.service.QrcodePatternService; +import com.supwisdom.dlpay.framework.tenant.TenantContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; -import java.util.ArrayList; import java.util.List; @Service @@ -16,10 +16,8 @@ public class QrcodePatternServiceImpl implements QrcodePatternService { private QrcodePatternDao qrcodePatternDao; @Override - @Cacheable(cacheNames = "qrcode_pattern_cache") + @Cacheable(cacheNames = "qrcode_pattern_cache", key = "@tenantHolder.genKey('qrcode_pattern')") public List getAllQrCodePattern() { - List list = new ArrayList<>(); - qrcodePatternDao.findAll().forEach(list::add); - return list; + return qrcodePatternDao.findByTenantid(TenantContext.getTenantSchema()); } } 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 e32f7d8b..a89e2e1d 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 @@ -1,5 +1,6 @@ package com.supwisdom.dlpay.agent.service +import com.supwisdom.dlpay.agent.AgentCode import com.supwisdom.dlpay.agent.AgentPayService import com.supwisdom.dlpay.agent.AgentResponse import com.supwisdom.dlpay.api.domain.TTransactionMain @@ -7,6 +8,12 @@ import org.springframework.stereotype.Component @Component("alipayAgent") class AlipayAgentService : AgentPayService { + override fun auth(shopaccno: String?, billno: String?): AgentResponse { + return AgentResponse().apply { + this.code = AgentCode.NOT_SUPPORT + } + } + override fun pay(transaction: TTransactionMain): AgentResponse { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/balance_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/balance_service.kt index 592153a0..6852f9b2 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/balance_service.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/balance_service.kt @@ -15,6 +15,12 @@ class BalanceAgentService : AgentPayService { agentRefno = "" } + override fun auth(shopaccno: String?, billno: String?): AgentResponse { + return AgentResponse().apply { + this.code = AgentCode.NOT_SUPPORT + } + } + override fun pay(transaction: TTransactionMain): AgentResponse { return responseCode } diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/citizencard_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/citizencard_service.kt index 74975676..5136d37b 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/citizencard_service.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/citizencard_service.kt @@ -43,6 +43,12 @@ class CitizenCardPayAgent : AgentPayService { YnrccRespCode(code, msg ?: "未知")) } + override fun auth(shopaccno: String?, billno: String?): AgentResponse { + return AgentResponse().apply { + this.code = AgentCode.NOT_SUPPORT + } + } + override fun pay(transaction: TTransactionMain): AgentResponse { val resp = citizencardPayService.cardPay(transaction.shopDtl.shopaccno, transaction.personDtl.userid, transaction.accdate, MoneyUtil.YuanToFen(transaction.personDtl.amount), transaction.refno) diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/swykt_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/swykt_service.kt index 7f96f224..165c4c78 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/swykt_service.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/swykt_service.kt @@ -1,5 +1,6 @@ package com.supwisdom.dlpay.agent.service +import com.supwisdom.dlpay.agent.AgentCode import com.supwisdom.dlpay.agent.AgentPayService import com.supwisdom.dlpay.agent.AgentResponse import com.supwisdom.dlpay.api.bean.BaseResp @@ -33,6 +34,12 @@ interface SWYKTV5Service{ @Component("swyktv5Agent") class SWYktV5AgentService : AgentPayService { + override fun auth(shopaccno: String?, billno: String?): AgentResponse { + return AgentResponse().apply { + this.code = AgentCode.NOT_SUPPORT + } + } + override fun pay(transaction: TTransactionMain?): AgentResponse { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/wanxiao_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/wanxiao_service.kt index 06aa907e..eb778754 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/wanxiao_service.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/wanxiao_service.kt @@ -1,5 +1,6 @@ package com.supwisdom.dlpay.agent.service +import com.supwisdom.dlpay.agent.AgentCode import com.supwisdom.dlpay.agent.AgentPayService import com.supwisdom.dlpay.agent.AgentResponse import com.supwisdom.dlpay.api.domain.TTransactionMain @@ -7,6 +8,12 @@ import org.springframework.stereotype.Component @Component("wanxiaoAgent") class WanxiaoAgentService : AgentPayService { + override fun auth(shopaccno: String?, billno: String?): AgentResponse { + return AgentResponse().apply { + this.code = AgentCode.NOT_SUPPORT + } + } + override fun pay(transaction: TTransactionMain?): AgentResponse { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/weichat_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/weichat_service.kt index a6869b5c..dc748d75 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/weichat_service.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/weichat_service.kt @@ -1,5 +1,6 @@ package com.supwisdom.dlpay.agent.service +import com.supwisdom.dlpay.agent.AgentCode import com.supwisdom.dlpay.agent.AgentPayService import com.supwisdom.dlpay.agent.AgentResponse import com.supwisdom.dlpay.api.domain.TTransactionMain @@ -7,6 +8,12 @@ import org.springframework.stereotype.Component @Component("wechatpayAgent") class WeChatPayAgentService : AgentPayService { + override fun auth(shopaccno: String?, billno: String?): AgentResponse { + return AgentResponse().apply { + this.code = AgentCode.NOT_SUPPORT + } + } + override fun pay(transaction: TTransactionMain?): AgentResponse { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } 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 a8b6e05a..fdf77bb3 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 @@ -2,6 +2,8 @@ package com.supwisdom.dlpay.api.controller import com.supwisdom.dlpay.agent.AgentCode import com.supwisdom.dlpay.agent.AgentPayService +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.service.* @@ -35,9 +37,15 @@ class ConsumeAPIController { lateinit var cardService: CardService @Autowired private lateinit var applicationContext: ApplicationContext + + @Autowired + private lateinit var sourceTypeService: SourceTypeService @Autowired lateinit var agentQueryResultTask: AgentQueryResultTask + @Autowired + private lateinit var agentServiceProxy: AgentServiceProxy + /** * ============================================================================ * 消费流水结果查询统一接口 @@ -434,20 +442,151 @@ class ConsumeAPIController { .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "交易扣费失败")) } - @PostMapping("/qrcodepay/init") - fun qrcodePayInit(@Valid @RequestBody param: QrcodePayParam): ResponseEntity { - //1. 识别qrcode - //2. 初始化交易流水 - //3. 调用第三方检查身份信息 - TODO("") + @PostMapping("/qrcode/init") + fun qrcodePayAuth(@RequestBody param: QrcodePayParam): ResponseEntity { + val qrcode = agentServiceProxy.qrcodeMatch(param.qrcode) + ?: return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, "未识别的支付码")) + + val sourceType = sourceTypeService.getBySourceType(qrcode.sourceType) + ?: return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, + "不支持的支付方式<${qrcode.sourceType}>")) + + val qrcodeTrans = agentServiceProxy.qrcodePayTransSaveOrUpdate( + QrcodePayTrans().apply { + this.agentMerchId = param.shopaccno + this.billno = param.billno + this.qrcode = param.qrcode + }) + + val service = createAgentService(qrcode.sourceType) + + val agentResp = service.auth(qrcodeTrans.agentMerchId, qrcodeTrans.billno) + + 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, + "支付方式<${qrcode.sourceType}> 不支持匿名支付")) + } else { + ResponseEntity.ok(ResponseBodyBuilder.create() + .success(QrcodePayResponse().also { + it.anonymous = qrcodeTransResp.isAnonymous + it.userid = qrcodeTransResp.agentUserId + })) + } + } + AgentCode.NOT_SUPPORT -> { + if (!sourceType.anonymousEnable) { + ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, + "支付方式<${qrcode.sourceType}> 不支持匿名支付")) + } else { + ResponseEntity.ok(ResponseBodyBuilder.create() + .success(QrcodePayResponse().also { + it.anonymous = true + })) + } + } + else -> { + ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, + "第三方身份错误,<${agentResp.agentMsg}")) + } + } } @PostMapping("/qrcodepay/confirm") - fun qrcodePayConfirm(@Valid @RequestBody param: QrcodePayParam): ResponseEntity { - //1. 检查交易流水状态,并 wip - //2. 请求第三方交易 - //3. 根据第三方返回处理业务流程 - TODO("") + fun qrcodePayInit(@Valid @RequestBody param: QrcodePayParam): ResponseEntity { + //1. 交易检查 + val qrcodeTrans = agentServiceProxy.qrcodePayTransFindByMerchIdAndBillno(param.shopaccno, + param.billno) ?: return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, "未找到billno")) + if (qrcodeTrans.refno.isNotEmpty()) { + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(QrcodePayResponse(), 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, "未识别的支付码")) + if (qrcodeTrans.sourceType != qrcode.sourceType) { + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(QrcodePayResponse(), 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, + "不支持的支付方式<${qrcodeTrans.sourceType}>")) + if (!sourceType.anonymousEnable && qrcodeTrans.isAnonymous) { + return ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, + "支付方式<${qrcodeTrans.sourceType}>不支持匿名支付")) + } + + //2. 初始化交易流水 + val builder = TransactionBuilder().apply { + setTransInfo(param.transdate, param.transtime, TradeCode.TRANSCODE_WECHAT, qrcodeTrans.sourceType) + setOutTransInfo(qrcodeTrans.agentMerchId, qrcodeTrans.billno) + } + + val shopacc = accountUtilServcie.readShopbyShopaccno(qrcodeTrans.agentMerchId) + builder.shop(shopacc).apply { + setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_IN) + } + if (qrcodeTrans.isAnonymous) { + builder.anonymous().apply { + setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_OUT) + } + } else { + val account = accountUtilServcie.readAccount(qrcodeTrans.userid) + builder.person(account).apply { + setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_OUT) + }.and().shop().apply { + setOpposite(account.accno, account.accname) + } + } + val transaction = builder.person().apply { + setOpposite(shopacc.shopaccno, shopacc.shopname) + }.and().init(transactionService) + + qrcodeTrans.refno = transaction.refno + agentServiceProxy.qrcodePayTransSaveOrUpdate(qrcodeTrans) + + //3. 调用第三方支付 + transactionService.wip(transaction.refno) + val service = createAgentService(qrcodeTrans.sourceType) + 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 + })) + } + AgentCode.REQUIRE_QUERY -> { + ResponseEntity.ok(ResponseBodyBuilder.create() + .success(QrcodePayResponse().also { + it.refno = transaction.refno + })) + } + else -> { + transactionService.fail(transaction.refno, response.agentMsg) + ResponseEntity.ok(ResponseBodyBuilder.create() + .fail(QrcodePayResponse(), TradeErrorCode.BUSINESS_DEAL_ERROR, + "第三方身份错误,<${response.agentMsg}")) + } + } } // ============================================== // diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt index e2ac86c8..edb618cb 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt @@ -87,13 +87,15 @@ class TransactionServiceImpl : TransactionService { TPersondtl().apply { this.refno = transaction.refno this.accdate = transaction.accdate - userid = builder.person().person.userid - accountNo = builder.person().person.accno - userName = builder.person().person.accname + if (!builder.person().isAnonymous()) { + userid = builder.person().person!!.userid + accountNo = builder.person().person!!.accno + userName = builder.person().person!!.accname + befbal = builder.person().person!!.availbal + } outtradeno = builder.outtradeno transdate = builder.transDate transtime = builder.transTime - befbal = builder.person().person.availbal amount = builder.person().amount this.sourceType = builder.sourceType payinfo = builder.person().payinfo @@ -183,9 +185,9 @@ class TransactionServiceImpl : TransactionService { } - if (builder.hasPerson()) { + if (builder.hasPerson() && !builder.person().isAnonymous()) { val dc = getDebitOrCredit(builder.person().tradeFlag, builder.isReverseTrans()) - transaction.sumAmountByAccno(builder.person().person.accno, + transaction.sumAmountByAccno(builder.person().person!!.accno, Subject.SUBJNO_PERSONAL_DEPOSIT, dc).also { if (transaction.personDtl.amount != getTransAmountFromDetail(builder, it)) { diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt index b0f583fb..a20638db 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt @@ -8,6 +8,7 @@ import com.supwisdom.dlpay.framework.domain.TShopacc import com.supwisdom.dlpay.framework.domain.TSubject import com.supwisdom.dlpay.framework.util.TradeDict import com.supwisdom.dlpay.framework.util.TradeErrorCode +import kotlin.math.abs open class SubTransactionBuilder>(val parent: TransactionBuilder) { var payinfo: String = "" @@ -65,7 +66,7 @@ open class SubTransactionBuilder>(val parent: Trans * amount : 交易金额, 正向交易金额必须 >= 0, 冲正交易金额必须 <= 0 */ fun setAmount(amount: Double, inOut: String): SubTransactionBuilder { - this.amount = if (inOut == TradeDict.TRADE_FLAG_IN) Math.abs(amount) else -Math.abs(amount) + this.amount = if (inOut == TradeDict.TRADE_FLAG_IN) abs(amount) else -abs(amount) this.tradeFlag = inOut return this } @@ -80,8 +81,11 @@ open class SubTransactionBuilder>(val parent: Trans } -class PersonTranactionBuilder(parent: TransactionBuilder, val person: TAccount) +class PersonTranactionBuilder(parent: TransactionBuilder, val person: TAccount?) : SubTransactionBuilder(parent) { + fun isAnonymous(): Boolean { + return person == null + } } class ShopTransactionBuilder(parent: TransactionBuilder, val shopacc: TShopacc) @@ -217,6 +221,15 @@ class TransactionBuilder { return this.personBuilder } + fun anonymous(): PersonTranactionBuilder { + if (this::personBuilder.isInitialized) { + throw TransactionCheckException(TradeErrorCode.BUSINESS_DEAL_ERROR, + "交易个人流水已经初始化") + } + this.personBuilder = PersonTranactionBuilder(this, null) + return this.personBuilder + } + fun person(account: TAccount): PersonTranactionBuilder { return if (!this::personBuilder.isInitialized) { PersonTranactionBuilder(this, account).also { @@ -296,7 +309,7 @@ class TransactionBuilder { } fun preCheck() { - if (dtltype.isNullOrEmpty()) { + if (dtltype.isEmpty()) { throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "流水类型错误") } @@ -333,7 +346,7 @@ class TransactionBuilder { } if (hasPerson()) { person().also { - if (it.person.transStatus != TradeDict.STATUS_NORMAL) { + if (!it.isAnonymous() && it.person!!.transStatus != TradeDict.STATUS_NORMAL) { throw TransactionCheckException(TradeErrorCode.PERSON_STATUS_ERROR, "个人状态错误") } diff --git a/payapi/src/main/resources/data.sql b/payapi/src/main/resources/data.sql index 5752950a..31b965a9 100644 --- a/payapi/src/main/resources/data.sql +++ b/payapi/src/main/resources/data.sql @@ -571,6 +571,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) +VALUES(1, '28\d{16}', 'alipay', '{tenantid}'); +INSERT INTO QRCODE_PATTERN(ID, PATTERN, SOURCETYPE, TENANTID) +VALUES(1, '13\d{16}', 'wechatpay', '{tenantid}'); ---------------------------------------------------- commit; \ No newline at end of file -- 2.17.1