토스 결제 API 소개

토스를 통한 결제 서비스를 사용하기 위한 API입니다. 토스 결제를 활용한 개발을 처음 시작하신다면, 좀 더 친절한 안내를 먼저 확인해보세요!

>> '토스 결제 시작하기' 문서로 바로가기


토스 결제 서비스를 지원하는 브라우저는 다음과 같습니다.

PC 브라우저, Android, iOS 모두 TLS 1.1 이상의 환경에서 동작이 가능하며, 디바이스 같은 경우 토스 앱의 최소 지원 버전 기준입니다.

  • IE 11, Safari 7, Chrome 38, Firefox 27 부터 지원
  • IE 9, 10 는 일부 지원 (Window 8.1 이상, Enable TLS 1.1, 1.2)
  • Android 5.0 Lollipop 부터 지원
  • iOS 9 부터 지원
  • Java 를 사용하시는 경우, jdk 1.8 이상 버전 사용을 권장합니다

결제 상태

결제 건이 생성된 후, 결제가 진행됨에 따라 결제 상태가 변경되며, 각 결제 상태마다 판매자 또는 구매자가 요청할 수 있는 행동도 변합니다. 아래는 결제 상태 목록과 각 상태에 대한 설명입니다.

생성된 결제의 현재 상태를 파악하려면 결제 상태 확인 API를 활용하세요.

결제 상태 목록

PAY_STANDBY
결제 대기 중
결제 건이 생성되었고, 구매자의 결제 진행을 대기 중인 상태. 이 상태에서 구매자나 가맹점이 결제를 취소할 수 있습니다. 또한 설정한 '만료 기간'이 도래하면 자동으로 취소됩니다.
PAY_APPROVED 수동 승인 설정 시
구매자 인증 완료
결제를 위한 구매자 인증 완료되고, 가맹점의 최종 승인을 기다리는 상태.
(결제 생성 시 'autoExecute'를 false로 설정한 경우에만 이 단계를 거칩니다)
PAY_CANCEL
결제 취소
결제가 완료되기 전에 구매자나 가맹점이 결제를 취소한 상태입니다. (결론적으론 금액의 이동 없이 종료된 건)
PAY_PROGRESS
결제 진행 중
구매자가 결제를 승인하여 구매자의 계좌에서 결제 금액을 출금 처리 중인 상태입니다.
PAY_COMPLETE
결제 완료
구매자 및 가맹점의 결제 승인 및 출금이 정상적으로 완료된 상태입니다
REFUND_PROGRESS
환불 진행 중
전액 또는 부분 환불을 진행 중인 상태로, 완료되기 전 까지 다른 환불을 진행할 수 없습니다.
REFUND_SUCCESS
환불 성공
전액 또는 부분 환불이 완료되어, 환불 처리한 금액이 구매자의 계좌로 입금 완료된 상태입니다.
SETTLEMENT_COMPLETE
정산 완료
결제 완료된 금액에 대해 정산이 완료되어 더 이상 환불이 불가한 상태입니다. (승인일 또는 구매 확정일로부터 1년 경과)
SETTLEMENT_REFUND_COMPLETE
환불 정산 완료
전액 또는 부분 환불에 대한 정산이 완료되어 더 이상 환불이 불가한 상태입니다. (승인일 또는 구매 확정일로부터 1년 경과했거나 전액 환불에 대한 정산 완료된 경우)
              
              
              
              
              
              
            

HTTP 응답 코드

HTTP Response Code

200
OK : 정상
400
Bad Request : 파라미터 오류
401
Unauthorized : 가맹점 key 오류
404
Not Found : 존재하지 않는 요청
50x
Server error : 서버 오류
              
              
              
              
              
              
            

결제 생성

결제 건을 생성합니다.

결제 생성 완료 후, 구매자의 결제 인증을 얻어 완료처리하는 방법은 아래 문서를 참고하세요.
토스 결제 시작하기 > 3. 구매자 인증 받기

endpoint

(POST)
https://pay.toss.im/api/v1/payments

parameters

