# 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 스타일 규칙 정의] |