Skip to main content
Silver 이상의 멤버십이 필요합니다 — 신청할 때뿐 아니라 인증된 모든 호출에서도 마찬가지입니다. 키 소유자의 멤버십이 만료되면 다시 구독할 때까지 프로젝트가 동결됩니다.
애플리케이션이 Discord 안에서 사용자의 Vito 잔액을 다룰 수 있게 해주는 REST API입니다. 잔액을 읽고, 청구하고, 지급하고, 사용자 간에 옮길 수 있습니다. 모든 엔드포인트는 JSON을 반환하며 /v1 아래에서 버전이 관리됩니다.
Vito는 실제 돈으로 바뀌거나 실제 돈에서 오지 않습니다. 오직 Vetox 잔액 사이에서만 이동합니다.

접근 권한 얻기

접근 권한은 프로젝트 단위로 부여됩니다. 네 가지가 모두 필요합니다.
1

활성 상태의 Silver 이상 멤버십

승인 시점뿐 아니라 호출할 때마다 확인합니다.
2

승인된 개발자 신청서

대시보드의 Vito API 페이지에서 제출합니다. Vetox 팀이 직접 검토합니다.
3

동의한 API 개발자 약관

신청서를 제출할 때 함께 동의합니다.
4

프로젝트에 필요한 스코프

작성하신 설명을 바탕으로 Vetox 팀이 부여합니다.
무엇을 만들고 있는지, 키를 어떻게 보관할지 구체적으로 적어 주세요. 거절되는 것은 늘 모호한 신청서입니다.

스코프

인증

비밀 키를 Bearer 토큰으로 보냅니다.
선택적인 두 계층이 프로젝트를 한층 더 단단하게 만듭니다.
  • IP 허용 목록 — 호출을 특정 서버 IP로 제한합니다
  • 요청 한도 — 소유자의 멤버십 등급에 따라 올라가는 프로젝트별 상한입니다

키 교체와 보관

키와 서명 시크릿은 정확히 한 번만 표시됩니다. 승인 후 API 키 탭에서 이를 확인할 수 있는 7일의 기간이 주어집니다. Vetox는 해시만 보관하므로 다시 보여줄 수 없습니다. 기간을 놓치면 교체해서 새로 받아야 합니다.
  • 서버 쪽에만 보관하세요 — 키를 가진 사람은 누구나 사용자에게 청구할 수 있습니다
  • 교체는 API 키 탭에서 합니다. 이전 키는 24시간의 유예 기간 동안 계속 작동하므로 중단 없이 배포할 수 있습니다
  • webhook 서명 시크릿은 별도로 교체되며, 자체적인 24시간 중첩 기간을 가집니다
  • 유출되면 즉시 교체하세요

사용자에게 청구하기

키만으로는 사용자의 Vito를 움직일 수 없습니다. 모든 청구는 사용자가 vetox.io에서 지갑 PIN으로 승인해야 합니다. 여러분의 앱 안에서도, Discord 안에서도 이루어지지 않습니다.
1

앱이 POST /v1/deduct를 호출

사용자, 금액, 요청이 시작된 guildId, 상품 정보를 함께 보냅니다.
2

Vito가 confirmUrl을 반환

대기 중인 확인 요청이며 10분 동안 유효합니다. 사용자에게 DM도 발송됩니다.
3

사용자가 PIN으로 승인

vetox.io에서 진행합니다.
4

Vito가 정산하고 알림

잔액이 차감되고 거래가 기록되며, 설정해 두었다면 서명된 webhook이 전송됩니다.
5

앱이 검증하고 마무리

서명을 확인한 뒤 콘텐츠를 열어 주거나 상품을 전달합니다.
처리를 마무리하는 시점은 오직 confirmation.completed입니다/deduct 응답으로 마무리하면 안 됩니다. 그 시점에는 청구가 아직 확정되지 않았습니다.

요청 매개변수 — /v1/deduct

사용자에게 지급하기

POST /v1/add내 잔액을 재원으로 사용자에게 Vito를 지급합니다. 보상이나 환불에 사용합니다. guildIdproduct를 제외하면 /deduct와 같은 필드를 씁니다.
청구와 달리 지급에는 확인 단계가 없습니다 — 즉시 정산됩니다. credit:create 스코프와 충분한 잔액이 필요하며, 그렇지 않으면 호출이 **402 VITO_INSUFFICIENT_OWNER_FUNDS**를 반환합니다.

수수료

