모듈 연동

스마트로페이 결제모듈 연동을 위한 가이드입니다.
- Test 연동시 체크 카드는 사용자제 부탁드립니다. 체크 카드 결제시 Test 계에서는 당일 전체 취소만 가능 합니다. (부분취소 지원불가)
- 스마트로 사업자번호로 제공된 테스트 Mid는 국민카드(카카오뱅크) 결제가 불가합니다.
- 스마트로 사업자번호로 제공된 테스트 Mid는 간편결제(카카오페이 카드, 페이코 카드)이용 시 삼성/현대/농협/신한카드만 이용 가능합니다.
그 외 카드사의 테스트가 필요한 경우 각 사업자의 사업자번호로 Mid를 신규발급 받아야하니 영업담당자를 통해 문의 주십시오.
- 카카오페이 카드 결제의 경우 카카오에서 자동 매입하므로 테스트 후 취소 해주시길 바랍니다. (미취소 시 결제금액 청구)
- KeyIn인증(카드 번호 입력을 통한 인증)설정 가맹점인 경우 국민카드(카카오뱅크), 하나카드결제가 불가합니다.
- 테스트서버 가상계좌 채번불가 은행안내 (국민, 전북, 광주, 대구, K뱅크)
- SmartroPay 메뉴얼의 Parameter 들은 가맹점에 통보 없이 응답값이 추가 될수 있습니다. 응답값 추가도 고려하여 개발 진행하시길 권장합니다 .

일반연동

인증과 승인이 별도의 프로세스로 진행되는 HTTP 통신 연동입니다.
* 스마트로페이 PC, Mobile 모듈의 기본 Charset은 UTF-8입니다. 연동 시 참고해 주세요.
* 스마트로페이의 응답은 POST입니다. 연동 시 참고해 주세요.
스마트로페이 SERVER IP
스마트로페이 서비스 IP 정보입니다.
구분 IP 비고
테스트 211.193.35.11 STG
운영 - 결제 211.193.35.20
운영 - 재통보 211.193.35.215 재통보 서비스 사용시
결제요청 파라미터
부가 서비스의 경우 [선택 파라미터] 항목을 참고하세요.
ex) 현금영수증, NonUi, 에스크로, 복합결제 등
파라미터 항목명 길이(char) 설명
공통
PayMethod 지불수단 10 CARD:신용카드 BANK:계좌이체 VBANK:가상계좌 CELLPHONE:휴대폰결제 NAVER:네이버페이
KAKAO:카카오페이 PAYCO:페이코페이 LPAY:엘페이 PINPAY:핀페이 SAMSUNGPAY:삼성페이
TOSS:토스 LINEPAY:라인페이 TMONEYPAY:티머니페이
※ 가상계좌 이용 시, 입금통보 URL(RetryUrl) 설정은 필수입니다. (좌측 재통보 메뉴 참고)
GoodsCnt 결제상품 품목 개수 2 기본값: 1
GoodsName 거래 상품명 40
Amt 거래 금액 12 숫자만 가능, 문장부호 제외
Moid 상품주문번호 40 특수문자 포함 불가
Mid 상점아이디 10
ReturnUrl 인증결과 전송 URL 100
BuyerName 구매자명 30
BuyerTel 구매자연락처 40
BuyerEmail 구매자메일주소 60
VbankExpDate 입금만료일 8 YYYYMMDD(형식), 가상계좌 결제 이용 시 필수
EncryptData 암호화데이터 가변 SHA256(EdiDate + Mid + Amt + merchantKey), 샘플소스 참고
EncryptData 생성 데모 - 클릭
GoodsCl 휴대폰 결제타입 1 0: 컨텐츠, 1: 실물(가맹점 설정에 따라 셋팅, 휴대폰 결제 시 필수)
EdiDate 전문생성일시 14 YYYYMMDDHHmmss(형식)
TaxAmt 과세 12 부가세 직접계산 가맹점 필수, 숫자만 가능, 문장부호 제외 (과세 직접계산 안내 - 클릭)
TaxFreeAmt 비과세 12 부가세 직접계산 가맹점 필수, 숫자만 가능, 문장부호 제외 (비과세 직접계산 안내 - 클릭)
VatAmt 부가세 12 부가세 직접계산 가맹점 필수, 숫자만 가능, 문장부호 제외 (부가세 직접계산 안내 - 클릭)
복합 결제 Parameter
VersionType 복합결제 전문 버전 1 복합결제 전문 사용시 VersionType=1 로 Setting 하여 전달
(복합결제 및 , 컵 보증금 사용 ,가맹점 분담 무이자 사용 여부등 전달 필요시 필수)
파라미터 항목명 길이(char) 설명
공통
StopUrl 결제중단 URL 100 결제 중단 시 이동할 페이지 URL (PC: 선택, Mobile: 필수)
PayType 간편결제 결제타입 10 CARD: 신용카드, MONEY: 머니/포인트 (카카오페이, 네이버페이, 페이코페이, 토스)
MallUserId 회원사고객ID 20 간편결제 이용 시 필수 (PINPAY 결제의 경우 회원ID 등 고객의 유니크한 값의 전달이 필요합니다.)
ParentEmail 보호자메일주소 60
BuyerAddr 배송지주소 100
BuyerPostNo 우편번호 6
UserIp 고객 IP 20
MallIp 상점서버IP 20
EncodingType 인코딩타입 5 utf8(기본값), euckr
OfferPeriod 용역제공기간 16 YYYYMMDDYYYYMMDD, 제공기간이 없을 시 공백처리
SkinColor UI 스타일 10 RED(기본값), GREEN, BLUE, PURPLE
OpenType 오픈타입 4 KR(기본값): 국내카드결제, EN: 해외카드결제
Language 결제창언어 5 KR(기본값): 한글, EN: 영어
MallReserved 상점예비정보 500 Base64 인코딩필요
(평문으로 전달시 한글 및 특수문자가 정상적으로 전달되지 않음)
NonUi Non-UI 사용여부(특수 가맹점용) 1 N(기본값): 미사용, Y: 사용
FnCd 카드사 코드(NonUi=Y일 경우만 사용) 3 Non-UI 신용카드일 경우 필수
통합코드조회 > 카드사코드 발급사코드로 호출
CardQuota 할부개월(NonUi=Y일 경우만 사용) 2 Non-UI 신용카드일 경우 필수
개월에 따라 00, 02, 03, ...으로 설정
CardPoint 카드사포인트 사용여부(NonUi=Y일 경우만 사용) 1 Non-UI 신용카드일 경우 선택
0: 미사용, 1: 사용
CashReceiptType 현금영수증 유형(NonUi=Y일 경우만 사용) 1 Non-UI 계좌이체, 가상계좌, 네이버페이머니일 경우 필수
0: 미발행, 1: 소득공제, 2: 지출증빙
ReceiptTypeNo 현금영수증 번호(NonUi=Y일 경우만 사용) 11 Non-UI 계좌이체, 가상계좌, 네이버페이머니일 경우 필수
CashReceiptType이 '미발행'이 아닐 경우 필수
ReceiptType 현금 영수증 발급 유무 1 사용 : "Y" , 미사용 :'N' (카카오페이 머니일 경우 사용)
Y로 요청되지 않는 경우 현금영수증이 발급되지않습니다.
BankCode 은행코드(NonUi=Y일 경우만 사용) 3 Non-UI 가상계좌일 경우 필수
에스크로

