69 Replies
⏳ 잠시만 기다려주세요! 곧 답변드리겠습니다
오류 문의일 경우 아래 정보를 미리 전달해주시면, 빠른 답변에 도움이 됩니다.
- 주문번호(orderId) :
- 문의 내용 :
(img를 함께 첨부해주시면 도움이됩니다)
* 계약관련 내용은 1544-7772로 문의주세요.
* 주말/공휴일에는 답변이 늦을 수 있어요.
어떤 api 호출하셨나요
https://api.tosspayments.com/v1/payments/
입니다
tossPayments.requestPayment 호출은 이거고
저건 return이네용
requestPAyment에는 시크릿키가 안들어가는데요?
js method 호출하셨다는거죠?
네ㅐ네
서버 투 서버 api 호출하신게 아니라요
네 js로 했습니다
button.addEventListener('click', function () {
tossPayments.requestPayment('카드', {
amount: '<?=$amount?>', orderId: '<?=$orderId?>', orderName: '테마여행요금', customerName: '<?=$rsvInfo["themeResName"]?>', successUrl: '<?=$urls?>/<?=$siteCd?>/theme?' + queryStr, failUrl: '<?=$urls?>/<?=$siteCd?>/theme?' + queryStr }); }); 이건 버튼누를시 호출이구요 돌아오는 succes됬을땐 fetch("https://api.tosspayments.com/v1/payments/<?=$paymentKey?>", { method: "POST", headers: { "Authorization" : "Basic <?=$base64encodeLive?>",
"Content-Type" : "application/json" }, body: "{"amount":<?=$amount?>, "orderId":"<?=$orderId?>"}" }) .then(response => response.json()) .then(function (result) { var payProc = "<?=$payProc?>"; var code = result.code; if (code) { alert(result.message + "새로고침을 해주세요."); history.back(-1); } else if (!code) { 이렇게 했을때 var code = result.code; 여기에서 존재하지않는 결제정보라고 나옵니다
amount: '<?=$amount?>', orderId: '<?=$orderId?>', orderName: '테마여행요금', customerName: '<?=$rsvInfo["themeResName"]?>', successUrl: '<?=$urls?>/<?=$siteCd?>/theme?' + queryStr, failUrl: '<?=$urls?>/<?=$siteCd?>/theme?' + queryStr }); }); 이건 버튼누를시 호출이구요 돌아오는 succes됬을땐 fetch("https://api.tosspayments.com/v1/payments/<?=$paymentKey?>", { method: "POST", headers: { "Authorization" : "Basic <?=$base64encodeLive?>",
"Content-Type" : "application/json" }, body: "{"amount":<?=$amount?>, "orderId":"<?=$orderId?>"}" }) .then(response => response.json()) .then(function (result) { var payProc = "<?=$payProc?>"; var code = result.code; if (code) { alert(result.message + "새로고침을 해주세요."); history.back(-1); } else if (!code) { 이렇게 했을때 var code = result.code; 여기에서 존재하지않는 결제정보라고 나옵니다
이러면 가능성은
클라이언트키와
시크릿키가 매칭되지 않을 경우입니다.
우선 서로 같은 mid의 clientKey와 secretKey를 사용했는지 확인해주시겠어요?
ㅇㅣ상없다고 느끼실 경우 paymentKey공유해주세요
해당mid에 맞는 클라이언트키랑 secret키 맞습니다
paymentKey는 어떤거죠?
잠시만요
일단 저 요청은 서버에서 호출되어야 합니다. JS Fetch를 사용하는 부분이 아닙니다.
php curl로 요청을 보낼 수 있도록 해주시는게 좋을것 같습니다.
일단 페이먼트키는 찾아보고있는데
기존에 저방법으로 계속 결제사용을 했었는데 문제있는건가요?
위에 남겨주신것처럼 secretKey는 front에 노출되면 안됩니다.
서버투 서버로 호출해주셔야해요
<?=$base64encodeLive?> 를 통해서 변수를 JS로 보내고 계십니다. 이러면 프론트에 노출이 되므로 사용하시면 안되고
CORS 등으로 인해 데이터가 undefined로 들어갈 수도 있습니다.
문제가 있는지 로그를 확인해보기 위해서 paymentKey요청드렸어요
paymentKey확인이 어려우면 orderId보내주세요
이렇게 해서 테스트키로는 문제없이 동작을 했거든요
동작은 합니다만, 키 값이 노출되면 고객이 마음대로 결제를 취소하거나 발생시킬 수 있습니다.
또한 브라우저 버전 및 보안 정책에 따라 데이터값이 안들어오는(CORS 문제) 경우가 있을 수 있으며, 이 경우 존재하지 않는 결제정보로 인식될 수도 있습니다.
💡 정보 제출
민감 정보를 안전하게 제출해주세요
clientKEy랑 secretKey사용한 것 남겨주세요
ㅇㅟ에 정보제출로 넘겨주시기 바랍니다.
[orderId] => bGltaW1ldGUxNzA2MDc5MDMy[paymentKey] => dJv2eBNjG0Poxy1XQL8Rgv0O9ezyxL37nO5Wmlg96RKwZz4Y
방금 결제진행했구요
네네
위 제출버튼으로 clientKey/secretKey 전달도 부탁드립니다.
보냈습니다
요청하고 받으신 error 코드 있으신가요?
우선 해당 정보로 결제승인 api 호출된 내역이 없습니다.
fetch("https://api.tosspayments.com/v1/payments/<?=$paymentKey?>", {
method: "POST",
headers: {
"Authorization" : "Basic <?=$base64encodeLive?>",
"Content-Type" : "application/json" }, body: "{"amount":<?=$amount?>, "orderId":"<?=$orderId?>"}" }) .then(response => response.json()) .then(function (result) { var payProc = "<?=$payProc?>"; var code = result.code; if (code) { alert(result.message + "새로고침을 해주세요."); history.back(-1); 이렇게 요청했을때 존재하지 않는 결제 정보입니다 라고 뜹니다 토스 상점관리자에서 승인 내역 확인해보면 오늘 10시부터 완료 취소 완료 취소 완료 완료 총 6건이 나오는데 이부분 확인 가능 할까요?
"Content-Type" : "application/json" }, body: "{"amount":<?=$amount?>, "orderId":"<?=$orderId?>"}" }) .then(response => response.json()) .then(function (result) { var payProc = "<?=$payProc?>"; var code = result.code; if (code) { alert(result.message + "새로고침을 해주세요."); history.back(-1); 이렇게 요청했을때 존재하지 않는 결제 정보입니다 라고 뜹니다 토스 상점관리자에서 승인 내역 확인해보면 오늘 10시부터 완료 취소 완료 취소 완료 완료 총 6건이 나오는데 이부분 확인 가능 할까요?
우선 "존재하지 않는 결제 정보 입니다." 부터 확인해보시죠.
네
해당시간대에 요청 확인되지 않네요.
<?=$paymentKey?>
<?=$orderId?>
<?=$amount?>
3개 값은 어디서 가져오시나요
amount는 테마여행에서 사용자가 선택한 옵션 등의 총 합 금액이라 이건 결제창을 띄우기전에 저희 서버에서 계산해서 나오구요
orderid는 현재 로그인한 회원의 아이디에 time()- 타임스탬프를 합친 값을 넣습니다
paymentKey는
button.addEventListener('click', function () {
tossPayments.requestPayment('카드', {
amount: '<?=$amount?>', orderId: '<?=$orderId?>', orderName: '테마여행요금', customerName: '<?=$rsvInfo["themeResName"]?>', successUrl: '<?=$urls?>/<?=$siteCd?>/theme?' + queryStr, failUrl: '<?=$urls?>/<?=$siteCd?>/theme?' + queryStr }); }); 이거를 요청했을 때 받아오는거 같은데..
amount: '<?=$amount?>', orderId: '<?=$orderId?>', orderName: '테마여행요금', customerName: '<?=$rsvInfo["themeResName"]?>', successUrl: '<?=$urls?>/<?=$siteCd?>/theme?' + queryStr, failUrl: '<?=$urls?>/<?=$siteCd?>/theme?' + queryStr }); }); 이거를 요청했을 때 받아오는거 같은데..
paymentKey는 응답값을 받아서 보내시나요?
네네
그런데 우선 api 요청한 내역이 확인되지 않습니다.
결제창이 나오는것과 api요청 내역은 다른가요?
결제창은 requestPayments할 때고
이후 아래 호출한내역이 없어요
fetch("https://api.tosspayments.com/v1/payments/<?=$paymentKey?>", {
method: "POST",
headers: {
"Authorization" : "Basic <?=$base64encodeLive?>",
"Content-Type" : "application/json"
},
body: "{"amount":<?=$amount?>, "orderId":"<?=$orderId?>"}"
})
.then(response => response.json())
.then(function (result) {
var payProc = "<?=$payProc?>";
var code = result.code;
if (code) {
alert(result.message + "새로고침을 해주세요.");
history.back(-1);
일단 다시 로그들 찍어보았는데
https://api.tosspayments.com/v1/payments/misoy20240124162415RkbH5 404 (Not Found)
이부분이 이렇게 낫파운드인데
잘못된게있을까요
저 url 눌러서 접속했을 때 화면이 어떻게 나타나나요
{"code":"UNAUTHORIZED_KEY","message":"인증되지 않은 시크릿 키 혹은 클라이언트 키 입니다.","data":null}
서버에서는 저기가 호출안되는건가요?
네 저부분에서 404에러가 나옵니다
return이라고 해놓은 저희서버설정까진 값이가지만
저부분을 호출할때
404에러가나와서요
서버에서 api.tosspayments.com 으로 ping은 날아가나요?
잠시만요
네
정상적으로 핑갑니다

그럼 왜 404가 뜨는지 정상적으로 호출했는지 확인해보셔야할 것 같아요
저 url은 틀린건아닌거죠??
브라우저에서 접속된거 방금 확인되셨으니, url은 정상일 것 같네요
일단 저희가 결제호출부터 return 즉 fethch로 api호출까지의 네트워크 로그인데 이부분도 문제가 있는지 확인부탁드립니다.

아 깨지네요 잠시만요
프론트에서 호출하시는건가요?
결제창 호출은 프론트에서 합니다

여기 호출을 프론트에서 하고 계신건가요?

네 js부분에서 fetch로 하고있습니다
그렇게 하시면 안됩니다. 백엔드에서 호출할 수 있도록 해주시고,
백엔드(PHP curl)에서도 404가 발생한다면 그때 확인이 가능할 것 같습니다.
추가로 404가 발생하는 원인은 해당 Endpoint가 없기 때문입니다.
결제 승인을 위해서 호출하시는 거면 /v1/payments/confirm 으로 보내주셔야 합니다.
지금 요청하신 Endpoint는 결제가 승인된 뒤 조회하는 용도의 GET전용 Endpoint로 POST가 없기때문에 404가 반환되고 있습니다.
GitHub
payment-samples/payment-window/php/success.php at main · tosspaymen...
Contribute to tosspayments/payment-samples development by creating an account on GitHub.
@sauos
저 혹시
지금 테스트중인거 말고
이미 실제로 사용중인 부분이 있는데 같은방식으로
이런 오류는 어떤걸 봐야하나요?...
테스트중인건 이번에 새로 넣으려고 하는거구요
기존에는 같은방식으로 쓰는중이라...

해당건은 따로 확인이 필요하거든요.
그러면 저위에 알럿창은 빼고...
기존 개발해놓은건 정상동작을 하는데
새로운것도 같은 같은 결제키랑 코드인데 안되는경우라면 뭔가 어떤걸 다르게 설정을 해야하는걸까요
그것보다 말씀드리긴 죄송하지만, 정상동작을 하더라도 코드에 문제가 있는 것 같습니다.
프론트에서 승인을 진행하는 프로세스는 일반적이지 않으며, 결제 값 조작이나 취소 등을 마음껏 진행할 수 있는 보안 취약점을 안고 가시는거라서요.
시크릿키가 노출되게 되면 결제 발생/취소/조회 모두 가능하게 되며 지금 이미 이 방식으로 연동이 되어있다면
이미 문제가 발생하고 있을 수 있습니다.
알겠습니다 이 부분은 확인하고 조치 하도록 하겠습니다
그런데 같은 결제키에 같은 로직인데 하나는 되고 하나는 결제 정보가 안뜨는 이유는 무엇일까요?
현재 FE 에서 저희 서버로 승인 API 를 호출하시기 때문에 브라우저가 있는 PC 의 네트워크 환경을 탈것 같습니다.
즉 잘 되는 케이스와 안되는 케이스가 서로 다른 PC 이신것 아닌가요?
같은 pc이고 같은 프로젝트에 패키지만 다른 상태 입니다
어쨌든 Ayaan 님말씀대로 승인 API 를 fetch 로 호출하시면 브라우저 상에서 secretkey 를 확인할수 있고, 이게 유출되면 지금 사용하시는 모든 결제를 임의로 취소 할수 있습니다.
절대로 FE 에서 secretkey 를 이용한 요청을 하시면 안됩니다.
우선 BE 로 해당 로직을 모두 수정해 주세요.
네 알겠습니다
❤️ 기술문의 경험이 어떠셨나요?!
간단히 코멘트 남겨주세요! 제품 발전에 큰 힘이 됩니다.