피드로 돌아가기
Building a SaaS engine in public: shipping the billing seam, not billing
Dev.toDev.to
Backend

결제 로직 분리를 통한 결제 게이트웨이 추상화 계층(Billing Seam) 설계

Building a SaaS engine in public: shipping the billing seam, not billing

Dmitry Isaenko2026년 6월 4일6intermediate

Context

특정 서비스용으로 개발된 CRM의 하드코딩된 결제 성공 로직이 재사용 가능한 SaaS 코어 라이브러리 전환 시 잠재적 장애 요인으로 작용. 무료 코어의 순수성을 유지하며 유료 결제 기능을 플러그인 형태로 확장할 수 있는 구조적 분리 필요.

Technical Solution

  • PaymentGatewayInterface 도입을 통한 결제 메커니즘의 추상화 및 세부 구현체(Stripe, Paddle 등)의 완전한 분리
  • Null Gateway 패턴 적용으로 실제 결제 드라이버 부재 시 'Silent Success'를 방지하고 즉각적인 예외를 발생시키는 Fail-fast 구조 설계
  • Laravel 스타일의 Driver Manager를 통한 설정 기반의 런타임 게이트웨이 교체 및 확장 가능성 확보
  • 무료 코어 내에 subscription 관련 DB 컬럼을 미리 정의하여 add-on 설치 없이도 상태 기반의 접근 제어(Access Decision) 가능하게 설계
  • Company::hasAccess() 메서드를 통한 RBAC 단계의 stub 제거 및 실제 구독 상태 확인 로직으로의 점진적 전환

- 재사용 가능한 라이브러리 설계 시 하드코딩된 Mock 로직이 실제 운영 환경의 오작동을 유발하는지 검토 - 외부 서비스 의존성이 높은 기능은 Interface를 통해 추상화하고, 기본 구현체로 Null Object 패턴 적용 고려 - Core와 Add-on 간의 경계를 정의할 때, 데이터 스키마는 Core에 두어 상태 추적이 가능하게 하고 비즈니스 로직은 Add-on으로 분리하는 전략 검토

원문 읽기