*(추가) 에스크로 API 서비스는 https://api.smilepay.co.kr를 참고해주세요.

EscrowCd 거래구분 1 0: 일반거래, 1: 에스크로거래 (하이브리드 에스크로 Mid일 경우, EscrowCd 설정 필수)
DeliveryCode 에스크로 택배사 코드 가변
DeliveryNumber 에스크로 송장번호 가변 택배사 운송장번호
DeliveryAddr1 에스크로 배송지주소 1 가변 배송지 기본주소(한글: 3byte, 그외: 1byte)
DeliveryAddr2 에스크로 배송지주소 2 가변 배송지 상세주소(한글: 3byte, 그외: 1byte)
DeliveryPost 에스크로 배송지 우편번호 가변
ReceiverName 에스크로 배송받는분 성함 가변 한글: 3byte, 그외: 1byte
ReceiverTel 에스크로 배송받는분 전화번호 가변
SellerAddr1 에스크로 판매자 주소 1 가변 판매자 기본주소(한글: 3byte, 그외: 1byte)
SellerAddr2 에스크로 판매자 주소 2 가변 판매자 상세주소(한글: 3byte, 그외: 1byte)
SellerPost 에스크로 판매자 우편번호 가변
SellerTel 에스크로 판매자 전화번호 가변
SellerId 에스크로 판매자 ID 가변
SellerName 에스크로 판매자 이름 가변 한글: 3byte, 그외: 1byte
분할정산
ProductInfo 상품정보 가변 분할 정산 이용시 상품정보에 "padj" 문자열 세팅 필수
DivideInfo 분할정산 정보 가변 분할 정산할 세부 상품 정보 (DivideInfo 설정 안내 - 클릭)
Mobile 앱 결제
ClientType 모바일 플랫폼 형태 3 가맹점 앱에서 WebView 이용하여 호출시 ClientType = 'HYB' (WebView 이용시 필수),
모바일 웹 브라우저일 경우 ClientType = 'WEB'
UrlScheme 스키마 URl 가변 가맹점 App 의 스키마 URL , IOS 에서 페이북머니 결제 인증 완료 후 가맹점 App 호출시 사용
복합 결제
복합결제 전문 (VersionType=1 일때 사용 가능)
MerInterestCl 가맹점 선택 무이자(카드사, 분담) 1 카드사와 분담 무이자 모두 설정 되어 있을 경우 기본은 카드사 무이자로 설정 되지만 ,
가맹점에서 해당 Parameter 전달 시 전달된 무이자로 설정
C : 카드사 무이자 , M : 분담 무이자
GreenDeposit 컵보증금 12 컵 보증금 전달시 사용 ex) GreenDeposit=100
플랫폼정산
PlatformSettlement 플랫폼정산 정보 500 플랫폼정산 신용카드 결제시 이용 (PlatformSettlement 설정 안내 - 클릭)

샘플 소스
STEP 1 결제 요청 시 필요한 암호화 정보를 설정합니다.

String Mid = "";                                                                                   // 발급받은 테스트 Mid 설정(Real 전환 시 운영 Mid 설정)
String MerchantKey = "";                                                                  // 발급받은 테스트 상점키 설정(Real 전환 시 운영 상점키 설정)
String EdiDate = getyyyyMMddHHmmss();
String Amt = "1004";
String EncryptData = encodeSHA256Base64(EdiDate + Mid + Amt + MerchantKey);
String today = getyyyyMMddHHmm();		                                   // 현재일자. 캐시방지용으로 사용

