Add payment domain and data access modules

This commit is contained in:
Ali CANLI
2022-07-13 12:49:02 +03:00
parent 2071a3dd86
commit ef9c18bfbd
66 changed files with 1551 additions and 49 deletions

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>payment-domain</artifactId>
<groupId>com.food.order</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>payment-application-service</artifactId>
<dependencies>
<dependency>
<groupId>com.food.order</groupId>
<artifactId>payment-domain</artifactId>
</dependency>
<dependency>
<groupId>com.food.order</groupId>
<artifactId>common-domain</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>com.food.order</groupId>
<artifactId>payment-domain-core</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,90 @@
package com.food.order.system.payment.application.service;
import com.food.order.system.payment.application.service.dto.PaymentRequest;
import com.food.order.system.payment.application.service.exception.PaymentApplicationServiceException;
import com.food.order.system.payment.application.service.mapper.PaymentDataMapper;
import com.food.order.system.payment.application.service.ports.output.repository.CreditEntryRepository;
import com.food.order.system.payment.application.service.ports.output.repository.CreditHistoryRepository;
import com.food.order.system.payment.application.service.ports.output.repository.PaymentRepository;
import com.food.order.system.payment.service.domain.PaymentDomainService;
import com.food.order.system.payment.service.domain.entity.CreditEntry;
import com.food.order.system.payment.service.domain.entity.CreditHistory;
import com.food.order.system.payment.service.domain.entity.Payment;
import com.food.order.system.payment.service.domain.event.PaymentCancelledEvent;
import com.food.order.system.payment.service.domain.event.PaymentCompletedEvent;
import com.food.order.system.payment.service.domain.event.PaymentEvent;
import com.food.order.system.payment.service.domain.event.PaymentFailedEvent;
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
import com.food.order.sysyem.valueobject.CustomerId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Component
@Slf4j
@RequiredArgsConstructor
public class PaymentRequestHelper {
private final PaymentDomainService paymentDomainService;
private final PaymentDataMapper paymentDataMapper;
private final PaymentRepository paymentRepository;
private final CreditEntryRepository creditEntryRepository;
private final CreditHistoryRepository creditHistoryRepository;
private final DomainEventPublisher<PaymentCompletedEvent> publisher;
private final DomainEventPublisher<PaymentCancelledEvent> publisherCancelled;
private final DomainEventPublisher<PaymentFailedEvent> failedEventDomainEventPublisher;
@Transactional
public PaymentEvent persistPayment(PaymentRequest paymentRequest) {
log.info("Received payment complete event for id : {}", paymentRequest.getOrderId());
var payment = paymentDataMapper.paymentRequestModelToPayment(paymentRequest);
var creditEntry = getCreditEntry(payment.getCustomerId());
var creditHistory = getCreditHistory(payment.getCustomerId());
List<String> failureMessage = new ArrayList<>();
var paymentEvent = paymentDomainService.validateAndInitializePayment
(payment, creditEntry, creditHistory, failureMessage,publisher,failedEventDomainEventPublisher);
persistDbObject(payment, creditEntry, creditHistory, failureMessage);
return paymentEvent;
}
public PaymentEvent persistCancelPayment(PaymentRequest paymentRequest) {
log.info("Received payment cancel event for id : {}", paymentRequest.getOrderId());
var payment = paymentRepository.findByOrderId
(UUID.fromString(paymentRequest.getOrderId())).orElseThrow(
() -> new PaymentApplicationServiceException("Payment not found"));
var creditEntry = getCreditEntry(payment.getCustomerId());
var creditHistory = getCreditHistory(payment.getCustomerId());
List<String> failureMessage = new ArrayList<>();
var paymentEvent = paymentDomainService.validateAndCancelledPayment
(payment, creditEntry, creditHistory, failureMessage,publisherCancelled,failedEventDomainEventPublisher);
persistDbObject(payment, creditEntry, creditHistory, failureMessage);
return paymentEvent;
}
private void persistDbObject(Payment payment, CreditEntry creditEntry, List<CreditHistory> creditHistory, List<String> failureMessage) {
paymentRepository.save(payment);
if (failureMessage.isEmpty()) {
creditEntryRepository.save(creditEntry);
creditHistoryRepository.save(creditHistory.get(creditHistory.size() - 1));
}
}
private List<CreditHistory> getCreditHistory(CustomerId customerId) {
return creditHistoryRepository.findByCustomerId(customerId).orElseThrow(
() -> new PaymentApplicationServiceException("No credit history found for customer id : " + customerId));
}
private CreditEntry getCreditEntry(CustomerId customerId) {
return creditEntryRepository.findByCustomerId(customerId).orElseThrow(
() -> new PaymentApplicationServiceException("Credit entry not found for customer id : " + customerId));
}
}

