결제창

보안 헤더(CSP)

결제 버튼을 눌러도 반응이 없다면 대부분 여기예요.

결제 버튼을 눌렀는데 아무 일도 일어나지 않는다면, 사이트의 보안 헤더가 결제창을 막고 있는 거예요. 어디에 무엇을 넣으면 되는지 안내해요.

CSP(Content-Security-Policy, 콘텐츠 보안 정책)는 웹서버가 내보내는 보안 헤더예요. 어떤 외부 화면을 페이지 안에 띄울 수 있는지 제한하는데, 결제창도 여기에 걸려요.

CSP를 설정한 적이 없다면 이 문서는 필요 없어요

CSP는 직접 켜야 동작해요. 설정한 적이 없다면 결제창은 그냥 떠요.

내 문제인지 먼저 확인해요

브라우저 개발자도구(F12) → Console 탭에 아래와 비슷한 줄이 있는지 봐요.

Refused to frame 'https://...' because it violates the following
Content Security Policy directive: "frame-src ..."

이 메시지가 보이면 부트페이 장애도, 연동키(Client Key) 문제도 아니에요. 내 웹서버 설정 문제예요.

무엇을 넣나요

결제창을 막는 지시어는 frame-src 하나예요. (iframe-src 라는 지시어는 없어요.)

frame-src 를 아예 선언하지 않으면 default-src 로 폴백되므로, default-src 'self' 만 있어도 똑같이 막혀요.

frame-src 만 추가하세요

script-src 처럼 원래 없던 지시어를 새로 만들면 없던 제약이 새로 생겨요. 특히 script-src 를 새로 선언하는 순간 목록에 적지 않은 스크립트가 전부 차단돼서, 사이트의 분석 도구·채팅 위젯·광고 태그가 한꺼번에 멈춰요.

해당 지시어를 이미 쓰고 있는 경우에만 아래 「이미 쓰고 있는 지시어만 병합」의 값을 합치세요.

어디에 넣나요

환경 위치
Vercel vercel.jsonheaders
Next.js next.config.jsheaders() 또는 middleware.ts
Nuxt nuxt.config.tsrouteRules
nginx add_header Content-Security-Policy "..." always;
Express helmet.contentSecurityPolicy({ directives })
헤더를 못 만질 때 HTML <head><meta http-equiv="Content-Security-Policy">
여러 곳에 있으면 마지막 것만 적용돼요

Vercel + Next.js 조합에서는 middleware.tsvercel.jsonnext.config.js 를 덮어써요. 한 곳만 고치고 "왜 안 바뀌지" 하는 경우가 많아요.

실제로 나가는 값을 확인해 주세요.

curl -sI https://내도메인 | grep -i content-security-policybash

기존 CSP가 이미 있다면 통째로 덮어쓰지 말고 frame-src 값만 병합​​하세요. 설정 파일의 다른 항목(rewrites 등)도 그대로 두어야 해요.

허용 도메인

사용하는 PG와 결제수단에 따라 필요한 값이 달라요. 어떤 PG를 쓰는지 모르겠다면 전체 목록을 그대로 넣어도 돼요.

전체 허용 값 — 그대로 복사해서 쓰세요
frame-src 'self' https://*.bootpay.co.kr https://*.lightpay.kr https://lightpay.kr https://*.nicepay.co.kr https://*.settlebank.co.kr https://settlebank.co.kr https://*.inicis.com https://*.kcp.co.kr https://*.tosspayments.com https://*.smartropay.co.kr https://*.smartro.co.kr https://*.teledit.com https://teledit.com https://*.danalpay.com https://danalpay.com https://*.danal.co.kr https://danal.co.kr https://*.payletter.com https://*.payapp.kr https://*.easypay.co.kr https://*.welcomepayments.co.kr https://welcomepayments.co.kr https://*.payco.com https://payco.com https://*.kakao.com https://*.kakaopay.com https://kakaopay.com https://*.naver.com https://*.mobilians.co.kr https://*.ksnet.co.kr https://*.kspay.co.kr https://*.jtnet.co.kr https://jtnet.co.kr https://*.paypal.com https://*.stripe.com https://*.stripe.network https://*.kbcard.com https://*.bccard.com https://*.lottecard.co.kr https://*.shinhancard.com https://*.hyundaicard.com https://*.hanacard.co.kr https://*.samsungcard.co.kr https://*.nonghyup.com https://*.wooricard.com https://dacs.wooricard.com:8886 https://*.citibank.co.kr https://*.vpay.co.kr https://vpay.co.kr https://*.daum.net https://*.daumcdn.net https://*.channel.io

항상 필요해요

https://*.bootpay.co.kr
https://*.lightpay.kr
https://lightpay.kr

