Skip to content

Instantly share code, notes, and snippets.

@ygpark2
Created May 27, 2016 00:53
Show Gist options
  • Save ygpark2/8b5deb5dbfa9570a7dd56c5117d074e6 to your computer and use it in GitHub Desktop.
Save ygpark2/8b5deb5dbfa9570a7dd56c5117d074e6 to your computer and use it in GitHub Desktop.
Smartro 결제 관련 자바 클래스
package com.kdn.evcs.service;
import kr.co.smartro.xpg_pay.crypt;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.net.URLCodec;
import org.aspectj.lang.annotation.Before;
import org.codehaus.jackson.JsonProcessingException;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriTemplate;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author : Young Gyu Park
* @date : 2016. 4. 4.
* @ClassRole : Smartro 관련 Service
*/
@Service("smartroService")
public class SmartroService {
@Value("${smartro.send_mid}")
private String sendMID;
@Value("${smartro.merchant_key}")
private String merchantKey;
@Value("${smartro.cashrcpt_url}")
private String smartro_cashrcpt_url;
@Value("${smartro.cardbill_url}")
private String smartro_cardbill_url;
@Value("${smartro.cellphone_url}")
private String smartro_cellphone_url;
@Value("${smartro.bill_key_action_url}")
private String smartro_bill_key_action_url;
@Value("${smartro.cancel_url}")
private String smartro_cancel_url;
@Value("${smartro.billing_return_page}")
private String smartro_billing_return_page;
@Value("${smartro.result_split}")
private String smartro_result_split;
private String billKeyMode = "0"; // 0 : 빌링키 암호화 리턴, 1 : 빌링키 평문리턴
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
private URLCodec urlCodec = new URLCodec();
private List<String> billingKeyNames = Arrays.asList("PayMethod", "GoodsCnt", "GoodsName",
"Amt", "Moid", "MID", "ReturnURL",
"RetryURL", "mallUserID", "BuyerName",
"BuyerTel", "BuyerEmail", "ParentEmail",
"BuyerAddr", "BuyerPostNo", "UserIP",
"MallIP", "VbankExpDate", "EncryptData",
"MallReserved", "FORWARD", "ResultYN",
"MallResultFWD", "TransType", "EncodingType",
"GoodsCl", "OpenType", "OfferPeriod",
"CustCI", "BillType");
private List<String> cashrcptPayParamNames = Arrays.asList("PayMethod", "ediDate", "GoodsCnt",
"GoodsName", "Amt", "Moid", "MID", "BL_TID", "CardQuota", "ChannelType", "VERIFY_V",
"MallIP", "MallReserved", "MallUserID", "BuyerName", "BuyerTel", "BuyerEmail",
"ParentEmail", "BuyerAddr", "BuyerPostNo", "UserIP", "ReturnURL", "RetryURL", "SUB_ID",
"ReceiptSupplyAmt", "ReceiptVAT", "ReceiptServiceAmt", "ReceiptIdentity",
"CashReceiptType", "GoodsCl", "ReturnType", "BillKeyMode");
private List<String> cardBillPayParamNames = Arrays.asList("PayMethod", "ediDate", "GoodsCnt",
"GoodsName", "Amt", "Moid", "MID", "BL_TID", "CardQuota", "ChannelType", "VERIFY_V",
"MallIP", "MallReserved", "MallUserID", "BuyerName", "BuyerTel", "BuyerEmail",
"ParentEmail", "BuyerAddr", "BuyerPostNo", "UserIP", "BillKeyMode");
private List<String> cardBillPayReturnParamNames = Arrays.asList("PayMethod", "MID", "Amt",
"Name", "GoodsName", "mallUserID", "TID", "OID", "AuthDate", "AuthCode", "ResultCode",
"ResultMsg", "MallReserved", "fn_cd", "fn_name", "BuyerEmail", "VerifyValue");
private List<String> cancelParamNames = Arrays.asList("PayMethod", "MID", "CancelAmt", "TID",
"Cancelpw", "CancelMSG", "EncodingType", "ReturnURL");
private List<String> billingKeyParamNames = Arrays.asList("payType", "EncryptData", "GoodsCnt",
"GoodsName", "Amt", "GoodsURL", "Moid", "MID", "ReturnURL", "ResultYN",
"RetryURL", "mallUserID", "BuyerName", "BuyerAuthNum", "BuyerTel", "BuyerEmail",
"ParentEmail", "BuyerAddr", "BuyerPostNo", "UserIP", "MallIP", "VbankExpDate",
"BrowserType", "PayMethod", "ediDate", "MallReserved", "FORWARD", "MallResultFWD",
"SUB_ID", "EncodingType", "Language", "OpenType",
"GoodsCl", "OfferPeriod", "CustCI", "BillType", "BillKeyMode");
private List<String> billingKeyReturnParamNames = Arrays.asList("PayMethod", "MID", "TID", "Amt",
"BuyerName", "mallUserID", "GoodsName", "GoodsCl", "OID", "AuthDate", "AuthCode",
"ResultCode", "ResultMsg", "VbankNum", "MallReserved", "CardUsePoint", "AcquCardCode",
"AcquCardName", "pinNo", "SignValue", "BillTid", "VerifyValue", "BillKeyMode");
private RestTemplate restTemplate = new RestTemplate();
@Before("setUp")
public void setUp() {
System.out.println("======================= smartroService =======================");
System.out.println("======================= setup =======================");
System.out.println("======================= ============== =======================");
restTemplate = new RestTemplate();
}
public void diffTest() {
ArrayList<String> a1 = new ArrayList<String>(billingKeyParamNames);
ArrayList<String> a2 = new ArrayList<String>(cardBillPayParamNames);
a1.removeAll(a2);
for (String keyName : a1) {
System.out.println(keyName);
}
}
private String getCardBillPayUrl() {
String smartro_cardbill_new_url = smartro_cardbill_url + "?";
for (String keyName : cardBillPayParamNames) {
smartro_cardbill_new_url += keyName + "={" + keyName + "}&";
}
return smartro_cardbill_new_url;
}
private String getCashrcptPayUrl() {
String smartro_cashrcpt_new_url = smartro_cashrcpt_url + "?";
for (String keyName : cashrcptPayParamNames) {
smartro_cashrcpt_new_url += keyName + "={" + keyName + "}&";
}
return smartro_cashrcpt_new_url;
}
private Map<String, String> getBillingKeyPayDefaultParams (String sBaseUrl) {
Map<String, String> params = new HashMap<String, String>()
{
{
String ediDate = dateFormat.format(new Date());
SimpleDateFormat offerPeriodFormat = new SimpleDateFormat("yyyyMMdd");
int goodsAmt = 100;
String encryptData = encodeMD5HexBase64(ediDate + sendMID + goodsAmt + merchantKey);
put("payType", String.valueOf(getPayType("CARDBILL")));
put("EncryptData", encryptData);
put("GoodsCnt", "01");
put("GoodsName", "빌링키인증");
put("Amt", String.valueOf(goodsAmt));
put("PayMethod", getPayMethod("CARDBILL"));
put("Moid", "00000001");
put("MID", sendMID);
put("ResultYN", "Y");
put("FORWARD", "Y"); // disable new popup from smartro
put("RetryURL", "https://tpay.smilepay.co.kr/inform.jsp");
put("OfferPeriod", offerPeriodFormat.format(new Date()));
put("MallIP", getIpAddress());
put("ediDate", ediDate);
put("EncodingType", "utf8");
put("SUB_ID", "test"); // 회원사 아이디
put("GoodsCl", "1"); // 결제구분 => 실물 : 1, 컨텐츠 : 0
put("OpenType", "KR"); // 오픈타입 => 한글 : KR, 영어 : EN
put("CustCI", "Y28798374M"); // 고객매칭정보
put("BillType", "AR"); // AR : 빌링키발급, AA : 결제+빌링키발급
put("BillKeyMode", billKeyMode); // 0 : 빌링키 암호화 리턴, 1 : 빌링키 평문리턴
put("MallResultFWD", "N");
}
};
params.put("ReturnURL", sBaseUrl + "/" + smartro_billing_return_page);
return params;
}
public String getBillingKeyPayJsonParams(String sBaseUrl) {
Map<String, String> defaultParams = getBillingKeyPayDefaultParams(sBaseUrl);
Map<String, String> params = new HashMap<String, String>();
for (String keyName : billingKeyParamNames) {
if (defaultParams.containsKey(keyName)) {
params.put(keyName, defaultParams.get(keyName));
} else {
params.put(keyName, "");
}
};
params.put("billPayActionUrl", smartro_bill_key_action_url);
JSONObject json = new JSONObject();
json.putAll( params );
return json.toJSONString();
}
public Map<String, String> getBillingKeyReturnParams(HttpServletRequest request) throws UnsupportedEncodingException {
Map<String, String> params = new HashMap<String, String>();
for (String keyName : billingKeyReturnParamNames) {
String value = request.getParameter(keyName) == null ? "" : request.getParameter(keyName);
params.put(keyName, value);
/* ===================================================================
switch (keyName) {
case "BuyerName":
System.out.println(" BuyerName origin value => " + value);
System.out.println(" BuyerName encoding value => " + new String(value.getBytes("EUC-KR"), "UTF-8"));
case "GoodsName":
System.out.println(" GoodsName origin value => " + value);
System.out.println(" GoodsName encoding value => " + new String(value.getBytes("EUC-KR"), "UTF-8"));
System.out.println("");
case "ResultMsg":
System.out.println(" ResultMsg origin value => " + value);
System.out.println(" ResultMsg encoding value => " + new String(value.getBytes("EUC-KR"), "UTF-8"));
System.out.println("");
// params.put(keyName, new String(value.getBytes("8859_1"), "EUC-KR"));
break;
default:
params.put(keyName, value);
break;
}
======================================================================= */
}
String firstTID = params.get("TID").substring(0, 10);
String midTID = params.get("TID").substring(10, 15);
String lastTID = params.get("TID").substring(15, params.get("TID").length());
String VerifySignValue = encodeMD5HexBase64(firstTID + params.get("ResultCode") + midTID + merchantKey + lastTID);
params.put("VerifySignValue", VerifySignValue);
String AuthDate = params.get("AuthDate");
String AuthCode = params.get("AuthCode");
String BillTid = params.get("BillTid");
String MID = params.get("MID");
String VerifyBillKeyValue ="";
if("0".equals(params.get("BillKeyMode"))) {
String decryptBillTid = getDecryptBillTID(BillTid);
params.put("DecryptBillTid", decryptBillTid);
VerifyBillKeyValue = encodeMD5HexBase64(MID+merchantKey+AuthDate+AuthCode+decryptBillTid);
} else {
VerifyBillKeyValue = encodeMD5HexBase64(MID+merchantKey+AuthDate+AuthCode+BillTid);
}
params.put("VerifyBillKValue", VerifyBillKeyValue);
return params;
}
private Map<String, String> getCardBillPayDefaultParams () {
Map<String, String> params = new HashMap<String, String>()
{
{
String ediDate = dateFormat.format(new Date());
put("PayMethod", getPayMethod("CARDBILL"));
put("ediDate", ediDate);
put("GoodsCnt", "01");
put("GoodsName", "충전전력 kWh당 단가적용 요금제");
put("MID", sendMID);
put("CardQuota", "00");
put("ChannelType", "WBL");
put("MallIP", getIpAddress());
put("UserIP", getIpAddress());
}
};
return params;
}
public Map<String, String> cardBillPay(String Amt, String billKeyMode, String BL_TID, String Moid, String BuyerName, String BuyerTel, String BuyerEmail, String ParentEmail, String BuyerAddr, String BuyerPostNo) throws UnsupportedEncodingException {
String callUrl = getCardBillPayUrl();
Map<String, String> defaultParams = getCardBillPayDefaultParams();
Map<String, String> params = new HashMap<String, String>();
for (String keyName : cardBillPayParamNames) {
if (defaultParams.containsKey(keyName)) {
params.put(keyName, defaultParams.get(keyName));
} else {
params.put(keyName, "");
}
}
params.put("Amt", Amt);
params.put("Moid", Moid);
params.put("BuyerName", BuyerName);
params.put("BuyerTel", BuyerTel);
params.put("BuyerEmail", BuyerEmail);
params.put("ParentEmail", ParentEmail);
params.put("BuyerAddr", BuyerAddr);
params.put("BuyerPostNo", BuyerPostNo);
params.put("BillKeyMode", billKeyMode);
params.put("BuyerPostNo", BuyerPostNo);
String VerifyValue = params.get("MID") + merchantKey + params.get("ediDate") + params.get("Amt") + BL_TID;
params.put("VERIFY_V", encodeMD5HexBase64(VerifyValue) );
if("0".equals(billKeyMode)) {
String encryptedBillTID = getEncryptBillTID(BL_TID);
params.put("BL_TID", UrlencodeBase64(encryptedBillTID));
} else {
params.put("BL_TID", BL_TID);
}
// System.out.println("VerifyValue : "+VerifyValue);
UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(callUrl);
URI uri = urlBuilder.build(false).expand(params).encode("EUC-KR").toUri();
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("EUC-KR")));
String responseBody = restTemplate.getForObject(uri, String.class);
System.out.println("******* card bill pay response => " + responseBody.trim());
return getResultParsingValues(responseBody.trim(), BL_TID);
}
public String cancelPayment(String TID, String CancelAmt, String CancelMSG, String ReturnURL) {
Map<String, String> params = new HashMap<String, String>();
for (String keyName : cancelParamNames) {
switch (keyName) {
case "TID":
params.put(keyName, TID);
break;
case "CancelAMT":
params.put(keyName, CancelAmt);
break;
case "CancelMSG":
params.put(keyName, CancelMSG);
break;
case "ReturnURL":
params.put(keyName, ReturnURL);
break;
default:
params.put(keyName, "");
break;
}
}
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "text/html,application/xhtml+xml,application/xml");
HttpEntity entity = new HttpEntity(headers);
// HttpEntity<String> response = restTemplate.exchange(smartro_cancel_url, HttpMethod.POST, entity, String.class, params);
Map<String, String> rspMap = restTemplate.postForObject(smartro_cancel_url, params, Map.class);
// System.out.println("response => " + response.getHeaders());
// System.out.println("response => " + response.getBody().trim());
return "";
}
public String testCashrcptPay() {
String callUrl = getCashrcptPayUrl();
SimpleDateFormat yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss");
String ediDate = yyyyMMddHHmmss.format(new Date());
Map<String, String> params = new HashMap<String, String>();
params.put("PayMethod", "CASHRCPT");
params.put("ediDate", ediDate);
params.put("GoodsCnt", "01");
params.put("GoodsName", "테스트 상품 이름");
params.put("Amt", "1100");
params.put("Moid", "0001");
params.put("MID", sendMID);
params.put("BL_TID", "");
params.put("CardQuota", "");
params.put("ChannelType", "");
params.put("VERIFY_V", "");
params.put("MallIP", "");
params.put("MallReserved", "");
params.put("MallUserID", "");
params.put("BuyerName", "홍길동");
params.put("BuyerTel", "01010101010");
params.put("BuyerEmail", "test@smartro.co.kr");
params.put("ParentEmail", "");
params.put("BuyerAddr", "");
params.put("BuyerPostNo", "");
params.put("UserIP", "");
params.put("ReturnURL", "");
params.put("RetryURL", "");
params.put("SUB_ID", "");
params.put("ReceiptSupplyAmt", "1000");
params.put("ReceiptVAT", "100");
params.put("ReceiptServiceAmt", "0");
params.put("ReceiptIdentity", "01073760311");
params.put("CashReceiptType", "1");
params.put("GoodsCl", "");
params.put("ReturnType", "TEXT");
params.put("BillKeyMode", "1");
String strVERIFY_V = params.get("ReceiptIdentity");
strVERIFY_V += params.get("Moid");
strVERIFY_V += merchantKey;
strVERIFY_V += params.get("ediDate");
strVERIFY_V += params.get("ReceiptSupplyAmt");
strVERIFY_V += params.get("ReceiptVAT");
strVERIFY_V += params.get("ReceiptServiceAmt");
strVERIFY_V += params.get("Amt");
System.out.println("strVERIFY_V:"+strVERIFY_V);
params.put("VERIFY_V", encodeMD5HexBase64(strVERIFY_V) );
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "text/html,application/xhtml+xml,application/xml");
HttpEntity entity = new HttpEntity(headers);
// HttpEntity<String> response = restTemplate.exchange(callUrl, HttpMethod.GET, entity, String.class, params);
// System.out.println("response => " + response.getHeaders());
// System.out.println("response => " + response.getBody().trim());
return getCashrcptPayUrl();
}
private Map<String, String> getResultParsingValues(String result, String BL_TID) {
List<String> resultList = Arrays.asList(result.split(smartro_result_split));
System.out.println("===== resultArray.length : " + resultList.size());
Map<String, String> resultMap = new HashMap<String, String>();
if(resultList.size() == 17) {
try {
resultMap.put("PayMethod", resultList.get(0));
resultMap.put("MID", resultList.get(1));
resultMap.put("Amt", resultList.get(2));
resultMap.put("Name", resultList.get(3));
resultMap.put("GoodsName", resultList.get(4));
resultMap.put("mallUserID", resultList.get(5));
resultMap.put("TID", resultList.get(6));
resultMap.put("OID", resultList.get(7));
resultMap.put("AuthDate", resultList.get(8));
resultMap.put("AuthCode", resultList.get(9));
resultMap.put("ResultCode", resultList.get(10));
resultMap.put("ResultMsg", resultList.get(11));
resultMap.put("MallReserved", resultList.get(12));
resultMap.put("fn_cd", resultList.get(13));
resultMap.put("fn_name", resultList.get(14));
resultMap.put("BuyerEmail", resultList.get(15));
resultMap.put("VerifyValue", resultList.get(16));
} catch (Exception e) {
}
} else {
}
return resultMap;
}
private String getCashrcptPay() {
return "";
}
private String jsonStringFromObject(Object object) throws JsonProcessingException {
URI uri = URI.create("/api/articles");
String responseString = restTemplate.getForObject(uri, String.class);
return responseString;
}
private String getEncryptBillTID(String billTID) {
String encryptBillTid = "";
try {
crypt cy = new crypt();
encryptBillTid = cy.xpgClientEncrypt(merchantKey, billTID);
} catch (Exception e) {
System.out.println("xpgClientEncrypt Exception:" + e);
}
return encryptBillTid;
}
private String getDecryptBillTID(String encryptedBillTID) {
String decryptBillTid = "";
try {
crypt cy = new crypt();
decryptBillTid = cy.xpgClientDecrypt(merchantKey, encryptedBillTID);
} catch (Exception e) {
System.out.println("xpgClientDecrypt Exception:" + e);
}
return decryptBillTid;
}
private String getPayMethod(String selectType) {
String payMethod = selectType;
switch (selectType) {
case "CARD":
break;
case "BANK":
break;
case "VBANK":
break;
case "CARD+BANK":
payMethod = "CARD";
break;
case "CELLPHONE":
break;
case "KEYIN":
break;
case "CARDBILL":
break;
default:
break;
}
return payMethod;
}
private int getPayType(String selectType) {
int payType = 0;
switch (selectType) {
case "CARD":
payType = 1;
break;
case "BANK":
payType = 6;
break;
case "VBANK":
payType = 7;
break;
case "CARD+BANK":
payType = 8;
break;
case "CELLPHONE":
payType = 9;
break;
case "KEYIN":
payType = 4;
break;
case "CARDBILL":
payType = 1;
break;
default:
break;
}
return payType;
}
private String getIpAddress() {
String ipAddress = null;
try {
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = networkInterfaces.nextElement();
byte[] hardwareAddress = networkInterface.getHardwareAddress();
if (null == hardwareAddress || 0 == hardwareAddress.length || (0 == hardwareAddress[0] && 0 == hardwareAddress[1] && 0 == hardwareAddress[2])) continue;
Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
if (inetAddresses.hasMoreElements()) ipAddress = inetAddresses.nextElement().toString();
break;
}
} catch (SocketException e) {
e.printStackTrace();
}
return ipAddress;
}
/**
* <pre>
* MD5+Base64
* </pre>
* @param str
* @return String
*/
private final String encodeMD5Base64(String str) {
return new String(Base64.encodeBase64(DigestUtils.md5(str)));
}
private final String encodeMD5HexBase64(String pw){
return new String(Base64.encodeBase64(DigestUtils.md5Hex(pw).getBytes()));
}
/**
* <pre>
* MD5+Base64
* </pre>
* @param str
* @return String
*/
private final String UrlencodeBase64(String str) {
return new String(Base64.encodeBase64(str.getBytes()));
}
private final String UrldecodeBase64(String str) {
return new String(Base64.decodeBase64(str.getBytes()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment