문서
API base https://pay.docenty.ai/api · 오류 형식 {error:{code,message,fix,docUrl,retryAfterSec?}}
퀵스타트 A — 코드 없이 결제 링크
- 로그인 (이메일 매직링크) → 핸들 입력 → "결제 링크 만들기" 선택
- 링크 화면에서 소개·후원 앱 확인 → 공개 → https://pay.docenty.ai/u/핸들 공유
- 구매자가 계좌이체 후 "입금했어요" → 판매 화면에서 이용 제공 → Docenty 입금 검증 후 BC 적립
퀵스타트 A′ — 판매자 (코드 없음): 과일·상담 팔기
- 로그인 → 앱(판매 페이지) 하나 → 상품 추가에서 "농수산·과일 단품" 또는 "전문직 상담" 템플릿 선택 (옵션·배송비·재고·환불 문안이 채워집니다)
- 상품 페이지 https://pay.docenty.ai/u/핸들/p/상품id 를 카톡·인스타에 공유 — 구매자는 옵션·수량을 고르고 배송지/희망 일시를 적은 뒤 카드·간편결제·가상계좌·계좌이체로 냅니다
- 또는 청구서: 고객 전화번호(알림톡)나 이메일로 결제 링크를 보냅니다. 입금 없으면 고객이 링크를 연 뒤에만 D+1/D+3 안내
- 판매 화면에서 발송/상담 완료 → 구매자 수령 확인(또는 7일 후 자동) → 빌드 크레딧 적립 → 출금(월 1회) 또는 서비스 비용 대납
사업자 없이 시작합니다(PG 직접 계약 불필요). 계속·반복 판매 시 부가세법상 사업자등록 의무는 별도입니다. 테스트 앱(dce_pk_test_)은 가짜 결제창으로 흐름만 확인합니다.
퀵스타트 B — 앱에 결제 붙이기
npx skills add ctb-rebooted/dct-pay-skill # Claude Code에서 /dct-pay pay
<script src="https://pay.docenty.ai/sdk/v1/earn.iife.js" data-app-key="dce_pk_…"></script>
<script>
DocentyEarn.identify(currentUser.email); // 이메일 모드 앱 (init은 script 태그가 자동 수행)
document.querySelector('#buy').onclick = () => DocentyEarn.checkout('prod_id');
DocentyEarn.entitled('pro').then(ok => { if (ok) unlockPro(); });
DocentyEarn.tipButton({ amounts: [1000, 3000, 5000] });
</script>자격증명 매트릭스
| 키 | 어디서 | 어디에 | 노출 |
|---|---|---|---|
| dce_pk_… | 대시보드 → 앱 → 설치 | 브라우저 SDK, x-app-key 라우트(checkouts·entitlements·credits/consume·events·apps/ping) | 공개 가능 (레이트리밋·CORS로 보호) |
| dce_sk_… | 설정 → 시크릿 키 또는 dct-pay login | Bearer: apps·products·slots·ledger·redemptions·creators/me | 서버·CLI 전용, 1회 표시 |
| 세션 쿠키 | 매직링크 | /dashboard, 서버 액션 | httpOnly |
API 레퍼런스 (요약)
| 메서드·경로 | 인증 | 설명 |
|---|---|---|
| POST /api/auth/request | — | {email} → 200 항상 (열거 방지) |
| POST /api/auth/cli/start · /poll | — | CLI 디바이스 코드 로그인 → 시크릿 1회 전달 |
| POST /api/creators | — | 202 verify_email (시크릿 미반환) |
| GET /api/creators/me | Bearer | 미인증 creator도 허용되는 유일한 라우트 |
| POST /api/apps · GET /api/apps | Bearer | 앱 등록 (buyerRefMode email|app_user_id) |
| POST /api/products · PATCH /api/products/:id | Bearer | one_time · credit_pack · tip(앱당 1개) · physical · service · digital_file · ticket (variants[], shippingKrw, inventory, images[], descriptionMd, fulfillment{fields}) |
| GET /api/templates · POST /api/templates/apply | — · Bearer | {appId, template: fruit|consulting, …} → 상품 + 정책 문안 |
| POST /api/checkouts | x-app-key | {productId | kind:'tip', amountKrw?, buyerRef?, provider?, variantId?, qty?, fulfillmentData?, payMethod?, easyPayProvider?} + 선택 Idempotency-Key → {checkoutId, url, qty, mode} |
| POST /api/checkouts/:id/identify | x-app-key | {email} 1회 바인딩 |
| POST /api/checkouts/:id/fulfillment | — | {fulfillmentData} 결제 전 필수 (FULFILLMENT_REQUIRED) |
| POST /api/checkouts/:id/portone/start | — | {payMethod, easyPayProvider?} → paymentId(`checkoutId-attempt`) + 브라우저 SDK payload |
| GET /api/checkouts/:id | x-app-key | 상태 폴링 — status + payment/verification/fulfillment/hold 4상태 + mode |
| POST /api/invoices · GET · /:id/resend · /:id/send | Bearer/세션 | {appId, to:{phone|email}, productId|amountKrw, note} → {invoiceId, checkoutId, orderUrl, deliveryStatus} (Idempotency-Key) |
| GET /api/o/:token · POST /api/o/:token/actions | 주문 링크(capability) | 마스킹 조회 / view_invoice·claim·confirm_receipt·dispute·refund_account·message |
| GET /api/orders · POST /api/orders/:id/fulfill | Bearer | 주문 목록 / {event: ship|fulfill, tracking?} (ship 은 입금 확인 후) |
| GET/POST /api/buyer-groups · POST /:id | Bearer | 거래처 그룹·서명 링크·가격 지정 (revoke/reissue/set_price) |
| PUT /api/creators/me/kyc · POST /api/payouts · POST /api/bill-pay | Bearer | 출금 정보(암호화) · 출금 신청 {amountKrw, idempotencyKey} · 대납 신청 |
| GET /api/creators/me/statement?month=&format=csv | Bearer | 판매 명세 (수수료 스냅샷 기준) |
| POST /api/integrations/nvland/leads | X-Pay-Signature (sp_002) | 리드 → 청구서 초안 (202) — 자동 발송 없음 |
| POST /api/checkouts/:id/confirm | Bearer(소유자) | 이용 제공만 (BC 0) |
| GET /api/entitlements?buyerRef= | x-app-key | {entitlements[], credits} |
| POST /api/credits/consume | x-app-key | 서버 사용 권장 |
| POST /api/apps/ping | x-app-key | SDK 설치 감지 (동의 불필요) |
| POST /api/events | x-app-key | consent:true 필수 |
| POST /api/slots | Bearer | 캠페인 자동 매칭 · 409 NO_CAMPAIGN |
| GET /api/ledger · POST /api/redemptions | Bearer | BC 잔액·사용 신청 |
| POST /api/webhooks/conversions/:campaignId | HMAC x-signature | 스폰서 전환 |
| POST /api/webhooks/portone | 서명 필수 | 결제·취소 (API 재조회) |
오류 코드
| code | status | 의미 · 조치 |
|---|---|---|
| UNAUTHORIZED | 401 | Bearer(dce_sk_) 또는 x-app-key(dce_pk_)가 없거나 틀림 |
| EMAIL_UNVERIFIED | 403 | 이메일 인증 전 Bearer 사용 — 메일의 링크를 먼저 누르세요 |
| RATE_LIMITED | 429 | retryAfterSec 초 뒤 재시도 (앱 키 60/min, IP 20/min, 로그인 3/min) |
| VALIDATION / BAD_JSON | 400 | 필드 이름·형식 오류 |
| NOT_FOUND | 404 | 소유하지 않은 리소스도 404 |
| PROVIDER_UNAVAILABLE | 400 | 카드 결제는 Docenty가 연결 중 — 계좌이체 사용 |
| BUYER_UNBOUND | 409 | 이메일 모드에서 identify 전에 결제 확정 시도 |
| BUYER_BOUND | 400 | identify 재호출 (1회 바인딩) |
| NO_TIP_PRODUCT | 404 | 앱에 후원 상품이 없음 |
| INSUFFICIENT_BC / BALANCE_NEGATIVE | 409 | 사용 신청 불가 |
| NO_CAMPAIGN | 409 | 매칭되는 활성 캠페인 없음 (슬롯 행 미생성) |
| SOLD_OUT | 409 | 재고 부족 — 수량을 줄이거나 다른 옵션 (재고는 상품 단위) |
| VARIANT_INVALID | 400 | 옵션 상품인데 variantId 누락/불일치 — fix 에 허용 id 목록 |
| FULFILLMENT_REQUIRED | 400 | 배송/예약 필드 누락 — fix 에 필수 항목. POST /checkouts/:id/fulfillment 로 채운 뒤 결제 |
| METHOD_UNAVAILABLE | 400 | 채널 키 없는 결제수단 — 다른 수단 선택 (available 목록은 /pay) |
| PAYMENT_ID_MISMATCH | 400 | paymentId 가 이 주문의 결제 시도가 아님 (payment_attempts 기준) |
| INVOICE_LIMIT | 429 | 청구서 하루 100건 한도 — retryAfterSec 뒤 |
| IDEMPOTENCY_CONFLICT | 409 | 같은 Idempotency-Key 로 다른 본문 — 새 키 사용 |
| ORDER_LINK_INVALID | 404 | /o 링크 만료·회수·서명 오류 — 판매자에게 새 링크 요청 |
| TEMPLATE_UNAVAILABLE / FEATURE_OFF | 400/403 | 준비 중 템플릿(v2.1) 또는 플래그 off |
| KYC_REQUIRED / PAYOUT_ACTIVE | 409 | 출금 정보 없음 / 처리 중 출금 있음 |
| BILL_PAY_LIMIT / DUPLICATE_INVOICE | 429/409 | 월 대납 한도(처리 중 포함) / 같은 vendor+청구서 번호 |
| NONCE_REPLAY / BAD_SIGNATURE | 409/401 | NvLand 리드 웹훅 (sp_002) — 새 nonce, 같은 leadId 로 재전송 |
| INTERNAL | 500 | 고정 문구 + requestId (원문은 서버 로그만) |
대금 흐름
판매주체 Docenty가 수납 → 입금 확인(verified_at) 시 창작자에게 상품 금액 − Docenty 5% + 300원 − PG 실비만큼 BC 적립(후원은 정률만, 배송비는 수수료 없음). 디지털·후원은 7일 뒤 사용 가능, 실물·상담·참가권은 구매자 수령 확인(또는 이행 후 7일 자동, 분쟁 시 보류) 시점에 바로 사용 가능. 수수료는 결제 시점 fee_snapshot 으로 봉인되어 요율 변경이 과거 주문에 소급되지 않습니다. 환불은 포트원 cancellation.id 또는 ops 환불 id 기준으로 정확히 한 번, 라인(수량)·배송비 단위로 반영되며 이미 사용 가능해진 BC는 음수 조정으로 상계됩니다.
크레딧 사용: 현금 출금(월 1회 배치, 최소 30,000원, 개인 3.3% 원천징수 / 사업자 세금계산서, 계좌·신원 정보 암호화) 또는 서비스 비용 대납(클라우드·LLM API·광고·도메인·호스팅·알림톡, 월 한도). 자금 성격은 판매주체 매출 → 용역대가/위탁판매 대금 지급이며 에스크로가 아닙니다(법률 자문 게이트). 빌드 크레딧 자체는 현금이 아니며 환급되지 않습니다.