본문 바로가기

E-commerce Vanila JS [11편] 결제단계

by Recstasy 2021. 12. 13.

결제 구현단계는 크게 '인증 - 배송 입력 - 결제 - 결제확인'  4단계로 이뤄진다. 

 

 

1 결제단계 :: Shipping

1) CheckoutSteps.js 생성

- 결제 단계마다 UI를 변경하는 컴포넌트 'CheckoutSteps.js'를 components/폴더 아래 생성한다.

 


 
  const
 CheckoutSteps = {
        render: (props) => {
            return `
                <div class="checkout-steps">
                    <div class="${props.step1 ? 'active' : '' }"> Signin </div>
                    <div class="${props.step2 ? 'active' : '' }"> Shipping </div>
                    <div class="${props.step3 ? 'active' : '' }"> Payment </div>
                    <div class="${props.step4 ? 'active' : '' }"> Place Order </div>
                </div>
            `;
          },
     };

    export default CheckoutSteps;

[ root\frontend\src\components\CheckoutSteps.js ]  

 

 

2) utils.js(frontend) 추가

- 로그인 혹은 회원가입 후, 로컬 스토러지에 장바구니 정보가 있다면 계속 결제단계를 진행할 수 있는 기능을 구현한다.

 


    import
 { getCartItems } from './localStorage' // 추가

  // 중략...

    export
 const redirectUser = () => {
        if(getCartItems().length !== 0){
            document.location.hash = '/shipping';
        }else{
            document.location.hash = '/';
        }
    };

[ root\frontend\src\utils.js ]  

 

 

3) SigninScreen.js || RegisterScreen.js 수정

