베타 운영 중·유료 거래는 2026년 12월 17일 정식 오픈 후 시작됩니다. 지금은 상품을 미리 등록하고 둘러보실 수 있습니다.

전달 방식별 연동
따라하기 가이드Pro 플랜부터결제 즉시 자동 발급

구독형 (SaaS) — 처음부터 판매까지

월간·연간으로 정기결제하는 SaaS를 파는 방식입니다. 결제와 갱신, 해지는 새몰이 처리하고 내 서비스는 구독 여부만 확인하면 됩니다.

아래 화면 예시는 실제 새몰 화면과 동일한 구성으로 재현한 것입니다. 내 계정에서는 상품 등록 상품 수정 페이지의 연동 정보 카드에서 같은 화면을 만나게 됩니다.
전달 방식은 여러 개를 고를 수 있습니다. 이 가이드는 구독형 (SaaS) 하나를 기준으로 설명하지만, 다른 방식과 함께 체크해도 됩니다. 방식마다 설정과 발급이 따로 적용됩니다. 세 축(상품 종류·가격 방식·전달 방식)이 어떻게 맞물리는지는 판매 가이드에 정리해 두었습니다.
가격을 매기려면 사업자 인증이 필요합니다. 개인사업자나 법인으로 정산 정보를 등록하고 인증을 마쳐야 유료 요금제를 설정할 수 있습니다. 비사업자는 0원(무료) 상품만 등록됩니다. 인증과 상관없이 연동 자체는 지금 그대로 따라 할 수 있습니다.

한눈에 보기

1구매자새몰구독하기 → 카드 등록 → 매 주기 자동 결제
2새몰구매자구독 권한 자동 발급 (API Key + Subscription License Key)
3새몰판매자entitlement.activated · subscription.renewed/expired 웹훅
4판매자새몰접근 시 구독 확인 (권한 확인 API 또는 새몰 계정 로그인)

결제·갱신·해지·환불 회수는 전부 새몰이 처리합니다. 판매자가 구현할 것은 단 하나 — 내 서비스에 들어온 사용자가 유효한 구독자인지 확인하는 부분입니다.

인증 연동 방식 고르기

구독 확인 방법은 2가지입니다. 두 방식 사이에 추가 플랜 조건은 없습니다 — 구독형 상품을 등록할 수 있는 플랜(Pro 이상)이면 어느 것을 골라도 됩니다. 등록 후 연동 정보 카드에서 필요한 자격증명을 확인합니다.

방식이런 서비스에 맞음판매자가 구현할 것
API Key자체 계정 체계가 이미 있는 서비스, CLI·데스크톱 도구구매자가 받은 키를 입력받아 verifyEntitlement 호출 (아래 4단계)
새몰 계정으로 로그인"새몰 계정으로 로그인" 버튼을 붙이는 웹 서비스SDK SaemolOAuth로 로그인 연동 (아래 5단계)
신원만 받을지, 구독 정보까지 받을지는 등록이 아니라 로그인 버튼을 만들 때 scope로 정합니다identity(로그인만) 또는 entitlement(로그인 + 구독 상태·플랜, 기본값). 같은 상품에서 페이지마다 다르게 요청할 수 있어, 이 때문에 상품을 나눌 필요가 없습니다.

따라하기

1

상품 등록 — 구독형 + 월/년 요금제

가격 방식을 구독형으로 고르면 전달 방식은 구독형(SaaS) 또는 수동 전달만 표시됩니다. 월간 또는 연간 유료 요금제가 최소 1개 필요합니다(정기결제 주기).

saemol.com/products/new

가격 방식 *

구독형

전달 방식 *

구독형 (SaaS)결제와 동시에 구독 권한을 발급합니다. 구독 상태가 바뀌면 웹훅으로 알려드립니다.
수동 전달주문이 들어오면 판매자가 계정이나 링크를 직접 전달합니다.

요금제 * 필수

플랜 이름 *

Pro

가격 (원) *

19,000

주기 *

월간
2

인증 연동 방식 선택

위 표에서 고른 방식을 선택합니다. 새몰 계정으로 로그인을 고르면 동의 후 내 서비스로 복귀할 OAuth Redirect URI가 필수입니다.

saemol.com/products/new

인증 연동 방식 *

새몰 계정으로 로그인 (SSO / OAuth 2.0)

신원만 받을지 구독 정보까지 받을지는 로그인 버튼을 만들 때 코드에서 정합니다 — 등록 시점에 고를 필요가 없습니다

OAuth Redirect URI (선택)

https://app.taskflow.io/auth/saemol/callback

새몰 계정으로 로그인 선택 시 필수 — 동의 후 복귀할 내 서비스 주소. 쉼표로 여러 개 등록, 정확히 일치하는 주소만 허용됩니다

웹훅 URL *

https://api.taskflow.io/webhooks/saemol
3

연동 정보 확인 — 시크릿과 OAuth 클라이언트

등록 직후(심사 전에도) 상품 수정 페이지의 연동 정보 카드에서 자격증명이 발급되어 있습니다.

saemol.com/dashboard/products/…/edit

연동 정보 — 구독형 (SaaS)

연동 시크릿 (API 호출 시 X-Saemol-Secret 헤더)

a3f8c2…e91b

테스트 시크릿 (샌드박스 — 테스트 키 전용)

test_7d21…f04a

OAuth 클라이언트 — Client ID / Client Secret

mfc_92be14… · mfcs_5a77c1…
시크릿은 서버 환경변수로만 보관하세요. 심사 전에는 테스트 키로 결제 없이 전 구간을 검증할 수 있습니다.
4

방식 1 — API Key: 권한 확인 API 호출

구매자에게 자동 발급된 API Key(mfk_…)를 내 서비스에서 입력받아, 로그인·요청 시점에 확인합니다. 자체 계정 체계가 이미 있거나 CLI·데스크톱 도구라면 이 방식이 가장 간단합니다.

saemol.com/orders/… (구매자 화면)

전달 정보

API Key

mfk_5f2a…c81d

구독이 활성화되었습니다. 아래 API Key로 서비스에 인증하거나, 판매자 안내에 따라 계정을 연동하세요.

server.ts — 권한 확인
import { Saemol } from '@saemol/sdk'
const saemol = new Saemol({ secret: process.env.SAEMOL_SECRET! })

const ent = await saemol.verifyEntitlement({ apiKey: userApiKey })

if (!ent.valid) return deny()        // 만료·해지·환불 포함
ent.plan_name                         // 'Pro' — 구매한 플랜
ent.plan_features                     // 플랜별 기능 목록 (상품 설정)
ent.current_period_end                // 이번 구독 주기 종료 시각

응답을 1~5분 캐시하면 요청마다 호출하지 않아도 됩니다. 해지·환불은 웹훅으로도 즉시 통지됩니다.

5

방식 2 — 새몰 계정으로 로그인 (SSO / OAuth 2.0)

내 서비스에 “새몰 계정으로 로그인” 버튼을 붙이는 방식입니다. 구매자는 키 입력 없이 로그인만으로 연동됩니다. 신원만 받을지, 구독 정보까지 받을지는 로그인 버튼의 scope로 정합니다 — 동의 화면에 뜨는 항목도 그에 따라 달라집니다.

…/oauth/authorize?…&scope=identity

TaskFlow

로그인만 (scope: identity)

새몰 계정의 이름·이메일
회원 식별자 (계정 연결용)
buyer@example.com 계정으로 진행합니다.
동의하고 계속하기
거부
…/oauth/authorize?… (scope 생략)

TaskFlow

로그인 + 구독 정보 (scope: entitlement)

새몰 계정의 이름·이메일
이 상품에 대한 구독 상태·플랜 정보
buyer@example.com 계정으로 진행합니다.
동의하고 계속하기
거부
auth.ts — 클라이언트 준비
import { SaemolOAuth } from '@saemol/sdk'

