플러터 자동 결제 구현 질문드립니다.
안녕하세요.
Flutter 기반으로 간편결제 기능은 구현 완료하여 정상적으로 승인받았고, 현재는 Firebase와 호스팅을 플러터 기반의 웹/앱을 활용하여 서비스를 운영하고 있습니다.
현재 플러터에서 정기 결제(Billing) 파트를 구현 중인데, 깃허브 페이지에 있는 노드 샘플 코드를 참고하여 웹뷰 방식으로 적용하던 중 아래와 같은 문제에 직면해 문의드립니다.
⚠️ 발생한 에러
1. 빌링키 발급 오류 -> 신청한 테스트 코드와 올바르게 연동된 상태입니다.
요청: POST /issue-billing-key
응답 코드: 400 Bad Request
오류 메시지
Message: Invalid or missing authKey
Code: AUTH_KEY_INVALID 2. 정기결제 실행 오류 요청: POST /confirm-billing 응답 코드: 403 Forbidden 오류 메시지 Message: Billing key is not valid or expired
Code: BILLING_KEY_INVALID 정기결제 관련 SDK가 제공되지 않아 웹뷰 방식으로 구현했는데, 현재 어떤 로직이나 파라미터에서 문제가 발생하는지 명확히 파악이 어려운 상황입니다. 혹시 아래 사항에 대해 도움 주실 수 있을까요? 1) 샘플 코드 상에서 필수적으로 확인해야 할 필드나 주의 사항이 있는지 2) 위 에러가 발생하는 주요 원인과 해결 방법 3) 정기 결제 기능 구현 시, 공식적으로 추천되는 플로우나 예제가 있는지 현재 코드를 공유드리고 싶지만, 보는 것이 조금 불편하실 수 있을 것 같아서 먼저 텍스트로 정리하여 문의드렸습니다.
Code: AUTH_KEY_INVALID 2. 정기결제 실행 오류 요청: POST /confirm-billing 응답 코드: 403 Forbidden 오류 메시지 Message: Billing key is not valid or expired
Code: BILLING_KEY_INVALID 정기결제 관련 SDK가 제공되지 않아 웹뷰 방식으로 구현했는데, 현재 어떤 로직이나 파라미터에서 문제가 발생하는지 명확히 파악이 어려운 상황입니다. 혹시 아래 사항에 대해 도움 주실 수 있을까요? 1) 샘플 코드 상에서 필수적으로 확인해야 할 필드나 주의 사항이 있는지 2) 위 에러가 발생하는 주요 원인과 해결 방법 3) 정기 결제 기능 구현 시, 공식적으로 추천되는 플로우나 예제가 있는지 현재 코드를 공유드리고 싶지만, 보는 것이 조금 불편하실 수 있을 것 같아서 먼저 텍스트로 정리하여 문의드렸습니다.

