Skip to content

English {#english}

Scope: m.pregoi.com (apps/admin-web) Payment step — ensure Pay opens Stripe Checkout; never advance to the next wizard step without a checkout URL when payment is required.

Canonical code: apps/admin-web/lib/api.ts (createCheckoutSession), apps/admin-web/app/page.tsx (Payment step === 3).

Related plans: Plan B — funnel observability · Plan C — logpath · Plan D — Activate · Onboarding, provisioning, logpath, admin console


한국어 {#korean}

1. 배경·증상

  • 증상: Pay 클릭 시 Stripe 없이 다음 단계(회사 정보)로 이동한다.
  • 코드 메커니즘: createCheckoutSessionNEXT_PUBLIC_PREGO_CONTROL_PLANE_URL(base)이 비어 있으면 POST /v1/checkout을 호출하지 않고 { url: undefined }를 반환한다(error 없음). UI는 res.url이 없으면 goToStep(4)를 실행해 실패가 사용자에게 보이지 않는다.

2. 목표·비목표

  • 목표: 유료 플랜에서 Pay → Stripe Hosted Checkout → 결제 완료 후 success_url 복귀 → 이후 단계. 실패 시 같은 스텝 유지 + 명시적 오류.
  • 비목표: Stripe Elements 인앱 카드 폼(별도 과제).

3. 설정 매트릭스 (배포 전 필수)

항목위치검증 방법
NEXT_PUBLIC_PREGO_CONTROL_PLANE_URLadmin-web Worker 빌드/Variables프로덕션에서 값 공백 아님
POST /v1/checkoutprego-control-plane200 + JSON url
Stripe 키·Price IDCP 시크릿테스트/라이브 모드 일관성
Stripe 웹훅Stripe Dashboardcheckout.session.completed
CORSCPm.pregoi.com Origin 허용

갭: app/api/public-config/route.tsNEXT_PUBLIC_PREGO_AUTH_URL만 런타임 노출. Control Plane base는 빌드 타임에만 주입되면 빈 빌드 시 결제 불가. 결정 필요: CP base를 public-config로 런타임 노출할지, Worker Variable 필수만 할지.

4. UI/UX 요구

상태동작
클릭 직후Pay 버튼 disabled + 스피너 또는 “Redirecting…”
res.url 존재window.location.assign(res.url)
res.error 또는 !res.url스텝 유지, 인라인/토스트 오류(개발 환경에서만 CP URL 누락 힌트 가능)
네트워크 예외동일, 재시도 버튼 권장

5. 테스트 시트 (수동)

#시나리오기대
T1base 설정됨, CP 정상Stripe 페이지
T2base 빈 값Pay 후 스텝 3 유지 + 오류
T3CP 500/4xx오류 표시, 스텝 3 유지
T4결제 완료?checkout=success, 스텝 4
T5결제 취소cancel_url 정책에 맞는 스텝

6. 구현 페이즈 (코드는 별도 작업)

  1. P0: 운영 Variables 점검·문서화.
  2. P1: res.url 없을 때 goToStep(4) 제거, 로딩·에러 표시.
  3. P2(선택): public-config에 CP base 노출 검토.
  4. P3: Plan C 연계 — checkout 요청에 x-trace-id, Stripe metadata.

7. 완료 정의 (DoD)

  • 스테이징·프로덕션에서 T1·T4 통과.
  • T2에서 절대 자동으로 회사정보 스텝으로 넘어가지 않음.
Help