[Iamport] 계좌 인증 기능 구현하기
본 포스트에서는 Iamport API를 활용하여 판매자가 입력한 계좌의 유효성을 인증하는 기능 구현 과정을 상세히 안내합니다.
일급기밀 프로젝트를 진행하면서, 판매자가 입력한 계좌가 유효한 계좌인지 (금융기관, 계좌번호, 예금주 가 유효한지) 인증하는 기능을 구현해야 했다.
이를 위해 오픈뱅킹과 같은 서비스들을 알아봤지만, 다음과 같은 이유로 Iamport 를 선택하였다.
1. 기존에 결제 기능을 위해서 Iamport 의 유료 서비스를 이용하고 있었음.
2. 오픈뱅킹에 비해서 코드가 간결하고, 가볍다는 느낌이 들었다.
참고한 API 도큐먼트 : https://api.iamport.kr/#!/vbanks/queryBankHolder
[이를 바탕으로 작성한 IamportUtil 파일]
/*
CREATED BY KHJ
2020.05
*/
package com.pieceofmood.pdf.util;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.eclipse.core.internal.jobs.ObjectMap;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class IamportUtil {
@Value("${IAMPORT_REST_API_KEY}")
private String IAMPORT_REST_API_KEY;
@Value("${IAMPORT_REST_API_SECRET}")
private String IAMPORT_REST_API_SECRET;
@Value("${IAMPORT_REST_URI}")
private String IAMPORT_REST_URI;
private JSONParser parser = new JSONParser();
public String getAccessToken() {
/*
Iamport 의 REST API 를 이요하기 전에,
접근을 허가해 줄 수 있는 Access Token 을 반환한다.
*/
String requestURI = IAMPORT_REST_URI + "/users/getToken";
JSONObject jsonObject = new JSONObject();
jsonObject.put("imp_key", IAMPORT_REST_API_KEY);
jsonObject.put("imp_secret", IAMPORT_REST_API_SECRET);
String json = jsonObject.toString();
Object rawResponse;
try {
rawResponse = parser.parse(doPost(requestURI, null, json));
JSONObject jsonObj = (JSONObject) rawResponse;
JSONObject response = (JSONObject) jsonObj.get("response");
String accessToken = (String) response.get("access_token");
LogUtil.info("ACCESS TOKEN : " + accessToken);
return accessToken;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
public String getBankAccountHolder(String bankCode, String bankNum) {
/*
1. Iamport 에서 지급해 주는 Access Token 을 Response 로 받는다.
2. Iamport REST API 를 이용하여, 금융 기관 Code, 계좌번호를 parameter 로 넘기면 예금주를 반환받는다.
*/
String holder = "";
String requestURI = IAMPORT_REST_URI + "/vbanks/holder";
requestURI = appendUri(requestURI, "bank_code", bankCode);
requestURI = appendUri(requestURI, "bank_num", bankNum);
LogUtil.info("REQUEST URI : " + requestURI);
String accessToken = getAccessToken();
if(!StringUtil.isEmpty(accessToken)) {
try {
Object rawResponse = parser.parse(doGet(requestURI, accessToken));
JSONObject jsonObj = (JSONObject) rawResponse;
JSONObject response = (JSONObject) jsonObj.get("response");
holder = (String) response.get("bank_holder");
} catch (ParseException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
return "계좌 정보 없음";
}
}
LogUtil.info("BANK HOLDER : " + holder);
return holder;
}
private String doGet(String requestURI, String accessToken) {
String output = "";
String readline = "";
try {
URL url = new URL(requestURI);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestProperty("charset", "utf-8");
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
/*
Authorization : "Bearer + Access Token" 의 형태로 인증 과정을 거친다.
*/
BufferedReader br = null;
if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED
&& conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
if(conn.getResponseCode() == 401) {
return "401";
}
LogUtil.info(conn.getResponseMessage());
br = new BufferedReader(new InputStreamReader(conn.getErrorStream(), "utf-8"));
} else {
br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
}
while((readline = br.readLine()) != null) {
// output += readline;
// remove backslash
//output += readline.replaceAll("\\\\", "");
output += readline;
}
LogUtil.info("POST REQUEST OUTPUT : " + output);
conn.disconnect();
return output;
}
catch(IOException e) {
e.printStackTrace();
}
return output;
}
private String doPost(String requestURI, String accessToken, String data) {
try {
String output = "";
String readline = "";
URL url = new URL(requestURI);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setRequestProperty("charset", "utf-8");
conn.setUseCaches(false);
if(!StringUtil.isEmpty(accessToken)) {
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
}
if(!StringUtil.isEmpty(data)) {
byte[] paramData = data.getBytes("UTF-8");
int paramDataLength = paramData.length;
conn.setRequestProperty("Content-Length", Integer.toString(paramDataLength));
try( DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) {
wr.write(paramData);
}
}
BufferedReader br = null;
if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED
&& conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
// CommonUtil.print(conn.getResponseCode());
if(conn.getResponseCode() == 401) {
return "401";
}
LogUtil.info(conn.getResponseMessage());
br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
} else {
br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
}
while((readline = br.readLine()) != null) {
// output += readline;
// remove backslash
output += readline.replaceAll("\\\\", "");
}
LogUtil.info("POST REQUEST OUTPUT : " + output);
conn.disconnect();
return output;
}
catch(IOException e) {
e.printStackTrace();
}
return null;
}
private static String appendUri(String uri, String key, String value) {
/*
요청하는 URI 에 Parameter 를 붙여나간다.
*/
try {
URI oldUri = new URI(uri);
String newQuery = oldUri.getQuery();
if (newQuery == null) {
newQuery = key + "=" + value;
} else {
newQuery += "&" + key + "=" + value;
}
URI newUri = new URI(oldUri.getScheme(), oldUri.getAuthority(),
oldUri.getPath(), newQuery, oldUri.getFragment());
return newUri.toString();
}
catch(URISyntaxException e) {
e.printStackTrace();
}
return "";
}
private List<Map<String, String>> getBankCodes(String accessToken) {
ObjectMapper mapper = new ObjectMapper();
List<Map<String, String>> result = new ArrayList<>();
String requestUri = IAMPORT_REST_URI + "/banks";
String response = doGet(requestUri, accessToken);
JsonNode json = null;
JsonNode banks = null;
try {
json = mapper.readValue(response, JsonNode.class);
banks = json.get("response");
if(banks.isArray()) {
for(JsonNode bank : banks) {
result.add(mapper.convertValue(bank, Map.class));
}
}
} catch(IOException e) {
e.printStackTrace();
}
return result;
}
}
이것도 읽어보세요