diff --git a/payments/build.gradle b/payments/build.gradle new file mode 100644 index 0000000..8b021f8 --- /dev/null +++ b/payments/build.gradle @@ -0,0 +1,8 @@ +plugins { + id 'myproject-convention' +} + +dependencies { + implementation project(':shared') +} + diff --git a/payments/src/main/java/com/commerce/payments/PaymentsApplication.java b/payments/src/main/java/com/commerce/payments/PaymentsApplication.java new file mode 100644 index 0000000..d9f424c --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/PaymentsApplication.java @@ -0,0 +1,19 @@ +package com.commerce.payments; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Payments 마이크로서비스 + * gRPC 서버로 동작 + */ +@SpringBootApplication(scanBasePackages = { + "com.commerce.payments", + "com.commerce.shared" +}) +public class PaymentsApplication { + + public static void main(String[] args) { + SpringApplication.run(PaymentsApplication.class, args); + } +} diff --git a/payments/src/main/java/com/commerce/payments/application/port/in/CustomerUseCase.java b/payments/src/main/java/com/commerce/payments/application/port/in/CustomerUseCase.java new file mode 100644 index 0000000..8fc3249 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/application/port/in/CustomerUseCase.java @@ -0,0 +1,6 @@ +package com.commerce.payments.application.port.in; + + +public interface CustomerUseCase { + void registryPayCard(RegistryCardCommand command); +} diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/CustomerUseCaseImpl.java b/payments/src/main/java/com/commerce/payments/application/port/in/CustomerUseCaseImpl.java similarity index 65% rename from platform/src/main/java/com/commerce/platform/core/application/in/CustomerUseCaseImpl.java rename to payments/src/main/java/com/commerce/payments/application/port/in/CustomerUseCaseImpl.java index 7f731d2..6040d9e 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/CustomerUseCaseImpl.java +++ b/payments/src/main/java/com/commerce/payments/application/port/in/CustomerUseCaseImpl.java @@ -1,17 +1,16 @@ -package com.commerce.platform.core.application.in; +package com.commerce.payments.application.port.in; -import com.commerce.platform.core.application.in.dto.RegistryCardCommand; -import com.commerce.platform.core.application.out.CustomerCardOutPort; -import com.commerce.platform.core.domain.aggreate.CustomerCard; -import com.commerce.platform.shared.exception.BusinessException; -import com.commerce.platform.shared.service.AesCryptoFacade; +import com.commerce.payments.application.port.out.CustomerCardOutPort; +import com.commerce.payments.domain.aggregate.CustomerCard; +import com.commerce.shared.exception.BusinessException; +import com.commerce.shared.service.AesCryptoFacade; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Service; -import static com.commerce.platform.shared.exception.BusinessError.DUPLICATED_REGISTRY_CARD; -import static com.commerce.platform.shared.exception.BusinessError.EXCEED_REGISTRY_CARD; +import static com.commerce.shared.exception.BusinessError.DUPLICATED_REGISTRY_CARD; +import static com.commerce.shared.exception.BusinessError.EXCEED_REGISTRY_CARD; @Log4j2 @RequiredArgsConstructor diff --git a/payments/src/main/java/com/commerce/payments/application/port/in/PaymentUseCase.java b/payments/src/main/java/com/commerce/payments/application/port/in/PaymentUseCase.java new file mode 100644 index 0000000..1853000 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/application/port/in/PaymentUseCase.java @@ -0,0 +1,11 @@ +package com.commerce.payments.application.port.in; + + +import com.commerce.payments.application.port.in.dto.PayCancelCommand; +import com.commerce.payments.application.port.in.dto.PayOrderCommand; + +public interface PaymentUseCase { + void doApproval(PayOrderCommand command); + void doCancel(PayCancelCommand cancelCommand); + Long doPartCancel(PayCancelCommand cancelCommand); +} diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/dto/RegistryCardCommand.java b/payments/src/main/java/com/commerce/payments/application/port/in/RegistryCardCommand.java similarity index 61% rename from platform/src/main/java/com/commerce/platform/core/application/in/dto/RegistryCardCommand.java rename to payments/src/main/java/com/commerce/payments/application/port/in/RegistryCardCommand.java index 7e23157..4b5f994 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/dto/RegistryCardCommand.java +++ b/payments/src/main/java/com/commerce/payments/application/port/in/RegistryCardCommand.java @@ -1,7 +1,7 @@ -package com.commerce.platform.core.application.in.dto; +package com.commerce.payments.application.port.in; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.vo.CustomerId; +import com.commerce.payments.domain.enums.PayProvider; +import com.commerce.shared.vo.CustomerId; public record RegistryCardCommand( CustomerId customerId, diff --git a/payments/src/main/java/com/commerce/payments/application/port/in/dto/PayCancelCommand.java b/payments/src/main/java/com/commerce/payments/application/port/in/dto/PayCancelCommand.java new file mode 100644 index 0000000..c0f6747 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/application/port/in/dto/PayCancelCommand.java @@ -0,0 +1,45 @@ +package com.commerce.payments.application.port.in.dto; + +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.domain.enums.PayProvider; +import com.commerce.payments.domain.enums.PaymentStatus; +import com.commerce.payments.domain.enums.PgProvider; +import com.commerce.shared.vo.Money; +import com.commerce.shared.vo.OrderId; +import com.commerce.shared.vo.Quantity; +import lombok.*; + +/** + * 전체/부분 취소 처리 객체 + */ +@Setter +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@Builder +public class PayCancelCommand { + private OrderId orderId; + private Long orderItemId; // 취소할 orderItem + private Quantity canceledQuantity; // 해당 orderItem의 취소 개수 + private PaymentStatus paymentStatus; + private String cancelReason; + + // 이후 계산 및 db데이터 기반으로 세팅됨] + private String pgTid; // pg 승인Tid + private Money canceledAmount; + private PayMethod payMethod; + private PayProvider payProvider; + private PgProvider pgProvider; + + private RefundReceiveAccount refundReceiveAccount; + + /** + * 환불 계좌 정보 (가상계좌 전용) + */ + @Getter + @AllArgsConstructor + public class RefundReceiveAccount { + private String bankCode; + private String accountNumber; + private String holderName; + } +} diff --git a/payments/src/main/java/com/commerce/payments/application/port/in/dto/PayOrderCommand.java b/payments/src/main/java/com/commerce/payments/application/port/in/dto/PayOrderCommand.java new file mode 100644 index 0000000..4315d90 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/application/port/in/dto/PayOrderCommand.java @@ -0,0 +1,21 @@ +package com.commerce.payments.application.port.in.dto; + +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.domain.enums.PayProvider; +import com.commerce.payments.domain.enums.PaymentStatus; +import com.commerce.shared.vo.Money; +import com.commerce.shared.vo.OrderId; +import lombok.*; + +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@Builder +public class PayOrderCommand { + private OrderId orderId; + private Money approvedAmount; + private int installment; + private PayMethod payMethod; + private PayProvider payProvider; + private final PaymentStatus paymentStatus = PaymentStatus.APPROVED; + private String jsonSubData; // pg사 요구 데이터 +} diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/CardBinPromotionOutPort.java b/payments/src/main/java/com/commerce/payments/application/port/out/CardBinPromotionOutPort.java similarity index 50% rename from platform/src/main/java/com/commerce/platform/core/application/out/CardBinPromotionOutPort.java rename to payments/src/main/java/com/commerce/payments/application/port/out/CardBinPromotionOutPort.java index b799be8..29f1048 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/out/CardBinPromotionOutPort.java +++ b/payments/src/main/java/com/commerce/payments/application/port/out/CardBinPromotionOutPort.java @@ -1,6 +1,7 @@ -package com.commerce.platform.core.application.out; +package com.commerce.payments.application.port.out; -import com.commerce.platform.core.domain.aggreate.CardBinPromotion; + +import com.commerce.payments.domain.aggregate.CardBinPromotion; import java.util.List; diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/CustomerCardOutPort.java b/payments/src/main/java/com/commerce/payments/application/port/out/CustomerCardOutPort.java similarity index 57% rename from platform/src/main/java/com/commerce/platform/core/application/out/CustomerCardOutPort.java rename to payments/src/main/java/com/commerce/payments/application/port/out/CustomerCardOutPort.java index cce339e..defd9cb 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/out/CustomerCardOutPort.java +++ b/payments/src/main/java/com/commerce/payments/application/port/out/CustomerCardOutPort.java @@ -1,7 +1,7 @@ -package com.commerce.platform.core.application.out; +package com.commerce.payments.application.port.out; -import com.commerce.platform.core.domain.aggreate.CustomerCard; -import com.commerce.platform.core.domain.vo.CustomerId; +import com.commerce.payments.domain.aggregate.CustomerCard; +import com.commerce.shared.vo.CustomerId; import java.util.Optional; diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/PaymentOutPort.java b/payments/src/main/java/com/commerce/payments/application/port/out/PaymentOutPort.java similarity index 52% rename from platform/src/main/java/com/commerce/platform/core/application/out/PaymentOutPort.java rename to payments/src/main/java/com/commerce/payments/application/port/out/PaymentOutPort.java index 3781d90..bed6820 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/out/PaymentOutPort.java +++ b/payments/src/main/java/com/commerce/payments/application/port/out/PaymentOutPort.java @@ -1,10 +1,10 @@ -package com.commerce.platform.core.application.out; +package com.commerce.payments.application.port.out; -import com.commerce.platform.core.domain.aggreate.Payment; -import com.commerce.platform.core.domain.aggreate.PaymentPartCancel; -import com.commerce.platform.core.domain.vo.Money; -import com.commerce.platform.core.domain.vo.OrderId; -import com.commerce.platform.core.domain.vo.PaymentId; +import com.commerce.payments.domain.aggregate.Payment; +import com.commerce.payments.domain.aggregate.PaymentPartCancel; +import com.commerce.shared.vo.Money; +import com.commerce.shared.vo.OrderId; +import com.commerce.shared.vo.PaymentId; import java.util.Optional; diff --git a/payments/src/main/java/com/commerce/payments/application/port/out/PgStrategy.java b/payments/src/main/java/com/commerce/payments/application/port/out/PgStrategy.java new file mode 100644 index 0000000..41894f8 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/application/port/out/PgStrategy.java @@ -0,0 +1,41 @@ +package com.commerce.payments.application.port.out; + + +import com.commerce.payments.domain.vo.payments.PgPayCancelResponse; +import com.commerce.payments.domain.vo.payments.PgPayResponse; +import com.commerce.payments.application.port.in.dto.PayCancelCommand; +import com.commerce.payments.application.port.in.dto.PayOrderCommand; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.domain.enums.PgProvider; + +/** + * PG사별 결제를 위한 메소드 정의 + */ +public abstract class PgStrategy { + + /** + * 승인 + */ + public abstract PgPayResponse processApproval(PayOrderCommand command); + + /** + * 취소 + */ + public abstract PgPayCancelResponse processCancel(PayCancelCommand command); + + /** + * PG사명 + */ + public abstract PgProvider getPgProvider(); + + /** + * 결제유형 + */ + public abstract PayMethod getPgPayMethod(); + + /** + * 결제창을 위한 초기화 + */ + public abstract Object initPayment(); + +} diff --git a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/CardBinPromotion.java b/payments/src/main/java/com/commerce/payments/domain/aggregate/CardBinPromotion.java similarity index 88% rename from platform/src/main/java/com/commerce/platform/core/domain/aggreate/CardBinPromotion.java rename to payments/src/main/java/com/commerce/payments/domain/aggregate/CardBinPromotion.java index ee8edbe..7a8f707 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/CardBinPromotion.java +++ b/payments/src/main/java/com/commerce/payments/domain/aggregate/CardBinPromotion.java @@ -1,9 +1,9 @@ -package com.commerce.platform.core.domain.aggreate; +package com.commerce.payments.domain.aggregate; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.vo.ValidPeriod; -import com.commerce.platform.core.domain.vo.promotion.BasePromotionData; -import com.commerce.platform.infrastructure.persistence.converter.PromotionDataConverter; +import com.commerce.payments.domain.enums.PayProvider; +import com.commerce.payments.domain.vo.promotion.BasePromotionData; +import com.commerce.payments.infrastructure.persistence.converter.PromotionDataConverter; +import com.commerce.shared.vo.ValidPeriod; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/CustomerCard.java b/payments/src/main/java/com/commerce/payments/domain/aggregate/CustomerCard.java similarity index 91% rename from platform/src/main/java/com/commerce/platform/core/domain/aggreate/CustomerCard.java rename to payments/src/main/java/com/commerce/payments/domain/aggregate/CustomerCard.java index 4a2accf..166d8cf 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/CustomerCard.java +++ b/payments/src/main/java/com/commerce/payments/domain/aggregate/CustomerCard.java @@ -1,9 +1,9 @@ -package com.commerce.platform.core.domain.aggreate; +package com.commerce.payments.domain.aggregate; -import com.commerce.platform.core.application.in.dto.RegistryCardCommand; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.vo.CustomerId; -import com.commerce.platform.shared.service.AesCryptoFacade; +import com.commerce.payments.application.port.in.RegistryCardCommand; +import com.commerce.payments.domain.enums.PayProvider; +import com.commerce.shared.service.AesCryptoFacade; +import com.commerce.shared.vo.CustomerId; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Payment.java b/payments/src/main/java/com/commerce/payments/domain/aggregate/Payment.java similarity index 76% rename from platform/src/main/java/com/commerce/platform/core/domain/aggreate/Payment.java rename to payments/src/main/java/com/commerce/payments/domain/aggregate/Payment.java index 1f431fa..e77e0bb 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Payment.java +++ b/payments/src/main/java/com/commerce/payments/domain/aggregate/Payment.java @@ -1,14 +1,16 @@ -package com.commerce.platform.core.domain.aggreate; - -import com.commerce.platform.core.application.in.dto.PayOrderCommand; -import com.commerce.platform.core.application.out.dto.PgPayResponse; -import com.commerce.platform.core.domain.enums.PayMethod; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.enums.PaymentStatus; -import com.commerce.platform.core.domain.enums.PgProvider; -import com.commerce.platform.core.domain.vo.Money; -import com.commerce.platform.core.domain.vo.OrderId; -import com.commerce.platform.core.domain.vo.PaymentId; +package com.commerce.payments.domain.aggregate; + + +import com.commerce.payments.domain.vo.payments.PgPayCancelResponse; +import com.commerce.payments.domain.vo.payments.PgPayResponse; +import com.commerce.payments.application.port.in.dto.PayOrderCommand; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.domain.enums.PayProvider; +import com.commerce.payments.domain.enums.PaymentStatus; +import com.commerce.payments.domain.enums.PgProvider; +import com.commerce.shared.vo.Money; +import com.commerce.shared.vo.OrderId; +import com.commerce.shared.vo.PaymentId; import jakarta.persistence.*; import lombok.*; @@ -23,6 +25,7 @@ public class Payment { @EmbeddedId + @AttributeOverride(name = "id", column = @Column(name = "id", nullable = false)) private PaymentId paymentId; @Embedded @@ -41,8 +44,8 @@ public class Payment { @Column(name = "pay_provider", length = 10) private PayProvider payProvider; - @Column(name = "installment", length = 2) - private String installment; + @Column(name = "installment", columnDefinition = "TINYINT") + private int installment; // PG 정보 @Enumerated(EnumType.STRING) @@ -96,10 +99,10 @@ public void approved(PgPayResponse pgResponse) { this.paymentStatus = PaymentStatus.APPROVED; } - public void canceled(PgPayResponse pgResponse) { - this.pgCancelTid = pgResponse.pgTid(); + public void canceled(PgPayCancelResponse cancelResponse) { + this.pgCancelTid = cancelResponse.pgCcTid(); - if(!pgResponse.isSuccess()) { + if(!cancelResponse.isSuccess()) { this.paymentStatus = PaymentStatus.FAILED; return; } diff --git a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/PaymentPartCancel.java b/payments/src/main/java/com/commerce/payments/domain/aggregate/PaymentPartCancel.java similarity index 69% rename from platform/src/main/java/com/commerce/platform/core/domain/aggreate/PaymentPartCancel.java rename to payments/src/main/java/com/commerce/payments/domain/aggregate/PaymentPartCancel.java index d92f87c..15b2039 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/PaymentPartCancel.java +++ b/payments/src/main/java/com/commerce/payments/domain/aggregate/PaymentPartCancel.java @@ -1,7 +1,7 @@ -package com.commerce.platform.core.domain.aggreate; +package com.commerce.payments.domain.aggregate; -import com.commerce.platform.core.domain.vo.Money; -import com.commerce.platform.core.domain.vo.PaymentId; +import com.commerce.shared.vo.Money; +import com.commerce.shared.vo.PaymentId; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; @@ -20,19 +20,27 @@ public class PaymentPartCancel { private Long id; @Embedded - @AttributeOverride(name = "id", column = @Column(name = "part_canceled_payment_id", nullable = false)) + @AttributeOverrides({ + @AttributeOverride(name = "id", column = @Column(name = "part_canceled_payment_id", nullable = false)) + }) private PaymentId paymentPartCancelId; @Embedded - @AttributeOverride(name = "id", column = @Column(name = "approved_payment_id", nullable = false)) + @AttributeOverrides({ + @AttributeOverride(name = "id", column = @Column(name = "approved_payment_id", nullable = false)) + }) private PaymentId approvedPaymentId; @Embedded - @AttributeOverride(name = "value", column = @Column(name = "canceled_amt")) + @AttributeOverrides({ + @AttributeOverride(name = "value", column = @Column(name = "canceled_amt", nullable = false)) + }) private Money canceledAmt; @Embedded - @AttributeOverride(name = "value", column = @Column(name = "remain_amt")) + @AttributeOverrides({ + @AttributeOverride(name = "value", column = @Column(name = "remain_amt", nullable = false)) + }) private Money remainAmt; @Column(name = "pg_cancel_tid", length = 100) diff --git a/platform/src/main/java/com/commerce/platform/core/domain/enums/PayMethod.java b/payments/src/main/java/com/commerce/payments/domain/enums/PayMethod.java similarity index 63% rename from platform/src/main/java/com/commerce/platform/core/domain/enums/PayMethod.java rename to payments/src/main/java/com/commerce/payments/domain/enums/PayMethod.java index c6b9f29..e55e887 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/enums/PayMethod.java +++ b/payments/src/main/java/com/commerce/payments/domain/enums/PayMethod.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.enums; +package com.commerce.payments.domain.enums; import lombok.AllArgsConstructor; import lombok.Getter; @@ -8,7 +8,8 @@ public enum PayMethod { CARD("카드결제"), EASY_PAY("간편결제"), - PHONE("휴대폰결제"); + PHONE("휴대폰결제"), + VIRTUAL_ACCOUNT("가상계좌결제"); private final String value; } diff --git a/platform/src/main/java/com/commerce/platform/core/domain/enums/PayProvider.java b/payments/src/main/java/com/commerce/payments/domain/enums/PayProvider.java similarity index 93% rename from platform/src/main/java/com/commerce/platform/core/domain/enums/PayProvider.java rename to payments/src/main/java/com/commerce/payments/domain/enums/PayProvider.java index 0bdf65b..0373240 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/enums/PayProvider.java +++ b/payments/src/main/java/com/commerce/payments/domain/enums/PayProvider.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.enums; +package com.commerce.payments.domain.enums; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/enums/PaymentStatus.java b/payments/src/main/java/com/commerce/payments/domain/enums/PaymentStatus.java similarity index 84% rename from platform/src/main/java/com/commerce/platform/core/domain/enums/PaymentStatus.java rename to payments/src/main/java/com/commerce/payments/domain/enums/PaymentStatus.java index 2a2fcc2..1254a71 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/enums/PaymentStatus.java +++ b/payments/src/main/java/com/commerce/payments/domain/enums/PaymentStatus.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.enums; +package com.commerce.payments.domain.enums; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/enums/PgProvider.java b/payments/src/main/java/com/commerce/payments/domain/enums/PgProvider.java similarity index 91% rename from platform/src/main/java/com/commerce/platform/core/domain/enums/PgProvider.java rename to payments/src/main/java/com/commerce/payments/domain/enums/PgProvider.java index 10d8998..0183ab5 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/enums/PgProvider.java +++ b/payments/src/main/java/com/commerce/payments/domain/enums/PgProvider.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.enums; +package com.commerce.payments.domain.enums; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/enums/TransactionStatus.java b/payments/src/main/java/com/commerce/payments/domain/enums/TransactionStatus.java similarity index 85% rename from platform/src/main/java/com/commerce/platform/core/domain/enums/TransactionStatus.java rename to payments/src/main/java/com/commerce/payments/domain/enums/TransactionStatus.java index 84f7e4b..fef6199 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/enums/TransactionStatus.java +++ b/payments/src/main/java/com/commerce/payments/domain/enums/TransactionStatus.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.enums; +package com.commerce.payments.domain.enums; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/service/PaymentPgRouter.java b/payments/src/main/java/com/commerce/payments/domain/service/PaymentPgRouter.java similarity index 71% rename from platform/src/main/java/com/commerce/platform/core/domain/service/PaymentPgRouter.java rename to payments/src/main/java/com/commerce/payments/domain/service/PaymentPgRouter.java index f73e87a..4dd5f45 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/service/PaymentPgRouter.java +++ b/payments/src/main/java/com/commerce/payments/domain/service/PaymentPgRouter.java @@ -1,12 +1,12 @@ -package com.commerce.platform.core.domain.service; +package com.commerce.payments.domain.service; -import com.commerce.platform.core.application.out.PgStrategy; -import com.commerce.platform.core.domain.enums.PayMethod; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.enums.PgProvider; -import com.commerce.platform.infrastructure.adaptor.PgCacheService; -import com.commerce.platform.infrastructure.persistence.PgFeeInfo; -import com.commerce.platform.infrastructure.persistence.PgFeeInfoRepository; +import com.commerce.payments.application.port.out.PgStrategy; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.domain.enums.PayProvider; +import com.commerce.payments.domain.enums.PgProvider; +import com.commerce.payments.infrastructure.adaptor.PgCacheService; +import com.commerce.payments.infrastructure.persistence.PgFeeInfo; +import com.commerce.payments.infrastructure.persistence.PgFeeInfoRepository; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.event.EventListener; @@ -17,6 +17,7 @@ import java.util.List; import java.util.Map; import java.util.TreeSet; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -28,7 +29,7 @@ @Service public class PaymentPgRouter { - private final Map pgStrategies; + private final Map> pgStrategies; private final PgCacheService pgCacheService; private final PgFeeInfoRepository feeInfoRepository; //결제방식 + 카드사/통신사 별 수수료기준 정렬됨 @@ -36,7 +37,13 @@ public class PaymentPgRouter { public PaymentPgRouter(List list, PgCacheService pgCacheService, PgFeeInfoRepository feeInfoRepository) { this.pgStrategies = list.stream() - .collect(Collectors.toMap(PgStrategy::getPgProvider, pg -> pg)); + .collect(Collectors.groupingBy( + PgStrategy::getPgProvider, + Collectors.toMap( + PgStrategy::getPgPayMethod, + Function.identity() + ) + )); this.pgCacheService = pgCacheService; this.feeInfoRepository = feeInfoRepository; } @@ -62,20 +69,19 @@ public PgStrategy routePg(PayMethod payMethod, PayProvider payProvider) { throw new IllegalStateException("현재 사용 가능한 PG사가 없습니다"); } - return pgStrategies.get(selectedPg); + return pgStrategies.get(selectedPg).get(payMethod); } /** - * PG Provider => Strategy bean 추출 + * PG Provider => Strategy 조회 */ - public PgStrategy getPgStrategyByProvider(PgProvider pgProvider) { - PgStrategy strategy = pgStrategies.get(pgProvider); + public PgStrategy getPgStrategyByProvider(PgProvider pgProvider, PayMethod payMethod) { + PgStrategy strategy = pgStrategies.get(pgProvider).get(payMethod); if (strategy == null) { throw new IllegalArgumentException("존재하지 않는 PG: " + pgProvider); } return strategy; } - @Scheduled(cron = "0 * * * * *") private void refreshPgCache() { setPgFeeCache(); diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/PaymentUseCaseImpl.java b/payments/src/main/java/com/commerce/payments/domain/service/PaymentUseCaseImpl.java similarity index 50% rename from platform/src/main/java/com/commerce/platform/core/application/in/PaymentUseCaseImpl.java rename to payments/src/main/java/com/commerce/payments/domain/service/PaymentUseCaseImpl.java index fac2c46..060a92a 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/PaymentUseCaseImpl.java +++ b/payments/src/main/java/com/commerce/payments/domain/service/PaymentUseCaseImpl.java @@ -1,55 +1,58 @@ -package com.commerce.platform.core.application.in; - -import com.commerce.platform.core.application.in.dto.PayCancelCommand; -import com.commerce.platform.core.application.in.dto.PayOrderCommand; -import com.commerce.platform.core.application.out.*; -import com.commerce.platform.core.application.out.dto.PgPayResponse; -import com.commerce.platform.core.domain.aggreate.*; -import com.commerce.platform.core.domain.service.PaymentPgRouter; -import com.commerce.platform.core.domain.vo.Money; -import com.commerce.platform.shared.exception.BusinessError; -import com.commerce.platform.shared.exception.BusinessException; +package com.commerce.payments.domain.service; + +import com.commerce.payments.domain.vo.payments.PgPayCancelResponse; +import com.commerce.payments.domain.vo.payments.PgPayResponse; +import com.commerce.payments.application.port.in.PaymentUseCase; +import com.commerce.payments.application.port.in.dto.PayCancelCommand; +import com.commerce.payments.application.port.in.dto.PayOrderCommand; +import com.commerce.payments.application.port.out.PaymentOutPort; +import com.commerce.payments.application.port.out.PgStrategy; +import com.commerce.payments.domain.aggregate.Payment; +import com.commerce.payments.domain.aggregate.PaymentPartCancel; +import com.commerce.shared.exception.BusinessError; +import com.commerce.shared.exception.BusinessException; +import com.commerce.shared.vo.Money; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; -import java.util.Optional; - -import static com.commerce.platform.shared.exception.BusinessError.*; +import static com.commerce.shared.exception.BusinessError.*; @Log4j2 @RequiredArgsConstructor @Service -public class PaymentUseCaseImpl implements PaymentUseCase{ +public class PaymentUseCaseImpl implements PaymentUseCase { private final PaymentPgRouter pgRouter; private final PaymentOutPort paymentOutPort; - private final OrderOutputPort orderOutputPort; - private final OrderItemOutPort orderItemOutPort; - private final ProductOutputPort productOutputPort; - private final CustomerCardOutPort customerCardOutPort; +// private final OrderOutputPort orderOutputPort; +// private final OrderItemOutPort orderItemOutPort; +// private final ProductOutputPort productOutputPort; +// private final CustomerCardOutPort customerCardOutPort; @Override @Transactional public void doApproval(PayOrderCommand payOrdercommand) { // 주문 결제처리 - Order orderEntity = orderOutputPort.findById(payOrdercommand.getOrderId()) - .orElseThrow(() -> new BusinessException(INVALID_ORDER_ID)); - orderEntity.validForPay(); +// Order orderEntity = orderOutputPort.findById(payOrdercommand.getOrderId()) +// .orElseThrow(() -> new BusinessException(INVALID_ORDER_ID)); +// orderEntity.validForPay(); + +// Order orderEntity = null; // pg사 라우팅 PgStrategy pgStrategy = pgRouter.routePg(payOrdercommand.getPayMethod(), payOrdercommand.getPayProvider()); // 결재 entity 생성 - payOrdercommand.setApprovedAmount(orderEntity.getResultAmt()); Payment paymentEntity = Payment.create(payOrdercommand, pgStrategy.getPgProvider()); // pg 결제 응답 수신 PgPayResponse pgResponse = pgStrategy.processApproval(payOrdercommand); + validRequestAmount(payOrdercommand.getApprovedAmount(), pgResponse.amount().value()); + // 결제 결과에 따른 주문/결제 상태 변경 - orderEntity.changeStatusAfterPay(pgResponse); +// orderEntity.changeStatusAfterPay(pgResponse); paymentEntity.approved(pgResponse); paymentOutPort.savePayment(paymentEntity); @@ -65,12 +68,12 @@ public void doApproval(PayOrderCommand payOrdercommand) { public void doCancel(PayCancelCommand cancelCommand) { // 주문 검증 - Order orderEntity = orderOutputPort.findById(cancelCommand.getOrderId()) - .orElseThrow(() -> new BusinessException(INVALID_ORDER_ID)); - orderEntity.validateForCancel(); +// Order orderEntity = orderOutputPort.findById(cancelCommand.getOrderId()) +// .orElseThrow(() -> new BusinessException(INVALID_ORDER_ID)); +// orderEntity.validateForCancel(); // 결제 검증 - Payment paymentEntity = paymentOutPort.findByOrderId(orderEntity.getOrderId()) + Payment paymentEntity = paymentOutPort.findByOrderId(cancelCommand.getOrderId()) .orElseThrow(() -> new BusinessException(INVALID_PAYMENT)); paymentEntity.validateForCancel(); @@ -80,20 +83,23 @@ public void doCancel(PayCancelCommand cancelCommand) { throw new BusinessException(BusinessError.PAYMENT_HAS_PARTIAL_CANCEL); } - cancelCommand.setCanceledAmount(orderEntity.getResultAmt()); + cancelCommand.setCanceledAmount(cancelCommand.getCanceledAmount()); cancelCommand.setPayProvider(paymentEntity.getPayProvider()); cancelCommand.setPayMethod(paymentEntity.getPayMethod()); cancelCommand.setPgProvider(paymentEntity.getPgProvider()); - PgStrategy pgStrategy = pgRouter.getPgStrategyByProvider(paymentEntity.getPgProvider()); - PgPayResponse pgResponse = pgStrategy.processCancel(cancelCommand); + PgStrategy pgStrategy = pgRouter.getPgStrategyByProvider(paymentEntity.getPgProvider(), paymentEntity.getPayMethod()); + PgPayCancelResponse pgResponse = pgStrategy.processCancel(cancelCommand); // PG 응답 반영 if (!pgResponse.isSuccess()) { throw new BusinessException(PG_RESPONSE_FAILED); } - orderEntity.refund(); + // Pg취소금액, 요청취소금액 검증 + validRequestAmount(cancelCommand.getCanceledAmount(), pgResponse.cancelAmount()); + +// orderEntity.refund(); paymentEntity.canceled(pgResponse); paymentOutPort.savePayment(paymentEntity); } @@ -105,12 +111,12 @@ public void doCancel(PayCancelCommand cancelCommand) { @Transactional public Long doPartCancel(PayCancelCommand cancelCommand) { // 주문 검정 - Order orderEntity = orderOutputPort.findById(cancelCommand.getOrderId()) - .orElseThrow(() -> new BusinessException(INVALID_ORDER_ID)); - orderEntity.validateForCancel(); +// Order orderEntity = orderOutputPort.findById(cancelCommand.getOrderId()) +// .orElseThrow(() -> new BusinessException(INVALID_ORDER_ID)); +// orderEntity.validateForCancel(); // 결제 검증 - Payment paymentEntity = paymentOutPort.findByOrderId(orderEntity.getOrderId()) + Payment paymentEntity = paymentOutPort.findByOrderId(cancelCommand.getOrderId()) .orElseThrow(() -> new BusinessException(INVALID_PAYMENT)); paymentEntity.validateForCancel(); @@ -129,28 +135,28 @@ public Long doPartCancel(PayCancelCommand cancelCommand) { } // 부분취소 가능수량 검증 - OrderItem orderItemEntity = orderItemOutPort.findById(cancelCommand.getOrderItemId()) - .orElseThrow(() -> new BusinessException(INVALID_ORDER_ITEM_ID)); - // 해당 건 삭제처리 - orderItemEntity.canceledItem(cancelCommand.getCanceledQuantity()); - // 새롭게 행 생성한다. - OrderItem refreshOrderItem = OrderItem.create(cancelCommand.getOrderId(), - orderItemEntity.getProductId(), - orderItemEntity.getQuantity().minus(cancelCommand.getCanceledQuantity())); - orderItemOutPort.saveAll(List.of(refreshOrderItem)); +// OrderItem orderItemEntity = orderItemOutPort.findById(cancelCommand.getOrderItemId()) +// .orElseThrow(() -> new BusinessException(INVALID_ORDER_ITEM_ID)); +// // 해당 건 삭제처리 +// orderItemEntity.canceledItem(cancelCommand.getCanceledQuantity()); +// // 새롭게 행 생성한다. +// OrderItem refreshOrderItem = OrderItem.create(cancelCommand.getOrderId(), +// orderItemEntity.getProductId(), +// orderItemEntity.getQuantity().minus(cancelCommand.getCanceledQuantity())); +// orderItemOutPort.saveAll(List.of(refreshOrderItem)); // 취소금액 계산 - Money canceledAmt = productOutputPort.findById(orderItemEntity.getProductId()) - .get() - .getPrice().multiply(cancelCommand.getCanceledQuantity()); +// Money canceledAmt = productOutputPort.findById(orderItemEntity.getProductId()) +// .get() +// .getPrice().multiply(cancelCommand.getCanceledQuantity()); - cancelCommand.setCanceledAmount(canceledAmt); + cancelCommand.setCanceledAmount(cancelCommand.getCanceledAmount()); cancelCommand.setPayProvider(paymentEntity.getPayProvider()); cancelCommand.setPayMethod(paymentEntity.getPayMethod()); cancelCommand.setPgProvider(paymentEntity.getPgProvider()); // 최종 남은금액 - Money refreshRemainAmt = remainAmt.subtract(canceledAmt); + Money refreshRemainAmt = remainAmt.subtract(cancelCommand.getCanceledAmount()); // 취소 요청 cancelCommand.setCanceledAmount(paymentEntity.getApprovedAmt()); @@ -158,34 +164,35 @@ public Long doPartCancel(PayCancelCommand cancelCommand) { cancelCommand.setPayMethod(paymentEntity.getPayMethod()); cancelCommand.setPgProvider(paymentEntity.getPgProvider()); - PgStrategy pgStrategy = pgRouter.getPgStrategyByProvider(paymentEntity.getPgProvider()); - PgPayResponse pgResponse = pgStrategy.processCancel(cancelCommand); + PgStrategy pgStrategy = pgRouter.getPgStrategyByProvider(paymentEntity.getPgProvider(), paymentEntity.getPayMethod()); + PgPayCancelResponse pgResponse = pgStrategy.processCancel(cancelCommand); if (!pgResponse.isSuccess()) { throw new BusinessException(PG_RESPONSE_FAILED); } + validRequestAmount(cancelCommand.getCanceledAmount(), pgResponse.cancelAmount()); + // 부분취소 내역 저장 PaymentPartCancel partCancel = PaymentPartCancel.create( paymentEntity.getPaymentId(), - canceledAmt, + cancelCommand.getCanceledAmount(), refreshRemainAmt ); - partCancel.completed(pgResponse.pgTid()); + partCancel.completed(pgResponse.pgCcTid()); paymentOutPort.savePartCancel(partCancel); return partCancel.getId(); } /** - * 등록된 카드로 결제 - * @param cardId + * pg 요청금액 , 고객 요청금액 동일 검증 + * @param customerRequestAmt + * @param pgResponseAmt */ - @Override - public void doApprovalWithCardId(Long cardId) { - CustomerCard customerCard = customerCardOutPort.findActiveById(cardId) - .orElseThrow(() -> new BusinessException(INVALID_ORDER_ID)); - + private void validRequestAmount(Money customerRequestAmt, Long pgResponseAmt) { + if(customerRequestAmt.value() != pgResponseAmt) { + throw new RuntimeException("요청금액 불일치"); + } } - } diff --git a/payments/src/main/java/com/commerce/payments/domain/vo/payments/PgPayCancelResponse.java b/payments/src/main/java/com/commerce/payments/domain/vo/payments/PgPayCancelResponse.java new file mode 100644 index 0000000..412418a --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/domain/vo/payments/PgPayCancelResponse.java @@ -0,0 +1,16 @@ +package com.commerce.payments.domain.vo.payments; + +import lombok.Builder; + +/** + * pg서 취소 응답 결과 DTO + */ +@Builder +public record PgPayCancelResponse( + String pgCcTid, + String responseCode, // pg사 응답코드 + String responseMessage, // pg사 응답메시지 + String cancelReason, // 취소사유 + Long cancelAmount, // 취소 금액 + boolean isSuccess +) { } diff --git a/payments/src/main/java/com/commerce/payments/domain/vo/payments/PgPayResponse.java b/payments/src/main/java/com/commerce/payments/domain/vo/payments/PgPayResponse.java new file mode 100644 index 0000000..c248f23 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/domain/vo/payments/PgPayResponse.java @@ -0,0 +1,43 @@ +package com.commerce.payments.domain.vo.payments; + +import com.commerce.shared.vo.Money; +import lombok.Builder; + +/** + * pg서 승인 응답 결과 DTO + * 결제유형에 따라 card/easyPay/virtualAccount 필드 세팅된다. + */ +@Builder +public record PgPayResponse ( + String pgTid, + String responseCode, // pg사 응답코드 + String responseMessage, // pg사 응답메시지 + Money amount, + boolean isSuccess, + Card card, // 카드결제 응답 + EasyPay easyPay, // 간편결제 응답 + VirtualAccount virtualAccount // 가상계좌 응답 +) { + @Builder + public record Card( + String approveNo, + String issuerCode, + String cardType + ) {} + + @Builder + public record EasyPay( + String provider, + String amount, + String discountAmount + ) {} + + @Builder + public record VirtualAccount( + String accountType, + String accountNumber, + String bankCode, + String depositorName, + String dueDate + ) {} +} diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/BasePromotionData.java b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/BasePromotionData.java similarity index 74% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/BasePromotionData.java rename to payments/src/main/java/com/commerce/payments/domain/vo/promotion/BasePromotionData.java index 8eb9907..2e427bd 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/BasePromotionData.java +++ b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/BasePromotionData.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.vo.promotion; +package com.commerce.payments.domain.vo.promotion; /** * 카드사별 프로모션 데이터 인터페이스 diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/BcPromotionData.java b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/BcPromotionData.java similarity index 79% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/BcPromotionData.java rename to payments/src/main/java/com/commerce/payments/domain/vo/promotion/BcPromotionData.java index 70a44c7..e7308ca 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/BcPromotionData.java +++ b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/BcPromotionData.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.vo.promotion; +package com.commerce.payments.domain.vo.promotion; import lombok.Builder; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/HanaPromotionData.java b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/HanaPromotionData.java similarity index 80% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/HanaPromotionData.java rename to payments/src/main/java/com/commerce/payments/domain/vo/promotion/HanaPromotionData.java index 00abb9f..0152b1f 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/HanaPromotionData.java +++ b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/HanaPromotionData.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.vo.promotion; +package com.commerce.payments.domain.vo.promotion; import lombok.Builder; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/HyundaiPromotionData.java b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/HyundaiPromotionData.java similarity index 81% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/HyundaiPromotionData.java rename to payments/src/main/java/com/commerce/payments/domain/vo/promotion/HyundaiPromotionData.java index 9376abe..2a8baab 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/HyundaiPromotionData.java +++ b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/HyundaiPromotionData.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.vo.promotion; +package com.commerce.payments.domain.vo.promotion; import lombok.Builder; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/KbPromotionData.java b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/KbPromotionData.java similarity index 79% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/KbPromotionData.java rename to payments/src/main/java/com/commerce/payments/domain/vo/promotion/KbPromotionData.java index a63d3d3..41232eb 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/KbPromotionData.java +++ b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/KbPromotionData.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.vo.promotion; +package com.commerce.payments.domain.vo.promotion; import lombok.Builder; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/LottePromotionData.java b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/LottePromotionData.java similarity index 80% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/LottePromotionData.java rename to payments/src/main/java/com/commerce/payments/domain/vo/promotion/LottePromotionData.java index 1e8cdac..dd392cb 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/LottePromotionData.java +++ b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/LottePromotionData.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.vo.promotion; +package com.commerce.payments.domain.vo.promotion; import lombok.Builder; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/NhPromotionData.java b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/NhPromotionData.java similarity index 79% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/NhPromotionData.java rename to payments/src/main/java/com/commerce/payments/domain/vo/promotion/NhPromotionData.java index 7200eba..7b1c765 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/NhPromotionData.java +++ b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/NhPromotionData.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.vo.promotion; +package com.commerce.payments.domain.vo.promotion; import lombok.Builder; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/SamsungPromotionData.java b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/SamsungPromotionData.java similarity index 81% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/SamsungPromotionData.java rename to payments/src/main/java/com/commerce/payments/domain/vo/promotion/SamsungPromotionData.java index 256b9bc..dcb9995 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/SamsungPromotionData.java +++ b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/SamsungPromotionData.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.vo.promotion; +package com.commerce.payments.domain.vo.promotion; import lombok.Builder; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/ShinhanPromotionData.java b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/ShinhanPromotionData.java similarity index 81% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/ShinhanPromotionData.java rename to payments/src/main/java/com/commerce/payments/domain/vo/promotion/ShinhanPromotionData.java index 6034ec8..514bb97 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/promotion/ShinhanPromotionData.java +++ b/payments/src/main/java/com/commerce/payments/domain/vo/promotion/ShinhanPromotionData.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.domain.vo.promotion; +package com.commerce.payments.domain.vo.promotion; import lombok.Builder; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CardBinPromotionAdaptor.java b/payments/src/main/java/com/commerce/payments/infrastructure/adaptor/CardBinPromotionAdaptor.java similarity index 74% rename from platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CardBinPromotionAdaptor.java rename to payments/src/main/java/com/commerce/payments/infrastructure/adaptor/CardBinPromotionAdaptor.java index 9304353..9807340 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CardBinPromotionAdaptor.java +++ b/payments/src/main/java/com/commerce/payments/infrastructure/adaptor/CardBinPromotionAdaptor.java @@ -1,9 +1,10 @@ -package com.commerce.platform.infrastructure.adaptor; +package com.commerce.payments.infrastructure.adaptor; -import com.commerce.platform.core.application.out.CardBinPromotionOutPort; -import com.commerce.platform.core.domain.aggreate.CardBinPromotion; -import com.commerce.platform.infrastructure.persistence.CardBinPromotionRepository; -import com.commerce.platform.infrastructure.persistence.processor.PromotionDataPostProcessor; + +import com.commerce.payments.application.port.out.CardBinPromotionOutPort; +import com.commerce.payments.domain.aggregate.CardBinPromotion; +import com.commerce.payments.infrastructure.persistence.CardBinPromotionRepository; +import com.commerce.payments.infrastructure.persistence.processor.PromotionDataPostProcessor; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Component; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CustomerCardAdaptor.java b/payments/src/main/java/com/commerce/payments/infrastructure/adaptor/CustomerCardAdaptor.java similarity index 69% rename from platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CustomerCardAdaptor.java rename to payments/src/main/java/com/commerce/payments/infrastructure/adaptor/CustomerCardAdaptor.java index 7a27fed..8465c6e 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CustomerCardAdaptor.java +++ b/payments/src/main/java/com/commerce/payments/infrastructure/adaptor/CustomerCardAdaptor.java @@ -1,9 +1,9 @@ -package com.commerce.platform.infrastructure.adaptor; +package com.commerce.payments.infrastructure.adaptor; -import com.commerce.platform.core.application.out.CustomerCardOutPort; -import com.commerce.platform.core.domain.aggreate.CustomerCard; -import com.commerce.platform.core.domain.vo.CustomerId; -import com.commerce.platform.infrastructure.persistence.CustomerCardRepository; +import com.commerce.payments.application.port.out.CustomerCardOutPort; +import com.commerce.payments.domain.aggregate.CustomerCard; +import com.commerce.payments.infrastructure.persistence.CustomerCardRepository; +import com.commerce.shared.vo.CustomerId; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/PaymentAdaptor.java b/payments/src/main/java/com/commerce/payments/infrastructure/adaptor/PaymentAdaptor.java similarity index 68% rename from platform/src/main/java/com/commerce/platform/infrastructure/adaptor/PaymentAdaptor.java rename to payments/src/main/java/com/commerce/payments/infrastructure/adaptor/PaymentAdaptor.java index 7f1234b..04818d4 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/PaymentAdaptor.java +++ b/payments/src/main/java/com/commerce/payments/infrastructure/adaptor/PaymentAdaptor.java @@ -1,13 +1,13 @@ -package com.commerce.platform.infrastructure.adaptor; - -import com.commerce.platform.core.application.out.PaymentOutPort; -import com.commerce.platform.core.domain.aggreate.Payment; -import com.commerce.platform.core.domain.aggreate.PaymentPartCancel; -import com.commerce.platform.core.domain.vo.Money; -import com.commerce.platform.core.domain.vo.OrderId; -import com.commerce.platform.core.domain.vo.PaymentId; -import com.commerce.platform.infrastructure.persistence.PaymentPartCancelRepository; -import com.commerce.platform.infrastructure.persistence.PaymentRepository; +package com.commerce.payments.infrastructure.adaptor; + +import com.commerce.payments.application.port.out.PaymentOutPort; +import com.commerce.payments.domain.aggregate.Payment; +import com.commerce.payments.domain.aggregate.PaymentPartCancel; +import com.commerce.payments.infrastructure.persistence.PaymentPartCancelRepository; +import com.commerce.payments.infrastructure.persistence.PaymentRepository; +import com.commerce.shared.vo.Money; +import com.commerce.shared.vo.OrderId; +import com.commerce.shared.vo.PaymentId; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/PgCacheService.java b/payments/src/main/java/com/commerce/payments/infrastructure/adaptor/PgCacheService.java similarity index 89% rename from platform/src/main/java/com/commerce/platform/infrastructure/adaptor/PgCacheService.java rename to payments/src/main/java/com/commerce/payments/infrastructure/adaptor/PgCacheService.java index 56437f4..0badc38 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/PgCacheService.java +++ b/payments/src/main/java/com/commerce/payments/infrastructure/adaptor/PgCacheService.java @@ -1,6 +1,6 @@ -package com.commerce.platform.infrastructure.adaptor; +package com.commerce.payments.infrastructure.adaptor; -import com.commerce.platform.core.domain.enums.PgProvider; +import com.commerce.payments.domain.enums.PgProvider; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.StringRedisTemplate; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/CardBinPromotionRepository.java b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/CardBinPromotionRepository.java similarity index 82% rename from platform/src/main/java/com/commerce/platform/infrastructure/persistence/CardBinPromotionRepository.java rename to payments/src/main/java/com/commerce/payments/infrastructure/persistence/CardBinPromotionRepository.java index 6ae72ae..a0b1df8 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/CardBinPromotionRepository.java +++ b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/CardBinPromotionRepository.java @@ -1,6 +1,6 @@ -package com.commerce.platform.infrastructure.persistence; +package com.commerce.payments.infrastructure.persistence; -import com.commerce.platform.core.domain.aggreate.CardBinPromotion; +import com.commerce.payments.domain.aggregate.CardBinPromotion; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/CustomerCardRepository.java b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/CustomerCardRepository.java similarity index 77% rename from platform/src/main/java/com/commerce/platform/infrastructure/persistence/CustomerCardRepository.java rename to payments/src/main/java/com/commerce/payments/infrastructure/persistence/CustomerCardRepository.java index c904a47..f5fa512 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/CustomerCardRepository.java +++ b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/CustomerCardRepository.java @@ -1,7 +1,7 @@ -package com.commerce.platform.infrastructure.persistence; +package com.commerce.payments.infrastructure.persistence; -import com.commerce.platform.core.domain.aggreate.CustomerCard; -import com.commerce.platform.core.domain.vo.CustomerId; +import com.commerce.payments.domain.aggregate.CustomerCard; +import com.commerce.shared.vo.CustomerId; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/PaymentPartCancelRepository.java b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/PaymentPartCancelRepository.java similarity index 72% rename from platform/src/main/java/com/commerce/platform/infrastructure/persistence/PaymentPartCancelRepository.java rename to payments/src/main/java/com/commerce/payments/infrastructure/persistence/PaymentPartCancelRepository.java index f5f25bb..4620a44 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/PaymentPartCancelRepository.java +++ b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/PaymentPartCancelRepository.java @@ -1,8 +1,8 @@ -package com.commerce.platform.infrastructure.persistence; +package com.commerce.payments.infrastructure.persistence; -import com.commerce.platform.core.domain.aggreate.PaymentPartCancel; -import com.commerce.platform.core.domain.vo.Money; -import com.commerce.platform.core.domain.vo.PaymentId; +import com.commerce.payments.domain.aggregate.PaymentPartCancel; +import com.commerce.shared.vo.Money; +import com.commerce.shared.vo.PaymentId; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/PaymentRepository.java b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/PaymentRepository.java similarity index 64% rename from platform/src/main/java/com/commerce/platform/infrastructure/persistence/PaymentRepository.java rename to payments/src/main/java/com/commerce/payments/infrastructure/persistence/PaymentRepository.java index cedcf31..5413257 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/PaymentRepository.java +++ b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/PaymentRepository.java @@ -1,8 +1,8 @@ -package com.commerce.platform.infrastructure.persistence; +package com.commerce.payments.infrastructure.persistence; -import com.commerce.platform.core.domain.aggreate.Payment; -import com.commerce.platform.core.domain.vo.OrderId; -import com.commerce.platform.core.domain.vo.PaymentId; +import com.commerce.payments.domain.aggregate.Payment; +import com.commerce.shared.vo.OrderId; +import com.commerce.shared.vo.PaymentId; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/PgFeeInfo.java b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/PgFeeInfo.java similarity index 88% rename from platform/src/main/java/com/commerce/platform/infrastructure/persistence/PgFeeInfo.java rename to payments/src/main/java/com/commerce/payments/infrastructure/persistence/PgFeeInfo.java index af88443..f55a009 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/PgFeeInfo.java +++ b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/PgFeeInfo.java @@ -1,8 +1,8 @@ -package com.commerce.platform.infrastructure.persistence; +package com.commerce.payments.infrastructure.persistence; -import com.commerce.platform.core.domain.enums.PayMethod; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.enums.PgProvider; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.domain.enums.PayProvider; +import com.commerce.payments.domain.enums.PgProvider; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/PgFeeInfoRepository.java b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/PgFeeInfoRepository.java similarity index 86% rename from platform/src/main/java/com/commerce/platform/infrastructure/persistence/PgFeeInfoRepository.java rename to payments/src/main/java/com/commerce/payments/infrastructure/persistence/PgFeeInfoRepository.java index c3df13d..979a657 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/PgFeeInfoRepository.java +++ b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/PgFeeInfoRepository.java @@ -1,7 +1,7 @@ -package com.commerce.platform.infrastructure.persistence; +package com.commerce.payments.infrastructure.persistence; -import com.commerce.platform.core.domain.enums.PayMethod; -import com.commerce.platform.core.domain.enums.PayProvider; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.domain.enums.PayProvider; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/converter/PromotionDataConverter.java b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/converter/PromotionDataConverter.java similarity index 91% rename from platform/src/main/java/com/commerce/platform/infrastructure/persistence/converter/PromotionDataConverter.java rename to payments/src/main/java/com/commerce/payments/infrastructure/persistence/converter/PromotionDataConverter.java index 2963542..24be68d 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/converter/PromotionDataConverter.java +++ b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/converter/PromotionDataConverter.java @@ -1,6 +1,6 @@ -package com.commerce.platform.infrastructure.persistence.converter; +package com.commerce.payments.infrastructure.persistence.converter; -import com.commerce.platform.core.domain.vo.promotion.BasePromotionData; +import com.commerce.payments.domain.vo.promotion.BasePromotionData; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/processor/PromotionDataPostProcessor.java b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/processor/PromotionDataPostProcessor.java similarity index 90% rename from platform/src/main/java/com/commerce/platform/infrastructure/persistence/processor/PromotionDataPostProcessor.java rename to payments/src/main/java/com/commerce/payments/infrastructure/persistence/processor/PromotionDataPostProcessor.java index d227858..3108377 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/processor/PromotionDataPostProcessor.java +++ b/payments/src/main/java/com/commerce/payments/infrastructure/persistence/processor/PromotionDataPostProcessor.java @@ -1,9 +1,9 @@ -package com.commerce.platform.infrastructure.persistence.processor; +package com.commerce.payments.infrastructure.persistence.processor; -import com.commerce.platform.core.domain.aggreate.CardBinPromotion; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.vo.promotion.*; -import com.commerce.platform.infrastructure.persistence.converter.PromotionDataConverter; +import com.commerce.payments.domain.aggregate.CardBinPromotion; +import com.commerce.payments.domain.vo.promotion.*; +import com.commerce.payments.domain.enums.PayProvider; +import com.commerce.payments.infrastructure.persistence.converter.PromotionDataConverter; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/danal/DanalPhoneService.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/danal/DanalPhoneService.java new file mode 100644 index 0000000..df76634 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/danal/DanalPhoneService.java @@ -0,0 +1,17 @@ +package com.commerce.payments.infrastructure.pg.danal; + +import com.commerce.payments.domain.enums.PayMethod; +import org.springframework.stereotype.Service; + +@Service +public class DanalPhoneService extends DanalStrategy{ + @Override + protected PayMethod getDanalPayMethod() { + return PayMethod.PHONE; + } + + @Override + public Object initPayment() { + return null; + } +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/danal/DanalStrategy.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/danal/DanalStrategy.java new file mode 100644 index 0000000..1d2428d --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/danal/DanalStrategy.java @@ -0,0 +1,44 @@ +package com.commerce.payments.infrastructure.pg.danal; + + +import com.commerce.payments.application.port.in.dto.PayCancelCommand; +import com.commerce.payments.application.port.in.dto.PayOrderCommand; +import com.commerce.payments.application.port.out.PgStrategy; +import com.commerce.payments.domain.vo.payments.PgPayCancelResponse; +import com.commerce.payments.domain.vo.payments.PgPayResponse; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.domain.enums.PgProvider; + +/** + * 여기서 필요에 따라 다날의 결제수단별 프로세스를 추상화한다. + */ +public abstract class DanalStrategy extends PgStrategy { + + @Override + public PgPayResponse processApproval(PayOrderCommand command) { + return null; + } + + @Override + public PgPayCancelResponse processCancel(PayCancelCommand command) { + return null; + } + + + @Override + public PgProvider getPgProvider() { + return PgProvider.DANAL; + } + + @Override + public PayMethod getPgPayMethod() { + return getDanalPayMethod(); + } + + /** + * Danal 구현체 중 특정 결제서비스 빈 추출을 위함 + * @return + */ + protected abstract PayMethod getDanalPayMethod(); + +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/NHNStrategy.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/NHNStrategy.java new file mode 100644 index 0000000..d86f740 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/NHNStrategy.java @@ -0,0 +1,143 @@ +package com.commerce.payments.infrastructure.pg.nhn; + +import com.commerce.payments.application.port.in.dto.PayCancelCommand; +import com.commerce.payments.application.port.in.dto.PayOrderCommand; +import com.commerce.payments.application.port.out.PgStrategy; +import com.commerce.payments.domain.vo.payments.PgPayCancelResponse; +import com.commerce.payments.domain.vo.payments.PgPayResponse; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.domain.enums.PaymentStatus; +import com.commerce.payments.domain.enums.PgProvider; +import com.commerce.payments.infrastructure.pg.nhn.dto.NhnApprovalRequest; +import com.commerce.payments.infrastructure.pg.nhn.dto.NhnApprovalResponse; +import com.commerce.payments.infrastructure.pg.nhn.dto.NhnCancelRequest; +import com.commerce.payments.infrastructure.pg.nhn.dto.NhnCancelResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +/** + * 결제유형별 특정 파라미터 값 구분 필요. + * 응답 개별 파싱 필요 + * + * 여기서 필요에 따라 NHN의 결제수단별 프로세스를 추상화한다. + */ +@Component +@RequiredArgsConstructor +public abstract class NHNStrategy extends PgStrategy { + private final RestTemplate restTemplate; + private static final String NHN_CONFIRM_URL = "https://stg-spl.kcp.co.kr/gw/enc/v1/payment"; + private static final String NHN_CANCEL_URL = "https://stg-spl.kcp.co.kr/gw/mod/v1/cancel"; + private final String SITE_CD = "T0000"; // 상점코드 + + /** + * 공통 승인 요청 + */ + @Override + public PgPayResponse processApproval(PayOrderCommand command) { + // 승인 요청객체 생성 + NhnApprovalRequest request = NhnApprovalRequest.builder() + .payType(getNhnPayType()) // 결제유형별 값 추출 + .tranCd("00100000") + .ordrNo(String.valueOf(command.getOrderId().id())) + .ordrMony(String.valueOf(command.getApprovedAmount().value())) + .build(); + + // API 호출 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity httpRequest = + new HttpEntity<>(request, headers); + + // 결제유형별 응답 파싱 가능하도록 함 + T response = restTemplate.exchange( + NHN_CONFIRM_URL, + HttpMethod.POST, + httpRequest, + getResponseType() + ).getBody(); + + // 결제유형별 응답 생성 + return convertToResponse(response); + } + + + /** + * 공통 취소 요청 + */ + @Override + public PgPayCancelResponse processCancel(PayCancelCommand command) { + // API 호출 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + NhnCancelRequest cancelRequest = NhnCancelRequest.builder() + .site_cd(SITE_CD) + .tno(command.getPgTid()) + .mod_type(command.getPaymentStatus().equals(PaymentStatus.PARTIAL_CANCELED) + ? "STPC" // 부분취소 코드 + : "STSC") // 전체취소 + .build(); + + HttpEntity httpRequest = + new HttpEntity<>(cancelRequest, headers); + + NhnCancelResponse response = restTemplate.exchange( + NHN_CANCEL_URL, + HttpMethod.POST, + httpRequest, + NhnCancelResponse.class + ).getBody(); + + return new PgPayCancelResponse( + response.tno(), + response.resCd(), + response.resMsg(), + null, + Long.parseLong(response.cardModMny()), + "0000".equals(response.resCd()) ? true : false + ); + } + + public PgProvider getPgProvider() { + return PgProvider.NHN; + } + + @Override + public PayMethod getPgPayMethod() { + return getNhnPayMethod(); + } + + @Override + public Object initPayment() { + return null; + } + + /** + * NHN 구현체 중 특정 결제서비스 빈 추출을 위함 + * @return + */ + protected abstract PayMethod getNhnPayMethod(); + + /** + * NHN 는 요청 시 결제유형별 pay_type값이 상이함. + * @return + */ + protected abstract String getNhnPayType(); + + /** + * 결제 응답 글래스 제공 + * */ + protected abstract Class getResponseType(); + + /** + * 결제수단별 승인 응답 메시지 파싱 + */ + protected abstract PgPayResponse convertToResponse(T response); + +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/NhnCardService.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/NhnCardService.java new file mode 100644 index 0000000..d19d9ac --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/NhnCardService.java @@ -0,0 +1,49 @@ +package com.commerce.payments.infrastructure.pg.nhn; + +import com.commerce.payments.domain.vo.payments.PgPayResponse; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.infrastructure.pg.nhn.dto.NhnCardApprovalResponse; +import com.commerce.shared.vo.Money; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +@Service +public class NhnCardService extends NHNStrategy{ + public NhnCardService(RestTemplate restTemplate) { + super(restTemplate); + } + + @Override + protected PayMethod getNhnPayMethod() { + return PayMethod.CARD; + } + + @Override + protected String getNhnPayType() { + return "PACA"; + } + + @Override + protected Class getResponseType() { + return NhnCardApprovalResponse.class; + } + + @Override + protected PgPayResponse convertToResponse(NhnCardApprovalResponse response) { + boolean isSuccess = "0000".equals(response.resCd()); + + return PgPayResponse.builder() + .pgTid(response.tno()) + .responseCode(response.resCd()) + .responseMessage(response.resMsg()) + .amount(Money.of(Long.parseLong(response.amount()))) + .isSuccess(isSuccess) + .card(PgPayResponse.Card.builder() + .approveNo(response.appNo()) + .issuerCode(response.cardCd()) + .cardType( response.cardBinType02()) + .build()) + .build(); + } + +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/NhnEasyService.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/NhnEasyService.java new file mode 100644 index 0000000..2997d22 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/NhnEasyService.java @@ -0,0 +1,47 @@ +package com.commerce.payments.infrastructure.pg.nhn; + +import com.commerce.payments.domain.vo.payments.PgPayResponse; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.infrastructure.pg.nhn.dto.NhnEasyCardApprovalResponse; +import com.commerce.shared.vo.Money; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +@Service +public class NhnEasyService extends NHNStrategy { + public NhnEasyService(RestTemplate restTemplate) { + super(restTemplate); + } + + @Override + protected PayMethod getNhnPayMethod() { + return PayMethod.EASY_PAY; + } + + @Override + protected String getNhnPayType() { + return "PACA"; + } + + @Override + protected Class getResponseType() { + return NhnEasyCardApprovalResponse.class; + } + + @Override + protected PgPayResponse convertToResponse(NhnEasyCardApprovalResponse response) { + boolean isSuccess = "0000".equals(response.resCd()); + + return PgPayResponse.builder() + .pgTid(response.tno()) + .responseCode(response.resCd()) + .responseMessage(response.resMsg()) + .amount(Money.of(Long.parseLong(response.amount()))) + .isSuccess(isSuccess) + .easyPay(PgPayResponse.EasyPay.builder() + .provider(response.cardOtherPayType()) + .build()) + .build(); + } + +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnApprovalRequest.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnApprovalRequest.java new file mode 100644 index 0000000..bf2c32b --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnApprovalRequest.java @@ -0,0 +1,34 @@ +package com.commerce.payments.infrastructure.pg.nhn.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; + +/** + * NHN 결제 승인 요청 + */ +@Builder +public record NhnApprovalRequest( + @JsonProperty("site_cd") + String siteCd, // siteCd 사이트코드 (5자리, 영문대문자+숫자) + + @JsonProperty("kcp_cert_info") + String kcpCertInfo, // NHN KCP 서비스 인증서 (PEM 파일 직렬화) + + @JsonProperty("enc_data") + String encData, // 결제창 인증결과 암호화 정보 (결제창에서 받은 값 그대로 사용) + + @JsonProperty("enc_info") + String encInfo, // 결제창 인증결과 암호화 정보 (결제창에서 받은 값 그대로 사용) + + @JsonProperty("tran_cd") + String tranCd, // 요청코드 (고정값: "00100000") + + @JsonProperty("ordr_mony") + String ordrMony, // 실제 결제 요청 금액 + + @JsonProperty("ordr_no") + String ordrNo, // 실제 결제 주문번호 + + @JsonProperty("pay_type") + String payType // 결제수단 구분 신용카드 : PACA +) { } diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnApprovalResponse.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnApprovalResponse.java new file mode 100644 index 0000000..3703f01 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnApprovalResponse.java @@ -0,0 +1,4 @@ +package com.commerce.payments.infrastructure.pg.nhn.dto; + +public interface NhnApprovalResponse { +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnCancelRequest.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnCancelRequest.java new file mode 100644 index 0000000..86c7c58 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnCancelRequest.java @@ -0,0 +1,25 @@ +package com.commerce.payments.infrastructure.pg.nhn.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; + +/** + * NHN 결제 취소 요청 + */ +@Builder +public record NhnCancelRequest ( + @JsonProperty("site_cd") + String site_cd, + + @JsonProperty("tno") + String tno, + + @JsonProperty("kcp_cert_info") + String kcp_cert_info, + + @JsonProperty("kcp_sign_data") + String kcp_sign_data, + + @JsonProperty("mod_type") + String mod_type +) {} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnCancelResponse.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnCancelResponse.java new file mode 100644 index 0000000..443faba --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnCancelResponse.java @@ -0,0 +1,42 @@ +package com.commerce.payments.infrastructure.pg.nhn.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public record NhnCancelResponse( + // 결과 정상 승인: "0000", 그 외 오류코드 + @JsonProperty("res_cd") + String resCd, + + // 결과 메시지 + @JsonProperty("res_msg") + String resMsg, + + // KCP 거래 고유번호 (14자리) + @JsonProperty("tno") + String tno, + + // 취소 처리 시각 yyyyMMddHHmmss + @JsonProperty("canc_time") + String cancTime, + + // 부분취소 금액 전체 취소 시: null 또는 "0" + @JsonProperty("mod_mny") + String modMny, + + // 부분취소 후 남은 금액 + @JsonProperty("rem_mny") + String remMny, + + // 부분취소 일련번호 + @JsonProperty("mod_pcan_seq_no") + String modPcanSeqNo, + + // 카드 취소금액 + @JsonProperty("card_mod_mny") + String cardModMny, + + // 쿠폰 취소금액 + @JsonProperty("coupon_mod_mny") + String couponModMny +) { +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnCardApprovalResponse.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnCardApprovalResponse.java new file mode 100644 index 0000000..0e7868b --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnCardApprovalResponse.java @@ -0,0 +1,54 @@ +package com.commerce.payments.infrastructure.pg.nhn.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * NHN 카드결제 승인응답 + */ +public record NhnCardApprovalResponse( + @JsonProperty("res_cd") + String resCd, // 결과코드 (정상: "0000") + + @JsonProperty("res_msg") + String resMsg, // 결과 메시지 + + @JsonProperty("res_en_msg") + String resEnMsg, // 영문 결과 메시지 + + @JsonProperty("pay_method") + String payMethod, // 결제수단 (PACA:카드, PABK:계좌이체, PAMC:휴대폰 등) + + @JsonProperty("order_no") + String orderNo, + + @JsonProperty("amount") + String amount, // 총 결제금액 (DB 금액 검증 필수) + + @JsonProperty("card_mny") + String cardMny, // 카드 실결제금액 (쿠폰제외, 100%할인시 0 가능) + + @JsonProperty("coupon_mny") + String couponMny, // 쿠폰/포인트 할인금액 + + @JsonProperty("card_no") + String cardNo, // 카드번호 (3번째 구간 마스킹) + + @JsonProperty("card_bin_type_02") + String cardBinType02, // 일반 : 0 / 체크 : 1 + + @JsonProperty("quota") + String quota, // 할부개월 (00:일시불, 03:3개월) + + @JsonProperty("tno") + String tno, // KCP 거래번호 (14자리, 전체 사용 필수) + + @JsonProperty("card_cd") + String cardCd, // 카드사 코드 (예: CCNH) + + @JsonProperty("card_name") + String cardName, // 카드사 명 (예: NH카드) + + @JsonProperty("app_no") + String appNo // 승인번호 (8자리) +) implements NhnApprovalResponse{ +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnEasyCardApprovalResponse.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnEasyCardApprovalResponse.java new file mode 100644 index 0000000..dec1e8b --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/nhn/dto/NhnEasyCardApprovalResponse.java @@ -0,0 +1,27 @@ +package com.commerce.payments.infrastructure.pg.nhn.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * NHN 제휴간편결제 신용카드 결제응답 + */ +public record NhnEasyCardApprovalResponse( + @JsonProperty("res_cd") + String resCd, // 결과코드 (정상: "0000") + + @JsonProperty("res_msg") + String resMsg, // 결과 메시지 + + @JsonProperty("res_en_msg") + String resEnMsg, // 영문 결과 메시지 + + @JsonProperty("amount") + String amount, // 총 결제금액 (DB 금액 검증 필수) + + @JsonProperty("tno") + String tno, // KCP 거래번호 (14자리, 전체 사용 필수 + + @JsonProperty("card_other_pay_type") + String cardOtherPayType // 제휴간편결제유형 +) implements NhnApprovalResponse{ +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossApprovalResponse.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossApprovalResponse.java new file mode 100644 index 0000000..e31780c --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossApprovalResponse.java @@ -0,0 +1,78 @@ +package com.commerce.payments.infrastructure.pg.toss; + +import java.util.List; + +/** + * TOSS 결제유형에 따른 승인 응답 DTO + **/ +public record TossApprovalResponse( + String mId, // 가맹점 ID (상점 식별자, MID) + String version, // API 버전 (예: "2022-11-16") + String paymentKey, // 결제 키 (토스가 발급한 결제 고유 식별자, 승인/취소/조회 시 필수) + String orderId, // 주문 ID (상점에서 생성한 주문 고유 번호) + String orderName, // 주문명 (예: "토스 티셔츠 외 2건", 결제창에 표시됨) + String method, // 결제수단 ("카드", "가상계좌", "간편결제", "휴대폰" 등) + Long totalAmount, // 총 결제 금액 (원 단위, 최초 결제 요청 금액) + Long balanceAmount, // 취소 후 남은 금액 (부분 취소 시 감소, 전액 취소 시 0) + String status, // 결제 상태 (READY, IN_PROGRESS, WAITING_FOR_DEPOSIT, DONE, CANCELED, PARTIAL_CANCELED, ABORTED, EXPIRED) + String requestedAt, // 결제 요청 시각 (ISO 8601 형식: 2024-12-01T10:00:00+09:00) + String approvedAt, // 결제 승인 시각 (ISO 8601 형식, 승인 완료 후에만 존재) + CardInfo card, // 카드 결제 정보 (카드 결제 시에만 존재, 나머지 null) + EasyPayInfo easyPay, // 간편결제 정보 (간편결제 시에만 존재, 나머지 null) + VirtualAccountInfo virtualAccount, // 가상계좌 정보 (가상계좌 결제 시에만 존재, 나머지 null) + List cancels // 취소 정보 리스트 (취소 발생 시 배열에 누적, 없으면 빈 배열 또는 null) +) { + /** + * 카드결제 정보 + */ + public record CardInfo( + String issuerCode, // 발급사 코드 (카드를 발행한 회사) + String acquirerCode, // 매입사 코드 (가맹점과 계약한 카드사) + String number, // 마스킹된 카드번호 (앞 8자리, 뒤 1자리만 표시) + Integer installmentPlanMonths, // 할부 개월 (0=일시불, 2~12=할부) + String cardType, // 카드 타입 (신용/체크/기프트) + String ownerType, // 소유자 구분 (개인/법인) + String approveNo // 승인번호 (PG사가 아닌 카드사에서 발급) + ) {} + + /** + * 간편결제 정보 + */ + public record EasyPayInfo( + String provider, // 간편결제 제공자 (토스페이, 네이버페이, 카카오페이 등) + String amount, // 실제 결제된 금액 + String discountAmount // 간편결제 할인 금액 (프로모션 적용 시) + ) {} + + /** + * 가상계좌 정보 + */ + public record VirtualAccountInfo( + String accountNumber, // 발급된 가상계좌 번호 (구매자가 입금할 계좌) + String bankCode, // 은행 코드 (20=우리, 004=KB, 011=NH농협) + String customerName, // 입금자명 (주문 시 입력한 구매자 이름) + String dueDate, // 입금 기한 (이 시간까지 입금해야 함) + String accountType, // 계좌 유형 (일반=주문마다 새 계좌, 고정=항상 동일 계좌) + Boolean expired, // 만료 여부 (true=입금 기한 지남) + String settlementStatus, // 정산 상태 (INCOMPLETED=미정산, COMPLETED=정산완료) + String refundStatus // 환불 처리 상태 (취소 시 환불 진행 현황) + ) {} + + /** + * 결제 취소 정보 + * - Payment 객체의 cancels 필드에 배열로 담겨서 반환됨 + * - 부분 취소를 여러 번 하면 배열에 여러 개의 취소 객체가 쌓임 + */ + public record CancelInfo( + String transactionKey, // 취소 거래 키 (각 취소마다 고유) + String cancelReason, // 취소 사유 + Long cancelAmount, // 취소 금액 + Long taxFreeAmount, // 취소된 면세 금액 + Long taxExemptionAmount, // 과세 제외 금액 (복지, 교육비 등) + Long refundableAmount, // 남은 취소 가능 금액 + Long easyPayDiscountAmount, // 간편결제 할인 금액 + String canceledAt, // 취소 처리 시각 (ISO 8601) + String cancelStatus, // 취소 상태 (DONE, FAILED, IN_PROGRESS 등) + String receiptKey // 취소 영수증 키 + ) {} +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossCancelResponse.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossCancelResponse.java new file mode 100644 index 0000000..40e168f --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossCancelResponse.java @@ -0,0 +1,9 @@ +package com.commerce.payments.infrastructure.pg.toss; + +public record TossCancelResponse( + String transactionKey, + String cancelStatus, + Long cancelAmount, + String cancelReason +) { +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossCardService.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossCardService.java new file mode 100644 index 0000000..fbbff88 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossCardService.java @@ -0,0 +1,47 @@ +package com.commerce.payments.infrastructure.pg.toss; + +import com.commerce.payments.domain.vo.payments.PgPayResponse; +import com.commerce.payments.application.port.in.dto.PayCancelCommand; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.infrastructure.pg.toss.dto.TossTransResponse; +import com.commerce.shared.vo.Money; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; + +@Service +public class TossCardService extends TossStrategy{ + public TossCardService(RestTemplate restTemplate) { + super(restTemplate); + } + + @Override + protected PayMethod getTossPayMethod() { + return PayMethod.CARD; + } + + @Override + protected PgPayResponse convertToResponse(TossTransResponse response) { + boolean isSuccess = "DONE".equals(response.status()); + + TossTransResponse.CardInfo cardResponse = response.card(); + return PgPayResponse.builder() + .pgTid(response.paymentKey()) + .responseCode(response.status()) + .responseMessage(response.status()) + .amount(Money.of(response.totalAmount())) + .isSuccess(isSuccess) + .card(PgPayResponse.Card.builder() + .approveNo(cardResponse.approveNo()) + .issuerCode(cardResponse.issuerCode()) + .cardType(cardResponse.cardType()) + .build()) + .build(); + } + + @Override + protected void generateCancelRequest(Map commonBody, PayCancelCommand command) { + // 추가 세팅 없음 + } +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossEasyService.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossEasyService.java new file mode 100644 index 0000000..431971e --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossEasyService.java @@ -0,0 +1,54 @@ +package com.commerce.payments.infrastructure.pg.toss; + +import com.commerce.payments.domain.vo.payments.PgPayResponse; +import com.commerce.payments.application.port.in.dto.PayCancelCommand; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.infrastructure.pg.toss.dto.TossTransResponse; +import com.commerce.shared.vo.Money; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; + +@Service +public class TossEasyService extends TossStrategy{ + public TossEasyService(RestTemplate restTemplate) { + super(restTemplate); + } + + @Override + protected PayMethod getTossPayMethod() { + return PayMethod.EASY_PAY; + } + + @Override + protected PgPayResponse convertToResponse(TossTransResponse response) { + boolean isSuccess = "DONE".equals(response.status()); + + TossTransResponse.EasyPayInfo easyPayInfo = response.easyPay(); + TossTransResponse.CardInfo card = response.card(); + + return PgPayResponse.builder() + .pgTid(response.paymentKey()) + .responseCode(response.status()) + .responseMessage(response.status()) + .amount(Money.of(response.totalAmount())) + .isSuccess(isSuccess) + .card(PgPayResponse.Card.builder() + .approveNo(card.approveNo()) + .issuerCode(card.issuerCode()) + .cardType(card.cardType()) + .build()) + .easyPay(PgPayResponse.EasyPay.builder() + .provider(easyPayInfo.provider()) + .amount(easyPayInfo.amount()) + .discountAmount(easyPayInfo.discountAmount()) + .build()) + .build(); + } + + @Override + protected void generateCancelRequest(Map commonBody, PayCancelCommand command) { + // 추가 세팅 없음 + } +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossStrategy.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossStrategy.java new file mode 100644 index 0000000..6b46881 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossStrategy.java @@ -0,0 +1,230 @@ +package com.commerce.payments.infrastructure.pg.toss; + +import com.commerce.payments.application.port.in.dto.PayCancelCommand; +import com.commerce.payments.application.port.in.dto.PayOrderCommand; +import com.commerce.payments.application.port.out.PgStrategy; +import com.commerce.payments.domain.vo.payments.PgPayCancelResponse; +import com.commerce.payments.domain.vo.payments.PgPayResponse; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.domain.enums.PgProvider; +import com.commerce.payments.infrastructure.pg.toss.dto.TossCancelResponse; +import com.commerce.payments.infrastructure.pg.toss.dto.TossTransResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.*; +import org.springframework.stereotype.Component; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; +import org.springframework.web.client.RestTemplate; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; + +import static com.commerce.payments.domain.enums.PaymentStatus.PARTIAL_CANCELED; + +/** + * TOSS PG + * 카드, 간편결제, 가상계좌 에 대해 동일한 승인/취소 API 사용 + * + * 여기서 필요에 따라 토스의 결제수단별 프로세스를 추상화한다. + */ +@Slf4j +@Component +@RequiredArgsConstructor +public abstract class TossStrategy extends PgStrategy { + + private static final String TOSS_CONFIRM_URL = "https://api.tosspayments.com/v1/payments/confirm"; + private static final String TOSS_CANCEL_URL = "https://api.tosspayments.com/v1/payments/"; + private final RestTemplate restTemplate; + private final String secretKey = "tmp"; + + /** + * TOSS 결제 승인 처리 + * 카드, 간편결제, 가상계좌 모두 동일한 API 사용 + * @param command 승인요청dto + * @return toss -> 공통dto 변환 + */ + @Override + public PgPayResponse processApproval(PayOrderCommand command) { + TossTransResponse response = callTossConfirmApi( + command.getJsonSubData(), + command.getOrderId().id(), + command.getApprovedAmount().value() + ); + + return convertToResponse(response); + } + + /** + * TOSS 결제 취소 처리 + * 카드, 간편결제, 가상계좌 모두 동일한 취소 API 사용 + * @param command 취소요청dto + * @return toss -> 공통dto 변환 + */ + @Override + public PgPayCancelResponse processCancel(PayCancelCommand command) { + TossCancelResponse tossCancelResponse = callTossCancelApi(command); + + boolean isSuccess = "DONE".equals(tossCancelResponse.cancelStatus()); + + return new PgPayCancelResponse( + tossCancelResponse.transactionKey(), + tossCancelResponse.cancelStatus(), + tossCancelResponse.cancelStatus(), + tossCancelResponse.cancelReason(), + tossCancelResponse.cancelAmount(), + isSuccess + ); + } + + @Override + public PgProvider getPgProvider() { + return PgProvider.TOSS; + } + + /** + * TOSS 구현체 중 특정 결제서비스 빈 추출을 위함 + * @return + */ + @Override + public PayMethod getPgPayMethod() { + return getTossPayMethod(); + } + + @Override + public Object initPayment() { + return null; + } + + /** + * 승인 API 호출 + */ + private TossTransResponse callTossConfirmApi( + String paymentKey, + String orderId, + Long amount + ) { + try { + HttpHeaders headers = createHeaders(); + // 요청 바디 + Map requestBody = new HashMap<>(); + requestBody.put("paymentKey", paymentKey); + requestBody.put("orderId", orderId); + requestBody.put("amount", amount); + + HttpEntity> request = new HttpEntity<>(requestBody, headers); + // api 호출 + return restTemplate.exchange( + TOSS_CONFIRM_URL, + HttpMethod.POST, + request, + TossTransResponse.class + ).getBody(); + + } catch (HttpClientErrorException e) { + log.error("TOSS 결제 승인 실패 (4xx) - status: {}, body: {}", + e.getStatusCode(), e.getResponseBodyAsString()); + throw new RuntimeException(e.getResponseBodyAsString()); + + } catch (HttpServerErrorException e) { + log.error("TOSS 서버 오류 (5xx) - status: {}, body: {}", + e.getStatusCode(), e.getResponseBodyAsString()); + throw new RuntimeException(e.getResponseBodyAsString()); + + } catch (Exception e) { + log.error("TOSS 승인 API 호출 중 예외 발생", e); + throw new RuntimeException(e.getMessage()); + } + } + + /** + * TOSS 결제 취소 API 호출 (통합) + */ + private TossCancelResponse callTossCancelApi(PayCancelCommand command) { + try { + String paymentKey = command.getPgTid(); // 결제 키 + Long cancelAmount = command.getCanceledAmount().value(); // 취소 금액 (null이면 전액 취소) + String cancelReason = command.getCancelReason(); + + String url = TOSS_CANCEL_URL + paymentKey + "/cancel"; + + HttpHeaders headers = createHeaders(); + + // 취소 요청 데이터 공통부 + Map requestBody = new HashMap<>(); + requestBody.put("cancelReason", cancelReason); + + // 부분 취소인 경우 금액 추가 + if (command.getPaymentStatus().equals(PARTIAL_CANCELED)) { + requestBody.put("cancelAmount", cancelAmount); + } + + // 결제유혈병 요청 데이터 추가 세팅 + generateCancelRequest(requestBody, command); + + HttpEntity> request = new HttpEntity<>(requestBody, headers); + ResponseEntity response = restTemplate.exchange( + url, + HttpMethod.POST, + request, + TossTransResponse.class + ); + + TossTransResponse.CancelInfo lastCancel = response.getBody() + .cancels() + .get(response.getBody().cancels().size() - 1); + + return new TossCancelResponse( + lastCancel.transactionKey(), + lastCancel.cancelStatus(), + lastCancel.cancelAmount(), + lastCancel.cancelReason() + ); + + } catch (HttpClientErrorException e) { + log.error("토스 결제 취소 실패 (4xx) - status: {}, body: {}", + e.getStatusCode(), e.getResponseBodyAsString()); + throw new RuntimeException("결제 취소 실패: " + e.getResponseBodyAsString()); + + } catch (HttpServerErrorException e) { + log.error("토스페이먼츠 서버 오류 (5xx) - status: {}, body: {}", + e.getStatusCode(), e.getResponseBodyAsString()); + throw new RuntimeException("토스페이먼츠 서버 오류: " + e.getResponseBodyAsString()); + + } catch (Exception e) { + log.error("결제 취소 API 호출 중 예외 발생", e); + throw new RuntimeException("결제 취소 중 오류가 발생했습니다: " + e.getMessage()); + } + } + + private HttpHeaders createHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.set(HttpHeaders.AUTHORIZATION, "Basic " + encodeSecretKey()); + + return headers; + } + + /** + * Secret Key Base64 인코딩 + */ + private String encodeSecretKey() { + return Base64.getEncoder() + .encodeToString((secretKey + ":").getBytes(StandardCharsets.UTF_8)); + } + + protected abstract PayMethod getTossPayMethod(); + + /** + * 결제수단별 응답 메시지 파싱 + */ + protected abstract PgPayResponse convertToResponse(TossTransResponse response); + + /** + * 결제수단별 취소 요청 body 생성 + */ + protected abstract void generateCancelRequest(Map commonBody, PayCancelCommand command); +} + diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossVirtualAccountService.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossVirtualAccountService.java new file mode 100644 index 0000000..30e5218 --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/TossVirtualAccountService.java @@ -0,0 +1,59 @@ +package com.commerce.payments.infrastructure.pg.toss; + +import com.commerce.payments.domain.vo.payments.PgPayResponse; +import com.commerce.payments.application.port.in.dto.PayCancelCommand; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.infrastructure.pg.toss.dto.TossTransResponse; +import com.commerce.shared.vo.Money; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; + +@Service +public class TossVirtualAccountService extends TossStrategy{ + + public TossVirtualAccountService(RestTemplate restTemplate) { + super(restTemplate); + } + + @Override + protected PayMethod getTossPayMethod() { + return PayMethod.VIRTUAL_ACCOUNT; + } + + @Override + protected PgPayResponse convertToResponse(TossTransResponse response) { + boolean isSuccess = "DONE".equals(response.status()) + || "WAITING_FOR_DEPOSIT".equals(response.status()); + + TossTransResponse.VirtualAccountInfo virtualAccountInfo = response.virtualAccount(); + return PgPayResponse.builder() + .pgTid(response.paymentKey()) + .responseCode(response.status()) + .responseMessage(response.status()) + .amount(Money.of(response.totalAmount())) + .isSuccess(isSuccess) + .virtualAccount(PgPayResponse.VirtualAccount.builder() + .accountType(virtualAccountInfo.accountType()) + .accountNumber(virtualAccountInfo.accountNumber()) + .bankCode(virtualAccountInfo.bankCode()) + .depositorName(virtualAccountInfo.customerName()) + .dueDate(virtualAccountInfo.dueDate()) + .build()) + .build(); + } + + @Override + protected void generateCancelRequest(Map commonBody, PayCancelCommand command) { + PayCancelCommand.RefundReceiveAccount refundAccount = command.getRefundReceiveAccount(); + + Map refundInfo = Map.of( + "bank", refundAccount.getBankCode(), + "accountNumber", refundAccount.getAccountNumber(), + "holderName", refundAccount.getHolderName() + ); + + commonBody.put("refundReceiveAccount", refundInfo); + } +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/dto/TossCancelResponse.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/dto/TossCancelResponse.java new file mode 100644 index 0000000..d33471c --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/dto/TossCancelResponse.java @@ -0,0 +1,9 @@ +package com.commerce.payments.infrastructure.pg.toss.dto; + +public record TossCancelResponse( + String transactionKey, + String cancelStatus, + Long cancelAmount, + String cancelReason +) { +} diff --git a/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/dto/TossTransResponse.java b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/dto/TossTransResponse.java new file mode 100644 index 0000000..4649f0e --- /dev/null +++ b/payments/src/main/java/com/commerce/payments/infrastructure/pg/toss/dto/TossTransResponse.java @@ -0,0 +1,78 @@ +package com.commerce.payments.infrastructure.pg.toss.dto; + +import java.util.List; + +/** + * TOSS 결제유형별 요청 응답 DTO + **/ +public record TossTransResponse( + String mId, // 가맹점 ID (상점 식별자, MID) + String version, // API 버전 (예: "2022-11-16") + String paymentKey, // 결제 키 (토스가 발급한 결제 고유 식별자, 승인/취소/조회 시 필수) + String orderId, // 주문 ID (상점에서 생성한 주문 고유 번호) + String orderName, // 주문명 (예: "토스 티셔츠 외 2건", 결제창에 표시됨) + String method, // 결제수단 ("카드", "가상계좌", "간편결제", "휴대폰" 등) + Long totalAmount, // 총 결제 금액 (원 단위, 최초 결제 요청 금액) + Long balanceAmount, // 취소 후 남은 금액 (부분 취소 시 감소, 전액 취소 시 0) + String status, // 결제 상태 (READY, IN_PROGRESS, WAITING_FOR_DEPOSIT, DONE, CANCELED, PARTIAL_CANCELED, ABORTED, EXPIRED) + String requestedAt, // 결제 요청 시각 (ISO 8601 형식: 2024-12-01T10:00:00+09:00) + String approvedAt, // 결제 승인 시각 (ISO 8601 형식, 승인 완료 후에만 존재) + CardInfo card, // 카드 결제 정보 (카드 결제 시에만 존재, 나머지 null) + EasyPayInfo easyPay, // 간편결제 정보 (간편결제 시에만 존재, 나머지 null) + VirtualAccountInfo virtualAccount, // 가상계좌 정보 (가상계좌 결제 시에만 존재, 나머지 null) + List cancels // 취소 정보 리스트 (취소 발생 시 배열에 누적, 없으면 빈 배열 또는 null) +) { + /** + * 카드결제 정보 + */ + public record CardInfo( + String issuerCode, // 발급사 코드 (카드를 발행한 회사) + String acquirerCode, // 매입사 코드 (가맹점과 계약한 카드사) + String number, // 마스킹된 카드번호 (앞 8자리, 뒤 1자리만 표시) + Integer installmentPlanMonths, // 할부 개월 (0=일시불, 2~12=할부) + String cardType, // 카드 타입 (신용/체크/기프트) + String ownerType, // 소유자 구분 (개인/법인) + String approveNo // 승인번호 (PG사가 아닌 카드사에서 발급) + ) {} + + /** + * 간편결제 정보 + */ + public record EasyPayInfo( + String provider, // 간편결제 제공자 (토스페이, 네이버페이, 카카오페이 등) + String amount, // 실제 결제된 금액 + String discountAmount // 간편결제 할인 금액 (프로모션 적용 시) + ) {} + + /** + * 가상계좌 정보 + */ + public record VirtualAccountInfo( + String accountNumber, // 발급된 가상계좌 번호 (구매자가 입금할 계좌) + String bankCode, // 은행 코드 (20=우리, 004=KB, 011=NH농협) + String customerName, // 입금자명 (주문 시 입력한 구매자 이름) + String dueDate, // 입금 기한 (이 시간까지 입금해야 함) + String accountType, // 계좌 유형 (일반=주문마다 새 계좌, 고정=항상 동일 계좌) + Boolean expired, // 만료 여부 (true=입금 기한 지남) + String settlementStatus, // 정산 상태 (INCOMPLETED=미정산, COMPLETED=정산완료) + String refundStatus // 환불 처리 상태 (취소 시 환불 진행 현황) + ) {} + + /** + * 결제 취소 정보 + * - Payment 객체의 cancels 필드에 배열로 담겨서 반환됨 + * - 부분 취소를 여러 번 하면 배열에 여러 개의 취소 객체가 쌓임 + */ + public record CancelInfo( + String transactionKey, // 취소 거래 키 (각 취소마다 고유) + String cancelReason, // 취소 사유 + Long cancelAmount, // 취소 금액 + Long taxFreeAmount, // 취소된 면세 금액 + Long taxExemptionAmount, // 과세 제외 금액 (복지, 교육비 등) + Long refundableAmount, // 남은 취소 가능 금액 + Long easyPayDiscountAmount, // 간편결제 할인 금액 + String canceledAt, // 취소 처리 시각 (ISO 8601) + String cancelStatus, // 취소 상태 (DONE, FAILED, IN_PROGRESS 등) + String receiptKey // 취소 영수증 키 + ) {} +} diff --git a/payments/src/main/proto/payment_service.proto b/payments/src/main/proto/payment_service.proto new file mode 100644 index 0000000..cf9d699 --- /dev/null +++ b/payments/src/main/proto/payment_service.proto @@ -0,0 +1,93 @@ +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "com.commerce.payments.grpc.proto"; +option java_outer_classname = "PaymentServiceProto"; + +package payment; + +service PaymentService { + // 결제 승인 + rpc ApprovePayment (PaymentApprovalRequest) returns (PaymentApprovalResponse); + + // 전체 취소 + rpc CancelPayment (PaymentCancelRequest) returns (PaymentCancelResponse); + + // 부분 취소 + rpc PartialCancelPayment (PaymentPartialCancelRequest) returns (PaymentPartialCancelResponse); + + // 등록된 카드로 결제 + rpc ApproveWithCard (CardPaymentRequest) returns (PaymentApprovalResponse); +} + +// 결제 승인 요청 +message PaymentApprovalRequest { + string order_id = 1; + int64 approved_amount = 2; + int32 installment = 3; + string pay_method = 4; // CARD, VIRTUAL_ACCOUNT, EASY_PAY + string pay_provider = 5; // TOSS, NICEPAY, KSNET, KCP +} + +// 결제 승인 응답 +message PaymentApprovalResponse { + bool success = 1; + string code = 2; + string message = 3; + PaymentData data = 4; +} + +message PaymentData { + string payment_id = 1; + int64 approved_amount = 2; + string approved_at = 3; + string pay_method = 4; + string status = 5; +} + +// 전체 취소 요청 +message PaymentCancelRequest { + string order_id = 1; +} + +// 전체 취소 응답 +message PaymentCancelResponse { + bool success = 1; + string code = 2; + string message = 3; + CancelData data = 4; +} + +message CancelData { + string payment_id = 1; + int64 canceled_amount = 2; + string canceled_at = 3; +} + +// 부분 취소 요청 +message PaymentPartialCancelRequest { + string order_id = 1; + int64 order_item_id = 2; + int64 canceled_quantity = 3; +} + +// 부분 취소 응답 +message PaymentPartialCancelResponse { + bool success = 1; + string code = 2; + string message = 3; + PartialCancelData data = 4; +} + +message PartialCancelData { + int64 partial_cancel_id = 1; + int64 canceled_amount = 2; + int64 remain_amount = 3; + string canceled_at = 4; +} + +// 등록된 카드 결제 요청 +message CardPaymentRequest { + int64 card_id = 1; + string order_id = 2; +} diff --git a/payments/src/main/resources/application.yml b/payments/src/main/resources/application.yml new file mode 100644 index 0000000..f4f7493 --- /dev/null +++ b/payments/src/main/resources/application.yml @@ -0,0 +1,39 @@ +spring: + application: + name: payments-service + + datasource: + hikari: + maximum-pool-size: 20 + connection-timeout: 3000 + + jpa: + hibernate: + ddl-auto: validate + properties: + hibernate: + format_sql: true + show_sql: true + dialect: org.hibernate.dialect.MySQLDialect + + data: + redis: + host: localhost + port: 6379 + +# gRPC Server 설정 +grpc: + server: + port: 9090 + +server: + port: 8081 + +logging: + level: + com.commerce.payments: DEBUG + io.grpc: INFO + org.hibernate.tool.schema: DEBUG + +aes256: + key: 61qDonoZcEtIEvUZVPkIKIYovHH82rXtK7T1g/rcc1k= \ No newline at end of file diff --git a/platform/src/test/java/com/commerce/platform/core/application/in/CustomerUseCaseImplTest.java b/payments/src/test/java/com/commerce/payments/application/port/in/CustomerUseCaseImplTest.java similarity index 80% rename from platform/src/test/java/com/commerce/platform/core/application/in/CustomerUseCaseImplTest.java rename to payments/src/test/java/com/commerce/payments/application/port/in/CustomerUseCaseImplTest.java index 2a9e287..a46315c 100644 --- a/platform/src/test/java/com/commerce/platform/core/application/in/CustomerUseCaseImplTest.java +++ b/payments/src/test/java/com/commerce/payments/application/port/in/CustomerUseCaseImplTest.java @@ -1,11 +1,10 @@ -package com.commerce.platform.core.application.in; +package com.commerce.payments.application.port.in; -import com.commerce.platform.core.application.in.dto.RegistryCardCommand; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.vo.CustomerId; -import com.commerce.platform.infrastructure.persistence.CustomerCardRepository; -import com.commerce.platform.shared.exception.BusinessException; -import com.commerce.platform.shared.service.AesCryptoFacade; +import com.commerce.payments.domain.enums.PayProvider; +import com.commerce.payments.infrastructure.persistence.CustomerCardRepository; +import com.commerce.shared.vo.CustomerId; +import com.commerce.shared.exception.BusinessException; +import com.commerce.shared.service.AesCryptoFacade; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -15,8 +14,8 @@ import java.util.ArrayList; import java.util.List; -import static com.commerce.platform.shared.exception.BusinessError.DUPLICATED_REGISTRY_CARD; -import static com.commerce.platform.shared.exception.BusinessError.EXCEED_REGISTRY_CARD; +import static com.commerce.shared.exception.BusinessError.DUPLICATED_REGISTRY_CARD; +import static com.commerce.shared.exception.BusinessError.EXCEED_REGISTRY_CARD; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/platform/src/test/java/com/commerce/platform/core/domain/service/PaymentPgRouterTest.java b/payments/src/test/java/com/commerce/payments/application/service/PaymentPgRouterTest.java similarity index 84% rename from platform/src/test/java/com/commerce/platform/core/domain/service/PaymentPgRouterTest.java rename to payments/src/test/java/com/commerce/payments/application/service/PaymentPgRouterTest.java index acedd33..9c0ef0e 100644 --- a/platform/src/test/java/com/commerce/platform/core/domain/service/PaymentPgRouterTest.java +++ b/payments/src/test/java/com/commerce/payments/application/service/PaymentPgRouterTest.java @@ -1,14 +1,16 @@ -package com.commerce.platform.core.domain.service; - -import com.commerce.platform.PlatformApplication; -import com.commerce.platform.core.domain.enums.PayMethod; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.enums.PgProvider; -import com.commerce.platform.infrastructure.adaptor.PgCacheService; -import com.commerce.platform.infrastructure.persistence.PgFeeInfo; -import com.commerce.platform.infrastructure.persistence.PgFeeInfoRepository; -import com.commerce.platform.infrastructure.pg.NHNStrategy; -import com.commerce.platform.infrastructure.pg.TossStrategy; +package com.commerce.payments.application.service; + + +import com.commerce.payments.PaymentsApplication; +import com.commerce.payments.domain.enums.PayMethod; +import com.commerce.payments.domain.enums.PayProvider; +import com.commerce.payments.domain.enums.PgProvider; +import com.commerce.payments.domain.service.PaymentPgRouter; +import com.commerce.payments.infrastructure.adaptor.PgCacheService; +import com.commerce.payments.infrastructure.persistence.PgFeeInfo; +import com.commerce.payments.infrastructure.persistence.PgFeeInfoRepository; +import com.commerce.payments.infrastructure.pg.nhn.NHNStrategy; +import com.commerce.payments.infrastructure.pg.toss.TossStrategy; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -115,7 +117,7 @@ void routePg_health() { @DisplayName("ApplicationStartedEvent 동작 검증") @Test void initPgCache() { - SpringApplication application = new SpringApplication(PlatformApplication.class); + SpringApplication application = new SpringApplication(PaymentsApplication.class); application.addListeners( (ApplicationListener) event -> { diff --git a/payments/src/test/java/com/commerce/payments/application/service/PaymentUseCaseImplTest.java b/payments/src/test/java/com/commerce/payments/application/service/PaymentUseCaseImplTest.java new file mode 100644 index 0000000..254d99a --- /dev/null +++ b/payments/src/test/java/com/commerce/payments/application/service/PaymentUseCaseImplTest.java @@ -0,0 +1,334 @@ +//package com.commerce.payments.application.service; +// +//import com.commerce.payments.domain.vo.payments.PgPayCancelResponse; +//import com.commerce.payments.domain.vo.payments.PgPayResponse; +//import com.commerce.payments.application.port.in.command.PayCancelCommand; +//import com.commerce.payments.application.port.in.command.PayOrderCommand; +//import com.commerce.payments.application.port.out.PaymentOutPort; +//import com.commerce.payments.application.port.out.PgStrategy; +//import com.commerce.payments.domain.aggregate.Payment; +//import com.commerce.payments.domain.enums.PayMethod; +//import com.commerce.payments.domain.enums.PayProvider; +//import com.commerce.payments.domain.enums.PaymentStatus; +//import com.commerce.payments.domain.enums.PgProvider; +//import com.commerce.payments.infrastructure.adaptor.PaymentAdaptor; +//import com.commerce.payments.infrastructure.persistence.PaymentPartCancelRepository; +//import com.commerce.shared.exception.BusinessError; +//import com.commerce.shared.exception.BusinessException; +//import com.commerce.shared.vo.Money; +//import com.commerce.shared.vo.PaymentId; +//import com.commerce.shared.vo.Quantity; +//import org.junit.jupiter.api.BeforeEach; +//import org.junit.jupiter.api.DisplayName; +//import org.junit.jupiter.api.Test; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +//import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +//import org.springframework.context.annotation.Import; +//import org.springframework.test.context.bean.override.mockito.MockitoBean; +// +//import java.util.List; +// +//import static org.assertj.core.api.Assertions.assertThat; +//import static org.assertj.core.api.Assertions.assertThatThrownBy; +//import static org.mockito.ArgumentMatchers.any; +//import static org.mockito.Mockito.mock; +//import static org.mockito.Mockito.when; +// +//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +//@Import({ +// PaymentUseCaseImpl.class, +// PaymentAdaptor.class, +//// OrderAdaptor.class, +//// OrderItemAdaptor.class, +//// ProductAdaptor.class, +//// CustomerCardAdaptor.class +//}) +//@DataJpaTest +//class PaymentUseCaseImplTest { +// +// @Autowired +// private PaymentUseCaseImpl paymentUseCase; +// +// @Autowired +// private PaymentOutPort paymentOutPort; +// +//// @Autowired +//// private OrderRepository orderRepository; +//// +//// @Autowired +//// private OrderItemRepository orderItemRepository; +// +// @Autowired +// private PaymentPartCancelRepository paymentPartCancelRepository; +// +// @MockitoBean +// private PaymentPgRouter mockPaymentPgRouter; +// +//// private Order testOrder; +// +//// private List testOrderItems; +// +//// private final ProductId productId1 = ProductId.of("P20251110222600000001"); +//// private final ProductId productId2 = ProductId.of("P20251110222600000002"); +// +// private PgPayResponse success_pgResponse = PgPayResponse.builder() +// .pgTid("PG_TID_12345") +// .responseCode("0000") +// .responseMessage("성공") +// .amount(Money.of(35000)) +// .isSuccess(true) +// .build(); +// +// private PgPayCancelResponse cancelResponse = PgPayCancelResponse.builder() +// .pgCcTid("PG_CC_TID_12345") +// .responseCode("success") +// .responseMessage("취소성공") +// .cancelReason("고객취소") +// .cancelAmount(35000L) +// .isSuccess(true) +// .build(); +// +// private PgPayResponse fail_pgResponse = PgPayResponse.builder() +// .pgTid("PG_TID_12345") +// .responseCode("errorCode") +// .responseMessage("실패") +// .isSuccess(false) +// .build(); +// +// @BeforeEach +// void init() { +// // 주문완료 상태의 신규order 저장 +// testOrder = Order.create(CustomerId.of("test1"), null); +// testOrder.confirm(Money.of(35000), Money.of(0)); +// orderRepository.save(testOrder); +// orderRepository.flush(); +// +// testOrderItems = List.of( +// OrderItem.create(testOrder.getOrderId(), productId1, Quantity.create(3)), +// OrderItem.create(testOrder.getOrderId(), productId2, Quantity.create(1)) +// ); +// +// orderItemRepository.saveAll(testOrderItems); +// orderItemRepository.flush(); +// } +// +// @DisplayName("주문 결제 성공") +// @Test +// void doApproval_successful() { +// PayOrderCommand command = new PayOrderCommand( +// testOrder.getOrderId(), +// null, +// null, +// PayMethod.CARD, +// PayProvider.KB, +// null +// ); +// +// mockPgStrategy(); +// +// paymentUseCase.doApproval(command); +// +// // then 승인 성공 +// Payment payment = paymentOutPort.findByOrderId(testOrder.getOrderId()) +// .get(); +// assertThat(payment).isNotNull(); +// assertThat(payment.getPaymentStatus()).isEqualTo(PaymentStatus.APPROVED); +// +// // order 상태 검증 +// assertThat(orderRepository.findById(testOrder.getOrderId()).get().getStatus()) +// .isEqualTo(OrderStatus.PAID); +// } +// +// @DisplayName("전체환불 성공") +// @Test +// void doCancel_successful() { +// // 주문 결제 +// doApproval_successful(); +// +// // 전체취소 요청 +// PayCancelCommand command = PayCancelCommand.builder() +// .orderId(testOrder.getOrderId()) +// .paymentStatus(PaymentStatus.FULL_CANCELED) +// .build(); +// +// mockPgStrategy(); +// +// paymentUseCase.doCancel(command); +// +// // payment 상태 +// assertThat(paymentOutPort.findByOrderId(testOrder.getOrderId())).isNotNull(); +// assertThat(paymentOutPort.findByOrderId(testOrder.getOrderId()).get().getPaymentStatus()) +// .isEqualTo(PaymentStatus.FULL_CANCELED); +// +// // order 상태 검증 +// Order refundedOrder = orderRepository.findById(testOrder.getOrderId()).orElseThrow(); +// assertThat(refundedOrder.getStatus()).isEqualTo(OrderStatus.REFUND); +// } +// +// @DisplayName("전체취소실패 : 부분취소내역 존재") +// @Test +// void doCancel_failed() { +// // 결제 승인 +// doApproval_successful(); +// +// mockPgStrategy(); +// +// // 부분취소 요청 +// OrderItem canceledItem = testOrderItems.get(0); +// +// PayCancelCommand partCancelCommand = PayCancelCommand.builder() +// .orderId(testOrder.getOrderId()) +// .orderItemId(canceledItem.getId()) +// .canceledQuantity(Quantity.create(2)) +// .paymentStatus(PaymentStatus.PARTIAL_CANCELED) +// .build(); +// +// mockPgStrategy(); +// +// // 부분취소 +// Long partCancelId = paymentUseCase.doPartCancel(partCancelCommand); +// +// // 전체취소 +// PayCancelCommand fullCancelCommand = PayCancelCommand.builder() +// .orderId(testOrder.getOrderId()) +// .paymentStatus(PaymentStatus.FULL_CANCELED) +// .build(); +// +// // 전체취소 실패 +// assertThatThrownBy(() -> paymentUseCase.doCancel(fullCancelCommand)) +// .isInstanceOf(BusinessException.class) +// .hasMessageContaining(BusinessError.PAYMENT_HAS_PARTIAL_CANCEL.getMessage()); +// +// // payment 상태 검증 +// Payment payment = paymentOutPort.findByOrderId(testOrder.getOrderId()).orElseThrow(); +// assertThat(payment.getPaymentStatus()) +// .isEqualTo(PaymentStatus.APPROVED); +// +// // order 상태 검증 +// Order order = orderRepository.findById(testOrder.getOrderId()).orElseThrow(); +// assertThat(order.getStatus()).isEqualTo(OrderStatus.PAID); +// } +// +// +// @DisplayName("부분취소 성공") +// @Test +// void doPartCancel_successful() { +// // 주문 결제 +// doApproval_successful(); +// +// // 부분취소 요청 +// OrderItem canceledItem = testOrderItems.get(0); +// +// PayCancelCommand partCancelCommand = PayCancelCommand.builder() +// .orderId(testOrder.getOrderId()) +// .orderItemId(canceledItem.getId()) +// .canceledQuantity(Quantity.create(2)) +// .paymentStatus(PaymentStatus.PARTIAL_CANCELED) +// .build(); +// +// mockPgStrategy(); +// +// // 부분취소 +// Long partCancelId = paymentUseCase.doPartCancel(partCancelCommand); +// +// // payment 상태 +// assertThat(paymentOutPort.findByOrderId(testOrder.getOrderId()).get().getPaymentStatus()) +// .as("원거래는 승인상태 유지") +// .isEqualTo(PaymentStatus.APPROVED); +// +// assertThat(paymentPartCancelRepository.findById(partCancelId)) +// .isPresent() +// .get() +// .satisfies(partCancel -> { +// assertThat(partCancel) +// .as("insert 부분취소") +// .isNotNull(); +// +// assertThat(partCancel.getCanceledAmt().getValue()) +// .as("부분취소 금액 검증") +// .isEqualTo(2500 * 2) ; +// }); +// +// // orderitem 검증 +// assertThat(orderItemRepository.findById(canceledItem.getId())) +// .isPresent() +// .get() +// .satisfies( +// orderItem -> { +// assertThat(orderItem.isCanceled()).isEqualTo(true); +// } +// ); +// +// assertThat(orderItemRepository.findByOrderIdAndProductIdAndCanceled(partCancelCommand.getOrderId(), canceledItem.getProductId(), false)) +// .isPresent() +// .get() +// .satisfies(oi -> { +// assertThat(oi.getQuantity().value()) +// .as("새로 추가된 orderitem 수량 확인") +// .isEqualTo(canceledItem.getQuantity().minus(partCancelCommand.getCanceledQuantity()).value()); +// assertThat(oi.isCanceled()).isEqualTo(false); +// }); +// +// // order 상태 검증 +// Order refundedOrder = orderRepository.findById(testOrder.getOrderId()).orElseThrow(); +// assertThat(refundedOrder.getStatus()) +// .as("주문상태는 결제완료로 유지") +// .isEqualTo(OrderStatus.PAID); +// } +// +// @DisplayName("부분취소 실패 : 취소 가능 수량 초과") +// @Test +// void doPartCancel_failed() { +// // 주문 결제 +// doApproval_successful(); +// +// // 부분취소 요청 +// PayCancelCommand partCancelCommand = PayCancelCommand.builder() +// .orderId(testOrder.getOrderId()) +// .orderItemId(testOrderItems.get(1).getId()) +// .canceledQuantity(Quantity.create(2)) +// .paymentStatus(PaymentStatus.PARTIAL_CANCELED) +// .build(); +// +// mockPgStrategy(); +// +// // 부분취소 +// assertThatThrownBy(() -> paymentUseCase.doPartCancel(partCancelCommand)) +// .isInstanceOf(BusinessException.class) +// .hasMessageContaining(BusinessError.INVALID_CANCELED_QUANTITY.getMessage()); +// +// assertThat(paymentOutPort.findByOrderId(testOrder.getOrderId()).get().getPaymentStatus()) +// .as("원거래는 승인상태 유지") +// .isEqualTo(PaymentStatus.APPROVED); +// +// PaymentId paymentId = paymentOutPort.findByOrderId(testOrder.getOrderId()).get().getPaymentId(); +// assertThat(paymentPartCancelRepository.existsPaymentPartCancelByApprovedPaymentId(paymentId)) +// .as("not insert 부분취소") +// .isEqualTo(false); +// +// // order 상태 검증 +// Order refundedOrder = orderRepository.findById(testOrder.getOrderId()).orElseThrow(); +// assertThat(refundedOrder.getStatus()).isEqualTo(OrderStatus.PAID) +// .as("주문상태는 결제완료로 유지"); +// } +// +// private void mockPgStrategy() { +// PgStrategy mockPgStrategy = mock(PgStrategy.class); +// +// when(mockPaymentPgRouter.routePg(any(PayMethod.class), any(PayProvider.class))) +// .thenReturn(mockPgStrategy); +// +// when(mockPaymentPgRouter.getPgStrategyByProvider(any(), any())) +// .thenReturn(mockPgStrategy); +// +// when(mockPgStrategy.getPgProvider()) +// .thenReturn(PgProvider.TOSS); +// +// when(mockPgStrategy.processApproval(any())) +// .thenReturn(success_pgResponse); +// +// when(mockPgStrategy.processCancel(any())) +// .thenReturn(cancelResponse); +// } +//} \ No newline at end of file diff --git a/platform/src/test/java/com/commerce/platform/infrastructure/adaptor/CardBinPromotionAdaptorTest.java b/payments/src/test/java/com/commerce/payments/infrastructure/adaptor/CardBinPromotionAdaptorTest.java similarity index 80% rename from platform/src/test/java/com/commerce/platform/infrastructure/adaptor/CardBinPromotionAdaptorTest.java rename to payments/src/test/java/com/commerce/payments/infrastructure/adaptor/CardBinPromotionAdaptorTest.java index 4375dec..b0f4ec8 100644 --- a/platform/src/test/java/com/commerce/platform/infrastructure/adaptor/CardBinPromotionAdaptorTest.java +++ b/payments/src/test/java/com/commerce/payments/infrastructure/adaptor/CardBinPromotionAdaptorTest.java @@ -1,8 +1,9 @@ -package com.commerce.platform.infrastructure.adaptor; +package com.commerce.payments.infrastructure.adaptor; -import com.commerce.platform.core.domain.aggreate.CardBinPromotion; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.vo.promotion.ShinhanPromotionData; + +import com.commerce.payments.domain.aggregate.CardBinPromotion; +import com.commerce.payments.domain.enums.PayProvider; +import com.commerce.payments.domain.vo.promotion.ShinhanPromotionData; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; diff --git a/payments/src/test/resources/application.yml b/payments/src/test/resources/application.yml new file mode 100644 index 0000000..b60eec6 --- /dev/null +++ b/payments/src/test/resources/application.yml @@ -0,0 +1,33 @@ +spring: + application: + name: platform + + datasource: + url: jdbc:mysql://localhost:3308/commerce_dev_db?useSSL=false&serverTimezone=Asia/Seoul&characterEncoding=UTF-8 + username: root + password: je1234 + driver-class-name: com.mysql.cj.jdbc.Driver + hikari: + maximum-pool-size: 10 + connection-timeout: 3000 + + jpa: + hibernate: + ddl-auto: update + show-sql: true + properties: + hibernate: + format_sql: true + dialect: org.hibernate.dialect.MySQLDialect + data: + redis: + host: 127.0.0.1 + port: 6379 + password: je1234 + + docker: + compose: + enabled: false + +aes256: + key: 61qDonoZcEtIEvUZVPkIKIYovHH82rXtK7T1g/rcc1k= \ No newline at end of file diff --git a/platform/build.gradle b/platform/build.gradle index 865ab10..0780b34 100644 --- a/platform/build.gradle +++ b/platform/build.gradle @@ -1,3 +1,7 @@ plugins { id 'myproject-convention' } + +dependencies { + implementation project(':shared') +} \ No newline at end of file diff --git a/platform/src/main/java/com/commerce/platform/bootstrap/admin/CouponAdController.java b/platform/src/main/java/com/commerce/platform/bootstrap/admin/CouponAdController.java index dccc4b1..f08c6ae 100644 --- a/platform/src/main/java/com/commerce/platform/bootstrap/admin/CouponAdController.java +++ b/platform/src/main/java/com/commerce/platform/bootstrap/admin/CouponAdController.java @@ -1,7 +1,7 @@ package com.commerce.platform.bootstrap.admin; import com.commerce.platform.bootstrap.dto.coupon.CouponRequest; -import com.commerce.platform.core.application.in.CouponUseCase; +import com.commerce.platform.core.application.port.in.CouponUseCase; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; diff --git a/platform/src/main/java/com/commerce/platform/bootstrap/admin/ProductAdController.java b/platform/src/main/java/com/commerce/platform/bootstrap/admin/ProductAdController.java index 4527757..790ac85 100644 --- a/platform/src/main/java/com/commerce/platform/bootstrap/admin/ProductAdController.java +++ b/platform/src/main/java/com/commerce/platform/bootstrap/admin/ProductAdController.java @@ -2,10 +2,10 @@ import com.commerce.platform.bootstrap.dto.product.CreateProductRequest; import com.commerce.platform.bootstrap.dto.product.UpdateStockRequest; -import com.commerce.platform.core.application.in.ProductUseCase; -import com.commerce.platform.core.application.in.dto.UpdateStockCommand; +import com.commerce.platform.core.application.port.in.ProductUseCase; +import com.commerce.platform.core.application.port.in.dto.UpdateStockCommand; import com.commerce.platform.core.domain.vo.ProductId; -import com.commerce.platform.core.domain.vo.Quantity; +import com.commerce.shared.vo.Quantity; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; diff --git a/platform/src/main/java/com/commerce/platform/bootstrap/customer/CouponController.java b/platform/src/main/java/com/commerce/platform/bootstrap/customer/CouponController.java index 29cb99d..4efd8e7 100644 --- a/platform/src/main/java/com/commerce/platform/bootstrap/customer/CouponController.java +++ b/platform/src/main/java/com/commerce/platform/bootstrap/customer/CouponController.java @@ -1,9 +1,9 @@ package com.commerce.platform.bootstrap.customer; -import com.commerce.platform.core.application.in.CouponIssueUseCase; -import com.commerce.platform.core.application.in.dto.CouponView; +import com.commerce.platform.core.application.port.in.CouponIssueUseCase; +import com.commerce.platform.core.application.port.in.dto.CouponView; import com.commerce.platform.core.domain.vo.CouponId; -import com.commerce.platform.core.domain.vo.CustomerId; +import com.commerce.shared.vo.CustomerId; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; diff --git a/platform/src/main/java/com/commerce/platform/bootstrap/customer/CustomerController.java b/platform/src/main/java/com/commerce/platform/bootstrap/customer/CustomerController.java index c2bfa86..cb3c9af 100644 --- a/platform/src/main/java/com/commerce/platform/bootstrap/customer/CustomerController.java +++ b/platform/src/main/java/com/commerce/platform/bootstrap/customer/CustomerController.java @@ -1,8 +1,6 @@ package com.commerce.platform.bootstrap.customer; import com.commerce.platform.bootstrap.dto.customer.RegistryCardRequest; -import com.commerce.platform.core.application.in.CustomerUseCase; -import com.commerce.platform.core.application.in.dto.RegistryCardCommand; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -16,12 +14,12 @@ @RestController public class CustomerController { - private final CustomerUseCase customerUsecase; +// private final CustomerUseCase customerUsecase; @PostMapping("/card") public ResponseEntity registryCard(@Valid @RequestBody RegistryCardRequest cardRequest) { - RegistryCardCommand command = cardRequest.to(); - customerUsecase.registryPayCard(command); +// RegistryCardCommand command = cardRequest.to(); +// customerUsecase.registryPayCard(command); return ResponseEntity.ok("성공"); } diff --git a/platform/src/main/java/com/commerce/platform/bootstrap/customer/OrderController.java b/platform/src/main/java/com/commerce/platform/bootstrap/customer/OrderController.java index a17f072..0b7d3a7 100644 --- a/platform/src/main/java/com/commerce/platform/bootstrap/customer/OrderController.java +++ b/platform/src/main/java/com/commerce/platform/bootstrap/customer/OrderController.java @@ -2,12 +2,12 @@ import com.commerce.platform.bootstrap.dto.order.OrderRefundRequest; import com.commerce.platform.bootstrap.dto.order.OrderRequest; -import com.commerce.platform.core.application.in.OrderUseCase; -import com.commerce.platform.core.application.in.dto.CreateOrderCommand; -import com.commerce.platform.core.application.in.dto.OrderDetailResponse; -import com.commerce.platform.core.application.in.dto.OrderResponse; -import com.commerce.platform.core.domain.vo.CustomerId; -import com.commerce.platform.core.domain.vo.OrderId; +import com.commerce.platform.core.application.port.in.OrderUseCase; +import com.commerce.platform.core.application.port.in.dto.CreateOrderCommand; +import com.commerce.platform.core.application.port.in.dto.OrderDetailResponse; +import com.commerce.platform.core.application.port.in.dto.OrderResponse; +import com.commerce.shared.vo.CustomerId; +import com.commerce.shared.vo.OrderId; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; diff --git a/platform/src/main/java/com/commerce/platform/bootstrap/customer/PaymentController.java b/platform/src/main/java/com/commerce/platform/bootstrap/customer/PaymentController.java index a50e1b6..d75e96f 100644 --- a/platform/src/main/java/com/commerce/platform/bootstrap/customer/PaymentController.java +++ b/platform/src/main/java/com/commerce/platform/bootstrap/customer/PaymentController.java @@ -1,100 +1,101 @@ -package com.commerce.platform.bootstrap.customer; - -import com.commerce.platform.bootstrap.dto.payment.PaymentCancelRequest; -import com.commerce.platform.bootstrap.dto.payment.PaymentRequest; -import com.commerce.platform.core.application.in.PaymentUseCase; -import com.commerce.platform.core.application.in.dto.PayCancelCommand; -import com.commerce.platform.core.application.in.dto.PayOrderCommand; -import com.commerce.platform.core.application.in.dto.PayResult; -import com.commerce.platform.core.domain.enums.PaymentStatus; -import com.commerce.platform.core.domain.vo.OrderId; -import com.commerce.platform.shared.exception.BusinessException; -import jakarta.validation.Valid; -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.util.Map; - -@RequiredArgsConstructor -@RequestMapping("/payments") -@RestController -public class PaymentController { - private final PaymentUseCase paymentUseCase; - - @PostMapping("/approval") - public ResponseEntity createPayment(@Valid @RequestBody PaymentRequest paymentRequest) { - PayResult result = null; - - try { - PayOrderCommand command = new PayOrderCommand( - OrderId.of(paymentRequest.orderId()), - null, - paymentRequest.installment(), - paymentRequest.payMethod(), - paymentRequest.payProvider() - ); - - paymentUseCase.doApproval(command); - } catch (BusinessException e) { - result = new PayResult.Failed(e.getCode(), e.getMessage()); - } catch (Exception e) { - result = new PayResult.Failed("9999", "승인 처리 중 오류가 발생했습니다"); - } - - return ResponseEntity.ok(result); - } - - @PatchMapping("/cancel") - public ResponseEntity fullCancel(@Valid @RequestBody PaymentCancelRequest cancelRequest) { - PayResult result = null; - - try { - PayCancelCommand cancelCommand = PayCancelCommand.builder() - .orderId(cancelRequest.orderId()) - .paymentStatus(PaymentStatus.FULL_CANCELED) - .build(); - - paymentUseCase.doCancel(cancelCommand); - } catch (BusinessException e) { - result = new PayResult.Failed(e.getCode(), e.getMessage()); - } catch (Exception e) { - result = new PayResult.Failed("9999", "전체취소 처리 중 오류가 발생했습니다"); - } - - return ResponseEntity.ok(result); - } - - @PatchMapping("/partial-cancel") - public ResponseEntity partialCancel(@Valid @RequestBody PaymentCancelRequest cancelRequest) { - PayResult result = null; - - try { - PayCancelCommand cancelCommand = PayCancelCommand.builder() - .orderId(cancelRequest.orderId()) - .orderItemId(cancelRequest.orderItemId()) - .canceledQuantity(cancelRequest.canceledQuantity()) - .paymentStatus(PaymentStatus.FULL_CANCELED) - .build(); - - paymentUseCase.doPartCancel(cancelCommand); - } catch (BusinessException e) { - result = new PayResult.Failed(e.getCode(), e.getMessage()); - } catch (Exception e) { - result = new PayResult.Failed("9999", "부분취소 처리 중 오류가 발생했습니다"); - } - - return ResponseEntity.ok(result); - } - - @PostMapping("/registry-card/{cardId}") - public ResponseEntity createPaymentWithRegistryCard( - @PathVariable Long cardId, - @RequestBody Map body) { - - // todo - paymentUseCase.doApprovalWithCardId(cardId); - - return ResponseEntity.ok("성공"); - } -} +//package com.commerce.platform.bootstrap.customer; +// +//import com.commerce.platform.bootstrap.dto.payment.PaymentCancelRequest; +//import com.commerce.platform.bootstrap.dto.payment.PaymentRequest; +//import com.commerce.payments.application.port.in.PaymentUseCase; +//import com.commerce.payments.application.port.in.command.PayCancelCommand; +//import com.commerce.payments.application.port.in.command.PayOrderCommand; +//import com.commerce.payments.application.port.in.command.PayResult; +//import com.commerce.payments.domain.enums.PaymentStatus; +//import com.commerce.shared.exception.BusinessException; +//import com.commerce.shared.vo.OrderId; +//import jakarta.validation.Valid; +//import lombok.RequiredArgsConstructor; +//import org.springframework.http.ResponseEntity; +//import org.springframework.web.bind.annotation.*; +// +//import java.util.Map; +// +//@RequiredArgsConstructor +//@RequestMapping("/payments") +//@RestController +//public class PaymentController { +// private final PaymentUseCase paymentUseCase; +// +// @PostMapping("/approval") +// public ResponseEntity createPayment(@Valid @RequestBody PaymentRequest paymentRequest) { +// PayResult result = null; +// +// try { +// PayOrderCommand command = new PayOrderCommand( +// OrderId.of(paymentRequest.orderId()), +// null, +// paymentRequest.installment(), +// paymentRequest.payMethod(), +// paymentRequest.payProvider(), +// null +// ); +// +// paymentUseCase.doApproval(command); +// } catch (BusinessException e) { +// result = new PayResult.Failed(e.getCode(), e.getMessage()); +// } catch (Exception e) { +// result = new PayResult.Failed("9999", "승인 처리 중 오류가 발생했습니다"); +// } +// +// return ResponseEntity.ok(result); +// } +// +// @PatchMapping("/cancel") +// public ResponseEntity fullCancel(@Valid @RequestBody PaymentCancelRequest cancelRequest) { +// PayResult result = null; +// +// try { +// PayCancelCommand cancelCommand = PayCancelCommand.builder() +// .orderId(cancelRequest.orderId()) +// .paymentStatus(PaymentStatus.FULL_CANCELED) +// .build(); +// +// paymentUseCase.doCancel(cancelCommand); +// } catch (BusinessException e) { +// result = new PayResult.Failed(e.getCode(), e.getMessage()); +// } catch (Exception e) { +// result = new PayResult.Failed("9999", "전체취소 처리 중 오류가 발생했습니다"); +// } +// +// return ResponseEntity.ok(result); +// } +// +// @PatchMapping("/partial-cancel") +// public ResponseEntity partialCancel(@Valid @RequestBody PaymentCancelRequest cancelRequest) { +// PayResult result = null; +// +// try { +// PayCancelCommand cancelCommand = PayCancelCommand.builder() +// .orderId(cancelRequest.orderId()) +// .orderItemId(cancelRequest.orderItemId()) +// .canceledQuantity(cancelRequest.canceledQuantity()) +// .paymentStatus(PaymentStatus.FULL_CANCELED) +// .build(); +// +// paymentUseCase.doPartCancel(cancelCommand); +// } catch (BusinessException e) { +// result = new PayResult.Failed(e.getCode(), e.getMessage()); +// } catch (Exception e) { +// result = new PayResult.Failed("9999", "부분취소 처리 중 오류가 발생했습니다"); +// } +// +// return ResponseEntity.ok(result); +// } +// +// @PostMapping("/registry-card/{cardId}") +// public ResponseEntity createPaymentWithRegistryCard( +// @PathVariable Long cardId, +// @RequestBody Map body) { +// +// // todo +// paymentUseCase.doApprovalWithCardId(cardId); +// +// return ResponseEntity.ok("성공"); +// } +//} diff --git a/platform/src/main/java/com/commerce/platform/bootstrap/customer/ProductController.java b/platform/src/main/java/com/commerce/platform/bootstrap/customer/ProductController.java index 40a299c..1ff054d 100644 --- a/platform/src/main/java/com/commerce/platform/bootstrap/customer/ProductController.java +++ b/platform/src/main/java/com/commerce/platform/bootstrap/customer/ProductController.java @@ -1,8 +1,8 @@ package com.commerce.platform.bootstrap.customer; import com.commerce.platform.bootstrap.dto.product.ProductInfo; -import com.commerce.platform.core.application.in.ProductUseCase; -import com.commerce.platform.core.application.in.dto.ProductDetail; +import com.commerce.platform.core.application.port.in.ProductUseCase; +import com.commerce.platform.core.application.port.in.dto.ProductDetail; import com.commerce.platform.core.domain.vo.ProductId; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; diff --git a/platform/src/main/java/com/commerce/platform/bootstrap/dto/customer/RegistryCardRequest.java b/platform/src/main/java/com/commerce/platform/bootstrap/dto/customer/RegistryCardRequest.java index 35100e7..b449545 100644 --- a/platform/src/main/java/com/commerce/platform/bootstrap/dto/customer/RegistryCardRequest.java +++ b/platform/src/main/java/com/commerce/platform/bootstrap/dto/customer/RegistryCardRequest.java @@ -1,8 +1,5 @@ package com.commerce.platform.bootstrap.dto.customer; -import com.commerce.platform.core.application.in.dto.RegistryCardCommand; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.vo.CustomerId; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; @@ -38,16 +35,16 @@ public record RegistryCardRequest( @Size(min = 1, max = 20) String cardNickName ) { - public RegistryCardCommand to() { - return new RegistryCardCommand( - CustomerId.of(this.customerId), - PayProvider.getPayProviderByValue(this.payProvider), - this.cardNumber, - this.password, - this.expiryMonth, - this.expiryYear, - this.birthDate, - this.cardNickName - ); - } +// public RegistryCardCommand to() { +// return new RegistryCardCommand( +// CustomerId.of(this.customerId), +// PayProvider.getPayProviderByValue(this.payProvider), +// this.cardNumber, +// this.password, +// this.expiryMonth, +// this.expiryYear, +// this.birthDate, +// this.cardNickName +// ); +// } } diff --git a/platform/src/main/java/com/commerce/platform/bootstrap/dto/payment/PaymentCancelRequest.java b/platform/src/main/java/com/commerce/platform/bootstrap/dto/payment/PaymentCancelRequest.java index d8ded64..991ffdc 100644 --- a/platform/src/main/java/com/commerce/platform/bootstrap/dto/payment/PaymentCancelRequest.java +++ b/platform/src/main/java/com/commerce/platform/bootstrap/dto/payment/PaymentCancelRequest.java @@ -1,8 +1,7 @@ package com.commerce.platform.bootstrap.dto.payment; -import com.commerce.platform.core.domain.enums.PaymentStatus; -import com.commerce.platform.core.domain.vo.OrderId; -import com.commerce.platform.core.domain.vo.Quantity; +import com.commerce.shared.vo.OrderId; +import com.commerce.shared.vo.Quantity; import jakarta.validation.constraints.NotBlank; /** @@ -17,5 +16,5 @@ public record PaymentCancelRequest( Quantity canceledQuantity, // 해당 orderItem의 취소 개수 @NotBlank - PaymentStatus paymentStatus + String paymentStatus ) {} \ No newline at end of file diff --git a/platform/src/main/java/com/commerce/platform/bootstrap/dto/payment/PaymentRequest.java b/platform/src/main/java/com/commerce/platform/bootstrap/dto/payment/PaymentRequest.java index 7bebb06..7c62627 100644 --- a/platform/src/main/java/com/commerce/platform/bootstrap/dto/payment/PaymentRequest.java +++ b/platform/src/main/java/com/commerce/platform/bootstrap/dto/payment/PaymentRequest.java @@ -1,7 +1,5 @@ package com.commerce.platform.bootstrap.dto.payment; -import com.commerce.platform.core.domain.enums.PayMethod; -import com.commerce.platform.core.domain.enums.PayProvider; import jakarta.validation.constraints.NotBlank; /** @@ -12,11 +10,11 @@ public record PaymentRequest( String orderId, @NotBlank - PayMethod payMethod, + String payMethod, @NotBlank - PayProvider payProvider, + String payProvider, @NotBlank - String installment + int installment ) { } diff --git a/platform/src/main/java/com/commerce/platform/bootstrap/dto/product/CreateProductRequest.java b/platform/src/main/java/com/commerce/platform/bootstrap/dto/product/CreateProductRequest.java index 6ea9a91..b74c6d5 100644 --- a/platform/src/main/java/com/commerce/platform/bootstrap/dto/product/CreateProductRequest.java +++ b/platform/src/main/java/com/commerce/platform/bootstrap/dto/product/CreateProductRequest.java @@ -2,9 +2,9 @@ import com.commerce.platform.core.domain.aggreate.Product; import com.commerce.platform.core.domain.enums.ProductStatus; -import com.commerce.platform.core.domain.vo.Money; import com.commerce.platform.core.domain.vo.ProductId; -import com.commerce.platform.core.domain.vo.Quantity; +import com.commerce.shared.vo.Money; +import com.commerce.shared.vo.Quantity; import jakarta.validation.constraints.*; public record CreateProductRequest( @@ -33,7 +33,7 @@ public static Product to(CreateProductRequest request) { .productId(ProductId.create()) .productName(request.name()) .description(request.description()) - .price(Money.create(request.price())) + .price(Money.of(request.price())) .stockQuantity(quantity) .status(ProductStatus.fromStockQuantity(quantity)) .build(); diff --git a/platform/src/main/java/com/commerce/platform/bootstrap/exception/GlobalExceptionHandler.java b/platform/src/main/java/com/commerce/platform/bootstrap/exception/GlobalExceptionHandler.java index 70dd5bb..032c7a7 100644 --- a/platform/src/main/java/com/commerce/platform/bootstrap/exception/GlobalExceptionHandler.java +++ b/platform/src/main/java/com/commerce/platform/bootstrap/exception/GlobalExceptionHandler.java @@ -1,7 +1,7 @@ package com.commerce.platform.bootstrap.exception; -import com.commerce.platform.shared.exception.BusinessException; -import com.commerce.platform.shared.exception.LockUnavailableException; +import com.commerce.shared.exception.BusinessException; +import com.commerce.platform.exception.LockUnavailableException; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.log4j.Log4j2; import org.springframework.http.HttpStatus; @@ -14,8 +14,8 @@ import java.util.HashMap; import java.util.Map; -import static com.commerce.platform.shared.exception.BusinessError.INVALID_REQUEST_VALUE; -import static com.commerce.platform.shared.exception.BusinessError.UNKNOWN_ERROR; +import static com.commerce.shared.exception.BusinessError.INVALID_REQUEST_VALUE; +import static com.commerce.shared.exception.BusinessError.UNKNOWN_ERROR; @Log4j2 @RestControllerAdvice diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/CustomerUseCase.java b/platform/src/main/java/com/commerce/platform/core/application/in/CustomerUseCase.java deleted file mode 100644 index 6422641..0000000 --- a/platform/src/main/java/com/commerce/platform/core/application/in/CustomerUseCase.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.commerce.platform.core.application.in; - -import com.commerce.platform.core.application.in.dto.RegistryCardCommand; - -public interface CustomerUseCase { - void registryPayCard(RegistryCardCommand command); -} diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/PaymentUseCase.java b/platform/src/main/java/com/commerce/platform/core/application/in/PaymentUseCase.java deleted file mode 100644 index 2529d21..0000000 --- a/platform/src/main/java/com/commerce/platform/core/application/in/PaymentUseCase.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.commerce.platform.core.application.in; - -import com.commerce.platform.core.application.in.dto.PayCancelCommand; -import com.commerce.platform.core.application.in.dto.PayOrderCommand; - -public interface PaymentUseCase { - void doApproval(PayOrderCommand command); - void doCancel(PayCancelCommand cancelCommand); - Long doPartCancel(PayCancelCommand cancelCommand); - void doApprovalWithCardId(Long cardId); // 등록된 카드로 결제 -} diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/dto/PayCancelCommand.java b/platform/src/main/java/com/commerce/platform/core/application/in/dto/PayCancelCommand.java deleted file mode 100644 index 281d3ca..0000000 --- a/platform/src/main/java/com/commerce/platform/core/application/in/dto/PayCancelCommand.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.commerce.platform.core.application.in.dto; - -import com.commerce.platform.core.domain.enums.PayMethod; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.enums.PaymentStatus; -import com.commerce.platform.core.domain.enums.PgProvider; -import com.commerce.platform.core.domain.vo.Money; -import com.commerce.platform.core.domain.vo.OrderId; -import com.commerce.platform.core.domain.vo.Quantity; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; - -/** - * 전체/부분 취소 처리 객체 - */ -@Setter -@Getter -@Builder -public class PayCancelCommand { - private OrderId orderId; - private Long orderItemId; // 취소할 orderItem - private Quantity canceledQuantity; // 해당 orderItem의 취소 개수 - private PaymentStatus paymentStatus; - - // 이후 계산 및 db데이터 기반으로 세팅됨 - private Money canceledAmount; - private PayMethod payMethod; - private PayProvider payProvider; - private PgProvider pgProvider; -} diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/dto/PayOrderCommand.java b/platform/src/main/java/com/commerce/platform/core/application/in/dto/PayOrderCommand.java deleted file mode 100644 index 339c032..0000000 --- a/platform/src/main/java/com/commerce/platform/core/application/in/dto/PayOrderCommand.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.commerce.platform.core.application.in.dto; - -import com.commerce.platform.core.domain.enums.PayMethod; -import com.commerce.platform.core.domain.enums.PayProvider; -import com.commerce.platform.core.domain.enums.PaymentStatus; -import com.commerce.platform.core.domain.vo.Money; -import com.commerce.platform.core.domain.vo.OrderId; -import lombok.AllArgsConstructor; -import lombok.Data; - -@AllArgsConstructor -@Data -public class PayOrderCommand { - private OrderId orderId; - private Money approvedAmount; - private String installment; - private PayMethod payMethod; - private PayProvider payProvider; - private final PaymentStatus paymentStatus = PaymentStatus.APPROVED; -} diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/dto/PayResult.java b/platform/src/main/java/com/commerce/platform/core/application/in/dto/PayResult.java deleted file mode 100644 index 25ced15..0000000 --- a/platform/src/main/java/com/commerce/platform/core/application/in/dto/PayResult.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.commerce.platform.core.application.in.dto; - -/** - * 결제 응답 - */ -public interface PayResult { - - record Success( - String paymentId, - String message - ) implements PayResult{} - - record Failed( - String errorCode, - String message - ) implements PayResult{} - -} diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/CardPay.java b/platform/src/main/java/com/commerce/platform/core/application/out/CardPay.java deleted file mode 100644 index 7ec9bb7..0000000 --- a/platform/src/main/java/com/commerce/platform/core/application/out/CardPay.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.commerce.platform.core.application.out; - -import com.commerce.platform.core.application.in.dto.PayCancelCommand; -import com.commerce.platform.core.application.in.dto.PayOrderCommand; -import com.commerce.platform.core.application.out.dto.PgPayResponse; - -public interface CardPay { - PgPayResponse approveCard(PayOrderCommand command); - PgPayResponse cancelCard(PayCancelCommand command); -} diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/EasyPay.java b/platform/src/main/java/com/commerce/platform/core/application/out/EasyPay.java deleted file mode 100644 index a4270a8..0000000 --- a/platform/src/main/java/com/commerce/platform/core/application/out/EasyPay.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.commerce.platform.core.application.out; - -import com.commerce.platform.core.application.in.dto.PayCancelCommand; -import com.commerce.platform.core.application.in.dto.PayOrderCommand; -import com.commerce.platform.core.application.out.dto.PgPayResponse; - -public interface EasyPay { - PgPayResponse approveEasyPay(PayOrderCommand command); - PgPayResponse cancelEasyPay(PayCancelCommand command); -} diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/PgStrategy.java b/platform/src/main/java/com/commerce/platform/core/application/out/PgStrategy.java deleted file mode 100644 index b3b293b..0000000 --- a/platform/src/main/java/com/commerce/platform/core/application/out/PgStrategy.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.commerce.platform.core.application.out; - -import com.commerce.platform.core.application.in.dto.PayCancelCommand; -import com.commerce.platform.core.application.in.dto.PayOrderCommand; -import com.commerce.platform.core.application.out.dto.PgPayResponse; -import com.commerce.platform.core.domain.enums.PgProvider; - -public abstract class PgStrategy { - - /** - * pg사별 요청에 따라 [Card | Easy | Phone]PayService 구현체 실행한다. - * @param request todo dto - * @return todo 결재응답dto - */ - public abstract String process(String request); - - public abstract PgProvider getPgProvider(); - - // todo tmp - public PgPayResponse processApproval(PayOrderCommand payOrdercommand) { - return null; - } - - // todo tmp - public PgPayResponse processCancel(PayCancelCommand cancelCommand) { - return null; - } -} diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/PhonePay.java b/platform/src/main/java/com/commerce/platform/core/application/out/PhonePay.java deleted file mode 100644 index 70c7526..0000000 --- a/platform/src/main/java/com/commerce/platform/core/application/out/PhonePay.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.commerce.platform.core.application.out; - -import com.commerce.platform.core.application.in.dto.PayCancelCommand; -import com.commerce.platform.core.application.in.dto.PayOrderCommand; -import com.commerce.platform.core.application.out.dto.PgPayResponse; - -public interface PhonePay { - PgPayResponse approvePhone(PayOrderCommand command); - PgPayResponse cancelPhone(PayCancelCommand command); -} diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/dto/PgPayResponse.java b/platform/src/main/java/com/commerce/platform/core/application/out/dto/PgPayResponse.java deleted file mode 100644 index 7d6ea9c..0000000 --- a/platform/src/main/java/com/commerce/platform/core/application/out/dto/PgPayResponse.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.commerce.platform.core.application.out.dto; - -public record PgPayResponse ( - String pgTid, - String responseCode, // pg사 응답코드 - String responseMessage, // pg사 응답메시지 - boolean isSuccess -) {} diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/CouponIssueUseCase.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/CouponIssueUseCase.java similarity index 58% rename from platform/src/main/java/com/commerce/platform/core/application/in/CouponIssueUseCase.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/CouponIssueUseCase.java index 997d514..7840d45 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/CouponIssueUseCase.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/CouponIssueUseCase.java @@ -1,8 +1,8 @@ -package com.commerce.platform.core.application.in; +package com.commerce.platform.core.application.port.in; -import com.commerce.platform.core.application.in.dto.CouponView; +import com.commerce.platform.core.application.port.in.dto.CouponView; import com.commerce.platform.core.domain.vo.CouponId; -import com.commerce.platform.core.domain.vo.CustomerId; +import com.commerce.shared.vo.CustomerId; import java.util.List; diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/CouponIssueUseCaseImpl.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/CouponIssueUseCaseImpl.java similarity index 85% rename from platform/src/main/java/com/commerce/platform/core/application/in/CouponIssueUseCaseImpl.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/CouponIssueUseCaseImpl.java index 384622b..97fab2d 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/CouponIssueUseCaseImpl.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/CouponIssueUseCaseImpl.java @@ -1,15 +1,15 @@ -package com.commerce.platform.core.application.in; +package com.commerce.platform.core.application.port.in; -import com.commerce.platform.core.application.in.dto.CouponView; -import com.commerce.platform.core.application.out.CouponIssueOutPort; -import com.commerce.platform.core.application.out.CouponOutPort; +import com.commerce.platform.core.application.port.in.dto.CouponView; +import com.commerce.platform.core.application.port.out.CouponIssueOutPort; +import com.commerce.platform.core.application.port.out.CouponOutPort; import com.commerce.platform.core.domain.service.LockFacade; import com.commerce.platform.core.domain.aggreate.Coupon; import com.commerce.platform.core.domain.aggreate.CouponIssues; import com.commerce.platform.core.domain.vo.CouponId; import com.commerce.platform.core.domain.vo.CouponIssueId; -import com.commerce.platform.core.domain.vo.CustomerId; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.vo.CustomerId; +import com.commerce.shared.exception.BusinessException; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; @@ -21,8 +21,8 @@ import java.util.function.Function; import java.util.stream.Collectors; -import static com.commerce.platform.shared.exception.BusinessError.DUPLICATE_ISSUED_COUPON; -import static com.commerce.platform.shared.exception.BusinessError.INVALID_COUPON; +import static com.commerce.shared.exception.BusinessError.DUPLICATE_ISSUED_COUPON; +import static com.commerce.shared.exception.BusinessError.INVALID_COUPON; @Log4j2 @RequiredArgsConstructor diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/CouponUseCase.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/CouponUseCase.java similarity index 79% rename from platform/src/main/java/com/commerce/platform/core/application/in/CouponUseCase.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/CouponUseCase.java index bb9b068..60034a7 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/CouponUseCase.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/CouponUseCase.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.application.in; +package com.commerce.platform.core.application.port.in; import com.commerce.platform.bootstrap.dto.coupon.CouponRequest; import com.commerce.platform.core.domain.aggreate.Coupon; diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/CouponUseCaseImpl.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/CouponUseCaseImpl.java similarity index 87% rename from platform/src/main/java/com/commerce/platform/core/application/in/CouponUseCaseImpl.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/CouponUseCaseImpl.java index e68f719..d0e396a 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/CouponUseCaseImpl.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/CouponUseCaseImpl.java @@ -1,7 +1,7 @@ -package com.commerce.platform.core.application.in; +package com.commerce.platform.core.application.port.in; import com.commerce.platform.bootstrap.dto.coupon.CouponRequest; -import com.commerce.platform.core.application.out.CouponOutPort; +import com.commerce.platform.core.application.port.out.CouponOutPort; import com.commerce.platform.core.domain.aggreate.Coupon; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/OrderUseCase.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/OrderUseCase.java similarity index 54% rename from platform/src/main/java/com/commerce/platform/core/application/in/OrderUseCase.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/OrderUseCase.java index c1ef457..831cf63 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/OrderUseCase.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/OrderUseCase.java @@ -1,11 +1,11 @@ -package com.commerce.platform.core.application.in; +package com.commerce.platform.core.application.port.in; import com.commerce.platform.bootstrap.dto.order.OrderRefundRequest; -import com.commerce.platform.core.application.in.dto.CreateOrderCommand; -import com.commerce.platform.core.application.in.dto.OrderDetailResponse; -import com.commerce.platform.core.application.in.dto.OrderResponse; -import com.commerce.platform.core.domain.vo.CustomerId; -import com.commerce.platform.core.domain.vo.OrderId; +import com.commerce.platform.core.application.port.in.dto.CreateOrderCommand; +import com.commerce.platform.core.application.port.in.dto.OrderDetailResponse; +import com.commerce.platform.core.application.port.in.dto.OrderResponse; +import com.commerce.shared.vo.CustomerId; +import com.commerce.shared.vo.OrderId; import java.util.List; diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/OrderUseCaseImpl.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/OrderUseCaseImpl.java similarity index 87% rename from platform/src/main/java/com/commerce/platform/core/application/in/OrderUseCaseImpl.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/OrderUseCaseImpl.java index c09ea26..306244e 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/OrderUseCaseImpl.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/OrderUseCaseImpl.java @@ -1,15 +1,19 @@ -package com.commerce.platform.core.application.in; +package com.commerce.platform.core.application.port.in; import com.commerce.platform.bootstrap.dto.order.OrderRefundRequest; -import com.commerce.platform.core.application.in.dto.CreateOrderCommand; -import com.commerce.platform.core.application.in.dto.CreateOrderCommand.OrderItemCommand; -import com.commerce.platform.core.application.in.dto.OrderDetailResponse; -import com.commerce.platform.core.application.in.dto.OrderDetailResponse.OrderItemResponse; -import com.commerce.platform.core.application.in.dto.OrderResponse; +import com.commerce.platform.core.application.port.in.dto.CreateOrderCommand; +import com.commerce.platform.core.application.port.in.dto.CreateOrderCommand.OrderItemCommand; +import com.commerce.platform.core.application.port.in.dto.OrderDetailResponse; +import com.commerce.platform.core.application.port.in.dto.OrderDetailResponse.OrderItemResponse; +import com.commerce.platform.core.application.port.in.dto.OrderResponse; import com.commerce.platform.core.application.out.*; +import com.commerce.platform.core.application.port.out.*; import com.commerce.platform.core.domain.aggreate.*; import com.commerce.platform.core.domain.vo.*; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.exception.BusinessException; +import com.commerce.shared.vo.CustomerId; +import com.commerce.shared.vo.Money; +import com.commerce.shared.vo.OrderId; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -18,7 +22,7 @@ import java.util.function.Function; import java.util.stream.Collectors; -import static com.commerce.platform.shared.exception.BusinessError.*; +import static com.commerce.shared.exception.BusinessError.*; @RequiredArgsConstructor @Service @@ -131,7 +135,7 @@ public OrderResponse refundOrder(OrderId orderId, OrderRefundRequest request) { * 쿠폰조회 및 적용 */ private Money applyCoupon(Order order, CouponId couponId) { - if(couponId == null) return Money.create(0); + if(couponId == null) return Money.of(0); CouponIssueId couponIssueId = new CouponIssueId(couponId, order.getCustomerId()); // 발급된 쿠폰 확인 @@ -169,7 +173,7 @@ private Money calculateTotalAmountFromProducts(List orderItems) { return product.getPrice() .multiply(item.getQuantity()); }) - .reduce(Money.create(0), Money::add); + .reduce(Money.of(0), Money::add); } } diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/ProductUseCase.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/ProductUseCase.java similarity index 61% rename from platform/src/main/java/com/commerce/platform/core/application/in/ProductUseCase.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/ProductUseCase.java index c1ba645..d7aa83b 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/ProductUseCase.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/ProductUseCase.java @@ -1,10 +1,10 @@ -package com.commerce.platform.core.application.in; +package com.commerce.platform.core.application.port.in; -import com.commerce.platform.core.application.in.dto.ProductDetail; -import com.commerce.platform.core.application.in.dto.UpdateStockCommand; +import com.commerce.platform.core.application.port.in.dto.ProductDetail; +import com.commerce.platform.core.application.port.in.dto.UpdateStockCommand; import com.commerce.platform.core.domain.aggreate.Product; import com.commerce.platform.core.domain.vo.ProductId; -import com.commerce.platform.core.domain.vo.Quantity; +import com.commerce.shared.vo.Quantity; import java.util.List; diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/ProductUseCaseImpl.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/ProductUseCaseImpl.java similarity index 77% rename from platform/src/main/java/com/commerce/platform/core/application/in/ProductUseCaseImpl.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/ProductUseCaseImpl.java index 84c1483..221c243 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/ProductUseCaseImpl.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/ProductUseCaseImpl.java @@ -1,18 +1,18 @@ -package com.commerce.platform.core.application.in; +package com.commerce.platform.core.application.port.in; -import com.commerce.platform.core.application.in.dto.ProductDetail; -import com.commerce.platform.core.application.out.ProductOutputPort; -import com.commerce.platform.core.application.in.dto.UpdateStockCommand; +import com.commerce.platform.core.application.port.in.dto.ProductDetail; +import com.commerce.platform.core.application.port.out.ProductOutputPort; +import com.commerce.platform.core.application.port.in.dto.UpdateStockCommand; import com.commerce.platform.core.domain.aggreate.Product; import com.commerce.platform.core.domain.vo.ProductId; -import com.commerce.platform.core.domain.vo.Quantity; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.vo.Quantity; +import com.commerce.shared.exception.BusinessException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.List; -import static com.commerce.platform.shared.exception.BusinessError.PRODUCT_NOT_FOUND; +import static com.commerce.shared.exception.BusinessError.PRODUCT_NOT_FOUND; @RequiredArgsConstructor @Service diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/dto/CouponView.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/dto/CouponView.java similarity index 79% rename from platform/src/main/java/com/commerce/platform/core/application/in/dto/CouponView.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/dto/CouponView.java index 7f82818..a6bb9e2 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/dto/CouponView.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/dto/CouponView.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.application.in.dto; +package com.commerce.platform.core.application.port.in.dto; public record CouponView( String couponName, diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/dto/CreateOrderCommand.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/dto/CreateOrderCommand.java similarity index 86% rename from platform/src/main/java/com/commerce/platform/core/application/in/dto/CreateOrderCommand.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/dto/CreateOrderCommand.java index 3d30d58..4ea60da 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/dto/CreateOrderCommand.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/dto/CreateOrderCommand.java @@ -1,10 +1,10 @@ -package com.commerce.platform.core.application.in.dto; +package com.commerce.platform.core.application.port.in.dto; import com.commerce.platform.bootstrap.dto.order.OrderRequest; import com.commerce.platform.core.domain.vo.CouponId; -import com.commerce.platform.core.domain.vo.CustomerId; +import com.commerce.shared.vo.CustomerId; import com.commerce.platform.core.domain.vo.ProductId; -import com.commerce.platform.core.domain.vo.Quantity; +import com.commerce.shared.vo.Quantity; import java.util.List; diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/dto/OrderDetailResponse.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/dto/OrderDetailResponse.java similarity index 88% rename from platform/src/main/java/com/commerce/platform/core/application/in/dto/OrderDetailResponse.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/dto/OrderDetailResponse.java index a3216f4..cf2a08b 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/dto/OrderDetailResponse.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/dto/OrderDetailResponse.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.application.in.dto; +package com.commerce.platform.core.application.port.in.dto; import java.util.List; diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/dto/OrderResponse.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/dto/OrderResponse.java similarity index 94% rename from platform/src/main/java/com/commerce/platform/core/application/in/dto/OrderResponse.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/dto/OrderResponse.java index 3d293be..d54ef53 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/dto/OrderResponse.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/dto/OrderResponse.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.application.in.dto; +package com.commerce.platform.core.application.port.in.dto; import com.commerce.platform.core.domain.aggreate.Order; diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/dto/ProductDetail.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/dto/ProductDetail.java similarity index 90% rename from platform/src/main/java/com/commerce/platform/core/application/in/dto/ProductDetail.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/dto/ProductDetail.java index d462925..1c76882 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/dto/ProductDetail.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/dto/ProductDetail.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.application.in.dto; +package com.commerce.platform.core.application.port.in.dto; import com.commerce.platform.core.domain.aggreate.Product; diff --git a/platform/src/main/java/com/commerce/platform/core/application/in/dto/UpdateStockCommand.java b/platform/src/main/java/com/commerce/platform/core/application/port/in/dto/UpdateStockCommand.java similarity index 69% rename from platform/src/main/java/com/commerce/platform/core/application/in/dto/UpdateStockCommand.java rename to platform/src/main/java/com/commerce/platform/core/application/port/in/dto/UpdateStockCommand.java index 0771f9d..ac73f33 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/in/dto/UpdateStockCommand.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/in/dto/UpdateStockCommand.java @@ -1,8 +1,8 @@ -package com.commerce.platform.core.application.in.dto; +package com.commerce.platform.core.application.port.in.dto; import com.commerce.platform.core.domain.enums.StockOperation; import com.commerce.platform.core.domain.vo.ProductId; -import com.commerce.platform.core.domain.vo.Quantity; +import com.commerce.shared.vo.Quantity; public record UpdateStockCommand( ProductId productId, diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/CouponIssueOutPort.java b/platform/src/main/java/com/commerce/platform/core/application/port/out/CouponIssueOutPort.java similarity index 79% rename from platform/src/main/java/com/commerce/platform/core/application/out/CouponIssueOutPort.java rename to platform/src/main/java/com/commerce/platform/core/application/port/out/CouponIssueOutPort.java index 021292c..8c3252e 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/out/CouponIssueOutPort.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/out/CouponIssueOutPort.java @@ -1,8 +1,8 @@ -package com.commerce.platform.core.application.out; +package com.commerce.platform.core.application.port.out; import com.commerce.platform.core.domain.aggreate.CouponIssues; import com.commerce.platform.core.domain.vo.CouponIssueId; -import com.commerce.platform.core.domain.vo.CustomerId; +import com.commerce.shared.vo.CustomerId; import java.util.List; import java.util.Optional; diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/CouponOutPort.java b/platform/src/main/java/com/commerce/platform/core/application/port/out/CouponOutPort.java similarity index 85% rename from platform/src/main/java/com/commerce/platform/core/application/out/CouponOutPort.java rename to platform/src/main/java/com/commerce/platform/core/application/port/out/CouponOutPort.java index dc308e4..391c7f4 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/out/CouponOutPort.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/out/CouponOutPort.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.application.out; +package com.commerce.platform.core.application.port.out; import com.commerce.platform.core.domain.aggreate.Coupon; import com.commerce.platform.core.domain.vo.CouponId; diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/LockOutPort.java b/platform/src/main/java/com/commerce/platform/core/application/port/out/LockOutPort.java similarity index 70% rename from platform/src/main/java/com/commerce/platform/core/application/out/LockOutPort.java rename to platform/src/main/java/com/commerce/platform/core/application/port/out/LockOutPort.java index 86eb743..a84e74c 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/out/LockOutPort.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/out/LockOutPort.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.application.out; +package com.commerce.platform.core.application.port.out; public interface LockOutPort { Integer getLock(String lockName, int timeoutSeconds); diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/OrderItemOutPort.java b/platform/src/main/java/com/commerce/platform/core/application/port/out/OrderItemOutPort.java similarity index 74% rename from platform/src/main/java/com/commerce/platform/core/application/out/OrderItemOutPort.java rename to platform/src/main/java/com/commerce/platform/core/application/port/out/OrderItemOutPort.java index 8d69be3..1fa4779 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/out/OrderItemOutPort.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/out/OrderItemOutPort.java @@ -1,7 +1,7 @@ -package com.commerce.platform.core.application.out; +package com.commerce.platform.core.application.port.out; import com.commerce.platform.core.domain.aggreate.OrderItem; -import com.commerce.platform.core.domain.vo.OrderId; +import com.commerce.shared.vo.OrderId; import java.util.List; import java.util.Optional; diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/OrderOutputPort.java b/platform/src/main/java/com/commerce/platform/core/application/port/out/OrderOutputPort.java similarity index 63% rename from platform/src/main/java/com/commerce/platform/core/application/out/OrderOutputPort.java rename to platform/src/main/java/com/commerce/platform/core/application/port/out/OrderOutputPort.java index 7cae091..9c06fb7 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/out/OrderOutputPort.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/out/OrderOutputPort.java @@ -1,8 +1,8 @@ -package com.commerce.platform.core.application.out; +package com.commerce.platform.core.application.port.out; import com.commerce.platform.core.domain.aggreate.Order; -import com.commerce.platform.core.domain.vo.CustomerId; -import com.commerce.platform.core.domain.vo.OrderId; +import com.commerce.shared.vo.CustomerId; +import com.commerce.shared.vo.OrderId; import java.util.List; import java.util.Optional; diff --git a/platform/src/main/java/com/commerce/platform/core/application/out/ProductOutputPort.java b/platform/src/main/java/com/commerce/platform/core/application/port/out/ProductOutputPort.java similarity index 86% rename from platform/src/main/java/com/commerce/platform/core/application/out/ProductOutputPort.java rename to platform/src/main/java/com/commerce/platform/core/application/port/out/ProductOutputPort.java index 4f18b7c..ef8c4f9 100644 --- a/platform/src/main/java/com/commerce/platform/core/application/out/ProductOutputPort.java +++ b/platform/src/main/java/com/commerce/platform/core/application/port/out/ProductOutputPort.java @@ -1,4 +1,4 @@ -package com.commerce.platform.core.application.out; +package com.commerce.platform.core.application.port.out; import com.commerce.platform.core.domain.aggreate.Product; import com.commerce.platform.core.domain.vo.ProductId; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Coupon.java b/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Coupon.java index a316799..7f61878 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Coupon.java +++ b/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Coupon.java @@ -1,10 +1,10 @@ package com.commerce.platform.core.domain.aggreate; import com.commerce.platform.core.domain.vo.CouponId; -import com.commerce.platform.core.domain.vo.Money; -import com.commerce.platform.core.domain.vo.Quantity; -import com.commerce.platform.core.domain.vo.ValidPeriod; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.vo.Quantity; +import com.commerce.shared.vo.ValidPeriod; +import com.commerce.shared.exception.BusinessException; +import com.commerce.shared.vo.Money; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; @@ -14,7 +14,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; -import static com.commerce.platform.shared.exception.BusinessError.*; +import static com.commerce.shared.exception.BusinessError.*; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -71,8 +71,8 @@ public static Coupon create( .couponName(couponName) .code(code) .discountPercent(discountPercent) - .minOrderAmt(Money.create(minOrderAmt)) - .maxDiscountAmt(Money.create(maxDiscountAmt)) + .minOrderAmt(Money.of(minOrderAmt)) + .maxDiscountAmt(Money.of(maxDiscountAmt)) .validPeriod(ValidPeriod.create(frDt, toDt)) .totalQuantity(Quantity.create(totalQuantity)) .issuedQuantity(Quantity.create(0)) @@ -84,7 +84,7 @@ public static Coupon create( */ public void isAvailable(Money orderAmt) { // 주문금액 확인 - if(this.minOrderAmt.value() > orderAmt.value()) throw new BusinessException(BELOW_LEAST_ORDER_AMT); + if(this.minOrderAmt.isGreaterThan(orderAmt)) throw new BusinessException(BELOW_LEAST_ORDER_AMT); // 유효기간 확인 isValidPeriod(); @@ -115,7 +115,7 @@ public Money calculateDiscountAmt(Money orderAmt) { // 할인금액 Money discountAmt = orderAmt.discount(this.discountPercent); - if(discountAmt.value() > this.maxDiscountAmt.value()) { + if(discountAmt.isGreaterThan(this.maxDiscountAmt)) { return this.maxDiscountAmt; } diff --git a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/CouponIssues.java b/platform/src/main/java/com/commerce/platform/core/domain/aggreate/CouponIssues.java index 44c7293..0ddc2a8 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/CouponIssues.java +++ b/platform/src/main/java/com/commerce/platform/core/domain/aggreate/CouponIssues.java @@ -3,9 +3,9 @@ import com.commerce.platform.core.domain.enums.CouponIssueStatus; import com.commerce.platform.core.domain.vo.CouponId; import com.commerce.platform.core.domain.vo.CouponIssueId; -import com.commerce.platform.core.domain.vo.CustomerId; -import com.commerce.platform.core.domain.vo.OrderId; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.vo.CustomerId; +import com.commerce.shared.exception.BusinessException; +import com.commerce.shared.vo.OrderId; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; @@ -16,8 +16,8 @@ import static com.commerce.platform.core.domain.enums.CouponIssueStatus.EXPIRED; import static com.commerce.platform.core.domain.enums.CouponIssueStatus.USED; -import static com.commerce.platform.shared.exception.BusinessError.EXPIRED_ISSUED_COUPON; -import static com.commerce.platform.shared.exception.BusinessError.USED_ISSUED_COUPON; +import static com.commerce.shared.exception.BusinessError.EXPIRED_ISSUED_COUPON; +import static com.commerce.shared.exception.BusinessError.USED_ISSUED_COUPON; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) diff --git a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Customer.java b/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Customer.java index bd8204c..016468c 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Customer.java +++ b/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Customer.java @@ -1,6 +1,6 @@ package com.commerce.platform.core.domain.aggreate; -import com.commerce.platform.core.domain.vo.CustomerId; +import com.commerce.shared.vo.CustomerId; import jakarta.persistence.Column; import jakarta.persistence.EmbeddedId; import jakarta.persistence.Entity; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Order.java b/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Order.java index 1d758b0..4155dc3 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Order.java +++ b/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Order.java @@ -1,11 +1,10 @@ package com.commerce.platform.core.domain.aggreate; -import com.commerce.platform.core.application.out.dto.PgPayResponse; import com.commerce.platform.core.domain.enums.OrderStatus; import com.commerce.platform.core.domain.vo.CouponId; -import com.commerce.platform.core.domain.vo.CustomerId; -import com.commerce.platform.core.domain.vo.Money; -import com.commerce.platform.core.domain.vo.OrderId; +import com.commerce.shared.vo.CustomerId; +import com.commerce.shared.vo.Money; +import com.commerce.shared.vo.OrderId; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; @@ -86,9 +85,9 @@ public static Order create( .orderId(OrderId.create()) .customerId(customerId) .couponId(couponId) - .discountAmt(Money.create(0)) - .originAmt(Money.create(0)) - .resultAmt(Money.create(0)) + .discountAmt(Money.of(0)) + .originAmt(Money.of(0)) + .resultAmt(Money.of(0)) .status(OrderStatus.PENDING) .orderedAt(LocalDateTime.now()) .build(); @@ -103,8 +102,8 @@ public void confirm(Money total, Money discount) { throw new RuntimeException("주문완료처리 불가"); } - if(total == Money.create(0) - || (this.couponId != null && discount == Money.create(0)) + if(total == Money.of(0) + || (this.couponId != null && discount == Money.of(0)) ) { throw new RuntimeException("주문생성 오류"); } @@ -143,11 +142,11 @@ public void validForPay() { } } - public void changeStatusAfterPay(PgPayResponse pgPayResponse) { - if(!pgPayResponse.isSuccess()) return; - - updateOrderStatus(PAID); - } +// public void changeStatusAfterPay(PgPayResponse pgPayResponse) { +// if(!pgPayResponse.isSuccess()) return; +// +// updateOrderStatus(PAID); +// } /** * 주문상태, 수정시간 변경 diff --git a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/OrderItem.java b/platform/src/main/java/com/commerce/platform/core/domain/aggreate/OrderItem.java index 88f755a..f406121 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/OrderItem.java +++ b/platform/src/main/java/com/commerce/platform/core/domain/aggreate/OrderItem.java @@ -1,16 +1,16 @@ package com.commerce.platform.core.domain.aggreate; -import com.commerce.platform.core.domain.vo.OrderId; import com.commerce.platform.core.domain.vo.ProductId; -import com.commerce.platform.core.domain.vo.Quantity; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.vo.Quantity; +import com.commerce.shared.exception.BusinessException; +import com.commerce.shared.vo.OrderId; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; -import static com.commerce.platform.shared.exception.BusinessError.INVALID_CANCELED_QUANTITY; +import static com.commerce.shared.exception.BusinessError.INVALID_CANCELED_QUANTITY; @Getter @Entity diff --git a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Product.java b/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Product.java index c656c69..ac6e5a1 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Product.java +++ b/platform/src/main/java/com/commerce/platform/core/domain/aggreate/Product.java @@ -1,10 +1,10 @@ package com.commerce.platform.core.domain.aggreate; import com.commerce.platform.core.domain.enums.ProductStatus; -import com.commerce.platform.core.domain.vo.Money; import com.commerce.platform.core.domain.vo.ProductId; -import com.commerce.platform.core.domain.vo.Quantity; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.vo.Quantity; +import com.commerce.shared.exception.BusinessException; +import com.commerce.shared.vo.Money; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; @@ -13,7 +13,7 @@ import static com.commerce.platform.core.domain.enums.ProductStatus.DISCONTINUED; import static com.commerce.platform.core.domain.enums.ProductStatus.OUT_OF_STOCK; -import static com.commerce.platform.shared.exception.BusinessError.PRODUCT_NOT_AVAILABLE; +import static com.commerce.shared.exception.BusinessError.PRODUCT_NOT_AVAILABLE; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) diff --git a/platform/src/main/java/com/commerce/platform/core/domain/enums/ProductStatus.java b/platform/src/main/java/com/commerce/platform/core/domain/enums/ProductStatus.java index 122697f..82a0de5 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/enums/ProductStatus.java +++ b/platform/src/main/java/com/commerce/platform/core/domain/enums/ProductStatus.java @@ -1,6 +1,6 @@ package com.commerce.platform.core.domain.enums; -import com.commerce.platform.core.domain.vo.Quantity; +import com.commerce.shared.vo.Quantity; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/service/LockFacade.java b/platform/src/main/java/com/commerce/platform/core/domain/service/LockFacade.java index bde84f1..4666cb0 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/service/LockFacade.java +++ b/platform/src/main/java/com/commerce/platform/core/domain/service/LockFacade.java @@ -1,7 +1,7 @@ package com.commerce.platform.core.domain.service; -import com.commerce.platform.core.application.out.LockOutPort; -import com.commerce.platform.shared.exception.LockUnavailableException; +import com.commerce.platform.core.application.port.out.LockOutPort; +import com.commerce.platform.exception.LockUnavailableException; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/CouponId.java b/platform/src/main/java/com/commerce/platform/core/domain/vo/CouponId.java index 84dd60a..9b1cc62 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/CouponId.java +++ b/platform/src/main/java/com/commerce/platform/core/domain/vo/CouponId.java @@ -1,6 +1,6 @@ package com.commerce.platform.core.domain.vo; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.exception.BusinessException; import io.micrometer.common.util.StringUtils; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; @@ -9,7 +9,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import static com.commerce.platform.shared.exception.BusinessError.INVALID_COUPON; +import static com.commerce.shared.exception.BusinessError.INVALID_COUPON; @Embeddable public record CouponId( diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/CouponIssueId.java b/platform/src/main/java/com/commerce/platform/core/domain/vo/CouponIssueId.java index b9e17e4..13919d8 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/CouponIssueId.java +++ b/platform/src/main/java/com/commerce/platform/core/domain/vo/CouponIssueId.java @@ -1,5 +1,6 @@ package com.commerce.platform.core.domain.vo; +import com.commerce.shared.vo.CustomerId; import jakarta.persistence.AttributeOverride; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/PaymentResult.java b/platform/src/main/java/com/commerce/platform/core/domain/vo/PaymentResult.java deleted file mode 100644 index 85482e2..0000000 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/PaymentResult.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.commerce.platform.core.domain.vo; - -public class PaymentResult { - String code; - String message; -} diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/PgRequest.java b/platform/src/main/java/com/commerce/platform/core/domain/vo/PgRequest.java deleted file mode 100644 index 12f22cc..0000000 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/PgRequest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.commerce.platform.core.domain.vo; - -import com.commerce.platform.core.domain.enums.TransactionStatus; - -/** - * pg 결제 요청 시 필요 데이터 - */ -public record PgRequest( - String mid, // pg사에서 관리하는 우리의 id 로 휴대폰/카드/간편결제 화면을 보여줄거임 - - // 주문정보 - String orderId, - - // 결제 정보 - TransactionStatus status, - Money amount, - String installment, - - // 상품정보 - String productName - -) { -} diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/PgResponse.java b/platform/src/main/java/com/commerce/platform/core/domain/vo/PgResponse.java deleted file mode 100644 index 7d9341d..0000000 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/PgResponse.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.commerce.platform.core.domain.vo; - -public class PgResponse { - private String tid; - private String code; - private String message; -} diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/ProductId.java b/platform/src/main/java/com/commerce/platform/core/domain/vo/ProductId.java index 5105127..4a76fa1 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/ProductId.java +++ b/platform/src/main/java/com/commerce/platform/core/domain/vo/ProductId.java @@ -1,6 +1,6 @@ package com.commerce.platform.core.domain.vo; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.exception.BusinessException; import io.micrometer.common.util.StringUtils; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; @@ -9,7 +9,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import static com.commerce.platform.shared.exception.BusinessError.INVALID_PRODUCT_ID; +import static com.commerce.shared.exception.BusinessError.INVALID_PRODUCT_ID; @Embeddable public record ProductId ( diff --git a/platform/src/main/java/com/commerce/platform/shared/exception/LockUnavailableException.java b/platform/src/main/java/com/commerce/platform/exception/LockUnavailableException.java similarity index 75% rename from platform/src/main/java/com/commerce/platform/shared/exception/LockUnavailableException.java rename to platform/src/main/java/com/commerce/platform/exception/LockUnavailableException.java index 4e0ab7c..823de9c 100644 --- a/platform/src/main/java/com/commerce/platform/shared/exception/LockUnavailableException.java +++ b/platform/src/main/java/com/commerce/platform/exception/LockUnavailableException.java @@ -1,4 +1,4 @@ -package com.commerce.platform.shared.exception; +package com.commerce.platform.exception; public class LockUnavailableException extends RuntimeException{ public LockUnavailableException(String message) { diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CouponAdaptor.java b/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CouponAdaptor.java index 566e65f..23f003d 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CouponAdaptor.java +++ b/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CouponAdaptor.java @@ -1,6 +1,6 @@ package com.commerce.platform.infrastructure.adaptor; -import com.commerce.platform.core.application.out.CouponOutPort; +import com.commerce.platform.core.application.port.out.CouponOutPort; import com.commerce.platform.core.domain.aggreate.Coupon; import com.commerce.platform.core.domain.vo.CouponId; import com.commerce.platform.infrastructure.persistence.CouponRepository; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CouponIssueAdaptor.java b/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CouponIssueAdaptor.java index 7fc8c62..663738c 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CouponIssueAdaptor.java +++ b/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/CouponIssueAdaptor.java @@ -1,9 +1,9 @@ package com.commerce.platform.infrastructure.adaptor; -import com.commerce.platform.core.application.out.CouponIssueOutPort; +import com.commerce.platform.core.application.port.out.CouponIssueOutPort; import com.commerce.platform.core.domain.aggreate.CouponIssues; import com.commerce.platform.core.domain.vo.CouponIssueId; -import com.commerce.platform.core.domain.vo.CustomerId; +import com.commerce.shared.vo.CustomerId; import com.commerce.platform.infrastructure.persistence.CouponIssueRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/OrderAdaptor.java b/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/OrderAdaptor.java index 1e4643a..0581cf6 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/OrderAdaptor.java +++ b/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/OrderAdaptor.java @@ -1,10 +1,10 @@ package com.commerce.platform.infrastructure.adaptor; -import com.commerce.platform.core.application.out.OrderOutputPort; +import com.commerce.platform.core.application.port.out.OrderOutputPort; import com.commerce.platform.core.domain.aggreate.Order; -import com.commerce.platform.core.domain.vo.CustomerId; -import com.commerce.platform.core.domain.vo.OrderId; +import com.commerce.shared.vo.CustomerId; import com.commerce.platform.infrastructure.persistence.OrderRepository; +import com.commerce.shared.vo.OrderId; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/OrderItemAdaptor.java b/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/OrderItemAdaptor.java index a64620d..cd14674 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/OrderItemAdaptor.java +++ b/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/OrderItemAdaptor.java @@ -1,9 +1,9 @@ package com.commerce.platform.infrastructure.adaptor; -import com.commerce.platform.core.application.out.OrderItemOutPort; +import com.commerce.platform.core.application.port.out.OrderItemOutPort; import com.commerce.platform.core.domain.aggreate.OrderItem; -import com.commerce.platform.core.domain.vo.OrderId; import com.commerce.platform.infrastructure.persistence.OrderItemRepository; +import com.commerce.shared.vo.OrderId; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/ProductAdaptor.java b/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/ProductAdaptor.java index 1031c8c..e7ad01a 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/ProductAdaptor.java +++ b/platform/src/main/java/com/commerce/platform/infrastructure/adaptor/ProductAdaptor.java @@ -1,6 +1,6 @@ package com.commerce.platform.infrastructure.adaptor; -import com.commerce.platform.core.application.out.ProductOutputPort; +import com.commerce.platform.core.application.port.out.ProductOutputPort; import com.commerce.platform.core.domain.aggreate.Product; import com.commerce.platform.core.domain.vo.ProductId; import com.commerce.platform.infrastructure.persistence.ProductRepository; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/CouponIssueRepository.java b/platform/src/main/java/com/commerce/platform/infrastructure/persistence/CouponIssueRepository.java index 39875bb..99a3af3 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/CouponIssueRepository.java +++ b/platform/src/main/java/com/commerce/platform/infrastructure/persistence/CouponIssueRepository.java @@ -3,7 +3,7 @@ import com.commerce.platform.core.domain.aggreate.CouponIssues; import com.commerce.platform.core.domain.vo.CouponId; import com.commerce.platform.core.domain.vo.CouponIssueId; -import com.commerce.platform.core.domain.vo.CustomerId; +import com.commerce.shared.vo.CustomerId; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/NamedLockRepository.java b/platform/src/main/java/com/commerce/platform/infrastructure/persistence/NamedLockRepository.java index 19aa279..d285d08 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/NamedLockRepository.java +++ b/platform/src/main/java/com/commerce/platform/infrastructure/persistence/NamedLockRepository.java @@ -1,6 +1,6 @@ package com.commerce.platform.infrastructure.persistence; -import com.commerce.platform.core.application.out.LockOutPort; +import com.commerce.platform.core.application.port.out.LockOutPort; import lombok.RequiredArgsConstructor; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/OrderItemRepository.java b/platform/src/main/java/com/commerce/platform/infrastructure/persistence/OrderItemRepository.java index e540e70..35d42b6 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/OrderItemRepository.java +++ b/platform/src/main/java/com/commerce/platform/infrastructure/persistence/OrderItemRepository.java @@ -1,8 +1,8 @@ package com.commerce.platform.infrastructure.persistence; import com.commerce.platform.core.domain.aggreate.OrderItem; -import com.commerce.platform.core.domain.vo.OrderId; import com.commerce.platform.core.domain.vo.ProductId; +import com.commerce.shared.vo.OrderId; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/OrderRepository.java b/platform/src/main/java/com/commerce/platform/infrastructure/persistence/OrderRepository.java index 8960bc7..410a986 100644 --- a/platform/src/main/java/com/commerce/platform/infrastructure/persistence/OrderRepository.java +++ b/platform/src/main/java/com/commerce/platform/infrastructure/persistence/OrderRepository.java @@ -1,8 +1,8 @@ package com.commerce.platform.infrastructure.persistence; import com.commerce.platform.core.domain.aggreate.Order; -import com.commerce.platform.core.domain.vo.CustomerId; -import com.commerce.platform.core.domain.vo.OrderId; +import com.commerce.shared.vo.CustomerId; +import com.commerce.shared.vo.OrderId; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/pg/DanalStrategy.java b/platform/src/main/java/com/commerce/platform/infrastructure/pg/DanalStrategy.java deleted file mode 100644 index bc2bddd..0000000 --- a/platform/src/main/java/com/commerce/platform/infrastructure/pg/DanalStrategy.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.commerce.platform.infrastructure.pg; - -import com.commerce.platform.core.application.out.PgStrategy; -import com.commerce.platform.core.domain.enums.PgProvider; -import org.springframework.stereotype.Component; - -@Component -public class DanalStrategy extends PgStrategy { - - @Override - public String process(String request) { - return ""; - } - - @Override - public PgProvider getPgProvider() { - return PgProvider.DANAL; - } - -} diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/pg/NHNStrategy.java b/platform/src/main/java/com/commerce/platform/infrastructure/pg/NHNStrategy.java deleted file mode 100644 index d26e1a1..0000000 --- a/platform/src/main/java/com/commerce/platform/infrastructure/pg/NHNStrategy.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.commerce.platform.infrastructure.pg; - -import com.commerce.platform.core.application.out.PgStrategy; -import com.commerce.platform.core.domain.enums.PgProvider; -import org.springframework.stereotype.Component; - -@Component -public class NHNStrategy extends PgStrategy { - - @Override - public String process(String request) { - return ""; - } - - public PgProvider getPgProvider() { - return PgProvider.NHN; - } -} diff --git a/platform/src/main/java/com/commerce/platform/infrastructure/pg/TossStrategy.java b/platform/src/main/java/com/commerce/platform/infrastructure/pg/TossStrategy.java deleted file mode 100644 index 0955da0..0000000 --- a/platform/src/main/java/com/commerce/platform/infrastructure/pg/TossStrategy.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.commerce.platform.infrastructure.pg; - -import com.commerce.platform.core.application.out.PgStrategy; -import com.commerce.platform.core.domain.enums.PgProvider; -import org.springframework.stereotype.Component; - -@Component -public class TossStrategy extends PgStrategy { - - @Override - public String process(String request) { - return ""; - } - - @Override - public PgProvider getPgProvider() { - return PgProvider.TOSS; - } -} diff --git a/platform/src/main/proto/payment_service.proto b/platform/src/main/proto/payment_service.proto new file mode 100644 index 0000000..eae500a --- /dev/null +++ b/platform/src/main/proto/payment_service.proto @@ -0,0 +1,78 @@ +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "com.commerce.platform.grpc.proto"; +option java_outer_classname = "PaymentServiceProto"; + +package payment; + +service PaymentService { + rpc ApprovePayment (PaymentApprovalRequest) returns (PaymentApprovalResponse); + rpc CancelPayment (PaymentCancelRequest) returns (PaymentCancelResponse); + rpc PartialCancelPayment (PaymentPartialCancelRequest) returns (PaymentPartialCancelResponse); + rpc ApproveWithCard (CardPaymentRequest) returns (PaymentApprovalResponse); +} + +message PaymentApprovalRequest { + string order_id = 1; + int32 installment = 2; + string pay_method = 3; + string pay_provider = 4; +} + +message PaymentApprovalResponse { + bool success = 1; + string code = 2; + string message = 3; + PaymentData data = 4; +} + +message PaymentData { + string payment_id = 1; + int64 approved_amount = 2; + string approved_at = 3; + string pay_method = 4; + string status = 5; +} + +message PaymentCancelRequest { + string order_id = 1; +} + +message PaymentCancelResponse { + bool success = 1; + string code = 2; + string message = 3; + CancelData data = 4; +} + +message CancelData { + string payment_id = 1; + int64 canceled_amount = 2; + string canceled_at = 3; +} + +message PaymentPartialCancelRequest { + string order_id = 1; + int64 order_item_id = 2; + int64 canceled_quantity = 3; +} + +message PaymentPartialCancelResponse { + bool success = 1; + string code = 2; + string message = 3; + PartialCancelData data = 4; +} + +message PartialCancelData { + int64 partial_cancel_id = 1; + int64 canceled_amount = 2; + int64 remain_amount = 3; + string canceled_at = 4; +} + +message CardPaymentRequest { + int64 card_id = 1; + string order_id = 2; +} diff --git a/platform/src/main/resources/application.yml b/platform/src/main/resources/application.yml index 4821882..a38c07a 100644 --- a/platform/src/main/resources/application.yml +++ b/platform/src/main/resources/application.yml @@ -28,5 +28,9 @@ spring: env-file: .env lifecycle-management: start_only -aes256: - key: 61qDonoZcEtIEvUZVPkIKIYovHH82rXtK7T1g/rcc1k= \ No newline at end of file +# gRPC Client 설정 +grpc: + client: + payment-service: + address: 'static://localhost:9090' + negotiationType: plaintext \ No newline at end of file diff --git a/platform/src/test/java/com/commerce/platform/bootstrap/api/ProductControllerTest.java b/platform/src/test/java/com/commerce/platform/bootstrap/api/ProductControllerTest.java index 1df9cdd..8d14fa7 100644 --- a/platform/src/test/java/com/commerce/platform/bootstrap/api/ProductControllerTest.java +++ b/platform/src/test/java/com/commerce/platform/bootstrap/api/ProductControllerTest.java @@ -4,11 +4,11 @@ import com.commerce.platform.bootstrap.dto.product.CreateProductRequest; import com.commerce.platform.bootstrap.dto.product.UpdateStockRequest; import com.commerce.platform.bootstrap.exception.GlobalExceptionHandler; -import com.commerce.platform.core.application.in.ProductUseCase; +import com.commerce.platform.core.application.port.in.ProductUseCase; import com.commerce.platform.core.domain.aggreate.Product; import com.commerce.platform.core.domain.enums.StockOperation; import com.commerce.platform.core.domain.vo.ProductId; -import com.commerce.platform.core.domain.vo.Quantity; +import com.commerce.shared.vo.Quantity; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -20,7 +20,7 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MockMvc; -import static com.commerce.platform.shared.exception.BusinessError.INVALID_REQUEST_VALUE; +import static com.commerce.shared.exception.BusinessError.INVALID_REQUEST_VALUE; import static org.hamcrest.Matchers.containsString; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; diff --git a/platform/src/test/java/com/commerce/platform/core/application/in/CouponIssueUseCaseImplTest.java b/platform/src/test/java/com/commerce/platform/core/application/in/CouponIssueUseCaseImplTest.java index 0ad4bb0..3dcd6c8 100644 --- a/platform/src/test/java/com/commerce/platform/core/application/in/CouponIssueUseCaseImplTest.java +++ b/platform/src/test/java/com/commerce/platform/core/application/in/CouponIssueUseCaseImplTest.java @@ -1,10 +1,11 @@ package com.commerce.platform.core.application.in; -import com.commerce.platform.core.application.in.dto.CouponView; +import com.commerce.platform.core.application.port.in.CouponIssueUseCase; +import com.commerce.platform.core.application.port.in.dto.CouponView; import com.commerce.platform.core.domain.aggreate.Coupon; import com.commerce.platform.core.domain.vo.CouponId; import com.commerce.platform.core.domain.vo.CouponIssueId; -import com.commerce.platform.core.domain.vo.CustomerId; +import com.commerce.shared.vo.CustomerId; import com.commerce.platform.infrastructure.persistence.CouponIssueRepository; import com.commerce.platform.infrastructure.persistence.CouponRepository; import org.junit.jupiter.api.DisplayName; diff --git a/platform/src/test/java/com/commerce/platform/core/application/in/PaymentUseCaseImplTest.java b/platform/src/test/java/com/commerce/platform/core/application/in/PaymentUseCaseImplTest.java deleted file mode 100644 index 39f6398..0000000 --- a/platform/src/test/java/com/commerce/platform/core/application/in/PaymentUseCaseImplTest.java +++ /dev/null @@ -1,325 +0,0 @@ -package com.commerce.platform.core.application.in; - -import com.commerce.platform.core.application.in.dto.PayCancelCommand; -import com.commerce.platform.core.application.in.dto.PayOrderCommand; -import com.commerce.platform.core.application.out.PaymentOutPort; -import com.commerce.platform.core.application.out.PgStrategy; -import com.commerce.platform.core.application.out.dto.PgPayResponse; -import com.commerce.platform.core.domain.aggreate.Order; -import com.commerce.platform.core.domain.aggreate.OrderItem; -import com.commerce.platform.core.domain.aggreate.Payment; -import com.commerce.platform.core.domain.enums.*; -import com.commerce.platform.core.domain.service.PaymentPgRouter; -import com.commerce.platform.core.domain.vo.*; -import com.commerce.platform.infrastructure.adaptor.*; -import com.commerce.platform.infrastructure.persistence.OrderItemRepository; -import com.commerce.platform.infrastructure.persistence.OrderRepository; -import com.commerce.platform.infrastructure.persistence.PaymentPartCancelRepository; -import com.commerce.platform.shared.exception.BusinessError; -import com.commerce.platform.shared.exception.BusinessException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.bean.override.mockito.MockitoBean; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * paymentUseCase, 결제관련 repository 통합테스트 - */ -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@Import({ - PaymentUseCaseImpl.class, - PaymentAdaptor.class, - OrderAdaptor.class, - OrderItemAdaptor.class, - ProductAdaptor.class, - CustomerCardAdaptor.class -}) -@DataJpaTest -class PaymentUseCaseImplTest { - - @Autowired - private PaymentUseCaseImpl paymentUseCase; - - @Autowired - private PaymentOutPort paymentOutPort; - - @Autowired - private OrderRepository orderRepository; - - @Autowired - private OrderItemRepository orderItemRepository; - - @Autowired - private PaymentPartCancelRepository paymentPartCancelRepository; - - @MockitoBean - private PaymentPgRouter mockPaymentPgRouter; - - private Order testOrder; - - private List testOrderItems; - - private final ProductId productId1 = ProductId.of("P20251110222600000001"); - private final ProductId productId2 = ProductId.of("P20251110222600000002"); - - private PgPayResponse success_pgResponse = new PgPayResponse( - "PG_TID_12345", - "0000", - "성공", - true - ); - - private PgPayResponse fail_pgResponse = new PgPayResponse( - "PG_TID_12345", - "errorCode", - "실패", - false - ); - - @BeforeEach - void init() { - // 주문완료 상태의 신규order 저장 - testOrder = Order.create(CustomerId.of("test1"), null); - testOrder.confirm(Money.create(35000), Money.create(0)); - orderRepository.save(testOrder); - orderRepository.flush(); - - testOrderItems = List.of( - OrderItem.create(testOrder.getOrderId(), productId1, Quantity.create(3)), - OrderItem.create(testOrder.getOrderId(), productId2, Quantity.create(1)) - ); - - orderItemRepository.saveAll(testOrderItems); - orderItemRepository.flush(); - } - - @DisplayName("주문 결제 성공") - @Test - void doApproval_successful() { - PayOrderCommand command = new PayOrderCommand( - testOrder.getOrderId(), - null, - null, - PayMethod.CARD, - PayProvider.KB - ); - - mockPgStrategy(); - - paymentUseCase.doApproval(command); - - // then 승인 성공 - Payment payment = paymentOutPort.findByOrderId(testOrder.getOrderId()) - .get(); - assertThat(payment).isNotNull(); - assertThat(payment.getPaymentStatus()).isEqualTo(PaymentStatus.APPROVED); - - // order 상태 검증 - assertThat(orderRepository.findById(testOrder.getOrderId()).get().getStatus()) - .isEqualTo(OrderStatus.PAID); - } - - @DisplayName("전체환불 성공") - @Test - void doCancel_successful() { - // 주문 결제 - doApproval_successful(); - - // 전체취소 요청 - PayCancelCommand command = PayCancelCommand.builder() - .orderId(testOrder.getOrderId()) - .paymentStatus(PaymentStatus.FULL_CANCELED) - .build(); - - mockPgStrategy(); - - paymentUseCase.doCancel(command); - - // payment 상태 - assertThat(paymentOutPort.findByOrderId(testOrder.getOrderId())).isNotNull(); - assertThat(paymentOutPort.findByOrderId(testOrder.getOrderId()).get().getPaymentStatus()) - .isEqualTo(PaymentStatus.FULL_CANCELED); - - // order 상태 검증 - Order refundedOrder = orderRepository.findById(testOrder.getOrderId()).orElseThrow(); - assertThat(refundedOrder.getStatus()).isEqualTo(OrderStatus.REFUND); - } - - @DisplayName("전체취소실패 : 부분취소내역 존재") - @Test - void doCancel_failed() { - // 결제 승인 - doApproval_successful(); - - mockPgStrategy(); - - // 부분취소 요청 - OrderItem canceledItem = testOrderItems.get(0); - - PayCancelCommand partCancelCommand = PayCancelCommand.builder() - .orderId(testOrder.getOrderId()) - .orderItemId(canceledItem.getId()) - .canceledQuantity(Quantity.create(2)) - .paymentStatus(PaymentStatus.PARTIAL_CANCELED) - .build(); - - mockPgStrategy(); - - // 부분취소 - Long partCancelId = paymentUseCase.doPartCancel(partCancelCommand); - - // 전체취소 - PayCancelCommand fullCancelCommand = PayCancelCommand.builder() - .orderId(testOrder.getOrderId()) - .paymentStatus(PaymentStatus.FULL_CANCELED) - .build(); - - // 전체취소 실패 - assertThatThrownBy(() -> paymentUseCase.doCancel(fullCancelCommand)) - .isInstanceOf(BusinessException.class) - .hasMessageContaining(BusinessError.PAYMENT_HAS_PARTIAL_CANCEL.getMessage()); - - // payment 상태 검증 - Payment payment = paymentOutPort.findByOrderId(testOrder.getOrderId()).orElseThrow(); - assertThat(payment.getPaymentStatus()) - .isEqualTo(PaymentStatus.APPROVED); - - // order 상태 검증 - Order order = orderRepository.findById(testOrder.getOrderId()).orElseThrow(); - assertThat(order.getStatus()).isEqualTo(OrderStatus.PAID); - } - - - @DisplayName("부분취소 성공") - @Test - void doPartCancel_successful() { - // 주문 결제 - doApproval_successful(); - - // 부분취소 요청 - OrderItem canceledItem = testOrderItems.get(0); - - PayCancelCommand partCancelCommand = PayCancelCommand.builder() - .orderId(testOrder.getOrderId()) - .orderItemId(canceledItem.getId()) - .canceledQuantity(Quantity.create(2)) - .paymentStatus(PaymentStatus.PARTIAL_CANCELED) - .build(); - - mockPgStrategy(); - - // 부분취소 - Long partCancelId = paymentUseCase.doPartCancel(partCancelCommand); - - // payment 상태 - assertThat(paymentOutPort.findByOrderId(testOrder.getOrderId()).get().getPaymentStatus()) - .as("원거래는 승인상태 유지") - .isEqualTo(PaymentStatus.APPROVED); - - assertThat(paymentPartCancelRepository.findById(partCancelId)) - .isPresent() - .get() - .satisfies(partCancel -> { - assertThat(partCancel) - .as("insert 부분취소") - .isNotNull(); - - assertThat(partCancel.getCanceledAmt().value()) - .as("부분취소 금액 검증") - .isEqualTo(2500 * 2) ; - }); - - // orderitem 검증 - assertThat(orderItemRepository.findById(canceledItem.getId())) - .isPresent() - .get() - .satisfies( - orderItem -> { - assertThat(orderItem.isCanceled()).isEqualTo(true); - } - ); - - assertThat(orderItemRepository.findByOrderIdAndProductIdAndCanceled(partCancelCommand.getOrderId(), canceledItem.getProductId(), false)) - .isPresent() - .get() - .satisfies(oi -> { - assertThat(oi.getQuantity().value()) - .as("새로 추가된 orderitem 수량 확인") - .isEqualTo(canceledItem.getQuantity().minus(partCancelCommand.getCanceledQuantity()).value()); - assertThat(oi.isCanceled()).isEqualTo(false); - }); - - // order 상태 검증 - Order refundedOrder = orderRepository.findById(testOrder.getOrderId()).orElseThrow(); - assertThat(refundedOrder.getStatus()) - .as("주문상태는 결제완료로 유지") - .isEqualTo(OrderStatus.PAID); - } - - @DisplayName("부분취소 실패 : 취소 가능 수량 초과") - @Test - void doPartCancel_failed() { - // 주문 결제 - doApproval_successful(); - - // 부분취소 요청 - PayCancelCommand partCancelCommand = PayCancelCommand.builder() - .orderId(testOrder.getOrderId()) - .orderItemId(testOrderItems.get(1).getId()) - .canceledQuantity(Quantity.create(2)) - .paymentStatus(PaymentStatus.PARTIAL_CANCELED) - .build(); - - mockPgStrategy(); - - // 부분취소 - assertThatThrownBy(() -> paymentUseCase.doPartCancel(partCancelCommand)) - .isInstanceOf(BusinessException.class) - .hasMessageContaining(BusinessError.INVALID_CANCELED_QUANTITY.getMessage()); - - assertThat(paymentOutPort.findByOrderId(testOrder.getOrderId()).get().getPaymentStatus()) - .as("원거래는 승인상태 유지") - .isEqualTo(PaymentStatus.APPROVED); - - PaymentId paymentId = paymentOutPort.findByOrderId(testOrder.getOrderId()).get().getPaymentId(); - assertThat(paymentPartCancelRepository.existsPaymentPartCancelByApprovedPaymentId(paymentId)) - .as("not insert 부분취소") - .isEqualTo(false); - - // order 상태 검증 - Order refundedOrder = orderRepository.findById(testOrder.getOrderId()).orElseThrow(); - assertThat(refundedOrder.getStatus()).isEqualTo(OrderStatus.PAID) - .as("주문상태는 결제완료로 유지"); - } - - private void mockPgStrategy() { - PgStrategy mockPgStrategy = mock(PgStrategy.class); - - when(mockPaymentPgRouter.routePg(any(PayMethod.class), any(PayProvider.class))) - .thenReturn(mockPgStrategy); - - when(mockPaymentPgRouter.getPgStrategyByProvider(any())) - .thenReturn(mockPgStrategy); - - when(mockPgStrategy.processCancel(any())) - .thenReturn(success_pgResponse); - - when(mockPgStrategy.getPgProvider()) - .thenReturn(PgProvider.TOSS); - - when(mockPgStrategy.processApproval(any())) - .thenReturn(success_pgResponse); - } -} \ No newline at end of file diff --git a/platform/src/test/java/com/commerce/platform/core/domain/service/ProductServiceTest.java b/platform/src/test/java/com/commerce/platform/core/domain/service/ProductServiceTest.java index 938452a..b353ff8 100644 --- a/platform/src/test/java/com/commerce/platform/core/domain/service/ProductServiceTest.java +++ b/platform/src/test/java/com/commerce/platform/core/domain/service/ProductServiceTest.java @@ -1,13 +1,12 @@ package com.commerce.platform.core.domain.service; -import com.commerce.platform.core.application.in.ProductUseCaseImpl; -import com.commerce.platform.core.application.in.dto.ProductDetail; -import com.commerce.platform.core.application.out.ProductOutputPort; +import com.commerce.platform.core.application.port.in.ProductUseCaseImpl; +import com.commerce.platform.core.application.port.in.dto.ProductDetail; +import com.commerce.platform.core.application.port.out.ProductOutputPort; import com.commerce.platform.core.domain.aggreate.Product; import com.commerce.platform.core.domain.enums.ProductStatus; -import com.commerce.platform.core.domain.vo.Money; import com.commerce.platform.core.domain.vo.ProductId; -import com.commerce.platform.core.domain.vo.Quantity; +import com.commerce.shared.vo.Quantity; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/platform/src/test/java/com/commerce/platform/shared/service/AesFacadeTest.java b/platform/src/test/java/com/commerce/platform/shared/service/AesFacadeTest.java index 192432e..2b936dd 100644 --- a/platform/src/test/java/com/commerce/platform/shared/service/AesFacadeTest.java +++ b/platform/src/test/java/com/commerce/platform/shared/service/AesFacadeTest.java @@ -1,5 +1,6 @@ package com.commerce.platform.shared.service; +import com.commerce.shared.service.AesCryptoFacade; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/settings.gradle b/settings.gradle index 62a23c0..a186fd4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,4 @@ rootProject.name = 'demo' include(':platform') +include(':payments') +include(':shared') diff --git a/shared/build.gradle b/shared/build.gradle new file mode 100644 index 0000000..4a8069f --- /dev/null +++ b/shared/build.gradle @@ -0,0 +1,3 @@ +plugins { + id 'myproject-convention' +} \ No newline at end of file diff --git a/shared/src/main/java/com/commerce/shared/SharedApplication.java b/shared/src/main/java/com/commerce/shared/SharedApplication.java new file mode 100644 index 0000000..0a68b4a --- /dev/null +++ b/shared/src/main/java/com/commerce/shared/SharedApplication.java @@ -0,0 +1,12 @@ +package com.commerce.shared; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SharedApplication { + + public static void main(String[] args) { + SpringApplication.run(SharedApplication.class, args); + } +} diff --git a/shared/src/main/java/com/commerce/shared/config/RestTemplateConfig.java b/shared/src/main/java/com/commerce/shared/config/RestTemplateConfig.java new file mode 100644 index 0000000..b1a5321 --- /dev/null +++ b/shared/src/main/java/com/commerce/shared/config/RestTemplateConfig.java @@ -0,0 +1,23 @@ +package com.commerce.shared.config; + +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +import java.nio.charset.StandardCharsets; +import java.time.Duration; + +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate(RestTemplateBuilder builder) { + return builder + .connectTimeout(Duration.ofSeconds(3)) + .readTimeout(Duration.ofSeconds(10)) + .additionalMessageConverters(new StringHttpMessageConverter(StandardCharsets.UTF_8)) + .build(); + } +} diff --git a/platform/src/main/java/com/commerce/platform/shared/exception/BusinessError.java b/shared/src/main/java/com/commerce/shared/exception/BusinessError.java similarity index 98% rename from platform/src/main/java/com/commerce/platform/shared/exception/BusinessError.java rename to shared/src/main/java/com/commerce/shared/exception/BusinessError.java index 8c88acd..b8ff6c0 100644 --- a/platform/src/main/java/com/commerce/platform/shared/exception/BusinessError.java +++ b/shared/src/main/java/com/commerce/shared/exception/BusinessError.java @@ -1,4 +1,4 @@ -package com.commerce.platform.shared.exception; +package com.commerce.shared.exception; import lombok.Getter; diff --git a/platform/src/main/java/com/commerce/platform/shared/exception/BusinessException.java b/shared/src/main/java/com/commerce/shared/exception/BusinessException.java similarity index 86% rename from platform/src/main/java/com/commerce/platform/shared/exception/BusinessException.java rename to shared/src/main/java/com/commerce/shared/exception/BusinessException.java index c3c6fee..04debd0 100644 --- a/platform/src/main/java/com/commerce/platform/shared/exception/BusinessException.java +++ b/shared/src/main/java/com/commerce/shared/exception/BusinessException.java @@ -1,4 +1,4 @@ -package com.commerce.platform.shared.exception; +package com.commerce.shared.exception; import lombok.Getter; diff --git a/platform/src/main/java/com/commerce/platform/shared/service/AesCryptoFacade.java b/shared/src/main/java/com/commerce/shared/service/AesCryptoFacade.java similarity index 98% rename from platform/src/main/java/com/commerce/platform/shared/service/AesCryptoFacade.java rename to shared/src/main/java/com/commerce/shared/service/AesCryptoFacade.java index bdcd694..cf667fa 100644 --- a/platform/src/main/java/com/commerce/platform/shared/service/AesCryptoFacade.java +++ b/shared/src/main/java/com/commerce/shared/service/AesCryptoFacade.java @@ -1,4 +1,4 @@ -package com.commerce.platform.shared.service; +package com.commerce.shared.service; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/CustomerId.java b/shared/src/main/java/com/commerce/shared/vo/CustomerId.java similarity index 71% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/CustomerId.java rename to shared/src/main/java/com/commerce/shared/vo/CustomerId.java index 07e54d2..2e11714 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/CustomerId.java +++ b/shared/src/main/java/com/commerce/shared/vo/CustomerId.java @@ -1,13 +1,13 @@ -package com.commerce.platform.core.domain.vo; +package com.commerce.shared.vo; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.exception.BusinessException; import io.micrometer.common.util.StringUtils; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import java.io.Serializable; -import static com.commerce.platform.shared.exception.BusinessError.INVALID_CUSTOMER; +import static com.commerce.shared.exception.BusinessError.INVALID_CUSTOMER; @Embeddable public record CustomerId ( diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/Money.java b/shared/src/main/java/com/commerce/shared/vo/Money.java similarity index 52% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/Money.java rename to shared/src/main/java/com/commerce/shared/vo/Money.java index 6cf8b6e..a6c69ae 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/Money.java +++ b/shared/src/main/java/com/commerce/shared/vo/Money.java @@ -1,10 +1,10 @@ -package com.commerce.platform.core.domain.vo; +package com.commerce.shared.vo; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.exception.BusinessException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; -import static com.commerce.platform.shared.exception.BusinessError.INVALID_MONEY; +import static com.commerce.shared.exception.BusinessError.INVALID_MONEY; @Embeddable public record Money( @@ -12,22 +12,26 @@ public record Money( long value ) { public Money add(Money money) { - return create(this.value + money.value); + return of(this.value + money.value); } public Money subtract(Money money) { - return create(this.value - money.value); + return of(this.value - money.value); } public Money discount(int percent) { - return create(this.value * (100 - percent)); + return of(this.value * (100 - percent)); } public Money multiply(Quantity quantity) { - return create(this.value * quantity.value()); + return of(this.value * quantity.value()); } - public static Money create(long value) { + public boolean isGreaterThan(Money other) { + return this.value > other.value; + } + + public static Money of(long value) { return new Money(value); } @@ -37,4 +41,5 @@ public static Money create(long value) { throw new BusinessException(INVALID_MONEY); } } + } diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/OrderId.java b/shared/src/main/java/com/commerce/shared/vo/OrderId.java similarity index 81% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/OrderId.java rename to shared/src/main/java/com/commerce/shared/vo/OrderId.java index 514411c..b3f868d 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/OrderId.java +++ b/shared/src/main/java/com/commerce/shared/vo/OrderId.java @@ -1,6 +1,6 @@ -package com.commerce.platform.core.domain.vo; +package com.commerce.shared.vo; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.exception.BusinessException; import io.micrometer.common.util.StringUtils; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; @@ -9,7 +9,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import static com.commerce.platform.shared.exception.BusinessError.INVALID_ORDER_ID; +import static com.commerce.shared.exception.BusinessError.INVALID_ORDER_ID; @Embeddable public record OrderId ( @@ -32,3 +32,4 @@ public static OrderId create() { || id.charAt(0) != 'O') throw new BusinessException(INVALID_ORDER_ID); } } + diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/PaymentId.java b/shared/src/main/java/com/commerce/shared/vo/PaymentId.java similarity index 77% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/PaymentId.java rename to shared/src/main/java/com/commerce/shared/vo/PaymentId.java index 51a8c7d..ad98abd 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/PaymentId.java +++ b/shared/src/main/java/com/commerce/shared/vo/PaymentId.java @@ -1,6 +1,6 @@ -package com.commerce.platform.core.domain.vo; +package com.commerce.shared.vo; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.exception.BusinessException; import io.micrometer.common.util.StringUtils; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; @@ -9,7 +9,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import static com.commerce.platform.shared.exception.BusinessError.INVALID_PAYMENT; +import static com.commerce.shared.exception.BusinessError.INVALID_PAYMENT; @Embeddable public record PaymentId( diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/Quantity.java b/shared/src/main/java/com/commerce/shared/vo/Quantity.java similarity index 59% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/Quantity.java rename to shared/src/main/java/com/commerce/shared/vo/Quantity.java index 53d18f9..4d16ff6 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/Quantity.java +++ b/shared/src/main/java/com/commerce/shared/vo/Quantity.java @@ -1,12 +1,10 @@ -package com.commerce.platform.core.domain.vo; +package com.commerce.shared.vo; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.exception.BusinessError; +import com.commerce.shared.exception.BusinessException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; -import static com.commerce.platform.shared.exception.BusinessError.INVALID_QUANTITY; -import static com.commerce.platform.shared.exception.BusinessError.QUANTITY_EXCEEDS_MAXIMUM; - @Embeddable public record Quantity ( @Column(name = "value") @@ -17,7 +15,7 @@ public Quantity add(Quantity quantity) { } public Quantity minus(Quantity quantity) { - if(this.value < quantity.value) throw new BusinessException(QUANTITY_EXCEEDS_MAXIMUM); + if(this.value < quantity.value) throw new BusinessException(BusinessError.QUANTITY_EXCEEDS_MAXIMUM); return new Quantity(this.value - quantity.value); } @@ -27,7 +25,7 @@ public static Quantity create(long quantity) { } public Quantity { - if(value < 0) throw new BusinessException(INVALID_QUANTITY); + if(value < 0) throw new BusinessException(BusinessError.INVALID_QUANTITY); } } diff --git a/platform/src/main/java/com/commerce/platform/core/domain/vo/ValidPeriod.java b/shared/src/main/java/com/commerce/shared/vo/ValidPeriod.java similarity index 80% rename from platform/src/main/java/com/commerce/platform/core/domain/vo/ValidPeriod.java rename to shared/src/main/java/com/commerce/shared/vo/ValidPeriod.java index 3f1f2d9..c6d2e82 100644 --- a/platform/src/main/java/com/commerce/platform/core/domain/vo/ValidPeriod.java +++ b/shared/src/main/java/com/commerce/shared/vo/ValidPeriod.java @@ -1,13 +1,13 @@ -package com.commerce.platform.core.domain.vo; +package com.commerce.shared.vo; -import com.commerce.platform.shared.exception.BusinessException; +import com.commerce.shared.exception.BusinessException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import java.io.Serializable; import java.time.LocalDate; -import static com.commerce.platform.shared.exception.BusinessError.INVALID_PERIOD; +import static com.commerce.shared.exception.BusinessError.INVALID_PERIOD; @Embeddable public record ValidPeriod ( diff --git a/shared/src/main/resources/application.yml b/shared/src/main/resources/application.yml new file mode 100644 index 0000000..c6d46f4 --- /dev/null +++ b/shared/src/main/resources/application.yml @@ -0,0 +1,5 @@ +server: + port: 8082 + +aes256: + key: 61qDonoZcEtIEvUZVPkIKIYovHH82rXtK7T1g/rcc1k= \ No newline at end of file