/* SHA256 암호화 */
public static final String encodeSHA256Base64(String strPW) {
    String passACL = null;
    MessageDigest md = null;

    try {
        md = MessageDigest.getInstance("SHA-256");
    } catch (Exception e) {
        e.printStackTrace();
    }

    md.update(strPW.getBytes());
    byte[] raw = md.digest();
    byte[] encodedBytes = Base64.encodeBase64(raw);
    passACL = new String(encodedBytes);

    return passACL;
}

/* 현재일자 */
public static final String getyyyyMMddHHmmss() {
    SimpleDateFormat yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss");
    return yyyyMMddHHmmss.format(new Date());
}

/* 현재일자  */
public static final String getyyyyMMddHHmm() {
    SimpleDateFormat yyyyMMddHHmm = new SimpleDateFormat("yyyyMMddHHmm");
    return yyyyMMddHHmm.format(new Date());
}

$Mid = "";           // 발급받은 테스트 Mid 설정(Real 전환 시 운영 Mid 설정)
$MerchantKey = "";   // 발급받은 테스트 상점키 설정(Real 전환 시 운영 상점키 설정)
$EdiDate = date("YmdHis");
$Amt = "1004";
$EncryptData = base64_encode(hash('sha256', $EdiDate.$Mid.$Amt.$MerchantKey, true));
$today = date("YmdHi");		// 현재일자. 캐시방지용으로 사용

Mid = ""			' 발급받은 테스트 Mid 설정(Real 전환 시 운영 Mid 설정)
MerchantKey = ""	' 발급받은 테스트 상점키 설정(Real 전환 시 운영 상점키 설정)
EdiDate = Year(Now()) & right("0"&Month(Now()),2) & right("0"&Day(Now()),2) & right("0"&Hour(Now()),2) & right("0"&Minute(Now()),2) & right("0"&Second(Now()),2)
Amt = "1004"
EncryptData = CryptoUtil.Sha256Encrypt(EdiDate & Mid & Amt & MerchantKey))
today = Year(Now()) & right("0"&Month(Now()),2) & right("0"&Day(Now()),2) & right("0"&Hour(Now()),2) & right("0"&Minute(Now()),2) 	' 현재일자. 캐시방지용으로 사용


// DLL 암호화 소스
using System;
using System.EnterpriseServices;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;

namespace SmartropayLib
{
	public class CryptoUtil : ServicedComponent
    {
        /// 
        /// SHA256 암호화
        /// 
        /// 문자열
        /// 암호화 문자열
        public string Sha256Encrypt(string text)
        {
            SHA256Managed sha256Managed = new SHA256Managed();
            byte[] encryptBytes = sha256Managed.ComputeHash(Encoding.UTF8.GetBytes(text));

            return Convert.ToBase64String(encryptBytes);
        }
    }
}
SDK를 호출하는 DOMAIN정보와 MODE 정보는 연동 환경 별 설정이 서로 다르니 아래 표를 참고해주세요.
[예시] PC 테스트 환경 : https://tpay.smartropay.co.kr/asset/js/SmartroPAY-1.0.min.js
연동 환경 / 변수 { DOMAIN } { MODE }
PC 테스트 https://tpay.smartropay.co.kr STG
PC 운영 https://pay.smartropay.co.kr REAL
모바일 테스트 https://tmpay.smartropay.co.kr STG
모바일 운영 https://mpay.smartropay.co.kr REAL
STEP 2 결제에 필요한 Form 데이터를 설정합니다.
    
        
<html lang="ko">
  <meta charset="utf-8"/>
  <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
  <meta name="description" content=""/>
  <meta name="author" content="Smartro"/>
  <title>SmartroPAY 연동가이드</title>
  <!--  예시 : <script src="https://tpay.smartropay.co.kr/asset/js/SmartroPAY-1.0.min.js?version=20231130"></script>-->
  <script src="{ DOMAIN }/asset/js/SmartroPAY-1.0.min.js?version={today}"></script>
  <script type="text/javascript">
    function goPay() {
        // STEP 2에서 구현
    };
  </script>
  </head>

  <body>
<form id="tranMgr" name="tranMgr" method="post">
  <!-- 각 값들을 가맹점에 맞게 설정해 주세요. -->
  <input type="text" name="PayMethod" value="CARD"/>
  <input type="text" name="GoodsCnt" value="1"/>
  <input type="text" name="GoodsName" value="거래 상품명"/>
  <input type="text" name="Amt" value="{ Amt }"/>
  <input type="text" name="Moid" value="Moid_202300000000"/>
  <input type="text" name="Mid" value="{ Mid }"/>
  <input type="text" name="ReturnUrl" class="input" value="가맹점 ReturnUrl 설정">
  <input type="text" name="StopUrl" class="input" value="결제중단 URL"/>
  <input type="text" name="BuyerName" value="구매자명"/>
  <input type="text" name="BuyerTel" value="01012345678"/>
  <input type="text" name="BuyerEmail" value="test@smartro.co.kr"/>
  <input type="text" name="VbankExpDate" value="20210824"/>
  <input type="text" name="EncryptData" value="{ EncryptData }"/>
  <input type="text" name="GoodsCl" value="0"/>
  <input type="text" name="EdiDate" value= "{ EdiDate }"/>

    <!-- MID 기본 세팅시 부가세 직접계산으로 설정됩니다. -->
  <input type="text" name="TaxAmt" value=""/>
  <input type="text" name="TaxFreeAmt" value=""/>
  <input type="text" name="VatAmt" value="">
  <td colspan="4" class="text-center">
    <button type="button" class="btn btn-primary" onclick="goPay();">결제하기</button>
  </td>
