๐Ÿ“Œ PortOne ๊ฒฐ์ œ ์‹œ์Šคํ…œ ์—ฐ๋™ (๊ฒฐ์ œํ•˜๊ธฐ + Access Token ๋ฐœ๊ธ‰ + ๋‹ค๊ฑด ์กฐํšŒ)

My Pale Blue Dotยท2025๋…„ 5์›” 15์ผ
0

SPRING BOOT

๋ชฉ๋ก ๋ณด๊ธฐ
32/40
post-thumbnail

๐Ÿ“Œ PortOne ๊ฒฐ์ œ ์‹œ์Šคํ…œ ์—ฐ๋™ (๊ฒฐ์ œํ•˜๊ธฐ + Access Token ๋ฐœ๊ธ‰ + ๋‹ค๊ฑด ์กฐํšŒ)

๐Ÿ“… ๋‚ ์งœ

2025-05-15


๐Ÿ“ ํ•™์Šต ๋‚ด์šฉ

1๏ธโƒฃ PortOne ๊ด€๋ฆฌ์ž ์ฝ˜์†” ์ค€๋น„


2๏ธโƒฃ HTML: ๊ฒฐ์ œ & ๋ณธ์ธ์ธ์ฆ ๋ฒ„ํŠผ ํ…Œ์ŠคํŠธ

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>PortOne ํ…Œ์ŠคํŠธ</title>
</head>
<body>

<!-- UI -->
<button onclick="pay()">๊ฒฐ์ œํ•˜๊ธฐ</button> |
<button onclick="auth()">๋ณธ์ธ์ธ์ฆ</button>

<!-- PortOne SDK ๋กœ๋“œ -->
<script src="https://cdn.iamport.kr/v1/iamport.js"></script>
<script>
    IMP.init("imp68801222"); // ๊ณ ๊ฐ์‚ฌ ์‹๋ณ„ ์ฝ”๋“œ

    function pay() {
        IMP.request_pay({
            channelKey: "channel-key-xxxxx",
            pay_method: "phone",
            merchant_uid: "merchant_" + crypto.randomUUID(), // ๊ณ ์œ  ์ฃผ๋ฌธ๋ฒˆํ˜ธ
            name: "ํ…Œ์ŠคํŠธ ๊ฒฐ์ œ",
            amount: 100,
            buyer_tel: "010-0000-0000"
        });
    }

    function auth() {
        IMP.certification({
            channelKey: "channel-key-xxxxx",
            merchant_uid: "test_" + new Date().toString()
        }, function(resp) {
            console.log(resp); // ๋ณธ์ธ์ธ์ฆ ๊ฒฐ๊ณผ ์ฝœ๋ฐฑ
        });
    }
</script>

</body>
</html>

3๏ธโƒฃ Spring Boot - Access Token ๋ฐœ๊ธ‰

@GetMapping("/getToken")
@ResponseBody
public void getToken() {
    log.info("GET/portOne/getToken");

    String url = "https://api.iamport.kr/users/getToken";

    HttpHeaders header = new HttpHeaders();
    MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
    params.add("imp_key", RESTAPI_KEY);       // ๋ฐœ๊ธ‰๋ฐ›์€ ํ‚ค ์ž…๋ ฅ
    params.add("imp_secret", RESTAPI_SECRET); // ๋ฐœ๊ธ‰๋ฐ›์€ ์‹œํฌ๋ฆฟ ์ž…๋ ฅ

    HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, header);

    RestTemplate rt = new RestTemplate();
    ResponseEntity<PortOneTokenResponse> response = rt.exchange(url, HttpMethod.POST, entity, PortOneTokenResponse.class);

    this.portOneTokenResponse = response.getBody(); // ์ถ”ํ›„ ์กฐํšŒ์— ์‚ฌ์šฉ
    System.out.println(this.portOneTokenResponse);
}

4๏ธโƒฃ Access Token ์‘๋‹ต DTO

@Data
private static class TokenData {
    public String access_token;
    public int now;
    public int expired_at;
}

@Data
private static class PortOneTokenResponse {
    public int code;
    public Object message;
    public TokenData response;
}

5๏ธโƒฃ ๊ฒฐ์ œ ๋‚ด์—ญ ๋‹ค๊ฑด ์กฐํšŒ

@GetMapping("/getPayments")
@ResponseBody
public void payments() {
    log.info("GET/portOne/getPayments...");

    // imp_uid ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค๊ฑด ์กฐํšŒ
    String url = "https://api.iamport.kr/payments?imp_uid[]=imp_xxxxx";

    HttpHeaders header = new HttpHeaders();
    header.add("Authorization", "Bearer " + this.portOneTokenResponse.getResponse().getAccess_token());
    header.add("Content-Type", "application/json");

    HttpEntity<?> entity = new HttpEntity<>(header);

    RestTemplate rt = new RestTemplate();
    ResponseEntity<String> response = rt.exchange(url, HttpMethod.GET, entity, String.class);

    System.out.println(response);
}

โœ… ์‘๋‹ต ์˜ˆ์‹œ (๋งˆ์Šคํ‚น ์ฒ˜๋ฆฌ)

{
  "code": 0,
  "message": null,
  "response": [
    {
      "amount": 100,
      "buyer_tel": "010-0000-0000",
      "imp_uid": "imp_",
      "merchant_uid": "merchant_",
      "pay_method": "phone",
      "pg_provider": "danal",
      "status": "paid"
    }
  ]
}

๐Ÿ”ฅ ์ •๋ฆฌ

  • PortOne ๊ด€๋ฆฌ์ž ์ฝ˜์†”์—์„œ ์ฑ„๋„ ์ƒ์„ฑ ๋ฐ ์—ฐ๋™ํ‚ค ๋ฐœ๊ธ‰ โ†’ HTML์—์„œ SDK ํ…Œ์ŠคํŠธ
  • ์„œ๋ฒ„์—์„œ๋Š” Access Token์„ ๋ฐœ๊ธ‰๋ฐ›๊ณ , ํ† ํฐ์„ ์‚ฌ์šฉํ•ด ๊ฒฐ์ œ ๋‚ด์—ญ์„ ์กฐํšŒ
  • imp_uid ๋ฐฐ์—ด๋กœ ๋‹ค๊ฑด ์กฐํšŒ ๊ฐ€๋Šฅ (207 Multi-Status ์‘๋‹ต์€ ์ •์ƒ)

๐Ÿ”— ์ฐธ๊ณ  ์ž๋ฃŒ


profile
Here, My Pale Blue.๐ŸŒ

0๊ฐœ์˜ ๋Œ“๊ธ€