- 장바구니에 물품을 담아둔 상태에서 로그인, 회원가입이 진행되었을 경우에는 redirectUser( )를 통해 배송단계 혹은 초기 페이지가 결정되어야 한다.

 

    import { signin } from '../api';
    import { getUserInfo, setUserInfo } from '../localStorage';
    import { showLoading, hideLoading, showMessage, redirectUser } from '../utils'// redirectUser 추가
   
    const SigninScreen = {
        after_render: () => {
            document.getElementById('signin-form')
            .addEventListener('submit', async(e) => {
                e.preventDefault();
                showLoading();
   
                const data = await signin({
                    email: document.getElementById('email').value,
                    password: document.getElementById('password').value,
                });
   
                hideLoading();
               
                if(data.error){
                    showMessage(data.error);
                }else{
                    setUserInfo(data);
                    //삭제 document.location.hash = '/';
                    redirectUser();
                }
            })
        },
        render: () => {
            if(getUserInfo().name){
                // 삭제 document.location.hash = '/';
                redirectUser();
            }

[ root\frontend\src\screens\SigninScreen.js ]  

 

 

RegisterScreen.js 역시 수정한다.


   
import { register } from '../api';
    import { getUserInfo, setUserInfo } from '../localStorage';
    import { showLoading, hideLoading, showMessage, redirectUser } from '../utils'// redirectUser 추가
   
    const RegisterScreen = {
        after_render: () => {
            document.getElementById('register-form')
            .addEventListener('submit', async(e) => {
                e.preventDefault();
                showLoading();
   
                const data = await register({
                    name: document.getElementById('name').value,
                    email: document.getElementById('email').value,
                    password: document.getElementById('password').value,
                });
   
                hideLoading();
               
                if(data.error){
                    showMessage(data.error);
                }else{
                    setUserInfo(data);
                    // 삭제 document.location.hash = '/';
                    redirectUser();
                }
            })
        },
        render: () => {
            if(getUserInfo().name){
                // 삭제 document.location.hash = '/';
                redirectUser();
            }

[ root\frontend\src\screens\RegisterScreen.js ]  

 

 

4) localStorage.js 추가

- 사용자가 입력한 배송폼 정보를 로컬 스토러지에 저장한다.

 


  // 중략...

   
export const getShipping = () => {
        const shipping = localStorage.getItem('shipping')
                        ? JSON.parse(localStorage.getItem('shipping'))
                        : {
                            address: '',
                            city: '',
                            postalCode: '',
                            country: '',
                        }
                        return shipping;
    }
   
    export const setShipping = ({
        address = '',
        city = '',
        postalCode = '',
        country= '',
    }) => {
        localStorage.setItem(
            'shipping',
            JSON.stringify({ address, city, postalCode, country })
        );
    }

[ root\frontend\src\localStorage.js ]  

 

 

5) ShippingScreen.js 생성

- 사용자가 배송관련 정보를 입력하는 폼을 랜더링한다.

 


   
import { getUserInfo, getShipping, setShipping } from '../localStorage';
    import CheckoutSteps from '../components/CheckoutSteps';
   
    const ShippingScreen = {
        after_render: () => {
            document.getElementById('shipping-form')
                    .addEventListener('submit', async(e) => {
                        e.preventDefault();
                        setShipping({
                            address: document.getElementById('address').value,
                            city: document.getElementById('city').value,
                            postalCode: document.getElementById('postalCode').value,
                            country: document.getElementById('country').value,
                        });
                        document.location.hash = '/payment';
                    })
        },
        render: () =>{
            const {name} = getUserInfo();
            if(!name){
                document.location.hash = '/';
            }
   
            const { address, city, postalCode, country } = getShipping();
            return `
                ${CheckoutSteps.render({ step1: true, step2: true })}
                <div class="form-container">
                    <form id="shipping-form">
                        <ul class="form-items">
                            <li>
                                <h1>Shipping</h1>
                            </li>
                            <li>
                                <label for="address">Adress</label>
                                <input type="text" name="address" id="address" value="${address}" />
                            </li>
                            <li>
                                <label for="city">City</label>
                                <input type="text" name="city" id="city" value="${city}" />
                             </li>
                             <li>
                                <label for="postalCode">Postal Code</label>
                                <input type="text" name="postalCode" id="postalCode" value="${postalCode}" />
                             </li>
                             <li>
                                <label for="country">Country</label>
                                <input type="text" name="country" id="country" value="${country}" />
                             </li>
                            <li>
                                <button type="submit" class="primary">Continue</button>
                            </li>
                        </ul>
                    </form>
                </div>
            `
        }
    }
   
    export default ShippingScreen;

[ root\frontend\src\screens\ShippingScreen.js ]  

 

 

6) index.js 추가

- /shipping 라우터를 추가한다.

 

 
  // 중략...
    import RegisterScreen from './screens/RegisterScreen';
    import ProfileScreen from './screens/ProfileScreen';
    import ShippingScreen from './screens/ShippingScreen' // 추가
   
    const routes = {
        '/' : HomeScreen,
        '/product/:id':ProductScreen,
        '/cart/:id': CartScreen,
        '/cart': CartScreen,
        '/signin': SigninScreen,
        '/register': RegisterScreen,
        '/profile': ProfileScreen,
        '/shipping': ShippingScreen,  // 추가
    }
   
    const router = async() => {
        showLoading();

  // 중략...

[ root\frontend\src\index.js ]  

 

 

7) style.css 추가

- 구매버튼 GUI를 수정한다.

 


  /* Checkout */
      .checkout-steps{
        display:flex;
        justify-content: space-between;
        width: 40rem;
        margin: 1rem auto;
    }
   
    .checkout-steps{
        border-top: 0.3rem #c0c0c0 solid;
        color: #c0c0c0;
        flex: 1 1;
        padding-top: 1rem;
    }
   
    .checkout-steps > div.active{
        color: #f08000;
        border-top-color:#f08000;
    }

[ root\frontend\style.css ]  

 

 

실행했을 때, 배송폼까지 진행한 단계는 아래와 같다.

 

 

 

 

[ 배송단계 ]  

 

 

 

2 결제단계 :: Payment

1) PaymentScreen.js 생성

- 작업의 효율성을 위해서 ShippingScreen.js를 복사한 뒤, 'Shipping'검색어를 'Payment'로 변경한다.

 

[ root\frontend\src\screens\PaymentScreen.js ]

 

 


    
import { getUserInfo, setPayment } from '../localStorage';
    import CheckoutSteps from '../components/CheckoutSteps';
   
    const PaymentScreen = {
        after_render: () => {
            document.getElementById('Payment-form')
                    .addEventListener('submit', async(e) => {
                        e.preventDefault();
                        const paymentMethod = document.querySelector(
                            'input[name="payment-method"]:checked'
                        ).value;
                        setPayment({ paymentMethod });
                        document.location.hash = '/placeorder';
                    });
        },
        render: () =>{
            const {name} = getUserInfo();
            if(!name){
                document.location.hash = '/';
            }
   
            return `
                ${CheckoutSteps.render({ step1: true, step2: true, step3: true })}
                <div class="form-container">
                    <form id="Payment-form">
                        <ul class="form-items">
                            <li>
                                <h1>Payment</h1>
                            </li>
   
                            <li>
                               <div>
                                    <input type="radio"
                                        name="payment-method"
                                        id="paypal"
                                        value="Paypal"
                                        checked
                                    />
                                    <label for="paypal">PayPal</label>
                               </div>
                             </li>
   
                             <li>
                                <div>
                                   <input type="radio"
                                       name="payment-method"
                                       id="stripe"
                                       value="Stripe"
                                   />
                                   <label for="stripe">Stripe</label>
                                </div>
                             </li>
   
                             <li>
                                <button type="submit" class="primary">Continue</button>
                             </li>
                        </ul>
                    </form>
                </div>
            `
        }
    }
   
    export default PaymentScreen;

[ root\frontend\src\screens\PaymentScreen.js ] 

 

 

 

 

2) localStorage.js 추가

- getPayment, setPayment 함수를 추가한다.

 


  // 중략...

    export const getPayment = () => {
        const payment = localStorage.getItem('payment')
        ? JSON.parse(localStorage.getItem('payment'))
        : {
            paymentMethod: 'paypal',
        };
        return payment;
    };
   
    export const setPayment = ({ paymentMethod = 'paypal' }) => {
        localStorage.setItem( 'payment', JSON.stringify({ paymentMethod }));
    };

[ root\frontend\src\localStorage.js ]  

 

 

3) index.js 수정

- '/payment' 라우터를 추가한다.

 

 
  // 중략...
    import ShippingScreen from './screens/ShippingScreen';
    import PaymentScreen from './screens/PaymentScreen'// 추가
   
    const routes = {
        '/' : HomeScreen,
        '/product/:id':ProductScreen,
        '/cart/:id': CartScreen,
        '/cart': CartScreen,
        '/signin': SigninScreen,
        '/register': RegisterScreen,
        '/profile': ProfileScreen,
        '/shipping': ShippingScreen,
        '/payment': PaymentScreen,    // 추가
    }
   
    const router = async() => {
        showLoading();
  // 중략...

[ root\frontend\src\index.js ] 

 

 

 

 

 

 


3 결제단계 :: PlaceOrder

1) PlaceOrderScreen.js 생성

