국내선 항공권 API 흐름

1.1 항공권 검색 요청

  • 엔드포인트:
    • GET /flights/search/{originType1}:{origin1}-{destinationType1}:{destination1}/{date1}
    • GET /flights/search/{originType1}:{origin1}-{destinationType1}:{destination1}/{date1}/{originType2}:{origin2}-{destinationType2}:{destination2}/{date2}
  • 컨트롤러: FlightSearchController#search
  • 목적: 출발지, 도착지, 날짜로 항공편을 검색
  • 인증: 불필요
  • 요청 데이터:
    • Path Parameters:
      • originType1: 출발지 타입 (AIRPORT/CITY)
      • origin1: 출발지 코드
      • destinationType1: 도착지 타입 (AIRPORT/CITY)
      • destination1: 도착지 코드
      • date1: 출발 날짜 (YYYY-MM-DD)
      • originType2: 출발지 타입 (AIRPORT/CITY, 왕복인 경우)
      • origin2: 출발지 코드 (왕복인 경우)
      • destinationType2: 도착지 타입 (AIRPORT/CITY, 왕복인 경우)
      • destination2: 도착지 코드 (왕복인 경우)
      • date2: 출발 날짜 (YYYY-MM-DD, 왕복인 경우)
    • Query Parameters:
      • adult: 성인 인원 (필수)
      • child: 소아 인원 (선택, 기본값 0)
      • infant: 유아 인원 (선택, 기본값 0)
      • cabins: 좌석 등급 목록 (필수)
      • freeBaggageOnly: 무료 수하물만 표시 여부 (선택, 기본값 false)
  • 응답 데이터:
    {
      "key": "string",
      "data": {
        "tripType": "ONE_WAY/ROUND_TRIP",
        "routeType": "DOMESTIC/INTERNATIONAL",
        "locations": {
          "string": {
            "type": "AIRPORT/CITY",
            "name": "string",
            "shortName": "string"
          }
        },
        "banners": ["string"]
      }
    }
    • key: 검색 결과 조회를 위한 캐시 키
    • data: 검색 미리보기 정보

1.2 검색 상태 확인

  • 엔드포인트: GET /domestic/flights/search/{listKey}/status
  • 컨트롤러: DomesticFlightSearchController#checkStatus
  • 목적: 검색 결과의 처리 상태 확인
  • 인증: 불필요
  • 요청 데이터:
    • Path Parameters:
      • listKey: 검색 요청 시 생성된 캐시 키 (필수)
  • 응답 데이터:
    {
      "status": "COMPLETE/PENDING/ERROR",
      "data": {
        "listKey": "string"
      }
    }
    • status: 처리 상태 (COMPLETE: 완료, PENDING: 진행중, ERROR: 오류)
    • data: 검색 결과 정보

1.3 운임 목록 조회

  • 엔드포인트: POST /domestic/flights/search/{listKey}
  • 컨트롤러: DomesticFlightSearchController#getFlights
  • 목적: 검색된 항공편의 운임 목록 조회
  • 인증: 불필요
  • 요청 데이터:
    • Path Parameters:
      • listKey: 검색 요청 시 생성된 캐시 키 (필수)
    • Request Body:
      {
        "page": {
          "pageNumber": "number",
          "pageSize": "number"
        },
        "filter": {
          "departureTimes": {
            "startTime": "string (HH:mm)",
            "endTime": "string (HH:mm)"
          },
          "airlines": ["string"],
          "paymentMethods": ["string"],
          "discountTypes": ["string"]
        },
        "sort": "PRICE/DEPARTURE_TIME/ARRIVAL_TIME/FLIGHT_TIME"
      }
  • 응답 데이터:
    {
      "items": [{
        "searchKey": "string",
        "schedule": {
          "marketingCarrier": "string",
          "operatingCarrier": "string",
          "flightNumber": "string",
          "departure": "string",
          "arrival": "string",
          "departureAt": "string (ISO 8601 datetime)",
          "arrivalAt": "string (ISO 8601 datetime)",
          "freeBaggage": {
            "volume": "number",
            "unit": "string"
          },
          "flightTime": "string (ISO 8601 duration)"
        },
        "cabin": "string",
        "discountType": "string",
        "bookingClass": "string",
        "seatAvailability": "number",
        "fares": [{
          "passengerFares": [{
            "type": "string",
            "fare": "number",
            "tax": "number",
            "fuelCharge": "number",
            "discount": "number",
            "total": "number"
          }],
          "adult": "number",
          "child": "number",
          "infant": "number",
          "tags": ["string"]
        }],
        "availablePaymentMethods": ["string"]
      }],
      "listKey": "string",
      "page": {
        "currentPage": "number",
        "pageSize": "number",
        "totalCount": "number"
      },
      "airlines": {
        "string": "string"
      },
      "locations": {
        "string": {
          "code": "string",
          "name": "string",
          "nameEng": "string",
          "type": "string",
          "country": "string",
          "countryEng": "string",
          "city": "string",
          "cityEng": "string",
          "timezone": "string"
        }
      },
      "filter": {
        "filterField": {
          "departureTimes": {
            "startTime": "string (HH:mm)",
            "endTime": "string (HH:mm)"
          },
          "airlines": ["string"],
          "paymentMethods": ["string"],
          "discountTypes": ["string"]
        },
        "researchField": {
          "cabins": ["string"]
        }
      },
      "sort": {
        "defaultSort": "string"
      },
      "bestItems": [{
        // items와 동일한 구조
      }]
    }

1.4 항공편 상세 조회

  • 엔드포인트:
    • GET /domestic/flights/detail/{detailKey1}
    • GET /domestic/flights/detail/{detailKey1}/{detailKey2}
  • 컨트롤러: DomesticFlightDetailController#getFlightDetail
  • 목적: 선택한 항공편의 상세 정보 조회
  • 인증: 불필요
  • 요청 데이터:
    • Path Parameters:
      • detailKey1: 가는 편 검색 키 (필수)
      • detailKey2: 오는 편 검색 키 (왕복인 경우)
    • Query Parameters:
      • adult: 성인 인원 (필수)
      • child: 소아 인원 (선택, 기본값 0)
      • infant: 유아 인원 (선택, 기본값 0)
      • outboundTotalPrice: 가는 편 총 운임 (필수)
      • inboundTotalPrice: 오는 편 총 운임 (왕복인 경우)
  • 응답 데이터:
    {
      "outbound": {
        "key": "string",
        "schedule": {
          "marketingCarrier": "string",
          "operatingCarrier": "string",
          "flightNumber": "string",
          "departure": "string",
          "arrival": "string",
          "departureAt": "string (ISO 8601 datetime)",
          "arrivalAt": "string (ISO 8601 datetime)",
          "freeBaggage": {
            "volume": "number",
            "unit": "string"
          }
        },
        "cabin": "string",
        "discountType": "string",
        "bookingClass": "string",
        "seatAvailability": "number",
        "fares": [{
          "passengerFares": [{
            "type": "string",
            "fare": "number",
            "tax": "number",
            "fuelCharge": "number",
            "discount": "number",
            "total": "number"
          }]
        }],
        "fareRules": [{
          "title": "string",
          "category": "string",
          "content": "string",
          "order": "number"
        }]
      },
      "inbound": {
        // outbound와 동일한 구조
      },
      "tripType": "ONE_WAY/ROUND_TRIP",
      "routeType": "DOMESTIC",
      "locations": {
        "string": {
          "code": "string",
          "name": "string",
          "nameEng": "string",
          "type": "string",
          "country": "string",
          "countryEng": "string",
          "city": "string",
          "cityEng": "string",
          "timezone": "string"
        }
      },
      "airlines": {
        "string": "string"
      },
      "banners": ["string"]
    }

2. 예약 (Booking)

