포스트맨으로 결제 생성하고 test.html 수정하는 번거로움을 없애기 위해 브라우저 URL 입력만으로 토스 결제창이 자동으로 뜨는 API를 만들었다.
1. 기존 테스트 방식의 번거로움
1. 포스트맨으로 POST /internal/v1/payments 호출
2. 응답에서 orderId 복사
3. test.html 열어서 orderId 수정
4. 브라우저에서 test.html 열기
5. 결제하기 버튼 클릭
매번 orderId를 복사해서 test.html을 수정하는 게 번거로웠다.
2. 해결 방법
백엔드 API가 HTML을 직접 반환하면 브라우저가 그걸 렌더링해서 토스 결제창을 자동으로 띄울 수 있다.
브라우저 주소창에 URL 입력
→ 결제 생성 (orderId 자동 생성)
→ HTML 응답 (토스 결제창 자동 실행)
→ 끝!
3. 왜 Spring이 브라우저를 직접 열 수 없어?
Spring 백엔드는 이것만 할 수 있다.
요청 받기 → 로직 처리 → 응답 반환 (JSON, HTML, Redirect 등)
브라우저를 직접 열거나 조작하는 건 불가능하다. 브라우저가 HTML 응답을 받아서 렌더링하는 거다. 토스 결제창은 JavaScript로만 띄울 수 있어서 HTML을 반환하는 방식을 선택했다.
4. 구현
PaymentInternalController에 GET /payment-page 엔드포인트를 추가했다.
@GetMapping("/payment-page")
public ResponseEntity getPaymentPage(
@RequestParam UUID bookingId,
@RequestParam UUID userId,
@Positive @RequestParam Integer amount) {
PaymentResult result = paymentCommandService.createPayment(
new CreatePaymentCommand(bookingId, userId, amount)
);
String html = """
const tossPayments = TossPayments("test_ck_QbgMGZzorzmyQnGjmOXkVl5E1em4");
tossPayments.requestPayment("카드", {
amount: %d,
orderId: "%s",
orderName: "First Ticket 예매",
customerName: "김토스",
successUrl: "http://localhost:8085/api/v1/payments/confirm-redirect",
failUrl: "http://localhost:8085/fail"
});
""".formatted(result.amount(), result.orderId()); return ResponseEntity.ok() .contentType(MediaType.TEXT_HTML) .body(html); }
@Positive로 amount 양수 검증을 추가했다.
5. 사용 방법
브라우저 주소창에 입력하면 끝이다!
http://localhost:8085/internal/v1/payments/payment-page?bookingId=ff1e8400-e29b-41d4-a716-446655440001&userId=aa1e8400-e29b-41d4-a716-446655440002&amount=50000
⚠️ bookingId는 매번 다른 UUID 사용 (unique 제약 때문에 중복 불가)
6. 두 가지 테스트 방법
방법 1 - 포스트맨 (기존)
POST /internal/v1/payments → orderId 받음 → test.html 수정 → 결제
방법 2 - 브라우저 URL (신규)
GET /internal/v1/payments/payment-page?bookingId=xxx&userId=xxx&amount=xxx → 끝!
7. Booking 서비스 연동 후 변경 계획
Booking 서비스가 완성되면 결제 생성은 Booking이 담당한다.
// 변경 전 (현재)
@GetMapping("/payment-page")
public ResponseEntity<String> getPaymentPage(
@RequestParam UUID bookingId,
@RequestParam UUID userId,
@RequestParam Integer amount) {
PaymentResult result = paymentCommandService.createPayment(...); // 제거 예정
...
}
// 변경 후 (Booking 연동 후)
@GetMapping("/payment-page")
public ResponseEntity<String> getPaymentPage(
@RequestParam String orderId,
@RequestParam Integer amount) {
// Booking이 생성한 orderId로 바로 결제창 실행
...
}
포스트맨 → Booking 예매 확정 API → orderId 응답
브라우저 → GET /internal/v1/payments/payment-page?orderId=xxx&amount=xxx
파라미터만 바꾸면 돼서 수정이 간단하다.
마무리
백엔드가 HTML을 반환하면 브라우저가 렌더링해서 JavaScript를 실행한다는 점을 활용했다.
프론트 없는 백엔드 개발 환경에서 테스트 편의성을 크게 높일 수 있었다.
'Spring 개발일지' 카테고리의 다른 글
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 전체 레이어 테스트 코드 작성 (0) | 2026.05.19 |
|---|---|
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - MSA 서비스 간 통신 정리 (0) | 2026.05.18 |
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 전체 결제 목록 조회 API (ADMIN) (0) | 2026.05.13 |
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - AuthContext 적용 및 공통 모듈 업데이트 (0) | 2026.05.12 |
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - X-User-Id 헤더 기반 사용자 인증 적용 (0) | 2026.05.11 |