</form>

<!-- PC 연동의 경우에만 아래 승인폼이 필요합니다. (Mobile은 제외) -->
<form id="approvalForm" name="approvalForm" method="post">
  <input type="hidden" id="Tid" name="Tid"/>
  <input type="hidden" id="TrAuthKey" name="TrAuthKey"/>
</form>
</body>
</html>



STEP 3 환경에 맞게 goPay() 함수를 구현합니다.
Callback 함수는 결제 후 이동할 ReturnUrl 페이지를 받는 함수로, PC 연동일 경우에만 구현하며 Mobile은 구현하지 않습니다.
- PC연동 스크립트

            
function goPay() {
    smartropay.init({
        mode: "{ MODE }"      // 예시 -> mode : "STG"
    });

// smartropay 결제 요청 함수, PC 연동시 아래와 같이 smartropay.payment 함수를 구현합니다.
    smartropay.payment({
        FormId : 'tranMgr',
        Callback : function(res) {
            var approvalForm = document.approvalForm;
            approvalForm.Tid.value = res.Tid;
            approvalForm.TrAuthKey.value = res.TrAuthKey;
            approvalForm.action = '가맹점 ReturnUrl';
            approvalForm.submit();
        }
    });
};
        


- Mobile연동 스크립트

            
function goPay() {
    smartropay.init({
        mode: "{ MODE }"        // 예시 -> mode : "STG"
    });

    // smartropay 결제 요청 함수, Mobile 연동시 아래와 같이 smartropay.payment 함수를 구현합니다.
    smartropay.payment({
        FormId : 'tranMgr'
    });
};
        
- 가상계좌 이용 시, 입금통보 URL(RetryUrl) 설정은 가맹점관리자 사이트에서 가능합니다. (좌측 재통보 메뉴 참고)
- 가상계좌 연동 시, 입금통보를 위한 입금 테스트는 여기를 이용해 주세요. (스테이징 서버에서만 이용 가능 합니다. 실서버에서는 사용 불가능 합니다.)

STEP 4 승인 요청 및 결제 결과 받기

- 결제요청 시 설정했던 ReturnUrl을 통해 TidTrAuthKey를 전달받습니다.
- Tid는 결제수단에 따라 승인요청 후 응답받는 Tid와 다를 수 있습니다. 승인요청 후 응답받은 Tid를 가맹점 거래정보에 저장해주세요.
- TrAuthKey는 인증단계가 완료된 후 전달되는 인증 간소화 키로, 이 값을 이용해 승인 요청을 한 뒤 결과를 전달받습니다.
- TrAuthKey의 생성 유효시간은 10분이며, 발급 후 10분이 지나면 승인 처리가 되지 않습니다.
        
String url = "https://tapproval.smartropay.co.kr/payment/approval/urlCallApproval.do";		// 테스트
//String url = "https://approval.smartropay.co.kr/payment/approval/urlCallApproval.do";   	// 운영

String Tid       = request.getParameter("Tid")==null?"":request.getParameter("Tid");
String TrAuthKey = request.getParameter("TrAuthKey")==null?"":request.getParameter("TrAuthKey");

HashMap<String, Object> result = callApi(TrAuthKey , Tid, url);

public HashMap<String, Object> callApi(String TrAuthKey, String Tid, String callUrl) {

	StringBuilder responseBody = null;
	HashMap<String, Object> result = new HashMap<>();

	// http urlCall 승인 요청 및 TrAuthKey 유효성 검증
	int connectTimeout = 1000;
	int readTimeout = 10000; // 가맹점에 맞게 TimeOut 조절

	URL url = null;
	HttpsURLConnection connection = null;

	try {
		SSLContext sslCtx = SSLContext.getInstance("TLSv1.2");
		sslCtx.init(null, null, new SecureRandom());

    	url = new URL(callUrl);
    	System.out.println(" url " + url.toString());
    	connection = (HttpsURLConnection)url.openConnection();
    	connection.setSSLSocketFactory(sslCtx.getSocketFactory());

    	connection.addRequestProperty("Content-Type", "application/json");
    	connection.addRequestProperty("Accept", "application/json");
    	connection.setDoOutput(true);
    	connection.setDoInput(true);
    	connection.setConnectTimeout(connectTimeout);
    	connection.setReadTimeout(readTimeout);

    	OutputStreamWriter osw = new OutputStreamWriter(new BufferedOutputStream(connection.getOutputStream()) , "utf-8" );

    	JSONObject body = new JSONObject();
    	body.put("Tid" ,Tid);
    	body.put("TrAuthKey" ,TrAuthKey);

    	char[] bytes = body.toString().toCharArray();
    	osw.write(bytes,0,bytes.length);
    	osw.flush();
    	osw.close();

    	BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
    	String line = null;
    	responseBody =  new StringBuilder();
    	while ((line = br.readLine()) != null) {
    		System.out.println(" response " +  line);
    		responseBody.append(line);
    	}
    	br.close();

    	// 결제결과
    	result = new ObjectMapper().readValue(responseBody.toString(), HashMap.class);

	} catch (MalformedURLException e) {
		// TODO Auto-generated catch block
    	e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
    	e.printStackTrace();
	} catch (Exception e) {
		e.printStackTrace();
	}
    return result;
}
		
	
        