2.1 예약 준비

  • 엔드포인트:
    • GET /domestic/bookings/ready/{outboundKey}
    • GET /domestic/bookings/ready/{outboundKey}/{inboundKey}
  • 컨트롤러: DomesticBookingController#ready
  • 목적: 예약 생성 전 필수 요소 체크
  • 인증: 필요
  • 요청 데이터:
    • Path Parameters:
      • outboundKey: 가는 편 검색 키 (필수)
      • inboundKey: 오는 편 검색 키 (왕복인 경우)
    • Query Parameters:
      • outboundTotalPrice: 가는 편 총 운임 (필수)
      • inboundTotalPrice: 오는 편 총 운임 (왕복인 경우)
      • adult: 성인 인원 (필수)
      • child: 소아 인원 (선택, 기본값 0)
      • infant: 유아 인원 (선택, 기본값 0)
  • 응답 데이터:
    {
      "nameLimitKor": "number",
      "nameLimitEng": "number",
      "outbound": {
        "key": "string",
        "schedule": {
          "marketingCarrier": "string",
          "operatingCarrier": "string",
          "flightNumber": "string",
          "departure": "string",
          "arrival": "string",
          "departureAt": "string (ISO 8601 datetime)",
          "arrivalAt": "string (ISO 8601 datetime)",
          "freeBaggage": {
            "volume": "number",
            "unit": "string"
          }
        },
        "cabin": "string",
        "discountType": "string",
        "bookingClass": "string",
        "seatAvailability": "number",
        "fare": {
          "passengerFares": [{
            "type": "string",
            "fare": "number",
            "tax": "number",
            "fuelCharge": "number",
            "discount": "number",
            "total": "number"
          }]
        },
        "fareRules": [{
          "title": "string",
          "category": "string",
          "content": "string",
          "order": "number"
        }]
      },
      "inbound": {
        // outbound와 동일한 구조
      },
      "fares": [{
        "adultPrice": "number",
        "originAdultPrice": "number",
        "totalPrice": "number"
      }],
      "airlines": {
        "string": "string"
      },
      "locations": {
        "string": {
          "code": "string",
          "name": "string",
          "nameEng": "string",
          "type": "string",
          "country": "string",
          "countryEng": "string",
          "city": "string",
          "cityEng": "string",
          "timezone": "string"
        }
      },
      "tripType": "ONE_WAY/ROUND_TRIP",
      "routeType": "DOMESTIC",
      "reservationUser": {
        "name": "string",
        "mobile": "string",
        "email": "string"
      }
    }

2.2 예약 생성

  • 엔드포인트: POST /domestic/bookings
  • 컨트롤러: DomesticBookingController#create
  • 목적: 예약 생성 요청
  • 인증: 필요
  • 요청 데이터:
    {
      "userName": "string",
      "userMobile": "string",
      "userEmail": "string",
      "outbound": {
        "key": "string",
        "requestTotalPrice": "number",
        "cashRewardDefinitionId": "string"
      },
      "inbound": {
        "key": "string",
        "requestTotalPrice": "number",
        "cashRewardDefinitionId": "string"
      },
      "passengers": [{
        "lastName": "string",
        "firstName": "string",
        "type": "ADULT/CHILD/INFANT",
        "gender": "MALE/FEMALE",
        "birthDate": "string (YYYY-MM-DD)",
        "nationality": "string"
      }]
    }
  • 응답 데이터:
    {
      "key": "string"
    }

2.3 예약 생성 상태 확인

  • 엔드포인트: GET /domestic/bookings/status/{cacheKey}
  • 컨트롤러: DomesticBookingController#checkCreate
  • 목적: 예약 생성 결과 확인
  • 인증: 필요
  • 요청 데이터:
    • Path Parameters:
      • cacheKey: 예약 생성 체크 키 (필수)
  • 응답 데이터:
    {
      "status": "COMPLETE/PENDING/ERROR",
      "data": {
        "outbound": {
          "searchKey": "string",
          "bookingId": "number",
          "paymentTimeLimit": "string (ISO 8601 datetime)"
        },
        "inbound": {
          "searchKey": "string",
          "bookingId": "number",
          "paymentTimeLimit": "string (ISO 8601 datetime)"
        }
      }
    }

3. 결제/발권 (Ticketing)

3.1 결제 준비

  • 엔드포인트: GET /domestic/ticketing/ready
  • 컨트롤러: DomesticTicketingController#ready
  • 목적: 결제/발권 요청 전 필수 요소 체크
  • 인증: 필요
  • 요청 데이터:
    • Query Parameters:
      • outboundBookingId: 가는 편 예약 ID (필수)
      • inboundBookingId: 오는 편 예약 ID (왕복인 경우)
  • 응답 데이터:
    {
      "outbound": {
        "schedule": {
          "marketingCarrier": "string",
          "operatingCarrier": "string",
          "flightNumber": "string",
          "departure": "string",
          "arrival": "string",
          "departureAt": "string (ISO 8601 datetime)",
          "arrivalAt": "string (ISO 8601 datetime)",
          "freeBaggage": {
            "volume": "number",
            "unit": "string"
          },
          "flightTime": "string (ISO 8601 duration)"
        },
        "cabin": "string",
        "bookingClass": "string",
        "passengerFares": [{
          "type": "string",
          "fare": "number",
          "tax": "number",
          "fuelCharge": "number",
          "discount": "number",
          "total": "number"
        }],
        "fareRules": [{
          "title": "string",
          "category": "string",
          "content": "string",
          "order": "number"
        }],
        "cashRewardPrice": "number",
        "discountType": "string"
      },
      "inbound": {
        // outbound와 동일한 구조
      },
      "totalFares": {
        "totalPrice": "number",
        "totalAirPrice": "number",
        "totalOtherTax": "number",
        "totalTicketingFee": "number",
        "totalDiscount": "number",
        "totalFuelCharge": "number"
      },
      "availablePaymentMethods": ["string"],
      "installments": ["number"],
      "paymentTimeLimit": "string (ISO 8601 datetime)",
      "tripType": "ONE_WAY/ROUND_TRIP",
      "routeType": "DOMESTIC",
      "airlines": {
        "string": "string"
      },
      "locations": {
        "string": {
          "code": "string",
          "name": "string",
          "nameEng": "string",
          "type": "string",
          "country": "string",
          "countryEng": "string",
          "city": "string",
          "cityEng": "string",
          "timezone": "string"
        }
      }
    }

