> ## Documentation Index
> Fetch the complete documentation index at: https://api-docs.vpms.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 구매 관리 (Purchase)

> 공개 구매 요청 및 결제 처리 API

## 개요

Booking 서비스의 구매 도메인은 공개 구매 요청 생성, 조회, 결제 처리 기능을 제공합니다. MainPay 결제 게이트웨이와의 연동을 통한 온라인 결제를 지원합니다.

## Types

### PublicPurchase

공개 구매 요청 객체

```graphql theme={null}
type PublicPurchase {
  id: ID!
  status: String!
  datePricesToken: String!
  accommodationId: ID!
  roomTypeId: ID!
  useStartAt: Date!
  useExpireAt: Date!
  data: String!
}
```

### MainPayPurchaseSignature

MainPay 결제 서명 정보

```graphql theme={null}
type MainPayPurchaseSignature {
  signature: String!
  timestamp: String!
  mbrRefNo: String!
  mbrNo: String!
  aid: String!
  pcUrl: String!
  mobileUrl: String!
}
```

## Queries

### getAccommodationPublicPurchases

숙박시설의 공개 구매 요청 목록을 페이지네이션하여 조회합니다.

#### GraphQL Signature

```graphql theme={null}
query GetAccommodationPublicPurchases(
  $accommodationId: ID!
  $first: Int
  $after: String
  $last: Int
  $before: String
) {
  getAccommodationPublicPurchases(
    accommodationId: $accommodationId
    first: $first
    after: $after
    last: $last
    before: $before
  ) {
    edges {
      cursor
      node {
        id
        status
        accommodationId
        roomTypeId
        useStartAt
        useExpireAt
      }
    }
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
    totalCount
  }
}
```

#### 파라미터

<ParamField path="accommodationId" type="ID!" required>
  조회할 숙박시설 ID
</ParamField>

<ParamField path="first" type="Int">
  앞에서부터 가져올 항목 수 (forward pagination)
</ParamField>

<ParamField path="after" type="String">
  이 커서 이후의 항목들을 가져옴
</ParamField>

<ParamField path="last" type="Int">
  뒤에서부터 가져올 항목 수 (backward pagination)
</ParamField>

<ParamField path="before" type="String">
  이 커서 이전의 항목들을 가져옴
</ParamField>

#### 예제

<CodeGroup>
  ```graphql Request theme={null}
  query {
    getAccommodationPublicPurchases(
      accommodationId: "01HQKS9V8X2N3P4Q5R"
      first: 10
    ) {
      edges {
        node {
          id
          status
          useStartAt
          useExpireAt
        }
      }
      totalCount
    }
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "getAccommodationPublicPurchases": {
        "edges": [
          {
            "node": {
              "id": "01HQKS9V8X2N3P4Q5R6S7T8U9V",
              "status": "PENDING",
              "useStartAt": "2025-01-15",
              "useExpireAt": "2025-01-16"
            }
          }
        ],
        "totalCount": 25
      }
    }
  }
  ```
</CodeGroup>

***

### getSinglePublicPurchase

단일 공개 구매 요청을 ID로 조회합니다.

#### GraphQL Signature

```graphql theme={null}
query GetSinglePublicPurchase($id: ID!) {
  getSinglePublicPurchase(id: $id) {
    id
    status
    datePricesToken
    accommodationId
    roomTypeId
    useStartAt
    useExpireAt
    data
  }
}
```

#### 파라미터

<ParamField path="id" type="ID!" required>
  조회할 구매 요청 ID
</ParamField>

***

### getAccommodationPgConfig

숙박시설의 PG(결제 게이트웨이) 설정을 조회합니다.

#### GraphQL Signature

```graphql theme={null}
query GetAccommodationPgConfig($accommodationId: ID!) {
  getAccommodationPgConfig(accommodationId: $accommodationId) {
    accommodationId
    data
  }
}
```

#### 파라미터

<ParamField path="accommodationId" type="ID!" required>
  조회할 숙박시설 ID
</ParamField>

## Mutations

### createPublicPurchaseRequest

새로운 공개 구매 요청을 생성합니다.

#### GraphQL Signature

```graphql theme={null}
mutation CreatePublicPurchaseRequest($input: CreatePublicPurchaseRequestInput!) {
  createPublicPurchaseRequest(input: $input) {
    id
    status
    accommodationId
    roomTypeId
    useStartAt
    useExpireAt
  }
}
```

#### 입력 파라미터

```graphql theme={null}
input CreatePublicPurchaseRequestInput {
  datePricesToken: String!
  accommodationId: ID!
  roomTypeId: ID!
  useStartAt: Date!
  useExpireAt: Date!
  person: Int!
  overSleeps: Int!
  request: String
  guestName: String!
  phone: String!
  roomTypeName: String!
  couponUsageHash: String
  claimedDiscountAmount: Int
}
```

<ParamField path="datePricesToken" type="String!" required>
  날짜별 가격 정보 토큰
</ParamField>

<ParamField path="accommodationId" type="ID!" required>
  숙박시설 ID
</ParamField>

<ParamField path="roomTypeId" type="ID!" required>
  객실 타입 ID
</ParamField>

<ParamField path="useStartAt" type="Date!" required>
  사용 시작일
</ParamField>

<ParamField path="useExpireAt" type="Date!" required>
  사용 종료일
</ParamField>

<ParamField path="person" type="Int!" required>
  투숙 인원
</ParamField>

<ParamField path="overSleeps" type="Int!" required>
  추가 인원
</ParamField>

<ParamField path="guestName" type="String!" required>
  투숙객 이름
</ParamField>

<ParamField path="phone" type="String!" required>
  투숙객 연락처
</ParamField>

<ParamField path="roomTypeName" type="String!" required>
  객실 타입 이름
</ParamField>

<ParamField path="request" type="String">
  특별 요청사항
</ParamField>

<ParamField path="couponUsageHash" type="String">
  쿠폰 사용 해시
</ParamField>

<ParamField path="claimedDiscountAmount" type="Int">
  할인 금액
</ParamField>

#### 예제

<CodeGroup>
  ```graphql Request theme={null}
  mutation {
    createPublicPurchaseRequest(input: {
      datePricesToken: "token_12345"
      accommodationId: "01HQKS9V8X2N3P4Q5R"
      roomTypeId: "01HQKS9V8X2N3P4Q5S"
      useStartAt: "2025-01-15"
      useExpireAt: "2025-01-16"
      person: 2
      overSleeps: 0
      guestName: "홍길동"
      phone: "01012345678"
      roomTypeName: "디럭스 더블"
      request: "조용한 방 부탁드립니다"
    }) {
      id
      status
    }
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "createPublicPurchaseRequest": {
        "id": "01HQKS9V8X2N3P4Q5R6S7T8U9V",
        "status": "PENDING"
      }
    }
  }
  ```
</CodeGroup>

***

### requestMainpayPurchaseReady

MainPay 결제를 준비하고 결제 서명을 발급합니다.

#### GraphQL Signature

```graphql theme={null}
mutation RequestMainpayPurchaseReady($input: MainPayPurchaseRequest!) {
  requestMainpayPurchaseReady(input: $input) {
    signature
    timestamp
    mbrRefNo
    mbrNo
    aid
    pcUrl
    mobileUrl
  }
}
```

#### 입력 파라미터

```graphql theme={null}
input MainPayPurchaseRequest {
  publicPurchaseId: ID!
  accommodationId: ID!
  amount: Int!
  goodsName: String!
  name: String!
  phone: String!
  email: String
  redirectionHost: String!
  accommodationName: String!
}
```

<ParamField path="publicPurchaseId" type="ID!" required>
  구매 요청 ID
</ParamField>

<ParamField path="amount" type="Int!" required>
  결제 금액 (원)
</ParamField>

<ParamField path="goodsName" type="String!" required>
  상품명
</ParamField>

<ParamField path="name" type="String!" required>
  구매자 이름
</ParamField>

<ParamField path="phone" type="String!" required>
  구매자 연락처
</ParamField>

<ParamField path="redirectionHost" type="String!" required>
  결제 완료 후 리다이렉션될 호스트 URL
</ParamField>

#### 응답

결제 페이지로 이동하기 위한 서명 정보를 반환합니다.

<ResponseField name="pcUrl" type="String!">
  PC 결제 페이지 URL
</ResponseField>

<ResponseField name="mobileUrl" type="String!">
  모바일 결제 페이지 URL
</ResponseField>

***

### resolveMainpayPurchase

MainPay 결제 결과를 확인하고 처리합니다.

#### GraphQL Signature

```graphql theme={null}
mutation ResolveMainpayPurchase($input: MainPayPurchaseResolve!) {
  resolveMainpayPurchase(input: $input) {
    complete
    resultCode
    resultMessage
  }
}
```

#### 입력 파라미터

<ParamField path="publicPurchaseId" type="ID!" required>
  구매 요청 ID
</ParamField>

<ParamField path="authToken" type="String!" required>
  MainPay 인증 토큰
</ParamField>

#### 응답

<ResponseField name="complete" type="Boolean!">
  결제 완료 여부
</ResponseField>

<ResponseField name="resultCode" type="String!">
  결제 결과 코드
</ResponseField>

<ResponseField name="resultMessage" type="String">
  결제 결과 메시지
</ResponseField>

***

### waitPublicPurchaseResolved

구매 요청이 완료될 때까지 대기하고 예약 객체를 반환합니다.

#### GraphQL Signature

```graphql theme={null}
mutation WaitPublicPurchaseResolved($id: ID!) {
  waitPublicPurchaseResolved(id: $id) {
    id
    # Reservation 필드들
  }
}
```

<Info>
  이 mutation은 결제 완료 후 예약이 생성될 때까지 대기하는 폴링 방식으로 동작합니다.
</Info>

## 결제 흐름

1. **구매 요청 생성**: `createPublicPurchaseRequest`
2. **결제 준비**: `requestMainpayPurchaseReady`로 결제 URL 획득
3. **결제 진행**: 반환된 URL로 사용자를 리다이렉션하여 MainPay 결제 진행
4. **결제 완료**: `resolveMainpayPurchase`로 결제 결과 확인
5. **예약 확인**: `waitPublicPurchaseResolved`로 생성된 예약 조회

## 관련 API

* [예약 API](/api-reference/core-svc/reservation) - 생성된 예약 관리
* [쿠폰 API](/api-reference/core-svc/coupon) - 할인 쿠폰 적용
