오류 코드
Operator API 가 돌려주는 오류 코드 전체와, 지갑 콜백에서 오퍼레이터가 돌려주는 status 값을 정리합니다.
오류 응답 모양
Operator API 는 실패하면 HTTP 4xx · 5xx 상태와 함께 아래 JSON 을 돌려줍니다.
json
{
"error": {
"code": "INVALID_REQUEST",
"message": "invalid fields",
"details": { "fields": ["player.nickname"] }
}
}| 필드 | 타입 | 설명 |
|---|---|---|
error.code | string | 오류 코드. 프로그램은 이 값으로 분기하세요 |
error.message | string | 사람이 읽는 영문 설명. 문구는 바뀔 수 있으므로 분기에 쓰지 마세요 |
error.details | object | 일부 오류에만 있음. 필드 오류의 fields(잘못된 필드 이름 목록), 변경 이력 되돌리기 오류의 kind · key · conflicts |
- 등록되지 않은 경로나 메서드로 요청하면 이 JSON 이 아니라 일반 텍스트 본문의 HTTP 404 · 405 가 옵니다. 경로 · 메서드 오타를 먼저 확인하세요.
- 같은 요청을 고치지 않고 다시 보내도 결과가 같은 오류(4xx 대부분)는 재시도하지 마세요. 재시도해도 되는 것은
RATE_LIMITED·INTERNAL_ERROR·TABLE_OPEN_FAILED·GAME_MAINTENANCE·UNAVAILABLE정도입니다. 재시도할 때는 새X-Timestamp·X-Nonce로 다시 서명해야 합니다.
HTTP 상태 요약
| HTTP | 뜻 |
|---|---|
| 400 | 요청 본문 · 파라미터가 잘못됨 |
| 401 | 서명 · 타임스탬프 · nonce 검증 실패 |
| 403 | 인증은 됐지만 허용되지 않은 요청 (오퍼레이터 상태 · IP · 권한) |
| 404 | 대상이 없거나 이 오퍼레이터의 것이 아님 |
| 409 | 현재 상태와 충돌 |
| 429 | 요청 한도 초과 |
| 500 | 플랫폼 내부 오류 |
| 503 | 일시적으로 쓸 수 없음 (점검 등) |
인증 · 공통 오류
모든 엔드포인트에서 날 수 있습니다. 검사 순서대로 적었습니다. 자세한 규칙은 인증 · 서명을 보세요.
| code | HTTP | 원인 | 대처 |
|---|---|---|---|
INVALID_SIGNATURE | 401 | X-Operator 가 등록되지 않은 코드 | 오퍼레이터 코드 확인 |
OPERATOR_DISABLED | 403 | 오퍼레이터가 정지 상태 | 플랫폼에 문의 |
IP_NOT_ALLOWED | 403 | 요청 IP 가 등록된 허용 IP 목록에 없음 | 오퍼레이터 서버의 공인 발신 IP 를 플랫폼에 등록 |
INVALID_SIGNATURE | 401 | X-Api-Key 를 보냈는데 값이 틀림 | 발급받은 api_key 확인 (재발급 뒤에는 이전 키가 바로 무효) |
INVALID_REQUEST | 400 | 요청 본문을 읽지 못함 | 본문 · Content-Length 확인 |
TIMESTAMP_OUT_OF_RANGE | 401 | X-Timestamp 가 정수가 아니거나 플랫폼 시각과 5분 넘게 차이남 | Unix 밀리초로 보내고 서버 시계를 NTP 로 맞춤 |
INVALID_SIGNATURE | 401 | 서명이 맞지 않음, 또는 X-Nonce 가 비었거나 128자를 넘음 | 서명문(타임스탬프 · nonce · 메서드 · 경로+쿼리 · 본문 원문)과 api_secret 확인. 본문이 64KB 를 넘어 잘린 경우도 여기서 실패 |
NONCE_REUSED | 401 | 5분 안에 같은 X-Nonce 를 다시 씀 | 요청마다 새 nonce 를 만들고, 재시도 때도 새로 만들어 다시 서명 |
RATE_LIMITED | 429 | 오퍼레이터당 초당 200건 초과 | 잠시 뒤 재시도, 호출 빈도 조절 · 결과 캐시 |
INTERNAL_ERROR | 500 | 플랫폼 내부 오류 | 잠시 뒤 재시도, 계속되면 플랫폼에 문의 |
엔드포인트별 오류
| code | HTTP | 나오는 곳 | 뜻 | 대처 |
|---|---|---|---|---|
INVALID_REQUEST | 400 | 본문 · 파라미터를 받는 모든 엔드포인트 | JSON 이 깨졌거나 필드 값이 잘못됨. 필드 오류면 details.fields 에 필드 이름 목록 | details.fields 의 필드를 고쳐 다시 보냄 |
CURRENCY_NOT_SUPPORTED | 400 | POST /launch | 이 오퍼레이터에 허용되지 않은 통화 | 계약한 통화 확인 (GET /currencies) |
CURRENCY_MISMATCH | 409 | POST /launch | 이미 있는 플레이어의 통화와 다른 통화로 실행 | 플레이어 통화는 처음 실행 때 정해지고 바뀌지 않음. 통화별로 다른 external_id 사용 |
PLAYER_BLOCKED | 403 | POST /launch | 플랫폼에서 차단된 플레이어 | 차단 해제는 POST /players/{external_id}/logout 에 block: false |
GAME_NOT_FOUND | 404 | POST /launch · 테이블 만들기 · 게임별 설정 | 없는 게임 코드이거나 이 오퍼레이터에 켜지지 않은 게임 | GET /games 로 켜진 게임 확인 |
GAME_MAINTENANCE | 503 | POST /launch | 게임 점검 중 | 점검이 끝난 뒤 다시 실행. 로비에 점검 표시 |
TABLE_NOT_FOUND | 404 | POST /launch · 테이블 | 없는 테이블, 닫힌 테이블, 다른 게임의 테이블, 다른 오퍼레이터의 전용 테이블 | GET /tables 로 현재 테이블 확인 |
PRIVATE_PASSWORD | 403 | POST /launch (table_password) | 프라이빗 테이블 비밀번호가 틀림 | 플레이어에게 다시 입력받음 |
RATE_LIMITED | 429 | POST /launch (table_password) | 같은 플레이어가 같은 테이블 비밀번호를 1분에 5번 넘게 시도 | 1분 뒤 다시 시도 |
TABLE_NOT_OWNED | 403 | 테이블 변경 · 닫기 · 테이블별 설정 | 오퍼레이터 전용 테이블이 아닌 공용 테이블을 바꾸려 함 | 전용 테이블만 바꿀 수 있음 |
TABLE_CREATE_FORBIDDEN | 403 | POST /tables | 테이블을 만들 수 없는 운영 방식이거나, 그 게임의 테이블 만들기가 허용되지 않음 | 운영 방식 · 허용 게임은 플랫폼과 협의 |
TEMPLATE_NOT_FOUND | 404 | POST /tables | 그 게임에 복사할 기본 테이블이 없음 | 플랫폼에 문의 |
TEMPLATE_NOT_ALLOWED | 400 | POST /tables | 복사 원본으로 지정한 테이블을 쓸 수 없음 | 다른 원본 테이블 지정 또는 원본 없이 게임 코드로 만들기 |
INVALID_CONFIG | 400 | 테이블 만들기 · 설정 · 타이머 · 레이크 · 라이브 · 통화 | 설정 값이 허용 범위 밖이거나 서로 맞지 않음 | message 를 참고해 값 수정 |
UNSUPPORTED_GAME | 400 | PUT /tables/{table_id}/live | 딜링 · 일시정지 제어를 지원하지 않는 게임 | 라이브 홀덤 · 스피드 홀덤 테이블에만 사용 |
TABLE_BUSY | 409 | PUT /tables/{table_id}/currency | 플레이어가 앉아 있어 통화를 바꿀 수 없음 | 테이블이 빈 뒤 다시 시도 |
TABLE_OPEN_FAILED | 500 | POST /tables · PUT /tables/{table_id}/currency | 테이블을 열지 못함 | 잠시 뒤 재시도, 계속되면 플랫폼에 문의 |
UNAVAILABLE | 503 | POST /tables | 지금은 테이블을 만들 수 없음 | 잠시 뒤 재시도, 계속되면 플랫폼에 문의 |
BAD_IMAGE | 400 | PUT /lobby-banners | 배너 그림 형식 · 크기 오류 | 허용 형식 · 크기로 다시 올림 |
BANNER_NOT_FOUND | 404 | PUT /games/{game_code}/lobby | 지정한 배너 그림이 아직 올라가지 않음 | 먼저 PUT /lobby-banners 로 그림을 올림 |
ROUND_NOT_FOUND | 404 | GET /rounds/{round_id} | 없는 라운드이거나 이 오퍼레이터 · 플레이어의 것이 아님 | round_id · external_id 확인 |
SESSION_NOT_FOUND | 404 | GET /sessions/{session_id} | 없는 테이블 세션 | tss_… ID 확인 |
PLAYER_NOT_FOUND | 404 | POST /players/{external_id}/logout | 한 번도 게임을 실행하지 않은 플레이어 | external_id 확인 |
DEALER_NOT_FOUND | 404 | 딜러 | 없는 딜러이거나 이 오퍼레이터의 딜러가 아님 | dealer_id 확인 |
DUPLICATE | 409 | POST /dealers | 이미 쓰는 딜러 로그인 아이디 (모든 오퍼레이터가 함께 씀) | 다른 아이디 사용 |
BAD_PHOTO | 400 | PUT /dealers/{dealer_id}/photo | 사진 형식 · 크기 오류 | 허용 형식 · 크기로 다시 올림 |
CARD_LOG_FORBIDDEN | 403 | GET /dealer-card-log | 이 운영 방식에서는 카드 입력 기록을 볼 수 없음 | independent 운영 방식 전용 |
PRIVATE_FORBIDDEN | 403 | 프라이빗 테이블 | 이 운영 방식에서는 프라이빗 테이블을 쓸 수 없음 | independent 운영 방식 전용 |
PRIVATE_OVERLAP | 409 | POST /private-tables | 같은 테이블의 다른 예약과 시간이 겹침 | 시간대 조정 |
PRIVATE_ENDED | 409 | DELETE /private-tables/{private_id} | 이미 끝났거나 취소된 예약 | 취소할 필요 없음 |
NOT_FOUND | 404 | DELETE /private-tables/{private_id} · POST /audit/{audit_id}/restore | 없는 예약 · 없는 변경 기록 | ID 확인 |
NOT_RESTORABLE | 403 | POST /audit/{audit_id}/restore | 오퍼레이터가 되돌릴 수 없는 종류의 변경 | 플랫폼에 문의 |
NOT_RESTORABLE | 409 | POST /audit/{audit_id}/restore | 되돌릴 값이 없거나 되돌리기 기능이 꺼져 있음 | — |
RESTORE_BLOCKED | 409 | POST /audit/{audit_id}/restore | 되돌리면 현재 상태와 맞지 않음. details.kind · details.key 에 막힌 대상 | message 를 참고해 먼저 정리 |
RESTORE_CONFLICT | 409 | POST /audit/{audit_id}/restore | 이 변경 뒤에 같은 대상이 다시 바뀜. details.conflicts 에 목록 | 나중 변경부터 되돌리거나 force: true 로 덮어씀 |
지갑 콜백 status
지갑 콜백에서는 방향이 반대입니다. 플랫폼이 오퍼레이터를 부르고, 오퍼레이터가 HTTP 200 과 함께 아래 status 중 하나를 돌려줍니다. 각 값에 대한 플랫폼 처리는 지갑 콜백 개요에 있습니다.
| status | 뜻 | debit 에서 | credit · rollback 에서 |
|---|---|---|---|
OK | 처리됨 | 확정 | 확정 |
INSUFFICIENT_FUNDS | 잔액 부족 | 거절 | 재시도됨 — 쓰지 말 것 |
PLAYER_NOT_FOUND | 플레이어 없음 | 거절 | 재시도됨 — 쓰지 말 것 |
PLAYER_BLOCKED | 차단 · 자기 배제 | 거절 | 재시도됨 — 쓰지 말 것 |
LIMIT_EXCEEDED | 책임 도박 한도 초과 | 거절 | 재시도됨 — 쓰지 말 것 |
CURRENCY_MISMATCH | 통화 불일치 | 거절 | 재시도됨 |
INVALID_SIGNATURE | 서명 검증 실패 | 거절 | 재시도됨 |
TX_ALREADY_ROLLED_BACK | rollback 이 먼저 온 debit | 거절 | 재시도됨 — 쓰지 말 것 |
INVALID_REQUEST | 필드 오류 | 거절 | 재시도됨 |
UNKNOWN_ERROR | 처리 여부를 모름 | 실패 + 플랫폼이 rollback | 재시도됨 |
credit · rollback 은 OK 로만 끝납니다. 엔드포인트별 상세는 balance · debit · credit · rollback 을 보세요.
플레이어 화면의 지갑 관련 오류
플레이어가 게임 화면에서 볼 수 있는 지갑 관련 오류입니다. 고객 문의 대응에 참고하세요.
| 코드 | 언제 |
|---|---|
INSUFFICIENT_FUNDS | 오퍼레이터 지갑이 debit 에 잔액 부족을 돌려줌 |
LIMIT_EXCEEDED | 오퍼레이터 지갑이 debit 에 한도 초과를 돌려줌 |
OPERATOR_CREDIT_EXHAUSTED | prepaid 운영 방식에서 오퍼레이터의 알(선불 크레딧)이 모자람 — 지갑은 호출되지 않음 |
WALLET_UNAVAILABLE | debit 결과가 불확실함(타임아웃 · 연결 실패 · UNKNOWN_ERROR), 그 밖의 지갑 거절, 잔액 새로고침 실패 |