View File

@@ -0,0 +1,35 @@
package com.food.order.system.payment.application.service;
import com.food.order.system.payment.application.service.dto.PaymentRequest;
import com.food.order.system.payment.application.service.ports.input.message.listener.PaymentRequestMessageListener;
import com.food.order.system.payment.service.domain.event.PaymentEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
@RequiredArgsConstructor
public class PaymentRequestMessageListenerImpl implements PaymentRequestMessageListener {
private final PaymentRequestHelper paymentRequestHelper;
@Override
public void completePayment(PaymentRequest paymentRequest) {
var event = paymentRequestHelper.persistPayment(paymentRequest);
fireEvent(event);
}
@Override
public void cancelPayment(PaymentRequest paymentRequest) {
var event = paymentRequestHelper.persistCancelPayment(paymentRequest);
fireEvent(event);
}
private void fireEvent(PaymentEvent event) {
log.info("Firing event : {}", event);
event.fire();
}
}

View File

@@ -0,0 +1,15 @@
package com.food.order.system.payment.application.service.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "payment-service")
public class PaymentServiceConfigData {
private String paymentRequestTopicName;
private String paymentResponseTopicName;
}

View File

@@ -0,0 +1,26 @@
package com.food.order.system.payment.application.service.dto;
import com.food.order.sysyem.valueobject.PaymentOrderStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import java.math.BigDecimal;
import java.time.Instant;
@Getter
@Builder
@AllArgsConstructor
public class PaymentRequest {
private String id;
private String sagaId;
private String orderId;
private String customerId;
private BigDecimal price;
private Instant createdAt;
private PaymentOrderStatus status;
public void setStatus(PaymentOrderStatus status) {
this.status = status;
}
}

View File