apiKey string
가맹점 key
웹 브라우저 혹은 외부에 노출되지 않도록 유의해 주시기 바랍니다.
orderNo string
가맹점의 상품 주문번호
주문번호는 50자 이내여야 하고, '숫자, 영문자, 특수문자 _-:.^@'만 사용할 수 있습니다.
가맹점 주문번호 테스트와 라이브 환경 사이에서 중복되지 않도록 가맹점의 관리가 필요합니다. 중복되는 경우, "PAYMENT_EXISTING_PAYMENT" 오류가 발생합니다.
amount integer
결제 금액
금액과 관련된 모든 파라미터는 Number 형태로 보내주셔야 에러가 발생하지 않습니다.
productDesc string
상품 설명
상품 설명은 공백으로만 설정할 수 없고, 백슬래시(\)와 따옴표(",')를 포함할 수 없으며 총 255자 이내여야 합니다. 이 값에 한글이 포함되었다면 인코딩에 유의해주세요.
retUrl string
Web 결제 완료 후 연결할 웹페이지의 URL (결제 최종 승인 및 완료 처리할 페이지)
결제 완료 화면으로의 이동일 뿐, 정확한 결제 성공 유무를 보장할 수 없으니 반드시 resultCallback 을 통하여 처리하시기 바랍니다.
retCancelUrl string
토스 브릿지 페이지에서 사용자가 결제를 중단할때 사용자를 이동시킬 가맹점 페이지
이 값을 사용하면 토스 서버가 retCancelUrl 을 실행시킬 취소 버튼을 생성하고, 구매자는 브라우저나 앱을 종료하지 않고 취소 버튼을 통하여 가맹점이 설정한 URL로 redirect됩니다.
구매자 편의를 위하 반드시 활용해주세요!
retAppScheme string
App 결제 완료 후 연결할 app scheme (결제 최종 승인 및 완료 처리할 페이지). retAppScheme을 사용할 경우 retUrl은 사용하지 않아도 됩니다.
앱 결제를 이용하는 경우를 대비하여 이 곳에 가맹점 앱 스킴값을 적용하면, 결제 완료 후 토스앱 이동의 이탈을 막고 가맹점 앱으로 redirect 됩니다.
autoExecute boolean
자동 승인 여부 설정(기본 값: true)

true 구매자 인증 완료 시, 바로 결제 완료 처리
(true로 설정하면 반드시 'resultCallback' 값을 설정하고 '결제 완료' callback을 받았을 때만 구매 완료 처리해야합니다)
false 구매자 인증 완료 후 가맹점의 최종 승인 시 결제 완료 처리
('execute API'를 통해 최종 승인합니다)
amountTaxable integer
결제 금액 중 과세금액 (복합과세)
해당 값이 없을 경우 0 으로 보내주셔야 합니다. 빈 값의 경우 에러가 발생합니다.
amountTaxFree integer
결제 금액 중 비과세금액 (복합과세)
해당 값이 없을 경우 0 으로 보내주셔야 합니다. 빈 값의 경우 에러가 발생합니다.
amountVat integer
결제 금액 중 부가세 (복합과세)
해당 값이 없을 경우 0 으로 보내주셔야 합니다. 빈 값의 경우 에러가 발생합니다.
amountServiceFee integer
결제 금액 중 봉사료 (복합과세)
해당 값이 없을 경우 0 으로 보내주셔야 합니다. 빈 값의 경우 에러가 발생합니다.
expiredTime timestamp
결제 만료 기한 (기본값 15분, 최대 1시간 설정 가능)
형식 : 1970-01-01 00:00:00
resultCallback string
결제 결과 callback URL (결제 성공)
토스 서버가 정상 출금 완료 후 이 곳에 입력한 URL로 결과를 전송하기 때문에 가맹점 서버에서 반드시 확인하셔야 합니다.
callback URL에 80, 443 이외의 port가 포함되면 이용할 수 없으니 유의해주세요.
cashReceipt boolean
현금영수증 발급 가능 여부
현금영수증 기능을 활용하시는 경우 true, 미 사용의 경우 false로 선언해 주시기 바랍니다. 그러나, 기본 값이 true이기 때문에 현금영수증 사용 시 별도로 선언하지 않으셔도 됩니다.
userPhone string
구매자가 결제 시 이용할 휴대전화번호 지정
(지정 시 구매자가 번호를 변경할 수 없으므로 전화번호 정보가 정확할 때만 이용하십시오)
metadata string
결제와 연관된 추가 데이터 (최대 1024자)

response

code integer
응답코드

0 성공
-1 실패 (실패사유는 msg와 errorCode 제공)
checkoutPage string
생성된 결제를 진행하는 웹페이지 URL (구매자를 이 URL로 보내야 함)
토스가 전달한 값 그대로 사용하세요.
payToken string
Toss 결제 토큰
msg string
응답이 성공이 아닌 경우 설명 메세지
errorCode string
에러 코드

COMMON_PAY_ERROR 시스템 에러가 발생 하였습니다.
CORE_USER_ERROR 존재하지 않는 사용자 입니다.
COMMON_TEMP_DENIAL_ERROR 일시적 시스템 에러가 발생하였습니다.
COMMON_INVALID_PARAMETER 요청한 값이 부족하거나 올바르지 않습니다.
PAYMENT_UNDER_CONSTRUCTION 동일한 결제가 이미 존재합니다.
PAYMENT_DUPLICATION_ORDER_NO 중복된 주문번호(orderNo) 가 전달되었습니다.
Definition
POST https://pay.toss.im/api/v1/payments
Example Request
curl https://pay.toss.im/api/v1/payments \
    -H "Content-Type: application/json" \
    -d '{
        "orderNo":"2015072012211",
        "amount":10000,
        "amountTaxFree":0,
        "productDesc":"테스트결제",
        "apiKey":"sk_test_apikey1234567890",
        "autoExecute":"true",
        "resultCallback":"http://YOUR-SITE.COM/callback",
        "retUrl": "http://YOUR-SITE.COM/ORDER-CHECK?orderno=1",
        "retCancelUrl": "http://YOUR-SITE.COM/close"
        }'import java.nio.charset.StandardCharsets;

