Skip to content

seunggulee1007/TossPayments

Repository files navigation

TossPayment

이 프로젝트는 인프런의 견고한 결제 시스템 구축 강의를 보며 공부할 겸 만든 결제 시스템 프로젝트입니다.

Kotlin, Spring Boot, Kafka, PostgreSQL을 사용해 결제 생성부터 PSP 승인, 정산, 원장 기록, 복구까지 이어지는 전체 흐름을 헥사고날 아키텍처로 구현했습니다.

서비스 구성

서비스 포트 역할
payment-service 8081 체크아웃, PSP 승인, 아웃박스 릴레이, 복구 처리
wallet-service 8082 판매자 지갑 정산과 낙관적 락 기반 동시성 제어
ledger-service 8083 복식부기 원장 기록

아키텍처 원칙

모든 서비스는 헥사고날 아키텍처를 기준으로 구성했습니다.

  • domain: 프레임워크에 의존하지 않음
  • application: 포트와 도메인에만 의존
  • adapter.in: HTTP, Kafka, 스케줄러 같은 외부 입력 수신
  • adapter.out: DB, Kafka, Toss API 같은 외부 연동 구현
  • bootstrap: Spring 빈 설정과 wiring 담당

결제 흐름

클라이언트 → 체크아웃 → Toss 승인 요청 → Outbox 저장 → Kafka 발행
                                                        ↓
                              payment.confirmed → wallet-service → wallet.updated ─┐
                                              └→ ledger-service → ledger.updated ──┤
                                                                                   ↓
                                                         payment-service가 최종 완료 처리

신뢰성 설계

항목 적용 위치
Transactional Outbox payment-service: 승인 성공 후 바로 Kafka에 보내지 않고 outbox에 저장한 뒤 relay
멱등 소비 wallet-service, ledger-service: processed-message 테이블로 중복 메시지 방지
낙관적 락 wallet-service, payment-service: @Version과 재시도로 동시성 충돌 완화
Dead Letter Queue 세 서비스 모두 비재시도 가능 실패를 .dlt 토픽으로 이동
Recovery Scheduler payment-service: EXECUTING, UNKNOWN 상태를 주기적으로 스캔

로컬 실행

필수 준비물:

  • Java 17
  • Docker

인프라 실행:

docker compose -f infra/docker-compose.yml up -d

애플리케이션 실행:

docker compose -f infra/docker-compose.yml up --build payment-service wallet-service ledger-service

로컬 엔드포인트

항목 URL
PostgreSQL localhost:5432
Kafka localhost:9092
Kafka UI http://localhost:8080
Payment 헬스체크 http://localhost:8081/actuator/health
Wallet 헬스체크 http://localhost:8082/actuator/health
Ledger 헬스체크 http://localhost:8083/actuator/health

주요 Payment API

메서드 경로 설명
POST /api/checkout 결제 주문 생성
GET /api/payments/{orderId} 결제 상태와 주문별 wallet/ledger 진행 상황 조회
POST /api/payments/recovery/scan 수동 복구 스캔 실행
GET /api/payments/recovery/pending 복구 대상 결제 목록 조회
GET /payments/success 결제 성공 리다이렉트 페이지

설정

Toss 시크릿 키는 TOSS_SECRET_KEY 환경 변수로 주입합니다. PSP 호출 타임아웃은 기본적으로 connect 3초, read 10초입니다.

payment:
  toss:
    connect-timeout: 3s
    read-timeout: 10s

Kafka consumer 재시도 설정은 서비스별로 조정할 수 있습니다.

<service>:
  messaging:
    retry-attempts: 2
    retry-backoff: 1s
    retry-max-backoff: 10s
    retry-multiplier: 2.0
    retry-jitter: 0.2
    dead-letter-suffix: .dlt

현재 한계

  • PSP 정산 파일 기반 reconciliation은 아직 구현하지 않았습니다.
  • 운영용 대시보드나 관리자 UI는 최소 수준만 구현되어 있습니다.

빌드 메모

  • Java 17 환경이 필요합니다.
  • Gradle 9에서 Kotlin/Detekt 플러그인 관련 deprecation warning이 일부 남아 있지만 테스트는 통과합니다.

About

토스페이먼츠 결제 승인부터 정산, 원장 기록, 복구까지 다루는 헥사고날 아키텍처 기반 결제 시스템 프로젝트

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors