테마 전환

1인 기업 결제 시스템: Stripe, Paddle, Lemon Squeezy, WeChat Pay 비교

Easton editorial illustration: one dominant circular payment-routing switch with four selectable rails, one downstream stacked entitlement ledger/database receiving the verified flow

"Paddle: webhook으로 접근 권한과 구독 상태 처리"

주의: 이 글은 세무, 법률, 법인 설립, 외환, 자격에 관한 조언이 아닙니다. Merchant of Record, VAT/GST/sales tax, 국내외 법인, 정산 경로는 서비스 약관과 전문가 의견을 확인합니다.

pricing.ts에는 starter_monthly, pro_yearly, lifetime_license, wechat_one_time이 있지만 데이터베이스에는 is_paid만 있습니다. checkout.session.completed webhook이 오고 사용자가 success_url로 돌아와도 entitlements는 비어 있습니다. 결제 버튼 문제가 아니라 제품, 주문, 구독, 접근 권한이 연결되지 않은 것입니다.

공급자를 고르기 전에 무엇을 파는지, 어떻게 과금하는지, 누구에게 파는지, 거래와 판매세 책임이 누구에게 있는지, 결제 후 누가 권한을 부여하는지 답해야 합니다. 네 서비스는 같은 계층의 버튼이 아닙니다.

결제 서비스보다 판매 모델을 먼저 정하기

일회성 구매는 주문과 전달, SaaS 구독은 전체 billing lifecycle, 사용량 과금은 추적 가능한 usage 데이터가 중요합니다. 먼저 products, prices, 로컬 테이블에 모델을 반영합니다.

판매 모델검토할 시작점핵심 비동기 이벤트로컬 핵심 테이블
일회성 디지털 상품Stripe / Paddle / Lemon Squeezycheckout.session.completed / transaction.completed / order_createdorders + entitlements
SaaS 구독Stripe Billing / Paddle Billing / Lemon Squeezycustomer.subscription.* / subscription.*subscriptions + entitlements + 필요 시 usage_events
구독과 일회성 혼합Stripe Billing / Paddle Billing여러 이벤트orders + subscriptions + entitlements
중국 본토 또는 WeChatWeChat Pay (JSAPI/H5/Native)결제 callback과 주문 조회orders + wechat_prepay

세 가지를 기억합니다.

  • 일회성 상품은 주문, 전달, 환불, 재전송이 중심이며 전체 구독 주기는 필요 없습니다.
  • SaaS 구독은 current_period_start/end, cancel_at, status를 가진 subscriptions가 필요하고 사용량 과금은 감사 가능한 usage_events를 추가합니다.
  • WeChat Pay는 결제 수단과 판매자 시스템이지 글로벌 Merchant of Record나 SaaS billing 플랫폼이 아닙니다.

기능은 바뀔 수 있으므로 구현 전에 계정 지역, 제품 모드, 결제 수단, API 버전, 약관을 확인합니다.

Merchant of Record가 모든 책임을 없애지는 않는다

Merchant of Record, 즉 MoR은 거래상 기록된 판매자입니다. Paddle과 Lemon Squeezy는 허용된 디지털 상품의 MoR로 범위 내 결제, 판매세, 환불, 분쟁을 처리합니다. 글로벌 판매세와 청구 운영은 줄지만 소득세, 법인, 제품 compliance, 데이터 보호, 회계 책임까지 없어지지는 않습니다.

Stripe 경로에서는 보통 판매자가 기록상 판매자입니다. Stripe Tax는 sales tax, VAT, GST 계산과 임계값 모니터링, 등록 관련 절차를 돕지만 Stripe를 자동으로 MoR로 만들지는 않습니다.

고정 매출 기준 대신 다음을 비교합니다.

차원자체 결제·billing stackMerchant of Record
맞춤성Checkout, Billing, Tax, 송장, 내부 절차 조합플랫폼 상품 정책, checkout, 계약, 정산 규칙 준수
세무·청구 운영판매자가 등록, 신고, 송장, 환불, 분쟁을 확인MoR이 범위 내 판매세, 결제, 일부 compliance 담당
비용결제 수수료 외 세무 도구, 개발, 재무, 지원 포함비율뿐 아니라 정산, 환불, 부가비용, 제한 비교
적합 상황강한 맞춤성, 기존 운영 조직, 특수 계약허용 상품의 글로벌 판매세와 구독 운영 부담 감소

정확한 계약과 세무 경계는 법인, 지역, 상품, 고객에 따라 달라집니다. 마케팅 페이지는 약관이나 전문 조언을 대신하지 않습니다.

Stripe, Paddle, Lemon Squeezy, WeChat Pay 선택하기

구독과 WeChat Pay가 모두 필요하면 문제를 나눕니다. 구독 주기, 글로벌 결제, 중국 결제를 같은 공급자가 처리할 필요는 없습니다. 결제 수단이 목록에 있어도 모든 지역, Checkout 모드, 반복 결제에서 되는 것은 아닙니다.

서비스책임 모델구독과 일회성 구매중국 결제기본 라이선스적합한 시작점
StripePayment, Billing, Tax 도구, 보통 MoR 아님높은 맞춤성의 Checkout과 BillingAlipay/WeChat Pay는 지역·통화·모드 의존일반 License Key 없음결제, 구독, 세무 도구, 내부 절차를 통제하는 SaaS
PaddleMerchant of RecordPaddle Billing과 CheckoutDashboard와 최신 문서에서 조건 확인앱이 권한 관리글로벌 판매세와 구독 운영을 줄이는 소프트웨어
Lemon SqueezyMerchant of Record디지털 상품, 단순 구독, 사용량 과금일회성 Alipay/WeChat Pay, 구독은 제한License Keys디지털 상품, 라이선스, 초기 구독
WeChat Pay결제 수단과 판매자 시스템JSAPI/H5/Native, billing은 직접중국 본토와 WeChat없음RMB 일회성 구매와 WeChat 결제

2026년 7월 18일 공식 문서에서 다음을 확인했습니다.

  • Stripe Checkout은 호스팅, 임베드, 조합형 컴포넌트를 제공하며 수단은 지역, 통화, 모드에 따라 달라집니다.
  • Paddle webhook은 at-least-once delivery입니다. 5초 안에 200이 없으면 재시도하며 중복과 역순이 가능하므로 event_id와 occurred_at을 사용합니다.
  • Lemon Squeezy는 Cards, PayPal, Apple Pay, Google Pay, Alipay, WeChat Pay, Cash App Pay, bank debits를 나열하지만 구독은 Cards, Apple Pay, Google Pay, PayPal만 지원합니다.
  • WeChat Pay H5는 서버 주문 생성, 결제 callback, 능동 조회가 필요하며 브라우저 복귀만으로 확정하지 않습니다.

수수료, 수단, 정산, 국가, 정책은 바뀝니다. 최종 예산에는 당일 가격과 계약을 확인합니다.

Webhook을 권한 동기화 경계로 사용하기

두 가지 흔한 실패가 있습니다.

  1. checkout.session.completed와 success_url은 처리됐지만 entitlements가 갱신되지 않아 결제 사용자가 접근하지 못합니다.
  2. 같은 이벤트가 webhook_events에 두 번 들어와 handler가 라이선스를 두 번 발행합니다.

HTTP 요청이나 성공 페이지를 최종 사실로 취급해서 생깁니다. 결제 이벤트는 중복, 지연, 역순이 가능하며 조회나 후속 이벤트가 필요한 상태도 있습니다.

Webhook endpoint 설계 원칙

원칙StripePaddleLemon SqueezyWeChat Pay
HTTPS endpoint필수필수필수필수
서명 검증Stripe-SignaturePaddle-SignatureX-SignatureWeChat Pay API v3 서명
멱등 키이벤트 또는 객체 IDevent_id이벤트 유형 + 객체 ID 또는 unique keyout_trade_no와 거래 ID
응답검증·저장 후 빠르게 응답하고 비동기 처리5초 안에 200성공 응답 뒤 비동기 처리현재 API 계약 준수
보상결제·구독 조회엔터티 조회와 reconciliation주문·구독 조회주문 조회, 대사, 수동 복구

운영 원칙은 다음과 같습니다.

  • webhook 또는 callback을 동기화 입구로 쓰며 success_url은 처리 중 상태만 보여 줍니다.
  • 서명을 먼저 검증하고 원본이나 필수 필드를 webhook_events에 저장한 뒤 복잡한 작업은 비동기 job으로 넘깁니다.
  • unique 제약으로 멱등성을 보장하고 event_id, source, occurred_at, processed_at, status, payload_hash를 기록합니다.
  • 역순은 이벤트 시각, 객체 갱신 시각, 상태 버전으로 판단하며 도착 순서만으로 덮어쓰지 않습니다.
  • 정기적으로 reconciliation을 실행하고 조회와 수동 복구 경로를 둡니다.

주문·구독·권한·이벤트 테이블

