환불 처리 완료 시 Booking 서비스가 예매 취소 상태로 변경할 수 있도록 payment.refund.completed 이벤트 발행을 추가했다.
1. 배경
기존에는 환불 처리가 완료되어도 Booking 서비스에 알리는 방법이 없었다.
Payment → 환불 처리 완료 (REFUNDED)
→ Booking은 모름
→ 예매 상태가 취소로 변경되지 않음 💀
Booking 서비스가 예매 취소 처리를 할 수 있도록 이벤트를 발행해야 했다.
2. 이벤트 명세서 작성
팀과 함께 이벤트 명세서를 작성했다.
결제 관련 이벤트를 명확하게 분리했다.
payment.completed → 결제 승인 완료 시 발행
payment.failed → 결제 최종 실패 시 발행
payment.refund.completed → 환불 완료 시 발행 (신규)
3. Payload 설계
Booking 담당자와 협의해서 Payload를 결정했다.
public record PaymentRefundCompletedPayload(
UUID paymentId,
UUID bookingId,
UUID userId
) {}
환불 완료 이벤트는 Booking이 예매 취소 처리하는 데 필요한 최소한의 정보만 담았다. reason은 환불 완료 이벤트에서는 불필요하다고 판단해서 제외했다.
4. PaymentRefundCompletedPayload 추가
public record PaymentRefundCompletedPayload(
UUID paymentId,
UUID bookingId,
UUID userId
) {
public static PaymentRefundCompletedPayload from(Payment payment) {
return new PaymentRefundCompletedPayload(
payment.getId(),
payment.getBookingId(),
payment.getUserId()
);
}
}
5. refundPayment()에 이벤트 발행 추가
// 5. 결제 상태 변경
payment.refund();
paymentRepository.save(payment);
// 6. 환불 완료 이벤트 발행
try {
Events.publish(
UUID.randomUUID().toString(),
"PAYMENT",
payment.getId(),
"payment.refund.completed",
PaymentRefundCompletedPayload.from(payment)
);
} catch (Exception e) {
log.error("환불 완료 이벤트 발행 실패 - paymentId: {}", payment.getId(), e);
// TODO: 보상 트랜잭션 구현 후 재발행 경로 연결 예정
}
6. 코드래빗 리뷰 대응
코드래빗이 중요한 문제를 지적했다.
토스 환불 성공 후 Events.publish()에서 예외가 나면
트랜잭션이 롤백되어 외부는 환불 완료인데
내부 결제는 REFUNDED로 남지 않을 수 있음
try-catch로 감싸서 이벤트 발행 실패가 트랜잭션 롤백으로 이어지지 않도록 했다.
이벤트 발행 실패 시 로그만 남기고 추후 보상 트랜잭션 구현 시 재발행 경로를 연결할 예정이다.
7. 전체 환불 흐름
사용자 환불 요청 또는 Booking 서비스 이벤트 수신
→ 토스 취소 요청
→ REFUNDED 상태 변경
→ payment.refund.completed 이벤트 발행
→ Booking이 수신
→ 예매 취소 처리
마무리
이벤트 명세서를 팀과 함께 작성하면서 서비스 간 통신 계약을 명확하게 정의했다.
이벤트 발행 실패가 트랜잭션 롤백으로 이어지면 외부 API(토스)와 내부 상태가 불일치할 수 있다. try-catch로 일단 보호하고 추후 보상 트랜잭션으로 완전한 해결책을 마련할 예정이다.
'Spring 개발일지' 카테고리의 다른 글
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - Kafka 토픽명 설정값 분리 / DB 인덱스 추가 / 테스트 코드 보완 (0) | 2026.06.01 |
|---|---|
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 사가 패턴 / 보상 트랜잭션 / DLQ 구현 (0) | 2026.05.29 |
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - Dockerfile 및 CI workflow 작성 (0) | 2026.05.27 |
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 결제 만료 스케줄러 구현 (0) | 2026.05.26 |
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 결제 서비스 코드 리팩토링 (0) | 2026.05.25 |