3.2 결제 요청

  • 엔드포인트: POST /domestic/ticketing
  • 컨트롤러: DomesticTicketingController#ticketing
  • 목적: 결제/발권 요청
  • 인증: 필요
  • 요청 데이터:
    {
      "bookingIds": ["number"],
      "paymentInfo": {
        "method": "string",
        "cardNumber": "string",
        "expiryMonth": "string",
        "expiryYear": "string",
        "cardHolderName": "string",
        "installment": "number"
      },
      "affiliateKey": "string",
      "referenceUserKey": "string"
    }
  • 응답 데이터:
    {
      "key": "string"
    }

3.3 결제 상태 확인

  • 엔드포인트: GET /domestic/ticketing/status/{cacheKey}
  • 컨트롤러: DomesticTicketingController#checkTicketing
  • 목적: 결제/발권 결과 확인
  • 인증: 필요
  • 요청 데이터:
    • Path Parameters:
      • cacheKey: 결제/발권 체크 키 (필수)
  • 응답 데이터:
    {
      "status": "COMPLETE/PENDING/ERROR",
      "data": null
    }

4. 예약 조회/취소 (Reservation/Cancel)

4.1 예약 상세 조회

  • 엔드포인트: GET /domestic/reservation/bookings/{bookingId}
  • 컨트롤러: DomesticReservationController#getBooking
  • 목적: 예약 상세 정보 조회
  • 인증: 필요
  • 요청 데이터:
    • Path Parameters:
      • bookingId: 예약 ID (필수)
  • 응답 데이터:
    {
      "id": "number",
      "orderNumber": "string",
      "reservationUser": {
        "name": "string",
        "mobile": "string",
        "email": "string"
      },
      "status": "string",
      "tripType": "ONE_WAY/ROUND_TRIP",
      "pnr": "string",
      "subPnr": "string",
      "schedule": {
        "marketingCarrier": "string",
        "operatingCarrier": "string",
        "flightNumber": "string",
        "departure": "string",
        "arrival": "string",
        "departureAt": "string (ISO 8601 datetime)",
        "arrivalAt": "string (ISO 8601 datetime)",
        "freeBaggage": {
          "volume": "number",
          "unit": "string"
        },
        "flightTime": "string (ISO 8601 duration)"
      },
      "passengers": [{
        "id": "number",
        "type": "ADULT/CHILD/INFANT",
        "lastName": "string",
        "firstName": "string",
        "birthDate": "string (YYYY-MM-DD)",
        "canceled": "boolean",
        "fare": {
          "id": "number",
          "airPrice": "number",
          "fuelCharge": "number",
          "otherTax": "number",
          "ticketingFee": "number",
          "sellerDiscount": "number",
          "cardPromotionCashback": "number"
        },
        "gender": "MALE/FEMALE",
        "nationality": "string",
        "ticket": {
          "ticketNumber": "string",
          "issuedAt": "string (ISO 8601 datetime)"
        },
        "refunds": [{
          "type": "string",
          "carrierRefundFee": "number",
          "sellerRefundFee": "number",
          "refundedAt": "string (ISO 8601 datetime)"
        }]
      }],
      "payments": [{
        "id": "number",
        "method": "string",
        "fareType": "string",
        "price": "number",
        "cardNumber": "string",
        "expiryDate": "string",
        "installment": "number",
        "cardHolderBirthDate": "string",
        "approvalNumber": "string",
        "approvedAt": "string (ISO 8601 datetime)",
        "canceledAt": "string (ISO 8601 datetime)"
      }],
      "fareRules": [{
        "title": "string",
        "category": "string",
        "content": "string",
        "order": "number"
      }],
      "cancelable": "boolean",
      "checkInUrlMobile": "string",
      "cancelInProgress": "boolean",
      "ancillaryAvailable": "boolean",
      "createdAt": "string (ISO 8601 datetime)",
      "canceledAt": "string (ISO 8601 datetime)",
      "tasfPaymentReceiptUrl": "string",
      "airPaymentReceiptUrl": "string",
      "routeType": "DOMESTIC",
      "airlines": {
        "string": {
          "iata": "string",
          "name": "string"
        }
      },
      "locations": {
        "string": {
          "code": "string",
          "name": "string",
          "nameEng": "string",
          "type": "string",
          "country": "string",
          "countryEng": "string",
          "city": "string",
          "cityEng": "string",
          "timezone": "string"
        }
      }
    }

