첫 구독을 연결하세요.
프로젝트를 만들고, 서버에 SDK를 설치하고, 모의 결제로 동작을 확인합니다.
1. 프로젝트와 API 키 만들기
아래 첫 연동 예제는 모의 결제 프로젝트를 기준으로 합니다. 토스 연결을 시험하려면 별도의 토스 테스트 프로젝트를 만들고, 프로젝트 화면의 토스페이먼츠 연결에 본인 상점의 테스트 키를 등록하세요. 카드 등록·구독·환불은 해당 프로젝트 콘솔에서 확인할 수 있습니다. 실운영은 별도 프로젝트를 만들고 본인 상점의 실운영 키와 실결제 연결 조건 동의를 등록합니다.
콘솔에서 가입·이메일 확인 후 프로젝트를 만드세요. 프로젝트의 API 주소를 복사하고 ‘API 키 관리’에서 서버용 키를 발급합니다. 키 원문은 한 번만 표시됩니다.
프로젝트별로 고객, 요금제, 결제 기록과 키가 분리됩니다. 계정당 프로젝트 3개, 프로젝트당 사용 중인 키 5개까지 만들 수 있습니다.
2. 서비스 서버에 설치하기
JavaScript · TypeScript
Node.js 24 이상이 필요합니다.
npm install axletPython
Python 3.10 이상이 필요합니다.
pip install axlet프로젝트 화면에서 확인한 값을 서비스 서버의 환경 변수로 설정하세요.
AXLET_API_URL=프로젝트_화면의_API_주소
AXLET_API_KEY=발급받은_프로젝트_키키를 브라우저 코드, 공개 저장소, 로그에 넣지 마세요. 이 키로 해당 프로젝트의 고객·구독·환불을 관리할 수 있습니다. 서비스 회원의 로그인과 본인 확인은 연결하는 서비스에서 처리합니다.
API 연결 확인
환경 변수를 설정한 서비스 서버에서 현재 요금제를 조회합니다. 모의·토스 테스트·실운영 프로젝트 모두 고객 생성이나 결제 없이 확인할 수 있습니다.
JavaScript
import { AxletClient } from 'axlet';
const axlet = new AxletClient({
apiKey: process.env.AXLET_API_KEY,
baseUrl: process.env.AXLET_API_URL,
});
const plans = await axlet.getPlans();
console.log(plans.current);Python
import os
from axlet import AxletClient
axlet = AxletClient(
api_key=os.environ['AXLET_API_KEY'],
base_url=os.environ['AXLET_API_URL'],
)
plans = axlet.get_plans()
print(plans['current'])현재 요금제가 반환되면 API 요청 인증과 조회에 성공한 것입니다. 콘솔에서 선택한 프로젝트의 요금제·기능 목록과 비교하세요. 조회 성공은 토스 상점 연결이나 실제 결제 가능 여부를 확인한 결과가 아닙니다. 오류가 발생하면 연결이 되지 않을 때를 확인하세요.
3. 첫 모의 구독 만들기
회원 ID를 고객의 externalId에 연결합니다. 아래 예시의 고객 등록·결제수단 등록·구독 요청은 각각 다른 요청 키를 사용합니다.
JavaScript
import { AxletClient } from 'axlet';
const axlet = new AxletClient({
apiKey: process.env.AXLET_API_KEY,
baseUrl: process.env.AXLET_API_URL,
});
const customer = await axlet.createCustomer({
name: '예시 고객', email: 'demo@example.com', externalId: 'demo-user-001',
}, { idempotencyKey: 'create-demo-user-001' });
await axlet.registerBilling(customer.id, { idempotencyKey: 'billing-demo-user-001' });
await axlet.subscribe(customer.id, { idempotencyKey: 'subscribe-demo-user-001' });
console.log(await axlet.getCredits(customer.id));
Python
import os
from axlet import AxletClient
axlet = AxletClient(
api_key=os.environ['AXLET_API_KEY'],
base_url=os.environ['AXLET_API_URL'],
)
customer = axlet.create_customer(
{'name': '예시 고객', 'email': 'demo@example.com', 'externalId': 'demo-user-001'},
idempotency_key='create-demo-user-001',
)
axlet.register_billing(customer['id'], idempotency_key='billing-demo-user-001')
axlet.subscribe(customer['id'], idempotency_key='subscribe-demo-user-001')
print(axlet.get_credits(customer['id']))콘솔에서 같은 프로젝트를 열면 SDK로 만든 고객과 구독이 표시됩니다. 모의 환경의 결제수단 등록은 실제 카드 등록 없이 진행됩니다.
고객사 서비스에 토스 카드 구독 연결하기
위 모의 예제와 달리 토스 프로젝트에서는 고객이 결제창에서 카드를 등록한 뒤 서버에서 등록을 완료해야 합니다. 먼저 토스 테스트 프로젝트에서 이 흐름을 확인하세요. 실제 결제를 받으려면 별도 실운영 프로젝트에 고객사 본인 상점의 빌링 계약용 라이브 키를 등록하고, 해당 프로젝트의 서버 API 키를 사용합니다. 모의·테스트 프로젝트의 고객과 결제 기록은 실운영으로 옮기지 않습니다.
1. 고객사 서버에서 카드 등록 시작
로그인한 회원과 연결된 Axlet 고객 ID를 서버에서 결정합니다. 브라우저가 보낸 고객 ID를 그대로 신뢰하지 마세요. 아래 요청의 registrationKey는 등록 시도마다 만든 8~100자 요청 키이며 같은 요청 재시도에는 유지합니다.
const registration = await axlet.registerBilling(customer.id, {
idempotencyKey: registrationKey,
});서버의 인증 세션 또는 DB에 회원 ID·고객 ID·registration.state·registration.customerKey를 연결해 저장하고, 등록 결과만 브라우저에 전달합니다. 프로젝트 API 키와 토스 시크릿 키는 브라우저에 전달하지 않습니다.
2. 고객 브라우저에서 토스 카드 등록창 열기
토스페이먼츠 JavaScript SDK v2(https://js.tosspayments.com/v2/standard)를 불러온 뒤 사용합니다. 아래 복귀 경로는 고객사에서 구현할 경로이며, 카드 등록 버튼을 눌렀을 때 실행합니다.
const successUrl = new URL('/billing/return', location.origin);
successUrl.searchParams.set('state', registration.state);
await TossPayments(registration.clientKey)
.payment({ customerKey: registration.customerKey })
.requestBillingAuth({
method: 'CARD',
successUrl: successUrl.href,
failUrl: new URL('/billing/failure', location.origin).href,
});
3. 고객사 서버에서 등록 완료 후 별도 구독 신청
복귀한 회원이 로그인 상태인지 확인하고, 받은 state와 customerKey가 1단계에서 저장한 값과 모두 일치하는지 검사한 뒤 실행합니다. 성공 URL에 도착한 사실만으로 구독을 활성화하지 않습니다.
await axlet.completeBilling({ state, customerKey, authKey }, {
idempotencyKey: completionKey,
});
// 상품·금액·결제 주기·해지 및 환불 조건에 대한 고객 동의를 확인한 서버에서 실행합니다.
await axlet.subscribe(customer.id, { idempotencyKey: subscriptionKey });completionKey와 subscriptionKey는 서로 다른 요청 키입니다. 응답이 유실돼도 같은 요청 키로 다시 확인하고 새 구독을 만들지 마세요. 카드 등록만으로는 청구되지 않으며, 구독 요청이 첫 결제를 시작합니다. 상품과 크레딧 설정은 고객을 받기 전에 프로젝트 콘솔에서 확정하세요. 이후 갱신은 Axlet의 정기 작업이 처리하므로 고객사에서 별도 월 청구 작업을 중복 실행하지 않습니다.
Python에서는 같은 순서로 register_billing, complete_billing, subscribe를 호출하며 요청 키 인자는 idempotency_key입니다. 인증 값이 포함된 복귀 URL은 처리 후 정리하고 로그·분석 도구에 남기지 마세요. 취소·실패 복귀에서는 구독을 시작하지 않습니다. 토스 공식 카드 등록창 안내
4. 기능 사용 전에 크레딧 차감하기
권한 조회 후 실제 차감이 성공한 것을 확인하고 유료 기능을 실행하세요. 조회와 실행 사이에 잔액이 달라질 수 있으므로 조회만으로 사용을 허용하지 않습니다.
const operationId = 'report-job-0001'; // 응답 유실 재요청에만 유지, 차감 취소 뒤 재실행은 새 ID
const access = await axlet.getAccess(customer.id, 'report');
if (!access.allowed) throw new Error('이용 권한 또는 크레딧이 필요합니다.');
await axlet.consumeUsage(customer.id, { feature: 'report', operationId },
{ idempotencyKey: operationId });
try {
await runReportOnce(operationId); // 서비스에서 작업 중복 실행 방지
} catch (error) {
await axlet.cancelUsage(customer.id, operationId,
{ idempotencyKey: 'cancel-report-job-0001' });
throw error;
}Python에서는 get_access, consume_usage, cancel_usage를 사용합니다. 요청 키와 작업 ID는 영문·숫자·밑줄·하이픈으로 8~100자입니다. 새 작업은 새 ID를, 같은 작업의 재요청은 기존 ID를 사용하세요.
차감을 취소한 작업 ID는 다시 차감할 수 없습니다. 취소한 작업을 다시 실행하려면 새 작업 ID와 새 요청 키로 차감부터 다시 요청하세요. 취소된 작업 ID로 차감을 요청하면 같은 요청 키든 새 요청 키든 409로 거절됩니다.
API 재시도 시 크레딧 중복 차감을 막으려면?
같은 작업을 다시 요청할 때는 operationId와 idempotencyKey를 그대로 사용합니다. 서버에서 요청을 처리했지만 네트워크 오류로 응답을 받지 못했더라도, 같은 요청의 재시도는 저장된 결과를 재사용합니다. 같은 요청 키를 다른 경로나 본문에 재사용하면 409 충돌로 거절됩니다.
예를 들어 보고서 작업 report-job-0001을 재시도할 때는 고객 ID·기능 ID·작업 ID·요청 키를 바꾸지 않습니다. 새 보고서 작업에는 새 ID를 발급합니다. 작업 ID는 같은 프로젝트의 다른 고객이나 기능에서도 겹치지 않게 관리하세요.
Axlet이 중복을 방지하는 범위는 크레딧 원장입니다. 보고서 생성·AI 모델 호출 같은 서비스의 실제 작업도 작업 ID를 기준으로 한 번만 실행되도록 구현해야 합니다. Python에서는 consume_usage의 idempotency_key 인자에 같은 키를 전달합니다.
구독 해지와 전액 환불은 어떻게 다른가요?
- 해지 예약 · 다음 갱신 중단
cancel은 다음 청구를 중단합니다. 이미 활성화된 구독의 현재 이용 기간과 남은 크레딧은 해당 기간이 끝날 때까지 유지됩니다.- 전액 환불 · 현재 구독 종료
refund는 현재 구독의 최신 확정 결제를 대상으로 합니다. 환불이 확인되면 해당 구독을 종료하고 이용 권한과 해당 결제에서 남은 크레딧을 회수합니다. 부분 환불은 지원하지 않습니다.- 사용 취소 · 실패한 작업의 차감 취소
cancelUsage(Python:cancel_usage)는 특정 작업의 크레딧 차감을 취소합니다. 결제 환불과는 다르며, 이미 만료되거나 환불로 닫힌 지급분의 잔액을 다시 살리지 않습니다.
세 동작에는 각각 다른 요청 키를 사용합니다. 모의·토스 테스트 프로젝트에서는 모의 처리 또는 토스 테스트 거래 취소만 수행하며 실제 카드 취소나 송금은 발생하지 않습니다. Axlet 자체의 이용 중단·탈퇴는 무료 베타 취소·환불 안내를 확인하세요.
호출량 기준과 429 응답
현재는 관찰 모드로 기준 초과를 기록하며 요청을 차단하지 않습니다. 적용 예정 기준은 키별 UTC 고정 1분 구간에 일반 요청 600회, 해지·환불·사용 취소·단건 결제 조회·상태 동기화 60회입니다. 두 한도는 별도로 계산합니다. 확정된 시행일은 사이트와 계정 이메일로 30일 이상 먼저 안내하며, 그 전에는 이 기준으로 요청을 거절하지 않습니다.
차단 모드에서 한도를 넘으면 서버는 처리 전에 HTTP 429, Retry-After 헤더와 {"code":"RATE_LIMITED","retryAfter":12} 형태의 대기 시간을 돌려줍니다. 초 단위 대기 시간이 지난 뒤 같은 본문·요청 키로 다시 요청하세요. SDK 오류의 status와 body.retryAfter(Python은 body["retryAfter"])로 확인할 수 있으며 SDK가 자동 재시도하지는 않습니다. 새 주문이나 새 요청 키를 만들어 재시도하지 마세요.
키 관리에서 초과한 UTC 날짜·횟수·최근 시각을 확인할 수 있습니다. 초과 기록은 복제나 약관 위반의 판정이 아닙니다. 정상 연동인데 계속 초과하면 키 원문·고객정보 없이 프로젝트 ID와 발생 시각을 support@axlet.app으로 알려 주세요. 기존 콘솔과 정기 작업은 이 프로젝트 API 키 한도를 적용하지 않아 키 폐기와 환불 지원에 사용할 수 있습니다.
연결이 되지 않을 때
- 401 · 인증 실패
- 서버 환경 변수와 API 주소를 확인하세요. 폐기한 키는 즉시 사용할 수 없습니다.
- 404 · 고객 또는 프로젝트 없음
- 현재 키와 고객 ID가 같은 프로젝트에 속하는지 확인하세요.
- 결과를 받지 못한 변경 요청
- 상태를 먼저 조회하고 같은 본문·요청 키로 재시도하세요. 새로운 주문을 만들어 다시 결제하지 않습니다.
- 발급한 키를 잃어버린 경우
- 키 목록에서 해당 키를 폐기하고 새 키를 발급하세요. 기존 키 원문은 다시 볼 수 없습니다.
베타 이용 범위
무료 베타 동안 Axlet 이용료는 무료입니다. 콘솔의 상품 가격은 모의 구독 예시이며 Axlet 이용료가 아닙니다. 모의·토스 테스트·실운영 프로젝트는 서로 다른 고객과 결제 기록을 사용합니다.
실결제는 판매자가 직접 계약·심사를 마친 토스페이먼츠 상점의 실운영 키로 연결합니다. 상품 대금은 판매자 상점에서 승인·정산되고 PG 수수료는 판매자의 계약을 따르며, Axlet은 대금을 받거나 보관하지 않습니다. 자세한 조건은 실결제 연결 조건을 확인하세요.
기존 단일 상점 SDK와 같은 메서드를 사용합니다. 직접 운영하는 API 서버도 baseUrl로 연결할 수 있습니다. 프로젝트 API의 주소는 웹사이트 주소와 다르므로 콘솔에 표시된 주소를 사용하세요.