# 3. 배송 및 결제 정보 전달

```js
const PG_CODE = process.env.PORTONE_PG_CODE || "";

export default class PaymentService {
  instance = Reflect.get(window, "IMP");

  async requestPayment({
    //
    merchantId,
    product,
    buyer,
  }: {
    merchantId: string,
    product: Product,
    buyer?: Buyer,
  }): Promise<{
    merchantId: string,
    transactionId: string,
  }> {
    return new Promise((resolve, reject) => {
      // 콜백이다. await이 아닌 Promsie가 쓰임. 패턴처럼 외우면 된다함.
      this.instance.request_pay(
        {
          pg: PG_CODE,
          pay_method: "card",
          merchant_uid: merchantId,
          name: product.name,
          amount: product.price,
          buyer_email: buyer?.email,
          buyer_name: buyer?.name,
          buyer_tel: buyer?.phoneNumber,
          buyer_addr: buyer?.address,
          buyer_postcode: buyer?.postalCode,
        },
        (response: PaymentResponse) => {
          if (response.success) {
            resolve({
              merchantId: response.merchant_uid,
              transactionId: response.imp_uid ?? "",
            });
          } else {
            reject(Error(response.error_msg));
          }
        }
      );
    });
  }
}

export const paymentService = new PaymentService();
```

resolve가 들어오면 일반 async 함수 리턴한거,

reject는 Error(response.error\_msg)를 throw 한 거랑 똑같은 효과라 함.

아무튼 성공, 실패에 따라 결과가 다른 Promise를 리턴한다.

원래 async await이 아니고 일반 callback인건데 async await으로 변환하는데 new Promise로 해준다고..

mdn promise 참고요...

***

## 정리를 좀 해보자면,..

1. `requestPayment` 메서드에서는 `window.IMP.request_pay` 함수를 사용해 결제 요청을 보내고,

결제 결과를 처리하는 콜백 함수를 등록한다.

즉, 이 함수의 실행 결과를 기다릴 필요없이 바로 다음 코드를 실행할 수 있다. (비동기 처리를 위해 콜백함수를 사용하고 있다)

2. `requestPayment` 메서드는 Promise 객체를 반환하도록 정의되어 있고, 이는 `async/await` 문법을 사용하기 위함이다.

`async, await` 문법은 비동기 함수의 처리 결과를 기다렸다가 다음 코드를 실행할 수 있게 해준다.

이를 위해 `requestPayment` 메서드 내부에서 `new Promise()`를 사용한다.

3. 이 함수는 Promise 객체를 생성하며, `resolve`와 `reject` 함수를 인자로 받는다.

성공한 경우 `resolve` 함수를 호출하여 결제 정보 객체를 전달한다.

실패한 경우 `reject` 함수를 호출하여 에러를 반환한다.

즉, `new Promise()`를 사용하여 콜백 함수를 Promise 객체로 감싸고, 이 Promise 객체를 반환함으로써 `콜백 함수를 Promise 객체 형태로 노출시키는 것`

이렇게 하면 `requestPayment` 메서드를 사용하는 쪽에서는 `Promise` 객체를 반환받아 `async/await` 문법을 사용하여 Promise 객체의 반환값을 기다렸다가 다음 코드를 실행할 수 있다. (비동기 처리)

```js
export default function usePayment(cart: Cart) {
  return {
    async requestPayment() {
      const now = new Date();
      const date = now.toISOString().slice(0, 10).replace(/-/g, "");
      const time = now.getTime();
      const nonce = Math.random().toString().slice(-5);
      const merchantId = `ORDER-${date}-${time}${nonce}`;

      const result = await paymentService.requestPayment({
        merchantId,
        product: {
          name: cart.lineItems[0].product.name,
          price: cart.totalPrice,
        },
      });

      return result;
    },
  };
}
```

## 프로세스

프론트보다 백에서 처리하는게 더 많아보인다. 결제 프로세스를 정확히 알 필요가 있다.
