토스는 결제만큼 연동도 간단합니다. 연동 전 아래 그림을 참고하시면 이해가 쉽습니다.
먼저 계약 문의를 통해 가맹점 가입을 신청합니다.
가입 승인이 완료되면 가맹점 계정이 발급되고, 가맹점 관리에 로그인하여 상점을 관리할 수 있습니다.
토스 가맹점 관리자에 로그인하면 결제 상점의 API Key를 확인할 수 있습니다. (발급받은 API Key는 '가맹점 관리자 > 가맹점 정보'에서 확인할 수 있습니다)
발급된 상점 API Key는 결제 생성 / 환불 등 모든 거래에서 인증 수단으로 활용합니다.
API Key가 외부에 유출되면 원치않는 결제 생성이나 환불 처리가 발생하여 상점의 금전적인 손실이 발생할 수
있습니다.
API key가 웹사이트에 노출되거나 외부인에게 유출되지 않도록 반드시 주의해주세요.
발급되는 API Key는 두 가지입니다. (테스트용 / 실거래용) 두 Key는 아래와 같은 차이가 있습니다.
주의해 주세요!
테스트가 완료되면 운영 오픈 전 반드시 '실 거래용 Key'로 변경 후 체크해주세요!
토스페이는 모두 운영환경으로 제공하고, apiKey 에 따라 테스트와 실거래를 구분합니다.
테스트용 Key로 서비스를 오픈하게 되는 경우, 고객의 결제는 성공했으나 가맹점에서는 금액을 받지 못한채로
무료 서비스를 제공하게 되는 위험이 있으니 반드시 확인해 주셔야 합니다.
고객은 '토스몰'을 둘러보다가 35,000원짜리 '토스 티셔츠'를 선택하여 결제를 요청합니다. 이 때, 토스몰은 토스 결제 서버에게 '결제 생성'을 요청해야합니다. 아래와 같이 결제 생성 API를 호출하세요.
고객의 결제는 아래와 같이 요청합니다.
curl https://pay.toss.im/api/v2/payments \ -H "Content-Type: application/json" \ -d '{ "orderNo":"1", "amount":25000, "amountTaxFree":0, "productDesc":"토스티셔츠", "apiKey":"sk_test_w5lNQylNqa5lNQe013Nq", "autoExecute":true, "resultCallback":"https://YOUR-SITE.COM/callback", "retUrl":"http://YOUR-SITE.COM/ORDER-CHECK", "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/v2/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", "1"); jsonBody.put("amount", 25000); jsonBody.put("amountTaxFree", 0); jsonBody.put("productDesc", "토스티셔츠"); jsonBody.put("apiKey", "sk_test_w5lNQylNqa5lNQe013Nq"); jsonBody.put("autoExecute", true); jsonBody.put("resultCallback", "https://YOUR-SITE.COM/callback"); jsonBody.put("retUrl", "http://YOUR-SITE.COM/ORDER-CHECK"); 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"] = "1"; $arrayBody["amount"] = 10000; $arrayBody["amountTaxFree"] = 0; $arrayBody["productDesc"] = "토스티셔츠"; $arrayBody["apiKey"] = "sk_test_w5lNQylNqa5lNQe013Nq"; $arrayBody["autoExecute"] = true; $arrayBody["resultCallback"] = "https://YOUR-SITE.COM/callback"; $arrayBody["retUrl"] = "http://YOUR-SITE.COM/ORDER-CHECK"; $arrayBody["retCancelUrl"] = "http://YOUR-SITE.COM/close"; $jsonBody = json_encode($arrayBody); $ch = curl_init('https://pay.toss.im/api/v2/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;
위 예제에서 알 수 있듯이 '결제 생성'을 위해서는 9가지 설정값을 담아 토스에 요청해야합니다.
앞서 말씀 드렸듯이, API Key는 절대 유출되어선 안됩니다.
결제 요청 내용이 웹페이지에 그대로 드러나지 않게 다시 한번 주의해주세요!
요청하신 결제 생성이 무사히 완료되면 토스는 아래와 같이 응답합니다.
이중 하나의 값이라도 전달받지 못했다면 방화벽의 문제일 수 있으니 '토스 방화벽 설정' 을 확인해 주셔야 합니다.
{"code":0,"checkoutPage":"https://pay.toss.im/payfront/auth?payToken=test_token1234567890",
"payToken":"example-payToken"}
code '0'은 결제 생성에 '성공'했음을 나타냅니다. 그 외에는 오류코드와 메시지가 전달됩니다.
checkoutPage결제를 진행할 수 있는 토스페이 웹페이지 URL입니다. 상점에서는 이 URL을 사용자에게 띄워주세요.
payToken 은 거래를 구분할 수 있는 토스 고유 값입니다. 결제를 진행할 때, 결제를 환불할 때, 결제의 현재 상태를 파악할 때 이 고유번호를 통해 해당 결제 건에 접근하게 되니 잘 보관해주세요!
토스페이 진행은 간단합니다. 결제 생성 시 응답으로 받은 'checkoutPage' URL로 구매자를 보내주시기만 하면 됩니다.
위 예제의 checkoutPage는 아래와 같습니다. (매 결제마다 다른 URL이 발급됩니다)
https://pay.toss.im/payfront/auth?payToken=example-payToken
checkoutPage URL로 이동시킬때 아래 사항을 주의해주세요.
구매자는 호출된 토스 화면을 통해 결제 수단을 선택한 후 결제를 진행할 수 있습니다.
그 후, 결제 인증까지의 모든 과정은 토스가 알아서 해드립니다. (토스머니를 선택했다면 계좌 유효성 검증 후
충전의 단계를 거치고, 카드 결제를 선택했다면 카드 소유자의 일치 여부를 확인하고 카드 추가부터 진행할 수
있습니다.)
토스 앱과 토스 서버 간의 통신이 이루어지는 구간입니다.
올바른 URL로 연결하셨다면 고객은 아래와 같은 화면을 통해 결제를 진행하게 됩니다.
토스는 앱 결제 방식을 지원합니다.
PC 웹 브라우저에서 결제를 진행하는 경우 사용자의 휴대폰 번호로 결제푸시 알람을 발송합니다.
이후 인증은 토스앱을 통해서 진행해 주시면 됩니다. 결제 보안을 위해 웹 키보드 방식의 웹결제는 제공하지 않습니다.
아래 그림과 같이, 고객이 결제 암호를 잘 입력하면 구매자 인증이 완료됩니다. 그러면 토스는 결제 생성 시 넘겨주신 'retUrl'로 고객을 보내드립니다.
retUrl로 고객을 보내면서, 인증 결과 (status) 와 함께 주문 번호 (orderNo), 결제수단(payMethod) 을 query
string 파라미터로 함께 보내드립니다. 예시는 다음과 같습니다.
카드 결제건의 경우 아래 인증 데이터에 추가로 결제카드 코드 (cardCompany)가 함께 리턴되고,
토스머니 결제건의 경우 추가로 은행 코드(bankCode)가 함께 리턴됩니다.
http://YOUR-SITE.COM/ORDER-CHECK?status=PAY_COMPLETE&orderNo=1&payMethod=TOSS_MONEY&bankCode=38
여기서 status 값을 확인해주세요.
결제 생성 요청에 대해 좀 더 자세히 알아봅니다. 아래 예제는 결제 생성 API가 지원하는 모든 파라미터를 사용한 코드입니다.
curl https://pay.toss.im/api/v2/payments \
-H "Content-Type: application/json" \
-d '{
"orderNo":"1", # 토스몰 고유의 주문번호 (필수)
"amount":25000, # 결제 금액 (필수)
"amountTaxFree":0, # 비과세 금액 (필수)
"productDesc":"토스티셔츠", # 상품 정보 (필수)
"apiKey":"sk_test_w5lNQylNqa5lNQe013Nq", # 상점의 API Key (필수)
"retUrl":"http://YOUR-SITE.COM/ORDER-CHECK?orderno=1", # 결제 완료 후 연결할 웹 URL (필수)
"retCancelUrl":"http://YOUR-SITE.COM/close", # 결제 취소 시 연결할 웹 URL (필수)
"autoExecute":true, # 자동 승인 설정 (필수)
"resultCallback":"https://YOUR-SITE.COM/callback", # 결제 결과 callback 웹 URL (필수-자동승인설정 true의 경우)
"callbackVersion":"V2", # callback 버전 (필수-자동승인설정 true의 경우)
"amountTaxable":22727, # 결제 금액 중 과세금액
"amountVat":2273, # 결제 금액 중 부가세
"amountServiceFee":0, # 결제 금액 중 봉사료
"expiredTime":"2019-06-17 12:47:35", # 결제 만료 예정 시각
"cashReceipt":true, # 현금영수증 발급 가능 여부
}'
결제 생성 요청 시 반드시 아래 9가지 값을 함께 보내주셔야합니다.
앱 결제를 위하여 토스에서 지원하는 스펙은 다음과 같습니다. 유의사항에 해당되는 부분이 있는지 꼭 확인해 주세요.
✓ '앱으로 결제하기' 를 클릭했을 때, 토스 앱 설치유무를 체크하고 곧바로 토스 앱을 호출하거나 앱 스토어로 이동하는 기능입니다.
✓ 토스페이 서버에서 위 링크를 직접 호출하고 있으니 연동하는 가맹점 앱에서 위의 링크를 허용할 수 있도록 처리해 주세요.
✓ 안드로이드의 경우, 가맹점 측의 Intent URI 파싱처리가 필요합니다.
✓ 토스에서는 iframe 방식을 공식 지원하지 않습니다만, 부득이하게 iframe 으로 토스 앱을 호출하시는 경우
앱이 호출되지 않거나 오류가 발생할 수 있으니 새 창을 띄워 호출하시길 권고드립니다.
이 파라미터를 통해 '결제 생성 후, 언제까지 결제 승인을 진행할 수 있는지' 설정할 수 있습니다. '결제 대기' 상태인 결제건의 만료 기한이 도래하면 토스 서버에서 자동으로 결제를 취소합니다.
상점 혹은 판매 물품에 특성에 따라 결제 만료 기간을 길게 혹은 짧게 설정할 수 있습니다.
결제 만료 기한은 최대 60분이며, 따로 설정하지 않는 경우 기본 15분으로 설정됩니다.
현금영수증 발급 가능 여부를 설정할 수 있습니다.
카드결제 혹은 문화상품권이나 백화점상품권, 모바일 쿠폰 등 과세 대상에서 제외되는 유가증권 등의 상품은
현금영수증 발행이
불가하며, 토스 머니와 같이 현금성 결제건에 한하여 현금영수증 발행이 가능합니다.
토스페이에서는 두 가지 옵션을 제공합니다.
구매자 인증이 완료되면 토스에서 즉시 출금을 시도하고 결제를 완료시키는 방법과 구매 상품의 재고 상황에 따라 '최종 승인'의 주체가 가맹점이 될 수도 있습니다.
결제 상점의 판매 상품에 따라 두 가지 방식을 고려하여 옵션을 활용할 수 있습니다.
아래 그림을 참고하세요.
전체 결제 금액 중 '비과세' 처리해야할 금액이 섞여있거나 부가세, 봉사료 비중을 원하는대로 설정하고 싶다면 결제 생성 시 '복합과세' 파라미터를 이용하세요.
토스에서는 총 금액과 비과세 금액만 필수로 체크하고 있습니다. 복합과세 설정이 필요하다면 네 가지 값을 설정해 주셔야 하며,
네 가지 값의 합은 총 결제 금액(amount)과 반드시 동일해야 합니다. 동일하지 않을 경우 에러가 발생합니다.
위 파라미터를 통해 설정한 값은 현금 영수증 발행 시 그대로 반영됩니다.
위 파라미터 값을 설정하지 않는 경우, 자동으로 아래와 같이 처리됩니다.
단, 현금영수증 발행 불가 결제(cashReceipt = false)인 경우, 아래와 같이 처리됩니다.
구매자 인증이 완료된 '대기' 상태에서 재고상태 확인 후 결제를 진행할 수 있습니다.
아래 예제는 승인 API가 지원하는 파라미터 중 일부를 사용한 코드입니다.
curl "https://pay.toss.im/api/v2/execute" \
-H "Content-Type: application/json" \
-d '{
"apiKey":"sk_test_w5lNQylNqa5lNQe013Nq", # 상점의 API Key (필수)
"payToken":"example-payToken", # 결제 고유 번호 (필수)
}'
'결제 승인'의 필수 파라미터는 2가지 입니다. '어느 가맹점'에서 '어떤 결제건'을 승인하는지 알려주세요!
결제 완료 건의 결제 금액 중 일부 또는 전부를 구매자에게 돌려줍니다.
환불 요청에 성공하는 즉시, 토스 머니로 결제된 거래건은 구매자의 계좌로 요청하신 금액이 입금되며,
카드결제 거래건은 승인취소 됩니다. 환불한 금액은 상점의 다음 정산에 반영됩니다.
아래 예제는 결제 환불 API가 지원하는 파라미터 중 일부를 사용한 코드입니다.
curl "https://pay.toss.im/api/v2/refunds" \
-H "Content-Type: application/json" \
-d '{
"apiKey":"sk_test_w5lNQylNqa5lNQe013Nq", # 상점의 API Key (필수)
"payToken":"example-payToken", # 결제 고유 번호 (필수)
"amount":10000, # 환불할 금액 (필수)
"amountTaxable":5000, # 환불할 금액 중 과세금액
"amountTaxFree":4000, # 환불할 금액 중 비과세금액 (필수)
"amountVat":500, # 환불할 금액 중 부가세
"amountServiceFee":500 # 환불할 금액 중 봉사료
}'
'결제 환불'의 필수 파라미터는 4가지 입니다. '어느 가맹점'에서 '어떤 결제건'을 환불하는지만 알려주세요!
총 결제 금액 중 일부만 환불하고자 하는 경우, 이 파라미터 값을 설정해주세요. 금액을 설정하지 않으면 결제 금액 전액을 환불합니다.
결제 생성 시, 세부 금액 구성(과세금액/비과세금액/부가세/봉사료)을 지정했다면, 환불 요청 시에도 반드시 어떤 부분에서 환불 처리할지 지정해야 합니다.
환불 요청하는 금액은 '남은 결제 금액'보다 작거나 같아야 하고, 환불할 세부 금액들의 총합은 반드시 전체 환불 금액(amount)과 동일해야 합니다. (다를 시 에러 발생)
결제 환불 사유를 기록해야한다면 이 파라미터를 활용하세요. 최대 255자까지 남길 수 있습니다.
결제가 생성되고 진행됨에 따라 결제의 '상태'는 끊임없이 바뀝니다. 상점 운영을 위해선 특정 결제건이 현재 어떤 상태인지 파악할 일이 많을 것입니다. 결제가 잘 끝난 것인지, 취소된 것은 아닌지. 환불 요청에 들어왔던 주문은 잘 환불 되었는지...
그럴땐 '결제 상태 확인 API'를 찾아주세요. 상황에 따라 승인,환불 응답을 수신하지 못한 경우에도 활용할 수 있습니다.
아래 예제는 결제 상태 확인 API 호출 코드입니다.
curl "https://pay.toss.im/api/v2/status" \
-H "Content-Type: application/json" \
-d '{
"apiKey":"sk_test_w5lNQylNqa5lNQe013Nq", # 상점의 API Key (필수)
"payToken":"example-payToken", # 결제 고유 번호 (필수)
}'
필수 파라미터는 딱 2가지 입니다. '어느 가맹점'에서 일어난 '어떤 결제건'을 조회하고 싶은지 알려주세요.
* '결제 고유 토큰 (payToken)' 대신 '상점의 주문번호 (orderNo)'값을 사용할 수도 있습니다.
결제 상태 확인 요청에 대한 응답은 아래와 같은 형태로 받게됩니다.
응답의 일부이며, 상세한 내용은 결제상태 API를 확인해주세요.
{
"code": 0, # 응답코드
"payToken": "example-payToken", # 결제 고유 토큰
"orderNo": "1", # 상점의 주문번호
"payStatus": "PAY_COMPLETE", # 결제 상태
"payMethod": "TOSS_MONEY", # 결제 수단
"amount": 15000, # 결제 요청금액
"transactions": [ # 거래 트랜잭션 목록
{
"stepType": "PAY",
"transactionId": "3243c76e-4669-881b-33a3b82ddf49",
"transactionAmount": 15000,
"discountAmount": 300,
"pointAmount": 0,
"paidAmount": 14700,
"regTs": "2020-03-01 12:33:20"
}
],
"createdTs": "2020-03-01 12:33:04", # 최초 결제요청 시간
"paidTs": "2020-03-01 12:33:20" # 결제 완료 처리 시간
}
각 항목은 다음과 같은 의미를 가지고 있습니다.
결제 상태는 아래 중 하나입니다.
각 상태에 대한 자세한 설명은 결제 API > 결제 상태 문서를 참고하세요.
PAY_STANDBY | 결제 대기 중 |
PAY_APPROVED | 구매자 인증 완료 |
PAY_CANCEL | 결제 취소 |
PAY_PROGRESS | 결제 진행 중 |
PAY_COMPLETE | 결제 완료 |
REFUND_PROGRESS | 환불 진행 중 |
REFUND_SUCCESS | 환불 성공 |
SETTLEMENT_COMPLETE | 정산 완료 |
SETTLEMENT_REFUND_COMPLETE | 환불 정산 완료 |
매출전표를 확인할 거래건의 결제토큰을 호출해 주세요.
호출 URL은 다음과 같습니다. 호출에 필요한 파라미터를 query string 형식으로 보내주시면 됩니다.
https://pay.toss.im/payfront/web/external/sales-check?payToken=example-payToken&transactionId=12637496-8a46-488c-bc30-febded96656f
✓ 신용카드 결제건만 확인 가능합니다. 토스머니 결제건은 현금영수증 발급내역으로 확인해 주세요.
✓ 매출전표 확인을 위해서는 구매자의 '생년월일' 과 '휴대폰번호' 로 추가 인증이 필요합니다.
✓ 결제대기(PAY_APPROVED) 혹은 결제취소(PAY_CANCEL) 등의 미완료 거래건은 확인이 불가합니다.
✓ 트랜잭션 코드 값은 필수 값이 아니므로 특정 상태를 확인하고 싶을 때 옵션 값으로 활용해 주세요!