Skip to main content

개요

ARI (Availability, Rate, Inventory) 시스템의 요금 관리 도메인은 숙박 시설의 객실 요금(Rate)과 요금제(Rate Plan)를 관리합니다. 주요 개념:
  • AriRate: 특정 객실 타입의 기본 요금 정보 (금액, 통화, 요금 타입)
  • AriRatePlan: 요금제로서 하나 이상의 Rate를 포함하며, 체크인/아웃 시간, 숙박 기간, 취소 정책 등을 정의
  • AriRateAdjustment: 요금에 적용되는 조정 규칙 (배수 또는 가감 금액)
  • 채널별 조정: 예약 채널에 따라 다른 요금 조정 적용

Queries

getAccommodationAriRateList

특정 숙박 시설의 모든 요금 목록을 조회합니다.

GraphQL Signature

query GetAccommodationAriRateList($accommodationId: ID!) {
  getAccommodationAriRateList(accommodationId: $accommodationId) {
    id
    accommodationId
    roomTypeId
    name
    code
    amount
    currency
    isBaseRate
    type
    adjustments {
      id
      multiplier
      adjustment
    }
    createdAt
    updatedAt
  }
}

파라미터

accommodationId
ID!
required
조회할 숙박 시설 ID

응답

id
Int!
요금 ID
accommodationId
ID!
숙박 시설 ID
roomTypeId
String!
객실 타입 ID
name
String!
요금 이름
code
String!
요금 코드 (고유 식별자)
amount
Decimal!
요금 금액
currency
String!
통화 코드 (예: KRW, USD)
isBaseRate
Boolean!
기본 요금 여부
type
NormalReservationType!
예약 타입:
  • rent: 대실
  • lodge: 숙박
adjustments
[AriRateAdjustment!]!
요금에 적용되는 조정 규칙 목록

예제

query {
  getAccommodationAriRateList(accommodationId: "01H8X9Y2Z3A4B5C6D7E8F9G0H1") {
    id
    name
    code
    amount
    currency
    isBaseRate
    type
    adjustments {
      multiplier
      adjustment
    }
  }
}

getAccommodationAriRatePlanList

특정 숙박 시설의 요금제 목록을 조회합니다.

GraphQL Signature

query GetAccommodationAriRatePlanList(
  $accommodationId: ID!
  $filter: AriRatePlanListFilter
) {
  getAccommodationAriRatePlanList(
    accommodationId: $accommodationId
    filter: $filter
  ) {
    id
    accommodationId
    name
    code
    roomTypeId
    type
    baseOccupancy
    maxOccupancy
    extraPersonCharge
    checkInAt
    checkOutAt
    duration
    minStayDuration
    maxStayDuration
    displayPeriod {
      id
      name
    }
    baseRate {
      id
      name
      amount
    }
    rates {
      id
      name
      amount
      isDefault
    }
    inclusions {
      id
      quantity
      inclusion {
        name
        charge
      }
    }
  }
}

파라미터

accommodationId
ID!
required
조회할 숙박 시설 ID
filter
AriRatePlanListFilter
필터 조건
  • roomTypeId: 특정 객실 타입으로 필터링
  • type: 예약 타입 (rent 또는 lodge)

응답

id
Int!
요금제 ID
name
String!
요금제 이름
code
String!
요금제 코드
roomTypeId
String
특정 객실 타입에만 적용되는 경우 객실 타입 ID
type
NormalReservationType!
예약 타입 (rent/lodge)
baseOccupancy
Int!
기준 인원
maxOccupancy
Int
최대 인원
extraPersonCharge
Decimal!
인원 추가 요금
checkInAt
String!
체크인 시간 (HH:mm 형식)
checkOutAt
String!
체크아웃 시간 (HH:mm 형식)
duration
Int
숙박 기간 (일)
minStayDuration
Int!
최소 숙박 일수
maxStayDuration
Int
최대 숙박 일수
displayPeriod
AriPeriod
요금제 노출 기간
baseRate
AriRate
기본 요금
rates
[AriRatePlanRate!]!
요금제에 포함된 요금 목록
inclusions
[AriRatePlanInclusion!]!
서비스 목록 (조식, 픽업 서비스 등)

예제

query {
  getAccommodationAriRatePlanList(
    accommodationId: "01H8X9Y2Z3A4B5C6D7E8F9G0H1"
    filter: { type: lodge }
  ) {
    id
    name
    code
    type
    baseOccupancy
    checkInAt
    checkOutAt
    baseRate {
      name
      amount
      currency
    }
    inclusions {
      quantity
      inclusion {
        name
        charge
      }
    }
  }
}

Mutations

createAriRate

새로운 요금을 생성합니다.

GraphQL Signature