@@ -0,0 +1,14 @@
package com.food.order.system.payment.application.service.exception;
import com.food.order.sysyem.exception.DomainException;
public class PaymentApplicationServiceException extends DomainException {
public PaymentApplicationServiceException(String message) {
super(message);
}
public PaymentApplicationServiceException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,23 @@
package com.food.order.system.payment.application.service.mapper;
import com.food.order.system.payment.application.service.dto.PaymentRequest;
import com.food.order.system.payment.service.domain.entity.Payment;
import com.food.order.sysyem.valueobject.CustomerId;
import com.food.order.sysyem.valueobject.Money;
import com.food.order.sysyem.valueobject.OrderId;
import org.springframework.stereotype.Component;
import java.util.UUID;
@Component
public class PaymentDataMapper {
public Payment paymentRequestModelToPayment(PaymentRequest paymentRequest) {
return Payment.builder()
.customerId(new CustomerId(UUID.fromString(paymentRequest.getCustomerId())))
.orderId(new OrderId(UUID.fromString(paymentRequest.getOrderId())))
.price(new Money(paymentRequest.getPrice()))
.build();
}
}

View File

@@ -0,0 +1,8 @@
package com.food.order.system.payment.application.service.ports.input.message.listener;
import com.food.order.system.payment.application.service.dto.PaymentRequest;
public interface PaymentRequestMessageListener {
void completePayment(PaymentRequest paymentRequest);
void cancelPayment(PaymentRequest paymentRequest);
}

View File

@@ -0,0 +1,7 @@
package com.food.order.system.payment.application.service.ports.output.message.publisher;
import com.food.order.system.payment.service.domain.event.PaymentCancelledEvent;
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
public interface PaymentCancelledMessagePublisher extends DomainEventPublisher<PaymentCancelledEvent> {
}

View File

@@ -0,0 +1,7 @@
package com.food.order.system.payment.application.service.ports.output.message.publisher;
import com.food.order.system.payment.service.domain.event.PaymentCompletedEvent;
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
public interface PaymentCompletedMessagePublisher extends DomainEventPublisher<PaymentCompletedEvent> {
}

View File

@@ -0,0 +1,7 @@
package com.food.order.system.payment.application.service.ports.output.message.publisher;
import com.food.order.system.payment.service.domain.event.PaymentFailedEvent;
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
public interface PaymentFailedMessagePublisher extends DomainEventPublisher<PaymentFailedEvent> {
}

View File

@@ -0,0 +1,11 @@
package com.food.order.system.payment.application.service.ports.output.repository;
import com.food.order.system.payment.service.domain.entity.CreditEntry;
import com.food.order.sysyem.valueobject.CustomerId;
import java.util.Optional;
public interface CreditEntryRepository {
CreditEntry save(CreditEntry creditEntry);
Optional<CreditEntry> findByCustomerId(CustomerId orderId);
}

View File

@@ -0,0 +1,12 @@
package com.food.order.system.payment.application.service.ports.output.repository;
import com.food.order.system.payment.service.domain.entity.CreditHistory;
import com.food.order.sysyem.valueobject.CustomerId;
import java.util.List;
import java.util.Optional;
public interface CreditHistoryRepository {
CreditHistory save(CreditHistory creditHistory);
Optional<List<CreditHistory>> findByCustomerId(CustomerId orderId);
}

View File

@@ -0,0 +1,13 @@
package com.food.order.system.payment.application.service.ports.output.repository;
import com.food.order.system.payment.service.domain.entity.Payment;
import java.util.Optional;
import java.util.UUID;
public interface PaymentRepository {
Payment save(Payment payment);
Optional<Payment> findByOrderId(UUID orderId);
}

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>payment-domain</artifactId>
<groupId>com.food.order</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>payment-domain-core</artifactId>
<dependencies>
<dependency>
<groupId>com.food.order</groupId>
<artifactId>common-domain</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,29 @@
package com.food.order.system.payment.service.domain;
import com.food.order.system.payment.service.domain.entity.CreditEntry;
import com.food.order.system.payment.service.domain.entity.CreditHistory;
import com.food.order.system.payment.service.domain.entity.Payment;
import com.food.order.system.payment.service.domain.event.PaymentCancelledEvent;
import com.food.order.system.payment.service.domain.event.PaymentCompletedEvent;
import com.food.order.system.payment.service.domain.event.PaymentEvent;
import com.food.order.system.payment.service.domain.event.PaymentFailedEvent;
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
import java.util.List;
public interface PaymentDomainService {
PaymentEvent validateAndInitializePayment( Payment paymentEvent,
CreditEntry creditEntry,
List<CreditHistory> creditHistory,
List<String> failureMessages,
DomainEventPublisher<PaymentCompletedEvent> publisher,
DomainEventPublisher<PaymentFailedEvent> failedEventDomainEventPublisher);
PaymentEvent validateAndCancelledPayment( Payment paymentEvent,
CreditEntry creditEntry,
List<CreditHistory> creditHistory,
List<String> failureMessages,
DomainEventPublisher<PaymentCancelledEvent> publisher,
DomainEventPublisher<PaymentFailedEvent> failedEventDomainEventPublisher);
}

View File

@@ -0,0 +1,127 @@
package com.food.order.system.payment.service.domain;
import com.food.order.system.payment.service.domain.entity.CreditEntry;
import com.food.order.system.payment.service.domain.entity.CreditHistory;
import com.food.order.system.payment.service.domain.entity.Payment;
import com.food.order.system.payment.service.domain.event.PaymentCancelledEvent;
import com.food.order.system.payment.service.domain.event.PaymentCompletedEvent;
import com.food.order.system.payment.service.domain.event.PaymentEvent;
import com.food.order.system.payment.service.domain.event.PaymentFailedEvent;
import com.food.order.system.payment.service.domain.valueobject.CreditHistoryId;
import com.food.order.system.payment.service.domain.valueobject.TransactionType;
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
import com.food.order.sysyem.valueobject.Money;
import com.food.order.sysyem.valueobject.PaymentStatus;
import lombok.extern.slf4j.Slf4j;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.UUID;
import static com.food.order.sysyem.DomainConstants.UTC;
@Slf4j
public class PaymentDomainServiceImpl implements PaymentDomainService {
@Override
public PaymentEvent validateAndInitializePayment(Payment payment,
CreditEntry creditEntry,
List<CreditHistory> creditHistory,
List<String> failureMessages,
DomainEventPublisher<PaymentCompletedEvent> publisher,
DomainEventPublisher<PaymentFailedEvent> failedPublisher) {
payment.validatePayment(failureMessages);
payment.initializePayment();
validateCreditEntry(payment,creditEntry,failureMessages);
subtractCreditEntry(payment,creditEntry);
updateCreditHistory(payment,creditHistory, TransactionType.DEBIT);
validateCreditHistory(creditEntry,creditHistory,failureMessages);
if (failureMessages.isEmpty()) {
log.info("Payment is valid and initialized");
payment.updateStatus(PaymentStatus.COMPLETED);
return new PaymentCompletedEvent(payment, ZonedDateTime.now(ZoneId.of(UTC)),publisher );
} else {
log.info("Payment is invalid and not initialized");
payment.updateStatus(PaymentStatus.FAILED);
return new PaymentFailedEvent(payment, ZonedDateTime.now(ZoneId.of(UTC)), failureMessages,failedPublisher);
}
}
@Override
public PaymentEvent validateAndCancelledPayment(Payment payment,
CreditEntry creditEntry,
List<CreditHistory> creditHistory,
List<String> failureMessages,
DomainEventPublisher<PaymentCancelledEvent> publisher,
DomainEventPublisher<PaymentFailedEvent> failedPublisher) {
payment.validatePayment(failureMessages);
addCreditEntry(payment,creditEntry);
updateCreditHistory(payment,creditHistory, TransactionType.CREDIT);
if (failureMessages.isEmpty()) {
log.info("Payment is valid and cancelled");
payment.updateStatus(PaymentStatus.CANCELED);
return new PaymentCancelledEvent(payment, ZonedDateTime.now(ZoneId.of(UTC)),publisher);
} else {
log.info("Payment is invalid and not cancelled");
payment.updateStatus(PaymentStatus.FAILED);
return new PaymentFailedEvent(payment, ZonedDateTime.now(ZoneId.of(UTC)), failureMessages,failedPublisher);
}
}
private void addCreditEntry(Payment payment, CreditEntry creditEntry) {
creditEntry.addCreditAmount(payment.getPrice());
}
private void validateCreditHistory(CreditEntry creditEntry, List<CreditHistory> creditHistory, List<String> failureMessages) {
var totalCreditHistory = getTotalHistoryAmount(creditHistory, TransactionType.CREDIT);
var totalDebitHistory = getTotalHistoryAmount(creditHistory, TransactionType.DEBIT);
if (totalDebitHistory.isGreaterThan(totalCreditHistory)) {
failureMessages.add("Customer id " + creditEntry.getCustomerId() + " has insufficient credit");
log.error("Customer id {} has insufficient credit", creditEntry.getCustomerId());
}
if (!creditEntry.getTotalCreditAmount().equals(totalCreditHistory.subtract(totalDebitHistory))) {
failureMessages.add("Customer id " + creditEntry.getCustomerId() + " has total is not equal to credit history");
log.error("Customer id {} has total is not equal to credit history", creditEntry.getCustomerId());
}
}
private Money getTotalHistoryAmount(List<CreditHistory> creditHistory, TransactionType transactionType) {
return creditHistory.stream()
.filter(history -> transactionType.equals(history.getTransactionType()))
.map(CreditHistory::getAmount)
.reduce(Money.ZERO, Money::add);
}
private void updateCreditHistory(Payment payment, List<CreditHistory> creditHistory, TransactionType transactionType) {
creditHistory.add(
CreditHistory.builder()
.id(new CreditHistoryId(UUID.randomUUID()))
.customerId(payment.getCustomerId())
.amount(payment.getPrice())
.transactionType(transactionType)
.build()
);
}
private void subtractCreditEntry(Payment payment, CreditEntry creditEntry) {
creditEntry.subtractCreditAmount(payment.getPrice());
}
private void validateCreditEntry(Payment payment, CreditEntry creditEntry, List<String> failureMessages) {
if(payment.getPrice().isGreaterThan(creditEntry.getTotalCreditAmount())){
failureMessages.add("Customer id "+ payment.getCustomerId() + " , has insufficient credit amount" +
creditEntry.getTotalCreditAmount() + " to pay for order id " + payment.getOrderId());
log.error("Payment price is greater than credit");
}
}
}

View File

@@ -0,0 +1,70 @@
package com.food.order.system.payment.service.domain.entity;
import com.food.order.system.payment.service.domain.valueobject.CreditEntryId;
import com.food.order.sysyem.entity.BaseEntity;
import com.food.order.sysyem.valueobject.CustomerId;
import com.food.order.sysyem.valueobject.Money;
public class CreditEntry extends BaseEntity<CreditEntryId> {
private final CustomerId customerId;
private Money totalCreditAmount;
public void addCreditAmount(Money creditAmount) {
totalCreditAmount = totalCreditAmount.add(creditAmount);
}
public void subtractCreditAmount(Money creditAmount) {
totalCreditAmount = totalCreditAmount.subtract(creditAmount);
}
private CreditEntry(Builder builder) {
setId(builder.creditEntryId);
customerId = builder.customerId;
totalCreditAmount = builder.totalCreditAmount;
}
public static Builder builder() {
return new Builder();
}
public CustomerId getCustomerId() {
return customerId;
}
public Money getTotalCreditAmount() {
return totalCreditAmount;
}
public static final class Builder {
private CreditEntryId creditEntryId;
private CustomerId customerId;
private Money totalCreditAmount;
private Builder() {
}
public Builder id(CreditEntryId val) {
creditEntryId = val;
return this;
}
public Builder customerId(CustomerId val) {
customerId = val;
return this;
}
public Builder totalCreditAmount(Money val) {
totalCreditAmount = val;
return this;
}
public CreditEntry build() {
return new CreditEntry(this);
}
}
}

View File

@@ -0,0 +1,72 @@
package com.food.order.system.payment.service.domain.entity;
import com.food.order.system.payment.service.domain.valueobject.CreditHistoryId;
import com.food.order.system.payment.service.domain.valueobject.TransactionType;
import com.food.order.sysyem.entity.BaseEntity;
import com.food.order.sysyem.valueobject.CustomerId;
import com.food.order.sysyem.valueobject.Money;
public class CreditHistory extends BaseEntity<CreditHistoryId> {
private final CustomerId customerId;
private final Money amount;
private final TransactionType transactionType;
private CreditHistory(Builder builder) {
setId(builder.creditHistoryId);
customerId = builder.customerId;
amount = builder.amount;
transactionType = builder.transactionType;
}
public static Builder builder() {
return new Builder();
}
public CustomerId getCustomerId() {
return customerId;
}
public Money getAmount() {
return amount;
}
public TransactionType getTransactionType() {
return transactionType;
}
public static final class Builder {
private CreditHistoryId creditHistoryId;
private CustomerId customerId;
private Money amount;
private TransactionType transactionType;
private Builder() {
}
public Builder id(CreditHistoryId val) {
creditHistoryId = val;
return this;
}
public Builder customerId(CustomerId val) {
customerId = val;
return this;
}
public Builder amount(Money val) {
amount = val;
return this;
}
public Builder transactionType(TransactionType val) {
transactionType = val;
return this;
}
public CreditHistory build() {
return new CreditHistory(this);
}
}
}

View File

@@ -0,0 +1,119 @@
package com.food.order.system.payment.service.domain.entity;
import com.food.order.system.payment.service.domain.valueobject.PaymentId;
import com.food.order.sysyem.entity.AggregateRoot;
import com.food.order.sysyem.valueobject.CustomerId;
import com.food.order.sysyem.valueobject.Money;
import com.food.order.sysyem.valueobject.OrderId;
import com.food.order.sysyem.valueobject.PaymentStatus;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
public class Payment extends AggregateRoot<PaymentId> {
private final OrderId orderId;
private final CustomerId customerId;
private final Money price;
private PaymentStatus status;
private ZonedDateTime createdAt;
public void initializePayment(){
setId(new PaymentId(UUID.randomUUID()));
createdAt = ZonedDateTime.now(ZoneId.of("UTC"));
}
public void validatePayment(List<String > failureMessages){
if (Objects.isNull(price) || !price.isGreaterThanZero()){
failureMessages.add("Payment price must be greater than zero");
}
}
public void updateStatus ( PaymentStatus status ) {
this.status = status;
}
private Payment(Builder builder) {
setId(builder.paymentId);
orderId = builder.orderId;
customerId = builder.customerId;
price = builder.price;
status = builder.status;
createdAt = builder.createdAt;
}
public static Builder builder() {
return new Builder();
}
public OrderId getOrderId() {
return orderId;
}
public CustomerId getCustomerId() {
return customerId;
}
public Money getPrice() {
return price;
}
public PaymentStatus getStatus() {
return status;
}
public ZonedDateTime getCreatedAt() {
return createdAt;
}
public static final class Builder {
private PaymentId paymentId;
private OrderId orderId;
private CustomerId customerId;
private Money price;
private PaymentStatus status;
private ZonedDateTime createdAt;
private Builder() {
}
public Builder id(PaymentId val) {
paymentId = val;
return this;
}
public Builder orderId(OrderId val) {
orderId = val;
return this;
}
public Builder customerId(CustomerId val) {
customerId = val;
return this;
}
public Builder price(Money val) {
price = val;
return this;
}
public Builder status(PaymentStatus val) {
status = val;
return this;
}
public Builder createdAt(ZonedDateTime val) {
createdAt = val;
return this;
}
public Payment build() {
return new Payment(this);
}
}
}

View File

@@ -0,0 +1,23 @@
package com.food.order.system.payment.service.domain.event;
import com.food.order.system.payment.service.domain.entity.Payment;
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
import java.time.ZonedDateTime;
import java.util.Collections;
public class PaymentCancelledEvent extends PaymentEvent{
private final DomainEventPublisher<PaymentCancelledEvent> publisher;
public PaymentCancelledEvent(Payment payment, ZonedDateTime createdAt, DomainEventPublisher<PaymentCancelledEvent> publisher) {
super(payment, createdAt, Collections.emptyList());
this.publisher = publisher;
}
@Override
public void fire() {
publisher.publish(this);
}
}

View File

@@ -0,0 +1,25 @@
package com.food.order.system.payment.service.domain.event;
import com.food.order.system.payment.service.domain.entity.Payment;
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
import java.time.ZonedDateTime;
import java.util.Collections;
public class PaymentCompletedEvent extends PaymentEvent{
private final DomainEventPublisher<PaymentCompletedEvent> publisher;
public PaymentCompletedEvent(Payment payment,
ZonedDateTime createdAt,
DomainEventPublisher<PaymentCompletedEvent> publisher) {
super(payment, createdAt , Collections.emptyList());
this.publisher = publisher;
}
@Override
public void fire() {
publisher.publish(this);
}
}

View File

@@ -0,0 +1,31 @@
package com.food.order.system.payment.service.domain.event;
import com.food.order.system.payment.service.domain.entity.Payment;
import com.food.order.sysyem.event.DomainEvent;
import java.time.ZonedDateTime;
import java.util.List;
public abstract class PaymentEvent implements DomainEvent<Payment> {
private final Payment payment;
private final ZonedDateTime createdAt;
private final List<String> failureMessages;
public PaymentEvent(Payment payment, ZonedDateTime createdAt, List<String> failureMessages) {
this.payment = payment;
this.createdAt = createdAt;
this.failureMessages = failureMessages;
}
public Payment getPayment() {
return payment;
}
public ZonedDateTime getCreatedAt() {
return createdAt;
}
public List<String> getFailureMessages() {
return failureMessages;
}
}

View File

@@ -0,0 +1,23 @@
package com.food.order.system.payment.service.domain.event;
import com.food.order.system.payment.service.domain.entity.Payment;
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
import java.time.ZonedDateTime;
import java.util.List;
public class PaymentFailedEvent extends PaymentEvent{
private final DomainEventPublisher<PaymentFailedEvent> publisher;
public PaymentFailedEvent(Payment payment, ZonedDateTime createdAt, List<String> failureMessages,
DomainEventPublisher<PaymentFailedEvent> publisher) {
super(payment, createdAt, failureMessages);
this.publisher = publisher;
}
@Override
public void fire() {
publisher.publish(this);
}
}

View File

@@ -0,0 +1,13 @@
package com.food.order.system.payment.service.domain.exception;
import com.food.order.sysyem.exception.DomainException;
public class PayemntDomainException extends DomainException {
public PayemntDomainException(String message) {
super(message);
}
public PayemntDomainException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,13 @@
package com.food.order.system.payment.service.domain.exception;
import com.food.order.sysyem.exception.DomainException;
public class PaymentNotFoundException extends DomainException {
public PaymentNotFoundException(String message) {
super(message);
}
public PaymentNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,11 @@
package com.food.order.system.payment.service.domain.valueobject;
import com.food.order.sysyem.valueobject.BaseId;
import java.util.UUID;
public class CreditEntryId extends BaseId<UUID> {
public CreditEntryId(UUID value) {
super(value);
}
}

View File

@@ -0,0 +1,12 @@
package com.food.order.system.payment.service.domain.valueobject;
import com.food.order.sysyem.valueobject.BaseId;
import java.util.UUID;
public class CreditHistoryId extends BaseId<UUID> {
public CreditHistoryId(UUID value) {
super(value);
}
}

View File

@@ -0,0 +1,11 @@
package com.food.order.system.payment.service.domain.valueobject;
import com.food.order.sysyem.valueobject.BaseId;
import java.util.UUID;
public class PaymentId extends BaseId<UUID> {
public PaymentId(UUID id) {
super(id);
}
}

View File

@@ -0,0 +1,5 @@
package com.food.order.system.payment.service.domain.valueobject;
public enum TransactionType {
DEBIT, CREDIT
}

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>payment-service</artifactId>
<groupId>com.food.order</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>payment-domain</artifactId>
<packaging>pom</packaging>
<modules>
<module>payment-domain-core</module>
<module>payment-application-service</module>
</modules>
</project>