모든 에러는 RFC 7807을 따라요. 본문은 application/problem+json이며 type, title, status, detail, request_id 필드를 포함하고, 필요에 따라 reason 또는 errors[]도 포함돼요.
{
"type": "https://www.kernelhost.com/en/kernelhost-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은 항상 unauthorized이며(키가 다른 IP 주소로 제한된 경우 ip_not_allowed), 의도적으로 그 이상의 정보를 제공하지 않습니다. 키, secret, 시간(±300초), nonce, 서명을 확인하십시오. 지원팀은 request_id로 정확한 원인을 확인할 수 있습니다. |
| 402 | payment_required | 결제 필요. 사유는 아래 참조. |
| 403 | forbidden_scope | 권한 부족. reason: missing_scope. |
| 404 | not_found | 리소스가 존재하지 않거나 이 키로 접근할 수 없어요 (테넌트 열거 방지). |
| 409 | idempotency_conflict, order_in_progress, service_not_active | 충돌입니다. Idempotency-Key가 이미 다른 본문이나 다른 엔드포인트에 사용되었거나(idempotency_conflict, 첫 요청이 아직 처리 중이면 reason in_progress), 계정의 다른 주문이 아직 처리 중이거나(reason order_in_progress, Retry-After 준수), 서비스가 해당 액션을 허용하지 않는 상태입니다(service_not_active, service_status 참조). |
| 413 | payload_too_large | 요청 body가 65,536바이트를 초과합니다. 인증 전에 거부됩니다. |
| 422 | unprocessable | 요청은 이해되었지만 실행할 수 없습니다. reason billing_cycle_not_available: 해당 결제 주기로는 이 제품이 제공되지 않습니다. reason zero_total_not_allowed: 프로모션 코드 같은 정당한 사유 없이 주문이 무료가 됩니다. |
| 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(은행 또는 게이트웨이가 카드를 거절했어요. 해결: 다른 카드를 사용하시거나 카드사에 문의해 주세요.)credit_apply_failed(크레딧을 청구서에 적용할 수 없었습니다. 아무 금액도 청구되지 않았으며 주문은 취소되었습니다. 새 Idempotency-Key로 다시 시도하거나 지원팀에 문의하십시오.)client_not_found(계정 ID를 찾을 수 없어요 (실제로는 거의 발생하지 않으며, 발생 시 지원팀에 문의해 주세요).)