URL url = null;
URLConnection connection = null;
StringBuilder responseBody = new StringBuilder();
try {
	url = new URL("https://pay.toss.im/api/v1/payments");
	connection = url.openConnection();
	connection.addRequestProperty("Content-Type", "application/json");
	connection.setDoOutput(true);
	connection.setDoInput(true);

	org.json.simple.JSONObject jsonBody = new JSONObject();
	jsonBody.put("orderNo", "2015072012211");
	jsonBody.put("amount", 10000);
	jsonBody.put("amountTaxFree", 0);
	jsonBody.put("productDesc", "테스트 결제");
	jsonBody.put("apiKey", "sk_test_apikey1234567890");
    jsonBody.put("autoExecute", "true");
    jsonBody.put("resultCallback", "http://"http://YOUR-SITE.COM/callback");
    jsonBody.put("retUrl", "http://YOUR-SITE.COM/ORDER-CHECK?orderno=1");
    jsonBody.put("retCancelUrl", "http://YOUR-SITE.COM/close");

	BufferedOutputStream bos = new BufferedOutputStream(connection.getOutputStream());
	
    bos.write(jsonBody.toJSONString().getBytes(StandardCharsets.UTF_8));
	bos.flush();
	bos.close();

	
    BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
	String line = null;
	while ((line = br.readLine()) != null) {
		responseBody.append(line);
	}
	br.close();
} catch (Exception e) {
	responseBody.append(e);
}
System.out.println(responseBody.toString());$arrayBody = array();
$arrayBody["orderNo"] = "2015072012211";
$arrayBody["amount"] = 10000;
$arrayBody["amountTaxFree"] = 0;
$arrayBody["productDesc"] = "테스트 결제";
$arrayBody["apiKey"] = "sk_test_apikey1234567890";
$arrayBody["autoExecute"] = "true";
$arrayBody["resultCallback"] = "http://YOUR-SITE.COM/callback";
$arrayBody["retUrl"] = "http://YOUR-SITE.COM/ORDER-CHECK?orderno=1";
$arrayBody["retCancelUrl"] = "http://YOUR-SITE.COM/close";
$jsonBody = json_encode($arrayBody);

$ch = curl_init('https://pay.toss.im/api/v1/payments');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonBody);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($jsonBody))
);

$result = curl_exec($ch);
curl_close($ch);

echo "Response: ".$result;Dim data, httpRequest, postResponse

data = "apiKey=sk_test_apikey1234567890"
data = data & "&orderNo=2015072012211"
data = data & "&amount=10000"
data = data & "&amountTaxFree=0"
data = data & "&productDesc=ASPtestProduct"
data = data & "&autoExecute=true"
data = data & "&resultCallback=http://YOUR-SITE.COM/callback"
data = data & "&retUrl=http://YOUR-SITE.COM/ORDER-CHECK?orderno=1"
data = data & "&retCancelUrl=http://YOUR-SITE.COM/close"

Set httpRequest = Server.CreateObject("MSXML2.ServerXMLHTTP")
httpRequest.Open "POST", "https://pay.toss.im/api/v1/payments", False
httpRequest.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
httpRequest.Send data

postResponse = httpRequest.ResponseText

Response.Write postResponseimport urllib, urllib2

url = "https://pay.toss.im/api/v1/payments"
params = {
    "orderNo": "2015072012211",
    "amount": 10000,
    "amountTaxFree": 0,
    "productDesc":"테스트 결제",
    "apiKey": "sk_test_apikey1234567890",
    "autoExecute": "true",
    "resultCallback": "http://YOUR-SITE.COM/callback",
    "retUrl": "http://YOUR-SITE.COM/ORDER-CHECK?orderno=1",
    "retCancelUrl": "http://YOUR-SITE.COM/close"
}

response = urllib.urlopen(url, urllib.urlencode(params))
print(response.read())require 'net/http'
require 'json'

uri = URI.parse("https://pay.toss.im/api/v1/payments")

params = {
        "orderNo" => "2015072012211",
        "amount"=> 10000,
        "amountTaxFree"=> 0,
        "productDesc" => "테스트 결제",
        "apiKey" => "sk_test_apikey1234567890",
        "autoExecute" => "true",
        "resultCallback" => "http://YOUR-SITE.COM/callback",
        "retUrl": "http://YOUR-SITE.COM/ORDER-CHECK?orderno=1",
        "retCancelUrl": "http://YOUR-SITE.COM/close"
}

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path)
request.set_form_data(params)
response = http.request(request)

p JSON.parse(response.body)
Example Response
{"code":0,"checkoutPage":"https://pay.toss.im/payfront/auth?payToken=test_token1234567890","payToken":"test_token1234567890"}

결제 결과 Callback (resultCallback)

결제 처리가 완료되면 결제 상태가 변경되고, 토스는 가맹점 서버로 변경 사항을 알려드립니다.

