Commit 6e0e826d authored by Jiwon Yoon's avatar Jiwon Yoon
Browse files

카카오페이 결제실패 및 예매내역삭제

parent 432e3eb3
......@@ -15,8 +15,9 @@ import AdminPage from "./pages/AdminPage/AdminPage";
import TicketingPage from "./pages/TicketingPage";
import TicketingSeatPage from './pages/TicketingSeatPage'
import SearchPage from "./pages/SearchPage";
import Payment from "./pages/PaymentPage/PaymentPage";
import PaymentPage from "./pages/PaymentPage/PaymentPage";
import PaymentCompletePage from "./pages/PaymentCompletePage";
import PaymentFailPage from "./pages/PaymentFailPage";
function App() {
......@@ -39,8 +40,9 @@ function App() {
<Route path="/guest" component={GuestPage}/>
<Route path="/ticket/seat" component={TicketingSeatPage}/>
<Route path="/ticket" component={TicketingPage} />
<Route path="/payment" component={Payment} />
<Route path="/payment" component={PaymentPage} />
<Route path="/paymentcomplete" component={PaymentCompletePage} />
<Route path="/paymentfail" component={PaymentFailPage} />
<Route path="/theater" component={TheaterPage}/>
<Route path="/search" component={SearchPage} />
</Switch>
......
import axios from "axios";
import { baseUrl } from "../utils/baseUrl.js";
const approveReq = async (info) => {
const url = `${baseUrl}/api/kakaopay/test/single`;
const { data } = await axios.post(url,info);
return data
}
const approveSuccess = async (info) => {
const url = `${baseUrl}/api/kakaopay/success`;
const { data } = await axios.post(url,info);
return data
}
const paymentCancel = async (info) => {
const url = `${baseUrl}/api/kakaopay/cancel`;
const { data } = await axios.post(url,info);
return data
}
const kakaopayApi = {
approveReq,
approveSuccess,
paymentCancel
}
export default kakaopayApi
\ No newline at end of file
......@@ -4,7 +4,7 @@ import { baseUrl } from "../utils/baseUrl.js";
const findReservedSeats = async (timeTable) => {
console.log(timeTable)
const url = `${baseUrl}/api/reservation/findreservation`;
const { data } = await axios.post(url,{timeTable:timeTable});
const { data } = await axios.post(url, { timeTable: timeTable });
return data
}
......@@ -25,12 +25,26 @@ const save = async (save) => {
const url = `${baseUrl}/api/reservation/save`;
const { data } = await axios.post(url, save);
return data
}
const saveTid = async (tid) => {
const url = `${baseUrl}/api/reservation/savetid`;
const { data } = await axios.post(url, tid);
return data
}
const deleteReservation = async () => {
const url = `${baseUrl}/api/reservation/delete`;
const { data } = await axios.get(url);
return data
}
const reservationApi = {
findReservation,
findReservedSeats,
findOneReservation,
save
save,
saveTid,
deleteReservation
}
export default reservationApi
\ No newline at end of file
import kakaopayApi from "../apis/kakaopay.api"
import catchErrors from "../utils/catchErrors"
const KakaopaymentCancelBtn = () => {
const [error, setError] = useState()
async function paymentCancel() {
try {
setError("")
//실행하기 전에 먼저 reservation에서 해당하는 예매건에 대한 tid가져오기
const response = await kakaopayApi.paymentCancel({
cid: 'TC0ONETIME',
tid: '',
cancel_amount: '',
cancel_tax_free_amount:0,
})
} catch (error) {
catchErrors(error,setError)
}
}
return (
<button className="btn btn-warning" onClick={paymentCancel }>결제취소</button>
)
}
\ No newline at end of file
......@@ -60,7 +60,7 @@ const TheaterInfo = () => {
information: response.transportation
})
} catch (error) {
catchErrors(error, setError)
// catchErrors(error, setError)
console.log(error)
}
}
......
......@@ -66,7 +66,7 @@ const MoviePage = ({ location }) => {
</div>
<div className="col-sm-6" style={{ color: "white" }}>
<h1 className="pb-3">{movieInfo.title}</h1>
<p>예매율:{Math.round((movieInfo.ticket_sales / (movieInfo.totalReservationRate.totalReservationRate || 1)) * 100)}% 누적관객수: {movieInfo.ticket_sales}</p>
<p>예매율: {Math.round((movieInfo.ticket_sales / (movieInfo.totalReservationRate.totalReservationRate || 1)) * 100)}% 누적관객수: {movieInfo.ticket_sales}</p>
{movieInfo.director || movieInfo.cast
?
<>
......@@ -80,7 +80,7 @@ const MoviePage = ({ location }) => {
if (idx !== 0) return acc + ', ' + cur.name
else return acc + cur.name
}, "")}</p>
<p>개봉일:{movieInfo.release_date}</p>
<p>개봉일: {movieInfo.release_date}</p>
<div className="text-end">
<Link to={{
pathname: `/ticket`,
......
......@@ -4,6 +4,7 @@ import moment from 'moment';
import { useAuth } from '../context/auth_context'
import catchErrors from '../utils/catchErrors'
import reservationApi from '../apis/reservation.api'
import kakaopayApi from '../apis/kakaopay.api';
const PaymentCompletePage = () => {
const { user } = useAuth()
......@@ -25,9 +26,10 @@ const PaymentCompletePage = () => {
async function saveGuestReservation() {
try {
setError("")
const response = await axios.get(`/api/auth/guestinfo/${user.id}`);
const response2 = await reservationApi.findOneReservation()
console.log("예매내역=====", response2)
const response3 = await reservationApi.saveTid({ tid: localStorage.getItem('tid')})
if (response.data || response2) {
const responseEmail = await axios.post('/api/email/send', {
reservationData: response2.map(el => { return { "row": el.row, "col": el.col } }),
......@@ -37,7 +39,7 @@ const PaymentCompletePage = () => {
theater: response2[0].theater.theaterName,
time: response2[0].timetable.date.split('T')[0] + ' ' + moment(response2[0].timetable.start_time).format('HH:mm')
})
console.log(responseEmail.data)
localStorage.removeItem('tid')
}
} catch (error) {
catchErrors(error, setError)
......@@ -46,18 +48,23 @@ const PaymentCompletePage = () => {
async function saveUserReservation() {
try {
setError("")
const response = await axios.post(`/api/auth/getuserinfo`, {
id: user.id
})
// if (response.data) {
// const responseEmail = await axios.post('/api/email/send', {
// ...response2.data,
// ...response.data,
// })
// console.log(responseEmail.data)
// }
const response2 = await reservationApi.findOneReservation()
const response3 = await reservationApi.saveTid({ tid: localStorage.getItem('tid')})
if (response.data || response2) {
const responseEmail = await axios.post('/api/email/send', {
reservationData: response2.map(el => { return { "row": el.row, "col": el.col } }),
userData: { ...response.data },
cinema: "Butter Studio 조치원",
title: response2[0].title,
theater: response2[0].theater.theaterName,
time: response2[0].timetable.date.split('T')[0] + ' ' + moment(response2[0].timetable.start_time).format('HH:mm')
})
localStorage.removeItem('tid')
}
} catch (error) {
catchErrors(error, setError)
}
......@@ -65,9 +72,10 @@ const PaymentCompletePage = () => {
async function approveKakaopay(tid) {
try {
setError("")
const urlParams = new URLSearchParams(window.location.search);
const pg_token = urlParams.get('pg_token');
const response = await axios.post(`/api/kakaopay/success`, {
const response = await kakaopayApi.approveSuccess({
'tid': tid,
cid: 'TC0ONETIME',
partner_order_id: 'butter_studio',
......@@ -81,10 +89,18 @@ const PaymentCompletePage = () => {
}
return (
<div className="text-center">
<h3>예매가 정상적으로 완료되었습니다.</h3>
<button>홈으로</button>
{user.role === "member" ? <button>마이페이지</button> : <></>}
<div className="container text-center py-5">
<h3 className="my-3 text-white">예매가 정상적으로 완료되었습니다.</h3>
{user.role === "member"
?
<a href="/mypage">
<button className="btn btn-warning mx-1">마이페이지</button>
</a>
:
<a href="/">
<button className="btn btn-warning mx-1">홈으로</button>
</a>
}
</div>
)
}
......
import { useEffect, useState } from 'react'
import { useAuth } from '../context/auth_context'
import catchErrors from '../utils/catchErrors'
import reservationApi from '../apis/reservation.api'
const PaymentCompletePage = () => {
const [error, setError] = useState()
useEffect(() => {
deleteReservation()
}, [])
async function deleteReservation() {
try {
const response = await reservationApi.deleteReservation()
localStorage.removeItem('tid')
} catch (error) {
catchErrors(error, setError)
}
}
return (
<div className="container text-center py-5">
<h3 className="my-3 text-white">결제에 실패하셨습니다.</h3>
<a href="/ticket">
<button className="btn btn-warning mx-1">다시 예매하기</button>
</a>
<a href="/">
<button className="btn btn-warning mx-1">홈으로</button>
</a>
</div>
)
}
export default PaymentCompletePage
\ No newline at end of file
import axios from 'axios'
import { useEffect, useState } from 'react'
import authApi from '../../apis/auth.api'
import kakaopayApi from '../../apis/kakaopay.api'
import reservationApi from '../../apis/reservation.api'
import { useAuth } from '../../context/auth_context'
import catchErrors from '../../utils/catchErrors'
......@@ -73,23 +74,25 @@ const Payment = ({ location }) => {
userType: "member",
user: userInfo.id,
...ticketInfo,
timetable: 1
timetableId: 1
})
const responsekakao = await axios.post('/api/kakaopay/test/single', {
const responsekakao = await kakaopayApi.approveReq({
cid: 'TC0ONETIME',
partner_order_id: 'butter_studio',
partner_user_id: '000000'+ (userInfo.id || guestInfo.id),
partner_user_id: '000000' + guestID,
item_name: ticketInfo.title,
item_code: ticketInfo.movieId,
quantity: ticketInfo.adult + ticketInfo.youth + ticketInfo.senior,
total_amount: ticketInfo.totalFee,
vat_amount: 0,
tax_free_amount: 0,
approval_url: 'http://localhost:3000/paymentcomplete',
fail_url: 'http://localhost:3000/ticket',
cancel_url: 'http://localhost:3000/ticket',
fail_url: 'http://localhost:3000/paymentfail',
cancel_url: 'http://localhost:3000/paymentfail',
})
if (response && responsekakao) {
window.location.href = responsekakao.data.redirect_url
localStorage.setItem('tid', responsekakao.tid)
window.location.href = responsekakao.redirect_url
}
} else {
if (guestID) {
......@@ -99,10 +102,10 @@ const Payment = ({ location }) => {
...ticketInfo,
timetableId: 1
})
const responsekakao = await axios.post('/api/kakaopay/test/single', {
const responsekakao = await kakaopayApi.approveReq({
cid: 'TC0ONETIME',
partner_order_id: 'butter_studio',
partner_user_id: '000000'+ guestID,
partner_user_id: '000000' + guestID,
item_name: ticketInfo.title,
item_code: ticketInfo.movieId,
quantity: ticketInfo.adult + ticketInfo.youth + ticketInfo.senior,
......@@ -110,12 +113,12 @@ const Payment = ({ location }) => {
vat_amount: 0,
tax_free_amount: 0,
approval_url: 'http://localhost:3000/paymentcomplete',
fail_url: 'http://localhost:3000/ticket',
cancel_url: 'http://localhost:3000/ticket',
fail_url: 'http://localhost:3000/paymentfail',
cancel_url: 'http://localhost:3000/paymentfail',
})
if (response||responsekakao) {
localStorage.setItem('tid',responsekakao.data.tid)
window.location.href = responsekakao.data.redirect_url
if (response && responsekakao) {
localStorage.setItem('tid', responsekakao.tid)
window.location.href = responsekakao.redirect_url
}
} else {
alert("비회원 정보를 모두 입력 후 비회원 정보 저장 버튼을 눌러주세요.")
......
......@@ -25,7 +25,7 @@ const TheaterPage = () => {
<TheaterInfo />
</div>
<div className="tab-pane fade" id="stillcut" role="tabpanel" aria-labelledby="stillcut-tab">
<div>상영시간표</div>
<div className="pb-5">상영시간표</div>
</div>
<div className="tab-pane fade" id="review" role="tabpanel" aria-labelledby="review-tab">
<div className="row justify-content-center">
......
import axios from 'axios'
import config from "../config/app.config.js";
const success = async(req, res) => {
const success = async (req, res) => {
try {
// const { cid, tid, partner_order_id, partner_user_id, pg_token } = req.body
const item = req.body
......@@ -20,12 +20,10 @@ const success = async(req, res) => {
})
const resp = response.data
console.log('resp', resp)
res.json({...resp})
res.json({ ...resp })
} catch (error) {
console.log(error)
}
}
const fail = (req, res) => {
......@@ -34,10 +32,27 @@ const fail = (req, res) => {
})
}
const cancel = (req, res) => {
return res.json({
message: 'Canceled'
const cancel = async (req, res) => {
try {
const item = req.body
const data = []
for (let property in item) {
let encodedKey = encodeURIComponent(property);
let encodedValue = encodeURIComponent(item[property]);
data.push(encodedKey + "=" + encodedValue);
}
const bodyData = data.join('&')
const response = await axios.post('https://kapi.kakao.com/v1/payment/cancel', bodyData, {
headers: {
'Authorization': `KakaoAK ${config.kakaoAdminKey}`,
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
})
const resp = response.data
res.json(resp)
} catch (error) {
console.log(error)
}
}
const singleTest = async (req, res) => {
......
......@@ -81,9 +81,46 @@ const saveReservation = async (req, res) => {
}
}
const saveTid = async (req, res) => {
try {
const { tid } = req.body
const token = req.cookies.butterStudio;
const { id, role } = jwt.verify(token, config.jwtSecret);
await Reservation.update({ tid: tid }, {
where: {
userType: role,
user: id
}
})
res.json({ message: 'Tid 저장 OK' })
} catch (error) {
console.log(error)
res.status(500).send(error.message || "예매DB에 Tid 저장 실패")
}
}
const deleteReservation = async(req,res)=>{
try {
const token = req.cookies.butterStudio;
const { id, role } = jwt.verify(token, config.jwtSecret);
await Reservation.destroy({
where: {
userType: role,
user: id
}
});
res.json({ message: '결제실패로 인한 예매DB삭제' })
} catch (error) {
console.log(error)
res.status(500).send(error.message || "예매DB 삭제실패")
}
}
export default {
findReservedSeats,
findReservation,
findOneReservation,
saveReservation
saveReservation,
saveTid,
deleteReservation
}
\ No newline at end of file
......@@ -10,7 +10,7 @@ dotenv.config({
});
sequelize
.sync({ force: true })
.sync({ force: false })
.then(async () => {
await Promise.all(
Object.keys(ROLE_NAME).map((name) => {
......
......@@ -11,9 +11,6 @@ const ReservationModel = (sequelize) => {
primaryKey: true,
autoIncrement: true,
},
// reservationNum: {
// type: DataTypes.INTEGER,
// },
movieId: {
type: DataTypes.INTEGER,
},
......
......@@ -15,4 +15,10 @@ router.route('/findonereservation')
router.route('/save')
.post(reservationCtrl.saveReservation)
router.route('/savetid')
.post(reservationCtrl.saveTid)
router.route('/delete')
.get(reservationCtrl.deleteReservation)
export default router;
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment