Commit 7008142a authored by Administrator's avatar Administrator

创建项目

parent 9398f372
...@@ -16,6 +16,18 @@ ...@@ -16,6 +16,18 @@
<dependencies> <dependencies>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.8.0</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>cn.quant.baa.pay</groupId> <groupId>cn.quant.baa.pay</groupId>
<artifactId>baa-pay-api</artifactId> <artifactId>baa-pay-api</artifactId>
......
package cn.quant.baa.pay; package cn.quant.baa.pay;
import java.time.Duration;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.Date; import java.util.Date;
...@@ -17,4 +18,9 @@ public class Constant { ...@@ -17,4 +18,9 @@ public class Constant {
*/ */
public static final LocalDate MINI_LOCAL_DATE = LocalDate.of(1970, 1, 1); public static final LocalDate MINI_LOCAL_DATE = LocalDate.of(1970, 1, 1);
public static final Date MINI_DATE = Date.from(MINI_LOCAL_DATE.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()); public static final Date MINI_DATE = Date.from(MINI_LOCAL_DATE.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
public static final String REDIS_NAMESPACE_PAY = "BAAPAY:PAY:P";
@Deprecated
public static final Duration PAY_DUE_TIME = Duration.ofMinutes(30);
} }
package cn.quant.baa.pay.acquirer; package cn.quant.baa.pay.acquirer;
import cn.quant.baa.pay.jpa.entity.PayHistoryEntity;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
/** /**
...@@ -8,6 +9,8 @@ import com.fasterxml.jackson.databind.JsonNode; ...@@ -8,6 +9,8 @@ import com.fasterxml.jackson.databind.JsonNode;
public class ChannelResponse { public class ChannelResponse {
private boolean success; private boolean success;
private String orderNo;
private String code; private String code;
private String message; private String message;
...@@ -22,9 +25,7 @@ public class ChannelResponse { ...@@ -22,9 +25,7 @@ public class ChannelResponse {
//微信平台签名 //微信平台签名
private String signature; private String signature;
private String payUrl; private String notification;
private String prepayId;
private JsonNode node; private JsonNode node;
...@@ -36,6 +37,14 @@ public class ChannelResponse { ...@@ -36,6 +37,14 @@ public class ChannelResponse {
this.success = success; this.success = success;
} }
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public String getCode() { public String getCode() {
return code; return code;
} }
...@@ -92,20 +101,12 @@ public class ChannelResponse { ...@@ -92,20 +101,12 @@ public class ChannelResponse {
this.signature = signature; this.signature = signature;
} }
public String getPayUrl() { public String getNotification() {
return payUrl; return notification;
}
public void setPayUrl(String payUrl) {
this.payUrl = payUrl;
}
public String getPrepayId() {
return prepayId;
} }
public void setPrepayId(String prepayId) { public void setNotification(String notification) {
this.prepayId = prepayId; this.notification = notification;
} }
public JsonNode getNode() { public JsonNode getNode() {
...@@ -127,8 +128,7 @@ public class ChannelResponse { ...@@ -127,8 +128,7 @@ public class ChannelResponse {
sb.append(", timestamp='").append(timestamp).append('\''); sb.append(", timestamp='").append(timestamp).append('\'');
sb.append(", nonce='").append(nonce).append('\''); sb.append(", nonce='").append(nonce).append('\'');
sb.append(", signature='").append(signature).append('\''); sb.append(", signature='").append(signature).append('\'');
sb.append(", payUrl='").append(payUrl).append('\''); sb.append(", notification='").append(notification).append('\'');
sb.append(", prepayId='").append(prepayId).append('\'');
sb.append(", node=").append(node); sb.append(", node=").append(node);
sb.append('}'); sb.append('}');
return sb.toString(); return sb.toString();
......
...@@ -64,27 +64,29 @@ public class MerchantAcquirer implements Acquirer { ...@@ -64,27 +64,29 @@ public class MerchantAcquirer implements Acquirer {
} }
@Override @Override
public ChannelResponse pay(PayRequestData payRequestData, PayHistoryEntity payHistoryEntity) throws Exception { public ChannelResponse pay(PayRequestData request, PayHistoryEntity history) throws Exception {
return acquirers.get(payRequestData.getChanId()).pay(payRequestData, payHistoryEntity); ChannelResponse response = acquirers.get(request.getChanId()).pay(request, history);
response.setOrderNo(String.valueOf(history.getTransactionId()));
return response;
} }
@Override @Override
public ChannelResponse refund(RefundRequestData refundRequestData) throws Exception { public ChannelResponse refund(RefundRequestData request) throws Exception {
return acquirers.get(refundRequestData.getChanId()).refund(refundRequestData); return acquirers.get(request.getChanId()).refund(request);
} }
@Override @Override
public ChannelResponse checkPay(CheckPayRequestData checkPayRequestData) throws Exception { public ChannelResponse checkPay(CheckPayRequestData request) throws Exception {
return acquirers.get(checkPayRequestData.getChanId()).checkPay(checkPayRequestData); return acquirers.get(request.getChanId()).checkPay(request);
} }
@Override @Override
public ChannelResponse checkRefund(CheckRefundRequestData checkRefundRequestData) throws Exception { public ChannelResponse checkRefund(CheckRefundRequestData request) throws Exception {
return acquirers.get(checkRefundRequestData.getChanId()).checkRefund(checkRefundRequestData); return acquirers.get(request.getChanId()).checkRefund(request);
} }
@Override @Override
public ChannelResponse close(CloseRequestData closeRequestData) throws Exception { public ChannelResponse close(CloseRequestData request) throws Exception {
return acquirers.get(closeRequestData.getChanId()).close(closeRequestData); return acquirers.get(request.getChanId()).close(request);
} }
} }
...@@ -100,15 +100,15 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer { ...@@ -100,15 +100,15 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
} }
@Override @Override
public ChannelResponse pay(PayRequestData payRequestData, PayHistoryEntity history) throws Exception { public ChannelResponse pay(PayRequestData request, PayHistoryEntity history) throws Exception {
ObjectNode bodyNode = objectMapper.createObjectNode(); ObjectNode bodyNode = objectMapper.createObjectNode();
// 转换金额为分 // 转换金额为分
BigInteger amount = new BigDecimal(payRequestData.getAmount()).multiply(new BigDecimal(100)).toBigInteger(); BigInteger amount = new BigDecimal(request.getAmount()).multiply(new BigDecimal(100)).toBigInteger();
bodyNode.put("mchid", properties.getPayAcctId()) bodyNode.put("mchid", properties.getPayAcctId())
.put("appid", properties.getPayAppId()) .put("appid", properties.getPayAppId())
.put("attach", payRequestData.getAttach()) .put("attach", request.getAttach())
.put("description", payRequestData.getSubject()) .put("description", request.getSubject())
.put("notify_url", payRequestData.getNotifyUrl()) .put("notify_url", request.getNotifyUrl())
.put("out_trade_no", history.getTransactionId().toString()); .put("out_trade_no", history.getTransactionId().toString());
bodyNode.putObject("amount") bodyNode.putObject("amount")
.put("total", amount); .put("total", amount);
...@@ -127,16 +127,16 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer { ...@@ -127,16 +127,16 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
} }
bodyNode.set("scene_info", sceneInfo); bodyNode.set("scene_info", sceneInfo);
String payAccess = properties.getPayAccess(); String payAccess = properties.getPayAccess();
ChannelResponse response = doExecute(EXECUTE_PAY, payAccess, history.getIds(), bodyNode); ChannelResponse response = doExecute(EXECUTE_PAY, payAccess, request, bodyNode);
JsonNode node = response.getNode(); JsonNode node = response.getNode();
if (node != null) { if (node != null) {
node = response.getNode().get("h5_url"); node = response.getNode().get("h5_url");
if (node != null) { if (node != null) {
response.setPayUrl(node.asText()); response.setNotification(node.asText());
} }
node = response.getNode().get("prepay_id"); node = response.getNode().get("prepay_id");
if (node != null) { if (node != null) {
response.setPrepayId(node.asText()); response.setNotification(node.asText());
} }
//TODO:he APP、小程序、H5、JS不同的方式设置对应的返回参数 //TODO:he APP、小程序、H5、JS不同的方式设置对应的返回参数
} }
...@@ -187,7 +187,7 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer { ...@@ -187,7 +187,7 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
* @param bodyNode * @param bodyNode
* @return * @return
*/ */
private ChannelResponse doExecute(String execute, String access, PayHistoryIds ids, ObjectNode bodyNode) throws Exception { private ChannelResponse doExecute(String execute, String access, Object request, ObjectNode bodyNode) throws Exception {
ChannelResponse response = null; ChannelResponse response = null;
...@@ -238,7 +238,7 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer { ...@@ -238,7 +238,7 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
// if (null == body) { // if (null == body) {
// throw new NullException("http response body is null."); // throw new NullException("http response body is null.");
// } else { // } else {
response = response(execute, access, ids, clientResponse); response = response(execute, access, request, clientResponse);
//签名信息 //签名信息
// String wsSignText = joining("\n", wxTimestamp, nonce, body); // String wsSignText = joining("\n", wxTimestamp, nonce, body);
...@@ -267,17 +267,17 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer { ...@@ -267,17 +267,17 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
response.setCode(COMMON_ERROR_CODE); response.setCode(COMMON_ERROR_CODE);
response.setMessage(COMMON_ERROR_CODE); response.setMessage(COMMON_ERROR_CODE);
} else { } else {
response.setCode(itemDTO.getCode()); response.setCode(itemDTO.getValue());
response.setMessage(itemDTO.getText()); response.setMessage(itemDTO.getText());
} }
} }
return response; return response;
} }
private ChannelResponse response(String execute, String access, PayHistoryIds ids, ClientResponse response) { private ChannelResponse response(String execute, String access, Object request, ClientResponse response) {
if (response == null) { if (response == null) {
throw new NullException(StringUtils.format("Client response is null : {}; {}; {};", execute, access, ids)); throw new NullException(StringUtils.format("Client response is null : {}; {}; {};", execute, access, request));
} }
ChannelResponse responseData = new ChannelResponse(); ChannelResponse responseData = new ChannelResponse();
...@@ -314,18 +314,18 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer { ...@@ -314,18 +314,18 @@ public class WeiXinMerchantAcquirer extends MerchantAcquirer {
} else { } else {
responseData.setSuccess(false); responseData.setSuccess(false);
responseData.setCode(codeNode.asText(COMMON_ERROR_CODE)); responseData.setCode(codeNode.asText(COMMON_ERROR_CODE));
responseData.setMessage(StringUtils.format("Client response http status : {}; {}; {}; {};", execute, access, ids, httpStatus)); responseData.setMessage(StringUtils.format("Client response http status : {}; {}; {}; {};", execute, access, request, httpStatus));
logger.warn(responseData.getMessage()); logger.warn(responseData.getMessage());
} }
} else { } else {
responseData.setSuccess(false); responseData.setSuccess(false);
responseData.setCode(codeNode.asText(COMMON_ERROR_CODE)); responseData.setCode(codeNode.asText(COMMON_ERROR_CODE));
responseData.setMessage(jsonNode.get("message").asText("")); responseData.setMessage(jsonNode.get("message").asText(""));
logger.warn("Client response body code : {}; {}; {}; {};", execute, access, ids, responseData); logger.warn("Client response body code : {}; {}; {}; {};", execute, access, request, responseData);
} }
} catch (Exception e) { } catch (Exception e) {
logger.warn(StringUtils.format("Object mapper read response : {}; {}; {};", execute, access, ids), e); logger.warn(StringUtils.format("Object mapper read response : {}; {}; {};", execute, access, request), e);
responseData.setSuccess(false); responseData.setSuccess(false);
responseData.setCode(COMMON_ERROR_CODE); responseData.setCode(COMMON_ERROR_CODE);
responseData.setMessage(e.getMessage()); responseData.setMessage(e.getMessage());
......
...@@ -48,5 +48,6 @@ public class ServerConfiguration { ...@@ -48,5 +48,6 @@ public class ServerConfiguration {
PersistentEntityInvoker invoker = new PersistentEntityInvoker(repositories); PersistentEntityInvoker invoker = new PersistentEntityInvoker(repositories);
return invoker; return invoker;
} }
} }
...@@ -4,7 +4,7 @@ package cn.quant.baa.pay.dict; ...@@ -4,7 +4,7 @@ package cn.quant.baa.pay.dict;
* Created by Administrator on 2021/8/24 0024. * Created by Administrator on 2021/8/24 0024.
*/ */
public enum MessageEnum { public enum MessageEnum {
EMPTY_REQ_DATA("2000000"), ILLEGAL_REQ_DATA("2000000"),
ILLEGAL_REQ_SUBJECT("2000000"), ILLEGAL_REQ_SUBJECT("2000000"),
ILLEGAL_REQ_MCH_ID("2000000"), ILLEGAL_REQ_MCH_ID("2000000"),
ILLEGAL_REQ_CHAN_ID("2000000"), ILLEGAL_REQ_CHAN_ID("2000000"),
......
...@@ -7,14 +7,11 @@ import cn.quant.baa.pay.jpa.entity.*; ...@@ -7,14 +7,11 @@ import cn.quant.baa.pay.jpa.entity.*;
import cn.quant.baa.pay.model.web.GoodsDetail; import cn.quant.baa.pay.model.web.GoodsDetail;
import cn.quant.baa.pay.model.web.PayRequestData; import cn.quant.baa.pay.model.web.PayRequestData;
import cn.quant.spring.util.DateUtils; import cn.quant.spring.util.DateUtils;
import org.hibernate.engine.jdbc.batch.spi.Batch;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date; import java.util.Date;
import static cn.quant.baa.pay.Constant.MINI_DATE;
import static cn.quant.baa.pay.Constant.MINI_LOCAL_DATE; import static cn.quant.baa.pay.Constant.MINI_LOCAL_DATE;
/** /**
...@@ -63,7 +60,7 @@ public class EntityBuilder { ...@@ -63,7 +60,7 @@ public class EntityBuilder {
return account; return account;
} }
public static PayHistoryEntity payHistory(AccountEntity account, PayHistoryIds ids, long historyId, PayRequestData data, AcquirerProperties profile public static PayHistoryEntity payHistory(AccountEntity account, PayHistoryIds ids, long historyId, PayRequestData data, AcquirerProperties properties
, TransactionSession session) { , TransactionSession session) {
BigDecimal discount = new BigDecimal(data.getDiscounts()); BigDecimal discount = new BigDecimal(data.getDiscounts());
...@@ -81,22 +78,17 @@ public class EntityBuilder { ...@@ -81,22 +78,17 @@ public class EntityBuilder {
entity.setCreditDebitFlag(CreditDebitFlag.C); entity.setCreditDebitFlag(CreditDebitFlag.C);
entity.setCurrencyCode(CurrencyCode.CNY); entity.setCurrencyCode(CurrencyCode.CNY);
entity.setCustomerGenFlag(true); entity.setCustomerGenFlag(true);
entity.setChannelId(properties.getMchChanId());
entity.setDiscAmount(discount); entity.setDiscAmount(discount);
entity.setGenFeeAmount(BigDecimal.ZERO); entity.setGenFeeAmount(BigDecimal.ZERO);
entity.setGoodsSigner(signer); entity.setGoodsSigner(signer);
entity.setShopName(data.getShopName()); entity.setShopName(data.getShopName());
entity.setMobilePhone(data.getPhoneNo()); entity.setMobilePhone(data.getPhoneNo());
entity.setNotifyUrl(data.getNotifyUrl());
entity.setOriginalTxnAmount(origAmt); entity.setOriginalTxnAmount(origAmt);
entity.setPayDueTime(LocalDateTime.now().plusMinutes(30));
entity.setPayAcctId(profile.getPayAcctId());
entity.setPayChanCode(profile.getPayChanCode());
entity.setPayAppId(profile.getPayAppId());
entity.setPayMethod(PayMethod.DRST); entity.setPayMethod(PayMethod.DRST);
entity.setPostCashAmount(cash); entity.setPostCashAmount(cash);
entity.setPostCreditAmount(credit); entity.setPostCreditAmount(credit);
entity.setPartitionKey(account.getPartitionKey()); entity.setPartitionKey(account.getPartitionKey());
entity.setRequestId(session.getRequestId());
entity.setRequestTime(session.getRequestTime()); entity.setRequestTime(session.getRequestTime());
entity.setShopName(data.getShopName()); entity.setShopName(data.getShopName());
entity.setStatementeFlag(true); entity.setStatementeFlag(true);
...@@ -139,7 +131,7 @@ public class EntityBuilder { ...@@ -139,7 +131,7 @@ public class EntityBuilder {
return entity; return entity;
} }
public static BatchCycleTriggerEntity payTrigger(Long triggerId, PayHistoryEntity history){ public static BatchCycleTriggerEntity payTrigger(Long triggerId, PayHistoryEntity history) {
Date now = DateUtils.now(); Date now = DateUtils.now();
BatchCycleTriggerEntity entity = new BatchCycleTriggerEntity(); BatchCycleTriggerEntity entity = new BatchCycleTriggerEntity();
entity.setAccountId(history.getAccountId()); entity.setAccountId(history.getAccountId());
......
...@@ -36,6 +36,9 @@ public class BatchCycleTriggerEntity extends PartitionEntity implements Serializ ...@@ -36,6 +36,9 @@ public class BatchCycleTriggerEntity extends PartitionEntity implements Serializ
@Column(name = "PAY_DUE_TIME", nullable = false) @Column(name = "PAY_DUE_TIME", nullable = false)
private LocalDateTime payDueTime; private LocalDateTime payDueTime;
@Column(name = "NOTIFY_URL", nullable = true, length = 1000)
private String notifyUrl;
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Column(name = "CHAN_NOTIFY_STATUS", nullable = false, length = 4) @Column(name = "CHAN_NOTIFY_STATUS", nullable = false, length = 4)
private StatusCode chanNotifyStatus; private StatusCode chanNotifyStatus;
...@@ -50,6 +53,9 @@ public class BatchCycleTriggerEntity extends PartitionEntity implements Serializ ...@@ -50,6 +53,9 @@ public class BatchCycleTriggerEntity extends PartitionEntity implements Serializ
@Column(name = "MCH_NOTIFY_TIME", nullable = true) @Column(name = "MCH_NOTIFY_TIME", nullable = true)
private Date mchNotifyTime; private Date mchNotifyTime;
@Column(name = "REQUEST_ID", nullable = true, length = 64)
private String requestId;
public long getTriggerId() { public long getTriggerId() {
return triggerId; return triggerId;
} }
...@@ -90,6 +96,14 @@ public class BatchCycleTriggerEntity extends PartitionEntity implements Serializ ...@@ -90,6 +96,14 @@ public class BatchCycleTriggerEntity extends PartitionEntity implements Serializ
this.payDueTime = payDueTime; this.payDueTime = payDueTime;
} }
public String getNotifyUrl() {
return notifyUrl;
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
public StatusCode getChanNotifyStatus() { public StatusCode getChanNotifyStatus() {
return chanNotifyStatus; return chanNotifyStatus;
} }
...@@ -122,6 +136,14 @@ public class BatchCycleTriggerEntity extends PartitionEntity implements Serializ ...@@ -122,6 +136,14 @@ public class BatchCycleTriggerEntity extends PartitionEntity implements Serializ
this.mchNotifyTime = mchNotifyTime; this.mchNotifyTime = mchNotifyTime;
} }
public String getRequestId() {
return requestId;
}
public void setRequestId(String requestId) {
this.requestId = requestId;
}
@Override @Override
public String getPersistentKey() { public String getPersistentKey() {
return StringUtils.toDelimitedString(CLASS_NAME, triggerId); return StringUtils.toDelimitedString(CLASS_NAME, triggerId);
...@@ -143,10 +165,12 @@ public class BatchCycleTriggerEntity extends PartitionEntity implements Serializ ...@@ -143,10 +165,12 @@ public class BatchCycleTriggerEntity extends PartitionEntity implements Serializ
sb.append(", targetId=").append(targetId); sb.append(", targetId=").append(targetId);
sb.append(", accountId=").append(accountId); sb.append(", accountId=").append(accountId);
sb.append(", payDueTime=").append(payDueTime); sb.append(", payDueTime=").append(payDueTime);
sb.append(", chanNotifyStatus='").append(chanNotifyStatus).append('\''); sb.append(", notifyUrl='").append(notifyUrl).append('\'');
sb.append(", chanNotifyStatus=").append(chanNotifyStatus);
sb.append(", chanNotifyTime=").append(chanNotifyTime); sb.append(", chanNotifyTime=").append(chanNotifyTime);
sb.append(", mchNotifyStatus='").append(mchNotifyStatus).append('\''); sb.append(", mchNotifyStatus=").append(mchNotifyStatus);
sb.append(", mchNotifyTime=").append(mchNotifyTime); sb.append(", mchNotifyTime=").append(mchNotifyTime);
sb.append(", requestId='").append(requestId).append('\'');
sb.append(',').append(super.toString()); sb.append(',').append(super.toString());
sb.append('}'); sb.append('}');
return sb.toString(); return sb.toString();
......
...@@ -33,14 +33,8 @@ public class PayHistoryEntity extends DescribablePartitionEntity implements Seri ...@@ -33,14 +33,8 @@ public class PayHistoryEntity extends DescribablePartitionEntity implements Seri
@Column(name = "ACCOUNT_ID", nullable = false, updatable = false) @Column(name = "ACCOUNT_ID", nullable = false, updatable = false)
private Long accountId; private Long accountId;
@Column(name = "PAY_APP_ID", nullable = false, updatable = false, length = 32) @Column(name = "CHANNEL_ID", nullable = false, updatable = false)
private String payAppId; private Long channelId;
@Column(name = "PAY_CHAN_CODE", nullable = false, updatable = false, length = 4)
private String payChanCode;
@Column(name = "PAY_ACCT_ID", nullable = false, updatable = false, length = 4)
private String payAcctId;
@Column(name = "SUBJECT", nullable = false, updatable = false, length = 128) @Column(name = "SUBJECT", nullable = false, updatable = false, length = 128)
private String subject; private String subject;
...@@ -125,9 +119,6 @@ public class PayHistoryEntity extends DescribablePartitionEntity implements Seri ...@@ -125,9 +119,6 @@ public class PayHistoryEntity extends DescribablePartitionEntity implements Seri
@Column(name = "ADDRESS", nullable = true, length = 500) @Column(name = "ADDRESS", nullable = true, length = 500)
private String address; private String address;
@Column(name = "NOTIFY_URL", nullable = true, length = 1000)
private String notifyUrl;
@Column(name = "ATTACH_TEXT", nullable = true, length = 512) @Column(name = "ATTACH_TEXT", nullable = true, length = 512)
private String attachText; private String attachText;
...@@ -155,28 +146,12 @@ public class PayHistoryEntity extends DescribablePartitionEntity implements Seri ...@@ -155,28 +146,12 @@ public class PayHistoryEntity extends DescribablePartitionEntity implements Seri
this.accountId = accountId; this.accountId = accountId;
} }
public String getPayAppId() { public Long getChannelId() {
return payAppId; return channelId;
}
public void setPayAppId(String payAppId) {
this.payAppId = payAppId;
}
public String getPayChanCode() {
return payChanCode;
} }
public void setPayChanCode(String payChanCode) { public void setChannelId(Long channelId) {
this.payChanCode = payChanCode; this.channelId = channelId;
}
public String getPayAcctId() {
return payAcctId;
}
public void setPayAcctId(String payAcctId) {
this.payAcctId = payAcctId;
} }
public String getSubject() { public String getSubject() {
...@@ -387,14 +362,6 @@ public class PayHistoryEntity extends DescribablePartitionEntity implements Seri ...@@ -387,14 +362,6 @@ public class PayHistoryEntity extends DescribablePartitionEntity implements Seri
this.address = address; this.address = address;
} }
public String getNotifyUrl() {
return notifyUrl;
}
public void setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
}
public String getAttachText() { public String getAttachText() {
return attachText; return attachText;
} }
...@@ -422,9 +389,7 @@ public class PayHistoryEntity extends DescribablePartitionEntity implements Seri ...@@ -422,9 +389,7 @@ public class PayHistoryEntity extends DescribablePartitionEntity implements Seri
sb.append("ids=").append(ids); sb.append("ids=").append(ids);
sb.append(", transactionId=").append(transactionId); sb.append(", transactionId=").append(transactionId);
sb.append(", accountId=").append(accountId); sb.append(", accountId=").append(accountId);
sb.append(", payAppId='").append(payAppId).append('\''); sb.append(", channelId=").append(channelId);
sb.append(", payChanCode='").append(payChanCode).append('\'');
sb.append(", payAcctId='").append(payAcctId).append('\'');
sb.append(", subject='").append(subject).append('\''); sb.append(", subject='").append(subject).append('\'');
sb.append(", statusCode=").append(statusCode); sb.append(", statusCode=").append(statusCode);
sb.append(", currencyCode=").append(currencyCode); sb.append(", currencyCode=").append(currencyCode);
...@@ -451,7 +416,6 @@ public class PayHistoryEntity extends DescribablePartitionEntity implements Seri ...@@ -451,7 +416,6 @@ public class PayHistoryEntity extends DescribablePartitionEntity implements Seri
sb.append(", mobilePhone='").append(mobilePhone).append('\''); sb.append(", mobilePhone='").append(mobilePhone).append('\'');
sb.append(", goodsSigner='").append(goodsSigner).append('\''); sb.append(", goodsSigner='").append(goodsSigner).append('\'');
sb.append(", address='").append(address).append('\''); sb.append(", address='").append(address).append('\'');
sb.append(", notifyUrl='").append(notifyUrl).append('\'');
sb.append(", attachText='").append(attachText).append('\''); sb.append(", attachText='").append(attachText).append('\'');
sb.append(',').append(super.toString()); sb.append(',').append(super.toString());
sb.append('}'); sb.append('}');
......
package cn.quant.baa.pay.model.web;
/**
* Created by Administrator on 2021/9/24 0024.
*/
public interface ChannelRequestData {
String getChanId();
}
...@@ -9,7 +9,7 @@ import java.util.Arrays; ...@@ -9,7 +9,7 @@ import java.util.Arrays;
/** /**
* Created by Administrator on 2021/8/24 0024. * Created by Administrator on 2021/8/24 0024.
*/ */
public class PayRequestData implements Serializable{ public class PayRequestData implements ChannelRequestData, Serializable{
private static final long serialVersionUID = -8274612481658761761L; private static final long serialVersionUID = -8274612481658761761L;
...@@ -25,10 +25,6 @@ public class PayRequestData implements Serializable{ ...@@ -25,10 +25,6 @@ public class PayRequestData implements Serializable{
@NotNull(message = "ILLEGAL_REQ_MCH_ID") @NotNull(message = "ILLEGAL_REQ_MCH_ID")
private String mchId; private String mchId;
/**
* 支付通道ID
*/
@NotNull(message = "ILLEGAL_REQ_CHAN_ID")
private String chanId; private String chanId;
/** /**
......
package cn.quant.baa.pay.model.web;
/**
* Created by Administrator on 2021/9/24 0024.
*/
public class PayResponseData {
private String orderNo;
private String prepay;
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public String getPrepay() {
return prepay;
}
public void setPrepay(String prepay) {
this.prepay = prepay;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("PayResponseData{");
sb.append("orderNo='").append(orderNo).append('\'');
sb.append(", prepay='").append(prepay).append('\'');
sb.append('}');
return sb.toString();
}
}
EMPTY_REQ_DATA=Illegal request data. ILLEGAL_REQ_DATA=Illegal request data.
ILLEGAL_REQ_MCH_ID=Illegal merchant id - {0}. ILLEGAL_REQ_MCH_ID=Illegal merchant id - {0}.
ILLEGAL_REQ_CHAN_ID=Illegal pay channel id - {0}. ILLEGAL_REQ_CHAN_ID=Illegal pay channel id - {0}.
ILLEGAL_REQ_BUYER_ID=Illegal payer id - {0}. ILLEGAL_REQ_BUYER_ID=Illegal payer id - {0}.
......
EMPTY_REQ_DATA=Illegal request data. ILLEGAL_REQ_DATA=Illegal request data.
ILLEGAL_REQ_MCH_ID=Illegal merchant id - {0}. ILLEGAL_REQ_MCH_ID=Illegal merchant id - {0}.
ILLEGAL_REQ_CHAN_ID=Illegal pay channel id - {0}. ILLEGAL_REQ_CHAN_ID=Illegal pay channel id - {0}.
ILLEGAL_REQ_BUYER_ID=Illegal payer id - {0}. ILLEGAL_REQ_BUYER_ID=Illegal payer id - {0}.
......
EMPTY_REQ_DATA=\u8BF7\u6C42\u6570\u636E\u683C\u5F0F\u9519\u8BEF ILLEGAL_REQ_DATA=\u8BF7\u6C42\u6570\u636E"data"\u683C\u5F0F\u9519\u8BEF
ILLEGAL_REQ_SUBJECT={0}-\u8BA2\u5355\u6807\u9898\u9519\u8BEF ILLEGAL_REQ_SUBJECT={0}-\u8BA2\u5355\u6807\u9898\u9519\u8BEF
ILLEGAL_REQ_MCH_ID={0}-\u5546\u6237ID\u9519\u8BEF ILLEGAL_REQ_MCH_ID={0}-\u5546\u6237ID\u9519\u8BEF
ILLEGAL_REQ_CHAN_ID={0}-\u652F\u4ED8\u901A\u9053ID\u9519\u8BEF ILLEGAL_REQ_CHAN_ID={0}-\u652F\u4ED8\u901A\u9053ID\u9519\u8BEF
......
...@@ -2,6 +2,7 @@ package cn.quant.baa.pay; ...@@ -2,6 +2,7 @@ package cn.quant.baa.pay;
import cn.quant.spring.util.IdentitySequencer; import cn.quant.spring.util.IdentitySequencer;
import cn.quant.spring.util.ServerUtils; import cn.quant.spring.util.ServerUtils;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
...@@ -21,10 +22,11 @@ import java.time.format.DateTimeFormatter; ...@@ -21,10 +22,11 @@ import java.time.format.DateTimeFormatter;
/** /**
* <p><b>Application VM Option:</b><br/> * <p><b>Application VM Option:</b><br/>
* <code>--spring.config.file=${project.build.directory}/target/config/application-dev.properties </code><br/> * <code>--spring.config.file=${project.build.directory}/target/config/application-dev.properties </code><br/>
* <code>-Dlogging.config=${project.build.directory}/target/config/logback-spring.xml</code></p> * <code>-Dlogging.config=${project.build.directory}/target/config/logback-pro.xml</code></p>
* <p><b>Enable Dubbo Annotation: </b><br/> * <p><b>Enable Dubbo Annotation: </b><br/>
* <code>@org.springframework.context.annotation.ImportResource(locations = {"classpath:application-dubbo.xml"})</code></p> * <code>@org.springframework.context.annotation.ImportResource(locations = {"classpath:application-dubbo.xml"})</code></p>
*/ */
@EnableApolloConfig
@ComponentScan @ComponentScan
@SpringBootApplication @SpringBootApplication
@EnableAutoConfiguration @EnableAutoConfiguration
......
package cn.quant.baa.pay.rest; package cn.quant.baa.pay.rest;
import cn.quant.baa.pay.acquirer.ChannelResponse;
import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.model.web.PayResponseData;
import cn.quant.spring.http.HttpResponseData;
import cn.quant.spring.rest.AbstractController; import cn.quant.spring.rest.AbstractController;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.ZonedDateTimeSerializer;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.Map;
/** /**
* Created by Administrator on 2021/8/28 0028. * Created by Administrator on 2021/8/28 0028.
*/ */
public abstract class BusinessController extends AbstractController { public abstract class BusinessController extends AbstractController {
private final static ObjectMapper objectMapper = new ObjectMapper();
public BusinessController() {
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
simpleModule.addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE);
simpleModule.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
simpleModule.addSerializer(LocalDate.class, LocalDateSerializer.INSTANCE);
simpleModule.addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE);
simpleModule.addSerializer(ZonedDateTime.class, ZonedDateTimeSerializer.INSTANCE);
objectMapper.registerModule(simpleModule);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
public Map deserialize(String value) throws IOException {
return objectMapper.readValue(value.getBytes(), Map.class);
}
public String serialize(HttpResponseData value) throws JsonProcessingException {
return objectMapper.writeValueAsString(value);
}
public HttpResponseData response(ChannelResponse response) {
TransactionSession session = TransactionSession.session();
PayResponseData data = new PayResponseData();
data.setOrderNo(response.getOrderNo());
data.setPrepay(response.getNotification());
HttpResponseData responseData = new HttpResponseData(data);
responseData.setSuccess(response.getSuccess());
responseData.setMessage(response.getMessage());
responseData.setStatus(response.getCode());
responseData.setRequestId(session.getRequestId());
return responseData;
}
} }
...@@ -45,7 +45,7 @@ public class MerchantController extends AbstractController { ...@@ -45,7 +45,7 @@ public class MerchantController extends AbstractController {
MerchantChannelRequestData data = request.getData(); MerchantChannelRequestData data = request.getData();
if (data == null) { if (data == null) {
AssertUtils.throwMessage(EMPTY_REQ_DATA); AssertUtils.throwMessage(ILLEGAL_REQ_DATA);
} }
Map<String, MerchantChannelResponseData> channels = merchantStorageService.getChannels(data); Map<String, MerchantChannelResponseData> channels = merchantStorageService.getChannels(data);
...@@ -63,7 +63,7 @@ public class MerchantController extends AbstractController { ...@@ -63,7 +63,7 @@ public class MerchantController extends AbstractController {
MerchantChannelRequestData data = request.getData(); MerchantChannelRequestData data = request.getData();
if (data == null) { if (data == null) {
AssertUtils.throwMessage(EMPTY_REQ_DATA); AssertUtils.throwMessage(ILLEGAL_REQ_DATA);
} }
MerchantAcquirerProperties channel = merchantStorageService.getChannel(Long.parseLong(data.getChanId())); MerchantAcquirerProperties channel = merchantStorageService.getChannel(Long.parseLong(data.getChanId()));
......
//package cn.quant.baa.pay.rest; package cn.quant.baa.pay.rest;
//
//import cn.quant.baa.pay.annotation.BusinessMapping; import cn.quant.baa.pay.acquirer.ChannelResponse;
//import cn.quant.baa.pay.component.Sequencer; import cn.quant.baa.pay.annotation.BusinessMapping;
//import cn.quant.baa.pay.context.TransactionSession; import cn.quant.baa.pay.component.Sequencer;
//import cn.quant.baa.pay.model.BusinessRequest; import cn.quant.baa.pay.model.BusinessRequest;
//import cn.quant.baa.pay.model.web.CheckPayRequestData; import cn.quant.baa.pay.model.web.CheckPayRequestData;
//import cn.quant.baa.pay.model.web.CheckRefundRequestData; import cn.quant.baa.pay.model.web.CheckRefundRequestData;
//import cn.quant.baa.pay.model.web.PayRequestData; import cn.quant.baa.pay.model.web.PayRequestData;
//import cn.quant.baa.pay.service.TransactionService; import cn.quant.baa.pay.service.TransactionService;
//import cn.quant.spring.context.ServerApplicationContext; import cn.quant.spring.context.ServerApplicationContext;
//import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature;
//import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper;
//import com.fasterxml.jackson.databind.JsonNode; import org.springframework.beans.factory.annotation.Autowired;
//import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.stereotype.Controller;
//import com.fasterxml.jackson.databind.PropertyNamingStrategy; import org.springframework.ui.Model;
//import com.fasterxml.jackson.databind.json.JsonMapper; import org.springframework.web.bind.annotation.*;
//import com.fasterxml.jackson.databind.node.ObjectNode;
//import org.json.JSONObject; import javax.servlet.http.HttpServletRequest;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Controller; /**
//import org.springframework.ui.Model; * Created with IntelliJ IDEA.
//import org.springframework.web.bind.annotation.*; * Author: Lipeng Liu
// * Date: 2021/9/9
//import javax.servlet.http.HttpServletRequest; * Time: 上午9:51
//import java.util.HashMap; * Description: No Description
//import java.util.Map; */
// @Controller
///** //@RestController
// * Created with IntelliJ IDEA. @RequestMapping("pay")
// * Author: Lipeng Liu public class PayTestController {
// * Date: 2021/9/9
// * Time: 上午9:51 ObjectMapper objectMapper = new ObjectMapper();
// * Description: No Description
// */ @Autowired
//@Controller private TransactionService transactionService;
////@RestController
//@RequestMapping("pay") @Autowired
//public class PayTestController { private ServerApplicationContext serverApplicationContext;
//
// ObjectMapper objectMapper = new ObjectMapper(); @Autowired
// private Sequencer sequencer;
// @Autowired
// private TransactionService transactionService; @GetMapping("")
// public String getPay(Model model) {
// @Autowired return "pay/index";
// private ServerApplicationContext serverApplicationContext; }
//
// @Autowired @RequestMapping("h5")
// private Sequencer sequencer; public String getH5(Model model) {
// return "pay/h5";
// @GetMapping("") }
// public String getPay(Model model) {
// return "pay/index"; @RequestMapping("checkPay")
// } public String checkPay(CheckPayRequestData data, Model model, HttpServletRequest servletRequest) throws Exception {
// String res = "";
// @RequestMapping("h5") if (servletRequest.getMethod().equals("POST")) {
// public String getH5(Model model) { res = transactionService.checkPay(data).toString();
// return "pay/h5"; }
// } model.addAttribute("res", res);
// return "pay/checkPay";
// @RequestMapping("checkPay") }
// public String checkPay(CheckPayRequestData data, Model model, HttpServletRequest servletRequest) {
// String res = ""; @RequestMapping("checkRefund")
// if (servletRequest.getMethod().equals("POST")) { public String checkRefund(CheckRefundRequestData data, Model model, HttpServletRequest servletRequest) throws Exception {
// res = transactionService.checkPay(data).toString();
// } String res = "";
// model.addAttribute("res", res); if (servletRequest.getMethod().equals("POST")) {
// return "pay/checkPay"; res = transactionService.checkRefund(data).toString();
// } }
// model.addAttribute("res", res);
// @RequestMapping("checkRefund") return "pay/checkRefund";
// public String checkRefund(CheckRefundRequestData data, Model model, HttpServletRequest servletRequest) { }
//
// String res = "";
// if (servletRequest.getMethod().equals("POST")) {
// res = transactionService.checkRefund(data).toString();
// }
// model.addAttribute("res", res);
// return "pay/checkRefund";
// }
//
//
// @PostMapping("goPay") // @PostMapping("goPay")
// @BusinessMapping(session = 1) // @BusinessMapping(session = 1)
// @ResponseBody // @ResponseBody
// public JsonNode goPay(@RequestBody(required = false) BusinessRequest<PayRequestData> requestData) { // public ChannelResponse goPay(@RequestBody(required = false) BusinessRequest<PayRequestData> requestData) throws Exception {
// PayRequestData data = requestData.getData(); // PayRequestData data = requestData.getData();
// String str = "{\"subject\":\"测试订单1\",\"mchId\":\"wx2f44c7fe7b08458d\",\"chanId\":\"75772285618946307\",\"outTradeNo\":\"11111111223\",\"originalAmount\":\"110.00\",\"amount\":0.01,\"discounts\":\"10.00\",\"notifyUrl\":\"http://127.0.0.1:8080/notifyUrl\",\"buyerId\":\"777777\",\"attach\":\"AAAA-BBBB-1111-2222\",\"creditAmount\":\"10.00\",\"cashAmount\":\"10\",\"goodsDetail\":[{\"goodsNo\":\"123123\",\"goodsId\":\"11111\",\"goodsName\":\"商品1\",\"quantity\":2,\"price\":\"10.00\",\"discounts\":\"2.5\",\"amount\":\"17.5\",\"attach\":\"---\",\"creditAmount\":123,\"cashAmount\":123}]}"; // String str = "{\"subject\":\"测试订单1\",\"mchId\":\"wx2f44c7fe7b08458d\",\"chanId\":\"75772285618946307\",\"outTradeNo\":\"11111111223\",\"originalAmount\":\"110.00\",\"amount\":0.01,\"discounts\":\"10.00\",\"notifyUrl\":\"http://127.0.0.1:8080/notifyUrl\",\"buyerId\":\"777777\",\"attach\":\"AAAA-BBBB-1111-2222\",\"creditAmount\":\"10.00\",\"cashAmount\":\"10\",\"goodsDetail\":[{\"goodsNo\":\"123123\",\"goodsId\":\"11111\",\"goodsName\":\"商品1\",\"quantity\":2,\"price\":\"10.00\",\"discounts\":\"2.5\",\"amount\":\"17.5\",\"attach\":\"---\",\"creditAmount\":123,\"cashAmount\":123}]}";
// try {
// objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// PayRequestData payRequestData = objectMapper.readValue(str, PayRequestData.class);
// String[] temp = data.getChanId().split("_");
// payRequestData.setChanId(temp[0]);
// payRequestData.setMchId(temp[1]);
// payRequestData.setOutTradeNo(data.getOutTradeNo());
// payRequestData.setSubject(data.getSubject());
// payRequestData.setAmount(data.getAmount());
// payRequestData.setNotifyUrl("http://127.0.0.1:8080/notifyUrl");
// JsonNode res = transactionService.pay(payRequestData);
// return res;
// } catch (JsonProcessingException e) {
// e.printStackTrace();
// }
// return objectMapper.createObjectNode();
// }
// //
//} // objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
\ No newline at end of file // PayRequestData payRequestData = objectMapper.readValue(str, PayRequestData.class);
// String[] temp = data.getChanId().split("_");
// payRequestData.setChanId(temp[0]);
// payRequestData.setMchId(temp[1]);
// payRequestData.setOutTradeNo(data.getOutTradeNo());
// payRequestData.setSubject(data.getSubject());
// payRequestData.setAmount(data.getAmount());
// payRequestData.setNotifyUrl("http://127.0.0.1:8080/notifyUrl");
// ChannelResponse response = transactionService.pay(payRequestData);
// return response;
//
// }
}
\ No newline at end of file
package cn.quant.baa.pay.rest; package cn.quant.baa.pay.rest;
import cn.quant.baa.pay.acquirer.AcquirerProperties;
import cn.quant.baa.pay.acquirer.AcquirerPropertiesSource;
import cn.quant.baa.pay.acquirer.ChannelResponse; import cn.quant.baa.pay.acquirer.ChannelResponse;
import cn.quant.baa.pay.annotation.BusinessMapping; import cn.quant.baa.pay.annotation.BusinessMapping;
import cn.quant.baa.pay.model.BusinessRequest; import cn.quant.baa.pay.model.BusinessRequest;
import cn.quant.baa.pay.model.web.*; import cn.quant.baa.pay.model.web.*;
import cn.quant.baa.pay.service.TransactionService; import cn.quant.baa.pay.service.TransactionService;
import cn.quant.baa.pay.util.AssertUtils;
import cn.quant.spring.http.HttpResponseData; import cn.quant.spring.http.HttpResponseData;
import cn.quant.spring.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import static cn.quant.baa.pay.Constant.PAY_DUE_TIME;
import static cn.quant.baa.pay.Constant.REDIS_NAMESPACE_PAY;
import static cn.quant.baa.pay.dict.MessageEnum.*;
/** /**
* Created by Administrator on 2021/8/24 0024. * Created by Administrator on 2021/8/24 0024.
*/ */
...@@ -20,22 +29,52 @@ public class TransactionController extends BusinessController { ...@@ -20,22 +29,52 @@ public class TransactionController extends BusinessController {
@Autowired @Autowired
private TransactionService transactionService; private TransactionService transactionService;
@Autowired
private AcquirerPropertiesSource acquirerPropertiesSource;
@Autowired
private StringRedisTemplate stringRedisTemplate;
public AcquirerProperties check(ChannelRequestData data) {
if (data == null) {
AssertUtils.throwMessage(ILLEGAL_REQ_DATA);
}
String chanId = data.getChanId();
if (chanId == null) {
AssertUtils.throwMessage(ILLEGAL_REQ_CHAN_ID, chanId);
}
AcquirerProperties properties = acquirerPropertiesSource.get(Long.valueOf(chanId));
if (properties == null) {
AssertUtils.throwMessage(ACQUIRER_NOSUCH, chanId);
}
return properties;
}
@ResponseBody @ResponseBody
@BusinessMapping(session = 1) @BusinessMapping(session = 1)
@PostMapping("/pay") @PostMapping("/pay")
public ResponseEntity pay(@RequestBody BusinessRequest<PayRequestData> request) { public ResponseEntity pay(@RequestBody BusinessRequest<PayRequestData> request) throws Exception {
PayRequestData requestData = request.getData(); PayRequestData requestData = request.getData();
ChannelResponse responseData = null; AcquirerProperties properties = check(requestData);
try { String institutionId = properties.getInstitutionId();
responseData = transactionService.pay(requestData); String productId = properties.getProductId();
} catch (Exception e) { String buyerId = requestData.getBuyerId();
e.printStackTrace(); String outTradeNo = requestData.getOutTradeNo();
String redisKey = StringUtils.toDelimitedString(REDIS_NAMESPACE_PAY, institutionId, productId, buyerId, outTradeNo);
String redisValue = stringRedisTemplate.opsForValue().get(redisKey);
if (redisValue != null) {
return ResponseEntity.ok(deserialize(redisValue));
} }
ChannelResponse channelResponse = transactionService.pay(properties, requestData);
ResponseEntity<HttpResponseData> responseEntity = succeed(responseData); HttpResponseData response = response(channelResponse);
if (channelResponse.getSuccess()) {
return responseEntity; stringRedisTemplate.opsForValue().set(redisKey, serialize(response), PAY_DUE_TIME);
}
return ResponseEntity.ok(response);
} }
@ResponseBody @ResponseBody
......
package cn.quant.baa.pay.service; package cn.quant.baa.pay.service;
import cn.quant.baa.pay.acquirer.AcquirerPropertiesSource;
import cn.quant.baa.pay.acquirer.AcquirerProperties; import cn.quant.baa.pay.acquirer.AcquirerProperties;
import cn.quant.baa.pay.acquirer.ChannelResponse; import cn.quant.baa.pay.acquirer.ChannelResponse;
import cn.quant.baa.pay.acquirer.MerchantAcquirer; import cn.quant.baa.pay.acquirer.MerchantAcquirer;
import cn.quant.baa.pay.config.DictionaryViewer;
import cn.quant.baa.pay.context.TransactionSession; import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.jpa.EntityBuilder; import cn.quant.baa.pay.jpa.EntityBuilder;
import cn.quant.baa.pay.jpa.entity.*; import cn.quant.baa.pay.jpa.entity.*;
import cn.quant.baa.pay.model.web.*; import cn.quant.baa.pay.model.web.*;
import cn.quant.baa.pay.util.AssertUtils; import cn.quant.baa.pay.util.AssertUtils;
import cn.quant.spring.util.StringUtils;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.ZonedDateTimeSerializer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -17,10 +26,16 @@ import org.springframework.stereotype.Service; ...@@ -17,10 +26,16 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import static cn.quant.baa.pay.dict.MessageEnum.*; import static cn.quant.baa.pay.Constant.PAY_DUE_TIME;
import static cn.quant.baa.pay.dict.MessageEnum.ACQUIRER_NOMATCH;
import static cn.quant.baa.pay.dict.MessageEnum.EXIST_ORDER;
/** /**
* Created by Administrator on 2021/8/24 0024. * Created by Administrator on 2021/8/24 0024.
...@@ -30,15 +45,10 @@ public class TransactionService extends BusinessService { ...@@ -30,15 +45,10 @@ public class TransactionService extends BusinessService {
private static final Logger logger = LoggerFactory.getLogger(TransactionService.class); private static final Logger logger = LoggerFactory.getLogger(TransactionService.class);
@Autowired
private AcquirerPropertiesSource acquirerPropertiesSource;
@Autowired @Autowired
private MerchantAcquirer acquirer; private MerchantAcquirer acquirer;
@Autowired
private DictionaryViewer dictionaryViewer;
@Transactional(propagation = Propagation.NOT_SUPPORTED) @Transactional(propagation = Propagation.NOT_SUPPORTED)
public void check(PayHistoryIds ids, TransactionSession session) { public void check(PayHistoryIds ids, TransactionSession session) {
PayHistoryEntity historyEntity = session.findOne(PayHistoryEntity.class, ids); PayHistoryEntity historyEntity = session.findOne(PayHistoryEntity.class, ids);
...@@ -48,22 +58,18 @@ public class TransactionService extends BusinessService { ...@@ -48,22 +58,18 @@ public class TransactionService extends BusinessService {
} }
@Transactional(propagation = Propagation.REQUIRES_NEW) @Transactional(propagation = Propagation.REQUIRES_NEW)
public ChannelResponse pay(PayRequestData data) throws Exception { public ChannelResponse pay(AcquirerProperties properties, PayRequestData data) throws Exception {
validate(data); validate(data);
String chanId = data.getChanId();
AcquirerProperties profile = acquirerPropertiesSource.get(Long.valueOf(chanId));
if (profile == null) {
AssertUtils.throwMessage(ACQUIRER_NOSUCH, chanId);
}
String institutionId = profile.getInstitutionId();
String productId = profile.getProductId();
String buyerId = data.getBuyerId();
TransactionSession session = TransactionSession.session(); TransactionSession session = TransactionSession.session();
Long chanId = properties.getMchChanId();
String institutionId = properties.getInstitutionId();
String productId = properties.getProductId();
String buyerId = data.getBuyerId();
String outTradeNo = data.getOutTradeNo(); String outTradeNo = data.getOutTradeNo();
PayHistoryIds ids = new PayHistoryIds(); PayHistoryIds ids = new PayHistoryIds();
ids.setInstitutionId(institutionId); ids.setInstitutionId(institutionId);
ids.setProductId(productId); ids.setProductId(productId);
...@@ -73,7 +79,7 @@ public class TransactionService extends BusinessService { ...@@ -73,7 +79,7 @@ public class TransactionService extends BusinessService {
prepare(institutionId, productId, buyerId, session); prepare(institutionId, productId, buyerId, session);
String mchId = data.getMchId(); String mchId = data.getMchId();
if (!mchId.equals(profile.getPayAppId())) { if (!mchId.equals(properties.getPayAppId())) {
AssertUtils.throwMessage(ACQUIRER_NOMATCH, chanId, mchId); AssertUtils.throwMessage(ACQUIRER_NOMATCH, chanId, mchId);
} }
...@@ -90,24 +96,23 @@ public class TransactionService extends BusinessService { ...@@ -90,24 +96,23 @@ public class TransactionService extends BusinessService {
details.add(detailEntity); details.add(detailEntity);
} }
PayHistoryEntity history = EntityBuilder.payHistory(account, ids, historyId, data, profile, session); PayHistoryEntity history = EntityBuilder.payHistory(account, ids, historyId, data, properties, session);
long triggerId = session.nextId();
ChannelResponse responseData = acquirer.pay(data, history); ChannelResponse responseData = acquirer.pay(data, history);
if(responseData.getSuccess()){ if (responseData.getSuccess()) {
EntityBuilder.nextTxnNo(account, history); EntityBuilder.nextTxnNo(account, history);
BatchCycleTriggerEntity trigger = EntityBuilder.payTrigger(triggerId, history); history.setPayDueTime(LocalDateTime.now().plus(PAY_DUE_TIME));
session.pushEntity(history); history.setRequestId(responseData.getRequestId());
session.pushEntity(trigger); history.setDescText(responseData.getNotification());
session.pushEntity(details);
session.commit(); BatchCycleTriggerEntity trigger = EntityBuilder.payTrigger(session.nextId(), history);
trigger.setRequestId(session.getRequestId());
session.addProperty(PayHistoryEntity.class, history); trigger.setNotifyUrl(data.getNotifyUrl());
session.addProperty(PayGoodsDetailEntity.class, details);
session.pushEntity(history, trigger);
session.pushEntity(details);
session.commit();
} }
return responseData; return responseData;
......
app.id=baa-pay-server
apollo.meta=http://apollo-dev.quantgroups.com
\ No newline at end of file
...@@ -7,10 +7,10 @@ spring.devtools.restart.enabled=true ...@@ -7,10 +7,10 @@ spring.devtools.restart.enabled=true
spring.devtools.livereload.enabled=true spring.devtools.livereload.enabled=true
#Server #Server
server.port=8080 #server.port=8080
server.servlet.context-path=/ server.servlet.context-path=/
#quant #quant
quant.server.number=1 #quant.server.number=1
quant.server.sequencer.operator=TWEPOCH_PLUS quant.server.sequencer.operator=TWEPOCH_PLUS
quant.server.sequencer.sequence-bits=8 quant.server.sequencer.sequence-bits=8
#Database #Database
......
...@@ -21,4 +21,4 @@ spring: ...@@ -21,4 +21,4 @@ spring:
cloud: cloud:
task: task:
initialize: initialize:
enable: false enable: false
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<appender name="ROLLINGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logging.dir}/${project.name}/${project.name}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logging.dir}/${project.name}/${project.name}.%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<maxHistory>90</maxHistory>
<maxFileSize>512MB</maxFileSize>
<totalSizeCap>10GB</totalSizeCap>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<charset>utf-8</charset>
<Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}][%p][%t|%logger{1.}|%M] - %msg %ex{full}%n</Pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %ex{full}%n</pattern>-->
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}][%p][%t|%logger{1.}|%M] - %msg %ex{full}%n</pattern>
</encoder>
</appender>
<logger name="cn.quant.baa.pay" level="DEBUG"/>
<logger name="javax.activation" level="ERROR"/>
<logger name="org.quartz.core" level="ERROR"/>
<logger name="org.quartz.simpl" level="ERROR"/>
<logger name="io.lettuce.core" level="ERROR"/>
<logger name="io.netty" level="ERROR"/>
<logger name="com.zaxxer.hikari.pool" level="ERROR"/>
<logger name="com.alibaba.dubbo.common.extension" level="ERROR"/>
<logger name="sun.net.www.protocol.http" level="ERROR"/>
<logger name="com.ctrip.framework.apollo.internals" level="ERROR"/>
<logger name="org.apache.zookeeper" level="ERROR"/>
<logger name="org.apache.curator" level="ERROR"/>
<logger name="org.apache.coyote" level="ERROR"/>
<logger name="org.apache.catalina" level="ERROR"/>
<logger name="org.hibernate.hql" level="ERROR"/>
<logger name="org.hibernate.loader" level="ERROR"/>
<logger name="org.hibernate.type" level="ERROR"/>
<logger name="org.hibernate.persister" level="ERROR"/>
<logger name="org.hibernate.cfg" level="ERROR"/>
<logger name="org.hibernate.mapping" level="ERROR"/>
<logger name="org.hibernate.jpa.event" level="ERROR"/>
<logger name="org.hibernate.validator.internal" level="ERROR"/>
<logger name="org.hibernate.engine.internal" level="ERROR"/>
<logger name="org.hibernate.boot.model" level="ERROR"/>
<logger name="org.hibernate.boot.internal" level="ERROR"/>
<logger name="org.apache.tomcat.util" level="ERROR"/>
<logger name="org.springframework.orm" level="ERROR"/>
<logger name="org.springframework.jmx" level="ERROR"/>
<logger name="org.springframework.jndi" level="ERROR"/>
<logger name="org.springframework.aop" level="ERROR"/>
<logger name="org.springframework.web" level="ERROR"/>
<logger name="org.springframework.context" level="ERROR"/>
<logger name="org.springframework.core" level="ERROR"/>
<logger name="org.springframework.beans" level="ERROR"/>
<logger name="org.springframework.boot.web" level="ERROR"/>
<logger name="org.springframework.boot.actuate" level="ERROR"/>
<logger name="org.springframework.boot.context" level="ERROR"/>
<logger name="org.springframework.boot.autoconfigure.logging" level="ERROR"/>
<logger name="org.springframework.data.redis" level="ERROR"/>
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE"/>
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="ERROR"/>
<logger name="org.hibernate.engine.QueryParameters" level="ERROR"/>
<logger name="org.hibernate.SQL" level="ERROR" />
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
<appender-ref ref="ROLLINGFILE"/>
</root>
</configuration>
\ No newline at end of file
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
</contextListener> </contextListener>
<appender name="ROLLINGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="ROLLINGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logging.dir}/${project.name}/${project.name}.log</file> <file>/home/quant_group/logs/${project.name}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logging.dir}/${project.name}/${project.name}.%d{yyyy-MM-dd}-%i.log</fileNamePattern> <fileNamePattern>/home/quant_group/logs/${project.name}.%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<maxHistory>90</maxHistory> <maxHistory>90</maxHistory>
<maxFileSize>512MB</maxFileSize> <maxFileSize>512MB</maxFileSize>
<totalSizeCap>10GB</totalSizeCap> <totalSizeCap>10GB</totalSizeCap>
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
<logger name="org.hibernate.engine.QueryParameters" level="ERROR"/> <logger name="org.hibernate.engine.QueryParameters" level="ERROR"/>
<logger name="org.hibernate.SQL" level="ERROR" /> <logger name="org.hibernate.SQL" level="ERROR" />
<root level="${logging.level}"> <root level="WARN">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
<appender-ref ref="ROLLINGFILE"/> <appender-ref ref="ROLLINGFILE"/>
</root> </root>
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment