feat: complete Spring Boot 카드 매입·정산 system (acquire-core migration target, mvn verify green, 24 tests)

This commit is contained in:
forge-bot 2026-07-18 15:27:41 +00:00
commit 0f6e3acfe6
92 changed files with 4320 additions and 0 deletions

34
domain/pom.xml Normal file
View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.klaro.acquiring</groupId>
<artifactId>card-acquiring-boot</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>domain</artifactId>
<name>domain</name>
<description>카드 매입·정산 도메인 엔티티/DTO/enum</description>
<dependencies>
<dependency>
<groupId>com.klaro.acquiring</groupId>
<artifactId>common-framework</artifactId>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,16 @@
package com.klaro.acquiring.domain.dto;
import java.math.BigDecimal;
/**
* 수수료 계산 결과(분해). 매입 금액에 대해 MDR/VAN 수수료와 순지급액(net) 담는다.
*
* @param baseAmount 기준(매입) 금액
* @param mdrFee 가맹점 할인수수료
* @param vanFee VAN 수수료
* @param totalFee 수수료 (mdr + van)
* @param netAmount 순지급액 (base - totalFee)
*/
public record FeeBreakdown(BigDecimal baseAmount, BigDecimal mdrFee, BigDecimal vanFee,
BigDecimal totalFee, BigDecimal netAmount) {
}

View file

@ -0,0 +1,69 @@
package com.klaro.acquiring.domain.entity;
import com.klaro.acquiring.domain.enums.TxStatus;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import java.time.LocalDate;
/** 승인 원장(au). 매입/대사의 기준이 되는 승인 거래. */
@Entity
@Table(name = "approval")
public class Approval {
@Id
@Column(name = "appr_no", length = 12)
private String apprNo;
@Column(name = "merch_id", length = 15, nullable = false)
private String merchId;
@Column(name = "card_no", length = 19, nullable = false)
private String cardNo;
@Column(name = "amount", precision = 18, scale = 2, nullable = false)
private BigDecimal amount;
@Column(name = "appr_date", length = 8, nullable = false)
private String apprDate;
@Column(name = "biz_date", nullable = false)
private LocalDate bizDate;
@Enumerated(EnumType.STRING)
@Column(name = "status", length = 12, nullable = false)
private TxStatus status = TxStatus.RECEIVED;
protected Approval() {
}
public Approval(String apprNo, String merchId, String cardNo, BigDecimal amount,
String apprDate, LocalDate bizDate) {
this.apprNo = apprNo;
this.merchId = merchId;
this.cardNo = cardNo;
this.amount = amount;
this.apprDate = apprDate;
this.bizDate = bizDate;
}
public String getApprNo() { return apprNo; }
public void setApprNo(String apprNo) { this.apprNo = apprNo; }
public String getMerchId() { return merchId; }
public void setMerchId(String merchId) { this.merchId = merchId; }
public String getCardNo() { return cardNo; }
public void setCardNo(String cardNo) { this.cardNo = cardNo; }
public BigDecimal getAmount() { return amount; }
public void setAmount(BigDecimal amount) { this.amount = amount; }
public String getApprDate() { return apprDate; }
public void setApprDate(String apprDate) { this.apprDate = apprDate; }
public LocalDate getBizDate() { return bizDate; }
public void setBizDate(LocalDate bizDate) { this.bizDate = bizDate; }
public TxStatus getStatus() { return status; }
public void setStatus(TxStatus status) { this.status = status; }
}

View file

@ -0,0 +1,49 @@
package com.klaro.acquiring.domain.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
/** 카드 마스터(마스킹 카드번호 기준). */
@Entity
@Table(name = "card")
public class Card {
@Id
@Column(name = "card_no", length = 19)
private String cardNo;
@Column(name = "bin", length = 6, nullable = false)
private String bin;
@Column(name = "brand", length = 10, nullable = false)
private String brand;
@Column(name = "issuer_code", length = 4)
private String issuerCode;
@Column(name = "status", length = 1, nullable = false)
private String status = "A";
protected Card() {
}
public Card(String cardNo, String bin, String brand, String issuerCode) {
this.cardNo = cardNo;
this.bin = bin;
this.brand = brand;
this.issuerCode = issuerCode;
}
public String getCardNo() { return cardNo; }
public void setCardNo(String cardNo) { this.cardNo = cardNo; }
public String getBin() { return bin; }
public void setBin(String bin) { this.bin = bin; }
public String getBrand() { return brand; }
public void setBrand(String brand) { this.brand = brand; }
public String getIssuerCode() { return issuerCode; }
public void setIssuerCode(String issuerCode) { this.issuerCode = issuerCode; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
}

View file

@ -0,0 +1,55 @@
package com.klaro.acquiring.domain.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import java.time.LocalDate;
/** 매입사 입금 통보(대사 3-leg 중 입금 leg). 승인번호 기준 매칭. */
@Entity
@Table(name = "deposit")
public class Deposit {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "deposit_id")
private Long depositId;
@Column(name = "appr_no", length = 12, nullable = false)
private String apprNo;
@Column(name = "merch_id", length = 15, nullable = false)
private String merchId;
@Column(name = "amount", precision = 18, scale = 2, nullable = false)
private BigDecimal amount;
@Column(name = "biz_date", nullable = false)
private LocalDate bizDate;
protected Deposit() {
}
public Deposit(String apprNo, String merchId, BigDecimal amount, LocalDate bizDate) {
this.apprNo = apprNo;
this.merchId = merchId;
this.amount = amount;
this.bizDate = bizDate;
}
public Long getDepositId() { return depositId; }
public void setDepositId(Long depositId) { this.depositId = depositId; }
public String getApprNo() { return apprNo; }
public void setApprNo(String apprNo) { this.apprNo = apprNo; }
public String getMerchId() { return merchId; }
public void setMerchId(String merchId) { this.merchId = merchId; }
public BigDecimal getAmount() { return amount; }
public void setAmount(BigDecimal amount) { this.amount = amount; }
public LocalDate getBizDate() { return bizDate; }
public void setBizDate(LocalDate bizDate) { this.bizDate = bizDate; }
}

View file

@ -0,0 +1,78 @@
package com.klaro.acquiring.domain.entity;
import com.klaro.acquiring.domain.enums.FeeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import java.time.LocalDate;
/** 매입 건별 수수료 내역(분해). MDR/VAN 각각 1행. */
@Entity
@Table(name = "fee")
public class Fee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "fee_id")
private Long feeId;
@Column(name = "purchase_id", nullable = false)
private Long purchaseId;
@Column(name = "merch_id", length = 15, nullable = false)
private String merchId;
@Enumerated(EnumType.STRING)
@Column(name = "fee_type", length = 8, nullable = false)
private FeeType feeType;
@Column(name = "base_amount", precision = 18, scale = 2, nullable = false)
private BigDecimal baseAmount;
@Column(name = "rate", precision = 6, scale = 4, nullable = false)
private BigDecimal rate = BigDecimal.ZERO;
@Column(name = "fee_amount", precision = 18, scale = 2, nullable = false)
private BigDecimal feeAmount;
@Column(name = "biz_date", nullable = false)
private LocalDate bizDate;
protected Fee() {
}
public Fee(Long purchaseId, String merchId, FeeType feeType, BigDecimal baseAmount,
BigDecimal rate, BigDecimal feeAmount, LocalDate bizDate) {
this.purchaseId = purchaseId;
this.merchId = merchId;
this.feeType = feeType;
this.baseAmount = baseAmount;
this.rate = rate;
this.feeAmount = feeAmount;
this.bizDate = bizDate;
}
public Long getFeeId() { return feeId; }
public void setFeeId(Long feeId) { this.feeId = feeId; }
public Long getPurchaseId() { return purchaseId; }
public void setPurchaseId(Long purchaseId) { this.purchaseId = purchaseId; }
public String getMerchId() { return merchId; }
public void setMerchId(String merchId) { this.merchId = merchId; }
public FeeType getFeeType() { return feeType; }
public void setFeeType(FeeType feeType) { this.feeType = feeType; }
public BigDecimal getBaseAmount() { return baseAmount; }
public void setBaseAmount(BigDecimal baseAmount) { this.baseAmount = baseAmount; }
public BigDecimal getRate() { return rate; }
public void setRate(BigDecimal rate) { this.rate = rate; }
public BigDecimal getFeeAmount() { return feeAmount; }
public void setFeeAmount(BigDecimal feeAmount) { this.feeAmount = feeAmount; }
public LocalDate getBizDate() { return bizDate; }
public void setBizDate(LocalDate bizDate) { this.bizDate = bizDate; }
}

View file

@ -0,0 +1,80 @@
package com.klaro.acquiring.domain.entity;
import com.klaro.acquiring.domain.enums.DrCr;
import com.klaro.acquiring.domain.enums.EntryType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import java.time.LocalDate;
/** 원장 전표(lg). 매입/수수료/정산/지급 반영 및 잔액검증 기준. */
@Entity
@Table(name = "ledger_entry")
public class LedgerEntry {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "entry_id")
private Long entryId;
@Column(name = "merch_id", length = 15, nullable = false)
private String merchId;
@Column(name = "biz_date", nullable = false)
private LocalDate bizDate;
@Enumerated(EnumType.STRING)
@Column(name = "entry_type", length = 12, nullable = false)
private EntryType entryType;
@Enumerated(EnumType.STRING)
@Column(name = "dr_cr", length = 8, nullable = false)
private DrCr drCr;
@Column(name = "amount", precision = 18, scale = 2, nullable = false)
private BigDecimal amount;
@Column(name = "ref_type", length = 20)
private String refType;
@Column(name = "ref_id", length = 30)
private String refId;
protected LedgerEntry() {
}
public LedgerEntry(String merchId, LocalDate bizDate, EntryType entryType, DrCr drCr,
BigDecimal amount, String refType, String refId) {
this.merchId = merchId;
this.bizDate = bizDate;
this.entryType = entryType;
this.drCr = drCr;
this.amount = amount;
this.refType = refType;
this.refId = refId;
}
public Long getEntryId() { return entryId; }
public void setEntryId(Long entryId) { this.entryId = entryId; }
public String getMerchId() { return merchId; }
public void setMerchId(String merchId) { this.merchId = merchId; }
public LocalDate getBizDate() { return bizDate; }
public void setBizDate(LocalDate bizDate) { this.bizDate = bizDate; }
public EntryType getEntryType() { return entryType; }
public void setEntryType(EntryType entryType) { this.entryType = entryType; }
public DrCr getDrCr() { return drCr; }
public void setDrCr(DrCr drCr) { this.drCr = drCr; }
public BigDecimal getAmount() { return amount; }
public void setAmount(BigDecimal amount) { this.amount = amount; }
public String getRefType() { return refType; }
public void setRefType(String refType) { this.refType = refType; }
public String getRefId() { return refId; }
public void setRefId(String refId) { this.refId = refId; }
}

View file

@ -0,0 +1,141 @@
package com.klaro.acquiring.domain.entity;
import com.klaro.acquiring.domain.enums.MerchantStatus;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.math.BigDecimal;
/**
* 가맹점 마스터. 레거시 merchant 테이블 + 수수료율/정산주기/지급계좌 마스터를 통합.
*/
@Entity
@Table(name = "merchant")
public class Merchant {
@Id
@Column(name = "merch_id", length = 15)
private String merchId;
@Column(name = "merch_name", length = 60, nullable = false)
private String merchName;
@Column(name = "biz_no", length = 12)
private String bizNo;
@Enumerated(EnumType.STRING)
@Column(name = "status", length = 12, nullable = false)
private MerchantStatus status = MerchantStatus.ACTIVE;
/** 가맹점 할인수수료율 (MDR), 예: 0.0230 = 2.3% */
@Column(name = "mdr_rate", precision = 6, scale = 4, nullable = false)
private BigDecimal mdrRate = BigDecimal.ZERO;
/** VAN 건당 정액 수수료(원) */
@Column(name = "van_fee", precision = 18, scale = 2, nullable = false)
private BigDecimal vanFee = BigDecimal.ZERO;
/** 정산주기 (T+n 영업일) */
@Column(name = "settlement_cycle", nullable = false)
private int settlementCycle = 2;
@Column(name = "bank_code", length = 3)
private String bankCode;
@Column(name = "account_no", length = 20)
private String accountNo;
protected Merchant() {
}
public Merchant(String merchId, String merchName, BigDecimal mdrRate, BigDecimal vanFee,
int settlementCycle, String bankCode, String accountNo) {
this.merchId = merchId;
this.merchName = merchName;
this.mdrRate = mdrRate;
this.vanFee = vanFee;
this.settlementCycle = settlementCycle;
this.bankCode = bankCode;
this.accountNo = accountNo;
}
public String getMerchId() {
return merchId;
}
public void setMerchId(String merchId) {
this.merchId = merchId;
}
public String getMerchName() {
return merchName;
}
public void setMerchName(String merchName) {
this.merchName = merchName;
}
public String getBizNo() {
return bizNo;
}
public void setBizNo(String bizNo) {
this.bizNo = bizNo;
}
public MerchantStatus getStatus() {
return status;
}
public void setStatus(MerchantStatus status) {
this.status = status;
}
public BigDecimal getMdrRate() {
return mdrRate;
}
public void setMdrRate(BigDecimal mdrRate) {
this.mdrRate = mdrRate;
}
public BigDecimal getVanFee() {
return vanFee;
}
public void setVanFee(BigDecimal vanFee) {
this.vanFee = vanFee;
}
public int getSettlementCycle() {
return settlementCycle;
}
public void setSettlementCycle(int settlementCycle) {
this.settlementCycle = settlementCycle;
}
public String getBankCode() {
return bankCode;
}
public void setBankCode(String bankCode) {
this.bankCode = bankCode;
}
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
public boolean isActive() {
return status == MerchantStatus.ACTIVE;
}
}

View file

@ -0,0 +1,77 @@
package com.klaro.acquiring.domain.entity;
import com.klaro.acquiring.domain.enums.PaymentStatus;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import java.time.LocalDate;
/** 지급(py). 정산 결과에 대한 가맹점 계좌 지급. */
@Entity
@Table(name = "payment")
public class Payment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "payment_id")
private Long paymentId;
@Column(name = "settlement_id", nullable = false)
private Long settlementId;
@Column(name = "merch_id", length = 15, nullable = false)
private String merchId;
@Column(name = "pay_date", nullable = false)
private LocalDate payDate;
@Column(name = "amount", precision = 18, scale = 2, nullable = false)
private BigDecimal amount;
@Column(name = "bank_code", length = 3)
private String bankCode;
@Column(name = "account_no", length = 20)
private String accountNo;
@Enumerated(EnumType.STRING)
@Column(name = "status", length = 15, nullable = false)
private PaymentStatus status = PaymentStatus.READY;
protected Payment() {
}
public Payment(Long settlementId, String merchId, LocalDate payDate, BigDecimal amount,
String bankCode, String accountNo) {
this.settlementId = settlementId;
this.merchId = merchId;
this.payDate = payDate;
this.amount = amount;
this.bankCode = bankCode;
this.accountNo = accountNo;
}
public Long getPaymentId() { return paymentId; }
public void setPaymentId(Long paymentId) { this.paymentId = paymentId; }
public Long getSettlementId() { return settlementId; }
public void setSettlementId(Long settlementId) { this.settlementId = settlementId; }
public String getMerchId() { return merchId; }
public void setMerchId(String merchId) { this.merchId = merchId; }
public LocalDate getPayDate() { return payDate; }
public void setPayDate(LocalDate payDate) { this.payDate = payDate; }
public BigDecimal getAmount() { return amount; }
public void setAmount(BigDecimal amount) { this.amount = amount; }
public String getBankCode() { return bankCode; }
public void setBankCode(String bankCode) { this.bankCode = bankCode; }
public String getAccountNo() { return accountNo; }
public void setAccountNo(String accountNo) { this.accountNo = accountNo; }
public PaymentStatus getStatus() { return status; }
public void setStatus(PaymentStatus status) { this.status = status; }
}

View file

@ -0,0 +1,89 @@
package com.klaro.acquiring.domain.entity;
import com.klaro.acquiring.domain.enums.TxStatus;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import java.time.LocalDate;
/** 매입 원장(ac). 승인 건에 대한 매입 접수/청구 결과 + 수수료 분해. */
@Entity
@Table(name = "purchase")
public class Purchase {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "purchase_id")
private Long purchaseId;
@Column(name = "appr_no", length = 12, nullable = false, unique = true)
private String apprNo;
@Column(name = "merch_id", length = 15, nullable = false)
private String merchId;
@Column(name = "card_no", length = 19, nullable = false)
private String cardNo;
@Column(name = "amount", precision = 18, scale = 2, nullable = false)
private BigDecimal amount;
@Column(name = "mdr_fee", precision = 18, scale = 2, nullable = false)
private BigDecimal mdrFee = BigDecimal.ZERO;
@Column(name = "van_fee", precision = 18, scale = 2, nullable = false)
private BigDecimal vanFee = BigDecimal.ZERO;
@Column(name = "net_amount", precision = 18, scale = 2, nullable = false)
private BigDecimal netAmount = BigDecimal.ZERO;
@Column(name = "biz_date", nullable = false)
private LocalDate bizDate;
@Enumerated(EnumType.STRING)
@Column(name = "status", length = 12, nullable = false)
private TxStatus status = TxStatus.RECEIVED;
protected Purchase() {
}
public Purchase(String apprNo, String merchId, String cardNo, BigDecimal amount, LocalDate bizDate) {
this.apprNo = apprNo;
this.merchId = merchId;
this.cardNo = cardNo;
this.amount = amount;
this.bizDate = bizDate;
}
public BigDecimal totalFee() {
return mdrFee.add(vanFee);
}
public Long getPurchaseId() { return purchaseId; }
public void setPurchaseId(Long purchaseId) { this.purchaseId = purchaseId; }
public String getApprNo() { return apprNo; }
public void setApprNo(String apprNo) { this.apprNo = apprNo; }
public String getMerchId() { return merchId; }
public void setMerchId(String merchId) { this.merchId = merchId; }
public String getCardNo() { return cardNo; }
public void setCardNo(String cardNo) { this.cardNo = cardNo; }
public BigDecimal getAmount() { return amount; }
public void setAmount(BigDecimal amount) { this.amount = amount; }
public BigDecimal getMdrFee() { return mdrFee; }
public void setMdrFee(BigDecimal mdrFee) { this.mdrFee = mdrFee; }
public BigDecimal getVanFee() { return vanFee; }
public void setVanFee(BigDecimal vanFee) { this.vanFee = vanFee; }
public BigDecimal getNetAmount() { return netAmount; }
public void setNetAmount(BigDecimal netAmount) { this.netAmount = netAmount; }
public LocalDate getBizDate() { return bizDate; }
public void setBizDate(LocalDate bizDate) { this.bizDate = bizDate; }
public TxStatus getStatus() { return status; }
public void setStatus(TxStatus status) { this.status = status; }
}

View file

@ -0,0 +1,88 @@
package com.klaro.acquiring.domain.entity;
import com.klaro.acquiring.domain.enums.TxStatus;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import java.time.LocalDate;
/** 대사 결과(rc). 승인-매입-입금 3-way 매칭 결과. */
@Entity
@Table(name = "reconcile_result")
public class ReconcileResult {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "recon_id")
private Long reconId;
@Column(name = "biz_date", nullable = false)
private LocalDate bizDate;
@Column(name = "appr_no", length = 12, nullable = false)
private String apprNo;
@Column(name = "merch_id", length = 15, nullable = false)
private String merchId;
@Column(name = "approval_amount", precision = 18, scale = 2, nullable = false)
private BigDecimal approvalAmount = BigDecimal.ZERO;
@Column(name = "purchase_amount", precision = 18, scale = 2, nullable = false)
private BigDecimal purchaseAmount = BigDecimal.ZERO;
@Column(name = "deposit_amount", precision = 18, scale = 2, nullable = false)
private BigDecimal depositAmount = BigDecimal.ZERO;
@Column(name = "diff_amount", precision = 18, scale = 2, nullable = false)
private BigDecimal diffAmount = BigDecimal.ZERO;
@Column(name = "matched", nullable = false)
private boolean matched;
@Enumerated(EnumType.STRING)
@Column(name = "status", length = 12, nullable = false)
private TxStatus status = TxStatus.RECEIVED;
@Column(name = "reason", length = 100)
private String reason;
protected ReconcileResult() {
}
public ReconcileResult(LocalDate bizDate, String apprNo, String merchId) {
this.bizDate = bizDate;
this.apprNo = apprNo;
this.merchId = merchId;
}
public Long getReconId() { return reconId; }
public void setReconId(Long reconId) { this.reconId = reconId; }
public LocalDate getBizDate() { return bizDate; }
public void setBizDate(LocalDate bizDate) { this.bizDate = bizDate; }
public String getApprNo() { return apprNo; }
public void setApprNo(String apprNo) { this.apprNo = apprNo; }
public String getMerchId() { return merchId; }
public void setMerchId(String merchId) { this.merchId = merchId; }
public BigDecimal getApprovalAmount() { return approvalAmount; }
public void setApprovalAmount(BigDecimal approvalAmount) { this.approvalAmount = approvalAmount; }
public BigDecimal getPurchaseAmount() { return purchaseAmount; }
public void setPurchaseAmount(BigDecimal purchaseAmount) { this.purchaseAmount = purchaseAmount; }
public BigDecimal getDepositAmount() { return depositAmount; }
public void setDepositAmount(BigDecimal depositAmount) { this.depositAmount = depositAmount; }
public BigDecimal getDiffAmount() { return diffAmount; }
public void setDiffAmount(BigDecimal diffAmount) { this.diffAmount = diffAmount; }
public boolean isMatched() { return matched; }
public void setMatched(boolean matched) { this.matched = matched; }
public TxStatus getStatus() { return status; }
public void setStatus(TxStatus status) { this.status = status; }
public String getReason() { return reason; }
public void setReason(String reason) { this.reason = reason; }
}

View file

@ -0,0 +1,81 @@
package com.klaro.acquiring.domain.entity;
import com.klaro.acquiring.domain.enums.TxStatus;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import java.math.BigDecimal;
import java.time.LocalDate;
/** 정산(st). 가맹점·영업일 단위 매입 집계 + netting 결과. */
@Entity
@Table(name = "settlement",
uniqueConstraints = @UniqueConstraint(name = "uq_settlement_merch_date",
columnNames = {"merch_id", "biz_date"}))
public class Settlement {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "settlement_id")
private Long settlementId;
@Column(name = "merch_id", length = 15, nullable = false)
private String merchId;
@Column(name = "biz_date", nullable = false)
private LocalDate bizDate;
@Column(name = "gross_amount", precision = 18, scale = 2, nullable = false)
private BigDecimal grossAmount = BigDecimal.ZERO;
@Column(name = "total_fee", precision = 18, scale = 2, nullable = false)
private BigDecimal totalFee = BigDecimal.ZERO;
@Column(name = "net_amount", precision = 18, scale = 2, nullable = false)
private BigDecimal netAmount = BigDecimal.ZERO;
@Column(name = "txn_count", nullable = false)
private int txnCount;
@Column(name = "pay_date", nullable = false)
private LocalDate payDate;
@Enumerated(EnumType.STRING)
@Column(name = "status", length = 12, nullable = false)
private TxStatus status = TxStatus.DONE;
protected Settlement() {
}
public Settlement(String merchId, LocalDate bizDate, LocalDate payDate) {
this.merchId = merchId;
this.bizDate = bizDate;
this.payDate = payDate;
}
public Long getSettlementId() { return settlementId; }
public void setSettlementId(Long settlementId) { this.settlementId = settlementId; }
public String getMerchId() { return merchId; }
public void setMerchId(String merchId) { this.merchId = merchId; }
public LocalDate getBizDate() { return bizDate; }
public void setBizDate(LocalDate bizDate) { this.bizDate = bizDate; }
public BigDecimal getGrossAmount() { return grossAmount; }
public void setGrossAmount(BigDecimal grossAmount) { this.grossAmount = grossAmount; }
public BigDecimal getTotalFee() { return totalFee; }
public void setTotalFee(BigDecimal totalFee) { this.totalFee = totalFee; }
public BigDecimal getNetAmount() { return netAmount; }
public void setNetAmount(BigDecimal netAmount) { this.netAmount = netAmount; }
public int getTxnCount() { return txnCount; }
public void setTxnCount(int txnCount) { this.txnCount = txnCount; }
public LocalDate getPayDate() { return payDate; }
public void setPayDate(LocalDate payDate) { this.payDate = payDate; }
public TxStatus getStatus() { return status; }
public void setStatus(TxStatus status) { this.status = status; }
}

