1. 포트원 관리자 콘솔 계정 생성 후 로그인
2. 좌측 메뉴의 결제 연동 -> 연동정보로 들어가기
3. 테스트 를 선택하고 채널 추가
4. 연동모드, 결제대행사, 결제 모듈 선택
5. 채널 이름, 속성, CID 는 일반결제로 저장
이제 카카오페이 결제 api 발급이 끝났다!
그럼 프론트와 서버에 적용을 시켜보자
<button type="button" class="btn btn-outline-dark" onclick="pay()" style="margin-left: 20px">결제하기</button>
결제 버튼을 하나 만들고
const pay = async () => {
const response = await PortOne.requestPayment({
// Store ID 설정
storeId: "발급받은 storeId",
// 채널 키 설정
channelKey: "발급받은 channelKey",
paymentId: '상품명', // 상품명 넣는 곳
orderName: 'payment-' + generateUUID(), // randomUUID() 함수가 인식이 안돼서 비슷하게 만들었다.
totalAmount: 1000, // 결제금액
currency: "CURRENCY_KRW",
payMethod: "EASY_PAY",
});
if (response.code !== undefined) {
// 오류 발생
return alert(response.message);
}
console.log(response);
// /payment/complete 엔드포인트를 구현해야 합니다. 다음 목차에서 설명합니다.
const notified = await fetch(`요청보낼경로`, {
method: "POST",
headers: { "Content-Type": "application/json" },
// paymentId와 주문 정보를 서버에 전달합니다
body: JSON.stringify({
paymentId: response.paymentId,
// 주문 정보...
}),
});
}
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
이런 식으로 script를 짜주면 될거같다.
참고로 storeId랑 channelKey는 아래 사진처럼 나와있다.
response를 올바르게 입력하면 결제버튼을 눌렀을때 카카오페이 결제 QR코드가 나오고 가상결제가 가능하다.
가상결제는 가짜돈이니까 그냥 하면 될거같고
오류가 없으면 fetch가 실행될텐데 여기서 내 서버로 추가 처리를 위한 요청을 보내야한다.
왜 추가 처리를 해야할까에 대해 얘기해보면
나쁜 사용자가 클라이언트에서 10만원짜리 상품의 값을 만원으로 조작해버리는 경우를 생각해보자..
추가 검증이 없다면 아무것도 못하고 90% 세일을 해주게 되어버린다..!
그럼 서버에서 어떻게 해줘야할까?
결제한 ID를 서버에 보내서 해당 결제건에서 결제된 금액과 DB에 저장된 해당 상품의 금액을 대조해보면 쉽게 위변조를 체크할 수 있다.
만약 조작된 결제라면 주문을 넣지 않고 환불처리를 하던가라는 식의 조치를 해줄 수 있을 것이다.
서버에서 처리해주는 코드는 아래와 같다.
getPaymentInfo 함수에서 paymentId를 이용해 포트원에 해당 결제 건의 정보를 받는다.
이후 DB에서 해당 상품의 금액과 비교하는 부분은 아직 구현하지 않았다.
case "/payment" -> {
// 결제 처리
JSONObject jsonObject = JsonParser.parse(req);
String paymentId = jsonObject.getString("paymentId");
System.out.println(paymentId);
try {
// 단건 결제 조회 후 해당 결제 정보 JSON 객체로 받기
JSONObject jsonObject1 = Api.getPaymentInfo(paymentId);
// JSON 객체 파싱해서 결제정보중에 원하는 결제 값을 얻어내기
String status = jsonObject1.getString("status");
System.out.println(status);
JSONObject amountObject = jsonObject1.getJSONObject("amount");
int amount = amountObject.getInt("total");
// 얻은 결제금액으로 DB와 비교후 위변조 처리
} catch (Exception e) {
throw new RuntimeException(e);
}
}
getPaymentInfo 의 URL과 SECRETKEY 는 각자 환경에 맞게 세팅하면 될거같다.
public class Api {
public static JSONObject getPaymentInfo( String paymentId) throws Exception {
URL url = new URL(Constants.PAYMENT_API_URL +paymentId);
// HTTP 연결 설정
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Authorization", "PortOne " + Constants.SECRETKEY); // Authorization 헤더에 access token 추가
// 응답 받기
return JsonParser.parse(connection);
}
}
JSON 객체로 파싱해서 돌려주는 메서드
public static JSONObject parse(HttpServletRequest req) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader reader = req.getReader();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
return new JSONObject(sb.toString()); // JSON 파싱해서 return
}
'Java' 카테고리의 다른 글
[JAVA] Servlet Filter란? (0) | 2025.01.15 |
---|---|
[JAVA] Thread (0) | 2025.01.08 |
[JAVA] Java란 무엇인가 (3) | 2025.01.02 |