$url = "https://tapproval.smartropay.co.kr/payment/approval/urlCallApproval.do";	// 테스트 
//$url = "https://approval.smartropay.co.kr/payment/approval/urlCallApproval.do";	// 운영 
        
$approval_data = array(
	'Tid' => $_REQUEST['Tid'],
	'TrAuthKey' => $_REQUEST['TrAuthKey']
);

// json data
$json = json_encode($approval_data);

$http_status = 0;

// https 통신
$ret = Curl($url, $json, $http_status);

function Curl($url, $post_data, &$http_status, &$header = null) {

    $ch=curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_URL, $url);

    // post_data
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    curl_setopt($ch, CURLOPT_HEADER, false);

    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-Type: application/json'));
    curl_setopt($ch, CURLOPT_VERBOSE, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    $response = curl_exec($ch);

    $body = null;
    // error
    if (!$response) {
        $body = curl_error($ch);
        // HostNotFound, No route to Host, etc  Network related error
        $http_status = -1;
        Log::error("CURL Error: = " . $body);
    } else {
       //parsing http status code
        $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        if (!is_null($header)) {
            $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);

            $header = substr($response, 0, $header_size);
            $body = substr($response, $header_size);
        } else {
            $body = $response;
        }
    }
    curl_close($ch);
    return $body;
}
		
    
           
url = "https://tapproval.smartropay.co.kr/payment/approval/urlCallApproval.do" 	' 테스트
'url = "https://approval.smartropay.co.kr/payment/approval/urlCallApproval.do"	' 운영

Set json = jsObject()
json("Tid") = request("Tid")
json("TrAuthKey") = request("TrAuthKey")

result = sendPost(url, json)

Function sendPost(callUrl, objJson)

    Set httpRequest = Server.CreateObject("MSXML2.ServerXMLHTTP")
    httpRequest.open "POST", url, False
    httpRequest.setRequestHeader "Content-type","application/json"
	httpRequest.setRequestHeader "Accept","application/json"
    httpRequest.send objJson.jsString
    postResponse = httpRequest.ResponseText

	sendPost = postResponse
End Function
		
    

결제결과 파라미터

파라미터 항목명 길이(char) 설명
PayMethod 지불수단 10 CARD:신용카드, BANK:계좌이체, VBANK:가상계좌, CELLPHONE:휴대폰결제, NAVER:네이버페이,
KAKAO:카카오페이, PAYCO:페이코페이, LPAY:엘페이, PINPAY:핀페이, SAMSUNGPAY:삼성페이,
TOSS:토스 LINEPAY:라인페이 TMONEYPAY:티머니페이
Mid 상점ID 10
Tid 거래번호 30
Moid 상품주문번호 40
GoodsName 상품명 40
GoodsCnt 결제상품 품목 개수 2 기본값: 1
Amt 금액 12
BuyerName 결제자명 30
BuyerAuthNum 구매자인증번호 15 휴대폰 결제 시 마스킹 처리된 전화번호 전달
MallUserId 고객사회원ID 20
AuthCode 승인번호 30
Currency 결제통화 3
ResultCode 결과코드 4 각 결제 수단별 응답코드는 [통합코드조회] 참고
ResultMsg 결과메시지 100
MallReserved 결과메시지 500 가맹점에서 설정한 값 전달
SignValue 위·변조 사인값 가변 위·변조 방지를 위해 전송되는 암호화 데이터
MerInterestCl 무이자할부 담당주체 1 실제 결제시 적용된 무이자정보
C : 카드사 무이자 , M : 분담 무이자, N : 일반할부
CardType 카드타입 1 0 : 신용, 1 : 체크, 2 : 신용+체크, 3 : 선불
CardOwnerType 법인/개인 구분 1 0 : 개인, 1 : 법인, 2 : 개인+법인, 3 : 선불, 4: 해외카드
파라미터 항목명 길이(char) 설명
신용카드(카카오페이 카드/네이버페이 카드/페이코페이/엘페이/핀페이 카드/삼성페이/토스 카드 포함)
AppCardCode 발급사코드 2
AppCardName 발급사명 20
AcquCardCode 매입사코드 2
AcquCardName 매입사명 20
CardMerchantNo 카드사가맹점번호 15
CardNum 카드번호 16 7~12자리 Masking 처리
CardQuota 할부개월 2 00: 일시불(기본값), 02, 03, ...
CardInterest 무이자 여부 1 0: 일반, 1: 카드사 무이자, 2: 상점 무이자
UsePoint 사용포인트 9 카드 사용 포인트
BalancePoint 잔여포인트 9 카드 잔여 포인트
계좌이체
BankCode 은행코드 3
BankName 은행명 20
계좌이체(현금영수증 발행시)
ReceiptResultCode 현금영수증 발급결과코드 4 7001 : 현금영수증 처리성공, 7001 외 코드는 통합코드 조회를 확인해주세요.
ReceiptType 현금영수증 용도구분(1:개인소득공제, 2:사업자지출증빙) 1
ReceiptAppNo 현금영수증 승인번호 30
가상계좌
VbankNum 가상계좌번호 20
AccountHolder 가상계좌 예금주명 40 가상계좌 원천사 쿠콘 이용시 해당 파라미터가 응답됩니다.
Bankcode 은행코드 3
VbankName 가상계좌은행명 20
VbankExpDate 가상계좌 입금만료일 8
카카오페이 공통
PayType 결제타입 10 CARD: 카카오페이 카드, MONEY: 카카오페이 머니
네이버페이 공통
PayType 결제타입 10 CARD: 네이버페이 카드, MONEY: 네이버페이 포인트
PayId 네이버페이 결제번호 100
페이코페이 공통
PayType 결제타입 10 CARD: 페이코페이 카드, MONEY: 페이코페이 포인트
PayId 페이코페이 결제번호 100
CpxAmt 쿠폰할인 금액 12
PayAmt 주결제수단 금액 12 총결제 금액 - 쿠폰할인 금액
토스 공통
PayType 결제타입 10 CARD: 토스 카드, MONEY: 토스 머니
복합결제 공통
CpxTid 복합결제 TID 30
CpxAuthCode 복합결제 승인번호 30
CpxAmt 복합결제 금액 12
PayAmt 주결제수단금액 12
InstDiscTid 즉시할인Tid 30
InstDiscAuthCode 즉시할인 승인번호 30
InstDiscAmt 즉시할인 금액 12
에스크로
EscrowCd 에스크로 거래구분 1 0: 일반거래, 1: 에스크로거래
DeliveryAddr1 에스크로 배송지주소 1 가변
DeliveryAddr2 에스크로 배송지주소 2 가변
ReceiverTel 에스크로 배송받는분 전화번호 가변
SellerAddr1 에스크로 판매자 주소 1 가변
SellerAddr2 에스크로 판매자 주소 2 가변
SellerTel 에스크로 판매자 전화번호 가변
EscrowAuthNumber 에스크로 인증번호(결제창에서 고객이 등록한 번호) 가변

EXTRA STEP 승인 결과 재 요청

승인 결과값을 전송 못 받았을 경우 승인 후 1시간 이내의 거래에 대한 승인 결과 값을 재 요청합니다.
TrAuthKeyTid 를 승인 결과 조회 URL 에 전달 하여 Step3의 결제 결과와 동일한 값을 전달 받을 수 있습니다.
        
String url = "https://tapproval.smartropay.co.kr/payment/approval/approvalInquiry.do";		// 테스트
//String url = "https://approval.smartropay.co.kr/payment/approval/approvalInquiry.do";   	// 운영

String Tid       = request.getParameter("Tid")==null?"":request.getParameter("Tid");
String TrAuthKey = request.getParameter("TrAuthKey")==null?"":request.getParameter("TrAuthKey");

HashMap<String, Object> result = callApi(TrAuthKey , Tid, url);

public HashMap<String, Object> callApi(String TrAuthKey, String Tid, String callUrl) {

	StringBuilder responseBody = null;
	HashMap<String, Object> result = new HashMap<>();

	// http urlCall 승인 요청 및 TrAuthKey 유효성 검증
	int connectTimeout = 1000;
	int readTimeout = 10000; // 가맹점에 맞게 TimeOut 조절

	URL url = null;
	HttpsURLConnection connection = null;

	try {
		SSLContext sslCtx = SSLContext.getInstance("TLSv1.2");
		sslCtx.init(null, null, new SecureRandom());

    	url = new URL(callUrl);
    	System.out.println(" url " + url.toString());
    	connection = (HttpsURLConnection)url.openConnection();
    	connection.setSSLSocketFactory(sslCtx.getSocketFactory());

    	connection.addRequestProperty("Content-Type", "application/json");
    	connection.addRequestProperty("Accept", "application/json");
    	connection.setDoOutput(true);
    	connection.setDoInput(true);
    	connection.setConnectTimeout(connectTimeout);
    	connection.setReadTimeout(readTimeout);

    	OutputStreamWriter osw = new OutputStreamWriter(new BufferedOutputStream(connection.getOutputStream()) , "utf-8" );

    	JSONObject body = new JSONObject();
    	body.put("Tid" ,Tid);
    	body.put("TrAuthKey" ,TrAuthKey);

    	char[] bytes = body.toString().toCharArray();
    	osw.write(bytes,0,bytes.length);
    	osw.flush();
    	osw.close();

    	BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
    	String line = null;
    	responseBody =  new StringBuilder();
    	while ((line = br.readLine()) != null) {
    		System.out.println(" response " +  line);
    		responseBody.append(line);
    	}
    	br.close();

    	// 결제결과
    	result = new ObjectMapper().readValue(responseBody.toString(), HashMap.class);

	} catch (MalformedURLException e) {
		// TODO Auto-generated catch block
    	e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
    	e.printStackTrace();
	} catch (Exception e) {
		e.printStackTrace();
	}
    return result;
}
		
	
        
$url = "https://tapproval.smartropay.co.kr/payment/approval/approvalInquiry.do";	// 테스트
//$url = "https://approval.smartropay.co.kr/payment/approval/approvalInquiry.do";	// 운영
        
$approval_data = array(
	'Tid' => $_REQUEST['Tid'],
	'TrAuthKey' => $_REQUEST['TrAuthKey']
);

// json data
$json = json_encode($approval_data);

$http_status = 0;

// https 통신
$ret = Curl($url, $json, $http_status);

