successUrl 쿼리 파라미터 amount 값의 설계 의도 문의
안녕하세요. 토스페이먼츠 결제 연동 과정에서 보안 관련 질문이 있어 문의드립니다.
현재 이해한 결제 흐름
1. 클라이언트에서 widgets.setAmount()로 금액 설정 (UI 표시용)
2. 결제 요청 전 서버에 orderId와 실제 상품 금액을 저장 (보안 검증용)
3. 결제 인증 완료 후 successUrl에 amount 쿼리 파라미터가 포함되어 리다이렉트
4. 서버에서 저장된 실제 금액으로 승인 API 호출
질문사항
1. successUrl의 amount 파라미터 출처
- 이 값이 클라이언트 setAmount()에서 설정한 값인지요?
- 만약 그렇다면, 악의적 사용자가 브라우저 개발자 도구로 이 값을 조작할 수 있지 않나요?
2. amount 파라미터의 용도
- MCP 가이드에서 "돌아온 금액과 같은지 확인"하라고 하는데, 클라이언트에서 조작 가능한 값으로 검증하는 것이 의미가 있나요?
- 실제로는 서버에 저장한 신뢰할 수 있는 금액으로만 승인해야 하는 것 아닌가요?
3. 설계 의도
- 조작 가능한 클라이언트 값을 쿼리 파라미터로 되돌려주는 이유가 궁금합니다
- 디버깅, 로깅, 또는 다른 특별한 목적이 있는 건가요?
현재 구현 방식
저희는 현재 successUrl의 amount는 검증에 사용하지 않고, 서버에 미리 저장한 실제 상품 금액으로만 승인 API를 호출하고 있습니다. 이것이 올바른 방식인지 확인해주세요.
감사합니다.
5 Replies
⏳ 잠시만 기다려주세요! 곧 답변드리겠습니다
오류 문의일 경우 아래 정보를 미리 전달해주시면, 빠른 답변에 도움이 됩니다.
- 주문번호(orderId) :
- 문의 내용 :
(img를 함께 첨부해주시면 도움이됩니다)
* 계약관련 내용은 1544-7772로 문의주세요.
* 주말/공휴일에는 답변이 늦을 수 있어요.
안녕하세요.
이해하신 내용에 일부 상충하는 내용이 있어, 해당 값에 대해서 의문이 생기신 것 같은데요.
결제 흐름
1. 서버에서 orderId와 실 상품 금액을 저장하거나, 추후 validation이 가능하도록 조치합니다.
2. 클라이언트에서 widget을 렌더하고, widgets.setAmount()로 금액을 설정합니다. (UI 표시용)
3. 결제 인증 완료 후 successUrl에 amount 쿼리 파라미터가 포함되어 리다이렉트 됩니다.
4. 리다이렉트된 amount 값으로 승인 API 호출을 해야합니다. (토스페이먼츠 측 validation에 실패)
amount 값이 반환되는 이유와 출처
- amount 값은 widgets.setAmount() 의 값이 반환되는게 맞으며, 개발자 도구로 조작할 수 있습니다.
- 이에, 해당 값을 돌려드림으로써 서버에서 계산한 실 상품 금액과 일치한지 확인 후, 일치하지 않으면 결제를 하지 않음으로써 악성 유저의 비정상 거래를 차단하도록 가이드하고 있습니다.
- 클라이언트에서 조작이 가능한 값으로 검증하는게 의미가 있나요? 라는 질문에 대해서는 이해하지 못했습니다. 서버에서 저장된 값과 비교하는 것이 '검증'을 의미하는 것인데, 해당 부분에 있어서 서버에서 저장된 값이 조작 되지 않는 한, 금액 값의 무결성이 깨질 수 있다 (의미가 없어진다) 라고 말하기는 어렵다고 판단됩니다. 혹시나 다른 반례가 있다면 말씀 부탁 드리겠습니다.
서버에 미리 저장한 실제 상품 금액으로 승인하는 행위의 정합성
- 해당 경우 INVALID_REQUEST 가 내려가는 것으로 알고 있습니다.
- 서버에 미리 저장한 실제 상품 금액은 validation 용도로 사용하셔서, 일치하지 않으면 결제를 하지않는 방향으로 개발 부탁드립니다.
안녕하세요. 빠른 답변 감사드립니다.
현재 제가 구현한 방식은
1. 결제 요청 전 단계에서 조작 불가능한 서버의 정확한 값으로 미리 amount를 저장합니다
2. 승인 시 '결제 요청 전 단계'에 미리 정확한 값으로 저장한 amount를 서버에서 불러옵니다.
3. 때문에 서버의 신뢰할 수 있는 값으로 승인 API를 호출합니다.
토스페이먼츠의 가이드를 따르면 1단계에서 서버에 정확한 amount가 저장되어 있습니다.
그렇다면, orderId로 저장된 데이터를 조회하면 신뢰할 수 있는 amount를 얻을 수 있을 것이고, successUrl의 쿼리 파라미터에 담겨있는 amount는 필요하지 않을 것입니다.
이때 정확히 궁금한 부분은 그렇다면 왜 굳이 successUrl에 amount를 쿼리 파라미터로 반환하는지 입니다.
보안 상의 문제를 질문드리는 것보다는 API 설계의 직관성에 대한 의문입니다.
주말 늦은 시간까지 답장주셔서 감사합니다!
2번 단계전에서 저희가 보낸 amount 와 서버에 있는 amount 를 확인하신후 고객에게 에러를 띄우거나 하시도록 한겁니다. 그냥 보내시면 2번 승인 요청하면 에러 날거구요.
❤️ 기술문의 경험이 어떠셨나요?!
간단히 코멘트 남겨주세요! 제품 발전에 큰 힘이 됩니다.