결제 API
이 엔드포인트를 통해 MIRI API 크레딧을 구매하고, 결제 완료를 확인하며, 계정 잔액을 조회할 수 있습니다.
인증
Miri-Api-Key: miri_live_sk_xxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
모든 결제 요청에는 API 키가 필요합니다. 구매를 시작할 때는 X-Idempotency-Key를 사용해 중복 주문을 방지하세요.
크레딧 구매
결제사 연동을 통해 크레딧 구매를 시작합니다.
엔드포인트
POST /public/v1/payments/purchase
헤더
Miri-Api-Key: miri_live_sk_xxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
X-Idempotency-Key: unique-request-id-123 (선택)
요청 본문
{
"packageType": "STANDARD",
"paymentMethod": "CARD"
}
필드 설명
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
packageType | string | 예 | 구매할 패키지(BASIC, STANDARD, PRO, MAX). |
paymentMethod | string | 아니요 | 결제 수단(현재 CARD만 지원). 생략 시 CARD. |
응답 (201 Created)
{
"success": true,
"data": {
"orderId": "ord_2025090100001",
"packageType": "STANDARD",
"amount": 20000,
"clientKey": "test_ck_xxxxxxxxxxxxxxxxx",
"successUrl": "https://partner.example.com/payments/success",
"failUrl": "https://partner.example.com/payments/fail"
},
"message": "Payment initiated. Please proceed with payment.",
"code": "SUCCESS",
"metadata": null
}
응답 필드
| 필드 | 타입 | 설명 |
|---|---|---|
orderId | string | 결제 주문 ID. |
packageType | string | 선택한 패키지. |
amount | number | 결제 금액(KRW). |
clientKey | string | 프런트엔드 결제에 사용하는 PG 클라이언트 키. |
successUrl | string | 결제 성공 후 리다이렉션 URL. |
failUrl | string | 결제 실패 후 리다이렉션 URL. |
멱등 요청
구매 요청을 재시도할 때 동일한 X-Idempotency-Key를 사용하면 새로운 주문을 만들지 않고 기존 orderId를 재사용합니다.
결제 확인
사용자가 결제를 완료한 후 확인을 진행합니다.
엔드포인트
POST /public/v1/payments/confirm
헤더
Miri-Api-Key: miri_live_sk_xxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
요청 본문
{
"orderId": "ord_2025090100001",
"paymentKey": "payment_key_from_gateway",
"amount": 20000
}
응답 (200 OK)
{
"success": true,
"data": {
"orderId": "ord_2025090100001",
"creditsAdded": 60,
"totalCredits": 300,
"message": "Payment successful. Credits have been added to your account."
},
"message": "Payment confirmed successfully",
"code": "SUCCESS",
"metadata": null
}
응답 필드
| 필드 | 타입 | 설명 |
|---|---|---|
orderId | string | 확인된 주문 ID. |
creditsAdded | integer | 이번 결제로 추가된 크레딧. |
totalCredits | integer | 확인 후 총 보유 크레딧. |
message | string | 사용자 안내 메시지. |
결제 상태 조회
언제든 주문 상태를 확인합니다.
엔드포인트
GET /public/v1/payments/{orderId}
응답 (200 OK)
{
"success": true,
"data": {
"orderId": "ord_2025090100001",
"status": "CONFIRMED",
"packageType": "STANDARD",
"amount": 20000,
"createdAt": "2025-09-01T10:00:00Z",
"confirmedAt": "2025-09-01T10:15:00Z"
},
"message": "Payment status retrieved",
"code": "SUCCESS",
"metadata": null
}
상태 값
| 상태 | 설명 |
|---|---|
PENDING | 주문이 확인을 기다리는 중이며 아직 크레딧이 추가되지 않았습니다. |
CONFIRMED | 결제가 완료되어 크레딧이 계정에 적립되었습니다. |
FAILED | 결제가 실패하거나 거절되어 크레딧이 추가되지 않았습니다. |
CANCELLED | 취소가 완료되어 주문이 종료되었습니다. 취소 과정에서 추가된 크레딧은 회수됩니다. |
REFUNDED | 정산 이후 플랫폼에서 환불 처리한 주문입니다. |
크레딧 잔액 조회
현재 보유 크레딧을 확인합니다.
엔드포인트
GET /public/v1/payments/credits
응답 (200 OK)
{
"success": true,
"data": {
"credits": 240,
"customerId": "550e8400-e29b-41d4-a716-446655440000"
},
"message": "Credit amount retrieved",
"code": "SUCCESS",
"metadata": null
}
크레딧 패키지 목록
구매 가능한 패키지를 조회합니다.
엔드포인트
GET /public/v1/payments/packages
응답 (200 OK)
{
"success": true,
"data": [
{
"packageType": "BASIC",
"credits": 1,
"price": 1000,
"displayName": "Basic Plan - 1 Credit",
"description": "1 credit for ₩1,000",
"bonusPercentage": 0,
"bonusCredits": 0
},
{
"packageType": "STANDARD",
"credits": 21,
"price": 20000,
"displayName": "Standard Plan - 21 Credits",
"description": "21 credits for ₩20,000",
"bonusPercentage": 5,
"bonusCredits": 1
},
{
"packageType": "PRO",
"credits": 110,
"price": 100000,
"displayName": "Pro Plan - 110 Credits",
"description": "110 credits for ₩100,000",
"bonusPercentage": 10,
"bonusCredits": 10
},
{
"packageType": "MAX",
"credits": 1200,
"price": 1000000,
"displayName": "Max Plan - 1,200 Credits",
"description": "1,200 credits for ₩1,000,000",
"bonusPercentage": 20,
"bonusCredits": 200
}
],
"message": "Available credit packages",
"code": "SUCCESS",
"metadata": null
}
패키지 요약
| 패키지 | 크레딧 (기본+보너스) | 보너스 % | 금액 (KRW) |
|---|---|---|---|
BASIC | 1 | 0% | ₩1,000 |
STANDARD | 20 + 1 | 5% | ₩20,000 |
PRO | 100 + 10 | 10% | ₩100,000 |
MAX | 1,000 + 200 | 20% | ₩1,000,000 |
결제 취소
이미 생성된 결제를 취소합니다.
엔드포인트
POST /public/v1/payments/cancel
헤더
Miri-Api-Key: miri_live_sk_xxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
요청 본문
{
"paymentKey": "payment_key_from_gateway",
"reason": "User requested cancellation"
}
응답 (200 OK)
{
"success": true,
"data": {
"message": "Payment cancelled"
},
"message": null,
"code": "SUCCESS",
"metadata": null
}
최상위 message 값은 null이며 안내 문구는 data.message를 참고하세요. 취소에 실패하면 400 Bad Request와 함께 code = "PAYMENT_CANCEL_FAILED"가 반환되며 metadata에 paymentKey, reason이 포함됩니다.
오류 코드
| 코드 | HTTP 상태 | 설명 |
|---|---|---|
INVALID_API_KEY | 401 | 헤더가 없거나 형식이 잘못된 경우(엣지 인증 필터). |
AUTH001 | 401 | API 키를 찾을 수 없음. |
AUTH003 | 403 | API 키가 정지됨. |
VAL001 | 400 | 요청 본문 파싱 실패. |
VAL002 | 400 | 필수 필드 누락(packageType 등). |
VAL003 | 400 | 필드 검증 실패 또는 지원하지 않는 값. |
VAL004 | 400 | 요청 크기가 허용치를 초과함. |
BUS002 | 402 | 시도한 작업을 수행하기에 크레딧 잔액이 부족함. |
PAYMENT_CANCEL_FAILED | 400 | 취소 요청이 거절됨(metadata에 paymentKey, reason 포함). |
NOT000 | 404 | 결제를 찾을 수 없거나 호출자와 일치하지 않음. |
SVC001 | 503 | 결제 서비스가 일시적으로 사용 불가. |
INT001 | 500 | 예기치 않은 서버 오류. |