티스토리 뷰
반응형
위 사이트에서 가입 후
결제연동 > 연동정보에서 테스트 채널을 생성해준다.
대충 요렇게 필요한 채널키와 상점 아이디가 생성이 된다.
서버구성
결제 창 띄우기 위한 경로만 설정
더보기
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class ViewController {
@GetMapping("/")
public String movePayment() {
return "payment";
}
}
스프링에 내장된 templates 활용했다.
(/src/main/resources/templates/payment.html)
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Hello, World!</title>
<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js" ></script>
<script src="https://cdn.portone.io/v2/browser-sdk.js"></script>
<script>
async function requestPay2() {
const response = await PortOne.requestPayment({
storeId: "your-storeId",
channelKey: "your-channelKey",
paymentId: `payment001`,
orderName: "테스트 상품입니다.",
totalAmount: 1000,
currency: "KRW",
payMethod: "CARD",
customer: {
fullName: "포트원",
phoneNumber: "010-0000-1234",
email: "test@portone.io",
},
});
if (response.code !== undefined) {
// 오류 발생
return alert(response.message);
}
console.log(response);
}
</script>
</head>
<body>
<h1>Hello, World!</h1>
<button onclick="requestPay2()">KG이니시스 결제</button>
</body>
</html>
이렇게해서 서버 띄우고 접근하면 결제창이 바로 호출된다.
Rest API로 결제정보 확인하기
api 호출을 위한 키발급을 받자!
그리고 스프링에서 application.properties에 저장하자!
api 호출할 때 쓸 base-url도 같이 셋팅!!
portone.v2.api.base-url=https://api.portone.io
portone.v2.api.secret=
우선 웹통신 해야하니까 webflux 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-webflux'
PortOneClient 추가
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import java.util.HashMap;
import java.util.Map;
@Component
public class PortOneClient {
private final WebClient webClient;
@Value("${portone.v2.api.secret}")
private String apiSecret;
public PortOneClient(@Value("${portone.v2.api.base-url}") String baseUrl, @Value("${portone.v2.api.secret}") String apiSecret) {
this.webClient = WebClient.builder()
.baseUrl(baseUrl)
.defaultHeader("Authorization", "PortOne " + apiSecret)
.defaultHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
.build();
}
/**
* 포트원 API 인증 토큰 발급
*/
public String getAccessToken() {
Map<String, String> requestBody = new HashMap<>();
requestBody.put("apiSecret", apiSecret);
Map<String, Object> response = webClient
.post()
.uri("/login/api-secret")
.bodyValue(requestBody)
.retrieve()
.bodyToMono(Map.class)
.block();
if (response != null && response.containsKey("accessToken")) {
String token = (String) response.get("accessToken");
return token;
}
throw new RuntimeException("포트원 API 토큰 발급 실패");
}
/**
* 결제 상세 조회
*/
public Map<String, Object> getPaymentDetails(String paymentId) {
return webClient
.get()
.uri("/payments/" + paymentId)
.retrieve()
.bodyToMono(Map.class)
.block();
}
/**
* 결제 취소
*/
public Map<String, Object> cancelPayment(String paymentId, int cancelAmount, String reason) {
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("amount", cancelAmount);
requestBody.put("reason", reason);
return webClient
.post()
.uri("/payments/" + paymentId + "/cancel")
.bodyValue(requestBody)
.retrieve()
.bodyToMono(Map.class)
.block();
}
}
PaymentApi 구성
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RequestMapping("/api/payment")
public class PaymentApi {
private final PortOneClient portOneClient;
private final ObjectMapper mapper;
public PaymentApi(PortOneClient portOneClient) {
this.portOneClient = portOneClient;
this.mapper = new ObjectMapper();
}
@PostMapping("/complate")
public String getPaymentDetails(@RequestBody Map<String, String> request) {
String paymentId = request.get("paymentId");
if (paymentId == null || paymentId.trim().isEmpty()) {
return "paymentId 값이 필요합니다.";
}
// PortOne 클라이언트를 호출하여 결제 상세 정보를 조회합니다.
Map<String, Object> paymentDetails = portOneClient.getPaymentDetails(paymentId);
try {
// JSON 형식으로 보기 좋게 변환하여 응답합니다.
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(paymentDetails);
} catch (JsonProcessingException e) {
e.printStackTrace();
return "JSON 변환 중 오류 발생";
}
}
}
결제창 호출 할 때 쓰인 paymentId를 넣고 호출해보면 정보를 잘 가져옵니다.
그 밖에 필요한 API 문서는 아래 링크를 참고!
반응형
'그 외 > 기타' 카테고리의 다른 글
Nuxt3 WebSocket example #2 (0) | 2024.07.29 |
---|---|
Nuxt3 WebSocket example (with Nitro) (0) | 2024.07.27 |
Nuxt3 Mysql 연동하기 및 서버구성 (0) | 2024.07.12 |
Node와 express로 간단하게 서버 구축하기 (1) | 2024.07.11 |
포트 사용여부 확인 및 죽이기 (0) | 2020.04.13 |
댓글