주소 검색(다음 우편번호)이나 상담 위젯을 함께 쓴다면 아래도 필요해요.

https://*.daum.net
https://*.daumcdn.net
https://*.channel.io

PG사별

PG사별 결제창 도메인 (21개)
PG사 허용 값
라이트페이 https://*.lightpay.kr https://lightpay.kr
⚠️ 결제 모듈이 세틀뱅크·나이스페이먼츠 로 넘어가요 — 그 값도 함께 넣으세요
나이스페이먼츠 https://*.nicepay.co.kr
세틀뱅크 (헥토파이낸셜) https://*.settlebank.co.kr https://settlebank.co.kr
KG이니시스 https://*.inicis.com
NHN KCP https://*.kcp.co.kr
토스페이먼츠 https://*.tosspayments.com
스마트로 https://*.smartropay.co.kr https://*.smartro.co.kr
다날 https://*.teledit.com https://teledit.com https://*.danalpay.com https://danalpay.com https://*.danal.co.kr https://danal.co.kr
페이레터 https://*.payletter.com
페이앱 https://*.payapp.kr
KICC 이지페이 https://*.easypay.co.kr
웰컴페이먼츠 https://*.welcomepayments.co.kr https://welcomepayments.co.kr
※ 결제창 주소 미확정. 막히면 콘솔 도메인을 추가하세요
페이코 https://*.payco.com https://payco.com
카카오페이 https://*.kakao.com https://*.kakaopay.com https://kakaopay.com
네이버페이 https://*.naver.com
KG모빌리언스 https://*.mobilians.co.kr
KSNET https://*.ksnet.co.kr https://*.kspay.co.kr
JTNet https://*.jtnet.co.kr https://jtnet.co.kr
※ 결제창 주소 미확정. 막히면 콘솔 도메인을 추가하세요
티페이 https://*.settlebank.co.kr https://settlebank.co.kr
※ 결제창 주소 미확정. 막히면 콘솔 도메인을 추가하세요
PayPal https://*.paypal.com
Stripe https://*.stripe.com https://*.stripe.network

샌드박스와 운영의 결제창 도메인이 다른 PG가 있어요(예: sandbox-pay.nicepay.co.krpay.nicepay.co.kr). 위처럼 와일드카드로 넣으면 둘 다 덮이니 운영 전환 시 다시 막히지 않아요.

카드 인증(3-D Secure)

PG 결제창 안에서 카드 인증 단계로 넘어가면 카드사 자체 서버​​가 열려요. PG 도메인만 허용하면 "결제창은 떴는데 카드를 고르니 멈춘다" 가 돼요. 카드결제를 받는다면 아래 값이 모두 필요해요.

카드사별 인증 도메인 (11개)
카드사 허용 값
KB국민카드 https://*.kbcard.com
BC카드 https://*.bccard.com
롯데카드 https://*.lottecard.co.kr
신한카드 https://*.shinhancard.com
현대카드 https://*.hyundaicard.com
하나카드 https://*.hanacard.co.kr
삼성카드 https://*.samsungcard.co.kr
NH농협카드 https://*.nonghyup.com
우리카드 https://*.wooricard.com https://dacs.wooricard.com:8886
씨티카드 https://*.citibank.co.kr
VPay (카드사 공동) https://*.vpay.co.kr https://vpay.co.kr

아래 카드사는 실제 인증 서버 여부를 확인하지 못해 목록에서 뺐어요. 해당 카드에서 막히면 콘솔에 찍힌 도메인을 추가하세요 — 신협 · 전북은행 · 광주은행 · 수협

우리카드는 포트(:8886)까지 적어야 해요

CSP는 포트를 생략하면 기본 포트(443)만 허용해요. 우리카드 인증 서버는 8886 포트에서만 응답하므로 https://*.wooricard.com 만으로는 덮이지 않아요.

놓치면 다른 카드는 되는데 우리카드 사용자만 결제가 실패해요.

https://*.wooricard.com https://dacs.wooricard.com:8886

본인인증

본인인증(method: 'auth')을 쓴다면 추가해요.

https://nice.checkplus.co.kr
https://*.mobile-ok.com
https://*.kmcert.com
https://*.vno.co.kr
https://*.teledit.com

이미 쓰고 있는 지시어만 병합

아래 지시어를 원래 선언해 두었다면 결제 도메인을 함께 넣어야 해요. 선언한 적이 없다면 건드리지 마세요.

form-action · connect-src · script-src · img-src

form-action — KG이니시스·NHN KCP 모바일은 폼 전송으로 결제창을 전환해요

