Toss Payments를 사용하는 프로젝트에서는 결제 성공/실패 후 Redirect URL로 사용자를 안내해야 합니다. 이 과정에서 URL 파라미터를 통해 결제 상태를 전달받아 처리하고, 적절한 페이지로 리디렉션하는 로직을 구현할 수 있습니다.
아래는 Toss Payments의 성공 및 실패 Redirect 처리 컴포넌트를 구현하는 방법과 관련된 내용을 설명합니다.
1. Redirect URL 설정
Toss Payments 요청 시 successUrl과 failUrl을 설정합니다. 이 URL로 결제 성공 또는 실패 후 리디렉션됩니다.
tossPayment.requestPayment('카드', {
amount: productAmount,
orderId: id,
orderName: name,
customerName: userName,
successUrl: `${url}/payment/success`, // 성공 시 Redirect
failUrl: `${url}/payment/fail`, // 실패 시 Redirect
});
2. 실패 Redirect 처리 컴포넌트
/payment/fail 경로에서 결제 실패를 처리하는 로직입니다. URL 파라미터에서 상태를 가져와 SweetAlert로 사용자에게 안내하고, 이후 적절한 페이지로 리디렉션합니다.
TossRedirectFailHandler 구현
import React, { useEffect } from "react";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import Swal from "sweetalert2";
const TossRedirectFailHandler = () => {
const { id } = useParams();
const nav = useNavigate();
const location = useLocation();
useEffect(() => {
const urlParams = new URL(window.location.href).searchParams;
const code = urlParams.get('code');
const message = urlParams.get('message');
if (code === 'PAY_PROCESS_CANCELED') {
Swal.fire({
title: '결제가 취소되었습니다.',
text: '사용자가 결제를 취소하였습니다.',
icon: 'info',
confirmButtonText: '확인',
confirmButtonColor: '#0EAD0E',
}).then(() => {
if (location.pathname === "/payment/fail") {
nav('/cart'); // 장바구니 페이지로 이동
}
});
} else {
Swal.fire({
title: '결제 오류 발생',
text: `오류 코드: ${code}\n오류 메시지: ${message}`,
icon: 'error',
confirmButtonText: '확인',
confirmButtonColor: '#FF0000',
}).then(() => {
nav('/cart');
});
}
}, [location, nav]);
return null; // 화면에 표시할 내용이 없는 처리용 컴포넌트
};
export default TossRedirectFailHandler;
3. 성공 Redirect 처리 컴포넌트
/payment/success 경로에서 결제 성공을 처리하는 로직입니다. 결제 완료 데이터를 서버로 전달하고, SweetAlert를 사용해 사용자에게 결제 완료 메시지를 표시합니다.
TossRedirectHandler 구현
import React, { useEffect } from "react";
import axios from '@/lib/GlobalAxios';
import { useNavigate, useLocation, useParams } from "react-router-dom";
import Swal from "sweetalert2";
const TossRedirectHandler = () => {
const { id } = useParams();
const nav = useNavigate();
const location = useLocation();
useEffect(() => {
const urlParams = new URL(window.location.href).searchParams;
const orderId = urlParams.get('orderId');
const paymentKey = urlParams.get('paymentKey');
const amount = urlParams.get('amount');
axios.post(`/api/v1/order/payment`, {
orderId,
paymentKey,
amount,
})
.then(response => {
if (response.data.result_data.error_code === 0) {
axios.get(`/api/v1/user`).then(userResponse => {
Swal.fire({
title: '결제 완료',
text: '결제가 성공적으로 완료되었습니다.',
icon: 'success',
confirmButtonText: '닫기',
confirmButtonColor: '#0EAD0E',
}).then(() => {
nav('/order_history'); // 주문 내역 페이지로 이동
});
});
} else {
handlePaymentError(response.data.result_data.error_code);
}
}).catch(error => {
console.error('결제 처리 오류:', error);
});
}, [nav]);
const handlePaymentError = (errorCode) => {
let errorMessage = '알 수 없는 오류가 발생했습니다.';
if (errorCode === '-1') errorMessage = '필수 파라미터가 부족합니다.';
if (errorCode === '-2') errorMessage = '주문 정보를 찾을 수 없습니다.';
if (errorCode === '-3') errorMessage = '결제 승인에 실패했습니다.';
Swal.fire({
title: '결제 오류',
text: errorMessage,
icon: 'error',
confirmButtonText: '확인',
confirmButtonColor: '#FF0000',
}).then(() => {
nav(`/cart`, { state: { payment: 'fail' } });
});
};
return null; // 화면에 표시할 내용이 없는 처리용 컴포넌트
};
export default TossRedirectHandler;
4. 라우팅 설정
React Router를 사용하여 /payment/success와 /payment/fail 경로를 설정합니다.
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import TossRedirectHandler from '@/components/TossRedirectHandler';
import TossRedirectFailHandler from '@/components/TossRedirectFailHandler';
export default function Router() {
const routes = useRoutes([
{ path: 'payment/success',element: <TossRedirectSuccessHandler /> },
{ path: 'payment/fail', element: <TossRedirectFailHandler /> },
]);
return createBrowserRouter(routes);
}
요약
- 성공/실패 Redirect URL 설정 시 successUrl과 failUrl을 지정합니다.
- TossRedirectFailHandler는 결제 실패 시 오류 메시지를 보여주고, 적절한 페이지로 리디렉션합니다.
- TossRedirectHandler는 결제 성공 후 서버와 통신하고, SweetAlert를 통해 사용자에게 결제 성공 메시지를 표시합니다.
- React Router로 Redirect 경로를 설정하여 동작을 연결합니다.