[Node/React] 쇼핑몰 사이트 만들기 - 12 Paypal 버튼 만들기, 결제하기

JS·2023년 3월 14일
0
post-thumbnail

12-1. Paypal 버튼 만들기

http://developer.paypal.com/developer/accounts/
가입하기


가입후 샌드박스 어카운트에 들어가서 test Id 생성


비밀번호 변경하기

models에 payment 모델 생성
//Payment.js
const mongoose = require("mongoose");

const paymentSchema = mongoose.Schema(
  {
    user: {
      type: Array,
      default: [],
    },
    data: {
      type: Array,
      default: [],
    },
    product: {
      type: Array,
      default: [],
    },
  },
  { timestamps: true }
);

const Payment = mongoose.model("Payment", paymentSchema);

module.exports = { Payment };

cd client 하고 ->
npm install react-paypal-express-checkout --save

구글에 react-paypal-express-checkout 검색후
npm페이지 참고

import React from "react";
import PaypalExpressBtn from "react-paypal-express-checkout";

export default class Paypal extends React.Component {
  render() {
    const onSuccess = (payment) => {
      console.log("The payment was succeeded!", payment);

      this.props.onSuccess(payment);
    };

    const onCancel = (data) => {
      console.log("The payment was cancelled!", data);
    };

    const onError = (err) => {};

    let env = "sandbox";
    let currency = "USD";
    let total = this.props.total;

    const client = {
      sandbox:
        "ATHoaUPgCKoNOD4pExA8Nx_lszXC5VN2QPGdswTRv5i_v0VPFVIs8jCGdVmcZuMwWNHeV10Z1RMDXhRl",
      production: "YOUR-PRODUCTION-APP-ID",
    };

    return (
      <PaypalExpressBtn
        env={env}
        client={client}
        currency={currency}
        total={total}
        onError={onError}
        onSuccess={onSuccess}
        onCancel={onCancel}
        style={{
          size: "large",
          color: "blue",
          shape: "rect",
          label: "checkout",
        }}
      />
    );
  }
}

12-2. Paypal로 결제하기

//cartPage.js
      {ShowTotal && <Paypal total={Total} onSuccess={transactionSuccess} />}
      
//Paypal.js  
//total 추가
let total = this.props.total;

      
    return (
      <PaypalExpressBtn
        env={env}
        client={client}
        currency={currency}
        total={total}
        onError={onError}
        onSuccess={onSuccess}
        onCancel={onCancel}
        style={{
          size: "large",
          color: "blue",
          shape: "rect",
          label: "checkout",
        }}
      />

12-3. 결제완료 후 장바구니 비우기, 결제 정보 저장하기

//CartPage.js
const transactionSuccess = (data) => {
    dispatch(
      onSuccessBuy({
        paymentData: data,
        cartDetail: props.user.cartDetail,
      })
    ).then((response) => {
      if (response.payload.success) {
        setShowTotal(false);
        setShowSuccess(true);
      }
    });
  };

//paypal.js
  this.props.onSuccess(payment);
// 결제를 성공하면 paypal에서 제공하는 정보(payment)를 부모 컴포넌트인 CartPage의 data parameter에 있음

//user_actions.js
export function onSuccessBuy(data) {
  const request = axios
    .post(`/api/users/successBuy`, data)
    .then((response) => response.data);
  return {
    type: ON_SUCCESS_BUY,
    payload: request,
  };
  
 //type.js
  export const ON_SUCCESS_BUY = 'on_success_buy';
 //user_reducer.js
    case ON_SUCCESS_BUY:
      return {
        ...state,
        cartDetail: action.payload.cartDetail,
        userData: {
          ...state.userData,
          cart: action.payload.cart,
        },
      };

 //users.js
  router.post("/successBuy", auth, (req, res) => {
  //1. User Collection 안에  History 필드 안에  간단한 결제 정보 넣어주기
  let history = [];
  let transactionData = {};

  req.body.cartDetail.forEach((item) => {
    history.push({
      dateOfPurchase: Date.now(),
      name: item.title,
      id: item._id,
      price: item.price,
      quantity: item.quantity,
      paymentId: req.body.paymentData.paymentID,
    });
  });

  //2. Payment Collection 안에  자세한 결제 정보들 넣어주기
  transactionData.user = {
    id: req.user._id,
    name: req.user.name,
    email: req.user.email,
  };

  transactionData.data = req.body.paymentData;
  transactionData.product = history;

  //history 정보 저장
  User.findOneAndUpdate(
    { _id: req.user._id },
    { $push: { history: history }, $set: { cart: [] } },
    { new: true },
    (err, user) => {
      if (err) return res.json({ success: false, err });

      //payment에다가  transactionData정보 저장
      const payment = new Payment(transactionData);
      payment.save((err, doc) => {
        if (err) return res.json({ success: false, err });

        //3. Product Collection 안에 있는 sold 필드 정보 업데이트 시켜주기

        //상품 당 몇개의 quantity를 샀는지

        let products = [];
        doc.product.forEach((item) => {
          products.push({ id: item.id, quantity: item.quantity });
        });

        async.eachSeries(
          products,
          (item, callback) => {
            Product.update(
              { _id: item.id },
              {
                $inc: {
                  sold: item.quantity,
                },
              },
              { new: false },
              callback
            );
          },
          (err) => {
            if (err) return res.status(400).json({ success: false, err });
            res.status(200).json({
              success: true,
              cart: user.cart,
              cartDetail: [],
            });
          }
        );
      });
    }
  );
});


결제완료화면

profile
신입 FE 개발자

0개의 댓글