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 참고요...
정리를 좀 해보자면,..
requestPayment
메서드에서는 window.IMP.request_pay
함수를 사용해 결제 요청을 보내고,
결제 결과를 처리하는 콜백 함수를 등록한다.
즉, 이 함수의 실행 결과를 기다릴 필요없이 바로 다음 코드를 실행할 수 있다. (비동기 처리를 위해 콜백함수를 사용하고 있다)
requestPayment
메서드는 Promise 객체를 반환하도록 정의되어 있고, 이는 async/await
문법을 사용하기 위함이다.
async, await
문법은 비동기 함수의 처리 결과를 기다렸다가 다음 코드를 실행할 수 있게 해준다.
이를 위해 requestPayment
메서드 내부에서 new Promise()
를 사용한다.
이 함수는 Promise 객체를 생성하며, resolve
와 reject
함수를 인자로 받는다.
성공한 경우 resolve
함수를 호출하여 결제 정보 객체를 전달한다.
실패한 경우 reject
함수를 호출하여 에러를 반환한다.
즉, new Promise()
를 사용하여 콜백 함수를 Promise 객체로 감싸고, 이 Promise 객체를 반환함으로써 콜백 함수를 Promise 객체 형태로 노출시키는 것
이렇게 하면 requestPayment
메서드를 사용하는 쪽에서는 Promise
객체를 반환받아 async/await
문법을 사용하여 Promise 객체의 반환값을 기다렸다가 다음 코드를 실행할 수 있다. (비동기 처리)
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;
},
};
}
프로세스
프론트보다 백에서 처리하는게 더 많아보인다. 결제 프로세스를 정확히 알 필요가 있다.