영수증 미리보기
모듈 연동
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"); // 현재일자. 캐시방지용으로 사용
smartroMid = "" ' 발급받은 테스트 smartroMid 설정(Real 전환 시 운영 smartroMid 설정)
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 & smartroMid & 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);
}
}
}
SmartroPAY 연동가이드
goPay() 함수를 구현하여 결제를 요청합니다.
* Callback 함수는 결제 후 이동할 ReturnUrl 페이지를 받는 함수로, PC 연동일
경우에만 구현하며 Mobile은 구현하지 않습니다.
function goPay() {
// 스마트로페이 초기화
smartropay.init({
mode: "STG" // STG: 테스트, REAL: 운영(운영서버 전환 시 변경 필수!)
});
// 스마트로페이 결제요청
// PC 연동시 아래와 같이 smartropay.payment 함수를 구현합니다.
smartropay.payment({
FormId : 'tranMgr', // 폼ID
Callback : function(res) {
var approvalForm = document.approvalForm;
approvalForm.Tid.value = res.Tid;
approvalForm.TrAuthKey.value = res.TrAuthKey;
approvalForm.action = '가맹점 ReturnUrl';
approvalForm.submit();
}
});
// Mobile 연동시 아래와 같이 smartropay.payment 함수를 구현합니다.
smartropay.payment({
FormId : 'tranMgr' // 폼ID
});
};
| 파라미터 | 항목명 | 길이(char) | 설명 |
|---|---|---|---|
| 공통 | |||
| PayMethod | 지불수단 | 10 |
CARD:신용카드
BANK:계좌이체
VBANK:가상계좌
CELLPHONE:휴대폰결제
NAVER:네이버페이
KAKAO:카카오페이
PAYCO:페이코페이
LPAY:엘페이
PINPAY:핀페이
SAMSUNGPAY:삼성페이
TOSS:토스
LINEPAY:라인페이
TMONEYPAY:티머니페이
APPLEPAY:애플페이
※ 가상계좌 이용 시, 입금통보 URL( RetryUrl) 설정은 필수입니다. (좌측 재통보 메뉴 참고) |
| GoodsCnt | 결제상품 품목 개수 | 2 | 기본값: 1 |
| GoodsName | 거래 상품명 | 40 | |
| Amt | 거래 금액 | 12 | 숫자만 가능, 문장부호 제외 |
| Moid | 상품주문번호 | 40 | 특수문자 포함 불가 |
| Mid | 상점아이디 | 10 | |
| ReturnUrl | 인증결과 전송 URL | 100 | Http 프로토콜 포함 전체 Url 설정 |
| BuyerName | 구매자명 | 30 | |
| BuyerTel | 구매자연락처 | 40 | 숫자만 입력 (문자 입력 시 10자 미만으로 설정 하셔야합니다. - 초과 시 승인 오류 발생) |
| BuyerEmail | 구매자메일주소 | 60 | |
| VbankExpDate | 입금만료일 | 12 |
가상계좌 필수
쿠콘 : 8자리(yyyyMMdd) 검증 더즌 : 8자리(yyyyMMdd), 12자리(yyyyMMddhhmm) 검증 |
| 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: 필수) Http 프로토콜 포함 전체 Url 설정 해외카드 사용 가맹점의 경우 PC 연동시에도 설정(인증실패 시 응답) |
| PayType | 간편결제 결제타입 | 10 | CARD : 신용카드, MONEY : 머니/포인트 (카카오페이, 네이버페이, 페이코페이, 토스, 커넥트페이) ACCOUNT : 계좌 (커넥트페이 전용) |
| MallUserId | 회원사고객ID | 20 | 간편결제 이용 시 필수 (핀페이, 커넥트페이 결제의 경우 회원ID 등 고객의 유니크한 값의 전달이 필요합니다.) |
| ReceiptType | 간편결제 현금 영수증 발급 유무 | 1 | 사용 : "Y" , 미사용 : "N" (카카오페이 머니, 토스 머니, 커넥트페이 계좌 결제시 사용) Y로 요청되지 않으면 간편결제사에 현금영수증 요청을 하지 않으며 PayMethod=CARD 로 호출한 경우에도 간편결제가 가능하므로 현금영수증 발급을 원한다면 설정이 필요합니다. |
| 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: 영어, JP: 일문, CN: 중문 |
| MallReserved | 상점예비정보 | 500 | Base64 인코딩필요
(평문으로 전달시 한글 및 특수문자가 정상적으로 전달되지 않음) |
| ShowEasyPay | 간편결제노출 옵션 | 1 | Y(기본값): 노출, N: 미노출
N으로 설정한 경우 CARD 결제에서 간편결제가 노출되지 않습니다. |
| ProductImgUrl | 결제화면 노출 이미지URL
(라인페이전용) |
500 | 결제화면에 노출될 이미지URL (size:84x84) |
| 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이 '미발행'이 아닐 경우 필수 |
| 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 설정 안내 - 클릭) |
RetryUrl) 설정은 가맹점관리자 사이트에서 가능합니다. (좌측 재통보 메뉴 참고)ReturnUrl을 통해 Tid와 TrAuthKey를 전달받습니다.Tid는 결제수단에 따라 승인요청 후 응답받는 Tid와 다를 수 있습니다. 승인요청 후 응답받은 Tid를 가맹점 거래정보에 저장해주세요.TrAuthKey는 인증단계가 완료된 후 전달되는 인증 간소화 키로, 이 값을 이용해 승인 요청을 한 뒤 결과를 전달받습니다.TrAuthKey의 생성 유효시간은 10분이며, 발급 후 10분이 지나면 승인 처리가 되지 않습니다.
/** 1. Parameter 확인
Enumeration elem = request.getParameterNames();
while(elem.hasMoreElements())
{
key = (String)elem.nextElement();
value = request.getParameter(key);
// 전달 Parameter 확인
System.out.println("[" + key + "] : " + value);
}
/** 2. 소켓 어댑터와 연동하는 Web 인터페이스 객체를 생성한다.*/
SmartroPayClient payClient = new SmartroPayClient();
// Real 로 전환시 IP 변경 211.193.35.215
payClient.setParam("SMILEPAY_DOMAIN_NAME", "211.193.35.11"); //STG 서버 IP
payClient.setParam("SMILEPAY_ADAPTOR_LISTEN_PORT", "8090"); // PORT
payClient.setParam("SOCKET_SO_TIMEOUT","120000");
/** 2-1. 로그 디렉토리 설정 */
payClient.setParam("SMILEPAY_LOG_HOME", "/adoptor/log"); // 가맹점 설정에 맞게 변경
/** 2-2. 로그파일 인코딩 설정(default : euc-kr) */
payClient.setParam("CharSet", "euc-kr");
/** 2-2. 어플리케이션로그 모드 설정(0: DISABLE, 1: ENABLE) */
payClient.setParam("APP_LOG","1");
/** 2-3. 이벤트로그 모드 설정(0: DISABLE, 1: ENABLE) */
payClient.setParam("EVENT_LOG","1");
/** 2-4. 암호화플래그 설정(N: 평문, A2:암호화) */
payClient.setParam("EncFlag","A2");
/** 2-5. 서비스모드 설정(결제 서비스 : PY0 , 취소 서비스 : CL1) */
payClient.setParam("SERVICE_MODE", "PY0");
/** 2-6. 통화구분 설정(현재 KRW(원화) 가능) */
payClient.setParam("Currency", "KRW");
// 결제 요청 Parameter Setting
payClient.setParam("ReqFlag", "00"); // 서비스구분
payClient.setParam("Tid", request.getParameter("Tid"));
payClient.setParam("TrAuthKey", request.getParameter("TrAuthKey"));
payClient.setParam("RetDatas", request.getParameter("RetDatas"));
/** 3. 결제 요청 */
WebMessageDTO responseDTO = payClient.doService();
/** 4. 결제 결과 */
String ResultCode = getDefaultStr(responseDTO.getParameter("ResultCode"), ""); // 결과코드
String ResultMsg = getDefaultStr(responseDTO.getParameter("ResultMsg"), ""); // 결과메시지
String AuthDate = getDefaultStr(responseDTO.getParameter("AuthDate"), ""); // 승인일시 YYMMDDHH24mmss
String AuthCode = getDefaultStr(responseDTO.getParameter("AuthCode"), ""); // 승인번호
| 파라미터 | 항목명 | 길이(char) | 필수여부 | 설명 |
|---|---|---|---|---|
| 인증간소화 Adoptor 승인 요청 | ||||
| ReqFlag | 서비스구분 | 2 | 필수 | [00: 인증 간소화 승인요청] |
| Tid | 거래 번호 | 30 | 필수 | |
| TrAuthKey | 인증간소화키 | 가변 | 필수 | |
| RetDatas | Adoptor Data | 가변 | 필수 | |
| 파라미터 | 항목명 | 길이(char) | 설명 |
|---|---|---|---|
| 인증간소화 Adoptor 승인 결과(공통) | |||
| PayMethod | 지불수단 | 10 |
CARD:신용카드,
BANK:계좌이체,
VBANK:가상계좌,
CELLPHONE:휴대폰결제,
NAVER:네이버페이,
KAKAO:카카오페이,
PAYCO:페이코페이
|
| Mid | 상점ID | 10 | |
| Tid | 거래번호 | 30 | |
| Moid | 상품주문번호 | 40 | |
| GoodsName | 상품명 | 40 | |
| GoodsCnt | 결제상품 품목 개수 | 2 | 기본값: 1 |
| Amt | 금액 | 12 | |
| BuyerName | 결제자명 | 30 | |
| BuyerAuthNum | 구매자인증번호 | 15 | 휴대폰 결제 시 마스킹 처리된 전화번호 전달 |
| MallUserId | 고객사회원ID | 20 | |
| AuthDate | 승인일시 | 12 | YYMMDDHH24mmss |
| AuthCode | 승인번호 | 30 | |
| ResultCode | 결과코드 | 4 | |
| ResultMsg | 결과메시지 | 100 | |
| 신용카드(카카오페이 카드/네이버페이 카드/페이코페이/엘페이/핀페이 카드 포함) | |||
| 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 | |
| 가상계좌 | |||
| VbankNum | 가상계좌번호 | 20 | |
| VbankName | 가상계좌은행명 | 20 | |
| 카카오페이 공통 | |||
| PayType | 결제타입 | 10 | CARD: 카카오페이 카드, MONEY: 카카오페이 머니 |
| 네이버페이 공통 | |||
| PayType | 결제타입 | 10 | CARD: 네이버페이 카드, MONEY: 네이버페이 포인트 |
| PayId | 네이버페이 결제번호 | 100 | |
| 페이코페이 공통 | |||
| PayType | 결제타입 | 10 | CARD: 페이코페이 카드, MONEY: 페이코페이 포인트 |
| PayId | 페이코페이 결제번호 | 100 | |
| CpxAmt | 쿠폰할인 금액 | 12 | |
| PayAmt | 주결제수단 금액 | 12 | 총결제 금액 - 쿠폰할인 금액 |
승인 결과값을 전송 못 받았을 경우 승인 후 1시간 이내의 거래에 대한 승인 결과 값을 재 요청합니다.
* TrAuthKey 와 Tid 를 승인 결과 조회 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 = 20000; // 원천사 별로 최대 응답 시간이 상이하므로 가맹점 환경에 맞게 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
Function jsObject()
Dim obj
Set obj = New JsonWrapper
Set jsObject = obj
End Function
Class JsonWrapper
Private dict
Private Sub Class_Initialize()
Set dict = Server.CreateObject("Scripting.Dictionary")
End Sub
Public Property Let Item(key, value)
dict(key) = value
End Property
Public Default Property Get Item(key)
Item = dict(key)
End Property
Public Function jsString()
Dim key, json, value
json = "{"
For Each key In dict.Keys
value = Replace(dict(key), """", "\""") ' 큰따옴표 escape
json = json & """" & key & """:""" & value & ""","
Next
If dict.Count > 0 Then json = Left(json, Len(json) - 1) ' 마지막 쉼표 제거
json = json & "}"
jsString = json
End Function
End Class
결제 중단 시 결과 파라미터
사용자가 결제 중단 시 이동하는 페이지(StopUrl)의 결과 파라미터입니다.
※ StopUrl 페이지 설정은 Mobile 연동 시 필수 사항입니다.
| 파라미터 | 항목명 | 길이(char) | 설명 |
|---|---|---|---|
| PayMethod | 지불수단 | 10 |
CARD:신용카드,
BANK:계좌이체,
VBANK:가상계좌,
CELLPHONE:휴대폰결제,
NAVER:네이버페이,
KAKAO:카카오페이,
PAYCO:페이코페이,
LPAY:엘페이,
PINPAY:핀페이,
SAMSUNGPAY:삼성페이,
TOSS:토스, LINEPAY:라인페이
TMONEYPAY:티머니페이
APPLEPAY:애플페이
|
| GoodsName | 거래 상품명 | 40 | |
| Amt | 거래 금액 | 12 | 숫자만 가능, 문장부호 제외 |
| Moid | 상품주문번호 | 40 | 특수문자 포함 불가 |
| Mid | 상점아이디 | 10 | |
| MallUserId | 회원사고객ID | 20 | |
| BuyerName | 구매자명 | 30 | |
| BuyerTel | 구매자연락처 | 40 | |
| BuyerEmail | 구매자메일주소 | 60 | |
| MallReserved | 상점예비정보 | 500 | |
| ResultCode | 결과코드 | 4 | |
| ResultMsg | 결과메시지 | 100 |
결제결과 시 전달받는
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()));
뱅크페이 [다른결제] > [일반결제] 항목을 선택하여 테스트를 진행해야합니다.
계좌이체 테스트용 개인 및 법인번호, 계좌번호, 비밀번호입니다.
개인 주민등록번호: 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);
}
과세 및 비과세 필드를 직접 계산하는 가맹점일 경우 아래와 같은 방식으로 계산하세요.
// 총금액(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) **/
- 플랫폼 정산 가맹점의 경우 아래의 방식으로 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";