내용

정산 시스템의 본질은 단순 CRUD가 아니라 **금액의 ‘확정 상태 관리’**입니다.

  • 결제(Payment)
    • 외부 PG 기준
    • 성공/실패 중심
    • 실시간 처리
  • 정산(Settlement)
    • 내부 재무 기준
    • 확정/미확정/조정 상태 존재
    • 배치 + 후처리

문제 상황

  • 결제 = 돈 들어옴
  • 환불 = 돈 나감
    → 단순히 payment에 음수 넣으면?

👉 데이터 무결성 붕괴 + 회계 대응 불가

해결

  • Payment ≠ Settlement
  • Refund 별도 엔티티
  • 정산은 상태 기반 관리

핵심 메시지

“정산은 이벤트 기록이 아니라 상태 관리 시스템이다”


2.

“정산 시스템에서 부분 환불을 설계하는 방법 – 음수 금액 모델의 함정”

내용

잘못된 방식

payment.amount = -10000
 

문제

  • 회계팀 이해 불가
  • 집계 쿼리 복잡도 폭발
  • 정산 기준 불일치

올바른 방식

  • Payment
  • Refund (별도 테이블)
  • Settlement (정산 결과)
Order
├─ Payment (10000)
├─ Refund (3000)
└─ Settlement (7000)
 

포인트

  • 환불은 “부정값”이 아니라 독립 이벤트
  • 정산은 “계산 결과”

3.

“정산 배치 설계 – 하루에 한 번 돌리면 끝인가?”

내용

정산 배치는 단순 스케줄러가 아니라
데이터 확정 프로세스

고려사항

  • PG 정산 지연
  • 취소/환불 타이밍
  • 재정산 필요성

설계

  • T+1 정산
  • 상태값
    • READY
    • SETTLED
    • ADJUSTED

추가

  • 재정산 가능 구조 필수
  • idempotency 보장

4.

“정산 시스템 동시성 문제 해결 – Optimistic Lock과 Retry 전략”

내용

문제

  • 동시에 환불 요청
  • 중복 정산
  • 금액 꼬임

해결

  • JPA Optimistic Lock
  • Retry 로직
 
@Version
private Long version;
 

핵심 포인트

  • 락보다 중요한 건 재시도 설계
  • 정산은 반드시 멱등성 보장

5.

“정산 시스템에서 멱등성(Idempotency)을 설계하는 방법”

내용

왜 중요한가

  • PG 중복 호출
  • 네트워크 재시도
  • 사용자 중복 클릭

해결

  • idempotency key
  • unique constraint
(orderId + actionType)
 

효과

  • 중복 환불 방지
  • 데이터 안정성 확보

6.

“정산 도메인에서 Aggregate 설계를 어떻게 해야 하는가”

내용

Aggregate 기준

  • Order
  • Payment
  • Refund
  • Settlement

잘못된 구조

  • 모든 걸 Order에 몰아넣음

올바른 구조

  • 책임 분리
  • 트랜잭션 경계 분리

7.

“이벤트 기반 정산 처리 – @TransactionalEventListener 활용 전략”

내용

  • 결제 완료 → 이벤트 발생
  • 정산 큐 적재
 
@TransactionalEventListener
 

장점

  • 결제와 정산 분리
  • 확장성 확보

8.

“정산 시스템 장애 사례 – 실제로 터지는 문제들”

내용

  • 환불 후 정산 미반영
  • 중복 정산
  • 배치 실패

대응

  • 재처리 구조
  • 로그 기반 복구
  • 상태 기반 설계

9.

“정산 시스템에서 쿼리 성능 최적화 – QueryDSL vs JPQL”

내용

  • 정산은 조회가 핵심
  • 집계 쿼리 많음

전략

  • QueryDSL로 복잡 쿼리 관리
  • Projection 활용

10.

“정산 시스템 아키텍처 – 모놀리식 vs MSA 어디까지 분리해야 하는가”

내용

  • Payment
  • Settlement
  • Accounting

판단 기준

  • 트래픽
  • 데이터 정합성 요구
LIST

+ Recent posts