테이블핵심 필드StripePaddleLemon Squeezy
ordersprovider_order_id, customer_id, amount, currency, status, created_atCheckout Session / PaymentIntenttransactionorder
subscriptionsprovider_subscription_id, customer_id, status, current_period_end, cancel_atsubscriptionsubscriptionsubscription
entitlementsuser_id, product_id, feature_key, source, status, expires_atorder 또는 subscription에서 파생transaction 또는 subscription에서 파생order, subscription, license에서 파생
webhook_eventsprovider, event_id, occurred_at, processed_at, status, payload_hash멱등성과 감사멱등성과 순서멱등성과 감사

한 공급자의 API 객체를 모두 복제하지 않습니다. 접근 판단에 필요한 안정 필드를 먼저 정하고 조회와 reconciliation용 객체 ID를 저장합니다.

권한 동기화 전략

전략사용 상황구현 요점
Lean cache대부분의 구독 SaaS필요한 customer, subscription, status, price, product만 저장하고 이벤트로 갱신
State mirror오프라인 청구 화면이나 복잡한 운영더 많은 데이터를 복제하고 갱신 시각과 reconciliation으로 차이 방지
License key일회성 디지털 상품이나 데스크톱활성화 후 instance ID를 저장하고 store, product, variant, customer를 검증하며 키를 사용자 시스템으로 취급하지 않음

Paddle은 대부분의 앱에 lean cache를 권장합니다. 풍부한 로컬 조회가 필요할 때만 state mirror를 씁니다. Lemon Squeezy 키도 앱에서 제품과 고객을 검증하고 instance를 계정과 기기에 매핑해야 합니다.

서비스별 통합 요점

아래는 첫 구현 범위이며 전체 문서를 대신하지 않습니다.

Stripe 통합 요점

초기 SaaS는 카드 폼을 직접 관리하기보다 호스팅 Checkout과 Customer Portal로 시작할 수 있습니다. Stripe Billing은 구독, 송장, 사용량 과금, 수익 회복을 다루며 Stripe Tax는 세무 도구이지 MoR은 아닙니다.

product_id는 상품이나 권한 패키지, price_id는 월간, 연간, seat, usage 모델로 로컬 권한에 매핑합니다. users.is_paid 하나만 두지 않습니다.

Next.js 장바구니와 Stripe 결제 튜토리얼에서 Checkout Session, webhook endpoint, 주문 처리를 볼 수 있습니다.

Paddle 통합 요점

Paddle Classic이 아니라 Paddle Billing 문서인지 확인합니다. API, webhook, Paddle.js, Product/Price 모델이 다릅니다.

Paddle Checkout은 결제 화면을 제공하지만 provisioning은 앱 책임입니다. 보통 customer, subscription, status, price, product, scheduled change면 충분하며 완전한 데이터가 필요할 때만 state mirror를 만듭니다.

webhook으로 갱신하고 reconciliation을 실행합니다. MoR이 앱 권한을 자동으로 알지는 못합니다.

Lemon Squeezy 통합 요점

Lemon Squeezy는 초기 디지털 상품, 라이선스, 단순 구독에 적합하며 MoR, checkout, subscriptions, usage-based billing, webhooks, License Keys를 제공합니다. 비용과 범위는 현재 store plan을 확인합니다.

활성화 후 instance ID를 저장하고 store_id, product_id, variant_id, customer를 검증합니다. 다른 상품 키나 재판매 키가 Pro를 열면 안 됩니다.

WeChat Pay 구독은 반복 결제 수단을 별도로 확인합니다. 현재 WeChat Pay와 Alipay를 나열하지만 구독은 Cards, Apple Pay, Google Pay, PayPal만 됩니다.

WeChat Pay의 경계

WeChat Pay는 중국 본토와 WeChat 결제에 맞지만 글로벌 MoR이나 완전한 SaaS billing lifecycle은 아닙니다. 판매자는 주문 상태, callback 서명, 조회, 환불, reconciliation, 송장, 권한을 관리합니다.

H5, JSAPI, Mini Program, Native는 결제 시나리오입니다. H5에서 backend가 주문을 만들고 h5_url을 전달하며, 브라우저 복귀 후에도 조회하고 callback을 같은 out_trade_no에 반영합니다.

제품 권한, 판매자 법인, 도메인, 수수료, API 매개변수는 현재 WeChat Pay 문서를 확인합니다.

다음 단계: 결제 버튼을 테스트 가능한 상태 머신으로 만들기

선택 후 통합을 검증 가능한 작업으로 나눕니다.

  1. orders, subscriptions, entitlements, webhook_events를 만들고 사용량 과금이면 usage_events를 추가합니다.
  2. 각 webhook과 callback에 서명, 멱등성, 역순 처리, 빠른 응답, 실패 복구를 구현합니다.
  3. 성공 페이지가 is_paid=true를 쓰지 않고 로컬 주문 상태를 조회하게 합니다.
  4. 조회, reconciliation, 환불, 갱신 실패, 수동 복구 테스트를 추가합니다.
  5. sandbox에서 이벤트를 재전송하고 역순으로 보내도 권한이 중복 부여되거나 잘못 되돌아가지 않는지 확인합니다.