19 Replies
⏳ 잠시만 기다려주세요! 곧 답변드리겠습니다
오류 문의일 경우 아래 정보를 미리 전달해주시면, 빠른 답변에 도움이 됩니다.
- 주문번호(orderId) :
- 문의 내용 :
(img를 함께 첨부해주시면 도움이됩니다)
* 계약관련 내용은 1544-7772로 문의주세요.
* 주말/공휴일에는 답변이 늦을 수 있어요.
요청: POST /issue-billing-key 이건 저희쪽 endpoint가 아닌것같은데요
저희쪽 endpoint와 요청시 사용한 값들을 남겨주시면 로그확인해볼게요
혹시, 정기 결제도 간편 결제와 엔드 포인트가 동일한 것일까요?
엔드포인트 연동 부분을 제대로 하지 않은 것 같아서 여쭤봅니다 🥲
다릅니다.
어떤 깃헙을 보셨는지 모르겠는데요 지금 사용하는 endpoint 가 저희가 제공하는게 아닙니다.
❤️ 기술문의 경험이 어떠셨나요?!
간단히 코멘트 남겨주세요! 제품 발전에 큰 힘이 됩니다.
API 사용하시나요?
아니면 jsSDK 쓰시나요?
자동결제(빌링) 이해하기 | 토스페이먼츠 개발자센터
자동결제는 정기 배송, 음악 스트리밍과 같은 구독형 서비스에서 사용할 수 있어요. 자동결제(빌링)의 개념과 과정을 설명합니다.
[현재 상황]: 안녕하세요, 개발자님들.
간편 결제는 이미 모두 완료되어 잘 동작하는데 정기 결제 파트를 며칠 째 구현하지 못하고 있어서 문제에 대해 조금 정리하여 여쭤봅니다.
Flutter의 WebView에서 JavaScript SDK(v2)를 활용해 정기결제(카드 등록)를 구현 중입니다.
예제로 보내주셨던 토스페이먼츠 공식 문서 링크를 이전부터 확인하고 구현하고 있었습니다. 그리고, GitHub의 ://billing/success
- ://billing/fail
콘솔 로그를 통해 위 값들이 디바이스에서는 정상적으로 들어간 것을 확인하였으나 뭔가 제대로 잘못 연동하고 있는 것으로 보입니다. WebView 안에서 해당 스크립트가 실행되는 것까지는 로그로 확인되고 있습니다.
그러나 카드 등록 페이지로의 통신이 이루어지지 않고 있으며, 토스페이먼츠 관리자 콘솔(API 로그)에도 호출 이력이 전혀 남지 않는 것을 보니 엔드 포인트 설정이나, 특정하게 놓치고 있는 부분이 있다 판단되어 다음과 같은 점을 여쭤보고 싶습니다.
1. 위와 같은 구성(WebView + JS SDK)에서도 정기결제 카드 등록이 정상적으로 동작하는 것이 맞는지?
2. 카드 등록 요청이 실제 토스 서버에 도달하면 API 로그에 기록에 남는 것으로 아는데 정기 결제의 엔드 포인트를 어떻게 작업해야 하는 것인지?(파이어베이스와 node로 작업하고 있습니다)
3. WebView 환경에서는 추가로 설정해야 하는 보안/도메인 조건이나 헤더가 있는지?
4. 샘플에서 사용하는 billing.html과 Flutter WebView 환경의 차이로 인해 예상되는 제한사항이 있을지?
위 상황에서 확인이 필요한 사항이나 추천해주실 디버깅 방법이 있다면 안내 부탁드리겠습니다.
[로그 정리]
I/flutter (15222): [빌링 웹뷰] 토스페이먼츠 SDK 초기화 - customerKey: BRAINRECHARGE_v2suTOYP7E
I/flutter (15222): [빌링 웹뷰] 페이지 로드 시작: about:blank
I/flutter (15222): [빌링 웹뷰] URL 변경: about:blank
I/chromium(15222): "페이지 로드 완료, 1초 후 자동 인증 요청", source: about:blank (84)
I/chromium(15222): "토스페이먼츠 SDK를 통한 빌링키 인증 요청 시작", source: about:blank (84)
I/chromium(15222): "clientKey: 정상입력"
I/chromium(15222): "customerKey: BRAINRECHARGE_v2suTOYP7E"
I/chromium(15222): "successUrl: 정상출력"
I/chromium(15222): "failUrl: 정상출력"
I/chromium(15222): "토스페이먼츠 SDK 초기화 완료"
I/chromium(15222): "빌링 인증 요청 전송 완료"
I/flutter (15222): [빌링 웹뷰] 탐색 요청: https://payment-gateway-sandbox.tosspayments.com/billing/mobile?clientKey=...&payload=... I/flutter (15222): [빌링 웹뷰] 페이지 로드 시작: https://payment-gateway-sandbox.tosspayments.com/billing/mobile?clientKey=...&payload=...
I/flutter (15222): [빌링 웹뷰] URL 변경: https://payment-gateway-sandbox.tosspayments.com/billing/mobile?clientKey=...&payload=...
I/flutter (15222): [빌링 웹뷰] 페이지 로드 완료: https://payment-gateway-sandbox.tosspayments.com/billing/mobile?clientKey=...&payload=... I/chromium(15222): "[object Object]", source: .../chunks/pages/_app-2c61663f30524949.js (37)
tosspayments-sample
중 express-javascript/public/payment/billing.html
예제를 참고하여 개발하고 있습니다.
현재 사용 중인 방식은 다음과 같습니다
플러터 웹뷰 코드로 HTML 내부에 <script src="https://js.tosspayments.com/v2/standard"></script>
를 포함
- Payments.requestBillingAuth({...})
를 호출
- 전달되는 파라미터:
- clientKey
: [신청한 클라이언트 키]
- customerKey
: BRAINRECHARGE_v2suTOYP7E
- successUrl
: appfailUrl
: appI/flutter (15222): [빌링 웹뷰] URL 변경: about:blank
I/chromium(15222): "페이지 로드 완료, 1초 후 자동 인증 요청", source: about:blank (84)
I/chromium(15222): "토스페이먼츠 SDK를 통한 빌링키 인증 요청 시작", source: about:blank (84)
I/chromium(15222): "clientKey: 정상입력"
I/chromium(15222): "customerKey: BRAINRECHARGE_v2suTOYP7E"
I/chromium(15222): "successUrl: 정상출력"
I/chromium(15222): "failUrl: 정상출력"
I/chromium(15222): "토스페이먼츠 SDK 초기화 완료"
I/chromium(15222): "빌링 인증 요청 전송 완료"
I/flutter (15222): [빌링 웹뷰] 탐색 요청: https://payment-gateway-sandbox.tosspayments.com/billing/mobile?clientKey=...&payload=... I/flutter (15222): [빌링 웹뷰] 페이지 로드 시작: https://payment-gateway-sandbox.tosspayments.com/billing/mobile?clientKey=...&payload=...
I/flutter (15222): [빌링 웹뷰] URL 변경: https://payment-gateway-sandbox.tosspayments.com/billing/mobile?clientKey=...&payload=...
I/flutter (15222): [빌링 웹뷰] 페이지 로드 완료: https://payment-gateway-sandbox.tosspayments.com/billing/mobile?clientKey=...&payload=... I/chromium(15222): "[object Object]", source: .../chunks/pages/_app-2c61663f30524949.js (37)
저희 결제창이 아예 표시 되지 않으시는 건가요?
넵, 결제창이 로딩되기 전 단계에서 멈추고 있습니다



혹시 빌링 계약을 하셨나요?
넵, 계약했습니다 아이디를 공유드려도 되는 부분일까요?
계약 중이신 MID 중에 bill_ 로 시작하는 MID 의 키를 사용하셔야 합니다.
지금은 일반결제용 MID 의 키로 호출하고 계시네요.
앗, 혹시 간편 결제와 정기 결제를 분기처리해서 개발을 진행했는데
간편 결제에 있는 위젯 코드가 먼저 반응하여 정기 결제 결제창이 아닌 간편 결제를 호출하면서 key값이 물리는 경우가 발생될 수 있는 것인지 여쭤볼 수 있을까요?
정기결제는 위젯에서 지원하지 않습니다.
Key 값이 물리는지 여부는 저희가 확인을 할수가 없구요.
웹뷰로 연동해서 작업하는 것인데 질문을 잘못드린 것 같습니다.
다시 확인해보겠습니다.
네 저희쪽으로는 Payments.requestBillingAuth({...}) 이게 호출될때 Payments 가 일반결제용 키로 생성된 상태로 요청이 오는 것으로 보입니다.