4.2 예약 취소 준비

  • 엔드포인트: GET /domestic/reservation/bookings/{bookingId}/cancel-ready
  • 컨트롤러: DomesticReservationController#expectedRefundFee
  • 목적: 환불 시 예상되는 수수료 조회
  • 인증: 필요
  • 요청 데이터:
    • Path Parameters:
      • bookingId: 예약 ID (필수)
  • 응답 데이터:
    {
      "totalPrice": "number",
      "refundFees": [{
        "passenger": {
          "id": "number",
          "type": "ADULT/CHILD/INFANT",
          "lastName": "string",
          "firstName": "string",
          "birthDate": "string (YYYY-MM-DD)",
          "canceled": "boolean",
          "fare": {
            "id": "number",
            "airPrice": "number",
            "fuelCharge": "number",
            "otherTax": "number",
            "ticketingFee": "number",
            "sellerDiscount": "number",
            "cardPromotionCashback": "number"
          },
          "gender": "MALE/FEMALE",
          "nationality": "string"
        },
        "refundFee": "number",
        "tasfRefundFee": "number"
      }],
      "paymentMethod": "string"
    }

4.3 예약 취소

  • 엔드포인트: POST /domestic/reservation/bookings/{bookingId}/cancel
  • 컨트롤러: DomesticReservationController#cancel
  • 목적: 예약 취소 요청
  • 인증: 필요
  • 요청 데이터:
    • Path Parameters:
      • bookingId: 예약 ID (필수)
  • 응답 데이터:
    {
      "key": "string"
    }

4.4 예약 취소 상태 확인

  • 엔드포인트: GET /domestic/reservation/bookings/{bookingId}/status-cancel
  • 컨트롤러: DomesticReservationController#checkCancel
  • 목적: 예약 취소 결과 확인
  • 인증: 필요
  • 요청 데이터:
    • Path Parameters:
      • bookingId: 예약 ID (필수)
  • 응답 데이터:
    {
      "status": "COMPLETE/PENDING/ERROR",
      "data": {
        "status": "string"
      }
    }

4.5 예약 취소 문서 요청

  • 엔드포인트: POST /domestic/reservation/bookings/{bookingId}/cancel-document
  • 컨트롤러: DomesticReservationController#cancelDocument
  • 목적: 예약 취소 문서 요청
  • 인증: 필요
  • 요청 데이터:
    • Path Parameters:
      • bookingId: 예약 ID (필수)
  • 응답 데이터:
    {
      "status": "OK"
    }

주의사항

  • 각 단계별로 필요한 데이터 검증이 필요합니다.
  • 각 단계는 이전 단계의 완료가 필요합니다.
  • 예약조회는 언제든지 가능합니다.
  • 발권은 예약 완료 후에만 가능합니다.
  • 국내선 API는 /domestic 경로를 사용합니다.
  • 인증이 필요한 API는 회원 또는 비회원 인증이 필요합니다.
  • 예약 취소 전에 반드시 예약 동기화 API를 호출하여 최신 스케줄 정보를 확인해야 합니다.
  • 비동기 처리 시 폴링을 통한 상태 확인이 필요합니다.

에러 처리

  • 각 단계별 적절한 에러 코드와 메시지를 반환합니다.
  • 네트워크 오류, 서버 오류, 비즈니스 로직 오류를 구분하여 처리합니다.
  • 사용자에게 명확한 에러 메시지를 제공합니다.
  • 비동기 처리 시 폴링을 통한 상태 확인이 필요합니다.

관련 문서