spring_2기[본캠프]/과제

[과제] 결제 시스템 Day4

minwoo95 2026. 2. 9. 21:40

https://github.com/teeeam3/payment-assignment

 

GitHub - teeeam3/payment-assignment: 결제 도메인 프로젝트입니다

결제 도메인 프로젝트입니다. Contribute to teeeam3/payment-assignment development by creating an account on GitHub.

github.com

1. 트러블슈팅: RestTemplate 빈(Bean) 주입 실패 및 라이브러리 인식 오류
[문제 상황]
PortOneClientImpl 작성 중 RestTemplate과 RestTemplateBuilder에 빨간 불이 들어오며 컴파일 에러 발생.
import 문을 추가했음에도 인텔리제이에서 client 패키지 경로를 인식하지 못함.

[원인 분석]
Spring Boot 3.x 버전의 변화: 이전 버전과 달리 RestTemplate을 자동으로 빈 등록해주지 않음.
IDE 캐시 및 라이브러리 꼬임: build.gradle에 의존성이 있어도 IDE 환경에서 인덱싱 오류로 경로를 찾지 못하는 현상 발생.

[해결 과정]
Configuration 클래스 생성: RestTemplateConfig를 만들어 직접 @Bean으로 등록하여 의존성 주입 환경 구축.
타임아웃 설정: 외부 API 장애 시 우리 서버의 가용성을 지키기 위해 연결(Connect) 및 읽기(Read) 타임아웃(5초)을 수동 설정.
인텔리제이 캐시 무효화: '파일 > 캐시 무효화(Invalidate Caches)' 기능을 통해 IDE의 라이브러리 인식 오류 해결.

[결과 및 배운 점]
외부 라이브러리를 쓸 때는 해당 라이브러리의 패키지 구조와 스프링 부트 버전에 따른 자동 등록 여부를 먼저 체크해야 한다는 점을 배움.

RestTemplate방식으로 도전하였으나, 역시...RestClient가 더 간결하니,,, 수정해야겠다... 쓸데없는.. 도전..



2. 트러블슈팅: 결제 검증 보상 트랜잭션 설계 및 하드코딩 리팩토링
[문제 상황]
외부 API 호출 URL과 API 키가 소스 코드에 직접 노출되어 보안 및 유지보수에 취약한 구조였음.
결제 검증 성공 후 서버 내부 로직(포인트, 멤버십) 실패 시, 실제 결제만 완료되고 서비스 처리는 안 되는 데이터 불일치 위험 존재.

[원인 분석]
보안 취약: API Secret 등 민감 정보가 Git에 노출될 경우 위변조 및 금전적 피해 발생 가능.
분산 시스템의 한계: DB 트랜잭션과 외부 API 호출은 하나의 트랜잭션으로 묶이지 않음.

[해결 과정]
환경 변수 분리: application.yml에 base-url, api-key 등을 정의하고 @Value 어노테이션을 통해 코드에 주입.
보상 트랜잭션 구현: PaymentService에서 try-catch를 활용, 내부 로직 실패 시 PortOneClient.cancel()을 호출하여 외부 결제를 취소하는 로직 반영.
Custom Exception 도입: PaymentAmountMismatchException 등을 생성하여 금액 위변조 시 즉각 대응

[결과 및 배운 점]
보안 정보는 반드시 외부 설정 파일(yml)로 관리해야 하며, 외부 API 연동 시에는 항상 실패했을 때를 대비한 보상 로직이 필수라는 점을 깨달음.

 

3. 트러블슈팅: 깃관련 공유시 팀원별 오류가 발생

[문제상황]

결제 기능 개발 중, main 브랜치의 대규모 패키지 리팩토링 사항을 반영하기 위해 병합(merge) 시도.

error: Your local changes... would be overwritten by merge: 로컬의 .gradle 캐시 파일들이 main 브랜치 내용과 충돌하여 병합 거부.

CONFLICT (modify/delete): stash pop 시 main에서 삭제된 파일과 로컬에서 수정된 파일 간의 충돌 발생.

fatal: Exiting because of an unresolved conflict: 충돌 상태가 해결되지 않아 추가 작업이 차단됨.

 

[원인 분석]

관리 대상 설정 오류: 빌드 시마다 변경되는 .gradle 폴더 내 바이너리 파일(fileHashes.bin 등)이 Git 관리 대상에 포함되어 브랜치 간 히스토리 불일치 유발.

패키지 리팩토링 영향: main 브랜치에서 진행된 도메인 기반 패키지 이동(User 도메인 분리)으로 인해 대량의 파일 경로가 변경되며 병합 복잡도 상승.

 

[해결 과정]

상태 보호 (Stashing): 현재 작업 중인 PaymentService 등의 로직을 git stash로 임시 보관하여 병합 시 데이터 유실 방지.

전략적 병합 (Merging): git merge origin/main을 시도하고, 발생하는 충돌 중 소스 코드가 아닌 캐시 파일들은 과감히 삭제(git rm)하여 충돌 해소.

충돌 해결 확정: git add/rm 후 git commit을 통해 병합 상태를 공식적으로 종료.

로직 복구 및 동기화: git stash pop을 실행하여 보관했던 결제 로직을 불러오고, 변경된 패키지 구조(domain/user)에 맞춰 최종 정렬.

 

[결과 및 배운 점]

결과: 리팩토링된 최신 도메인 구조 위에서 결제 기능 개발 환경 완벽 구축.

배운 점:

.gitignore 관리의 중요성: 빌드 유발 파일은 프로젝트 초기에 확실히 제외해야 협업 생산성이 올라감을 체감.

Stash & Pop 전략: 복잡한 병합 상황에서 현재 작업물을 안전하게 보호하는 가장 강력한 수단임을 재확인.

Conflict를 대하는 자세: 충돌은 에러가 아니라 '의견 조율'의 과정이며, 특히 설정 파일 충돌 시에는 비즈니스 로직에 미치는 영향을 최우선으로 고려해야 함.

 

결론... 그냥 처음부터 깃전략 세울때 했음 아무 문제 없었으나, 깃문제로 1시간 정도 허비...ㅠㅠ

'spring_2기[본캠프] > 과제' 카테고리의 다른 글

[과제] Standard Spring Task 4  (0) 2026.02.10
[과제] 결제 시스템 Day5  (0) 2026.02.10
[과제] 결제 시스템 Day3  (0) 2026.02.06
[과제] Standard Spring Task 3  (0) 2026.02.06
[과제] 결제 시스템 Day2  (0) 2026.02.05