← 프로젝트 목록

Backend Project · 02

인증·결제 운영 플랫폼

인증 운영 기관 · 기업 연계 프로젝트 · Spring Boot 백엔드

Java 21Spring Boot 3.5Spring Security + JWTPortOneGemini Vision OCRMySQLRedisWebFluxSSE
Overview

기업이 비건 인증을 신청 → 서류 제출 → 심사 → 인증서 발급받는 전 과정을 처리하는 백엔드. 인증 운영 기관과 연계해 실제 운영 중이며, 결제 검증·JWT 인증·사업자등록증 OCR·인증 도메인·SSE 알림을 직접 담당했다.

Problem

인증 신청에는 유료 결제가 필수다. 외부 PG(PortOne) 연동과 프론트가 보낸 결제 금액의 위·변조를 서버에서 막아야 했고, 사업자등록증 서류에서 필드를 안정적으로 추출(OCR)하고, 심사 상태 변화를 사용자에게 실시간으로 알려야 했다.

My Role & Technical Decisions

결제 검증·JWT 인증·사업자등록증 OCR·인증 도메인·SSE 알림 담당 — PortOne 결제 사전등록(prepare)/검증(verify) 플로우, Spring Security + JWT 인증, PDFBox+Gemini Vision 기반 사업자등록증 구조화 추출, 인증 신청·심사·발급 도메인, SSE 실시간 알림을 설계·구현했다.

Architecture
인증·결제 운영 플랫폼 아키텍처민감한 운영 도메인을 익명화하고 결제, 인증, 증빙 처리의 책임 경계를 보여줍니다.

01 · 결제·주문

중복 요청을 차단하고 결제 결과를 주문 상태에 반영

  1. 01Web Client주문 · 결제 요청
  2. HTTPS
  3. 02Spring API멱등키 · 상태 검증
  4. approve
  5. 03Payment Gateway승인 · 취소
  6. transaction
  7. 04MariaDB주문 · 결제 원장
  8. result
  9. 05Notification처리 결과 안내

02 · 인증 처리

신원 확인과 권한 판정을 분리

  1. 01Identity Provider본인 확인
  2. verified identity
  3. 02Auth Service토큰 · 권한 정책
  4. authorized
  5. 03Certification API신청 · 심사 상태
  6. append
  7. 04Audit Log변경 이력

03 · 증빙 문서

업로드된 문서를 비동기로 추출·검증

  1. 01Document Upload증빙 파일
  2. store
  3. 02Object Storage암호화 보관
  4. process
  5. 03OCR Worker텍스트 추출
  6. exception
  7. 04Review Queue예외 수동 검수
  • 사용자·클라이언트
  • 애플리케이션
  • 데이터
  • 비동기 처리
  • 배포
  • 관측
  • 보안·검증
  • 외부 시스템
Key API Endpoints
MethodPathDescription
POST/api/payments/prepare결제 사전 등록 (주문·금액 생성)
POST/api/payments/verifyPortOne 결제 검증 (금액 위·변조 방지)
POST/api/business/ocr사업자등록증 OCR 구조화 추출
POST/api/vegan-certification비건 인증 신청
GET/api/certificate/**인증서 조회·발급
Troubleshooting & Evidence

전액 마일리지(0원) 결제가 영원히 '대기(PENDING)'에 멈추고 마일리지만 빠져나감↗

원인: 완료 처리를 PG 웹훅 수신에만 의존했는데, 0원 결제는 PortOne에 요청 자체가 가지 않아 웹훅이 영영 오지 않음. 게다가 마일리지를 prepare 시점에 선차감해 결제 미완료에도 차감은 이미 발생 — 두 결함의 결합으로 결제 불일치

해결: 0원 결제는 PG 조회·웹훅 대기를 건너뛰고 즉시 완료 처리하는 분기를 추가하고, 마일리지 차감 시점을 prepare→complete(@Transactional)로 이동해 실패 시 롤백으로 자동 복원. 완료는 기업 단위 Redisson 락으로 동시성을 보호하고, 누락 위험이 있던 수동 보상 로직을 제거(약 -255줄)

배운 점: 완료 처리를 외부 콜백(웹훅) 단일 경로에만 의존하면 콜백이 안 오는 엣지(0원 등)에서 통째로 멈춘다 — 동기 검증 경로에도 완료 트리거를 두고, 차감 같은 부수효과는 확정 시점에 두거나 트랜잭션 롤백으로 복원되게 설계한다

사업자등록증 OCR의 필드 추출이 불안정↗

원인: Tesseract의 인식 성능 자체가 사업자등록증에서 부족(필드 누락·오인식). 전처리·파라미터·후처리 규칙을 계속 손봐야 했다

해결: 튜닝 비용과 교체 비용을 비교해 Gemini Vision으로 교체. PDFBox로 PDF를 이미지화하고, 출력 형식을 JSON 스키마로 고정해 필드를 직접 구조화 수신 — 정확도를 끌어올린 핵심은 이 JSON 형식 지정이었다. LLM 응답의 코드펜스·잡텍스트는 정제 후 파싱(신뢰 경계)

배운 점: 표·레이아웃이 있는 정형 서류는 텍스트 OCR 결과를 후처리로 필드에 매핑하는 방식이 문서 서식이 바뀔 때마다 깨진다 — 추출 단계에서 바로 구조화(JSON)하면 후처리 자체가 사라진다

Metrics
PENDING 고착 해소
0원 결제 완료 분기 + 마일리지 차감 시점 이동
수동 보상 제거
트랜잭션 롤백으로 마일리지 정합성 보장
후처리 제거
OCR 결과를 Gemini JSON 구조화 추출로 대체
Infra & Deploy

Spring Boot 3.5(Java 21) · Spring Security + JWT · MySQL · Redis(토큰). WebFlux WebClient로 PortOne 결제 API 호출, PDFBox+Gemini Vision 사업자등록증 OCR, 메일 발송, SSE 기반 실시간 알림. 기업·사업자 서류와 인증서 문서 흐름 관리.

Next Step

프로젝트에 대해 더 이야기해 보세요.

연락하기