backend와 데이터베이스는 Supabase Edge Functions 실전 및 이 시리즈의 관련 글로 이어집니다. 결제 페이지 복귀가 아니라 중복, 지연, 역순, 환불에도 주문·구독·권한이 올바른 상태로 수렴해야 완료입니다.

1인 기업 결제 시스템을 선택하고 구현하는 절차

판매 모델, 책임 경계, 대상 시장에서 시작해 공급자를 고르고 감사 가능한 권한 동기화 경로를 만듭니다.

⏱️ Estimated time: 45 min

  1. 1

    Step 1: 판매 모델 정의

    일회성 구매, SaaS 구독, 사용량 과금, 혼합 모델을 정하고 환불, 갱신, 업그레이드, 다운그레이드, 접근 종료 규칙을 기록합니다.
  2. 2

    Step 2: 세무와 운영 책임 분리

    결제, billing, Tax 도구를 직접 조합할지 Merchant of Record를 쓸지 결정하고 법인과 세무 책임은 약관과 전문가 의견으로 확인합니다.
  3. 3

    Step 3: 시장별 결제 수단 선택

    글로벌 카드와 구독에는 Stripe, Paddle, Lemon Squeezy를, 중국 본토나 WeChat의 일회성 구매에는 WeChat Pay를 검토하며 계정 지역, 품목, 지원 조건을 확인합니다.
  4. 4

    Step 4: 로컬 상태 모델 생성

    orders, subscriptions, entitlements, webhook_events를 만들고 공급자 이벤트 또는 주문 ID에 unique 제약을 둬 멱등성과 감사를 보장합니다.
  5. 5

    Step 5: 비동기 권한 동기화 검증

    서명, 중복, 역순, timeout, 환불, 갱신 실패, 수동 복구를 테스트합니다. 성공 페이지는 처리 상태만 보여 줍니다.

FAQ

Stripe, Paddle, Lemon Squeezy의 핵심 차이는 무엇인가요?
Stripe는 결제, Billing, Tax 도구를 제공하고 판매·세무·운영 책임은 보통 판매자에게 남습니다. Paddle과 Lemon Squeezy는 범위 내 거래의 Merchant of Record로 결제, 판매세, 일부 compliance를 담당합니다. 앱 권한 동기화는 여전히 직접 구현합니다.
초기 1인 기업은 Merchant of Record와 Stripe 중 무엇을 선택해야 하나요?
하나의 매출 기준으로 결정하지 않습니다. 시장, 제품 허용 범위, 세무와 청구 운영 역량, 정산, 환불, 맞춤성, 총비용을 비교하고 법인과 세무는 전문가에게 확인합니다.
Paddle이나 Lemon Squeezy가 SaaS 권한을 자동으로 열어 주나요?
아닙니다. 결제, billing, Merchant of Record 업무는 처리하지만 앱이 webhook을 받아 주문이나 구독을 로컬 entitlements에 연결하고 누락을 reconciliation으로 복구해야 합니다.
Lemon Squeezy가 WeChat Pay를 지원하면 구독에도 쓸 수 있나요?
그렇지 않습니다. 현재 WeChat Pay와 Alipay를 나열하지만 구독 상품은 Cards, Apple Pay, Google Pay, PayPal만 지원합니다. 출시 전에 최신 문서를 확인합니다.
WeChat Pay가 글로벌 SaaS의 Stripe를 대체할 수 있나요?
직접 대체할 수 없습니다. 중국 본토와 WeChat용 결제 수단이므로 글로벌 구독, 판매세, billing lifecycle, 다중 통화는 별도로 설계해야 합니다.
중복되거나 역순이거나 누락된 webhook은 어떻게 처리하나요?
서명을 검증해 원본을 저장하고 이벤트나 주문 ID에 unique 제약을 둡니다. 이벤트 시각이나 상태 버전으로 순서를 판단하고 빠르게 응답한 뒤 비동기 처리하며 조회, reconciliation, 수동 복구로 보완합니다.
최소 결제 시스템에는 어떤 테이블이 필요한가요?
최소 orders, entitlements, webhook_events가 필요합니다. 구독은 subscriptions, 사용량 과금은 추적 가능한 usage_events를 추가합니다.

3분 읽기 · 게시일: 2026년 10월 21일

댓글

GitHub로 로그인하여 댓글을 남기세요

Easton BlogEaston Blog