mutation CreateAriRate($accommodationId: ID!, $input: CreateAriRateInput!) {
  createAriRate(accommodationId: $accommodationId, input: $input) {
    id
    name
    code
    amount
    currency
    isBaseRate
    type
    adjustments {
      id
      multiplier
      adjustment
    }
  }
}

파라미터

accommodationId
ID!
required
숙박 시설 ID
input
CreateAriRateInput!
required
요금 생성 정보
input.name
String!
required
요금 이름
input.code
String!
required
요금 코드 (객실 타입 내에서 고유해야 함)
input.amount
Decimal!
required
요금 금액
input.currency
String!
required
통화 코드 (기본값: KRW)
input.roomTypeId
String!
required
객실 타입 ID
input.isBaseRate
Boolean
기본 요금 여부 (기본값: false)
input.type
NormalReservationType!
required
예약 타입 (rent/lodge)
input.adjustments
[AriRateAdjustmentWithPriorityInput!]
요금 조정 규칙 목록

응답

생성된 AriRate 객체를 반환합니다.

예제

mutation {
  createAriRate(
    accommodationId: "01H8X9Y2Z3A4B5C6D7E8F9G0H1"
    input: {
      name: "주중 스탠다드 요금"
      code: "WEEKDAY_STD"
      amount: "120000"
      currency: "KRW"
      roomTypeId: "room_type_001"
      isBaseRate: true
      type: lodge
      adjustments: [
        {
          multiplier: "1.0"
          adjustment: "0"
          priority: 0
        }
      ]
    }
  ) {
    id
    name
    code
    amount
    isBaseRate
  }
}

검증 규칙

  • 동일한 roomTypeIdcode 조합이 이미 존재하면 ARI_RATE.CODE_ALREADY_EXISTS 에러 발생
  • 동일한 roomTypeIdtype에 대해 isBaseRate: true인 요금이 이미 존재하면 에러 발생

createAriRatePlan

새로운 요금제를 생성합니다.

GraphQL Signature

mutation CreateAriRatePlan($accommodationId: ID!, $input: CreateAriRatePlanInput!) {
  createAriRatePlan(accommodationId: $accommodationId, input: $input) {
    id
    name
    code
    type
    baseOccupancy
    checkInAt
    checkOutAt
    rates {
      id
      name
      amount
    }
    inclusions {
      quantity
      inclusion {
        name
      }
    }
  }
}

파라미터

accommodationId
ID!
required
숙박 시설 ID
input
CreateAriRatePlanInput!
required
요금제 생성 정보
input.name
String!
required
요금제 이름
input.code
String!
required
요금제 코드
input.roomTypeId
String
특정 객실 타입에만 적용하는 경우 객실 타입 ID
input.type
NormalReservationType!
required
예약 타입 (rent/lodge)
input.baseAdjustment
AriRatePlanAdjustmentInput!
required
기본 요금 조정 규칙
  • multiplier: 곱셈 배수
  • adjustment: 가감 금액
input.rates
[AriRatePlanRateInput!]!
required
요금제에 포함할 요금 목록
  • rateId: 요금 ID
  • isDefault: 기본 요금 여부
  • sortOrder: 정렬 순서
input.baseOccupancy
Int!
required
기준 인원
input.maxOccupancy
Int
최대 인원
input.extraPersonCharge
Decimal
인원 추가 요금 (기본값: 0)
input.checkInAt
String!
required
체크인 시간 (HH:mm 형식)
input.checkOutAt
String!
required
체크아웃 시간 (HH:mm 형식)
input.duration
Int
숙박 기간 (일)
input.minStayDuration
Int
최소 숙박 일수 (기본값: 1)
input.maxStayDuration
Int
최대 숙박 일수
input.displayPeriodId
Int
노출 기간 ID
input.inclusions
[AriInclusionInput!]
서비스 목록
input.channelAdjustments
[AriRatePlanChannelAdjustmentInput!]
채널별 요금 조정 규칙
input.cancellationPolicyId
Int
취소 정책 ID
input.description
String
요금제 설명

응답

생성된 AriRatePlan 객체를 반환합니다.

예제

mutation {
  createAriRatePlan(
    accommodationId: "01H8X9Y2Z3A4B5C6D7E8F9G0H1"
    input: {
      name: "프리미엄 요금제"
      code: "PREMIUM"
      type: lodge
      baseAdjustment: {
        multiplier: "1.0"
        adjustment: "0"
      }
      rates: [
        {
          rateId: 1
          isDefault: true
          sortOrder: 0
        }
      ]
      baseOccupancy: 2
      maxOccupancy: 4
      extraPersonCharge: "20000"
      checkInAt: "15:00"
      checkOutAt: "11:00"
      minStayDuration: 1
      inclusions: [
        {
          id: 1
          quantity: 2
        }
      ]
      description: "조식 포함 프리미엄 요금제"
    }
  ) {
    id
    name
    code
    baseOccupancy
    rates {
      name
      amount
    }
    inclusions {
      quantity
      inclusion {
        name
      }
    }
  }
}