다시 한번 말씀드립니다.
‘결제완료’ callback을 받았을 때, 결제완료 상태를 변경하시고 재고차감 등의 로직을 처리해 주세요.
자동 승인 설정을 사용 시 (autoExecute가 true) 필수적으로 활용해야 합니다.

* 생성된 결제 건에 resultCallback 파라미터 값이 있을 경우에만 동작합니다.

parameter

status string
PAY_COMPLETE
payToken string
Toss 결제 토큰
orderNo timestamp
결제 처리 시각
형식 : 2019-04-01 00:00:00
paidTs string
Toss 결제와 이어진 주문번호
metadata string
결제 생성 시 저장한 연관 정보

HTTP 응답 코드

HTTP Response Code

200
OK : 정상
400
Bad Request : 파라미터 오류
401
Unauthorized : 가맹점 key 오류
404
Not Found : 존재하지 않는 요청
50x
Server error : 서버 오류
xxx
Server error : 기타 등등
Definition
POST http://YOUR-SITE.COM/callback (결제 생성 시 가맹점에서 설정한 callback URL)
Example Request
{
 "status": "PAY_COMPLETE",
 "payToken": "test_token1234567890",
 "orderNo": "2015072012211",
 "paidTs": "2019-04-01 00:00:00"
}                            
                        

가맹점 결제 승인

자동 승인 설정을 false로 사용하는 가맹점에서만 처리하는 로직입니다.
구매자 인증 완료 상태(PAY_APPROVED)의 결제 건을 가맹점이 주체가 되어 최종 승인하고 결제를 완료 처리합니다.

결제 승인에 관한 자세한 내용은 아래 문서를 참고하세요.
토스 결제 시작하기 > 결제 승인하기

필수 파라미터는 딱 2가지 입니다. '어느 가맹점'에서 '어떤 결제건'을 최종 승인할지 알려주세요.
필요에 따라 결제건의 유효성 검증을 할 수 있습니다.

endpoint

(POST)
https://pay.toss.im/api/v1/execute

parameters

apiKey string
가맹점 key
웹 브라우저 혹은 외부에 노출되지 않도록 유의해 주시기 바랍니다.
payToken string
토스 결제 토큰 (승인할 결제 건의 토큰값)
amount integer
결제 금액
결제 승인 시 orderNo와 amount를 함께 보내면 일치 여부를 확인합니다. payToken과 연결된 결제건과 orderNo나 amount가 다르면 승인 실패처리하여 다시 한번 유효성을 검증합니다.
orderNo string
가맹점의 상품 주문번호
결제 승인 시 orderNo와 amount를 함께 보내면 일치 여부를 확인합니다. payToken과 연결된 결제건과 orderNo나 amount가 다르면 승인 실패처리하여 다시 한번 유효성을 검증합니다.

response

code integer
응답코드

0 성공
-1 실패 (실패사유는 msg와 errorCode로 제공)
approvalTime timestamp
승인시각 (yyyy-MM-dd HH:mm:ss)
amount integer
승인한 결제 금액
orderNo string
승인한 상품 주문번호
msg string
응답이 성공이 아닌 경우 설명 메세지
errorCode string
에러 코드

PAY_EXPIRED 결제 기한이 만료되었습니다.
COMMON_TIMEOUT 출금 타임 아웃이 발생하였습니다.
PAY_UNAUTHORIZED 본인의 결제가 아닙니다.
COMMON_EXCEED_LIMIT 결제한도를 초과 하였습니다.
PAY_ALREADY_COMPLETED 이미 완료된 결제입니다.
PAY_ITS_NOT_ABLE_TO_PAY 결제를 진행 할 수 없는 상태 입니다.
COMMON_NOT_ENOUGH_CASH 잔고가 부족합니다.
EXECUTE_PAY_NOT_APPROVED 승인 되지 않은 결제 입니다.
COMMON_SIGN_FAILED_CS_CALL 전자서명에 실패 하였습니다.
COMMON_BREAK_TIME_OF_BANK 은행 점검시간 입니다.
Definition
POST https://pay.toss.im/api/v1/execute
Example Request
curl "https://pay.toss.im/api/v1/execute" \
    -H "Content-Type: application/json" \
    -d '{
        "payToken":"test_token1234567890",
        "apiKey":"sk_test_apikey1234567890"
        }'import java.nio.charset.StandardCharsets;

URL url = null;
URLConnection connection = null;
StringBuilder responseBody = new StringBuilder();
try {
	url = new URL("https://pay.toss.im/api/v1/execute");
	connection = url.openConnection();
	connection.addRequestProperty("Content-Type", "application/json");
	connection.setDoOutput(true);
	connection.setDoInput(true);

	org.json.simple.JSONObject jsonBody = new JSONObject();
	jsonBody.put("payToken", "test_token1234567890");
	jsonBody.put("apiKey", "sk_test_apikey1234567890");

	BufferedOutputStream bos = new BufferedOutputStream(connection.getOutputStream());
	
    bos.write(jsonBody.toJSONString().getBytes(StandardCharsets.UTF_8));
	bos.flush();
	bos.close();

	
    BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
	String line = null;
	while ((line = br.readLine()) != null) {
		responseBody.append(line);
	}
	br.close();
} catch (Exception e) {
	responseBody.append(e);
}
System.out.println(responseBody.toString());$arrayBody = array();
$arrayBody["payToken"] = "test_token1234567890";
$arrayBody["apiKey"] = "sk_test_apikey1234567890";
$jsonBody = json_encode($arrayBody);

