# EBP SDK 사용 가이드 (ebp-sdk.js) > **SDK 현재 버전:** `v0.1.0` EBP SDK는 프론트엔드(Client Side)에서 간편하고 안전하게 결제를 연동할 수 있도록 다양한 결제창 제공 및 암호화 기능을 제공하는 Javascript SDK입니다.
실제 연동 전 SDK의 동작을 미리 확인해 볼 수 있는 [SDK Testbed](/sdk/testbed)를 제공하고 있습니다. --- ## 1. SDK 로드 (SDK Loading) EBP SDK는 브라우저 캐시로 인한 오동작을 예방하기 위해 별도의 수동 캐시 방지 코드를 작성할 필요 없이, **EBP SDK 로더 스크립트(`ebp-sdk-loader.js`)**를 결제 페이지의 `` 태그 내에 포함하여 간편하게 로드하는 것을 권장합니다. 연동 환경별 서버 도메인 정보는 [Getting Started > 환경별 서버 정보](/docs/overview/getting-started#1.2.1)에서 확인하실 수 있습니다. ### SDK 로더 특징 및 로드 방법 EBP SDK 로더는 중복 로드 방지, 자체 경로에 기반한 코어 SDK 비동기 로딩, 그리고 캐시 오동작을 방지하는 동적 타임스탬프(`t`) 파라미터 삽입 기능을 자체 내장하고 있습니다. EBP SDK가 비동기적으로 로딩 완료된 후 자동으로 설정을 적용하고 기동할 수 있도록, 로더 스크립트 로드 전에 **`window.EbpSdkConfig`** 전역 객체에 필요한 필수/선택 속성들을 선언해야 합니다. ```html ``` --- ### 1.1. EBP SDK 보안 단시간 유효 토큰 획득 및 EbpConfig 설정 (Short-lived Token Acquisition) EBP SDK는 브라우저(EBP SDK) 환경에서 시그니처나 Access Key 노출 없이 안전하게 결제 사양 조회 및 결제 요청을 수행하기 위해 **단시간 유효 보안 토큰(Short-lived Secure Token)** 기반의 보안 체계를 적용합니다. Store 프론트엔드는 이 API를 직접 호출해서는 안 되며, 보안 유지 및 서명 노출 방지를 위해 반드시 Store 백엔드를 통해 안전하게 토큰을 중개 발급받은 후 EBP SDK에 전달해야 합니다. EBP SDK를 초기화할 때, 실시간으로 단시간 유효 보안 토큰을 동적으로 조회하여 리턴해 줄 수 있는 비동기 함수(Promise 리턴 콜백 펑션)인 **`getSdkToken`**을 **`window.EbpSdkConfig`** 전역 객체 설정에 반드시 주입해야 합니다. SDK 내부에서는 필요한 시점에 이 펑션을 비동기 기동하여 토큰을 안전하게 획득 및 갱신하며, 요청 헤더 **`X-SDK-Token`**에 실어 통신합니다. - **window.EbpSdkConfig 토큰 획득 콜백 프로퍼티**: - `getSdkToken` (type: `() => Promise`, requirement: `Yes`) - **설명**: Store 프론트엔드가 자체적으로 Store 백엔드의 단시간 유효 토큰 발급 API를 호출하고, 그 결과에서 토큰 값을 자유롭게 추출하여 리턴하는 비동기 함수입니다. --- ## 2. SDK 초기화 및 결제창 호출 상점 백엔드를 통해 [결제 의사 생성 API](/docs/api-endpoints/purchase/payment-intents) 의 응답 객체(`response`)와 가맹점 설정 객체(`config`)를 인자로 전달하여 `window.EbpSdk.processPayment(response, config)`를 호출함으로써 결제 단계를 초기화하고 결제창을 호출합니다. > [!NOTE] > **PG 동적 연동 및 필수 설정 유의사항** > 백엔드를 통해 Payment Intents API를 호출하고 그 응답을 전달할 때, 호출한 결제 수단 및 호출자 정보(국가, 통화 등)에 따라 해당 결제를 진행할 PG(Payment Gateway)가 자동으로 결정됩니다. > 이에 따라 응답 결과의 `response.data.pgResult.pgProvider` 값에 맞춰 `processPayment`에 전달해야 할 `config` 내의 PG 전용 필수 옵션이 달라질 수 있습니다. (예: `pgProvider`가 `WORLDPAY_AWP`인 경우, 하단에 설명된 `worldpayAwp` 설정이 필수로 제공되어야 합니다.) > > 결제 수단별로 지원되는 PG 정보 및 상세 연동 사양은 [결제 사양 조회 API](/docs/api-endpoints/billing/capacity)를 통해 사전에 확인할 수 있습니다. ```javascript // payment-intents API 호출을 통해 응답(response)을 받았다고 가정합니다. const response = { // ... payment-intents 응답 데이터 }; // SDK 설정 객체 const config = { // SDK 보안 토큰 획득 비동기 콜백 펑션 설정 (필수) getSdkToken: async () => { // Store 프론트엔드가 자체적으로 Store 백엔드 API를 호출하여 토큰을 획득 및 반환합니다. const response = await fetch("/api/v2/sdk/token", { method: "POST" }); const json = await response.json(); return json.data?.token; // 최종 단시간 유효 보안 토큰 문자열만 리턴 }, // PG사별 전용 설정 (동적 결정된 pgProvider에 따라 해당하는 설정을 추가) worldpayAwp: { // ... (Worldpay AWP 결제 시 하단의 '3. Worldpay AWP 연동 설정' 참조) }, worldpay: { // Worldpay HPP(Redirect/Embedded) 결제 전용 설정 uiMode: "embedded", // 'embedded' | 'popup' containerId: "worldpayContainerDiv", // 'embedded' 모드일 때 필수 onReady: function(data) { console.log('Worldpay Ready', data); }, onError: function(err) { console.error('Worldpay Error', err); } }, checkoutCom: { // Checkout.com 결제 전용 설정 uiMode: "embedded", // 'embedded' | 'popup' containerId: "checkoutcomContainerDiv", // 'embedded' 모드일 때 필수 environment: "sandbox", // 'sandbox' | 'production' onReady: function(data) { console.log('Checkout.com Ready', data); } }, omise: { // Omise 결제 전용 설정 uiMode: "modal", // 'modal' | 'popup' itemName: "LGE TV" }, // (선택 사항) 커스텀 스피너 콜백 spinner: { open: function() { console.log('Spinner Open'); }, close: function() { console.log('Spinner Close'); } }, // 결제 성공 콜백 (공통 필수) onSuccess: function(result) { alert('결제가 완료되었습니다.'); console.log('Result:', result); }, // 결제 실패 콜백 (공통 필수) onFailure: function(error) { alert('결제 처리 중 오류가 발생했습니다.'); console.error('Error:', error); } }; // SDK 초기화 및 결제 준비 window.EbpSdk.processPayment(response, config); ``` ### Config 설정 항목 (Configuration Options) | depth | Field | Details & Description | |:------| :----------- | :-------------------- | | 0 | getSdkToken | [type:function] [req:Yes] [desc:EBP SDK가 필요할 때 비동기로 단시간 유효 보안 토큰을 동적으로 조회하는 콜백 함수 (Promise을 리턴해야 함)] | | 0 | worldpayAwp | [type:object] [req:Conditional] [desc:Worldpay AWP 결제 적용 시 사용되는 PG 전용 조건부 필수 설정 객체 (상세 내역은 3번 섹션 참고)] | | 1 | elements | [type:object] [req:Yes] [desc:EBP SDK가 HTML UI 요소를 제어하고 조회할 때 참조하는 셀렉터 설정 객체] | | 2 | submit | [type:string] [req:Yes] [desc:최종 결제 처리를 유발하는 결제 버튼의 CSS Selector (예: `"#pay-btn"`)] | | 2 | cardHolder | [type:string] [req:Yes] [desc:카드 소유자 영문 이름을 입력받는 HTML input 엘리먼트의 CSS Selector (예: `"#card-holder"`)] | | 1 | config | [type:object] [req:Yes] [desc:Worldpay Access Checkout SDK 초기화 시 바이패스되어 전달되는 Hosted Fields 설정 객체] | | 2 | form | [type:string] [req:Yes] [desc:Hosted Fields가 삽입될 카드 입력 폼 요소의 CSS Selector (예: `"#payment-form"`)] | | 2 | fields | [type:object] [req:Yes] [desc:Hosted Fields를 마운트할 개별 입력 필드의 CSS Selector 모음] | | 3 | pan | [type:string\|object] [req:Yes] [desc:카드 번호(PAN) 입력 컨테이너의 CSS Selector 또는 설정 객체] | | 3 | expiry | [type:string\|object] [req:Yes] [desc:만료일(Expiry) 입력 컨테이너의 CSS Selector 또는 설정 객체] | | 3 | cvv | [type:string\|object] [req:Yes] [desc:보안코드(CVV) 입력 컨테이너의 CSS Selector 또는 설정 객체] | | 2 | styles | [type:object] [req:Optional] [desc:Hosted Fields input 내에 적용할 CSS 스타일 규칙 정의] | | 0 | worldpay | [type:object] [req:Conditional] [desc:Worldpay HPP(Redirect/Embedded) 결제 적용 시 사용되는 조건부 필수 설정 객체] | | 1 | uiMode | [type:string] [req:Optional] [desc:결제 UI 방식 (`"embedded"`: 화면 특정 영역에 Iframe 마운트, `"popup"`: 새 창 팝업. 기본값: `"popup"`)] | | 1 | containerId | [type:string] [req:Optional] [desc:embedded 방식일 때 Worldpay Iframe이 마운트될 DOM 요소의 ID] | | 1 | onReady | [type:function] [req:Optional] [desc:HPP 결제창 마운트 완료 및 준비 완료 시 콜백] | | 1 | onError | [type:function] [req:Optional] [desc:결제 실패 또는 오류 발생 시 호출되는 콜백] | | 0 | checkoutCom | [type:object] [req:Conditional] [desc:Checkout.com 결제 적용 시 사용되는 조건부 필수 설정 객체] | | 1 | uiMode | [type:string] [req:Optional] [desc:결제 UI 방식 (`"embedded"`: 화면에 카드 폼 직접 마운트, `"popup"`: 새 창 팝업. 기본값: `"popup"`)] | | 1 | containerId | [type:string] [req:Optional] [desc:embedded 방식일 때 카드 입력 콤포넌트가 마운트될 DOM 요소의 ID] | | 1 | environment | [type:string] [req:Optional] [desc:PG사 샌드박스 또는 실운영 환경 (`"sandbox"` \| `"production"`. 기본값: `"sandbox"`)] | | 0 | omise | [type:object] [req:Conditional] [desc:Omise 결제 적용 시 사용되는 조건부 필수 설정 객체] | | 1 | uiMode | [type:string] [req:Optional] [desc:결제 UI 방식 (`"modal"`: Omise hosted form 모달 노출, `"popup"`: 새 창 팝업. 기본값: `"popup"`)] | | 1 | itemName | [type:string] [req:Optional] [desc:Omise Checkout hosted form 모달 상단에 노출될 상품 정보] | | 0 | spinner | [type:object] [req:Optional] [desc:결제 진행 중 표시되는 로딩 화면(Spinner)을 커스텀하기 위한 객체] | | 1 | open | [type:function] [req:Optional] [desc:SDK 내부에서 API 통신이나 연동 프로세스가 시작되어 로딩바를 노출해야 할 때 실행할 콜백 함수] | | 1 | close | [type:function] [req:Optional] [desc:로딩바를 숨겨야 할 때 실행할 콜백 함수] | | 0 | onSuccess | [type:function] [req:Yes] [desc:결제가 최종 성공했을 때 실행될 콜백 함수. 인자로 결과 데이터를 전달받습니다.] | | 0 | onFailure | [type:function] [req:Yes] [desc:결제가 실패했을 때 실행될 콜백 함수. 인자로 에러 객체를 전달받습니다.] | --- ## 3. Worldpay AWP 연동 설정 (Worldpay AWP Configuration) Worldpay AWP(Access Worldpay) 결제 연동 시에는 `worldpayAwp` 설정 속성을 필수로 전달해야 합니다. 이 설정은 Worldpay Checkout SDK 초기화에 쓰이는 `config` 영역과 EBP SDK 내부 UI 바인딩 및 조회를 위한 `elements` 영역으로 격리되어 있습니다. 특히 **`elements.submit`**과 **`elements.cardHolder`**는 결제 처리를 구동하기 위한 **필수값(Required)**으로 반드시 제공되어야 합니다. ### 설정 예시 (Example) ```javascript // payment-intents API 호출을 통해 응답(response)을 받았다고 가정합니다. const response = { // ... payment-intents 응답 데이터 (pgProvider가 'WORLDPAY_AWP'인 경우) }; // SDK 설정 객체 const config = { worldpayAwp: { // EBP SDK 내부 UI 제어용 엘리먼트 설정 (필수) elements: { // 결제 요청을 수행할 최종 결제 버튼의 CSS Selector submit: "#pay-btn", // 카드 소유주 이름(Card Holder Name) 입력 필드의 CSS Selector cardHolder: "#card-holder" }, // Worldpay Access Checkout SDK에 직접 전달되는 입력 폼 및 필드 설정 (필수) config: { // 카드 입력 폼 요소의 CSS Selector form: "#payment-form", fields: { // 카드 번호(PAN) 입력 컨테이너의 CSS Selector pan: "#card-number", // 카드 만료일(MM/YY) 입력 컨테이너의 CSS Selector expiry: "#card-expiry", // 카드 보안코드(CVV) 입력 컨테이너의 CSS Selector cvv: "#card-cvv" }, // Worldpay Hosted Fields용 인라인 스타일 (선택) styles: { 'input': { 'font-size': '16px', 'color': '#333333' } } } }, // 결제 진행 중 표시되는 스피너 콜백 (선택) spinner: { open: function() { console.log('Spinner Open'); }, close: function() { console.log('Spinner Close'); } }, // 결제 성공 콜백 onSuccess: function(result) { alert('결제가 완료되었습니다.'); console.log('Result:', result); }, // 결제 실패 콜백 onFailure: function(error) { alert('결제 처리 중 오류가 발생했습니다.'); console.error('Error:', error); } }; // SDK 초기화 및 결제 준비 window.EbpSdk.processPayment(response, config); ``` ### Worldpay AWP 설정 항목 상세 (`worldpayAwp`) | depth | Field | Details & Description | |:------| :--------- | :-------------------- | | -1 | worldpayAwp | [type:object] [req:Conditional] [desc:Worldpay AWP 결제 적용 시 사용되는 PG 전용 조건부 필수 설정 객체 (상세 내역은 3번 섹션 참고)] | | 0 | elements | [type:object] [req:Yes] [desc:EBP SDK가 HTML UI 요소를 제어하고 조회할 때 참조하는 셀렉터 설정 객체] | | 1 | submit | [type:string] [req:Yes] [desc:최종 결제 처리를 유발하는 결제 버튼의 CSS Selector (예: `"#pay-btn"`)] | | 1 | cardHolder | [type:string] [req:Yes] [desc:카드 소유자 영문 이름을 입력받는 HTML input 엘리먼트의 CSS Selector (예: `"#card-holder"`)] | | 0 | config | [type:object] [req:Yes] [desc:Worldpay Access Checkout SDK 초기화 시 바이패스되어 전달되는 Hosted Fields 설정 객체] | | 1 | form | [type:string] [req:Yes] [desc:Hosted Fields가 삽입될 카드 입력 폼 요소의 CSS Selector (예: `"#payment-form"`)] | | 1 | fields | [type:object] [req:Yes] [desc:Hosted Fields를 마운트할 개별 입력 필드의 CSS Selector 모음] | | 2 | pan | [type:string\|object] [req:Yes] [desc:카드 번호(PAN) 입력 컨테이너의 CSS Selector 또는 설정 객체] | | 2 | expiry | [type:string\|object] [req:Yes] [desc:만료일(Expiry) 입력 컨테이너의 CSS Selector 또는 설정 객체] | | 2 | cvv | [type:string\|object] [req:Yes] [desc:보안코드(CVV) 입력 컨테이너의 CSS Selector 또는 설정 객체] | | 1 | styles | [type:object] [req:Optional] [desc:Hosted Fields input 내에 적용할 CSS 스타일 규칙 정의] |