- 결제의 마지막 단계는 합계, 총합, 세금, 기타 가격의 총합을 고객에게 보여준다.

 


 
import { getCartItems, getShipping, getPayment, cleanCart } from '../localStorage';
  import CheckoutSteps from '../components/CheckoutSteps';
 
 
  const convertCartToOrder = () =>{
      const orderItems = getCartItems();
      if(orderItems.length === 0){
          document.location.hash = '/cart';
      }
      const shipping = getShipping();
      if(!shipping.address){
          document.location.hash = '/shipping';
      }
      const payment = getPayment();
      if(!payment.paymentMethod){
          document.location.hash = '/payment';
      }
      const itemsPrice = orderItems.reduce( (a, c) => a + c.price * c.qty, 0);
      const shippingPrice = itemsPrice > 100 ? 0 : 10;
      const taxPrice = Math.round(0.15 * itemsPrice * 100) / 100;
      const totalPrice = itemsPrice + shippingPrice + taxPrice;
      return {
          orderItems,
          shipping,
          payment,
          itemsPrice,
          shippingPrice,
          taxPrice,
          totalPrice
      }
  }
 
  const PlaceOrderScreen = {
      after_render: () => {
      },
      render: () =>{
          const {
              orderItems,
              shipping,
              payment,
              itemsPrice,
              shippingPrice,
              taxPrice,
              totalPrice
          } = convertCartToOrder();
 
          return `
              <div>
              ${CheckoutSteps.render({
                  step1: true,
                  step2: true,
                  step3: true,
                  step4: true
              })}
 
              <div class="order">
                  <div class="order-info">
                      <div>
                          <h2>Shipping</h2>
                          <div>
                              ${shipping.address}, ${shipping.city}, ${shipping.postalCode},
                              ${shipping.country}
                          </div>
                      </div>
                      <div>
                          <h2>Payment</h2>
                              <div>
                                  Payment Method: ${payment.paymentMethod}
                              </div>
                      </div>
                      <div>
                          <ul class="cart-list-container">
                              <li>
                                  <h2>Shopping Cart</h2>
                                  <div>Price</div>
                              </li>
                          ${orderItems.map(item => `
                              <li>
                                  <div class="cart-image">
                                      <img src="${item.image}" alt="${item.name}">
                                  </div>
                                  <div class="cart-name">
                                      <div>
                                          <a href="/#/product/${item.product}">${item.name} </a>
                                      </div>
                                      <div> Qty: ${item.qty} </div>
                                  </div>
                                  <div class="cart-price"> $${item.price}<div>
                              </li>
                          `).join('\n')}
                          </ul>
                      </div>
                  </div>
                  <div class="order-action">
                      <ul>
                          <li>
                              <h2>Order Summary</h2>
                          </li>
                          <li><div>Items</div><div>$${itemsPrice}</div></li>
                          <li><div>Shipping</div><div>$${shippingPrice}</div></li>
                          <li><div>Tax</div><div>$${taxPrice}</div></li>
                          <li class="total"><div>Order Total</div><div>$${totalPrice}</div></li>
                          <li>
                              <button id="placeorder-button" class="primary fw">Place Order</button>
                          </li>
                      </ul>
                  </div>
              </div>
          `;
      },
  };
 
  export default PlaceOrderScreen;

[ root\frontend\src\screens\PlaceOrder.js ] 

 

 

2) index.js 수정

- '/placeorder' 라우터를 추가한다.

 

 
  // 중략...
    import ShippingScreen from './screens/ShippingScreen';
    import PaymentScreen from './screens/PaymentScreen';
   
import PlaceOrder from './screens/PlaceOrderScreen';    // 추가
   
    const routes = {
        '/' : HomeScreen,
        '/product/:id':ProductScreen,
        '/cart/:id': CartScreen,
        '/cart': CartScreen,
        '/signin': SigninScreen,
        '/register': RegisterScreen,
        '/profile': ProfileScreen,
        '/shipping': ShippingScreen,
        '/payment': PaymentScreen
        '/placeorder': PlaceOrder,     // 추가
    }
   
    const router = async() => {
        showLoading();
  // 중략...


[ root\frontend\src\index.js ] 

 

3) style.css 추가