function Curl($url, $post_data, &$http_status, &$header = null) {

    $ch=curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_URL, $url);

    // post_data
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    curl_setopt($ch, CURLOPT_HEADER, false);

    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-Type: application/json'));
    curl_setopt($ch, CURLOPT_VERBOSE, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    $response = curl_exec($ch);

    $body = null;
    // error
    if (!$response) {
        $body = curl_error($ch);
        // HostNotFound, No route to Host, etc  Network related error
        $http_status = -1;
        Log::error("CURL Error: = " . $body);
    } else {
       //parsing http status code
        $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        if (!is_null($header)) {
            $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);

            $header = substr($response, 0, $header_size);
            $body = substr($response, $header_size);
        } else {
            $body = $response;
        }
    }
    curl_close($ch);
    return $body;
}
		
    
           
url = "https://tapproval.smartropay.co.kr/payment/approval/approvalInquiry.do" 	' 테스트
'url = "https://approval.smartropay.co.kr/payment/approval/approvalInquiry.do"	' 운영

Set json = jsObject()
json("Tid") = request("Tid")
json("TrAuthKey") = request("TrAuthKey")

result = sendPost(url, json)

Function sendPost(callUrl, objJson)

    Set httpRequest = Server.CreateObject("MSXML2.ServerXMLHTTP")
    httpRequest.open "POST", url, False
    httpRequest.setRequestHeader "Content-type","application/json"
	httpRequest.setRequestHeader "Accept","application/json"
    httpRequest.send objJson.jsString
    postResponse = httpRequest.ResponseText

	sendPost = postResponse
End Function
		
    



결제 중단 시 결과 파라미터
- 사용자가 결제 중단 시 이동하는 페이지(StopUrl)의 결과 파라미터입니다.
- StopUrl 페이지 설정은 Mobile 연동 시 필수 사항입니다.
파라미터 항목명 길이(char) 설명
PayMethod 지불수단 10 CARD:신용카드, BANK:계좌이체, VBANK:가상계좌, CELLPHONE:휴대폰결제, NAVER:네이버페이,
KAKAO:카카오페이, PAYCO:페이코페이, LPAY:엘페이, PINPAY:핀페이, SAMSUNGPAY:삼성페이,
TOSS:토스, LINEPAY:라인페이 TMONEYPAY:티머니페이
GoodsName 거래 상품명 40
Amt 거래 금액 12 숫자만 가능, 문장부호 제외
Moid 상품주문번호 40 특수문자 포함 불가
Mid 상점아이디 10
MallUserId 회원사고객ID 20
BuyerName 구매자명 30
BuyerTel 구매자연락처 40
BuyerEmail 구매자메일주소 60
MallReserved 상점예비정보 500
ResultCode 결과코드 4
ResultMsg 결과메시지 100


(추가) SignValue 생성 규칙

결제결과 시 전달받는 SignValue 파라미터는 아래와 같은 규칙으로 생성됩니다.

                    
String Tid = request.getParameter("Tid");
String ResultCode = request.getParameter("ResultCode");
String mKey = "";   // 가맹점 상점키 설정

signValue = encodeSHA256Base64(Tid.substring(0, 10)
			+ ResultCode
			+ Tid.substring(10, 15)
			+ mKey
			+ Tid.substring(15, Tid.length()));
                
                    
$Tid = $_REQUEST['Tid']==null?"":$_REQUEST['Tid'];
$ResultCode = $_REQUEST['ResultCode']==null?"":$_REQUEST['ResultCode'];
$MerchantKey = "";   // 발급받은 테스트 상점키 설정(Real 전환 시 운영 상점키 설정)

$SignValue = base64_encode(hash('sha256',
                    substr($Tid,0,10).$ResultCode.substr($Tid,10,5).$MerchantKey.substr($Tid,15,15),true));
                
                    
Tid = request("Tid")
ResultCode = request("ResultCode")
merchantKey = ""   ' 발급받은 테스트 상점키 설정(Real 전환 시 운영 상점키 설정)

SignValue = CryptoUtil.Sha256Encrypt(Mid(Tid,1,10) & ResultCode & Mid(Tid,11,5) & merchantKey & Mid(Tid,16,15))
					
                

(추가) 계좌이체 테스트 시 정보 설정

계좌이체 테스트용 개인 및 법인번호, 계좌번호, 비밀번호입니다.

            
개인 주민등록번호: 631206-1277229
법인 사업자등록번호: 128-75-17955
계좌번호: 000123456789(테스트 계좌번호)
비밀번호: 000으로 시작되는 임의의 4자리 숫자 (ex. 0001)
        

(추가) 분할정산 파라미터 설정 예시

분할정산 사용 가맹점일 경우, 아래와 같이 DivideInfo 파라미터를 설정합니다.

                    
/** 분할정산 파라미터 설정 시, 각 분할정산 상품 금액의 합계가 결제 요청 시 보내는 금액과 같아야 합니다.
예시) 상품1의 가격=502원, 상품2의 가격=502원, 합계 1004원 -> Amt=1004
DivideInfo (분할정산 정보) 설정 예시 - JSON Object 형식으로 설정 **/
String DivideInfo = "{ 'DivideInfo':
                        [
                        {'Amt':'502','Mid':'SMTSUB002m','GoodsName':'상품1'},     // 분할정산 1
                        {'Amt':'502','Mid':'SMTSUB003m','GoodsName':'상품2'}      // 분할정산 2
                        ] }";