$ch = curl_init('https://pay.toss.im/api/v1/execute');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonBody);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($jsonBody))
);

$result = curl_exec($ch);
curl_close($ch);

echo "Response: ".$result;Dim data, httpRequest, postResponse

data = "apiKey=sk_test_apikey1234567890"
data = data & "&payToken=test_token1234567890"

Set httpRequest = Server.CreateObject("MSXML2.ServerXMLHTTP")
httpRequest.Open "POST", "https://pay.toss.im/api/v1/execute", False
httpRequest.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
httpRequest.Send data

postResponse = httpRequest.ResponseText

Response.Write postResponseimport urllib, urllib2

url = "https://pay.toss.im/api/v1/execute"
params = {
    "payToken": "test_token1234567890",
    "apiKey": "sk_test_apikey1234567890"
}

response = urllib.urlopen(url, urllib.urlencode(params))
print(response.read())require 'net/http'
require 'json'

uri = URI.parse("https://pay.toss.im/api/v1/execute")

params = {
        "payToken" => "test_token1234567890",
        "apiKey" => "sk_test_apikey1234567890"
}

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path)
request.set_form_data(params)
response = http.request(request)

p JSON.parse(response.body)
Example Response

{"code":0,"approvalTime":"2016-11-16 13:59:59"}
            

결제 취소

결제 대기 중인 결제 건을 취소합니다. (결제가 완료되어 구매자의 계좌에서 출금된 상태에서는 취소할 수 없으며 환불 처리해야 합니다)

endpoint

(POST)
https://pay.toss.im/api/v1/cancel

parameters

apiKey string
가맹점 key
웹 브라우저 혹은 외부에 노출되지 않도록 유의해 주시기 바랍니다.
payToken string
Toss 결제 토큰
reason string
취소 사유 (최대 50자)

response

code integer
응답코드

0 성공
-1 실패 (실패사유는 msg와 errorCode로 제공)
msg string
응답이 성공이 아닌 경우 설명 메세지
errorCode string
에러 코드
Definition
POST https://pay.toss.im/api/v1/cancel
Example Request
curl "https://pay.toss.im/api/v1/cancel" \
    -H "Content-Type: application/json" \
    -d '{
        "payToken":"test_token1234567890",
        "apiKey":"sk_test_apikey1234567890"
        }'import java.nio.charset.StandardCharsets;

URL url = null;
URLConnection connection = null;
StringBuilder responseBody = new StringBuilder();
try {
	url = new URL("https://pay.toss.im/api/v1/cancel");
	connection = url.openConnection();
	connection.addRequestProperty("Content-Type", "application/json");
	connection.setDoOutput(true);
	connection.setDoInput(true);

	org.json.simple.JSONObject jsonBody = new JSONObject();
	jsonBody.put("payToken", "test_token1234567890");
	jsonBody.put("reason", "재고 부족");
	jsonBody.put("apiKey", "sk_test_apikey1234567890");

	BufferedOutputStream bos = new BufferedOutputStream(connection.getOutputStream());
	
    bos.write(jsonBody.toJSONString().getBytes(StandardCharsets.UTF_8));
	bos.flush();
	bos.close();

	
    BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
	String line = null;
	while ((line = br.readLine()) != null) {
		responseBody.append(line);
	}
	br.close();
} catch (Exception e) {
	responseBody.append(e);
}
System.out.println(responseBody.toString());$arrayBody = array();
$arrayBody["payToken"] = "test_token1234567890";
$arrayBody["reason"] = "재고 부족";
$arrayBody["apiKey"] = "sk_test_apikey1234567890";
$jsonBody = json_encode($arrayBody);

$ch = curl_init('https://pay.toss.im/api/v1/cancel');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonBody);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($jsonBody))
);

$result = curl_exec($ch);
curl_close($ch);

echo "Response: ".$result;Dim data, httpRequest, postResponse
​
data = "apiKey=sk_test_apikey1234567890"
data = data & "&payToken=test_token1234567890"
data = data & "&reason=SoldOut"
​
Set httpRequest = Server.CreateObject("MSXML2.ServerXMLHTTP")
httpRequest.Open "POST", "https://pay.toss.im/api/v1/cancel", False
httpRequest.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
httpRequest.Send data
​
postResponse = httpRequest.ResponseText
​
Response.Write postResponse
import urllib, urllib2

url = "https://pay.toss.im/api/v1/cancel"
params = {
    "payToken": "test_token1234567890",
    "reason":"재고 부족",
    "apiKey": "sk_test_apikey1234567890"
}

response = urllib.urlopen(url, urllib.urlencode(params))
print(response.read())require 'net/http'
require 'json'

uri = URI.parse("https://pay.toss.im/api/v1/cancel")