form-action 'self' https://*.bootpay.co.kr https://*.lightpay.kr https://lightpay.kr https://*.nicepay.co.kr https://*.settlebank.co.kr https://settlebank.co.kr https://*.inicis.com https://*.kcp.co.kr https://*.tosspayments.com https://*.smartropay.co.kr https://*.smartro.co.kr https://*.teledit.com https://teledit.com https://*.danalpay.com https://danalpay.com https://*.danal.co.kr https://danal.co.kr https://*.payletter.com https://*.payapp.kr https://*.easypay.co.kr https://*.welcomepayments.co.kr https://welcomepayments.co.kr https://*.payco.com https://payco.com https://*.kakao.com https://*.kakaopay.com https://kakaopay.com https://*.naver.com https://*.mobilians.co.kr https://*.ksnet.co.kr https://*.kspay.co.kr https://*.jtnet.co.kr https://jtnet.co.kr https://*.paypal.com https://*.stripe.com https://*.stripe.network https://*.kbcard.com https://*.bccard.com https://*.lottecard.co.kr https://*.shinhancard.com https://*.hyundaicard.com https://*.hanacard.co.kr https://*.samsungcard.co.kr https://*.nonghyup.com https://*.wooricard.com https://dacs.wooricard.com:8886 https://*.citibank.co.kr https://*.vpay.co.kr https://vpay.co.kr

connect-src — 결제 승인·상태 조회 통신

connect-src 'self' https://*.bootpay.co.kr https://*.lightpay.kr https://lightpay.kr https://*.nicepay.co.kr https://*.settlebank.co.kr https://settlebank.co.kr https://*.inicis.com https://*.kcp.co.kr https://*.tosspayments.com https://*.smartropay.co.kr https://*.smartro.co.kr https://*.teledit.com https://teledit.com https://*.danalpay.com https://danalpay.com https://*.danal.co.kr https://danal.co.kr https://*.payletter.com https://*.payapp.kr https://*.easypay.co.kr https://*.welcomepayments.co.kr https://welcomepayments.co.kr https://*.payco.com https://payco.com https://*.kakao.com https://*.kakaopay.com https://kakaopay.com https://*.naver.com https://*.mobilians.co.kr https://*.ksnet.co.kr https://*.kspay.co.kr https://*.jtnet.co.kr https://jtnet.co.kr https://*.paypal.com https://*.stripe.com https://*.stripe.network

script-src — 부트페이 SDK·주소 검색 스크립트

script-src 'self' 'unsafe-inline' https://*.bootpay.co.kr https://*.lightpay.kr https://lightpay.kr https://*.daum.net https://*.daumcdn.net https://*.channel.io

img-src — 카드사 로고·QR (data: blob:)

img-src 'self' data: blob: https://*.bootpay.co.kr https://*.lightpay.kr https://lightpay.kr https://*.nicepay.co.kr https://*.settlebank.co.kr https://settlebank.co.kr https://*.inicis.com https://*.kcp.co.kr https://*.tosspayments.com https://*.smartropay.co.kr https://*.smartro.co.kr https://*.teledit.com https://teledit.com https://*.danalpay.com https://danalpay.com https://*.danal.co.kr https://danal.co.kr https://*.payletter.com https://*.payapp.kr https://*.easypay.co.kr https://*.welcomepayments.co.kr https://welcomepayments.co.kr https://*.payco.com https://payco.com https://*.kakao.com https://*.kakaopay.com https://kakaopay.com https://*.naver.com https://*.mobilians.co.kr https://*.ksnet.co.kr https://*.kspay.co.kr https://*.jtnet.co.kr https://jtnet.co.kr https://*.paypal.com https://*.stripe.com https://*.stripe.network

CSP를 건드릴 수 없다면

보안 정책이나 권한 문제로 헤더를 못 만지는 경우, 결제창을 Redirect 방식​​으로 열면 frame-src 를 아예 거치지 않아요. CSP와 무관하게 결제가 진행돼요.

extra: {
  open_type: 'redirect',
  redirect_url: 'https://내도메인/payment/result',   // 필수
}javascript

부트페이는 원래 Web SDK에서 Redirect를 기본값으로 권장해요. 방식별 결과 수신 차이와 서버 라우트 구성은 창 모드 문서를 참고하세요.

그래도 막힌다면

  1. 콘솔의 Refused to frame 문구에 찍힌 도메인을 그대로 추가해요. 이 목록보다 콘솔이 정확해요 — PG와 카드사는 도메인을 바꿔요.
  2. curl -sI 로 실제 나가는 헤더를 확인해요. 설정이 다른 곳에서 덮이고 있을 수 있어요.
  3. 위를 다 했는데 모바일만 안 된다면 Redirect 방식으로 전환해요.

운영 반영 전에는 Content-Security-Policy-Report-Only 로 먼저 돌려 위반만 수집해 보는 방법도 있어요.