// DivideInfo 인코딩
if(StringUtils.isNotEmpty(DivideInfo)) // Base64 인코딩(utf-8 인코딩)
{
	String temp = DivideInfo.replaceAll("'","\"");
	Charset euckrCharset = Charset.forName("utf-8");
	ByteBuffer byteBuffer = euckrCharset.encode(temp);
	byte[] euckrStringBuffer = new byte[byteBuffer.remaining()];
	byteBuffer.get(euckrStringBuffer);
	String b64Enc = new String(Base64.encodeBase64(euckrStringBuffer));
	DivideInfo = b64Enc;
	requestData.put("DivideInfo", DivideInfo);
}
                
                    
// 분할정산 파라미터 설정 시, 각 분할정산 상품 금액의 합계가 결제 요청 시 보내는 금액과 같아야 합니다.
// ex) 상품1의 가격=502원, 상품2의 가격=502원, 합계 1004원 -> Amt=1004
$DivideInfo = "{'DivideInfo':[{'Amt':'502','Mid':'SMTSUB002m','GoodsName':'상품1'},{'Amt':'502','Mid':'SMTSUB003m','GoodsName':'상품2'}]}";
/*
DivideInfo (분할정산 정보) 설정 예시 - JSON Object 형식으로 설정
{
    'DivideInfo':
    [
        {'Amt':'502','Mid':'SMTSUB002m','GoodsName':'상품1'}, // 분할정산 1
        {'Amt':'502','Mid':'SMTSUB003m','GoodsName':'상품2'} 	// 분할정산 2
    ]
}
*/
//DivideInfo 인코딩
if(!empty($DivideInfo)) // Base64 인코딩(utf-8 인코딩)
{
	$temp = str_replace("'", "\"", $DivideInfo);
	$b64Enc = base64_encode($temp);
	$DivideInfo = $b64Enc;
}
                
    	            
' 분할정산 파라미터 설정 시, 각 분할정산 상품 금액의 합계가 결제 요청 시 보내는 금액과 같아야 합니다.
' ex) 상품1의 가격=502원, 상품2의 가격=502원, 합계 1004원 -> Amt=1004
DivideInfo = "{'DivideInfo':[{'Amt':'502','Mid':'SMTSUB002m','GoodsName':'상품1'},{'Amt':'502','Mid':'SMTSUB003m','GoodsName':'상품2'}]}"

'DivideInfo (분할정산 정보) 설정 예시 - JSON Object 형식으로 설정
'{
    '	'DivideInfo':
    '	[
    '		{'Amt':'502','Mid':'SMTSUB002m','GoodsName':'상품1'}, // 분할정산 1
    '		{'Amt':'502','Mid':'SMTSUB003m','GoodsName':'상품2'}  // 분할정산 2
    '	]
'}

'DivideInfo 인코딩
IF IsEmpty(trim(DivideInfo)) = false Then 'Base64 인코딩(utf-8 인코딩)
    'temp = Replace(DivideInfo, "'", "\"")

    '한글 데이터가 있는 경우, utf-8 encoding 처리 후 base64Encode 필요
    b64Enc = base64Encode(temp)
    DivideInfo = b64Enc
end if
                

(추가) 과세 및 비과세 직접 계산 방식

과세 및 비과세 필드를 직접 계산하는 가맹점일 경우 아래와 같은 방식으로 계산하세요.

		
// 총금액(Amt) = 과세금액(TaxAmt) + 부가세(VatAmt) + 비과세(TaxFreeAmt)

// 비과세(TaxFreeAmt) 금액이 0원일 경우
tmp = Amt / 1.1;
VatAmt = (long)Math.floor(Amt - tmp);  // 부가세 절사
TaxAmt = Amt - VatAmt
/**  예시 : 총금액(Amt:5000) = 과세금액(TaxAmt:4546) + 부가세(VatAmt:454) **/


// 비과세(TaxFreeAmt) 금액이 0원 이상일 경우
tmp = (Amt- TaxFreeAmt) / 1.1;
VatAmt = (long)Math.floor(Amt - tmp - TaxFreeAmt);  // 부가세 절사
TaxAmt = Amt - VatAmt - TaxFreeAmt
/**  예시 : 총금액(Amt:5000) = 과세금액(TaxAmt:4364) + 부가세(VatAmt:436)+ 비과세(TaxFreeAmt:200) **/

		
	
- 위의 계산방식은 일반 연동을 사용하며 부가세를 직접 계산하는 가맹점일 경우에 한합니다.
- 비과세 가맹점인 경우 비과세금액(TaxFreeAmt)이 총금액(Amt)과 일치해야 하며 과세(TaxAmt)와 부가세(VatAmt)는 0 으로 세팅
- 간편 연동을 사용하거나 직접 계산을 하지 않는 경우, 비과세 가맹점에는 해당되지 않습니다.
※ 부가세 계산방식을 자동 계산 방식으로 변경 희망하시는 경우, 영업 담당자에게 문의 부탁드립니다.

(추가) 특수 결제 가맹점 PlatformSettlement 설정

- 플랫폼 정산 가맹점의 경우 아래의 방식으로 PlatformSettlement 필드 설정을 하세요


String fixStr = "PFST";
String space =" ";

// 예약어 + 공백 1칸 + "코드1=금액" + ",코드1=금액" + ",코드3=금액" + ... (코드 값은 사전 협의된 값 사용)
// 금액은 숫자만 가능, 문장부호 제외
String PlatformSettlement = fixStr + space + "M01=1000,M02=500,P02=700,...";
// ex) "PFST M01=1000,M02=500,P02=700";