params = {
        "payToken" => "test_token1234567890",
        "reason" => "재고 부족",
        "apiKey" => "sk_test_apikey1234567890"
}

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path)
request.set_form_data(params)
response = http.request(request)

p JSON.parse(response.body)
Example Response
{"code":0}
            

결제 환불

결제 완료 건의 결제 금액 중 일부 또는 전부를 구매자에게 돌려줍니다.

endpoint

(POST)
https://pay.toss.im/api/v1/refunds

parameters

apiKey string
가맹점 key
웹 브라우저 혹은 외부에 노출되지 않도록 유의해 주시기 바랍니다.
payToken string
토스 결제 토큰
refundNo string
환불 번호
환불 상태 확인 시 필요. 미입력 시 자동 생성되며 환불 완료 응답에서 확인 가능
reason string
환불 사유 (최대 50자)
amount integer
환불할 금액
미입력시 환불할 결제건의 남은 전액을 환불 처리
amountTaxable integer
환불할 금액 중 과세금액
amountTaxFree integer
환불할 금액 중 비과세금액
환불할 금액중 비과세 금액, 없으면 0으로 설정
amountVat integer
환불할 금액 중 부가세
값이 없으면 환불할 과세금액을 11로 나눈 후 소수점 첫째 자리에서 올림
amountServiceFee integer
환불할 금액 중 봉사료
결제 생성 시 봉사료 설정한 경우에만 입력 가능

response

code integer
응답코드

0 성공
-1 실패 (실패사유는 msg와 errorCode로 제공)
refundNo string
환불 번호
환불 상태 확인 시 필요
refundableAmount integer
환불 가능 금액
approvalTime timestamp
승인시각 (yyyy-MM-dd HH:mm:ss)
msg string
응답이 성공이 아닌 경우 설명 메세지
errorCode string
에러 코드

INACTIVE_USER 계정이 비활성화/삭제된 사용자의 결제.
COMMON_REFUND_ERROR 이미 환불된 결제, 환불 가능 기간 180일이 지난 결제.
REFUND_EXCEED_DAILY 환불 금액이 상점의 일 환불 한도보다 클수 없습니다.
REFUND_EXCEED_AMOUNT 환불금액이 결제금액보다 더 클수 없습니다.
REFUND_PENDING_SUCCESS 점검이 끝난 후 자동으로 환불이 될 예정입니다. 잠시만 기다려주세요.
REFUND_NO_TAXFREE_ON_COMPLEX_TAX 과세정보가 올바르지 않습니다.
Definition
POST https://pay.toss.im/api/v1/refunds
Example Request
curl "https://pay.toss.im/api/v1/refunds" \
    -H "Content-Type: application/json" \
    -d '{
        "payToken":"test_token1234567890",
        "apiKey":"sk_test_apikey1234567890"
        }'import java.nio.charset.StandardCharsets;

URL url = null;
URLConnection connection = null;
StringBuilder responseBody = new StringBuilder();
try {
	url = new URL("https://pay.toss.im/api/v1/refunds");
	connection = url.openConnection();
	connection.addRequestProperty("Content-Type", "application/json");
	connection.setDoOutput(true);
	connection.setDoInput(true);

	org.json.simple.JSONObject jsonBody = new JSONObject();
	jsonBody.put("payToken", "test_token1234567890");
	jsonBody.put("amount", "5000");
	jsonBody.put("apiKey", "sk_test_apikey1234567890");

	BufferedOutputStream bos = new BufferedOutputStream(connection.getOutputStream());
	
    bos.write(jsonBody.toJSONString().getBytes(StandardCharsets.UTF_8));
	bos.flush();
	bos.close();

	
    BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
	String line = null;
	while ((line = br.readLine()) != null) {
		responseBody.append(line);
	}
	br.close();
} catch (Exception e) {
	responseBody.append(e);
}
System.out.println(responseBody.toString());$arrayBody = array();
$arrayBody["payToken"] = "test_token1234567890";
$arrayBody["amount"] = 5000;
$arrayBody["apiKey"] = "sk_test_apikey1234567890";
$jsonBody = json_encode($arrayBody);

$ch = curl_init('https://pay.toss.im/api/v1/refunds');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonBody);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($jsonBody))
);

$result = curl_exec($ch);
curl_close($ch);

echo "Response: ".$result;Dim data, httpRequest, postResponse

data = "apiKey=sk_test_apikey1234567890"
data = data & "&payToken=test_token1234567890"
data = data & "&amount=1000"

Set httpRequest = Server.CreateObject("MSXML2.ServerXMLHTTP")
httpRequest.Open "POST", "https://pay.toss.im/api/v1/refunds", False
httpRequest.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
httpRequest.Send data

postResponse = httpRequest.ResponseText

Response.Write postResponseimport urllib, urllib2

url = "https://pay.toss.im/api/v1/refunds"
params = {
    "payToken": "test_token1234567890",
    "amount": 5000,
    "apiKey": "sk_test_apikey1234567890"
}

response = urllib.urlopen(url, urllib.urlencode(params))
print(response.read())require 'net/http'
require 'json'

