[Nextjs]드디어 결제 모듈을 붙여보자

코드왕·2025년 1월 11일
0
  1. 토스페이먼츠 API 정보를 받아온다

2.환경변수에 값을 넣어준다

  1. API를 만든다

api/payments 라우터를 만든다음에 GET요청을 받으면 결제를 확정 시킨다
결제가 완료되면 payments/complete 페이지로 이동 시킨다.

// app/api/payments/route.js
export async function GET(req, res) {
  // Extract query parameters using URLSearchParams
  const url = new URL(req.url, `http://${req.headers.host}`);
  const orderId = url.searchParams.get('orderId');
  const paymentKey = url.searchParams.get('paymentKey');
  const amount = url.searchParams.get('amount');

  const secretKey = process.env.NEXT_PUBLIC_TOSS_PAYMENTS_SECRET_KEY;

  const apiUrl = "https://api.tosspayments.com/v1/payments/confirm";
  const basicToken = Buffer.from(`${secretKey}:`, "utf-8").toString("base64");

  const response = await fetch(apiUrl, {
    method: "post",
    body: JSON.stringify({
      amount,
      orderId,
      paymentKey,
    }),
    headers: {
      Authorization: `Basic ${basicToken}`,
      "Content-Type": "application/json",
    },
  });

  const data = await response.json();

  // Redirect to the complete page with orderId
  return new Response(null, {
    status: 302,
    headers: { 'Location': `/payments/complete?orderId=${orderId}` },
  });
}
  1. 결제 완료 페이지를 만든다

searchParams로 받은 url을 기반으로 해서 orderId기반으로 결제 내용을 조회하여 결제된 내용을 화면에 표시해준다.

// app/payments/complete/page.js
import React from 'react';

async function page({searchParams}) {
    const secretKey = process.env.NEXT_PUBLIC_TOSS_PAYMENTS_SECRET_KEY || "";
    const basicToken = Buffer.from(`${secretKey}:`, `utf-8`).toString("base64");

    const url = `https://api.tosspayments.com/v1/payments/orders/${searchParams.orderId}`;
    const payments = await fetch(url, {
        headers: {
            Authorization: `Basic ${basicToken}`,
            "Content-Type": "application/json",
        },
    }).then((res) => res.json());

    const { card } = payments;
    return (
        <div>
            <h1>결제가 완료되었습니다</h1>
            <ul>
                <li>결제 상품 {payments.orderName}</li>
                <li>주문번호 {payments.orderId} </li>
                <li>카드회사 {card.company}</li>
                <li>카드번호 {card.number}</li>
                <li>결제금액 {card.amount}</li>
                <li>
                    결제승인날짜{" "}
                    {Intl.DateTimeFormat().format(new Date(payments.approvedAt))}
                </li>
            </ul>
        </div>
    );
}

export default page;
  1. 결제 페이지를 만든다

결제 페이지를 만드는데 loadTossPayments SDK를 이용해서 결제 창을 불러온다. 결제를 하고 나서 successUrl을 보낸다. 1번에서 만든 api로 해당 결제를 확정 시키게 된다. 결제 하고자하는 금액과 아이디를 넣으면 된다.

pip install @tosspayments/payment-sdk

만약 카드 결제만 필요할 경우 requestPayment의 첫번째 인자로 '카드','계좌이체','휴대폰'을 넣어주면 된다.

'use client'
import Image from "next/image";
import {Button} from "@nextui-org/react";
import {loadTossPayments} from "@tosspayments/payment-sdk";

export default function Home() {
  const handleClick = async (paymentMethod) => {
    const tossPayments = await loadTossPayments(process.env.NEXT_PUBLIC_TOSS_PAYMENTS_CLIENT_KEY);
    await tossPayments.requestPayment( {
      amount: 5000,
      orderId: Math.random().toString(36).slice(2),
      orderName: "맥북",
      successUrl: "http://localhost:3000/api/payments",
      failUrl: "http://localhost:3000/api/payments/fail",
    });
  };
  return (
    <div>
      <h1>맥북 팝니다.</h1>
      <p>5000</p>
      <Button onClick={() => handleClick("카드")} color="primary">카드로 구매하기</Button>
      <Button onClick={() => handleClick("계좌이체")} color="secondary">계좌이체로 구매하기</Button>
      <Button onClick={() => handleClick("휴대폰")} color="success">휴대폰으로 구매하기</Button>
    </div>
  );
}
profile
CODE DIVE!

0개의 댓글