export const oauth = new SaemolOAuth({
  clientId:     process.env.SAEMOL_OAUTH_CLIENT_ID!,
  clientSecret: process.env.SAEMOL_OAUTH_CLIENT_SECRET!,
  redirectUri:  'https://app.taskflow.io/auth/saemol/callback',
})
로그인 버튼 — scope로 무엇을 받을지 정한다
// state(CSRF 토큰)는 SDK가 만들어 돌려줍니다 — 세션에 저장했다가 콜백에서 대조
// scope 생략 = entitlement(로그인 + 구독). 신원만 받으려면 { scope: 'identity' }
const { url, state } = oauth.createAuthorizationUrl()
session.oauthState = state
res.redirect(url)
콜백 — 로그인과 (요청했다면) 구독 확인을 한 번에
import { isSubscriptionActive, hasPlanFeature } from '@saemol/sdk'

// GET /auth/saemol/callback?code=mfoc_…&state=…
// 오류 확인 → state 검증 → 토큰 교환 → userinfo까지 한 번에 처리합니다
const { user, tokens } = await oauth.handleCallback({
  url:           req.url,
  expectedState: session.oauthState,
})

// user → { sub, name, email, entitlement?: { valid, plan_name, plan_features, … } | null }
// scope='identity'로 요청했다면 entitlement는 없습니다 — 신원만 연결하고 끝냅니다.
if (user.entitlement) {
  if (!isSubscriptionActive(user)) return showSubscribePage()
  if (hasPlanFeature(user, 'advanced')) enableAdvancedFeatures()
}

createSession({
  saemolUserId: user.sub,
  plan:         user.entitlement?.plan_name ?? null,
  refreshToken: tokens.refresh_token,   // 갱신용으로 보관
})

액세스 토큰은 1시간, 리프레시 토큰은 30일 유효합니다. 만료되면 oauth.refresh()로 갱신하세요 — 갱신 시 두 토큰이 모두 새로 발급(회전)되므로 새 리프레시 토큰을 반드시 저장해야 합니다. 이전 값은 즉시 무효가 됩니다.

토큰 갱신 — 만료 시 자동 복구
import { SaemolOAuthError } from '@saemol/sdk'

try {
  user = await oauth.getUserInfo({ accessToken })
} catch (err) {
  if (err instanceof SaemolOAuthError && err.code === 'invalid_token') {
    const tokens = await oauth.refresh({ refreshToken })
    await saveTokens(tokens)          // refresh_token이 회전됨 — 새 값 저장 필수
    user = await oauth.getUserInfo({ accessToken: tokens.access_token })
  } else {
    throw err
  }
}
구매자가 동의 화면에서 거부하면 handleCallback SaemolOAuthError(code: 'access_denied')를 던집니다.state가 일치하지 않으면 토큰 교환 전에 state_mismatch로 중단합니다 — 위조된 콜백이 세션을 만들지 못하게 막는 지점입니다.
6

구독 상태 웹훅 수신

갱신·만료·해지는 웹훅으로 통지됩니다. 구독 수명주기 4종은 모두 기본(basic) 이벤트라 SDK 티어와 무관하게 발송됩니다 — Business 전용인 일부 확장 이벤트와 달리 별도 조건이 없습니다.

이벤트시점판매자 처리
subscription.created첫 결제 성공환영 메일·온보딩
subscription.renewed갱신 결제 성공이용 기간 연장 반영
subscription.cancelled해지 예약주기말 종료 예정 안내
subscription.expired구독 종료 확정접근 차단·재구독 유도

서명 검증 방법은 웹훅 가이드 참고. 수신이 없어도 verify·userinfo가 항상 최신 상태를 반환하므로 안전합니다.

출시 전 체크리스트

  • 월간/연간 유료 요금제가 1개 이상 있다 (정기결제 주기)
  • 테스트 키로 verify(또는 새몰 계정 로그인)와 웹훅까지 확인했다 — 개발 단계부터 연동
  • 로그인 방식 사용 시: Redirect URI가 운영 도메인과 정확히 일치한다
  • 해지·환불 시 접근 차단이 동작한다 (verify 재확인 또는 웹훅 처리)

다음으로 볼 문서