OrderPaidHandler.java
package com.ecommerce.inventory.application.service;
import com.ecommerce.inventory.application.exception.InventoryError;
import com.ecommerce.inventory.application.exception.InventoryException;
import com.ecommerce.inventory.application.model.InventoryModels.ReservationView;
import com.ecommerce.inventory.infrastructure.persistence.mapper.ConsumedEventMapper;
import com.ecommerce.inventory.infrastructure.persistence.mapper.InventoryReservationMapper;
import com.ecommerce.platform.common.idempotency.PayloadFingerprint;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class OrderPaidHandler {
public static final String CONSUMER_GROUP = "inventory-order-paid-v1";
private final ConsumedEventMapper consumedEventMapper;
private final InventoryReservationMapper reservationMapper;
private final InventoryService inventoryService;
public OrderPaidHandler(
ConsumedEventMapper consumedEventMapper,
InventoryReservationMapper reservationMapper,
InventoryService inventoryService) {
this.consumedEventMapper = consumedEventMapper;
this.reservationMapper = reservationMapper;
this.inventoryService = inventoryService;
}
@Transactional
public void handle(OrderPaidCommand command) {
String payloadFingerprint = PayloadFingerprint.of(command.orderNo(), command.reservationNo());
if (consumedEventMapper.insertIfAbsent(
command.eventId(), CONSUMER_GROUP, payloadFingerprint,
reservationMapper.currentTime()) != 1) {
String storedFingerprint = consumedEventMapper.selectPayloadFingerprint(
command.eventId(), CONSUMER_GROUP);
if (!PayloadFingerprint.matches(storedFingerprint, payloadFingerprint)) {
throw new InventoryException(InventoryError.IDEMPOTENCY_CONFLICT);
}
return;
}
ReservationView reservation = inventoryService.getReservation(command.reservationNo());
if (!reservation.orderNo().equals(command.orderNo())) {
throw new InventoryException(InventoryError.IDEMPOTENCY_CONFLICT);
}
ReservationView confirmed =
inventoryService.confirmReservation(command.reservationNo());
if (!"CONFIRMED".equals(confirmed.status())) {
throw new InventoryException(InventoryError.INVALID_STATE);
}
}
public record OrderPaidCommand(String eventId, String orderNo, String reservationNo) {
}
}