Frontend/GAN:ERATE

[REACT] 아임포트 일반결제 성공

sefdcrxe 2023. 8. 25. 06:43

아직 결제 검증 통신은 구현하지 못했지만

결제는 성공했다 !

 

포트와 연동된 화면 창
결제 성공 창

결제 화면을 구현하는 데에는 아래의 파일을 활용했다

 

1. 아임포트 payment.html -> 각종 변수 설정 및 로직 참고

2. index.html -> 아임포트 script 추가

3. PaymentPage.js -> 해당 결제 페이지 구현 창

4. VerifyPage.js -> 결제 검증 페이지 구현 창

5. user_actions.js -> 결제할 상품 통신 코드 & 결제 검증 통신 코드

----

6. PaymentPage.css -> 디자인

 

 

어떤 것을 중심으로 고려하면서 코드를 짰는 지에 대해서는 바로 이전 게시물을 참고하면 되고,

백엔드와의 소통은 결제 직전 정보 확인 통신과 결제 검증 통신이 있다만 그 외에는 

최대한 PaymentPage.js  파일 내에서 코드를 구현했다 

useEffect(() => {
dispatch(getProductDetail(productId))
.then(response => {
if (response.payload) {
setData(response.payload);
}
});
}, [dispatch, productId]);

user_actions.js에서 결제할 상품 통신 함수 코드인 getProductDetail 함수를 들고와 컨솔을 찍으니

데이터는 잘 담겨져왔었다

 

[user_actions.js]의 getProductDetail 함수 코드 혹시 모르니 같이 첨부해두겠다

export function getProductDetail(dataProductId) {
const token = localStorage.getItem('accessToken');
const request = axios.get(`/v1/data-products/1`, {
headers: {
Authorization: `Bearer ${token}`
},
withCredentials: true // withCredentials 옵션 추가
})

.then(response => {
if (response.data.code === 0) {
console.log(response.data.data)
return response.data.data;
 
} else {
console.error("Failed");
console.log(response.data.data)
return null;
}
})
.catch(error => {
console.error(error);
return null;
});
return {
type: GET_PRODUCT_DETAIL,
payload: request
};
}

 

 

이에 추가적으로 아래와 같이 requestPay 코드를 구현해서 아임포트에서 참고한 각 변수들을 차곡차곡 담아주었고,

const requestPay = () => {
if (!data) return; // 상품 데이터가 없는 경우 리턴

const timestamp = Date.now();
const milliseconds = timestamp % 1000; // Extract milliseconds part
const uniqueId = `order_${timestamp}_${milliseconds}`; // Combine timestamp and milliseconds
 
const IMP = window.IMP;
IMP.init("imp설정값 넣어주세요")
IMP.request_pay(
{
pg: "html5_inicis",
pay_method: "card",
merchant_uid: uniqueId, // Use the uniqueId here
name: data.title, // 상품 이름
amount: data.price, // 상품 가격

buyer_email: null,
buyer_name: null,
buyer_tel: null,
buyer_addr: null,
buyer_postcode: null
},
 
response => {
if (response.success) {

verifyAndProcessPayment(response);

console.log('결제 성공', response);
// alert('결제 성공');

// window.location.href = '/v1/verify';

} else {
console.error('결제 실패', response);
}
});
}

하단의 결제하기버튼과 쓰윽 연결해주었다

<button className="payment-btn" onClick={requestPay}>결제하기</button>

요렇게 설정해두면 결제하기 버튼을 눌렀을 때 포트 창과 연동이 된다

:>

 

 

 

구현하면서 가장 골칫거리는 바로 현재 창에서는 포트 연결이 되지만

결제 직후 또는 서버 재접속 시, script 에러가 나서 아예 페이지 자체도 접속하지못하는,,

이도저도 못하는 상황이 연속되었다

정말 꽝꽝 막막했지만 이때는

챗삐삐삐 보다눈 구글링이 답이었던 것

 

해결했던 방법 중 하나는 script를 index.html 내로 집어넣는 것이었다

사실 script를 어디에 설정할 지 몰라서 Payment.js  파일에 함께 담아두었는데 내가 봐도 문법이 영 이상하다싶었더니

역시나 오류는 여기엥서 났었던 것

<!-- PortOne SDK -->
<script src="https://cdn.iamport.kr/v1/iamport.js"></script>
<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js" ></script>
<!-- iamport.payment.js -->
<script type="text/javascript" src="https://cdn.iamport.kr/js/iamport.payment-1.1.8.js"></script>
<!--

이렇게 쏘옥 넣어주니 요번엔 다른 에러가 났다

 

'판매자 코드가 없다' 라는 에러였는데 이건 코드와 변수 설정의 문제인 것 같아

Payment.js 파일로 돌아와 merchant_uid: uniqueId, 변수 설정을 다시 해주었다

어떻게 했냐아 아주 작은 단위로 세세하게 쪼개서 중복되는 아이디가 없도록 설정을 해주었다

const IMP = window.IMP;
IMP.request_pay(
{
pg: "html5_inicis",
pay_method: "card",
merchant_uid: uniqueId, // Use the uniqueId here
name: data.title, // 상품 이름
amount: data.price, // 상품 가격

buyer_email: null,
buyer_name: null,
buyer_tel: null,
buyer_addr: null,
buyer_postcode: null
},

이 코드에서 밀리세컨드 단위까지 고려한 변수로 추가한 것

const timestamp = Date.now();
const milliseconds = timestamp % 1000; // Extract milliseconds part
const uniqueId = `order_${timestamp}_${milliseconds}`; // Combine timestamp and milliseconds
 

그리고 마지막으로 해준 건

IMP.init("imp31818680")

init 코드를 const IMP 내로 정의되게 해주었다

 

 

이렇게 코드 하나하나 잡아 뜯으니 오류가 안뜨더라

ㅠㅅㅠ 훕

곧 바 로 화면창이 슥슥 넘어가게 됐고 결국은 결제 성공했다

 

오늘 깨달은 건 오류가 날 때 오류가 나는 부분 쪽에

console창 세세하게 찍으며 오류가 무엇인지 확인해보고 직접 수정하는 것이 가장 효율적이라는 것이다

ㅎㅎ 요것들은

결제 구현하구 그리고 결제 검증까지 넘어가는 과정에서 에러를 잡으려고 수동적으로 결제했던 내역들

 

고생해쑤다아🖤