@bootpay/client-js 5.4.0 → 5.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ export * from './src/payment'
2
+ import _default from './src/payment'
3
+ export default _default
@@ -0,0 +1,5 @@
1
+ import { h as a } from "./chunks/bootpay-DVdQIYCS.mjs";
2
+ export {
3
+ a as Bootpay,
4
+ a as default
5
+ };
@@ -1,4 +1,4 @@
1
- import { BootpayAnalyticsModel, BootpayAnalyticsUserModel, RequestAuthenticationModel, RequestPaymentModel, RequestPaymentUrlModel, RequestSubscriptionModel } from './types/bootpay-interface';
1
+ import { BootpayAnalyticsModel, BootpayAnalyticsUserModel, OnboardingResultModel, RequestAuthenticationModel, RequestOnboardingModel, RequestPaymentModel, RequestPaymentUrlModel, RequestSubscriptionModel } from './types/bootpay-interface';
2
2
  import { EnvironmentInterface } from './support/environment';
3
3
  import { BootpayRequestPaymentManager } from './lib/bootpay';
4
4
  import { BootpayAnalyticsManager } from './lib/analytics';
@@ -11,6 +11,7 @@ export interface BootpayInterface {
11
11
  requestSubscription(data: RequestSubscriptionModel): Promise<any>;
12
12
  requestAuthentication(data: RequestAuthenticationModel): Promise<any>;
13
13
  requestPaymentUrl(data: RequestPaymentUrlModel): Promise<any>;
14
+ requestOnboarding(data: RequestOnboardingModel): Promise<OnboardingResultModel>;
14
15
  confirm(): Promise<any>;
15
16
  errorHandler(data: any): any;
16
17
  setEnvironmentMode(env: 'development' | 'stage' | 'production', hostname?: string | undefined | null): void;
@@ -0,0 +1,17 @@
1
+ import { BootpayWindowEvent } from '../../vendor/mixins/event';
2
+ import { OnboardingResultModel } from '../../types/bootpay-interface';
3
+
4
+ /**
5
+ * 리셀러 등록 폼(PG 신청 화면) 결과 메시지 — Bootpay.requestOnboarding 전용
6
+ * 신청 화면은 JSON 문자열 { bootpay_event: true, event: 'done' | 'cancel', id, kind, pg_wait_id, status } 를 보낸다.
7
+ * 결과는 리셀러 화면 상태를 바꾸므로 기존 리스너와 달리 origin 을 확인한다 — 신청 화면 origin 에서,
8
+ * 이 SDK 가 연 창(popup · iframe)이 보낸 메시지만 받는다.
9
+ * 토큰 · 결과는 로그나 분석 이벤트로 보내지 않는다.
10
+ * @date: 26-10-27
11
+ */
12
+ export declare class BootpayOnboardingEventManager extends BootpayWindowEvent {
13
+ $messageEventName: string;
14
+ constructor();
15
+ bindOnboarding(allowedOrigin: string, expectedSource: () => Window | null, onDone: (result: OnboardingResultModel) => void, onCancel: () => void): void;
16
+ unbind(): void;
17
+ }
@@ -7,6 +7,6 @@ export declare class BootpayPollingEvent extends Resource {
7
7
  * Comment by GOSOMI
8
8
  * @date: 2021-12-29
9
9
  */
10
- pollingStatus(gatewayUrl: string, receiptId: string, applicationId: string | null, transactionKey: string | null): Promise<import('axios').AxiosResponse<any, any>>;
10
+ pollingStatus(gatewayUrl: string, receiptId: string, applicationId: string | null, transactionKey: string | null): Promise<import('../../vendor/mixins/resource').HttpResponse<any>>;
11
11
  }
12
12
  export declare const BootpayPolling: BootpayPollingEvent;
@@ -53,6 +53,34 @@ export declare const BootpayMessage: {
53
53
  };
54
54
  };
55
55
  };
56
+ popupBlocked: {
57
+ PAYMENT: {
58
+ ko: string;
59
+ en: string;
60
+ };
61
+ CARD_SUBSCRIPTION: {
62
+ ko: string;
63
+ en: string;
64
+ };
65
+ AUTH: {
66
+ ko: string;
67
+ en: string;
68
+ };
69
+ };
70
+ popupBlockedError: {
71
+ PAYMENT: {
72
+ ko: string;
73
+ en: string;
74
+ };
75
+ CARD_SUBSCRIPTION: {
76
+ ko: string;
77
+ en: string;
78
+ };
79
+ AUTH: {
80
+ ko: string;
81
+ en: string;
82
+ };
83
+ };
56
84
  closeMessage: {
57
85
  PAYMENT: {
58
86
  ko: string;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 결제창 iframe 에 넘겨줄 권한 — Chrome Local Network Access(142+)
3
+ * 다른 도메인 iframe 은 allow 가 없으면 로컬 주소(127.0.0.1 등) 호출이 묻지도 않고 거부된다
4
+ * ISP 인증서 결제는 PG 프레임이 https://127.0.0.1:55501 로 구매자 PC 의 ISP 프로그램을 부르므로
5
+ * 결제창이 열리는 iframe 은 이 권한을 PG 프레임까지 넘겨줘야 한다
6
+ * local-network-access 는 처음 나온 이름(신버전 Chrome 에서는 별칭), local-network · loopback-network 는 나눠진 새 이름
7
+ * 지원하지 않는 브라우저는 모르는 이름을 무시한다
8
+ * Comment by GOSOMI
9
+ * @date: 2026-11-06
10
+ */
11
+ export declare const PAYMENT_IFRAME_ALLOW = "local-network-access *; local-network *; loopback-network *";
@@ -0,0 +1,40 @@
1
+ import { TemplateManager } from '../../vendor/mixins/template-manager';
2
+ import { BootpayOnboardingEventManager } from '../event/onboarding';
3
+ import { OnboardingResultModel, RequestOnboardingModel } from '../../types/bootpay-interface';
4
+
5
+ type OnboardingDisplay = 'popup' | 'iframe' | 'redirect';
6
+ /**
7
+ * 리셀러 등록 폼(PG 신청 화면) 창 — Bootpay.requestOnboarding 전용
8
+ * - popup: window.open + 500ms 닫힘 감시(결제창 readyToPopup 과 같은 방식) — 닫히면 cancel
9
+ * - iframe(기본): 결제창 덮개(bootpay-payment-background) + iframe, 본문 스크롤 잠금 — 끝나면 덮개 제거 · 스크롤 복구
10
+ * - redirect: 현재 창 이동. Promise 는 끝나지 않는다(결과는 return_url 쿼리 · 리셀러 웹훅)
11
+ * 신청 화면 주소: {ONBOARDING_URL}/onboarding/s/{token}?display=…&origin={리셀러 페이지 origin}
12
+ * @date: 26-10-27
13
+ */
14
+ export declare class OnboardingTemplateManager extends TemplateManager {
15
+ $template: string;
16
+ $windowId: string;
17
+ $iFrameId: string;
18
+ $onboardingWindowId: string;
19
+ $event: BootpayOnboardingEventManager;
20
+ $popup: Window | null;
21
+ $popupWatcher: ReturnType<typeof setInterval> | undefined;
22
+ $abortPrevious: (() => void) | null;
23
+ constructor();
24
+ template(): string;
25
+ /**
26
+ * 신청 화면 주소 — url 을 주면 부트페이 신청 화면 주소(ONBOARDING_URL)일 때만 쓴다
27
+ */
28
+ onboardingUrl(data: RequestOnboardingModel, display: OnboardingDisplay): string;
29
+ /**
30
+ * 신청 화면을 연다. done 은 resolve, cancel 과 error 는 reject
31
+ */
32
+ open(data: RequestOnboardingModel): Promise<OnboardingResultModel>;
33
+ currentWindow(display: OnboardingDisplay): Window | null;
34
+ /**
35
+ * 창 · 덮개 · 감시 · 리스너를 정리하고 본문 스크롤을 되돌린다
36
+ */
37
+ destroy(): void;
38
+ }
39
+ export declare const OnboardingTemplate: OnboardingTemplateManager;
40
+ export {};
@@ -14,9 +14,11 @@ declare class TemplatePaymentManager extends TemplateManager {
14
14
  $closeButton: string;
15
15
  $popupItemNameId: string;
16
16
  $popupPriceId: string;
17
+ $popupMessageId: string;
17
18
  $env: any;
18
19
  $popup?: any;
19
20
  $popupWatcher?: any;
21
+ $popupBlocked: boolean;
20
22
  $themeColor?: string;
21
23
  mode: string;
22
24
  modeApiUrl: any;
@@ -76,6 +78,26 @@ declare class TemplatePaymentManager extends TemplateManager {
76
78
  * @date: 2021-06-23
77
79
  */
78
80
  readyToPopup(url?: string | undefined): void;
81
+ /**
82
+ * 팝업이 차단됐을 때
83
+ * 처음에는 「계속하기」 안내창을 차단 안내 문구로 다시 띄워 팝업을 허용한 뒤 다시 누를 수 있게 한다
84
+ * 그래도 차단되면 RC_POPUP_BLOCKED 로 끝낸다 — 사용자가 닫은 RC_CLOSE_WINDOW 와 구분해 가맹점이 안내를 달리할 수 있게 한다
85
+ * Comment by GOSOMI
86
+ * @date: 2026-11-06
87
+ */
88
+ private handlePopupBlocked;
89
+ /**
90
+ * 「계속하기」 안내창을 팝업 차단 안내 문구로 바꿔 다시 보여준다
91
+ * Comment by GOSOMI
92
+ * @date: 2026-11-06
93
+ */
94
+ private showPopupBlockedMessage;
95
+ /**
96
+ * 팝업창이 열려 있는지 — 차단되어 null 인 경우도 닫힌 것으로 본다
97
+ * Comment by GOSOMI
98
+ * @date: 2026-11-06
99
+ */
100
+ private isPopupOpened;
79
101
  /**
80
102
  * 팝업창을 닫는다
81
103
  * Comment by GOSOMI
@@ -111,6 +133,19 @@ declare class TemplatePaymentManager extends TemplateManager {
111
133
  * @returns void
112
134
  */
113
135
  showPopupMessage(displayData: PopupDisplayResponseModel): void;
136
+ /**
137
+ * 팝업 안내 창에 결제 요청 extra.theme_color 를 적용한다
138
+ * 값이 없거나 CSS 색상이 아니면 common.sass 의 기본색(--bootpay-primary)을 쓴다
139
+ */
140
+ private applyPopupThemeColor;
141
+ /**
142
+ * CSS 색상 문자열을 [r, g, b] 로 변환한다 — 브라우저가 계산한 값을 읽으므로 hex/rgb/hsl/색상명 모두 지원한다
143
+ */
144
+ private resolveRgb;
145
+ /**
146
+ * WCAG 상대 휘도 — 버튼 글자색(흰색/검정)을 고르는 데 쓴다
147
+ */
148
+ private relativeLuminance;
114
149
  /**
115
150
  * 팝업 버튼 창을 닫는다
116
151
  * Comment by GOSOMI
@@ -0,0 +1,10 @@
1
+ import { default as Bootpay, BootpayInterface } from './bootpay';
2
+
3
+ export { Bootpay };
4
+ export default Bootpay;
5
+ export * from './types/bootpay-interface';
6
+ declare global {
7
+ interface Window {
8
+ Bootpay: BootpayInterface;
9
+ }
10
+ }
@@ -27,6 +27,7 @@ export interface EnvironmentInterface {
27
27
  ANALYTICS_URL: EnvironmentMode;
28
28
  DOOR_URL: EnvironmentMode;
29
29
  WIDGET_URL: EnvironmentMode;
30
+ ONBOARDING_URL: EnvironmentMode;
30
31
  sdkNames: SdkNameInterface;
31
32
  sdkVersion: string;
32
33
  packageVersion: string;
@@ -40,6 +41,7 @@ export interface EnvironmentInterface {
40
41
  toApi(uri: string): string;
41
42
  toDoor(uri: string): string;
42
43
  toWidget(uri: string): string;
44
+ toOnboarding(uri: string): string;
43
45
  isMobile(): boolean;
44
46
  isMobileSafari(): any;
45
47
  toAnalytics(uri: string): string;
@@ -17,6 +17,8 @@ interface RequestPaymentBaseModel {
17
17
  deposit_price?: number
18
18
  platform_type?: number
19
19
  currency?: string // 결제 currency 화폐단위
20
+ currencies?: string[] // 통합결제창에서 결제 가능한 통화 목록 ex) ['krw', 'usd']
21
+ currency_prices?: { [currency: string]: number } // 통화별 결제 금액 ex) { usd: 11.12, cny: 100.23 }, 없으면 price를 환율로 환산
20
22
  uuid?: string // UUID
21
23
  sk?: string // 세션 고유키
22
24
  ti?: number // 재방문까지 걸린 시각
@@ -236,6 +238,7 @@ export interface ExtraModel {
236
238
 
237
239
  theme_color?: string // 부트페이 결제창(카드 등록 등) 강조색 — 버튼 배경 · 입력 focus, CSS 색상값 ( 비우면 기본색 #3182F6, 이니시스는 결제창 SKIN 으로도 쓴다 )
238
240
  theme_text_color?: string // theme_color 배경 위 글자색, CSS 색상값 ( 비우면 기본색 #FFFFFF )
241
+ force_redirect?: boolean
239
242
  }
240
243
 
241
244
  export interface WidgetExtraModel extends Partial<ExtraModel> {
@@ -306,4 +309,31 @@ export interface PopupDisplayResponseModel {
306
309
  export interface CommissionKeyModel {
307
310
  commerce?: string
308
311
  marketer?: string
309
- }
312
+ }
313
+
314
+ /**
315
+ * 리셀러 등록 폼(PG 신청) 열기 요청 — Bootpay.requestOnboarding
316
+ * token: 리셀러 서버가 발급받은 등록 폼 토큰(rst_…)
317
+ * display: 'iframe'(기본, 현재 페이지 위 덮개) | 'popup'(새 창) | 'redirect'(현재 창 이동 — Promise 가 끝나지 않는다)
318
+ * url: 발급 응답의 url 을 그대로 쓸 때만. 부트페이 신청 화면 주소일 때만 받는다
319
+ * @date: 26-10-27
320
+ */
321
+ export interface RequestOnboardingModel {
322
+ token: string
323
+ display?: 'popup' | 'iframe' | 'redirect'
324
+ url?: string
325
+ }
326
+
327
+ /**
328
+ * 리셀러 등록 폼 결과 — done 은 resolve, cancel(창 닫기 · 나중에 할게요)과 error 는 reject
329
+ * @date: 26-10-27
330
+ */
331
+ export interface OnboardingResultModel {
332
+ event: 'done' | 'cancel' | 'error'
333
+ id?: string
334
+ kind?: 'pg_join' | string
335
+ pg_wait_id?: string
336
+ status?: number | null
337
+ error_code?: 'ONBOARDING_TOKEN_REQUIRED' | 'ONBOARDING_URL_INVALID' | 'POPUP_BLOCKED' | string
338
+ message?: string
339
+ }
@@ -1,18 +1,56 @@
1
- import { AxiosInstance } from 'axios';
2
-
3
1
  interface EncryptParamsFormat {
4
2
  payload: string;
5
3
  token: string;
6
4
  }
5
+ export interface HttpResponse<T = any> {
6
+ data: T;
7
+ status: number;
8
+ headers: Headers;
9
+ }
10
+ export interface HttpRequestOptions {
11
+ params?: {
12
+ [key: string]: any;
13
+ };
14
+ }
15
+ /**
16
+ * 요청 실패 — 응답을 받은 경우 response 에 data · status 를 담는다 (axios 오류와 같은 모양)
17
+ */
18
+ export declare class HttpError extends Error {
19
+ code?: string;
20
+ response?: HttpResponse;
21
+ constructor(message: string, code?: string, response?: HttpResponse);
22
+ }
23
+ /**
24
+ * fetch 로 만든 HTTP 클라이언트 — axios(약 20KB)를 대신한다
25
+ * 이전 axios.create({ timeout: 60000 }) 인스턴스와 같게 동작한다
26
+ * - body 는 JSON 으로 보내고, 응답은 JSON 이면 파싱한다 (아니면 문자열 그대로)
27
+ * - 2xx 가 아니면 'Request failed with status code N' 으로 reject 한다
28
+ * Comment by GOSOMI
29
+ * @date: 2026-11-06
30
+ */
31
+ export declare class HttpClient {
32
+ timeout: number;
33
+ constructor(timeout?: number);
34
+ get<T = any>(url: string, options?: HttpRequestOptions): Promise<HttpResponse<T>>;
35
+ post<T = any>(url: string, data?: any, options?: HttpRequestOptions): Promise<HttpResponse<T>>;
36
+ put<T = any>(url: string, data?: any, options?: HttpRequestOptions): Promise<HttpResponse<T>>;
37
+ request<T = any>(method: string, url: string, data?: any, options?: HttpRequestOptions): Promise<HttpResponse<T>>;
38
+ static parseBody(text: string): any;
39
+ /**
40
+ * query string 을 붙인다 — axios 와 같이 null · undefined 는 빼고, 배열은 key[] 로, 객체는 JSON 으로 보낸다
41
+ */
42
+ static buildUrl(url: string, params?: {
43
+ [key: string]: any;
44
+ }): string;
45
+ }
7
46
  export declare class Resource {
8
- $http: AxiosInstance;
47
+ $http: HttpClient;
9
48
  constructor();
10
49
  static encryptParams(data: object | string): EncryptParamsFormat;
11
50
  static toUnderscore(value: string): string;
12
51
  static toCamelcase(value: string): string;
13
52
  static objectKeyToUnderscore(value: any): any;
14
53
  static objectKeyToCamel(value: any): any;
15
- static axiosMultipayConfigure(): void;
16
54
  static isHttpBodyUsedMethod(method: string): boolean;
17
55
  }
18
56
  export {};
package/package.json CHANGED
@@ -1,17 +1,29 @@
1
1
  {
2
2
  "name": "@bootpay/client-js",
3
- "version": "5.4.0",
3
+ "version": "5.5.2",
4
4
  "main": "dist/index.mjs",
5
+ "types": "dist/index.d.ts",
5
6
  "exports": {
6
7
  ".": {
7
- "import": "./dist/index.mjs",
8
- "types": "./dist/index.d.ts"
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.mjs"
10
+ },
11
+ "./payment": {
12
+ "types": "./dist/payment.d.ts",
13
+ "import": "./dist/payment.mjs"
14
+ }
15
+ },
16
+ "typesVersions": {
17
+ "*": {
18
+ "payment": [
19
+ "dist/payment.d.ts"
20
+ ]
9
21
  }
10
22
  },
11
23
  "styles": "dist/index.css",
12
24
  "scripts": {
13
25
  "test": "echo \"Error: no test specified\" && exit 1",
14
- "build": "rm -rf ./dist && vite build",
26
+ "build": "rm -rf ./dist && vite build && vite build --mode umd",
15
27
  "deploy": "NODE_ENV=production ./node_modules/.bin/webpack --output-path=./dist --mode=production && gzip -kf dist/*.min.js && ./webview.sh $npm_package_version"
16
28
  },
17
29
  "dependencies": {
package/vite.config.ts CHANGED
@@ -4,28 +4,52 @@ import dts from 'vite-plugin-dts'
4
4
  import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'
5
5
  import path from 'path'
6
6
 
7
- export default defineConfig({
8
- build: {
9
- minify: 'esbuild',
10
- lib: {
11
- entry: path.resolve(__dirname, 'src/index.ts'),
12
- name: 'Bootpay',
13
- fileName: 'index'
14
- }
15
- },
16
- plugins: [
17
- dts({ copyDtsFiles: true, insertTypesEntry: true }),
18
- cssInjectedByJsPlugin()
19
- ],
20
- base: './',
21
- root: './',
22
- publicDir: '_public',
23
- resolve: {
24
- extensions: ['.css', '.sass', '.scss', '.ts', '.js', '.d.ts'],
25
- alias: {
26
- '~': resolve(__dirname, 'src'),
27
- // 또는 프로젝트 루트를 원한다면
28
- // '~': resolve(__dirname, '.'),
7
+ // npm 패키지 빌드 — `vite build` 와 `vite build --mode umd` 두 번 돌린다 (package.json build 스크립트)
8
+ // - 기본: ES 모듈. 전체(index.mjs)와 결제 전용(payment.mjs) 진입점이 공통 코드를 chunks/ 로 공유한다
9
+ // - umd: index.umd.js. UMD 는 진입점을 여러 개 둘 수 없어 따로 만든다 (기존 파일 경로 유지)
10
+ export default defineConfig(({ mode }) => {
11
+ const umd = mode === 'umd'
12
+ return {
13
+ build: {
14
+ minify: 'esbuild',
15
+ emptyOutDir: !umd,
16
+ // CSS 를 import 한 chunk(공통 chunk)에 주입 코드를 넣는다 — 어느 진입점을 불러도 스타일이 들어가도록
17
+ cssCodeSplit: !umd,
18
+ lib: umd ? {
19
+ entry: path.resolve(__dirname, 'src/index.ts'),
20
+ name: 'Bootpay',
21
+ fileName: 'index',
22
+ formats: ['umd']
23
+ } : {
24
+ entry: {
25
+ index: path.resolve(__dirname, 'src/index.ts'),
26
+ payment: path.resolve(__dirname, 'src/payment.ts')
27
+ },
28
+ formats: ['es'],
29
+ fileName: (_format, entryName) => `${ entryName }.mjs`
30
+ },
31
+ rollupOptions: umd ? {} : {
32
+ output: {
33
+ chunkFileNames: 'chunks/[name]-[hash].mjs'
34
+ }
35
+ }
36
+ },
37
+ plugins: umd ? [
38
+ cssInjectedByJsPlugin()
39
+ ] : [
40
+ dts({ copyDtsFiles: true, insertTypesEntry: true }),
41
+ cssInjectedByJsPlugin({ relativeCSSInjection: true })
42
+ ],
43
+ base: './',
44
+ root: './',
45
+ publicDir: '_public',
46
+ resolve: {
47
+ extensions: ['.css', '.sass', '.scss', '.ts', '.js', '.d.ts'],
48
+ alias: {
49
+ '~': resolve(__dirname, 'src'),
50
+ // 또는 프로젝트 루트를 원한다면
51
+ // '~': resolve(__dirname, '.'),
52
+ }
29
53
  }
30
54
  }
31
55
  })