단순히 고정값을 보내어 호출한 저번 포스팅에 이어,
이번 포스팅에서는 폼에서 수정한 값으로 결제창 호출 시 데이터를 보낼 수 있도록 구현하겠습니다.
1. "가격", "결제 수단", "구매수량에 따른 최종 결제 금액"의 상태값이 변할 수 있도록 useState를 활용하여 변수를 선언해 줍니다.
const [price, setPrice] = useState<number>(1004);
const [selctedMethod, setSelectedMethod] = useState<string>('');
const [totalPrice, setTotalPrice] = useState<number>(1004);
2. 폼 제출 시 결제 수단의 선택 유무를 판단하여 나이스페이 결제창을 호출하는 함수를 구현합니다.
const handleSubmit = (e: any) => {
e.preventDefault();
if (e.target.method.value === '') {
alert('결제수단을 선택하세요.')
return false;
} else {
getPayments();
}
}
3. react + typescript + styled-components를 사용하여 작성한 최종 코드입니다.
import axios from 'axios';
import React, { useState } from 'react';
import { Tomato } from './assets/index';
import { styled } from 'styled-components';
interface ErrorResultType {
errorMsg: string;
}
const App = () => {
const [name, setName] = useState<string>("맛있는 방울토마토");
const [price, setPrice] = useState<number>(1004);
const [selctedMethod, setSelectedMethod] = useState<string>('');
const [totalPrice, setTotalPrice] = useState<number>(1004);
// 나이스 페이 결제창 호출
const getPayments = async () => {
try {
const res = await axios.get(`http://localhost:8000/api/payments`);
const { AUTHNICE } = window as any;
AUTHNICE.requestPay({
clientId: res.data.clientId,
method: selctedMethod,
orderId: res.data.orderId,
amount: totalPrice,
goodsName: name,
returnUrl: '/api/paysuccess',
fnError: function (result: ErrorResultType) {
console.log('개발자확인용 : ' + result.errorMsg);
}
});
} catch (error) {
console.log(error);
}
}
// 폼 제출
const handleSubmit = (e: any) => {
e.preventDefault();
if (e.target.method.value === '') {
alert('결제수단을 선택하세요.')
return false;
} else {
getPayments();
}
}
return (
<AppContainer>
<ProductImage src={Tomato} alt=''></ProductImage>
<FormContainer
onSubmit={(e:any) => handleSubmit(e)}>
<FormBox>
<h4>상품명</h4>
<p>{name}</p>
</FormBox>
<FormBox>
<h4>결제 수단</h4>
<MethodContainer>
<MethodBox>
<label htmlFor='card'>카드</label>
<input id='card' name='method' type='radio' value={'card'}
onChange={(e) => setSelectedMethod(e.target.value)}></input>
</MethodBox>
<MethodBox>
<label htmlFor='bank'>계좌이체</label>
<input id='bank' name='method' type='radio' value={'bank'}
onChange={(e) => setSelectedMethod(e.target.value)}></input>
</MethodBox>
<MethodBox>
<label htmlFor='cellphone'>휴대폰</label>
<input id='cellphone' name='method' type='radio' value={'cellphone'}
onChange={(e) => setSelectedMethod(e.target.value)}></input>
</MethodBox>
<MethodBox>
<label htmlFor='kakaopay'>카카오페이</label>
<input id='kakaopay' name='method' type='radio' value={'kakaopay'}
onChange={(e) => setSelectedMethod(e.target.value)}></input>
</MethodBox>
<MethodBox>
<label htmlFor='samsungpayCard'>삼성페이</label>
<input id='samsungpayCard' name='method' type='radio' value={'samsungpayCard'} onChange={(e) => setSelectedMethod(e.target.value)}></input>
</MethodBox>
<MethodBox>
<label htmlFor='naverpayCard'>네이버페이</label>
<input id='naverpayCard' name='method' type='radio' value={'naverpayCard'}
onChange={(e) => setSelectedMethod(e.target.value)}></input>
</MethodBox>
</MethodContainer>
</FormBox>
<FormBox>
<h4>수량</h4>
<input
className='count-input'
type='number'
min={1}
defaultValue={1}
onChange={(e) => {
const value = Number(e.target.value);
setTotalPrice(value * price);
}}></input>
</FormBox>
<FormBox>
<h4>결제 금액</h4>
<p>{totalPrice}원</p>
</FormBox>
<BuyButton>구매하기</BuyButton>
</FormContainer>
</AppContainer>
);
}
export default App;
const AppContainer = styled.div`
padding: 100px;
`;
const FormBox = styled.div`
display: flex;
flex-direction: column;
margin-bottom: 14px;
.count-input {
width: 100px;
}
`;
const MethodContainer = styled.div`
display: flex;
`;
const MethodBox = styled.div`
display: flex;
margin-right: 15px;
input {
margin-left: 5px;
}
`;
const ProductImage = styled.img`
width: 400px;
height: 300px;
`;
const FormContainer = styled.form`
margin-top: 20px;
`;
const BuyButton = styled.button`
width: 70px;
height: 30px;
background-color: black;
color: white;
font-size: 15px;
`;
4. 시연 영상
'React' 카테고리의 다른 글
browser-image-compression을 활용하여 이미지 최적화하기 (0) | 2023.09.10 |
---|---|
[Project] 나이스 페이먼츠 테스트용 전자결제 연동하기 (2) - 키 발급 및 프론트엔드 진행 1차 (0) | 2023.07.29 |
[Project] 나이스 페이먼츠 테스트용 전자결제 연동하기 (1) - 테스트 상점 개설하기 (0) | 2023.07.24 |