구독·결제 관리 대시보드 + npm에 배포한 결제 위젯 라이브러리. 토스페이먼츠 실연동과 모듈 라이브러리화(npm publish · yalc)를 한 저장소에서 증명하는 풀스택 포트폴리오.
- npm 패키지: https://www.npmjs.com/package/@kimnioyh/react-payment-widget
- GitHub: https://github.com/kimnioyh/subpay
- 라이브 데모: (배포 후 추가)
- 핀테크(결제) 실무 — 토스페이먼츠 테스트 결제 → 서버 승인(confirm) 2단계 처리(금액 위변조 검증·멱등).
- 라이브러리 저자 경험 — 결제 위젯을 별도 npm 패키지로 추출·배포하고 앱이 소비.
tsup번들·타입 배포·yalc로컬 링크.
- 구독 CRUD — 등록/수정/해지(soft delete), RHF + zod 검증.
- 결제 흐름 — 라이브러리로 토스 결제창 호출 → 서버가 주문(PENDING) 선생성 → 승인(confirm) →
DONE저장. - 대시보드 — 월 예상 지출·활성 구독·이번달 결제 요약 + 구독별 지출 차트(Recharts).
- 품질 — 라이브러리 유닛(Vitest+RTL) · 앱 E2E(Playwright) · strict 타입 0 · 접근성(aria-label·차트 대체 테이블).
subpay/
├─ apps/dashboard/ Next.js 16 · React 19 · TS strict · Tailwind
│ ├─ app/ App Router + Route Handlers
│ ├─ lib/prisma.ts Prisma 7 (better-sqlite3 driver adapter)
│ └─ prisma/schema.prisma Subscription / Payment 모델
├─ packages/react-payment-widget/ npm 배포 라이브러리 (@kimnioyh/react-payment-widget)
│ └─ src/ usePayment 훅 + <PaymentButton> (토스 SDK v2 래핑), tsup 빌드
└─ sandbox/ 위젯 로컬(yalc) vs 배포(npm) 좌우 비교 (토스 SDK mock)
| 영역 | 선택 | 이유 |
|---|---|---|
| 모노레포 | pnpm workspace | 라이브러리+앱 한 저장소, 로컬 링크 |
| 번들러(lib) | tsup (rollup+esbuild) | ESM/CJS + d.ts 자동, 설정 최소 |
| 앱 | Next.js 16 (App Router) + TS strict | 국내 FE 표준 |
| 서버 상태 | TanStack Query | 데이터페칭 선언적 표준 |
| 폼 | react-hook-form + zod | 런타임 검증 = 신뢰 경계 |
| 결제 | 토스페이먼츠(테스트) | 도메인 차별화 |
| DB | Prisma 7 + SQLite | 풀스택-라이트 |
| 차트 | Recharts | 대시보드 |
| 테스트 | Vitest+RTL / Playwright | 유닛 + E2E |
[구독 목록] 결제 클릭
└─ POST /api/payments 서버가 amount 확정 + orderId(멱등키) 발급 + PENDING 저장
└─ 토스 결제창(usePayment)
└─ 성공 리다이렉트 → confirmPayment (서버)
· PENDING 조회(orderId) · 이미 DONE이면 그대로(멱등)
· 금액 대조(위변조 검증) · 토스 confirm(secretKey) · DONE 기록
포인트: secretKey는 서버 전용, 금액은 서버가 확정 후 대조, orderId 유니크로 이중 결제 차단.
pnpm install
# 1) 라이브러리 빌드 (앱이 workspace로 소비)
pnpm --filter @kimnioyh/react-payment-widget build
# 2) 앱 환경변수: 토스 테스트 키 + DB 경로
cd apps/dashboard
cp .env.example .env # NEXT_PUBLIC_TOSS_CLIENT_KEY / TOSS_SECRET_KEY 채우기
npx prisma db push # SQLite 스키마 반영
# 3) 실행
pnpm dev # http://localhost:3000pnpm test # 라이브러리 유닛 (Vitest)
pnpm e2e # 앱 E2E (Playwright — 최초 1회 `npx playwright install` 필요)
pnpm build # 전체 strict 빌드cd sandbox && npm install && npm run dev # 좌: yalc 로컬빌드 / 우: npm 배포판- 라이브러리 사용법·API:
packages/react-payment-widget/README.md - 위젯 비교 샌드박스:
sandbox/README.md
김효인 · FE 포트폴리오