결제 서비스 개요
자체 결제 수단을 운영하고, 이를 기반으로 결제, 환불, 정산까지 처리하는 전용 페이먼트 플랫폼
외부 PG나 카드망을 거치지 않고, 내부 원장과 트랜잭션 상태를 직접 관리
단일 서비스에 결제 로직이 집중되는 구조를 피하기 위해 Pay·Transaction·Payment 서비스로 책임을 분리하고,
결제 흐름을 상태 기반 전이(State Transaction)로 관리하는 구조



ERD 설계

Pay Service: 결제 오케스트레이션 & 사용자 자산 관리
- 사용자의 계좌(Account)·결제 잔액(Pay)·포인트(Point) 관리
- 결제 전체 흐름을 조율하는 중앙 오케스트레이터 역할을 수행
주요 필드
Account
- accountId (PK)
- userId
- balance
- status
- createdAt
- updatedAt
Pay
- payId (PK)
- userId
- amount
- createdAt
- updatedAt
Point
- pointId (PK)
- userId
- balance
- createdAt
- updatedAt
특징
- 사용자 계좌(Account), 결제 잔액(Pay), 포인트(Point)의 정합성 관리 주체
- 결제 흐름을 조율하는 중앙 오케스트레이터 역할 수행
- 실제 금액 차감 및 포인트 사용은 Pay 서비스에서 수행
- 결제 결과를 Transaction 서비스의 상태 전이로 확정
- Redis 기반 분산 락으로 중복 결제 및 Race Condition 방지
- 결제 완료 후 보상/적립 로직은 Kafka 기반 비동기 처리
- `transactionId` 기반 멱등성 보장
Transaction Service: 결제 상태의 Source of Truth
- 결제 요청의 상태를 단일 기준으로 관리
- 결제 흐름 전체에서 Source of Truth 역할 수행
- 결제의 시작부터 완료/실패까지 현재 결제 진행 단계를 명확히 표현
주요 필드
Transaction
- transactionId (PK)
- userId
- sellerId
- orderId
- amount
- status (PENDING / PAYMENT / REFUND / CANCELLATION / SUCCESS / FAILED)
- createdAt
- updatedAt
특징
- 결제 요청 시 가장 먼저 생성되는 엔티티
- 생성 시점에는 절대 돈이 이동하지 않음
- 상태 전이 기반 설계로 결제 흐름 단순화
- 중복 요청·네트워크 재전송 상황에서도 idempotent
- Kafka를 통해 상태 변경 이벤트 발행
- Pay, Notification, Cash 서비스는 Transaction 상태를 구독
Payment Service: 결제 실행 기록 & 프로세스 관리
- 결제 / 환불 / 취소 요청을 실행 단위로 기록하는 서비스
- 실제 자산 변경은 수행하지 않으며, Pay 서비스에 잔액 검증만 위임
- 결제 시도의 결과를 Payment 상태(`PAYMENT` / `FAILED` 등)로 기록
- `transactionId`를 기준으로 Transaction 흐름에 종속
주요 필드
Payment
- paymentId (PK)
- transactionId (FK → Transaction)
- method (INTERNAL / EXTERNAL)
- status
- approvedAt
- createdAt
- updatedAt
특징
- 실제 돈을 이동시키지 않음
- Transaction 상태 전이의 근거 데이터 제공
- Pay 서비스와 직접적인 상태 공유 없음
- Transaction을 통해 간접적으로 연결
- 결제 실패·취소·환불 이력의 단일 실행 로그 역할
전체 결제 흐름
시퀀스 다이어그램

1단계: 결제 시작 (Pay -> Transaction)
- Pay 서비스: 결제 요청을 수신
- Transaction: 결제 트랜잭션을 대기 상태(`PENDING`) 로 생성 요청
- Transaction: `transactionId`를 발급
- Pay: 해당 `transactionId`를 담은 보안 토큰(JWT) 을 생성해 응답
특징
- 이 단계에서는 돈 움직임 X
- 트랜잭션 상태: `PENDING`
- 사용자에게 결제 프론트엔드로 Redirect 가능
- 락 범위: `user` 단위, 짧은 시간
=> 결제 의사만 기록하고, 실제 결제는 아직 확정되지 않은 상태
2단계: 결제 가능 상태 조회 (결제 프론트엔드 -> Pay)
- 결제 시작 이후, 사용자는 결제 전용 프론트엔드 페이지로 리다이렉트
- 결제 프론트엔드 토큰을 전달하며 결제 가능 여부 조회를 요청
- Pay: 토큰을 통해 트랜잭션을 식별
- 다음 정보를 읽기 전용으로 조회
- Transaction 상태
- Pay 잔액
- Point
- Account
특징
- 상태 변경 X
- 읽기 전용
- 결제 가능 여부 판단
- 포인트 사용 UI
- 최종 결제 금액 표시
=> 결제 확정을 위한 사전 조회이며, 실제 금액 차감이나 결제 성공 판정은 수행 X
3단계: 실결제 (Pay -> Transaction -> Payment -> Pay)
- Pay: 결제 흐름을 중앙에서 조율
- Payment: 결제 성공 여부를 판정
- Pay: 그 결과를 신뢰하고 금전 상태를 반영
상세 흐름
- Pay: 토큰을 통해 트랜잭션을 식별하고 결제 확정 흐름을 시작
- Transaction: 결제 대상 트랜잭션을 조회
- Pay: 결제 확정 요청을 Transaction 서비스에 전달
- Transaction: Payment 서비스에 결제 처리를 위임
- Payment: Pay 서비스에 결제 가능 여부(잔액/포인트) 를 질의
- 결제가 가능하면 Payment는 결제 성공(`PAYMENT`) 상태로 기록
- Transaction: 해당 결제 결과를 반영하여 상태를 `PAYMENT`로 전이
- Pay는 결제 성공(`PAYMENT`) 상태를 기준으로:
- Pay 잔액 차감
- Point 차감
- PaySettlement 기록
특징
- 결제 성공의 판정자: Payment 서비스
- 실제 금전 차감의 집행자: Pay 서비스
- 상태의 Source of Truth: Transaction 서비스
=> 실제 금액 차감은 Pay 서비스에서 수행되며, Transaction의 `PAYMENT` 상태 전이를 통해 결제 결과가 확정
(2단계의 사전 결제 검증 결과와 무관하게 Payment 서비스의 결제 처리 결과 기준으로 최종 결제 성공 여부 결정)
4단계: 결제 완료 후 정합성
- Transaction 서비스는 상태 변경을 Kafka 이벤트로 발행
- 상태: `PAYMENT`/`REFUND`/`CANCELLATION`
- Pay 서비스는 해당 이벤트를 구독해
- 포인트 보상
- 추가 보정 처리
- 후속 비즈니스 로직 수행
특징
- 비동기 처리
- 최종 일관성(Eventual Consistency)
- Transaction이 시스템의 Source of Truth
참고
기본 클라이언트
→ Pay (결제 시작)
→ Redirect (결제 프론트엔드 + token)
→ 결제 프론트엔드가 Pay API 조회
- 기본 클라이언트
- 상품 선택
- 결제 요청 시작
- 결제 프론트엔드 (결제 전용 페이지)
- Pay가 제공하는 결제 UI
- 토큰 기반으로 상태 조회 / 결제 확정
깃허브
플랜티파이
플랜티파이 has 21 repositories available. Follow their code on GitHub.
github.com
GitHub - hk-plantify/pay-service: [Java] Account, Pay, Point 등 페이 결제 관련 서비스(+ transaction, payment repo)
[Java] Account, Pay, Point 등 페이 결제 관련 서비스(+ transaction, payment repo) - hk-plantify/pay-service
github.com
GitHub - hk-plantify/transaction-service
Contribute to hk-plantify/transaction-service development by creating an account on GitHub.
github.com
GitHub - hk-plantify/payment-service
Contribute to hk-plantify/payment-service development by creating an account on GitHub.
github.com