diff --git a/.eslintrc.js b/.eslintrc.js index 122d8e3e2b965d861df884841b293af7be1c0f80..34d437930f4335db784ff173a694f6a52cd26e83 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -37,6 +37,7 @@ module.exports = { "semi": ["error", "always"], "object-curly-spacing": ["error", "always"], "space-infix-ops": ["error", { "int32Hint": false }], + "prefer-const": "off", // react.js "react/react-in-jsx-scope": "off", diff --git a/src/_app/App.tsx b/src/_app/App.tsx index 6ff1b23922c0749d83cb6ecf7902e63745de2286..f1dab050c6b499440a033c7bb2309d96e1ee340e 100644 --- a/src/_app/App.tsx +++ b/src/_app/App.tsx @@ -59,7 +59,7 @@ function App() { <Route path={APP_ROUTE.MENU} element={<MenuPage connector={connector} setHeaderName={setHeaderName} />} /> <Route path={APP_ROUTE.CART} element={<CartPage connector={connector} />} /> <Route path={APP_ROUTE.HISTORY} element={<HistoryPage connector={connector} />} /> - <Route path={APP_ROUTE.ORDER.SUCCESS} element={<SuccessPage />} /> + <Route path={APP_ROUTE.ORDER.SUCCESS} element={<SuccessPage connector={connector} />} /> <Route path={APP_ROUTE.ORDER.FAIL} element={<FailPage />} /> <Route path={APP_ROUTE.ORDER.CANCEL} element={<CancelPage />} /> </Routes> diff --git a/src/common/utils/query.ts b/src/common/utils/query.ts new file mode 100644 index 0000000000000000000000000000000000000000..dfccda7783cd376a4b187e3fe9b7515874d19ff4 --- /dev/null +++ b/src/common/utils/query.ts @@ -0,0 +1,10 @@ +function getQueryStrings(search: string, str: string): string { + const queryStrings: any = {}; + const urlParams = new URLSearchParams(search); + urlParams.forEach((value, key) => { + queryStrings[key] = value; + }); + return queryStrings[str]; +} + +export { getQueryStrings }; diff --git a/src/pages/cart-page/CartPage.tsx b/src/pages/cart-page/CartPage.tsx index d34830eaa1735b779aa0c43149e84036d45566a9..6ffc400be4c16aea3587f64128a5c58c1009599a 100644 --- a/src/pages/cart-page/CartPage.tsx +++ b/src/pages/cart-page/CartPage.tsx @@ -23,9 +23,6 @@ const CartPage: FC<Props> = ({ connector }) => { const [quantities, setQuantities] = useState<number[]>([]); const [totalPrice, setTotalPrice] = useState(0); - const a = 1; - const b = 1; - useEffect(() => { setQuantities(cartItem?.menus.map((d) => d.quantity) ?? []); @@ -54,16 +51,23 @@ const CartPage: FC<Props> = ({ connector }) => { if (!cartItem?.shop) return; void (async () => { - const _device = detectDeviceType(); - - const orderRequest = await connector.post<OrderPostModel>('/order', { - shopId: cartItem.shop._id, - items: cartItem.menus.map((d) => ({ menuId: d._id, quantity: d.quantity })), - takeout: cartItem.takeout - }); - - if (_device === DEVICE.MOBILE) window.location.href = orderRequest.next_redirect_mobile_url; - else if (_device === DEVICE.PC) window.location.href = orderRequest.next_redirect_pc_url; + try { + const _device = detectDeviceType(); + + const orderRequest = await connector.post<OrderPostModel>('/order', { + shopId: cartItem.shop._id, + items: cartItem.menus.map((d) => ({ menuId: d._id, quantity: d.quantity })), + takeout: cartItem.takeout + }); + + localStorage.setItem('payment_id', orderRequest.payment_id); + + if (_device === DEVICE.MOBILE) window.location.href = orderRequest.next_redirect_mobile_url; + else if (_device === DEVICE.PC) window.location.href = orderRequest.next_redirect_pc_url; + } catch (e) { + alert('결제요청에 실패하였습니다'); + console.error(e); + } })(); }; diff --git a/src/pages/order-page/cancel-page/CancelPage.tsx b/src/pages/order-page/cancel-page/CancelPage.tsx index fcacfc580bff4fd3dc351914bfeacf17c4fb6ff3..4d303d7754ccc515f22fcecbd425d8d161df7687 100644 --- a/src/pages/order-page/cancel-page/CancelPage.tsx +++ b/src/pages/order-page/cancel-page/CancelPage.tsx @@ -1,4 +1,10 @@ +import { useEffect } from "react"; + const CancelPage = () => { + useEffect(() => { + localStorage.removeItem('payment_id'); + }, []); + return (<div>cancel</div>); }; diff --git a/src/pages/order-page/fail-page/FailPage.tsx b/src/pages/order-page/fail-page/FailPage.tsx index 50903bcf43b6912264ccf035cb01c988e2dfcccc..39e3a4de09de594608b3827a1f1258e6b9205ede 100644 --- a/src/pages/order-page/fail-page/FailPage.tsx +++ b/src/pages/order-page/fail-page/FailPage.tsx @@ -1,5 +1,13 @@ +import { useEffect } from "react"; + const FailPage = () => { - return (<div>fail</div>); + useEffect(() => { + localStorage.removeItem('payment_id'); + }, []); + + return ( + <div>fail</div> + ); }; export default FailPage; diff --git a/src/pages/order-page/success-page/SuccessPage.tsx b/src/pages/order-page/success-page/SuccessPage.tsx index 6c6f05cf77bf0959bfc4a7141c192b6b13cba8d2..1e99e6542b79ece9e35738b67ce2e66370adbbe9 100644 --- a/src/pages/order-page/success-page/SuccessPage.tsx +++ b/src/pages/order-page/success-page/SuccessPage.tsx @@ -1,5 +1,43 @@ -const SuccessPage = () => { - return (<div>suc</div>); +import { useEffect } from "react"; +import { useLocation } from "react-router-dom"; + +import { getQueryStrings } from "../../../common/utils/query"; + +import type { OrderApprovePostModel } from "./config/type"; +import type Connector from "../../../common/instances/Connector"; +import type { FC } from "react"; + +interface Props { + connector: Connector; +} + +const SuccessPage: FC<Props> = ({ connector }) => { + const location = useLocation(); + + useEffect(() => { + if (!location.search) return; + + void (async () => { + try { + await connector.post<OrderApprovePostModel>('/order/approve', { + pg_token: getQueryStrings(location.search, 'pg_token'), + payment_id: localStorage.getItem('payment_id'), + }); + } catch (e) { + alert("결제에 실패하였습니다"); + console.error(e); + } finally { + localStorage.removeItem('payment_id'); + } + })(); + }, [location]); + + + return ( + <div> + Success! + </div> + ); }; export default SuccessPage; diff --git a/src/pages/order-page/success-page/config/type.ts b/src/pages/order-page/success-page/config/type.ts new file mode 100644 index 0000000000000000000000000000000000000000..6919d9791dd417e2e91c75a783f67a7c68bf6827 --- /dev/null +++ b/src/pages/order-page/success-page/config/type.ts @@ -0,0 +1,15 @@ +import type { CartItemPostModel } from "../../../cart-page/config/type"; + +interface OrderApprovePostModel { + "_id": string; + "userId": CartItemPostModel['userId'], + "shopId": CartItemPostModel['shopId'], + "items": CartItemPostModel['items'], + "paymentMethod": CartItemPostModel['paymentMethod'] + "waitingCount": CartItemPostModel['waitingCount'] + "takeout": CartItemPostModel['takeout'] + "totalPrice": CartItemPostModel['totalPrice'] + "createdTime": CartItemPostModel['createdTime'] +} + +export type { OrderApprovePostModel };