초기소스

This commit is contained in:
jazz
2025-10-29 17:08:05 +09:00
parent e531aa9540
commit 439a379a02
7551 changed files with 1234427 additions and 3 deletions

View File

@@ -0,0 +1,385 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="org.json.simple.JSONObject" %>
<%@ page import="org.json.simple.parser.JSONParser" %>
<%@ page import="org.json.simple.parser.ParseException" %>
<%@ page import="java.io.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.net.HttpURLConnection" %>
<%@ page import="java.net.URL" %>
<%@ page import="java.security.PrivateKey" %>
<%@ page import="java.nio.charset.StandardCharsets" %>
<%@ page import="java.security.Signature" %>
<%@ page import="java.security.SignatureException" %>
<%@ page import="java.security.NoSuchAlgorithmException" %>
<%@ page import="java.security.InvalidKeyException" %>
<%@ page import="java.nio.file.Files" %>
<%@ page import="java.nio.file.Path" %>
<%@ page import="java.nio.file.Paths" %>
<%@ page import="java.util.stream.Collectors" %>
<%@ page import="org.bouncycastle.asn1.ASN1Sequence" %>
<%@ page import="org.bouncycastle.asn1.pkcs.PrivateKeyInfo" %>
<%@ page import="org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo" %>
<%@ page import="org.bouncycastle.pkcs.PKCSException" %>
<%@ page import="org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter" %>
<%@ page import="org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder" %>
<%@ page import="org.bouncycastle.operator.InputDecryptorProvider" %>
<%@ page import="org.bouncycastle.operator.OperatorCreationException" %>
<%!
/*
==========================================================================
null 값을 처리하는 메소드
--------------------------------------------------------------------------
*/
public String f_get_parm( String val )
{
if ( val == null ) val = "";
return val;
}
/*
==========================================================================
서명데이터 생성 관련 메소드 (결제 취소시 필요)
--------------------------------------------------------------------------
*/
// 개인키 파일을 읽어 PrivateKey 객체 리턴
public static PrivateKey loadSplMctPrivateKeyPKCS8()
{
PrivateKey priKey = null;
// 개인키 인증서 경로 및 비밀번호(테스트용)
String filePath = "C:/gconedev/workspace/gconebo/src/main/resources/KCP_AUTH_A8HW6_CERT/splPrikeyPKCS8.pem";
String privateKeyPassword = "changeit";
try
{
Path path = Paths.get( filePath );
/*********************************
* PKCS#8 foramt 에서 header & footer 제거
*********************************/
String strPriKeyData = Files.readAllLines( path )
.stream()
.filter( line -> !line.startsWith( "-----BEGIN" ) && !line.startsWith( "-----END" ) )
.collect( Collectors.joining() );
// Base64 decoding
byte[] btArrPriKey = Base64.getDecoder().decode( strPriKeyData );
/*********************************
* PEMParser 적용 항목 선언
*********************************/
ASN1Sequence derSeq = ASN1Sequence.getInstance( btArrPriKey );
PKCS8EncryptedPrivateKeyInfo encPkcs8PriKeyInfo = new PKCS8EncryptedPrivateKeyInfo( org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance( derSeq ) );
/*********************************
* 복호화 & Key 변환
*********************************/
JcaPEMKeyConverter pemKeyConverter = new JcaPEMKeyConverter();
InputDecryptorProvider decProvider = new JceOpenSSLPKCS8DecryptorProviderBuilder().build( privateKeyPassword.toCharArray() );
PrivateKeyInfo priKeyInfo = encPkcs8PriKeyInfo.decryptPrivateKeyInfo( decProvider );
priKey = pemKeyConverter.getPrivateKey( priKeyInfo );
}
catch (IOException e)
{
e.printStackTrace();
}
catch (OperatorCreationException e)
{
e.printStackTrace();
}
catch (PKCSException e)
{
e.printStackTrace();
}
return priKey;
}
//Signature 데이터 생성
public static String makeSignatureData(String targetData)
{
String signData = null;
PrivateKey priKey = null;
priKey = loadSplMctPrivateKeyPKCS8();
byte[] btArrTargetData = targetData.getBytes( StandardCharsets.UTF_8 );
try {
Signature sign = Signature.getInstance( "SHA256WithRSA" );
sign.initSign( priKey );
sign.update( btArrTargetData );
byte[] btArrSignData = sign.sign();
signData = Base64.getEncoder().encodeToString( btArrSignData );
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
}
return signData;
}
%>
<%
request.setCharacterEncoding("UTF-8");
/*
==========================================================================
결제 API URL
--------------------------------------------------------------------------
*/
String target_URL = "https://stg-spl.kcp.co.kr/gw/mod/v1/cancel"; // 개발서버
//String target_URL = "https://spl.kcp.co.kr/gw/mod/v1/cancel"; // 운영서버
/*
==========================================================================
요청정보
--------------------------------------------------------------------------
*/
String site_cd = "T0007";//f_get_parm( request.getParameter( "site_cd" )); // 사이트코드
//인증서정보(직렬화)
String kcp_cert_info = "-----BEGIN CERTIFICATE-----MIIDgTCCAmmgAwIBAgIHBy4lYNG7ojANBgkqhkiG9w0BAQsFADBzMQswCQYDVQQGEwJLUjEOMAwGA1UECAwFU2VvdWwxEDAOBgNVBAcMB0d1cm8tZ3UxFTATBgNVBAoMDE5ITktDUCBDb3JwLjETMBEGA1UECwwKSVQgQ2VudGVyLjEWMBQGA1UEAwwNc3BsLmtjcC5jby5rcjAeFw0yMTA2MjkwMDM0MzdaFw0yNjA2MjgwMDM0MzdaMHAxCzAJBgNVBAYTAktSMQ4wDAYDVQQIDAVTZW91bDEQMA4GA1UEBwwHR3Vyby1ndTERMA8GA1UECgwITG9jYWxXZWIxETAPBgNVBAsMCERFVlBHV0VCMRkwFwYDVQQDDBAyMDIxMDYyOTEwMDAwMDI0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAppkVQkU4SwNTYbIUaNDVhu2w1uvG4qip0U7h9n90cLfKymIRKDiebLhLIVFctuhTmgY7tkE7yQTNkD+jXHYufQ/qj06ukwf1BtqUVru9mqa7ysU298B6l9v0Fv8h3ztTYvfHEBmpB6AoZDBChMEua7Or/L3C2vYtU/6lWLjBT1xwXVLvNN/7XpQokuWq0rnjSRThcXrDpWMbqYYUt/CL7YHosfBazAXLoN5JvTd1O9C3FPxLxwcIAI9H8SbWIQKhap7JeA/IUP1Vk4K/o3Yiytl6Aqh3U1egHfEdWNqwpaiHPuM/jsDkVzuS9FV4RCdcBEsRPnAWHz10w8CX7e7zdwIDAQABox0wGzAOBgNVHQ8BAf8EBAMCB4AwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAg9lYy+dM/8Dnz4COc+XIjEwr4FeC9ExnWaaxH6GlWjJbB94O2L26arrjT2hGl9jUzwd+BdvTGdNCpEjOz3KEq8yJhcu5mFxMskLnHNo1lg5qtydIID6eSgew3vm6d7b3O6pYd+NHdHQsuMw5S5z1m+0TbBQkb6A9RKE1md5/Yw+NymDy+c4NaKsbxepw+HtSOnma/R7TErQ/8qVioIthEpwbqyjgIoGzgOdEFsF9mfkt/5k6rR0WX8xzcro5XSB3T+oecMS54j0+nHyoS96/llRLqFDBUfWn5Cay7pJNWXCnw4jIiBsTBa3q95RVRyMEcDgPwugMXPXGBwNoMOOpuQ==-----END CERTIFICATE-----";
String tno = "24876447935038";//f_get_parm( request.getParameter( "tno" )); // NHN KCP 거래번호
String mod_ip = "127.0.0.1"; //f_get_parm( request.getParameter( "mod_ip" )); // 취소요청 IP
String mod_desc = f_get_parm( request.getParameter( "mod_desc" )); // 취소사유
String vcnt_yn = f_get_parm( request.getParameter( "vcnt_yn" )); // 배송업체명
/* = -------------------------------------------------------------------------- = */
String mod_type = "STE1"; //f_get_parm( request.getParameter( "mod_type" )); // 에스크로 상태변경 타입
String mod_type_check = f_get_parm( request.getParameter( "mod_type_check" )); // 에스크로 상태변경 타입 체크
String deli_numb = "789456123";//f_get_parm( request.getParameter( "deli_numb" )); // 송장번호
String deli_corp = "대한통운";//f_get_parm( request.getParameter( "deli_corp" )); // 배송업체명
String mod_mny = f_get_parm( request.getParameter( "mod_mny" )); // 부분취소 요청 금액
String rem_mny = f_get_parm( request.getParameter( "rem_mny" )); // 부분취소 가능 금액
String refund_account = f_get_parm( request.getParameter( "refund_account" )); // 환불계좌번호
String refund_nm = f_get_parm( request.getParameter( "refund_nm" )); // 환불계좌 예금주명
String bank_code = f_get_parm( request.getParameter( "bank_code" )); // 환불계좌 은행코드
String a_refund_account = f_get_parm( request.getParameter( "a_refund_account" )); // 환불계좌번호
String a_refund_nm = f_get_parm( request.getParameter( "a_refund_nm" )); // 환불계좌 예금주명
String a_bank_code = f_get_parm( request.getParameter( "a_bank_code" )); // 환불계좌 은행코드
String cancel_target_data = site_cd + "^" + tno + "^" + mod_type;
String kcp_sign_data = makeSignatureData(cancel_target_data);
String temp_req_param = "";
String req_data = "";
String temp_result = "";
String res_data = "";
JSONObject json_req = new JSONObject();
if(mod_type.equals("STE1"))
{
json_req.put("site_cd", site_cd); //
json_req.put("kcp_cert_info", kcp_cert_info); //
json_req.put("tno", tno);
json_req.put("mod_ip", mod_ip); //
json_req.put("mod_type",mod_type); //
json_req.put("deli_numb",deli_numb); //
json_req.put("deli_corp",deli_corp); //
json_req.put("kcp_sign_data",kcp_sign_data);
}
else if(mod_type.equals("STE2") || mod_type.equals("STE4") ||
mod_type.equals("STE3") || mod_type.equals("STE5"))
{
json_req.put("site_cd", site_cd);
json_req.put("kcp_cert_info", kcp_cert_info);
json_req.put("tno", tno);
json_req.put("mod_ip", mod_ip);
json_req.put("mod_desc", mod_desc);
json_req.put("mod_type",mod_type);
json_req.put("kcp_sign_data",kcp_sign_data);
if(vcnt_yn.equals("Y"))
{
json_req.put("refund_account",refund_account);
json_req.put("refund_nm",refund_nm);
json_req.put("bank_code",bank_code);
}
}
else if( mod_type_check.equals("STE9_A") || mod_type_check.equals("STE9_AP") ||
mod_type_check.equals("STE9_AR") || mod_type_check.equals("STE9_V") ||
mod_type_check.equals("STE9_VP"))
{
json_req.put("site_cd", site_cd);
json_req.put("kcp_cert_info", kcp_cert_info);
json_req.put("tno", tno);
json_req.put("mod_ip", mod_ip);
json_req.put("mod_desc", mod_desc);
json_req.put("kcp_sign_data",kcp_sign_data);
json_req.put("mod_desc_cd", "CA06");
json_req.put("mod_type",mod_type);
if(mod_type_check.equals("STE9_A"))
{
json_req.put("sub_mod_type", "STSC");
json_req.put("mod_sub_type", "MDSC03");
}
if(mod_type_check.equals("STE9_AP"))
{
json_req.put("sub_mod_type", "STPC");
json_req.put("mod_sub_type", "MDSC04");
json_req.put("part_canc_yn", "Y");
json_req.put("rem_mny", rem_mny);
json_req.put("mod_mny", mod_mny);
}
if(mod_type_check.equals("STE9_AR"))
{
json_req.put("sub_mod_type", "STHD");
json_req.put("mod_sub_type", "MDSC04");
json_req.put("mod_account", a_refund_account);
json_req.put("mod_bankcode", a_bank_code);
json_req.put("mod_depositor", a_refund_nm);
}
if(mod_type_check.equals("STE9_V"))
{
json_req.put("sub_mod_type", "STHD");
json_req.put("mod_sub_type", "MDSC00");
json_req.put("mod_account", a_refund_account);
json_req.put("mod_bankcode", a_bank_code);
json_req.put("mod_depositor", a_refund_nm);
}
if(mod_type_check.equals("STE9_VP"))
{
json_req.put("sub_mod_type", "STPD");
json_req.put("mod_sub_type", "MDSC04");
json_req.put("part_canc_yn", "Y");
json_req.put("rem_mny", rem_mny);
json_req.put("mod_mny", mod_mny);
json_req.put("mod_account", a_refund_account);
json_req.put("mod_bankcode", a_bank_code);
json_req.put("mod_depositor", a_refund_nm);
}
}
String temp_req_data = json_req.toString();
req_data = temp_req_data.replace(",",",\r\n");
String inputLine = null;
StringBuffer outResult = new StringBuffer();
try
{
// API REQ
URL url = new URL(target_URL);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept-Charset", "UTF-8");
OutputStream os = conn.getOutputStream();
os.write(req_data.getBytes("UTF-8"));
os.flush();
// API RES
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
while ((inputLine = in.readLine()) != null)
{
outResult.append(inputLine);
}
conn.disconnect();
}
catch(Exception e)
{
e.printStackTrace();
}
temp_result = outResult.toString();
res_data = temp_result.replace(",",",\r\n");
// RES JSON DATA Parsing
JSONParser parser = new JSONParser();
JSONObject json_res = (JSONObject)parser.parse(temp_result);
%>
<!DOCTYPE html>
<html>
<head>
<title>*** NHN KCP API SAMPLE ***</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=yes, target-densitydpi=medium-dpi">
<link href="../static/css/style.css" rel="stylesheet" type="text/css"/>
</head>
<body oncontextmenu="return false;">
<div class="wrap">
<!-- header -->
<div class="header">
<a href="index.html" class="btn-back"><span>뒤로가기</span></a>
<h1 class="title">TEST SAMPLE</h1>
</div>
<!-- //header -->
<!-- contents -->
<div id="skipCont" class="contents">
<h2 class="title-type-3">요청 DATA</h2>
<ul class="list-type-1">
<li>
<div class="left">
<p class="title"></p>
</div>
<div class="right">
<div class="ipt-type-1 pc-wd-3">
<textarea style="height:200px; width:450px" readonly><%=req_data%></textarea>
</div>
</div>
</li>
</ul>
<h2 class="title-type-3">응답 DATA </h2>
<ul class="list-type-1">
<li>
<div class="left">
<p class="title"></p>
</div>
<div class="right">
<div class="ipt-type-1 pc-wd-3">
<textarea style="height:200px; width:450px" readonly><%=res_data%></textarea>
</div>
</div>
</li>
</ul>
<ul class="list-btn-2">
<li class="pc-only-show"><a href="../index.html" class="btn-type-3 pc-wd-2">처음으로</a></li>
</ul>
</div>
<div class="grid-footer">
<div class="inner">
<!-- footer -->
<div class="footer">
ⓒ NHN KCP Corp.
</div>
<!-- //footer -->
</div>
</div>
</div>
<!--//wrap-->
</body>
</html>