모든 에러는 RFC 7807을 따라요. 본문은 application/problem+json이며 type, title, status, detail, request_id 필드를 포함하고, 필요에 따라 reason 또는 errors[]도 포함돼요.
{
"type": "https://www.kernelhost.com/en/reseller-api/errors/payment_required",
"title": "Payment required",
"status": 402,
"detail": "The order could not be paid.",
"request_id": "01HX7Z3K8Q...",
"reason": "insufficient_credit_and_no_card"
}
| HTTP | type | 의미 |
|---|---|---|
| 400 | validation_failed | 입력 유효성 검사 실패. 필드별 상세는 errors[]를 참조해 주세요. |
| 401 | auth_failed | 인증 실패. reason이 사유를 알려드려요: missing_headers, bad_key, bad_timestamp, timestamp_out_of_window, bad_nonce, bad_signature, signature_mismatch, replay_detected, unknown_or_locked_key, ip_not_allowed. |
| 402 | payment_required | 결제 필요. 사유는 아래 참조. |
| 403 | forbidden_scope | 권한 부족. reason: missing_scope. |
| 404 | not_found | 리소스가 존재하지 않거나 이 키로 접근할 수 없어요 (테넌트 열거 방지). |
| 409 | idempotency_conflict | 동일한 Idempotency-Key가 다른 본문으로 이미 사용됐어요. |
| 429 | rate_limited | 속도 제한 초과. Retry-After 헤더를 따라 주세요. |
| 500 | internal_error | 내부 서버 오류. 지원팀에 문의하실 때 감사 로그와 상관관계를 맺기 위해 request_id를 함께 제공해 주세요. |
Payment Required 사유 (HTTP 402)
주문 결제가 처리되지 못하면 API는 HTTP 402와 함께 기계 판독 가능한 reason을 JSON 본문에 담아 반환해요.
insufficient_credit_and_no_card(크레딧 부족 및 등록된 카드 없음. 해결: 크레딧을 충전하시거나 고객 포털에서 카드를 추가해 주세요.)card_declined(은행 또는 게이트웨이가 카드를 거절했어요. 해결: 다른 카드를 사용하시거나 카드사에 문의해 주세요.)card_expired(카드 유효 기간 만료. 해결: 고객 포털에서 새 카드를 추가해 주세요.)client_not_found(계정 ID를 찾을 수 없어요 (실제로는 거의 발생하지 않으며, 발생 시 지원팀에 문의해 주세요).)

