Commit 3aac1d6d authored by Administrator's avatar Administrator

创建项目

parent ee1659fd
...@@ -22,6 +22,11 @@ ...@@ -22,6 +22,11 @@
<version>1.0.0</version> <version>1.0.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!--javax--> <!--javax-->
<dependency> <dependency>
<groupId>javax.inject</groupId> <groupId>javax.inject</groupId>
......
package cn.quant.baa.pay.aspect; package cn.quant.baa.pay.aspect;
import cn.quant.baa.pay.model.BusinessRequest;
import cn.quant.baa.pay.annotation.BusinessMapping; import cn.quant.baa.pay.annotation.BusinessMapping;
import cn.quant.baa.pay.component.Sequencer;
import cn.quant.baa.pay.context.TransactionSession; import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.spring.IllegalArgException; import cn.quant.baa.pay.model.BusinessRequest;
import cn.quant.spring.context.ServerApplicationContext; import cn.quant.spring.context.ServerApplicationContext;
import cn.quant.spring.util.StringUtils; import cn.quant.spring.util.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
...@@ -26,12 +26,17 @@ import java.lang.reflect.Method; ...@@ -26,12 +26,17 @@ import java.lang.reflect.Method;
@Component @Component
public class BusinessMappingAspect { public class BusinessMappingAspect {
@Autowired
private Sequencer sequencer;
@Autowired @Autowired
private ServerApplicationContext serverApplicationContext; private ServerApplicationContext serverApplicationContext;
public void session(Object arg) { public void session(Object arg) {
if (BusinessRequest.class.isInstance(arg)) { if (BusinessRequest.class.isInstance(arg)) {
TransactionSession.newInstance((BusinessRequest) arg, serverApplicationContext); TransactionSession.newInstance((BusinessRequest) arg, serverApplicationContext, sequencer);
} }
} }
...@@ -47,7 +52,7 @@ public class BusinessMappingAspect { ...@@ -47,7 +52,7 @@ public class BusinessMappingAspect {
if (annotation.session() > 0) { if (annotation.session() > 0) {
Object[] args = joinPoint.getArgs(); Object[] args = joinPoint.getArgs();
if (args.length < annotation.session()) { if (args.length < annotation.session()) {
throw new IllegalArgException(StringUtils.format("Business mapping session value({}) less than arguments size({}) - {}" throw new IllegalArgumentException(StringUtils.format("Business mapping session value({}) less than arguments size({}) - {}"
, annotation.session(), args.length, method)); , annotation.session(), args.length, method));
} }
session(args[annotation.session() - 1]); session(args[annotation.session() - 1]);
......
...@@ -28,7 +28,7 @@ public class Sequencer { ...@@ -28,7 +28,7 @@ public class Sequencer {
return sequencer.nextId(flake % 225L); return sequencer.nextId(flake % 225L);
} }
public int getPartitionKey(long id) { public int partitionKey(long id) {
return (int) ((id >> 8 << 8) ^ id); return (int) ((id >> 8 << 8) ^ id);
} }
......
package cn.quant.baa.pay.context; package cn.quant.baa.pay.context;
import cn.quant.baa.pay.component.Sequencer;
import cn.quant.baa.pay.jpa.entity.AccountEntity; import cn.quant.baa.pay.jpa.entity.AccountEntity;
import cn.quant.baa.pay.model.BusinessRequest; import cn.quant.baa.pay.model.BusinessRequest;
import cn.quant.spring.NullException;
import cn.quant.spring.context.BusinessSession; import cn.quant.spring.context.BusinessSession;
import cn.quant.spring.context.ServerApplicationContext; import cn.quant.spring.context.ServerApplicationContext;
import cn.quant.spring.data.jpa.entity.OptimisticEntity; import cn.quant.spring.data.jpa.entity.OptimisticEntity;
...@@ -26,9 +26,24 @@ public class TransactionSession extends BusinessSession { ...@@ -26,9 +26,24 @@ public class TransactionSession extends BusinessSession {
private AccountEntity account; private AccountEntity account;
public TransactionSession(ServerApplicationContext context) { private Sequencer sequencer;
public TransactionSession(ServerApplicationContext context, Sequencer sequencer) {
super(context); super(context);
this.repositoryProxy = new JapRepositoryProxy(context.getParent()); this.repositoryProxy = new JapRepositoryProxy(context.getParent());
this.sequencer = sequencer;
}
public long nextId() {
return sequencer.nextId();
}
public long nextId(long id) {
return sequencer.nextId(id);
}
public int partitionKey(long id){
return sequencer.partitionKey(id);
} }
/** /**
...@@ -46,10 +61,10 @@ public class TransactionSession extends BusinessSession { ...@@ -46,10 +61,10 @@ public class TransactionSession extends BusinessSession {
local.remove(); local.remove();
} }
public static TransactionSession newInstance(BusinessRequest request, ServerApplicationContext context) { public static TransactionSession newInstance(BusinessRequest request, ServerApplicationContext context, Sequencer sequencer) {
TransactionSession session = local.get(); TransactionSession session = local.get();
if (session == null) { if (session == null) {
session = new TransactionSession(context); session = new TransactionSession(context, sequencer);
Date businessDate = request.getBusinessDate(); Date businessDate = request.getBusinessDate();
if (businessDate == null) { if (businessDate == null) {
session.setBusinessDate(LocalDateTime.now()); session.setBusinessDate(LocalDateTime.now());
...@@ -105,7 +120,7 @@ public class TransactionSession extends BusinessSession { ...@@ -105,7 +120,7 @@ public class TransactionSession extends BusinessSession {
return repositoryProxy.getRepository(cls); return repositoryProxy.getRepository(cls);
} }
public <T> T findOne(Class<T> cls, Object key) { public <T> T findOne(Class<T> cls, Object key) {
RepositoryProxy repositoryProxy = this.getRepositoryProxy(); RepositoryProxy repositoryProxy = this.getRepositoryProxy();
T t = null; T t = null;
if (repositoryProxy != null) { if (repositoryProxy != null) {
......
package cn.quant.baa.pay.dict;
import java.math.BigDecimal;
/**
* Created by Administrator on 2021/8/27 0027.
*/
public enum CreditDebitFlag {
N("非金融交易", BigDecimal.ZERO),
C("贷记", BigDecimal.ONE),
D("借记", BigDecimal.ONE.negate());
public final String text;
public final BigDecimal sign;
public final boolean positive;
CreditDebitFlag(String txt, BigDecimal sign) {
this.sign = sign;
this.text = txt;
this.positive = (sign.compareTo(BigDecimal.ZERO) >= 0);
}
}
...@@ -5,13 +5,20 @@ package cn.quant.baa.pay.dict; ...@@ -5,13 +5,20 @@ package cn.quant.baa.pay.dict;
*/ */
public enum MessageEnum { public enum MessageEnum {
EMPTY_REQ_DATA("2000000"), EMPTY_REQ_DATA("2000000"),
MCH_ID_ILLEGAL("2000000"), ILLEGAL_REQ_SUBJECT("2000000"),
CHAN_ID_ILLEGAL("2000000"), ILLEGAL_REQ_MCH_ID("2000000"),
BUYER_ID_ILLEGAL("2000000"), ILLEGAL_REQ_CHAN_ID("2000000"),
INSTITUTION_ID_ILLEGAL("2000000"), ILLEGAL_REQ_BUYER_ID("2000000"),
PRODUCT_ID_ILLEGAL("2000000"), ILLEGAL_REQ_INST_ID("2000000"),
ILLEGAL_REQ_PROD_ID("2000000"),
ILLEGAL_REQ_OUT_TRADE_NO("2000000"),
ILLEGAL_REQ_ORIG_AMT("2000000"),
ILLEGAL_REQ_AMT("2000000"),
ILLEGAL_REQ_DISC_AMT("2000000"),
ILLEGAL_REQ_CASH_AMT("2000000"),
ILLEGAL_REQ_CREDIT_AMT("2000000"),
EXIST_ORDER("300"),
ACQUIRER_NOSUCH("2000000"), ACQUIRER_NOSUCH("2000000"),
ACQUIRER_NOMATCH("2000000"), ACQUIRER_NOMATCH("2000000"),
......
package cn.quant.baa.pay.dict;
/**
* Created by Administrator on 2021/8/27 0027.
*/
public enum PayMethod {
AUTO("自动"),
DRST("主动"),
MANU("手动");
public final String text;
PayMethod(String text) {
this.text = text;
}
}
package cn.quant.baa.pay.jpa.entity;
import cn.quant.spring.data.jpa.entity.DescriptionEntity;
import org.hibernate.envers.Audited;
import java.io.Serializable;
/**
* Created by Administrator on 2021/8/22 0022.
*/
@Audited
public abstract class AuditedDescriptionEntity extends DescriptionEntity implements Serializable{
private static final long serialVersionUID = -5974712123235831070L;
}
package cn.quant.baa.pay.jpa.entity;
import cn.quant.spring.data.jpa.entity.OptimisticEntity;
import cn.quant.spring.data.jpa.entity.PartitionEntity;
import org.hibernate.envers.Audited;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.io.Serializable;
/**
* <p><b>Enable Audited Annotation:</b><br/>
* <code>@org.hibernate.envers.Audited</code><br/>
* <code>@javax.persistence.EntityListeners(AuditingEntityListener.class)</code><br/>
* <code>@javax.persistence.MappedSuperclass</code><br/>
* </p>
* Created by hechao on 2020/2/13.
* @see cn.quant.baa.pay.support.AuditorAwareHandler
*/
@Audited
public abstract class AuditedOptimisticEntity extends OptimisticEntity implements Serializable {
private static final long serialVersionUID = 7857933536111031118L;
}
\ No newline at end of file
package cn.quant.baa.pay.jpa.entity; package cn.quant.baa.pay.jpa.entity;
import cn.quant.baa.pay.dict.DictType; import cn.quant.baa.pay.dict.DictType;
import cn.quant.spring.data.jpa.entity.OptimisticEntity;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.EmbeddedId; import javax.persistence.EmbeddedId;
...@@ -14,7 +15,7 @@ import java.util.Objects; ...@@ -14,7 +15,7 @@ import java.util.Objects;
*/ */
@Entity @Entity
@Table(name = "dictionary") @Table(name = "dictionary")
public class DictionaryEntity extends AuditedOptimisticEntity implements Serializable { public class DictionaryEntity extends OptimisticEntity implements Serializable {
@EmbeddedId @EmbeddedId
private DictionaryIds ids; private DictionaryIds ids;
......
package cn.quant.baa.pay.jpa.entity;
import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.dict.*;
import cn.quant.baa.pay.model.MerchantAcquirerProfile;
import cn.quant.baa.pay.model.PayRequestData;
import cn.quant.spring.util.DateUtils;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import static cn.quant.baa.pay.Constant.MINI_LOCAL_DATE;
/**
* Created by Administrator on 2021/8/27 0027.
*/
public class EntityBuilder {
public static AccountEntity account(AccountIds ids, String productId, long accountId, String buyerId, int partitionKey) {
LocalDate now = LocalDate.now();
AccountEntity account = new AccountEntity();
account.setIds(ids);
account.setAccountId(accountId);
account.setAcctTypeId(AcctTypeId.EMPS);
account.setAutoPaymentFlag(false);
account.setAutoPaymentWarnDate(MINI_LOCAL_DATE);
account.setAutoStatus(StatusCode.NORM);
account.setAutoStatusDate(now);
account.setCorpotateAcctFlag(false);
account.setCreditTxnCount(0);
account.setCurrencyCode(CurrencyCode.CNY);
account.setCurrentCycleNo(1);
account.setDebitTxtCount(0);
account.setExternalAcctNo(buyerId);
account.setManualStatus(null);
account.setManualStatusDate(null);
account.setNextTxnNo(1);
account.setOpenDate(now);
account.setProductId(productId);
account.setProtocolRule(null);
account.setTotalCredit(BigDecimal.ZERO);
account.setTotalDebit(BigDecimal.ZERO);
account.setTxnNo(0);
Date date = DateUtils.now();
account.setCreatedDate(date);
account.setModifiedDate(date);
account.setPartitionKey(partitionKey);
return account;
}
public static PayHistoryEntity history(MerchantAcquirerProfile profile, AccountEntity account, PayHistoryIds ids, PayRequestData data
, TransactionSession session) {
BigDecimal discount = new BigDecimal(data.getDiscounts());
BigDecimal origAmt = new BigDecimal(data.getOriginalAmount());
BigDecimal cash = new BigDecimal(data.getCashAmount());
BigDecimal credit = new BigDecimal(data.getCreditAmount());
BigDecimal amount = new BigDecimal(data.getAmount());
String signer = data.getGoodsSigner();
Long accountId = account.getAccountId();
PayHistoryEntity entity = new PayHistoryEntity();
entity.setIds(ids);
entity.setAccountId(accountId);
entity.setAddress(data.getAddress());
entity.setAttachText(data.getAttach());
entity.setCreditDebitFlag(CreditDebitFlag.C);
entity.setCurrencyCode(CurrencyCode.CNY);
entity.setCustomerGenFlag(true);
entity.setDiscAmount(discount);
entity.setGenFeeAmount(BigDecimal.ZERO);
entity.setGoodsSigner(signer);
entity.setShopName(data.getShopName());
entity.setMobilePhone(data.getPhoneNo());
entity.setNotifyUrl(data.getNotifyUrl());
entity.setOriginalTxnAmount(origAmt);
entity.setPayAcctId(profile.getPayAcctId());
entity.setPayChanCode(profile.getPayChanCode());
entity.setPayAppId(profile.getPayAppId());
entity.setPayMethod(PayMethod.DRST);
entity.setPostCashAmount(cash);
entity.setPostCreditAmount(credit);
entity.setPartitionKey(session.partitionKey(accountId));
entity.setRequestId(session.getRequestId());
entity.setRequestTime(session.getRequestTime());
entity.setShopName(data.getShopName());
entity.setStatementeFlag(true);
entity.setStatisticsCode("RPAY");
entity.setStatusCode(StatusCode.PEND);
entity.setSubject(data.getSubject());
entity.setTransactionId(session.nextId());
entity.setTxnAmount(amount);
entity.setTxnDate(session.getBusinessLocalDate());
entity.setTxnTime(session.getBusinessLocalTime());
entity.setTxnTypeCode("RETL");
if (cash.compareTo(BigDecimal.ZERO) > 0) {
entity.setTxnCode("R001");
} else {
entity.setTxnCode("R002");
}
if (cash.add(credit).compareTo(cash.max(credit)) > 0) {
entity.setTxnCode("R003");
}
return entity;
}
}
package cn.quant.baa.pay.jpa.entity; package cn.quant.baa.pay.jpa.entity;
import cn.quant.baa.pay.dict.AccessCode; import cn.quant.baa.pay.dict.AccessCode;
import cn.quant.spring.data.jpa.entity.DescriptionEntity;
import cn.quant.spring.util.StringUtils; import cn.quant.spring.util.StringUtils;
import javax.persistence.*; import javax.persistence.*;
...@@ -12,7 +13,7 @@ import java.util.Objects; ...@@ -12,7 +13,7 @@ import java.util.Objects;
*/ */
@Entity @Entity
@Table(name = "mch_channel") @Table(name = "mch_channel")
public class MchChannelEntity extends AuditedDescriptionEntity implements Serializable { public class MchChannelEntity extends DescriptionEntity implements Serializable {
private static final long serialVersionUID = 2948677889658286512L; private static final long serialVersionUID = 2948677889658286512L;
private final static String CLASS_NAME = MchChannelEntity.class.getSimpleName(); private final static String CLASS_NAME = MchChannelEntity.class.getSimpleName();
......
package cn.quant.baa.pay.jpa.entity; package cn.quant.baa.pay.jpa.entity;
import cn.quant.spring.data.jpa.entity.OptimisticEntity;
import cn.quant.spring.util.StringUtils; import cn.quant.spring.util.StringUtils;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
...@@ -17,7 +18,7 @@ import java.util.Objects; ...@@ -17,7 +18,7 @@ import java.util.Objects;
*/ */
@Entity @Entity
@Table(name = "pay_app") @Table(name = "pay_app")
public class PayAppEntity extends AuditedOptimisticEntity implements Serializable { public class PayAppEntity extends OptimisticEntity implements Serializable {
private static final long serialVersionUID = -5502377854231068271L; private static final long serialVersionUID = -5502377854231068271L;
......
package cn.quant.baa.pay.jpa.entity; package cn.quant.baa.pay.jpa.entity;
import cn.quant.baa.pay.dict.AccessType; import cn.quant.baa.pay.dict.AccessType;
import cn.quant.spring.data.jpa.entity.DescriptionEntity;
import javax.persistence.*; import javax.persistence.*;
import java.io.Serializable; import java.io.Serializable;
...@@ -11,7 +12,7 @@ import java.util.Objects; ...@@ -11,7 +12,7 @@ import java.util.Objects;
*/ */
@Entity @Entity
@Table(name = "pay_feature") @Table(name = "pay_feature")
public class PayFeatureEntity extends AuditedDescriptionEntity implements Serializable { public class PayFeatureEntity extends DescriptionEntity implements Serializable {
private static final long serialVersionUID = -3977191384143230391L; private static final long serialVersionUID = -3977191384143230391L;
......
package cn.quant.baa.pay.jpa.repository;
import cn.quant.baa.pay.jpa.entity.PayFeatureEntity;
import cn.quant.baa.pay.jpa.entity.PayFeatureIds;
import cn.quant.baa.pay.jpa.entity.PayHistoryEntity;
import cn.quant.baa.pay.jpa.entity.PayHistoryIds;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* Created by Administrator on 2021/8/22 0022.
*/
@Repository
public interface PayHistoryRepository extends JpaRepository<PayHistoryEntity, PayHistoryIds> {
}
...@@ -14,9 +14,9 @@ import java.util.Locale; ...@@ -14,9 +14,9 @@ import java.util.Locale;
*/ */
public class AssertUtils { public class AssertUtils {
public static String getMessage(MessageEnum code, Object... args){ public static String getMessage(MessageEnum code, Object... args) {
ServerApplicationContext context = ContextLoader.getCurrentApplicationContext(); ServerApplicationContext context = ContextLoader.getCurrentApplicationContext();
return context.getMessage(code.name(), args, Locale.SIMPLIFIED_CHINESE); return context.getMessage(code.name(), Locale.SIMPLIFIED_CHINESE, args);
} }
public static BusinessException exception(MessageEnum code, Object... args) { public static BusinessException exception(MessageEnum code, Object... args) {
...@@ -29,7 +29,7 @@ public class AssertUtils { ...@@ -29,7 +29,7 @@ public class AssertUtils {
public static void throwMessage(MessageEnum code) throws BusinessException { public static void throwMessage(MessageEnum code) throws BusinessException {
ServerApplicationContext context = ContextLoader.getCurrentApplicationContext(); ServerApplicationContext context = ContextLoader.getCurrentApplicationContext();
throw new BusinessException(code, context.getMessage(code.name(), Locale.SIMPLIFIED_CHINESE)); throw new BusinessException(code, context.getMessage(code.name()));
} }
public static void notEmpty(String requestId, Object val, Class cls) { public static void notEmpty(String requestId, Object val, Class cls) {
...@@ -39,14 +39,20 @@ public class AssertUtils { ...@@ -39,14 +39,20 @@ public class AssertUtils {
} }
public static void notEmpty(String requestId, Number val, String msg) { public static void notEmpty(String requestId, Number val, String msg) {
if(StringUtils.isEmpty(val)){ if (StringUtils.isEmpty(val)) {
throw new NullException(msg); throw new NullException(msg);
} }
} }
public static void notEmpty(String requestId, String val, String msg) { public static void notEmpty(String requestId, String val, String msg) {
if(StringUtils.isEmpty(val)){ if (StringUtils.isEmpty(val)) {
throw new NullException(msg); throw new NullException(msg);
} }
} }
public static void hasLength(MessageEnum code, String val, int start, int end) {
if (val == null || val.length() < start || val.length() > end) {
throwMessage(code);
}
}
} }
package cn.quant.baa.pay; package cn.quant.baa.pay.model;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
/** /**
...@@ -12,6 +14,7 @@ public class GoodsDetail implements Serializable{ ...@@ -12,6 +14,7 @@ public class GoodsDetail implements Serializable{
/** /**
* 商品ID * 商品ID
*/ */
@Size(min = 6, max = 64)
private String goodsId; private String goodsId;
/** /**
...@@ -22,7 +25,7 @@ public class GoodsDetail implements Serializable{ ...@@ -22,7 +25,7 @@ public class GoodsDetail implements Serializable{
/** /**
* 数量 * 数量
*/ */
private Integer quantity; private String quantity;
/** /**
* 商品单价 * 商品单价
...@@ -61,11 +64,11 @@ public class GoodsDetail implements Serializable{ ...@@ -61,11 +64,11 @@ public class GoodsDetail implements Serializable{
this.goodsName = goodsName; this.goodsName = goodsName;
} }
public Integer getQuantity() { public String getQuantity() {
return quantity; return quantity;
} }
public void setQuantity(Integer quantity) { public void setQuantity(String quantity) {
this.quantity = quantity; this.quantity = quantity;
} }
......
package cn.quant.baa.pay; package cn.quant.baa.pay.model;
import java.io.Serializable; import java.io.Serializable;
......
package cn.quant.baa.pay; package cn.quant.baa.pay.model;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
......
package cn.quant.baa.pay; package cn.quant.baa.pay.model;
import java.io.Serializable; import java.io.Serializable;
......
package cn.quant.baa.pay.model; package cn.quant.baa.pay.model;
import cn.quant.baa.pay.MerchantAcquirer;
import cn.quant.baa.pay.MerchantAcquirerBook;
import cn.quant.baa.pay.config.DictionaryViewer; import cn.quant.baa.pay.config.DictionaryViewer;
import cn.quant.baa.pay.dict.DictType; import cn.quant.baa.pay.dict.DictType;
import cn.quant.spring.UnsupportedException; import cn.quant.spring.UnsupportedException;
......
package cn.quant.baa.pay; package cn.quant.baa.pay.model;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
...@@ -13,53 +15,80 @@ public class PayRequestData implements Serializable{ ...@@ -13,53 +15,80 @@ public class PayRequestData implements Serializable{
/** /**
* 订单标题 * 订单标题
*/ */
@Size(max = 128, message = "ILLEGAL_REQ_SUBJECT")
private String subject; private String subject;
/** /**
* 商户ID * 商户ID
*/ */
@NotNull(message = "ILLEGAL_REQ_MCH_ID")
private String mchId; private String mchId;
/** /**
* 支付通道ID * 支付通道ID
*/ */
@NotNull(message = "ILLEGAL_REQ_CHAN_ID")
private String chanId; private String chanId;
/** /**
* 商户订单号 * 商户订单号
*/ */
@Size(min = 6, max = 64, message = "ILLEGAL_REQ_OUT_TRADE_NO")
@NotNull(message = "ILLEGAL_REQ_OUT_TRADE_NO")
private String outTradeNo; private String outTradeNo;
/** /**
* 原订单金额 * 原订单金额
*/ */
@NotNull(message = "ILLEGAL_REQ_ORIG_AMT")
private String originalAmount; private String originalAmount;
/** /**
*实际订单金额 *实际订单金额
*/ */
@NotNull(message = "ILLEGAL_REQ_AMT")
private String amount; private String amount;
/** /**
* 优惠金额 * 优惠金额
*/ */
@NotNull(message = "ILLEGAL_REQ_DISC_AMT")
private String discounts; private String discounts;
/** /**
* 通知地址 * 现金金额
*/ */
private String notifyUrl; @NotNull(message = "ILLEGAL_REQ_CASH_AMT")
private String cashAmount;
/**
* 用信金额
*/
@NotNull(message = "ILLEGAL_REQ_CREDIT_AMT")
private String creditAmount;
/** /**
*买家ID *买家ID
*/ */
@Size(min = 6, max = 32, message ="ILLEGAL_REQ_BUYER_ID" )
@NotNull(message = "ILLEGAL_REQ_BUYER_ID")
private String buyerId; private String buyerId;
/**
* 通知地址
*/
private String notifyUrl;
/** /**
* 附加信息 * 附加信息
*/ */
private String attach; private String attach;
/**
* 店铺名
*/
private String shopName;
/** /**
* 收货人名称 * 收货人名称
*/ */
...@@ -136,6 +165,22 @@ public class PayRequestData implements Serializable{ ...@@ -136,6 +165,22 @@ public class PayRequestData implements Serializable{
this.discounts = discounts; this.discounts = discounts;
} }
public String getCashAmount() {
return cashAmount;
}
public void setCashAmount(String cashAmount) {
this.cashAmount = cashAmount;
}
public String getCreditAmount() {
return creditAmount;
}
public void setCreditAmount(String creditAmount) {
this.creditAmount = creditAmount;
}
public String getNotifyUrl() { public String getNotifyUrl() {
return notifyUrl; return notifyUrl;
} }
...@@ -160,6 +205,14 @@ public class PayRequestData implements Serializable{ ...@@ -160,6 +205,14 @@ public class PayRequestData implements Serializable{
this.attach = attach; this.attach = attach;
} }
public String getShopName() {
return shopName;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
public String getGoodsSigner() { public String getGoodsSigner() {
return goodsSigner; return goodsSigner;
} }
...@@ -202,9 +255,12 @@ public class PayRequestData implements Serializable{ ...@@ -202,9 +255,12 @@ public class PayRequestData implements Serializable{
sb.append(", originalAmount='").append(originalAmount).append('\''); sb.append(", originalAmount='").append(originalAmount).append('\'');
sb.append(", amount='").append(amount).append('\''); sb.append(", amount='").append(amount).append('\'');
sb.append(", discounts='").append(discounts).append('\''); sb.append(", discounts='").append(discounts).append('\'');
sb.append(", notifyUrl='").append(notifyUrl).append('\''); sb.append(", cashAmount='").append(cashAmount).append('\'');
sb.append(", creditAmount='").append(creditAmount).append('\'');
sb.append(", buyerId='").append(buyerId).append('\''); sb.append(", buyerId='").append(buyerId).append('\'');
sb.append(", notifyUrl='").append(notifyUrl).append('\'');
sb.append(", attach='").append(attach).append('\''); sb.append(", attach='").append(attach).append('\'');
sb.append(", shopName='").append(shopName).append('\'');
sb.append(", goodsSigner='").append(goodsSigner).append('\''); sb.append(", goodsSigner='").append(goodsSigner).append('\'');
sb.append(", phoneNo='").append(phoneNo).append('\''); sb.append(", phoneNo='").append(phoneNo).append('\'');
sb.append(", address='").append(address).append('\''); sb.append(", address='").append(address).append('\'');
......
...@@ -7,6 +7,7 @@ import cn.quant.baa.pay.dict.CurrencyCode; ...@@ -7,6 +7,7 @@ import cn.quant.baa.pay.dict.CurrencyCode;
import cn.quant.baa.pay.dict.StatusCode; import cn.quant.baa.pay.dict.StatusCode;
import cn.quant.baa.pay.jpa.entity.AccountEntity; import cn.quant.baa.pay.jpa.entity.AccountEntity;
import cn.quant.baa.pay.jpa.entity.AccountIds; import cn.quant.baa.pay.jpa.entity.AccountIds;
import cn.quant.baa.pay.jpa.entity.EntityBuilder;
import cn.quant.baa.pay.jpa.repository.AccountRepository; import cn.quant.baa.pay.jpa.repository.AccountRepository;
import cn.quant.baa.pay.model.AssertUtils; import cn.quant.baa.pay.model.AssertUtils;
import cn.quant.spring.NullException; import cn.quant.spring.NullException;
...@@ -33,65 +34,24 @@ public abstract class BusinessService { ...@@ -33,65 +34,24 @@ public abstract class BusinessService {
private static final Logger logger = LoggerFactory.getLogger(BusinessService.class); private static final Logger logger = LoggerFactory.getLogger(BusinessService.class);
@Autowired
private Sequencer sequencer;
public void prepare(String institutionId, String productId, String buyerId, TransactionSession session) { public TransactionSession prepare(String institutionId, String productId, String buyerId, TransactionSession session) {
if (session == null) { if (session == null) {
throw new NullException("Session is null."); throw new NullException("Session is null.");
} }
if (StringUtils.isEmpty(institutionId)) {
AssertUtils.throwMessage(INSTITUTION_ID_ILLEGAL);
}
if (StringUtils.isEmpty(productId)) {
AssertUtils.throwMessage(PRODUCT_ID_ILLEGAL);
}
if (StringUtils.isEmpty(buyerId)) {
AssertUtils.throwMessage(BUYER_ID_ILLEGAL);
}
AccountIds ids = new AccountIds(); AccountIds ids = new AccountIds();
ids.setInstitutionId(institutionId); ids.setInstitutionId(institutionId);
ids.setAccountRefNo(buyerId); ids.setAccountRefNo(buyerId);
AccountEntity account = session.findOne(AccountEntity.class, ids); AccountEntity account = session.findOne(AccountEntity.class, ids);
if (account == null) { if (account == null) {
Long id = sequencer.nextId(buyerId.hashCode()); Long id = session.nextId(buyerId.hashCode());
LocalDate now = LocalDate.now(); account = EntityBuilder.account(ids, productId, id, buyerId, session.partitionKey(id));
account = new AccountEntity();
account.setIds(ids);
account.setAccountId(id);
account.setAcctTypeId(AcctTypeId.EMPS);
account.setAutoPaymentFlag(false);
account.setAutoPaymentWarnDate(MINI_LOCAL_DATE);
account.setAutoStatus(StatusCode.NORM);
account.setAutoStatusDate(now);
account.setCorpotateAcctFlag(false);
account.setCreditTxnCount(0);
account.setCurrencyCode(CurrencyCode.CNY);
account.setCurrentCycleNo(1);
account.setDebitTxtCount(0);
account.setExternalAcctNo(buyerId);
account.setManualStatus(null);
account.setManualStatusDate(null);
account.setNextTxnNo(1);
account.setOpenDate(now);
account.setProductId(productId);
account.setProtocolRule(null);
account.setTotalCredit(BigDecimal.ZERO);
account.setTotalDebit(BigDecimal.ZERO);
account.setTxnNo(0);
Date date = DateUtils.now();
account.setCreatedDate(date);
account.setModifiedDate(date);
account.setPartitionKey(sequencer.getPartitionKey(id));
session.pushEntity(account); session.pushEntity(account);
} }
session.setAccount(account); session.setAccount(account);
return session;
} }
} }
package cn.quant.baa.pay.service; package cn.quant.baa.pay.service;
import cn.quant.baa.pay.MerchantChannelRequestData; import cn.quant.baa.pay.model.MerchantChannelRequestData;
import cn.quant.baa.pay.config.MerchantAcquirerBuilder; import cn.quant.baa.pay.config.MerchantAcquirerBuilder;
import cn.quant.baa.pay.MerchantAcquirer; import cn.quant.baa.pay.model.MerchantAcquirer;
import cn.quant.baa.pay.MerchantAcquirerBook; import cn.quant.baa.pay.model.MerchantAcquirerBook;
import cn.quant.baa.pay.model.MerchantAcquirerProfile; import cn.quant.baa.pay.model.MerchantAcquirerProfile;
import cn.quant.baa.pay.model.ModelBuilder; import cn.quant.baa.pay.model.ModelBuilder;
import cn.quant.spring.util.StringUtils; import cn.quant.spring.util.StringUtils;
......
package cn.quant.baa.pay.service; package cn.quant.baa.pay.service;
import cn.quant.baa.pay.PayRequestData;
import cn.quant.baa.pay.config.MerchantAcquirerBuilder; import cn.quant.baa.pay.config.MerchantAcquirerBuilder;
import cn.quant.baa.pay.context.TransactionSession; import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.jpa.entity.AccountEntity;
import cn.quant.baa.pay.jpa.entity.EntityBuilder;
import cn.quant.baa.pay.jpa.entity.PayHistoryEntity;
import cn.quant.baa.pay.jpa.entity.PayHistoryIds;
import cn.quant.baa.pay.model.AssertUtils; import cn.quant.baa.pay.model.AssertUtils;
import cn.quant.baa.pay.model.GoodsDetail;
import cn.quant.baa.pay.model.MerchantAcquirerProfile; import cn.quant.baa.pay.model.MerchantAcquirerProfile;
import cn.quant.spring.util.StringUtils; import cn.quant.baa.pay.model.PayRequestData;
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;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import static cn.quant.baa.pay.dict.MessageEnum.*; import static cn.quant.baa.pay.dict.MessageEnum.*;
...@@ -22,46 +27,55 @@ public class TransactionService extends BusinessService { ...@@ -22,46 +27,55 @@ public class TransactionService extends BusinessService {
private static final Logger logger = LoggerFactory.getLogger(TransactionService.class); private static final Logger logger = LoggerFactory.getLogger(TransactionService.class);
@Autowired @Autowired
private MerchantAcquirerBuilder merchantAcquirerBuilder; private MerchantAcquirerBuilder merchantAcquirerBuilder;
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void check(PayHistoryIds ids, TransactionSession session) {
PayHistoryEntity historyEntity = session.findOne(PayHistoryEntity.class, ids);
if (historyEntity != null) {
AssertUtils.throwMessage(EXIST_ORDER, ids.getInstitutionId(), ids.getProductId(), ids.getExternalOrderNo());
}
}
@Transactional @Transactional
public void pay(PayRequestData data) { public void pay(PayRequestData data) {
if (data == null) {
AssertUtils.throwMessage(EMPTY_REQ_DATA);
}
String chanId = data.getChanId(); String chanId = data.getChanId();
if (StringUtils.isEmpty(chanId)) {
AssertUtils.throwMessage(CHAN_ID_ILLEGAL);
}
String mchId = data.getMchId();
if (StringUtils.isEmpty(mchId)) {
AssertUtils.throwMessage(MCH_ID_ILLEGAL);
}
MerchantAcquirerProfile profile = merchantAcquirerBuilder.get(Long.valueOf(chanId)); MerchantAcquirerProfile profile = merchantAcquirerBuilder.get(Long.valueOf(chanId));
if (profile == null) { if (profile == null) {
AssertUtils.throwMessage(ACQUIRER_NOSUCH); AssertUtils.throwMessage(ACQUIRER_NOSUCH, chanId);
} }
String mchId = data.getMchId();
if (!mchId.equals(profile.getPayAppId())) { if (!mchId.equals(profile.getPayAppId())) {
AssertUtils.throwMessage(ACQUIRER_NOMATCH); AssertUtils.throwMessage(ACQUIRER_NOMATCH, chanId, mchId);
} }
TransactionSession session = TransactionSession.session();
String institutionId = profile.getInstitutionId(); String institutionId = profile.getInstitutionId();
String productId = profile.getProductId(); String productId = profile.getProductId();
TransactionSession session = TransactionSession.session();
String buyerId = StringUtils.trimAllWhitespace(data.getBuyerId());
if (StringUtils.isEmpty(buyerId)) {
AssertUtils.throwMessage(BUYER_ID_ILLEGAL);
}
String outTradeNo = data.getOutTradeNo();
PayHistoryIds ids = new PayHistoryIds();
ids.setInstitutionId(institutionId);
ids.setProductId(productId);
ids.setExternalOrderNo(outTradeNo);
check(ids, session);
GoodsDetail[] goodsDetail = data.getGoodsDetail();
String buyerId = data.getBuyerId();
prepare(institutionId, productId, buyerId, session); prepare(institutionId, productId, buyerId, session);
AccountEntity account = session.getAccount();
System.currentTimeMillis(); PayHistoryEntity history = EntityBuilder.history(profile, account, ids, data, session);
session.pushEntity(history);
session.commit(); session.commit();
......
...@@ -30,7 +30,7 @@ public class ExceptionAdvice { ...@@ -30,7 +30,7 @@ public class ExceptionAdvice {
@ResponseBody @ResponseBody
public HttpResponseData handlerException(HttpServletRequest request, Exception e) { public HttpResponseData handlerException(HttpServletRequest request, Exception e) {
log.error("Exception url:{}, error:{}", request.getRequestURI(), e); log.error("!!- Exception request url - {} ", request.getRequestURI(), e);
String message = e.getMessage(); String message = e.getMessage();
HttpResponseData responseData = new HttpResponseData(e); HttpResponseData responseData = new HttpResponseData(e);
......
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<properties>
<project.logging.path>./</project.logging.path>
</properties>
</profile> </profile>
</profiles> </profiles>
......
package cn.quant.baa.pay.rest;
import cn.quant.baa.pay.model.AssertUtils;
import cn.quant.spring.IllegalParameterException;
import cn.quant.spring.NullException;
import cn.quant.spring.context.ContextLoader;
import cn.quant.spring.context.ServerApplicationContext;
import cn.quant.spring.rest.AbstractController;
import org.springframework.beans.factory.annotation.Autowired;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.Set;
import static cn.quant.baa.pay.dict.MessageEnum.EMPTY_REQ_DATA;
/**
* Created by Administrator on 2021/8/28 0028.
*/
public abstract class BusinessController extends AbstractController {
@Autowired
private Validator validator;
public <T> void validate(T t) {
if (t == null) {
throw new NullException();
}
Set<ConstraintViolation<T>> validate = validator.validate(t);
if (validate.size() > 0) {
ConstraintViolation<T> next = validate.iterator().next();
String s = next.getPropertyPath().toString();
String template = next.getMessageTemplate();
ServerApplicationContext applicationContext = ContextLoader.getCurrentApplicationContext();
String message = applicationContext.getMessage(template, "{0}-Illegal request parameter", (Object) s);
throw new IllegalParameterException(message);
}
}
}
package cn.quant.baa.pay.rest; package cn.quant.baa.pay.rest;
import cn.quant.baa.pay.MerchantAcquirer; import cn.quant.baa.pay.model.MerchantAcquirer;
import cn.quant.baa.pay.MerchantAcquirerBook; import cn.quant.baa.pay.model.MerchantAcquirerBook;
import cn.quant.baa.pay.MerchantChannelRequestData; import cn.quant.baa.pay.model.MerchantChannelRequestData;
import cn.quant.baa.pay.annotation.BusinessMapping; import cn.quant.baa.pay.annotation.BusinessMapping;
import cn.quant.baa.pay.context.TransactionSession; import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.model.AssertUtils; import cn.quant.baa.pay.model.AssertUtils;
...@@ -45,10 +45,6 @@ public class MerchantController extends AbstractController { ...@@ -45,10 +45,6 @@ public class MerchantController extends AbstractController {
AssertUtils.throwMessage(EMPTY_REQ_DATA); AssertUtils.throwMessage(EMPTY_REQ_DATA);
} }
String mchId = data.getMchId();
if (StringUtils.isEmpty(mchId)) {
AssertUtils.throwMessage(MCH_ID_ILLEGAL);
}
Map<String, MerchantAcquirerBook> channels = merchantService.getChannels(data); Map<String, MerchantAcquirerBook> channels = merchantService.getChannels(data);
ResponseEntity<HttpResponseData> entity = succeed(session.getRequestId(), channels); ResponseEntity<HttpResponseData> entity = succeed(session.getRequestId(), channels);
...@@ -67,10 +63,6 @@ public class MerchantController extends AbstractController { ...@@ -67,10 +63,6 @@ public class MerchantController extends AbstractController {
AssertUtils.throwMessage(EMPTY_REQ_DATA); AssertUtils.throwMessage(EMPTY_REQ_DATA);
} }
String id = data.getChanId();
if (StringUtils.isEmpty(id)) {
AssertUtils.throwMessage(CHAN_ID_ILLEGAL);
}
MerchantAcquirer channel = merchantService.getChannel(data); MerchantAcquirer channel = merchantService.getChannel(data);
ResponseEntity<HttpResponseData> entity = succeed(session.getRequestId(), channel); ResponseEntity<HttpResponseData> entity = succeed(session.getRequestId(), channel);
......
package cn.quant.baa.pay.rest; package cn.quant.baa.pay.rest;
import cn.quant.baa.pay.PayRequestData;
import cn.quant.baa.pay.annotation.BusinessMapping; import cn.quant.baa.pay.annotation.BusinessMapping;
import cn.quant.baa.pay.config.MerchantAcquirerBuilder;
import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.model.AssertUtils;
import cn.quant.baa.pay.model.BusinessRequest; import cn.quant.baa.pay.model.BusinessRequest;
import cn.quant.baa.pay.model.MerchantAcquirerProfile; import cn.quant.baa.pay.model.GoodsDetail;
import cn.quant.baa.pay.model.PayRequestData;
import cn.quant.baa.pay.service.TransactionService; import cn.quant.baa.pay.service.TransactionService;
import cn.quant.spring.rest.AbstractController; import cn.quant.spring.rest.AbstractController;
import cn.quant.spring.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import static cn.quant.baa.pay.dict.MessageEnum.*; import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.Set;
/** /**
* Created by Administrator on 2021/8/24 0024. * Created by Administrator on 2021/8/24 0024.
*/ */
@RestController @RestController
@RequestMapping("/transaction") @RequestMapping("/transaction")
public class TransactionController extends AbstractController { public class TransactionController extends BusinessController {
@Autowired @Autowired
private TransactionService transactionService; private TransactionService transactionService;
...@@ -30,8 +29,9 @@ public class TransactionController extends AbstractController { ...@@ -30,8 +29,9 @@ public class TransactionController extends AbstractController {
@PostMapping("/pay") @PostMapping("/pay")
public void pay(@RequestBody BusinessRequest<PayRequestData> request) { public void pay(@RequestBody BusinessRequest<PayRequestData> request) {
PayRequestData data = request.getData();
PayRequestData data = request.getData();
validate(data);
transactionService.pay(data); transactionService.pay(data);
......
...@@ -5,6 +5,7 @@ spring.application.name=Application ...@@ -5,6 +5,7 @@ spring.application.name=Application
#Devtool #Devtool
spring.devtools.restart.enabled=true 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=/
......
...@@ -65,4 +65,8 @@ spring: ...@@ -65,4 +65,8 @@ spring:
view: view:
prefix: classpath:/view/ prefix: classpath:/view/
suffix: .jsp suffix: .jsp
static-path-pattern: /** static-path-pattern: /**
\ No newline at end of file messages:
basename: messages, i18n/messages, cn.quant.spring/messages
fallback-to-system-locale: true
encoding: UTF-8
\ No newline at end of file
...@@ -21,6 +21,4 @@ spring: ...@@ -21,6 +21,4 @@ spring:
cloud: cloud:
task: task:
initialize: initialize:
enable: false enable: false
messages: \ No newline at end of file
basename: i18n/messages
\ No newline at end of file
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