> ## 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.

# Booking Service API

> 공개 구매 및 결제 처리 API 레퍼런스

## 개요

Booking Service는 VPMS 클러스터의 공개 구매 및 온라인 결제를 담당하는 서비스입니다. 외부 사용자가 웹사이트를 통해 직접 객실을 예약하고 결제할 수 있는 기능을 제공합니다.

## 주요 기능

<CardGroup cols={2}>
  <Card title="구매 요청 관리" icon="shopping-cart">
    공개 구매 요청 생성 및 조회
  </Card>

  <Card title="결제 처리" icon="credit-card">
    MainPay 게이트웨이를 통한 온라인 결제
  </Card>

  <Card title="문의 관리" icon="message">
    고객 문의 및 답변 처리
  </Card>

  <Card title="PG 설정" icon="gear">
    숙박시설별 결제 게이트웨이 설정
  </Card>
</CardGroup>

## API 도메인

### 구매 관리 (Purchase)

공개 구매 요청 및 결제 프로세스를 관리합니다.

* **[구매 API](/api-reference/booking-svc/purchase)**: 공개 구매 요청 생성, 조회, 결제 처리

### 문의 관리 (Inquiry)

고객 문의사항을 관리합니다.

* 문의 등록
* 답변 처리
* 상태 관리

## 기술 스택

* **API 타입**: GraphQL (Apollo Federation)
* **프레임워크**: Fastify + TypeScript
* **데이터베이스**: PostgreSQL + Prisma ORM
* **결제**: MainPay PG 연동

## GraphQL Endpoint

```
POST https://development.vpms.io/graphql
```

<Info>
  GraphQL 공통 설정 및 인증 방법은 [GraphQL 설정 가이드](/api-reference/introduction)를 참고하세요.
</Info>

Booking Service는 Apollo Federation의 서브그래프로 동작하며, API Gateway를 통해 통합된 스키마로 접근할 수 있습니다.

## 공개 구매 흐름

<Steps>
  <Step title="객실 검색">
    사용자가 날짜와 인원을 선택하여 객실 검색
  </Step>

  <Step title="구매 요청 생성">
    [createPublicPurchaseRequest](/api-reference/booking-svc/purchase#createpublicpurchaserequest)로 구매 요청 생성
  </Step>

  <Step title="결제 준비">
    [requestMainpayPurchaseReady](/api-reference/booking-svc/purchase#requestmainpaypurchaseready)로 결제 서명 획득
  </Step>

  <Step title="결제 진행">
    MainPay 결제 페이지로 리다이렉션하여 결제 진행
  </Step>

  <Step title="결제 완료 처리">
    [resolveMainpayPurchase](/api-reference/booking-svc/purchase#resolvemainpaypurchase)로 결제 결과 확인
  </Step>

  <Step title="예약 생성">
    [waitPublicPurchaseResolved](/api-reference/booking-svc/purchase#waitpublicpurchaseresolved)로 예약 생성 확인
  </Step>
</Steps>

## 예제: 공개 구매 프로세스

<CodeGroup>
  ```typescript TypeScript theme={null}
  // 1. 구매 요청 생성
  const createPurchase = async () => {
    const { data } = await client.mutate({
      mutation: gql`
        mutation CreatePurchase($input: CreatePublicPurchaseRequestInput!) {
          createPublicPurchaseRequest(input: $input) {
            id
            status
          }
        }
      `,
      variables: {
        input: {
          datePricesToken: "token_12345",
          accommodationId: "01HQKS9V8X",
          roomTypeId: "01HQKS9V8Y",
          useStartAt: "2025-01-15",
          useExpireAt: "2025-01-16",
          person: 2,
          overSleeps: 0,
          guestName: "홍길동",
          phone: "01012345678",
          roomTypeName: "디럭스 더블"
        }
      }
    });

    return data.createPublicPurchaseRequest.id;
  };

  // 2. 결제 준비
  const preparePayment = async (purchaseId: string) => {
    const { data } = await client.mutate({
      mutation: gql`
        mutation PreparePayment($input: MainPayPurchaseRequest!) {
          requestMainpayPurchaseReady(input: $input) {
            pcUrl
            mobileUrl
            signature
          }
        }
      `,
      variables: {
        input: {
          publicPurchaseId: purchaseId,
          accommodationId: "01HQKS9V8X",
          amount: 150000,
          goodsName: "디럭스 더블 1박",
          name: "홍길동",
          phone: "01012345678",
          redirectionHost: "https://booking.example.com",
          accommodationName: "벤딧 호텔"
        }
      }
    });

    // 결제 페이지로 리다이렉션
    window.location.href = data.requestMainpayPurchaseReady.pcUrl;
  };

  // 3. 결제 완료 처리 (리다이렉션 후)
  const completePayment = async (purchaseId: string, authToken: string) => {
    const { data } = await client.mutate({
      mutation: gql`
        mutation CompletePayment($input: MainPayPurchaseResolve!) {
          resolveMainpayPurchase(input: $input) {
            complete
            resultCode
            resultMessage
          }
        }
      `,
      variables: {
        input: {
          publicPurchaseId: purchaseId,
          authToken: authToken
        }
      }
    });

    if (data.resolveMainpayPurchase.complete) {
      // 예약 확인 페이지로 이동
      return data;
    }
  };
  ```

  ```javascript JavaScript theme={null}
  // 전체 구매 프로세스
  async function completePurchaseFlow() {
    // 1. 구매 요청 생성
    const purchaseResponse = await fetch('https://development.vpms.io/graphql', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        query: `
          mutation CreatePurchase($input: CreatePublicPurchaseRequestInput!) {
            createPublicPurchaseRequest(input: $input) { id }
          }
        `,
        variables: {
          input: {
            // ... 구매 정보
          }
        }
      })
    });

    const { data: { createPublicPurchaseRequest } } = await purchaseResponse.json();
    const purchaseId = createPublicPurchaseRequest.id;

    // 2. 결제 준비 및 리다이렉션
    const paymentResponse = await fetch('https://development.vpms.io/graphql', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        query: `
          mutation PreparePayment($input: MainPayPurchaseRequest!) {
            requestMainpayPurchaseReady(input: $input) {
              pcUrl
            }
          }
        `,
        variables: {
          input: {
            publicPurchaseId: purchaseId,
            // ... 결제 정보
          }
        }
      })
    });

    const { data: { requestMainpayPurchaseReady } } = await paymentResponse.json();
    window.location.href = requestMainpayPurchaseReady.pcUrl;
  }
  ```
</CodeGroup>

## MainPay 결제 연동

Booking Service는 MainPay 결제 게이트웨이와 연동하여 안전한 온라인 결제를 제공합니다.

### 지원 결제 수단

* 신용카드
* 계좌이체
* 가상계좌
* 간편결제

### 결제 보안

* PCI-DSS 준수
* SSL/TLS 암호화 통신
* 결제 서명 검증

## 관련 서비스

* [Core Service](/api-reference/core-svc/introduction) - 예약 및 객실 관리
* [User Service](/api-reference/user-svc/introduction) - 사용자 인증

## 지원

문의사항이 있으시면 [support@vendit.io](mailto:support@vendit.io)로 연락주세요.
