xdata-kr Billing Refunds API
The Billing Refunds API from xdata-kr — 2 operation(s) for billing refunds.
The Billing Refunds API from xdata-kr — 2 operation(s) for billing refunds.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/xdata-kr:xdata-kr-billing-refunds-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: XBOSS Billing Refunds API
description: '통합 REST API 서버 (홈택스 등). Human API guide: https://developer.xdata.kr · OpenAPI Reference: /docs'
version: 2.0.0
security:
- basicClientCredential: []
- mcpOAuth2: []
tags:
- name: Billing Refunds
paths:
/v1/refunds:
post:
tags:
- Billing Refunds
summary: Create Refund
description: 환불 요청.
operationId: create_refund_v1_refunds_post
parameters:
- name: env_scope
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.
enum:
- production
- real_test
- sandbox
title: Env Scope
description: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.
- name: Idempotency-Key
in: header
required: true
schema:
type: string
minLength: 1
maxLength: 128
title: Idempotency-Key
- name: Authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
- name: X-Env-Scope
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.
enum:
- production
- real_test
- sandbox
title: X-Env-Scope
description: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RefundCreateRequest'
responses:
'202':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/RefundCreateResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
get:
tags:
- Billing Refunds
summary: List Refunds
description: 환불 목록 조회.
operationId: list_refunds_v1_refunds_get
parameters:
- name: query
in: query
required: true
schema:
$ref: '#/components/schemas/RefundListQuery'
- name: env_scope
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.
enum:
- production
- real_test
- sandbox
title: Env Scope
description: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.
- name: Authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
- name: X-Env-Scope
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.
enum:
- production
- real_test
- sandbox
title: X-Env-Scope
description: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/PageEnvelope_RefundResponse_'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
/v1/refunds/{refund_id}:
get:
tags:
- Billing Refunds
summary: Get Refund
description: 환불 단건 조회.
operationId: get_refund_v1_refunds__refund_id__get
parameters:
- name: refund_id
in: path
required: true
schema:
type: integer
title: Refund Id
- name: env_scope
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.
enum:
- production
- real_test
- sandbox
title: Env Scope
description: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.
- name: Authorization
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
title: Authorization
- name: X-Env-Scope
in: header
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.
enum:
- production
- real_test
- sandbox
title: X-Env-Scope
description: 환경을 고릅니다. 값은 production · real_test · sandbox 중 하나입니다. 경로 접두(/v1/sandbox/... · /v1/test/... · /v1/production/...) · X-Env-Scope 헤더 · env_scope 쿼리 가운데 한 통로로 반드시 보내야 합니다. 빼면 자동으로 채우지 않고 거절하며, 두 통로에 서로 다른 값을 담아도 거절합니다. 거절은 HTTP 422 이고 오류 코드는 VALIDATION_ENV_SCOPE_MISMATCH 입니다.
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/RefundResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
input:
title: Input
ctx:
type: object
title: Context
type: object
required:
- loc
- msg
- type
title: ValidationError
PageEnvelope_RefundResponse_:
properties:
items:
items:
$ref: '#/components/schemas/RefundResponse'
type: array
title: Items
description: Page result items. Empty list allowed.
next_cursor:
anyOf:
- type: string
- type: 'null'
title: Next Cursor
description: Opaque cursor for next page, or null on last page.
has_more:
type: boolean
title: Has More
description: Whether another page exists. False when next_cursor is null.
default: false
additionalProperties: false
type: object
title: PageEnvelope[RefundResponse]
RefundListQuery:
properties:
organization_id:
anyOf:
- type: integer
minimum: 1.0
- type: 'null'
title: Organization Id
description: 조직 PK. 본인 조직 미지정 가능(라우트 주입).
payment_id:
anyOf:
- type: integer
minimum: 1.0
- type: 'null'
title: Payment Id
description: 결제 ID 필터 (단일 결제의 환불 이력 조회).
status:
anyOf:
- items:
type: string
enum:
- PENDING
- SUCCEEDED
- FAILED
- CANCELED
type: array
- type: 'null'
title: Status
description: 상태 필터(다중). 미지정 시 전체.
limit:
type: integer
maximum: 100.0
minimum: 1.0
title: Limit
description: 페이지 크기.
default: 20
cursor:
anyOf:
- type: string
- type: 'null'
title: Cursor
description: 이전 응답의 next_cursor.
type: object
title: RefundListQuery
description: '환불 목록 조회 쿼리.
자동 필터(라우트 강제):
- `organization_id`: 본인 조직(ADMIN은 명시 가능)
- `env_scope = X-Env-Scope`
명세에 GET 목록 표가 없어 이 DTO 가 그 자리를 대신하며
함께 잠금한다(`InvoiceListQuery`/`PaymentListQuery` 패턴 동형).'
RefundCreateRequest:
properties:
payment_id:
type: integer
minimum: 1.0
title: Payment Id
description: 환불 대상 결제 ID (payments.id). status='SUCCEEDED'만 허용하고 무통장 입금 결제는 받지 않는다(422).
amount_minor:
type: integer
exclusiveMinimum: 0.0
title: Amount Minor
description: 환불 금액 (minor unit 정수). 0 과 음수는 받지 않는다. 전액/부분 모두 허용. 환불 합산 ≤ 원 결제 amount_minor는 서비스 계층 검증.
reason:
anyOf:
- type: string
enum:
- USER_REQUEST
- OPS_DISPUTE_RESOLUTION
- DUPLICATE_PAYMENT
- PAYMENT_FAILED_REVERSAL
- FRAUDULENT_PAYMENT
- OTHER
- type: 'null'
title: Reason
description: 환불 사유 enum. 미지정이면 기본값 없이 저장하고 응답 reason 은 null (note 만 있으면 그 글만 저장).
note:
anyOf:
- type: string
maxLength: 200
- type: 'null'
title: Note
description: 운영 메모(자유 텍스트). SCHEMA `refunds.reason VARCHAR(255)` 컬럼에 `reason` enum과 함께 합성 저장(서비스 계층 책임). PII/secret 금지.
cancel_subscription:
type: boolean
title: Cancel Subscription
description: 동일 트랜잭션에서 구독 CANCELED 전이 여부. True 시 `subscriptions.status='CANCELED'`로 전이 + `audit_logs.billing.subscription.transition` 적재.
default: false
metadata:
anyOf:
- additionalProperties:
type: string
type: object
- type: 'null'
title: Metadata
description: '운영 메타데이터 (예: source, dispute_id, support_ticket_id). PII/secret 적재 금지. 키 화이트리스트는 별도 결정.'
additionalProperties: false
type: object
required:
- payment_id
- amount_minor
title: RefundCreateRequest
description: "환불 생성 요청.\n\n처리 흐름:\n1) AuthPolicyService 평가(`request_kind='billing'`, BILLING_ADMIN·SYS_ADMIN 또는 본인 조직 OWNER)\n2) `payment_id` 소유권·`status='SUCCEEDED'`·env_scope 검증 - 무통장 입금 결제는 이 요청으로 환불하지 않는다\n (`422 BILLING_INVALID_INPUT`, 아무것도 쓰기 전에 거절)\n3) 환불 합산 ≤ 원 결제 amount_minor 검증 (서비스 계층 책임)\n - 위반 시 `422 BILLING_REFUND_EXCEEDS_PAYMENT`\n4) `refunds` 행 PENDING 생성\n5) 환불 요청 (어댑터 호출)\n6) `cancel_subscription=true`인 경우 동일 트랜잭션에서 구독 `CANCELED` 전이\n7) 동기 응답: 202 Accepted + 환불 객체 스냅샷(PENDING)\n\nPG 환불 결과는 웹훅으로 수신 → `refunds.SUCCEEDED` + `invoices.REFUNDED/PARTIALLY_REFUNDED`.\n\n`organization_id`는 본 DTO에 두지 않는다 — `payment_id`로 조직이 자동 추론되며,\n라우트가 `PrincipalContext.organization_id`와의 일치를 검증하여 403 차단(IDOR 방지).\n\n`metadata`는 입력만 허용(응답 미노출). PII/secret/credential 적재 금지.\n키 화이트리스트는 후속 ADR."
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
RefundCreateResponse:
properties:
refund_id:
type: integer
minimum: 1.0
title: Refund Id
description: refunds.id (BIGSERIAL PK).
payment_id:
type: integer
minimum: 1.0
title: Payment Id
description: 원 결제 ID (payments.id).
amount_minor:
type: integer
exclusiveMinimum: 0.0
title: Amount Minor
description: 환불 금액 (minor unit). 0 과 음수는 받지 않는다.
status:
type: string
enum:
- PENDING
- SUCCEEDED
- FAILED
- CANCELED
title: Status
description: 환불 상태. 본 응답은 보통 PENDING(202 Accepted).
env_scope:
type: string
enum:
- sandbox
- real_test
- production
title: Env Scope
description: 환경 스코프. 모든 응답에 일관되게 노출한다(환경 식별 + 감사 일관성).
requested_at:
type: string
format: date-time
title: Requested At
description: 환불 요청 시각 (aware datetime, naive 입력 시 422).
additionalProperties: false
type: object
required:
- refund_id
- payment_id
- amount_minor
- status
- env_scope
- requested_at
title: RefundCreateResponse
description: '환불 생성 응답 - `202 Accepted` 의 몸통.
즉시 응답 다섯 칸(`refund_id` · `payment_id` · `amount_minor` · `status` ·
`requested_at`)에 **`env_scope` 를 더해** 모든 응답에 일관되게 노출한다.
GET 단건 조회(`RefundResponse`)와 다른 객체:
- 본 응답은 **즉시 응답 최소 필드**만 포함(BFF 폴링 시작용).
- 상세 조회는 `GET /v1/refunds/{id}` (`RefundResponse`) 사용.
`status`는 통상 PENDING(PG 비동기 결과 대기). 동기 SUCCEEDED는 PG가 즉시 응답한 경우만.'
RefundResponse:
properties:
refund_id:
type: integer
minimum: 1.0
title: Refund Id
description: refunds.id.
organization_id:
type: integer
minimum: 1.0
title: Organization Id
description: 소유 조직 PK.
payment_id:
type: integer
minimum: 1.0
title: Payment Id
description: 원 결제 ID.
invoice_id:
anyOf:
- type: integer
minimum: 1.0
- type: 'null'
title: Invoice Id
description: 연결된 인보이스 ID. NULL 허용.
env_scope:
type: string
enum:
- sandbox
- real_test
- production
title: Env Scope
description: 환경 스코프.
pg_provider:
type: string
enum:
- portone
- toss
- payup
- offline
title: Pg Provider
description: PG 사업자.
provider_refund_id:
anyOf:
- type: string
maxLength: 120
- type: 'null'
title: Provider Refund Id
description: PG 발급 환불 식별자. PG 비동기 처리 중에는 NULL일 수 있다. BFF/관리자/대사 입력용. 외부 사용자 UI 표시 권장 X.
amount_minor:
type: integer
exclusiveMinimum: 0.0
title: Amount Minor
description: 환불 금액 (minor unit). 0 과 음수는 받지 않는다.
currency:
type: string
const: KRW
title: Currency
description: 통화 코드. v1=KRW.
status:
type: string
enum:
- PENDING
- SUCCEEDED
- FAILED
- CANCELED
title: Status
description: 환불 상태 (4값 enum).
reason:
anyOf:
- type: string
enum:
- USER_REQUEST
- OPS_DISPUTE_RESOLUTION
- DUPLICATE_PAYMENT
- PAYMENT_FAILED_REVERSAL
- FRAUDULENT_PAYMENT
- OTHER
- type: 'null'
title: Reason
description: 환불 사유 enum. SCHEMA 자유 텍스트를 enum으로 정규화 노출 (자유 텍스트 원문은 `audit_logs.billing.refund.transition.payload.reason_raw`로 보존).
requested_at:
type: string
format: date-time
title: Requested At
description: 환불 요청 시각 (aware datetime, naive 입력 시 422).
confirmed_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Confirmed At
description: 환불 확정 시각 (SUCCEEDED 진입 시 채워짐).
created_at:
type: string
format: date-time
title: Created At
description: 환불 행 생성 시각 (aware datetime, naive 입력 시 422).
additionalProperties: false
type: object
required:
- refund_id
- organization_id
- payment_id
- env_scope
- pg_provider
- amount_minor
- currency
- status
- requested_at
- created_at
title: RefundResponse
description: "환불 단일 객체 응답 - `GET /v1/refunds/{id}`.\n\nSCHEMA → DTO 매핑:\n- `refunds.id` → `refund_id`.\n- `organization_id/payment_id/invoice_id/env_scope/provider/provider_refund_id/\n amount_minor/currency/status/requested_at/confirmed_at/created_at` → 직접 매핑.\n- `reason`은 enum 정규화하여 노출(SCHEMA는 자유 텍스트지만 DTO는 enum 형식 권장).\n- `requested_by/metadata/updated_at` 미노출 (운영 추적은 audit_logs + 운영 API).\n\n`provider_refund_id`는 PG 트랜잭션 식별자. PG 비동기 처리 중에는 NULL일 수 있다."
securitySchemes:
basicClientCredential:
type: http
scheme: basic
description: 'Console-issued client credential. Send `Authorization: Basic base64(client_id:client_secret)`.'
mcpOAuth2:
type: oauth2
description: For MCP clients. OAuth 2.0 authorization code flow with PKCE (S256) for public clients. The client_id is the HTTPS URL of an OAuth Client ID Metadata Document that XBOSS has allow-listed; dynamic client registration is not supported.
flows:
authorizationCode:
authorizationUrl: https://api.xdata.kr/oauth/authorize
tokenUrl: https://api.xdata.kr/oauth/token
scopes: {}