- 주문합계 css를 추가한다.

 

  /* Order */
    .order{
        display:flex;
        flex-wrap:wrap;
        padding: 1rem;
        justify-content: space-between;
    }
   
    .order h2{
        margin: 0;
        font-size: 2rem;
        padding-bottom: 1rem;
    }
   
    .order-info{
        flex: 3 1 60rem;
    }
   
    .order .cart-list-container{
        padding: 0;
    }
   
    .order-info > div{
        border:0.1rem #c0c0c0 solid;
        border-radius: 0.5rem;
        background-color:#fcfcfc;
        padding: 1rem;
        margin: 1rem;
    }

    .order-info > div:first-child{
        margin-top:0;
    }

   
    .order-info > div > div{
        padding: 1rem;
    }
   
    .order-action{
        flex: 1 1 20rem;
        border:0.1rem #c0c0c0 solid;
        border-radius:0.5rem;
        background-color:#fcfcfc;
        padding: 1rem;
    }
   
    .order-action > ul{
      padding: 0;
      list-style-type:none;
    }
   
    .order-action li{
        display:flex;
        justify-content: space-between;
        margin-bottom: 1rem;
    }
   
    .order-action .total{
        font-size: 2rem;
        font-weight: bold;
        color: #c04000;
    }

[ root\frontend\src\localStorage.js ] 

 

 

4) localStorage.js추가

- cleanCart( ) 추가하기

 


  // 중략...
   
    localStorage.setItem('payment', JSON.stringify({ paymentMethod }))
  };
 
  export const cleanCart = () => {
      localStorage.removeItem('cartItems');
  }

[ root\frontend\src\localStorage.js ] 

 

 

5) api.js

- 페이팔 버튼을 클릭했을 때, POST방식으로 페이팔 서버와 데이터를 주고받을 수 있는 라우터가 필요하다. api.js는 프론트와 벡앤드의 가교 역할을 하는만큼 createOrder( )를 생성해서 결제 데이터를 페이팔에 전달해주는 기능을 구현한다. 

 


  // 중략...
  }

  export const createOrder = async(order) => {
      try{
          const { token } = getUserInfo();
          const response = await axios({
              url: `${apiUrl}/api/orders`,
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json',
                  Authorization: `Bearer ${token}`,
              },
              data: order,
          });
          if(response.statusText !== 'Created'){
              throw new Error(response.data.message);
          }
          return response.data;
      }catch(err){
          return { error: err.response ? err.response.data.message : err.message }
      }
  }

[ root\frontend\src\api.js ] 

 

 

6) orderModel.js

- 서버에 저장할 때 사용하는 사용자 주문정보 스키마를 생성한다.

 

 

 
import mongoose from 'mongoose';
 
  const orderSchema = new mongoose.Schema({
          orderItems:[
              {
                  name:{type: String, required: true},
                  image:{type: String, required: true},
                  price:{type: Number, required: true},
                  qty:{type: Number, required: true},
                  product:{
                      type: String,
                      ref: 'Product',
                      required: true,
                  },
              }
          ],
          user: {
              type: String,
              ref: 'User',
              required: true,
          },
          shipping:{
              address: String,
              city: String,
              postalCode: String,
              country: String,
          },
          payment: {
              paymentMethod: String,
              paymentResult: {
                  orderID: String,
                  payerID: String,
                  paymentID: String,
              },
          },
          itemsPrice: Number,
          taxPrice: Number,
          shippingPrice: Number,
          totalPrice: Number,
          isPaid: { type: Boolean, required: true, default: false },
          paidAt: Date,
          isDelivered: { type: Boolean, required: true, default: false },
          deliveredAt: Date,
      },
      {
          timestamps: true,
      }
  );
 
  const Order = mongoose.model('Order', orderSchema);
  export default Order;

[ root\backend\models\orderModel.js ] 

 

 

7) orderRouter.js 생성

- 사용자 주문정보가 서버에 저장되도록 orderRouter.js를 생성한다.

 


 
import express from 'express';
  import expressAsyncHandler from 'express-async-handler';
  import { isAuth } from '../utils';
  import Order from '../models/orderModel';
 
  const orderRouter = express.Router();
 
  orderRouter.post(
      '/',
      isAuth,
      expressAsyncHandler( async(req, res) => {
          const order = new Order({
              orderItems: req.body.orderItems,
              user: req.user._id,
              shipping: req.body.shipping,
              payment: req.body.payment,
              itemPrice: req.body.itemPrice,
              taxPrice: req.body.taxPrice,
              shippingPrice: req.body.shippingPrice,
              totalPrice: req.body.totalPrice,
          });
          const createOrder = await order.save();
          res.status(201).send({ message: 'New order created', data: createdOrder })
      })
  );
 
  export default orderRouter;

