자바스 개발 구축 환경
해당 프로젝트는 Spring Legacy Project로 sts-3.9 버전을 사용하였습니다.
주제
- 자격증을 공부하기 위해 정보를 얻고 싶은 취준생들을 위한 사이트이다.
- 자신이 원하는 자격증을 검색하여 교재, 동영상, 관심 있는 자격증을 등록할 수 있고, 홈페이지에 시험 d-day를 확인하도록 도와준다.
- 회원들끼리 정보를 공유할 수 있으며, 가까운 지역의 스터디카페를 추천해 준다.
나의 개발 파트
- 로그인(auth)
- 회원, 관리자 (등급 분배)
- 관리자
- 관리자 번호로 회원 등급 조절
- 회원 결제정보 확인, 취소
- 스터디카페 예약 시 결제
- 상품결제
- 결제수단 선택
- 결제 후 날짜변경
- 결제 취소
결제 api를 사용할 때 내가 고민을 많이 했던 부분과 참조한 부분을 정리하여 기록을 남기면 좋을 것 같다는 생각을 했다.
Iamport 회원가입부터 결제테스트, 상품(스터디카페) oracle db 연동, 상품 결제, oracle db 결제내역저장, 결제 취소 순으로 포스팅할 계획입니다.
아이엠포트 회원가입
아이엠 포트에 로그인 후 카카오페이를 활용하여 구현을 진행하기에 결제대행사를 카카오페이로 추가합니다.
그 후 구 관리자 콘솔로 이동합니다.
시스템설정 -> 내 정보에서 가맹점 식별코드, REST API키, RESET API secret을 확인할 수 있습니다.
그럼 아이엠포트 결제를 위한 준비 단계를 밟았습니다. 이제 String 개발 툴로 돌아가 api를 추가해 봅시다!+
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.2</version>
</dependency>
해당 정보는 github에 올리면 안 되는 개인의 정보로 ignore 파일에 따로 관리하도록 합니다.
IamportClient를 활용해 iamport의 함수들로 (결제내역, 정보, 취소) 활용할 수 있었습니다.
function requestPay() {
// IMP.request_pay(param, callback) 결제창 호출
var uid = '';
IMP.init('가맹점 번호 자리입니다');
IMP.request_pay({ // param
pg: 'kakaopay',
pay_method: "card",
merchant_uid: createOrderNum(), //가맹점 주문번호 (아임포트를 사용하는 가맹점에서 중복되지 않은 임의의 문자열을 입력)
name: scName.textContent, //결제창에 노출될 상품명
amount: cdPay.textContent, //금액
buyer_email : email.textContent,
buyer_name : userName.textContent,
buyer_tel : phone.textContent.trim(),
}, function (rsp) { // callback
if (rsp.success) { // 결제 성공 시: 결제 승인 또는 가상계좌 발급에 성공한 경우
uid = rsp.imp_uid;
// 결제검증
$.ajax({
url: '/order/verify_iamport/' + rsp.imp_uid,
type: 'post'
}).done(function(data) {
// 결제를 요청했던 금액과 실제 결제된 금액이 같으면 해당 주문건의 결제가 정상적으로 완료된 것으로 간주한다.
if (cdPay.textContent == data.response.amount) {
// jQuery로 HTTP 요청
// 주문정보 생성 및 테이블에 저장
// 데이터를 json으로 보내기 위해 바꿔준다.
data = JSON.stringify({
"orderNum" : rsp.merchant_uid,
"productNum" : detailNum.textContent, //상품번호
"num" : userNum.value, // 회원번호
"productName" : rsp.name,
"orderDate" : new Date().getTime(),
"totalPrice" : rsp.paid_amount,
"imp_uid" : rsp.imp_uid,
"reserNum" : reserNum.textContent // 예약정보를 담고있는번호
});
jQuery.ajax({
url: "/order/complete",
type: "POST",
dataType: 'json',
contentType: 'application/json',
data : data
})
.done(function(res) {
if (res > 0) {
swal('주문정보 저장 성공')
createPayInfo(uid);
}
else {
swal('주문정보 저장 실패');
}
})
}
else {
alert('결제 실패');
}
})
} else {
swal("결제에 실패하였습니다.","에러 내용: " + rsp.error_msg,"error");
}
});
}
저와 같이 넘기는 정보가 결제 정보뿐만 아니라 해당 카페의 좌석, 날짜, 시간 등 넘겨줘야 하는 데이터가 추가적으로 있다면 데이터를 json으로 보내기 위해 변경하여 같이 넘겨주는 형식을 활용하시면 될 것 같습니다.
아이엠포트 api 를 사용해서 결제라는 시스템을 시도했을 때 바로 성공해서 좋았지만, 예외사항에 대해 한 번 더 고민해볼 필요가 있다고 생각했습니다.
현재 if문으로 한번 더 감싼이유는 html에서 금액을 조정했을 경우에 결제가 진행되면 안 되기 때문입니다.
그래서 서버에서 결제로 넘어오는 금액과 가격이 맞지 않는다면 결제를 취소하고, 맞다면 결제를 진행하는 방식을 사용했습니다.
백엔드에서 주문정보와 결제 정보를 저장할 때 결제 완료된 금액과 실제 계산되어야 할 금액이 다를 경우를 String 에서도 관리함으로써 이중으로 결제 금액을 관리하였습니다.
// 주문번호 만들기
function createOrderNum(){
const date = new Date();
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
let orderNum = year + month + day;
for(let i=0;i<10;i++) {
orderNum += Math.floor(Math.random() * 8);
}
return orderNum;
}
@ResponseBody
@RequestMapping(value = "/verify_iamport/{imp_uid}", method = RequestMethod.POST)
public IamportResponse<Payment> verifyIamportPOST(@PathVariable(value = "imp_uid") String imp_uid) throws IamportResponseException, IOException {
return client.paymentByImpUid(imp_uid);
}
지금까지 결제버튼까지의 코드를 이해하시고 활용하신다면 버튼 클릭 시 결제 큐알코드까지 확인하실 수 있으실 것 같습니다 !
다음 포스팅에는 테스트 결제 후 화면이동, 결제정보 저장, 결제 리스트 확인, 결제 취소(환불)에 대해 포스팅하겠습니다.
'Project > 국비프로젝트' 카테고리의 다른 글
[Java Spring] 결제 시스템 (Iamport api) 활용기 2 - 자격증 공부를 위한 사이트 자바스 개발 회고록 (0) | 2023.01.05 |
---|