Skip to content

Commit

Permalink
Merge pull request #43 from URECA-PODONG/feat/#6
Browse files Browse the repository at this point in the history
Feat(#6): 결제취소 연동, 결제내역 연동, 오류 해결
  • Loading branch information
Suh-code authored Nov 4, 2024
2 parents a3354aa + c8cf01c commit c0fe8ff
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 29 deletions.
16 changes: 6 additions & 10 deletions src/Router.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,16 @@ import WalkMapPage from './pages/WalkPage/WalkMapPage.jsx';
import WalkJournalPage from './pages/WalkPage/WalkJournalPage.jsx';
import Payment from './pages/PaymentPage/Payment.jsx';
import PaymentEnd from './pages/PaymentPage/PaymentEnd.jsx';
import CancelPay from './pages/PaymentPage/CancelPay.jsx';
import PetEditPage from './pages/MyPage/PetEditPage.jsx';

import PayListTest from './pages/PaymentPage/paylisttest.jsx';
import PaymentCancelList from './pages/PaymentPage/PaymentCancelList.jsx';
import PaymentHistory from './pages/PaymentPage/PaymentHistory.jsx';

import ComunityWrite from './pages/CommunityPage/CommunityWrite.jsx';
import CommunityList from './pages/CommunityPage/CommunityList.jsx';
import CommunityDetail from './pages/CommunityPage/CommunityDetail.jsx';

import HealthCare from './pages/HealthCare/HealthCare.jsx';
import ShoppingCart from './pages/ShoppingCart/ShoppingCart.jsx';
import { CartProvider } from './pages/ShoppingCart/CartContext';
import PayCancelReq from './pages/PaymentPage/PayCancelReq.jsx';
import PaymentCancelDone from './pages/PaymentPage/PaymentCancelDone.jsx';

function Router() {
return (
Expand All @@ -43,18 +39,18 @@ function Router() {
<NavSelector />
<Routes>
<Route path="/" element={<Outlet />}>
<Route index element={<PaymentHistory />} />
<Route index element={<MainPage />} />
<Route path="login" element={<LoginPage />} />
<Route path="shoppingDetail/:productId" element={<ShoppingDetail />} />
<Route path="shoppingCart" element={<ShoppingCart />} />
<Route path="healthCare" element={<HealthCare />} />

<Route path="payment" element={<Payment />} />
<Route path="paymentCancelList" element={<PaymentCancelList />} />
<Route path="payCancelReq" element={<PayCancelReq />} />
<Route path="paymentEnd" element={<PaymentEnd />} />
<Route path="paymentHistory" element={<PaymentHistory />} />
<Route path="cancelpay" element={<CancelPay />} />
<Route path="paymentlist" element={<PayListTest />} />
<Route path="paymentlist" element={<PaymentHistory />} />
<Route path="paymentCancelDone" element={<PaymentCancelDone />} />

<Route path="nanumList" element={<Outlet />}>
<Route index element={<NanumList />} />
Expand Down
60 changes: 48 additions & 12 deletions src/pages/PaymentPage/CancelPay.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
import React from "react";
import React, { useEffect, useState } from "react";
import axios from "axios";

const CancelPay = () => {
// 결제 취소 함수

const CancelPay = ({ userId }) => {
const [impUid, setImpUid] = useState(null);

// userId에 따른 imp_uid 가져오기
const fetchImpUid = async () => {
try {
const response = await axios.get(`http://localhost:8080/api/payment/list/${userId}`);
const paymentData = response.data;

console.log("Fetched Payment Data:", paymentData); // 전체 데이터를 확인

// 배열의 첫 번째 객체의 impUid만 가져옵니다
if (paymentData.length > 0 && paymentData[0].impUid) {
setImpUid(paymentData[0].impUid);
} else {
console.error("impUid를 찾을 수 없습니다.");
alert("impUid를 찾을 수 없습니다.");
}
} catch (error) {
console.error("impUid 가져오기 에러 발생:", error);
alert("impUid를 가져오는 데 실패했습니다.");
}
};

// 결제 취소 요청 핸들링
const handleCancel = async () => {
const imp_uid = "imp_624092379683"; // 테스트용 결제번호
const confirm = window.confirm(`${imp_uid} / 결제를 취소하시겠습니까?`);
if (!impUid) return; // imp_uid가 없는 경우 실행 중지

const confirm = window.confirm(`${impUid} / 결제를 취소하시겠습니까?`);
if (confirm) {
try {
// Access token 요청
Expand All @@ -14,16 +39,16 @@ const CancelPay = () => {
method: "post",
headers: { "Content-Type": "application/json" },
data: {
imp_key: "6424817121242405",
imp_secret: "Qxc7mtPG7i3Rp0s2g4t9ftrE90QkD1jB32mmYIKQIaYyAdjAYFLD2Q9Ff7aA4KLSa7abVuXcut47ZTQ9",
imp_key: import.meta.env.VITE_IMP_KEY,
imp_secret: import.meta.env.VITE_IMP_SECRET,
},
});

// 인증 토큰 추출
const { access_token } = getToken.data.response;

// 취소 요청
await getCancelData(access_token, imp_uid);
await getCancelData(access_token, impUid);
} catch (error) {
console.error("토큰 추출 에러 발생:", error);
}
Expand All @@ -36,13 +61,13 @@ const CancelPay = () => {
const response = await axios.post(
"/iamport/payments/cancel",
{
imp_uid: "imp_624092379683", // 결제번호 (필수)
cancel_request_amount: 1000
imp_uid: imp_uid, // 결제번호 (필수)
cancel_request_amount: 1000,
},
{
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${access_token}`,
Authorization: `Bearer ${access_token}`,
},
}
);
Expand All @@ -54,9 +79,20 @@ const CancelPay = () => {
}
};

// 컴포넌트가 렌더링될 때 imp_uid를 먼저 가져오고 handleCancel 함수 실행
useEffect(() => {
fetchImpUid();
}, []);

useEffect(() => {
if (impUid) {
handleCancel();
}
}, [impUid]);

return (
<div>
<button onClick={handleCancel}>환불하기</button>
<p>결제 취소 요청 중...</p>
</div>
);
};
Expand Down
183 changes: 183 additions & 0 deletions src/pages/PaymentPage/PayCancelReq.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import React, { useState } from 'react';
import styled from 'styled-components';
import CancelPay from "./CancelPay";

const StyledH2 = styled.h2`
font-weight: bold;
margin-bottom: 10px;
`;

const OrderCancellationWrapper = styled.div`
padding: 20px;
margin-top: 64px;
`;

const OrderInfo = styled.div`
display: flex;
justify-content: space-between;
margin-bottom: 20px;
font-size: 13px;
`;

const CancelItem = styled.div`
margin-bottom: 20px;
`;

const ItemInfo = styled.div`
display: flex;
align-items: center;
margin-bottom: 10px;
input {
margin-right: 10px;
}
label {
display: flex;
align-items: center;
img {
width: 50px;
height: 50px;
margin-right: 10px;
}
div {
p {
margin: 0;
}
}
}
`;

const CancelReason = styled.div`
margin-bottom: 20px;
select {
width: 100%;
margin-top: 10px;
border-radius: 8px;
}
textarea {
margin-top: 10px;
width: 100%;
height: 100px;
border-radius: 8px;
}
`;

const RefundInfo = styled.div`
margin-bottom: 20px;
`;

const RefundDetails = styled.div`
.refund-detail {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
`;

const Divider = styled.hr`
border: none;
border-top: 1px solid #e0e0e0;
margin: 20px 0;
`;

const CancelButton = styled.button`
background-color: #ff6e00;
color: white;
padding: 10px 20px;
border: none;
cursor: pointer;
width: 100%;
font-size: 14px;
font-weight: bold;
border-radius: 5px;
transition: background-color 0.3s;
&:hover {
background-color: darkorange;
}
`;

function PayCancelReq() {
const [cancelReason, setCancelReason] = useState('');
const [detailedReason, setDetailedReason] = useState('');
const [isCancelRequested, setIsCancelRequested] = useState(false);

const handleReasonChange = (e) => {
setCancelReason(e.target.value);
};

const handleDetailedReasonChange = (e) => {
setDetailedReason(e.target.value);
};

const handleCancel = () => {
setIsCancelRequested(true);
console.log("주문 취소 요청");
};

return (
<OrderCancellationWrapper>
<OrderInfo>
<span>주문일시</span>
<span>24.10.17</span>
</OrderInfo>
<CancelItem>
<StyledH2>취소 사유 선택</StyledH2>
<Divider />
<ItemInfo>
<input type="checkbox" id="item1" />
<label>
<div>
<p>상품명, 상품사진 등등 db</p>
<p>상품가격 db</p>
</div>
</label>
</ItemInfo>
</CancelItem>
<CancelReason>
<StyledH2>취소 사유</StyledH2>
<select value={cancelReason} onChange={handleReasonChange}>
<option value="">사유를 선택해주세요.</option>
<option value="change_mind">단순 고객 변심</option>
<option value="wrong_item">잘못된 상품 주문</option>
<option value="change_option">상품 옵션 변경</option>
<option value="time_delivery">배송 지연</option>
<option value="change_paymethod">결제 수단 변경</option>
<option value="other">기타</option>
</select>
<textarea
placeholder="상세 사유를 상세하게 입력해주세요."
value={detailedReason}
onChange={handleDetailedReasonChange}
/>
</CancelReason>
<Divider />
<RefundInfo>
<RefundDetails>
<div className="refund-detail">
<span>환불 금액</span>
<span>37,000원</span>
</div>
<div className="refund-detail">
<span>상품액</span>
<span>37,000원</span>
</div>
<div className="refund-detail">
<span>배송비</span>
<span>0원</span>
</div>
</RefundDetails>
</RefundInfo>
<CancelButton onClick={handleCancel}>결제 취소</CancelButton>

{isCancelRequested && <CancelPay userId={1} />}
</OrderCancellationWrapper>
);
}

export default PayCancelReq;
10 changes: 5 additions & 5 deletions src/pages/PaymentPage/Payment.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ const Payment = () => {
IMP.init("imp02101050"); // 포트원 가맹점 식별코드

const userId = 1;
const response = await axios.get(`http://localhost:8080/api/user/getInfo/${userId}`);
const response = await axios.get(`http://localhost:8080/api/user/${userId}`);
const userData = response.data;
console.log("User Data:", userData);

Expand All @@ -137,10 +137,10 @@ const Payment = () => {
merchant_uid: `mid_${new Date().getTime()}`, // 주문번호 (중복되지 않도록 생성)
name: "테스트 결제", // 결제명
amount: 1000, // 결제 금액
buyer_email: userData.buyer_email, // 구매자 이메일
buyer_name: userData.buyer_name, // 구매자 이름
buyer_tel: userData.buyer_tel, // 구매자 전화번호
buyer_addr: userData.buyer_addr, // 구매자 주소
buyer_email: userData.accountEmail, // 구매자 이메일
buyer_name: userData.nickname, // 구매자 이름
buyer_tel: userData.phoneNumber, // 구매자 전화번호
buyer_addr: userData.address, // 구매자 주소
buyer_postcode: "000-000", // 구매자 우편번호
}, (rsp) => {
if (rsp.success) { // 프론트에서 결제가 완료되면
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ const PaymentTotal = styled.p`
margin-top: 10px;
`;

const PaymentCancelList = () => {
const PaymentCancelDone = () => {
const [orderNumber, setOrderNumber] = useState('');
const [content, setContent] = useState({});

Expand Down Expand Up @@ -200,4 +200,4 @@ const PaymentCancelList = () => {
);
};

export default PaymentCancelList;
export default PaymentCancelDone;

0 comments on commit c0fe8ff

Please sign in to comment.