[ root\backend\routers\orderRouter.js ] 

 

 

8) server.js 추가

- 'api/orders' 서버쪽 라우터를 추가한다.

 


  // 중략...
  import userRouter from './routers/userRouter';
  import orderRouter from './routers/orderRouter'// 추가
 
  dbMain().then( () => {
      console.log('Connected to mongoDB');
  }).catch( err => console.log(err) );
 
  async function dbMain(){
      await mongoose
              .connect( config.MONGODB_URL, {
                  useNewUrlParser: true,
                  useUnifiedTopology: true
              })
  }
 
  const app = express();
 
  app.use(cors());
  app.use(bodyParser.json());
  app.use('/api/users', userRouter );
  app.use('/api/orders', orderRouter );     // 추가
  app.get('/api/products', (req, res) => {
   
  // 중략...


[ root\backend\server.js ] 

 

 

9) data.js 수정

- token값이 24자리에 맞게끔 data.js의 _id를 24자리로 맞춰준다.

 

  export default {
      products:[
          {
              _id: '111111111111111111111111'// 수정
              name: 'tree01 3d model',
              category: 'Nature',
              image: '/images/tree_modeling.jpg',
              price: 1.2,
              size: '3.1mb',

            // 중략...
          },
          {

[ root\backend\data.js ] 

 

 

 

 

 

 


4 결제단계 :: Order

1) OrderScreen.js 생성

- 'OrderScreen.js'는 주문 결과창을 랜더링하는 기능을 구현한다.

 


 
import { parseRequestUrl } from '../utils';
  import { getOrder } from '../api';
 
  const OrderScreen = {
      after_render:async() => {},
      render:async() => {
          const request = parseRequestUrl();
          const {
              _id,
              shipping,
              payment,
              orderItems,
              itemsPrice,
              shippingPrice,
              taxPrice,
              totalPrice,
              isDelivered,
              deliveredAt,
              isPaid,
              paidAt,
         
          } = await getOrder(request.id);
      return `
          <div>
              <h1>Order ${_id}</h1>
              <div class="order">
                  <div class="order-info">
                      <div>
                          <h2>Shipping</h2>
                          <div>
                              ${shipping.address}, ${shipping.city}, ${shipping.postalCode},
                              ${shipping.country}
                          </div>
                              ${
                            isDelivered
                            ? `<div class="success"> Delivered at ${deliveredAt}</div>`
                            : `<div class="error"> Not Delivered </div>`
                            }
                      </div>
                      <div>
                          <h2>Payment</h2>
                          <div>
                              Payment Method: ${payment.paymentMethod}
                          </div>
                              ${
                              isPaid
                              ? `<div class="success"> Paid at ${paidAt}</div>`
                              : `<div class="error"> Not Paid </div>`
                              }
                      </div>
                      <div>
                          <ul class="cart-list-container">
                              <li>
                                  <h2>Shopping Cart</h2>
                                  <div>Price</div>
                              </li>
                          ${
                          orderItems.map(item => `
                              <li>
                                  <div class="cart-image">
                                      <img src="${item.image}" alt="${item.name}">
                                  </div>
                                  <div class="cart-name">
                                      <div>
                                          <a href="/#/product/${item.product}">${item.name} </a>
                                      </div>
                                      <div> Qty: ${item.qty} </div>
                                  </div>
                                  <div class="cart-price"> $${item.price}<div>
                              </li>
                          `).join('\n')}
                          </ul>
                      </div>
                  </div>
                  <div class="order-action">
                      <ul>
                          <li>
                              <h2>Order Summary</h2>
                          </li>
                          <li>
                              <div>Items</div>
                              <div>$${itemsPrice}</div>
                          </li>
                          <li>
                              <div>Shipping</div>
                              <div>$${shippingPrice}</div>
                          </li>
                          <li>
                              <div>Tax</div>
                              <div>$${taxPrice}</div>
                          </li>
                          <li class="total">
                              <div>Order Total</div>
                              <div>$${totalPrice}</div>
                          </li>             
                           <li>
                               <div class="fw" id="paypal-button">
                               </div>
                           </li>
                       </ul>
                  </div>
              </div>
          </div>
          `;
      },
  };
 
  export default OrderScreen;

[ root\frontend\src\screens\OrderScreen.js ] 

 

 

2) orderRouter.js 생성

- orderRouter.js는 주문정보가 서버에 저장되는 POST방식의 라우팅 뿐만 아니라 사용자 ID를 쿼리한 GET방식으로 정보를 받을 수 있어야 한다. 아래 코드를 추가하자.

 

  // 중략...
  import Order from '../models/orderModel';

  const orderRouter = express.Router();
 
  // <-- 추가

  orderRouter.get('/:id', isAuth, expressAsyncHandler( async(req, res) => {
      const order = await Order.findById(req.params.id);
      if(order){
          res.send(order);
      }else{
          res.status(400).send({
              message: 'Order Not Found'
          })
      }
  }));

  // 추가-->

  orderRouter.post(
    '/',
 
  // 중략...

[ root\backend\routers\orderRouter.js ] 

 

 

3) api.js 추가

- OrderScreen.js는 다음과 같이 getOrder( )메서드로 서버에서 사용자id관련 주문정보를 받고 있다. 

 


 
import { parseRequestUrl } from '../utils';
  import { getOrder } from '../api';
 
  const OrderScreen = {
      after_render:async() => {},
      render:async() => {
          const request = parseRequestUrl();
   
     // <-- 서버에서 주문정보를 받는 부분
          const {
              _id,
              shipping,
              payment,
              orderItems,
              itemsPrice,
              shippingPrice,
              taxPrice,
              totalPrice,
              isDelivered,
              deliveredAt,
              isPaid,
              paidAt,
         
          } = await getOrder(request.id);

    // 서버에서 주문정보를 받는 부분 -->

[ root\frontend\src\screens\OrderScreen.js ] 

 

위의 주문정보를 받기 위해서 api.js파일에 getOrder( )함수를 추가한다.

 


  export const createOrder = async(order) => {
    // 중략...
  }

 
export const getOrder = async(id) => {
      try{
          const { token } = getUserInfo();
          const response = await axios({
              url: `${apiUrl}/api/orders/${id}`,
              headers: {
                  'Content-Type': 'application/json',
                  Authorization: `Bearer ${token}`,
              },
          });
          if(response.statusText !== 'OK'){
              throw new Error(response.data.message);
          }
          return response.data;
      }catch(err){
          return {error: err.message}
      }
  }

[ root\frontend\src\api.js ] 

 

 

4) index.js 추가

- GET방식의 'order/:id'라우터를 추가한다.

 


 
// 중략...
  import PlaceOrderScreen from './screens/PlaceOrderScreen';
  import OrderScreen from './screens/OrderScreen'// 추가
 
  const routes = {
      '/' : HomeScreen,
      '/product/:id':ProductScreen,
      '/order/:id': OrderScreen// 추가
      '/cart/:id': CartScreen,
      // 중략...
  }

[ root\frontend\src\index.js ] 

 

 

5) Test

- 현재까지 구현한 코드를 실행한다면, 아래와 같이 주문결과를 볼 수 있다. 

 

test화면

 

*파일:  

blogTest_Shoppingmall_11편.zip.001
10.00MB
blogTest_Shoppingmall_11편.zip.002
10.00MB
blogTest_Shoppingmall_11편.zip.003
1.35MB

댓글

최신글 전체

이미지
제목
글쓴이
등록일