实现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 d7eecb2..c5e3cef 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 @@
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 @@
@Sign
private String shopaccno;
+ @Sign
+ @NotNull
+ private Boolean anonymous;
+
public String getBillno() {
return billno;
}
@@ -43,12 +50,12 @@
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 @@
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 66c1579..950f338 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 @@
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 5ba80d6..9b10dfc 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 @@
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 54da64e..d63e9d0 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 @@
import com.supwisdom.dlpay.agent.domain.QrcodePattern;
import org.springframework.data.repository.CrudRepository;
+import java.util.List;
+
public interface QrcodePatternDao extends CrudRepository<QrcodePattern, Integer> {
+ List<QrcodePattern> 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 1db85a8..9cc6730 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 @@
public interface QrcodePayTransDao extends CrudRepository<QrcodePayTrans, String> {
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 2949c61..c74bbd3 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 @@
@NotNull
private String pattern;
+ @Column(name = "tenantid", length = 20)
+ @NotNull
+ private String tenantid;
+
public Integer getId() {
return id;
}
@@ -43,4 +47,12 @@
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 e5ccb69..a6619a4 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 @@
@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 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 d3fb4f4..37b76cd 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 @@
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 @@
@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 d2ad391..2d7ad9f 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 @@
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 @@
private QrcodePatternDao qrcodePatternDao;
@Override
- @Cacheable(cacheNames = "qrcode_pattern_cache")
+ @Cacheable(cacheNames = "qrcode_pattern_cache", key = "@tenantHolder.genKey('qrcode_pattern')")
public List<QrcodePattern> getAllQrCodePattern() {
- List<QrcodePattern> 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 e32f7d8..a89e2e1 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 @@
@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 592153a..6852f9b 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 @@
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 7497567..5136d37 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 @@
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 7f96f22..165c4c7 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 @@
@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 06aa907..eb77875 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 @@
@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 a6869b5..dc748d7 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 @@
@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 a8b6e05..fdf77bb 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 @@
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 @@
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 @@
.fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "交易扣费失败"))
}
- @PostMapping("/qrcodepay/init")
- fun qrcodePayInit(@Valid @RequestBody param: QrcodePayParam): ResponseEntity<Any> {
- //1. 识别qrcode
- //2. 初始化交易流水
- //3. 调用第三方检查身份信息
- TODO("")
+ @PostMapping("/qrcode/init")
+ fun qrcodePayAuth(@RequestBody param: QrcodePayParam): ResponseEntity<ApiResponse> {
+ 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<Any> {
- //1. 检查交易流水状态,并 wip
- //2. 请求第三方交易
- //3. 根据第三方返回处理业务流程
- TODO("")
+ fun qrcodePayInit(@Valid @RequestBody param: QrcodePayParam): ResponseEntity<ApiResponse> {
+ //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 e2ac86c..edb618c 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 @@
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 @@
}
- 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 b0f583f..a20638d 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.TSubject
import com.supwisdom.dlpay.framework.util.TradeDict
import com.supwisdom.dlpay.framework.util.TradeErrorCode
+import kotlin.math.abs
open class SubTransactionBuilder<T : SubTransactionBuilder<T>>(val parent: TransactionBuilder) {
var payinfo: String = ""
@@ -65,7 +66,7 @@
* amount : 交易金额, 正向交易金额必须 >= 0, 冲正交易金额必须 <= 0
*/
fun setAmount(amount: Double, inOut: String): SubTransactionBuilder<T> {
- 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 @@
}
-class PersonTranactionBuilder(parent: TransactionBuilder, val person: TAccount)
+class PersonTranactionBuilder(parent: TransactionBuilder, val person: TAccount?)
: SubTransactionBuilder<PersonTranactionBuilder>(parent) {
+ fun isAnonymous(): Boolean {
+ return person == null
+ }
}
class ShopTransactionBuilder(parent: TransactionBuilder, val shopacc: TShopacc)
@@ -217,6 +221,15 @@
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 @@
}
fun preCheck() {
- if (dtltype.isNullOrEmpty()) {
+ if (dtltype.isEmpty()) {
throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
"流水类型错误")
}
@@ -333,7 +346,7 @@
}
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 5752950..31b965a 100644
--- a/payapi/src/main/resources/data.sql
+++ b/payapi/src/main/resources/data.sql
@@ -571,6 +571,9 @@
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