View file

@ -0,0 +1,17 @@
package com.klaro.acquiring.domain.enums;
/** 원장 차변/대변. */
public enum DrCr {
DEBIT("차변"),
CREDIT("대변");
private final String label;
DrCr(String label) {
this.label = label;
}
public String label() {
return label;
}
}

View file

@ -0,0 +1,19 @@
package com.klaro.acquiring.domain.enums;
/** 원장 전표 유형. */
public enum EntryType {
PURCHASE("매입"),
FEE("수수료"),
SETTLEMENT("정산"),
PAYMENT("지급");
private final String label;
EntryType(String label) {
this.label = label;
}
public String label() {
return label;
}
}

View file

@ -0,0 +1,17 @@
package com.klaro.acquiring.domain.enums;
/** 수수료 유형. 매입 건별 수수료 내역 분해에 사용. */
public enum FeeType {
MDR("가맹점 할인수수료"),
VAN("VAN 수수료");
private final String label;
FeeType(String label) {
this.label = label;
}
public String label() {
return label;
}
}

View file

@ -0,0 +1,24 @@
package com.klaro.acquiring.domain.enums;
/** 가맹점 상태. 레거시 merchant.status(CHAR(1)) 대응. */
public enum MerchantStatus {
ACTIVE("A", "정상"),
SUSPENDED("H", "정지"),
CLOSED("C", "해지");
private final String code;
private final String label;
MerchantStatus(String code, String label) {
this.code = code;
this.label = label;
}
public String code() {
return code;
}
public String label() {
return label;
}
}

View file

@ -0,0 +1,19 @@
package com.klaro.acquiring.domain.enums;
/** 지급 상태. */
public enum PaymentStatus {
READY("지급대기"),
FILE_CREATED("지급파일생성"),
PAID("지급완료"),
FAILED("지급실패");
private final String label;
PaymentStatus(String label) {
this.label = label;
}
public String label() {
return label;
}
}

View file

@ -0,0 +1,36 @@
package com.klaro.acquiring.domain.enums;
/**
* 처리 상태코드. 레거시 *_core.h 상태 상수(R/M/U/S) 대응.
*/
public enum TxStatus {
RECEIVED("R", "접수/수신"),
DONE("M", "처리완료"),
FAILED("U", "불일치/실패"),
SETTLED("S", "정산완료");
private final String code;
private final String label;
TxStatus(String code, String label) {
this.code = code;
this.label = label;
}
public String code() {
return code;
}
public String label() {
return label;
}
public static TxStatus fromCode(String code) {
for (TxStatus s : values()) {
if (s.code.equals(code)) {
return s;
}
}
throw new IllegalArgumentException("알 수 없는 상태코드: " + code);
}
}