모든 청구는 플랫폼 수수료를 뺀 금액으로 정산됩니다. 앱 내 Vito 송금과 동일한 요율이며 본인의 멤버십 등급을 기준으로 합니다.
5 Vito 이하 금액은 수수료가 없으며, /v1/add를 통한 지급은 항상 수수료가 없습니다.

Webhook

설정 탭에서 https 콜백 URL을 하나 이상 추가하세요. 확인 요청이 최종 상태에 도달할 때마다 Vito가 서명된 POST를 보냅니다.
webhook은 프로젝트에 콜백 URL 서명 시크릿이 모두 있을 때만 발송됩니다. 시크릿(whsec_…)은 API 키 탭에서 한 번만 확인할 수 있습니다.

서명 검증

모든 전송에는 X-Vito-Signature 헤더가 포함됩니다.
각 전송에는 두 개의 헤더가 더 따라옵니다. 재시도 시 같은 id가 다시 오므로 X-Vito-Event-Id를 중복 제거 키로 사용하세요.
서명 시크릿을 교체하는 동안 헤더에는 서명이 여러 개 담깁니다. 최신 것이 먼저입니다.
h1어느 하나라도 일치하면 전송을 수락하세요. 첫 번째만 읽는 검증 코드는 새 시크릿을 배포할 때까지 모든 webhook을 거부하는데, 이는 24시간 중첩 기간을 둔 이유 자체를 무너뜨립니다.
서명 시크릿으로 <ts>:<rawBody>의 HMAC을 다시 계산하고 상수 시간으로 비교하세요.
JSON 파싱이나 미들웨어가 다시 쓰기 전의 원본 본문을 기준으로 검증하세요.

이벤트

다섯 가지 이벤트 유형이 모두 같은 페이로드 형태를 공유합니다. 결과는 data.status에 담깁니다.
webhook은 대기 시간을 늘려가며 5회 재시도됩니다. 2xx로 빠르게 응답하고 실제 처리는 비동기로 수행하세요.

오류 코드

모든 응답은 봉투에 담깁니다. 성공은 data를, 실패는 error를 담으며 둘이 함께 오는 일은 없습니다.
모든 코드에는 VITO_ 접두사가 붙습니다. 전체 문자열로 비교하세요. RATE_LIMITEDFORBIDDEN이 단독으로 오는 일은 없습니다.

요청 한도

분당 할당량의 절반(최소 30)에 해당하는 IP별 한도도 함께 적용됩니다.
부하가 높을 때 쓰기 엔드포인트는 실패 시 차단됩니다 — 이중 지불 위험을 감수하는 대신 청구를 거부합니다. 읽기 엔드포인트는 실패 시 허용됩니다. 거부된 쓰기는 “일어나지 않은 것”으로 간주하고 다시 시도하세요.
재시도를 안전하게 중복 제거하려면 Idempotency-Key 헤더를 보내세요.

엔드포인트

제한

  • 확인 요청은 10분 후 만료됩니다 — 확인되지 않은 요청은 포기된 것으로 처리하세요
  • amount는 양의 정수여야 합니다
  • metadata는 10개 키로 제한됩니다
  • 건당 및 일일 상한은 Vetox 팀이 설정하며 설정 탭에 읽기 전용으로 표시됩니다

보안 점검 목록

API 키와 서명 시크릿은 결코 클라이언트 코드에 두어서는 안 됩니다. 둘 중 하나라도 유출되면 즉시 교체하세요.
원본 본문을 기준으로 서명을 확인하고 약 5분보다 오래된 전송은 거부하세요.
/deduct 응답만 보고 상품을 전달하지 마세요. 청구는 confirmation.completed에서야 확정됩니다.
실제로 사용하는 스코프만 요청하고 IP 허용 목록을 켜 두세요.

문제 해결

소유자의 멤버십이 만료되었습니다. 호출할 때마다 다시 확인합니다.
복구할 수 없습니다 — 해시만 저장되기 때문입니다. 교체해서 새로 받으세요.
24시간의 중첩 기간 동안에는 두 시크릿을 모두 받아들이세요.
사용자가 승인하지 않았습니다. 확인 요청은 10분 후 만료됩니다.
프로젝트에는 콜백 URL과 서명 시크릿이 모두 필요합니다. 둘 중 하나만으로는 아무것도 전송되지 않습니다.
정산 수수료입니다. 피하려면 5 Vito 이하 금액을 쓰거나 가격에 반영하세요.
/v1/add는 본인의 잔액에서 나가는 것이지 없던 데서 생기지 않습니다. 잔액을 충전하세요.

Vito

잔액, PIN, 수수료.

결제 요청

청구했을 때 사용자에게 보이는 화면.