uri = URI.parse("https://pay.toss.im/api/v1/refunds")

params = {
        "payToken" => "test_token1234567890",
        "amount"=> 5000,
        "apiKey" => "sk_test_apikey1234567890"
}

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path)
request.set_form_data(params)
response = http.request(request)

p JSON.parse(response.body)
Example Response
{"code":0,"refundNo":"cc92a9ef-8a81-2938-dda9-ff8a78ae29b8","approvalTime":"2016-11-16 13:59:59"}
            

결제 상태 확인

생성된 결제의 현재 상태를 조회합니다.

endpoint

(POST)
https://pay.toss.im/api/v1/status

parameters

apiKey string
가맹점 key
웹 브라우저 혹은 외부에 노출되지 않도록 유의해 주시기 바랍니다.
payToken 또는 orderNo string
토스 결제 토큰 또는 가맹점 주문번호 (payToken의 우선순위 높음)

response

code integer
응답코드

0 성공
-1 실패 (실패사유는 msg와 errorCode로 제공)
payToken string
토스 결제 토큰
payStatus string
결제 상태

PAY_STANDBY 결제 대기 중
PAY_APPROVED 구매자 인증 완료
PAY_CANCEL 결제 취소
PAY_PROGRESS 결제 진행 중
PAY_COMPLETE 결제 완료
REFUND_PROGRESS 환불 진행 중
REFUND_SUCCESS 환불 성공
SETTLEMENT_COMPLETE 정산 완료
SETTLEMENT_REFUND_COMPLETE 환불 정산 완료
orderNo string
토스 결제와 이어진 주문번호
amount integer
결제 금액
amountTaxable integer
결제 금액 중 과세금액 (복합과세)
amountTaxFree integer
결제 금액 중 비과세금액 (복합과세)
amountVat integer
결제 금액 중 부가세 (복합과세)
amountServiceFee integer
결제 금액 중 봉사료 (복합과세)
timeCreated timestamp
결제 생성 시각
timePayComplete timestamp
결제 완료 시각
timePayCancel timestamp
결제 취소 시각
productDesc string
상품 설명
availableActions list
가능한 액션 목록

CANCEL 결제 취소
REFUND 결제 환불
refunds list
조회한 결제건에 대한 환불 요청 및 결과
timeRefundSuccess timestamp
환불 완료 시각
metadata string
결제와 연관된 추가 데이터
msg string
응답이 성공이 아닌 경우 설명 메세지
errorCode string
에러 코드
payMethod string
결제수단

TOSS_MONEY 토스 머니
CARD 토스 카드
cardCompanyName string
결제 카드사명
토스카드 결제의 경우에만 리턴
테스트용 apiKey로 결제 진행 시 리턴되지 않습니다.
spreadOut integer
할부 개월
토스카드 결제의 경우에만 리턴
isInterest boolean
무이자 여부
토스카드 결제의 경우에만 리턴
true : 적용, false : 미적용
Definition
POST https://pay.toss.im/api/v1/status
Example Request
curl "https://pay.toss.im/api/v1/status" \
    -H "Content-Type: application/json" \
    -d '{
        "payToken":"test_token1234567890",
        "apiKey":"sk_test_apikey1234567890"
        }'import java.nio.charset.StandardCharsets;

