Docenty Pay

문서

API base https://pay.docenty.ai/api · 오류 형식 {error:{code,message,fix,docUrl,retryAfterSec?}}

  1. 로그인 (이메일 매직링크) → 핸들 입력 → "결제 링크 만들기" 선택
  2. 링크 화면에서 소개·후원 앱 확인 → 공개 → https://pay.docenty.ai/u/핸들 공유
  3. 구매자가 계좌이체 후 "입금했어요" → 판매 화면에서 이용 제공 → Docenty 입금 검증 후 BC 적립

퀵스타트 A′ — 판매자 (코드 없음): 과일·상담 팔기

  1. 로그인 → 앱(판매 페이지) 하나 → 상품 추가에서 "농수산·과일 단품" 또는 "전문직 상담" 템플릿 선택 (옵션·배송비·재고·환불 문안이 채워집니다)
  2. 상품 페이지 https://pay.docenty.ai/u/핸들/p/상품id 를 카톡·인스타에 공유 — 구매자는 옵션·수량을 고르고 배송지/희망 일시를 적은 뒤 카드·간편결제·가상계좌·계좌이체로 냅니다
  3. 또는 청구서: 고객 전화번호(알림톡)나 이메일로 결제 링크를 보냅니다. 입금 없으면 고객이 링크를 연 뒤에만 D+1/D+3 안내
  4. 판매 화면에서 발송/상담 완료 → 구매자 수령 확인(또는 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 loginBearer: 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/meBearer미인증 creator도 허용되는 유일한 라우트
POST /api/apps · GET /api/appsBearer앱 등록 (buyerRefMode email|app_user_id)
POST /api/products · PATCH /api/products/:idBearerone_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/checkoutsx-app-key{productId | kind:'tip', amountKrw?, buyerRef?, provider?, variantId?, qty?, fulfillmentData?, payMethod?, easyPayProvider?} + 선택 Idempotency-Key → {checkoutId, url, qty, mode}
POST /api/checkouts/:id/identifyx-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/:idx-app-key상태 폴링 — status + payment/verification/fulfillment/hold 4상태 + mode
POST /api/invoices · GET · /:id/resend · /:id/sendBearer/세션{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/fulfillBearer주문 목록 / {event: ship|fulfill, tracking?} (ship 은 입금 확인 후)
GET/POST /api/buyer-groups · POST /:idBearer거래처 그룹·서명 링크·가격 지정 (revoke/reissue/set_price)
PUT /api/creators/me/kyc · POST /api/payouts · POST /api/bill-payBearer출금 정보(암호화) · 출금 신청 {amountKrw, idempotencyKey} · 대납 신청
GET /api/creators/me/statement?month=&format=csvBearer판매 명세 (수수료 스냅샷 기준)
POST /api/integrations/nvland/leadsX-Pay-Signature (sp_002)리드 → 청구서 초안 (202) — 자동 발송 없음
POST /api/checkouts/:id/confirmBearer(소유자)이용 제공만 (BC 0)
GET /api/entitlements?buyerRef=x-app-key{entitlements[], credits}
POST /api/credits/consumex-app-key서버 사용 권장
POST /api/apps/pingx-app-keySDK 설치 감지 (동의 불필요)
POST /api/eventsx-app-keyconsent:true 필수
POST /api/slotsBearer캠페인 자동 매칭 · 409 NO_CAMPAIGN
GET /api/ledger · POST /api/redemptionsBearerBC 잔액·사용 신청
POST /api/webhooks/conversions/:campaignIdHMAC x-signature스폰서 전환
POST /api/webhooks/portone서명 필수결제·취소 (API 재조회)

오류 코드

codestatus의미 · 조치
UNAUTHORIZED401Bearer(dce_sk_) 또는 x-app-key(dce_pk_)가 없거나 틀림
EMAIL_UNVERIFIED403이메일 인증 전 Bearer 사용 — 메일의 링크를 먼저 누르세요
RATE_LIMITED429retryAfterSec 초 뒤 재시도 (앱 키 60/min, IP 20/min, 로그인 3/min)
VALIDATION / BAD_JSON400필드 이름·형식 오류
NOT_FOUND404소유하지 않은 리소스도 404
PROVIDER_UNAVAILABLE400카드 결제는 Docenty가 연결 중 — 계좌이체 사용
BUYER_UNBOUND409이메일 모드에서 identify 전에 결제 확정 시도
BUYER_BOUND400identify 재호출 (1회 바인딩)
NO_TIP_PRODUCT404앱에 후원 상품이 없음
INSUFFICIENT_BC / BALANCE_NEGATIVE409사용 신청 불가
NO_CAMPAIGN409매칭되는 활성 캠페인 없음 (슬롯 행 미생성)
SOLD_OUT409재고 부족 — 수량을 줄이거나 다른 옵션 (재고는 상품 단위)
VARIANT_INVALID400옵션 상품인데 variantId 누락/불일치 — fix 에 허용 id 목록
FULFILLMENT_REQUIRED400배송/예약 필드 누락 — fix 에 필수 항목. POST /checkouts/:id/fulfillment 로 채운 뒤 결제
METHOD_UNAVAILABLE400채널 키 없는 결제수단 — 다른 수단 선택 (available 목록은 /pay)
PAYMENT_ID_MISMATCH400paymentId 가 이 주문의 결제 시도가 아님 (payment_attempts 기준)
INVOICE_LIMIT429청구서 하루 100건 한도 — retryAfterSec 뒤
IDEMPOTENCY_CONFLICT409같은 Idempotency-Key 로 다른 본문 — 새 키 사용
TEMPLATE_UNAVAILABLE / FEATURE_OFF400/403준비 중 템플릿(v2.1) 또는 플래그 off
KYC_REQUIRED / PAYOUT_ACTIVE409출금 정보 없음 / 처리 중 출금 있음
BILL_PAY_LIMIT / DUPLICATE_INVOICE429/409월 대납 한도(처리 중 포함) / 같은 vendor+청구서 번호
NONCE_REPLAY / BAD_SIGNATURE409/401NvLand 리드 웹훅 (sp_002) — 새 nonce, 같은 leadId 로 재전송
INTERNAL500고정 문구 + 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·광고·도메인·호스팅·알림톡, 월 한도). 자금 성격은 판매주체 매출 → 용역대가/위탁판매 대금 지급이며 에스크로가 아닙니다(법률 자문 게이트). 빌드 크레딧 자체는 현금이 아니며 환급되지 않습니다.