검증 규칙

  • 요금제에 포함되는 모든 Rate는 동일한 accommodationId를 가져야 함
  • roomTypeId가 지정된 경우, 포함된 모든 Rate는 동일한 roomTypeId를 가져야 함

updateAriRate

기존 요금을 수정합니다.

GraphQL Signature

mutation UpdateAriRate($rateId: Int!, $input: UpdateAriRateInput!) {
  updateAriRate(rateId: $rateId, input: $input) {
    id
    name
    code
    amount
    currency
    isBaseRate
    type
    updatedAt
  }
}

파라미터

rateId
Int!
required
수정할 요금 ID
input
UpdateAriRateInput!
required
수정할 필드 (모든 필드 선택적)

예제

mutation {
  updateAriRate(
    rateId: 1
    input: {
      amount: "130000"
      adjustments: [
        {
          multiplier: "1.2"
          adjustment: "5000"
          priority: 0
        }
      ]
    }
  ) {
    id
    amount
    adjustments {
      multiplier
      adjustment
    }
  }
}

검증 규칙

  • 요금 코드 변경 시 중복 검증 실행
  • isBaseRate 변경 시 중복 검증 실행
  • 요금 히스토리가 자동으로 생성됨

updateAriRatePlan

기존 요금제를 수정합니다.

GraphQL Signature

mutation UpdateAriRatePlan($ratePlanId: Int!, $input: UpdateAriRatePlanInput!) {
  updateAriRatePlan(ratePlanId: $ratePlanId, input: $input) {
    id
    name
    code
    baseOccupancy
    maxOccupancy
    checkInAt
    checkOutAt
    updatedAt
  }
}

파라미터

ratePlanId
Int!
required
수정할 요금제 ID
input
UpdateAriRatePlanInput!
required
수정할 필드 (모든 필드 선택적)

예제

mutation {
  updateAriRatePlan(
    ratePlanId: 1
    input: {
      name: "스탠다드 플러스 요금제"
      maxOccupancy: 3
      extraPersonCharge: "25000"
    }
  ) {
    id
    name
    maxOccupancy
    extraPersonCharge
  }
}

검증 규칙

  • roomTypeId 변경 시 포함된 모든 Rate의 roomTypeId와 일치해야 함
  • 요금제 히스토리가 자동으로 생성됨

deleteAriRate

요금을 삭제합니다.

GraphQL Signature

mutation DeleteAriRate($rateId: Int!) {
  deleteAriRate(rateId: $rateId)
}

파라미터

rateId
Int!
required
삭제할 요금 ID

응답

success
Boolean!
삭제 성공 여부

예제

mutation {
  deleteAriRate(rateId: 3)
}

제약 사항

요금제에서 사용 중인 요금은 삭제할 수 없습니다. CANNOT_DELETE_USING_RATE 에러가 발생합니다.

deleteAriRatePlan

요금제를 삭제합니다.

GraphQL Signature

mutation DeleteAriRatePlan($ratePlanId: Int!) {
  deleteAriRatePlan(ratePlanId: $ratePlanId)
}

파라미터

ratePlanId
Int!
required
삭제할 요금제 ID

응답

success
Boolean!
삭제 성공 여부

예제

mutation {
  deleteAriRatePlan(ratePlanId: 2)
}

요금 조정 시스템

AriRateAdjustment

요금 조정은 다음 공식으로 계산됩니다:
최종 요금 = (기본 요금 × multiplier) + adjustment
예시:
  • 기본 요금: 100,000원
  • multiplier: 1.5, adjustment: 10,000원
  • 최종 요금 = (100,000 × 1.5) + 10,000 = 160,000원

채널별 조정

예약 채널에 따라 다른 요금을 적용할 수 있습니다:
channelAdjustments: [
  {
    channelId: 1
    adjustment: {
      multiplier: "0.9"  # 10% 할인
      adjustment: "-5000"
    }
  }
]

기간별 조정

특정 기간에만 적용되는 요금 조정:
adjustments: [
  {
    multiplier: "1.3"
    adjustment: "0"
    periodId: 1  # 성수기 기간
    priority: 1
  }
]

사용 흐름

  1. 요금 생성: createAriRate로 기본 요금 생성
  2. 요금제 생성: createAriRatePlan으로 요금을 포함하는 요금제 생성
  3. 조정 규칙 추가: 채널별, 기간별 조정 규칙 설정
  4. 요금 조회: 고객 예약 시 적용 가능한 요금제 조회
  5. 요금 계산: 조정 규칙을 적용하여 최종 요금 계산

관련 API