URL url = null;
URLConnection connection = null;
StringBuilder responseBody = new StringBuilder();
try {
	url = new URL("https://pay.toss.im/api/v1/status");
	connection = url.openConnection();
	connection.addRequestProperty("Content-Type", "application/json");
	connection.setDoOutput(true);
	connection.setDoInput(true);

	org.json.simple.JSONObject jsonBody = new JSONObject();
	jsonBody.put("orderNo", "2015072012211");
	jsonBody.put("apiKey", "sk_test_apikey1234567890");

	BufferedOutputStream bos = new BufferedOutputStream(connection.getOutputStream());
	
    bos.write(jsonBody.toJSONString().getBytes(StandardCharsets.UTF_8));
	bos.flush();
	bos.close();

	
    BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
	String line = null;
	while ((line = br.readLine()) != null) {
		responseBody.append(line);
	}
	br.close();
} catch (Exception e) {
	responseBody.append(e);
}
System.out.println(responseBody.toString());$arrayBody = array();
$arrayBody["orderNo"] = "2015072012211";
$arrayBody["apiKey"] = "sk_test_apikey1234567890";
$jsonBody = json_encode($arrayBody);
// echo "Request: ".$request."
"; $ch = curl_init('https://pay.toss.im/api/v1/status'); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonBody); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Content-Length: ' . strlen($jsonBody)) ); $result = curl_exec($ch); curl_close($ch); echo "Response: ".$result;
Dim data, httpRequest, postResponse data = "apiKey=sk_test_apikey1234567890" data = data & "&orderNo=2015072012211" Set httpRequest = Server.CreateObject("MSXML2.ServerXMLHTTP") httpRequest.Open "POST", "https://pay.toss.im/api/v1/status", False httpRequest.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded" httpRequest.Send data postResponse = httpRequest.ResponseText Response.Write postResponseimport urllib, urllib2 url = "https://pay.toss.im/api/v1/status" params = { "orderNo": "2015072012211", "apiKey": "sk_test_apikey1234567890" } response = urllib.urlopen(url, urllib.urlencode(params)) print(response.read())require 'net/http' require 'json' uri = URI.parse("https://pay.toss.im/api/v1/status") params = { "orderNo" => "2015072012211", "apiKey" => "sk_test_apikey1234567890" } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri.path) request.set_form_data(params) response = http.request(request) p JSON.parse(response.body)
Example Response
{
    "payToken": "test_token1234567890",
    "payStatus": "REFUND_SUCCESS",
    "orderNo": "2015072012211",
    "amount":110000,
    "amountTaxable":100000,
    "amountTaxFree":0,
    "amountVat":10000,
    "amountServiceFee":0,
    "timeCreated":"2017-02-15 11:59:48",
	"timePayComplete":"2017-02-15 12:01:19",
	"timePayCancel":"",
    "productDesc":"테스트 상품",
    
    "availableActions": [
    "REFUND"
    ],
    "refunds": [
        {
        "reason": "일부 상품 환불",
        "amount": 100,
        "refundNo": "7161b8e3-4b79-49d7-ab3c-3ae898aa073b",
        "timeRefundSuccess": "2017-02-15 16:12:40",
        "status": "SUCCESS"
        },
        {
        "reason": "일부 상품 환불",
        "amount": 200,
        "refundNo": "a636fe94-4e1e-41c8-90d9-b17180bdaf04",
        "timeRefundSuccess": "2017-02-15 16:12:43",
        "status": "SUCCESS"
        },
        {
        "reason": "일부 상품 환불",
        "amount": 500,
        "refundNo": "cc92a9ef-8a81-2938-dda9-ff8a78ae29b8",
        "timeRefundSuccess": "2017-02-15 16:12:46",
        "status": "SUCCESS"
        }
    ],
    "code": 0,
    "status": 200,
    "metadata": "metadata",
    "payMethod": "CARD",
    "cardCompanyName": "현대카드",
    "spreadOut": "06",
    "isInterest": "true"
}
            

환불 상태 확인

요청하신 환불 건의 현재 상태를 조회합니다. (요청 건별 조회)

endpoint

(GET)
https://pay.toss.im/api/v1/refunds/{refundNo}

parameters

apiKey string
가맹점 key
웹 브라우저 혹은 외부에 노출되지 않도록 유의해 주시기 바랍니다.

response

code integer
응답코드

0 성공
-1 실패 (실패사유는 msg와 errorCode로 제공)
refund list
환불 번호와 금액, 상태, 사유
msg string
응답이 성공이 아닌 경우 설명 메세지
errorCode string
에러 코드
Definition
GET https://pay.toss.im/api/v1/refunds/{refundNo}
Example Request
curl -X GET \
  'https://pay.toss.im/api/v1/refunds/f0fe4083-fe1b-44e5-ba04-4390bc19bc5e?apiKey=sk_test_apikey1234567890' \
  -H 'content-type: application/json'OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n    \"apiKey\":\"sk_test_LY5kmjV2l7LY5kmjV2l7\"\n}");
Request request = new Request.Builder()
  .url("https://pay.toss.im/api/v1/refunds/f0fe4083-fe1b-44e5-ba04-4390bc19bc5e?apiKey=sk_test_apikey1234567890")
  .get()
  .addHeader("content-type", "application/json")
  .build();

Response response = client.newCall(request).execute();$request = new HttpRequest();
$request->setUrl('https://pay.toss.im/api/v1/refunds/f0fe4083-fe1b-44e5-ba04-4390bc19bc5e');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'apiKey' => 'sk_test_apikey1234567890'
));

$request->setHeaders(array(
  'content-type' => 'application/json'
));

$request->setBody('{
    "apiKey":"sk_test_LY5kmjV2l7LY5kmjV2l7"
}');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}import http.client

conn = http.client.HTTPSConnection("pay.toss.im")

payload = "{\n    \"apiKey\":\"sk_test_LY5kmjV2l7LY5kmjV2l7\"\n}"

headers = {
    'content-type': "application/json"
    }

conn.request("GET", "/tosspay/api/v1/refunds/f0fe4083-fe1b-44e5-ba04-4390bc19bc5e?apiKey=sk_test_apikey1234567890", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))require 'uri'
require 'net/http'

url = URI("https://pay.toss.im/api/v1/refunds/f0fe4083-fe1b-44e5-ba04-4390bc19bc5e?apiKey=sk_test_apikey1234567890")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["content-type"] = 'application/json'
request.body = "{\n    \"apiKey\":\"sk_test_LY5kmjV2l7LY5kmjV2l7\"\n}"

response = http.request(request)
puts response.read_body
Example Response
{
    "code": 0,
    "refund": {
        "refundNo": "7161b8e3-4b79-49d7-ab3c-3ae898aa073b",
        "status": "SUCCESS",
        "amount": 100,
        "reason": "부분 환불 테스트"
    }
}