完成二维码消费初始化接口
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmRequest.java b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmRequest.java
index 51685c4..cc34fe2 100644
--- a/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmRequest.java
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmRequest.java
@@ -13,7 +13,7 @@
/**
* QrcodePayConfirmRequest
*/
-@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-12T16:09:45.966+08:00[Asia/Shanghai]")
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-13T16:43:43.940+08:00[Asia/Shanghai]")
public class QrcodePayConfirmRequest {
@JsonProperty("billno")
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmResponse.java
new file mode 100644
index 0000000..71d6839
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmResponse.java
@@ -0,0 +1,216 @@
+package com.supwisdom.dlpay.payapi.model;
+
+import java.util.Objects;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.openapitools.jackson.nullable.JsonNullable;
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+
+/**
+ * QrcodePayConfirmResponse
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-13T16:43:43.940+08:00[Asia/Shanghai]")
+
+public class QrcodePayConfirmResponse {
+ @JsonProperty("refno")
+ private String refno;
+
+ @JsonProperty("hostDate")
+ private String hostDate;
+
+ @JsonProperty("hostTime")
+ private String hostTime;
+
+ @JsonProperty("description")
+ private String description;
+
+ /**
+ * Gets or Sets result
+ */
+ public enum ResultEnum {
+ SUCCESS("success"),
+
+ REQUIRE_QUERY("require_query"),
+
+ ALREADY_SUCCESS("already_success"),
+
+ FAILED("failed");
+
+ private String value;
+
+ ResultEnum(String value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public String toString() {
+ return String.valueOf(value);
+ }
+
+ @JsonCreator
+ public static ResultEnum fromValue(String value) {
+ for (ResultEnum b : ResultEnum.values()) {
+ if (b.value.equals(value)) {
+ return b;
+ }
+ }
+ throw new IllegalArgumentException("Unexpected value '" + value + "'");
+ }
+ }
+
+ @JsonProperty("result")
+ private ResultEnum result;
+
+ public QrcodePayConfirmResponse refno(String refno) {
+ this.refno = refno;
+ return this;
+ }
+
+ /**
+ * Get refno
+ * @return refno
+ */
+ @ApiModelProperty(value = "")
+
+@Pattern(regexp="[0-9]*") @Size(min=16)
+ public String getRefno() {
+ return refno;
+ }
+
+ public void setRefno(String refno) {
+ this.refno = refno;
+ }
+
+ public QrcodePayConfirmResponse hostDate(String hostDate) {
+ this.hostDate = hostDate;
+ return this;
+ }
+
+ /**
+ * Get hostDate
+ * @return hostDate
+ */
+ @ApiModelProperty(value = "")
+
+@Pattern(regexp="[0-9]*") @Size(min=8,max=8)
+ public String getHostDate() {
+ return hostDate;
+ }
+
+ public void setHostDate(String hostDate) {
+ this.hostDate = hostDate;
+ }
+
+ public QrcodePayConfirmResponse hostTime(String hostTime) {
+ this.hostTime = hostTime;
+ return this;
+ }
+
+ /**
+ * Get hostTime
+ * @return hostTime
+ */
+ @ApiModelProperty(value = "")
+
+@Pattern(regexp="[0-9]*") @Size(min=6,max=6)
+ public String getHostTime() {
+ return hostTime;
+ }
+
+ public void setHostTime(String hostTime) {
+ this.hostTime = hostTime;
+ }
+
+ public QrcodePayConfirmResponse description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ /**
+ * Get description
+ * @return description
+ */
+ @ApiModelProperty(value = "")
+
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public QrcodePayConfirmResponse result(ResultEnum result) {
+ this.result = result;
+ return this;
+ }
+
+ /**
+ * Get result
+ * @return result
+ */
+ @ApiModelProperty(value = "")
+
+
+ public ResultEnum getResult() {
+ return result;
+ }
+
+ public void setResult(ResultEnum result) {
+ this.result = result;
+ }
+
+
+ @Override
+ public boolean equals(java.lang.Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ QrcodePayConfirmResponse qrcodePayConfirmResponse = (QrcodePayConfirmResponse) o;
+ return Objects.equals(this.refno, qrcodePayConfirmResponse.refno) &&
+ Objects.equals(this.hostDate, qrcodePayConfirmResponse.hostDate) &&
+ Objects.equals(this.hostTime, qrcodePayConfirmResponse.hostTime) &&
+ Objects.equals(this.description, qrcodePayConfirmResponse.description) &&
+ Objects.equals(this.result, qrcodePayConfirmResponse.result);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(refno, hostDate, hostTime, description, result);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class QrcodePayConfirmResponse {\n");
+
+ sb.append(" refno: ").append(toIndentedString(refno)).append("\n");
+ sb.append(" hostDate: ").append(toIndentedString(hostDate)).append("\n");
+ sb.append(" hostTime: ").append(toIndentedString(hostTime)).append("\n");
+ sb.append(" description: ").append(toIndentedString(description)).append("\n");
+ sb.append(" result: ").append(toIndentedString(result)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(java.lang.Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+}
+
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitRequest.java b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitRequest.java
index cdb426d..f3fbfac 100644
--- a/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitRequest.java
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitRequest.java
@@ -13,7 +13,7 @@
/**
* QrcodePayInitRequest
*/
-@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-12T16:09:45.966+08:00[Asia/Shanghai]")
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-13T16:43:43.940+08:00[Asia/Shanghai]")
public class QrcodePayInitRequest {
@JsonProperty("qrcode")
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitResponse.java b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitResponse.java
new file mode 100644
index 0000000..0cce937
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitResponse.java
@@ -0,0 +1,156 @@
+package com.supwisdom.dlpay.payapi.model;
+
+import java.util.Objects;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.supwisdom.dlpay.api.bean.ApiResponse;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.openapitools.jackson.nullable.JsonNullable;
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+
+/**
+ * QrcodePayInitResponse
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-13T16:43:43.940+08:00[Asia/Shanghai]")
+
+public class QrcodePayInitResponse extends ApiResponse {
+ @JsonProperty("anonymous")
+ private Boolean anonymous;
+
+ @JsonProperty("userid")
+ private String userid;
+
+ @JsonProperty("username")
+ private String username;
+
+ @JsonProperty("sourcetype")
+ private String sourcetype;
+
+ public QrcodePayInitResponse anonymous(Boolean anonymous) {
+ this.anonymous = anonymous;
+ return this;
+ }
+
+ /**
+ * Get anonymous
+ * @return anonymous
+ */
+ @ApiModelProperty(value = "")
+
+
+ public Boolean getAnonymous() {
+ return anonymous;
+ }
+
+ public void setAnonymous(Boolean anonymous) {
+ this.anonymous = anonymous;
+ }
+
+ public QrcodePayInitResponse userid(String userid) {
+ this.userid = userid;
+ return this;
+ }
+
+ /**
+ * Get userid
+ * @return userid
+ */
+ @ApiModelProperty(value = "")
+
+
+ public String getUserid() {
+ return userid;
+ }
+
+ public void setUserid(String userid) {
+ this.userid = userid;
+ }
+
+ public QrcodePayInitResponse username(String username) {
+ this.username = username;
+ return this;
+ }
+
+ /**
+ * Get username
+ * @return username
+ */
+ @ApiModelProperty(value = "")
+
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public QrcodePayInitResponse sourcetype(String sourcetype) {
+ this.sourcetype = sourcetype;
+ return this;
+ }
+
+ /**
+ * Get sourcetype
+ * @return sourcetype
+ */
+ @ApiModelProperty(value = "")
+
+
+ public String getSourcetype() {
+ return sourcetype;
+ }
+
+ public void setSourcetype(String sourcetype) {
+ this.sourcetype = sourcetype;
+ }
+
+
+ @Override
+ public boolean equals(java.lang.Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ QrcodePayInitResponse qrcodePayInitResponse = (QrcodePayInitResponse) o;
+ return Objects.equals(this.anonymous, qrcodePayInitResponse.anonymous) &&
+ Objects.equals(this.userid, qrcodePayInitResponse.userid) &&
+ Objects.equals(this.username, qrcodePayInitResponse.username) &&
+ Objects.equals(this.sourcetype, qrcodePayInitResponse.sourcetype);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(anonymous, userid, username, sourcetype);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class QrcodePayInitResponse {\n");
+
+ sb.append(" anonymous: ").append(toIndentedString(anonymous)).append("\n");
+ sb.append(" userid: ").append(toIndentedString(userid)).append("\n");
+ sb.append(" username: ").append(toIndentedString(username)).append("\n");
+ sb.append(" sourcetype: ").append(toIndentedString(sourcetype)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(java.lang.Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+}
+
diff --git a/payapi-spec/consumeapi.yaml b/payapi-spec/consumeapi.yaml
index 4d62dd5..1aa2630 100644
--- a/payapi-spec/consumeapi.yaml
+++ b/payapi-spec/consumeapi.yaml
@@ -124,7 +124,8 @@
description: 初始化成功
content:
application/json:
- $ref: '#/components/schemas/QrcodePayInitResponse'
+ schema:
+ $ref: '#/components/schemas/QrcodePayInitResponse'
'default':
description: 请求错误
content:
@@ -148,7 +149,8 @@
description: 交易成功
content:
application/json:
- $ref: '#/components/schemas/QrcodePayConfirmResponse'
+ schema:
+ $ref: '#/components/schemas/QrcodePayConfirmResponse'
'409':
description: 交易正忙,稍后重试
content:
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/k12_consume_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/k12_consume_api_controller.kt
new file mode 100644
index 0000000..5fe60fe
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/k12_consume_api_controller.kt
@@ -0,0 +1,249 @@
+package com.supwisdom.dlpay.api
+
+import com.supwisdom.dlpay.agent.AgentCode
+import com.supwisdom.dlpay.agent.AgentPayService
+import com.supwisdom.dlpay.agent.AgentPayServiceContext
+import com.supwisdom.dlpay.agent.domain.QrcodePayTrans
+import com.supwisdom.dlpay.agent.service.AgentServiceProxy
+import com.supwisdom.dlpay.api.bean.QrcodePayResponse
+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.Dictionary
+import com.supwisdom.dlpay.framework.util.TradeCode
+import com.supwisdom.dlpay.framework.util.TradeDict
+import com.supwisdom.dlpay.framework.util.TradeErrorCode
+import com.supwisdom.dlpay.payapi.model.QrcodePayConfirmRequest
+import com.supwisdom.dlpay.payapi.model.QrcodePayInitRequest
+import com.supwisdom.dlpay.payapi.model.QrcodePayInitResponse
+import org.apache.commons.lang3.StringUtils
+import org.springframework.http.HttpStatus
+import org.springframework.http.ResponseEntity
+import org.springframework.stereotype.Controller
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.context.request.NativeWebRequest
+
+import javax.validation.Valid
+import java.util.Optional
+
+@Controller
+@RequestMapping("\${openapi.aPITitle.base-path:/api}")
+class K12ConsumeApiController
+constructor(private val request: NativeWebRequest,
+ private val agentServiceProxy: AgentServiceProxy,
+ private val systemUtilService: SystemUtilService,
+ private val sourceTypeService: SourceTypeService,
+ private val agentPayServiceContext: AgentPayServiceContext,
+ private val userService: UserService,
+ private val consumePayService: ConsumePayService,
+ private val transactionService: TransactionServiceProxy,
+ private val accountUtilServcie: AccountUtilServcie ) : ConsumeApi {
+
+ override fun getRequest(): Optional<NativeWebRequest> {
+ return Optional.ofNullable(request)
+ }
+
+ override fun qrcodePayInit(xTenantId: String, @Valid param: QrcodePayInitRequest): ResponseEntity<Void> {
+ val apiResp = QrcodePayInitResponse()
+ // 1. 检查 qrcode
+ val qrcode = agentServiceProxy.qrcodeMatch(param.qrcode)
+ ?: return ResponseBodyBuilder.badRequest("未识别的支付码") as ResponseEntity<Void>
+
+ val sourceType = sourceTypeService.getBySourceType(qrcode.sourceType)
+ ?: return ResponseBodyBuilder.badRequest(
+ "不支持的支付方式<${qrcode.sourceType}>") as ResponseEntity<Void>
+ if (sourceType.paySubjno.isEmpty()
+ || !StringUtils.isNumeric(sourceType.paySubjno)) {
+ return ResponseBodyBuilder.notFound(
+ "支付方式<${qrcode.sourceType}>未配置科目号") as ResponseEntity<Void>
+ }
+ val systime = systemUtilService.sysdatetime
+ // 2. 记录 qrcode 交易明细表
+ val qrcodeTrans = agentServiceProxy.qrcodePayTransSaveOrUpdate(
+ QrcodePayTrans().apply {
+ this.agentMerchId = param.shopaccno
+ this.billno = param.billno
+ this.qrcode = param.qrcode
+ this.createTime = systime.sysdate
+ this.hostdate = systime.hostdate
+ this.sourceType = sourceType.sourceType
+ this.updateTime = systime.sysdate
+ })
+ // 3. 查询用户身份
+ val service = createAgentService<QrcodePayTrans>(qrcode.sourceType)
+ val agentResp = service.auth(param.shopaccno, param.billno)
+ // 4. 重新读取 qrcode 交易明细表,以获取 service.auth 查询后的结果数据
+ // 修改, 通过返回值来判断
+// val qrcodeTransResp = agentServiceProxy.qrcodePayTransFindByMerchIdAndBillno(qrcodeTrans.agentMerchId,
+// qrcodeTrans.billno)
+ apiResp.also {
+ it.sourcetype = sourceType.sourceType
+ }
+ return when (agentResp.code) {
+ AgentCode.SUCCESS -> {
+ val qrcodeTransResp = agentResp.payload
+ // 更新qrcode交易明细表 是否匿名 字段
+ agentServiceProxy.qrcodePayTransSaveOrUpdate(qrcodeTrans.also{
+ it.isAnonymous = qrcodeTransResp.isAnonymous
+ })
+ if (!sourceType.anonymousEnable && qrcodeTransResp.isAnonymous) {
+ ResponseBodyBuilder.failEntity(apiResp,
+ HttpStatus.BAD_REQUEST.value(),
+ "支付方式<${qrcode.sourceType}> 不支持匿名支付") as ResponseEntity<Void>
+ } else {
+ val person = userService.findByUseridOrThirdUniqueIdenty(qrcodeTransResp.userid, null)
+ ResponseBodyBuilder.successEntity(
+ QrcodePayInitResponse().apply {
+ this.anonymous = qrcodeTransResp.isAnonymous
+ this.sourcetype = sourceType.sourceType
+ this.userid = qrcodeTransResp.agentUserId
+ this.username = person!!.name
+ }
+ ) as ResponseEntity<Void>
+ }
+ }
+ AgentCode.NOT_SUPPORT -> {
+ val qrcodeTransResp = agentResp.payload
+ agentServiceProxy.qrcodePayTransSaveOrUpdate(qrcodeTrans.also{
+ it.isAnonymous = qrcodeTransResp.isAnonymous
+ })
+ if (!sourceType.anonymousEnable) {
+ ResponseBodyBuilder.failEntity(apiResp,
+ HttpStatus.BAD_REQUEST.value(),
+ "支付方式<${qrcode.sourceType}> 不支持匿名支付") as ResponseEntity<Void>
+ } else {
+ ResponseBodyBuilder.successEntity(apiResp.also {
+ it.anonymous = qrcodeTransResp.isAnonymous
+ }) as ResponseEntity<Void>
+ }
+ }
+ else -> {
+ ResponseBodyBuilder.failEntity(apiResp,
+ HttpStatus.INTERNAL_SERVER_ERROR.value(),
+ "第三方身份错误,<${agentResp.agentMsg}") as ResponseEntity<Void>
+ }
+ }
+ }
+
+ fun <T> createAgentService(sourceType: String): AgentPayService<T> {
+ return agentPayServiceContext.findAgentPayService(sourceType)
+ ?: throw TransactionCheckException(TradeErrorCode.BUSINESS_DEAL_ERROR,
+ "支付类型<$sourceType>未定义")
+ }
+
+// override fun qrcodePayConfirm(xTenantId: String, @Valid param: QrcodePayConfirmRequest): ResponseEntity<Void> {
+// //1. 交易检查
+// val apiResponse = QrcodePayResponse()
+// val qrcodeTrans = agentServiceProxy.qrcodePayTransFindByMerchIdAndBillno(param.shopaccno,
+// param.billno) ?: return ResponseBodyBuilder.notFound(
+// "未找到billno") as ResponseEntity<Void>
+// if (!qrcodeTrans.refno.isNullOrEmpty()) {
+// return ResponseEntity.ok(ResponseBodyBuilder.create()
+// .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(apiResponse, TradeErrorCode.BUSINESS_DEAL_ERROR, "未识别的支付码"))
+// if (qrcodeTrans.sourceType != qrcode.sourceType) {
+// return ResponseEntity.ok(ResponseBodyBuilder.create()
+// .fail(apiResponse, TradeErrorCode.BUSINESS_DEAL_ERROR, "支付码不符"))
+// }
+// qrcodeTrans.qrcode = param.qrcode
+// }
+//
+// val sourceType = sourceTypeService.getBySourceType(qrcodeTrans.sourceType)
+// ?: return ResponseEntity.ok(ResponseBodyBuilder.create()
+// .fail(apiResponse, TradeErrorCode.BUSINESS_DEAL_ERROR,
+// "不支持的支付方式<${qrcodeTrans.sourceType}>"))
+// if (!sourceType.anonymousEnable && qrcodeTrans.isAnonymous) {
+// return ResponseEntity.ok(ResponseBodyBuilder.create()
+// .fail(apiResponse, TradeErrorCode.BUSINESS_DEAL_ERROR,
+// "支付方式<${qrcodeTrans.sourceType}>不支持匿名支付"))
+// }
+// qrcodeTrans.spip = param.spip
+// val dtlType = consumePayService.getDtltypeDictionary(param.dtltype, Dictionary.DTLTYPES)
+// //2. 初始化交易流水
+// // sourcetype 资产类科目
+// val stSubject = accountUtilServcie.readSubject(sourceType.paySubjno)
+// // build 交易明细
+// val builder = TransactionBuilder().apply {
+// setTransInfo(param.transdate, param.transtime, TradeCode.TRANSCODE_QRCODE, qrcodeTrans.sourceType)
+// setOutTransInfo(qrcodeTrans.agentMerchId, qrcodeTrans.billno)
+// payinfo = qrcodeSummary(sourceType)
+// description = dtlType.dictcaption
+// dtltype = param.dtltype
+// }
+//
+// val shopacc = accountUtilServcie.readShopbyShopaccno(qrcodeTrans.agentMerchId)
+// val amount = param.amount / 100.0
+// builder.shop(shopacc).apply {
+// setAmount(amount, TradeDict.TRADE_FLAG_IN)
+// }
+// if (qrcodeTrans.isAnonymous) {
+// builder.anonymous().apply {
+// 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(param.userid)
+// builder.person(account).apply {
+// 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))
+// }
+//
+// // 同一个客户ID + billno 是唯一索引,如果重复请求不能保存
+// val transaction = builder.init(transactionService)
+//
+// // qrcode 交易明细表记录 refno
+// qrcodeTrans.refno = transaction.refno
+// // 保存失败,可能客户端重复请求,导致前序交易已完成
+// agentServiceProxy.qrcodePayTransSaveOrUpdate(qrcodeTrans)
+//
+// //3. 调用第三方支付
+// transactionService.wip(transaction.refno)
+// val service = createAgentService<QrcodePayTrans>(qrcodeTrans.sourceType)
+// 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, response.agentRefno)
+// ResponseEntity.ok(ResponseBodyBuilder.create()
+// .success(apiResponse))
+// }
+// AgentCode.REQUIRE_QUERY -> {
+// ResponseEntity.ok(ResponseBodyBuilder.create()
+// .success(apiResponse.also {
+// it.isRequireQuery = true
+// }))
+// }
+// else -> {
+// transactionService.fail(transaction.refno, response.agentMsg)
+// ResponseEntity.ok(ResponseBodyBuilder.create()
+// .fail(apiResponse, TradeErrorCode.BUSINESS_DEAL_ERROR,
+// "第三方身份错误,<${response.agentMsg}"))
+// }
+// }
+// }
+//
+// override fun qrcodePayQuery(xTenantId: String, refno: String): ResponseEntity<Void> {
+// return null
+// }
+}
\ No newline at end of file