@youidian/pay-sdk 1.0.0

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,80 @@
1
+ /**
2
+ * Youidian Payment SDK - Client Module
3
+ * 用于浏览器端集成,包含支付弹窗、状态轮询等功能
4
+ * 不依赖 Node.js crypto 模块
5
+ */
6
+ /**
7
+ * Payment event types from checkout pages
8
+ */
9
+ type PaymentEventType = 'PAYMENT_SUCCESS' | 'PAYMENT_CANCELLED' | 'PAYMENT_CLOSE' | 'PAYMENT_RESIZE';
10
+ /**
11
+ * Payment event data from postMessage
12
+ */
13
+ interface PaymentEventData {
14
+ type: PaymentEventType;
15
+ orderId?: string;
16
+ height?: number;
17
+ }
18
+ /**
19
+ * Order status response
20
+ */
21
+ interface OrderStatus {
22
+ orderId: string;
23
+ status: 'PENDING' | 'PAID' | 'CANCELLED' | 'REFUNDED' | 'FAILED';
24
+ paidAt?: string;
25
+ channelTransactionId?: string;
26
+ }
27
+ /**
28
+ * Payment UI Options
29
+ */
30
+ interface PaymentUIOptions {
31
+ locale?: string;
32
+ onSuccess?: (orderId?: string) => void;
33
+ onCancel?: (orderId?: string) => void;
34
+ onClose?: () => void;
35
+ /** Origin to validate postMessage (defaults to '*', set for security) */
36
+ allowedOrigin?: string;
37
+ }
38
+ /**
39
+ * Poll Options
40
+ */
41
+ interface PollOptions {
42
+ /** Polling interval in ms (default: 3000) */
43
+ interval?: number;
44
+ /** Timeout in ms (default: 300000 = 5 minutes) */
45
+ timeout?: number;
46
+ /** Callback on each status check */
47
+ onStatusChange?: (status: OrderStatus) => void;
48
+ }
49
+ /**
50
+ * Client-side Payment UI Helper
51
+ * 浏览器端支付 UI 辅助类,用于弹出支付窗口和轮询订单状态
52
+ */
53
+ declare class PaymentUI {
54
+ private iframe;
55
+ private modal;
56
+ private messageHandler;
57
+ /**
58
+ * Opens the payment checkout page in an iframe modal.
59
+ * @param checkoutUrl - The checkout page URL
60
+ * @param options - UI options
61
+ */
62
+ openPayment(checkoutUrl: string, options?: PaymentUIOptions): void;
63
+ /**
64
+ * Close the payment modal
65
+ */
66
+ close(): void;
67
+ /**
68
+ * Poll order status from integrator's API endpoint
69
+ * @param statusUrl - The integrator's API endpoint to check order status
70
+ * @param options - Polling options
71
+ * @returns Promise that resolves when order is paid or rejects on timeout/failure
72
+ */
73
+ pollOrderStatus(statusUrl: string, options?: PollOptions): Promise<OrderStatus>;
74
+ }
75
+ /**
76
+ * Convenience function to create a PaymentUI instance
77
+ */
78
+ declare function createPaymentUI(): PaymentUI;
79
+
80
+ export { type OrderStatus, type PaymentEventData, type PaymentEventType, PaymentUI, type PaymentUIOptions, type PollOptions, createPaymentUI };
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Youidian Payment SDK - Client Module
3
+ * 用于浏览器端集成,包含支付弹窗、状态轮询等功能
4
+ * 不依赖 Node.js crypto 模块
5
+ */
6
+ /**
7
+ * Payment event types from checkout pages
8
+ */
9
+ type PaymentEventType = 'PAYMENT_SUCCESS' | 'PAYMENT_CANCELLED' | 'PAYMENT_CLOSE' | 'PAYMENT_RESIZE';
10
+ /**
11
+ * Payment event data from postMessage
12
+ */
13
+ interface PaymentEventData {
14
+ type: PaymentEventType;
15
+ orderId?: string;
16
+ height?: number;
17
+ }
18
+ /**
19
+ * Order status response
20
+ */
21
+ interface OrderStatus {
22
+ orderId: string;
23
+ status: 'PENDING' | 'PAID' | 'CANCELLED' | 'REFUNDED' | 'FAILED';
24
+ paidAt?: string;
25
+ channelTransactionId?: string;
26
+ }
27
+ /**
28
+ * Payment UI Options
29
+ */
30
+ interface PaymentUIOptions {
31
+ locale?: string;
32
+ onSuccess?: (orderId?: string) => void;
33
+ onCancel?: (orderId?: string) => void;
34
+ onClose?: () => void;
35
+ /** Origin to validate postMessage (defaults to '*', set for security) */
36
+ allowedOrigin?: string;
37
+ }
38
+ /**
39
+ * Poll Options
40
+ */
41
+ interface PollOptions {
42
+ /** Polling interval in ms (default: 3000) */
43
+ interval?: number;
44
+ /** Timeout in ms (default: 300000 = 5 minutes) */
45
+ timeout?: number;
46
+ /** Callback on each status check */
47
+ onStatusChange?: (status: OrderStatus) => void;
48
+ }
49
+ /**
50
+ * Client-side Payment UI Helper
51
+ * 浏览器端支付 UI 辅助类,用于弹出支付窗口和轮询订单状态
52
+ */
53
+ declare class PaymentUI {
54
+ private iframe;
55
+ private modal;
56
+ private messageHandler;
57
+ /**
58
+ * Opens the payment checkout page in an iframe modal.
59
+ * @param checkoutUrl - The checkout page URL
60
+ * @param options - UI options
61
+ */
62
+ openPayment(checkoutUrl: string, options?: PaymentUIOptions): void;
63
+ /**
64
+ * Close the payment modal
65
+ */
66
+ close(): void;
67
+ /**
68
+ * Poll order status from integrator's API endpoint
69
+ * @param statusUrl - The integrator's API endpoint to check order status
70
+ * @param options - Polling options
71
+ * @returns Promise that resolves when order is paid or rejects on timeout/failure
72
+ */
73
+ pollOrderStatus(statusUrl: string, options?: PollOptions): Promise<OrderStatus>;
74
+ }
75
+ /**
76
+ * Convenience function to create a PaymentUI instance
77
+ */
78
+ declare function createPaymentUI(): PaymentUI;
79
+
80
+ export { type OrderStatus, type PaymentEventData, type PaymentEventType, PaymentUI, type PaymentUIOptions, type PollOptions, createPaymentUI };
package/dist/client.js ADDED
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
+
22
+ // src/client.ts
23
+ var client_exports = {};
24
+ __export(client_exports, {
25
+ PaymentUI: () => PaymentUI,
26
+ createPaymentUI: () => createPaymentUI
27
+ });
28
+ module.exports = __toCommonJS(client_exports);
29
+ var PaymentUI = class {
30
+ constructor() {
31
+ __publicField(this, "iframe", null);
32
+ __publicField(this, "modal", null);
33
+ __publicField(this, "messageHandler", null);
34
+ }
35
+ /**
36
+ * Opens the payment checkout page in an iframe modal.
37
+ * @param checkoutUrl - The checkout page URL
38
+ * @param options - UI options
39
+ */
40
+ openPayment(checkoutUrl, options) {
41
+ if (typeof document === "undefined") return;
42
+ if (this.modal) return;
43
+ let finalUrl = checkoutUrl;
44
+ if (options?.locale) {
45
+ try {
46
+ const url = new URL(checkoutUrl);
47
+ if (!url.pathname.startsWith(`/${options.locale}/`)) {
48
+ url.pathname = `/${options.locale}${url.pathname}`;
49
+ finalUrl = url.toString();
50
+ }
51
+ } catch (_e) {
52
+ if (!checkoutUrl.startsWith(`/${options.locale}/`)) {
53
+ finalUrl = `/${options.locale}${checkoutUrl.startsWith("/") ? "" : "/"}${checkoutUrl}`;
54
+ }
55
+ }
56
+ }
57
+ this.modal = document.createElement("div");
58
+ Object.assign(this.modal.style, {
59
+ position: "fixed",
60
+ top: "0",
61
+ left: "0",
62
+ width: "100%",
63
+ height: "100%",
64
+ backgroundColor: "rgba(0,0,0,0.5)",
65
+ display: "flex",
66
+ alignItems: "center",
67
+ justifyContent: "center",
68
+ zIndex: "9999",
69
+ transition: "opacity 0.3s ease"
70
+ });
71
+ const container = document.createElement("div");
72
+ Object.assign(container.style, {
73
+ width: "450px",
74
+ height: "min(600px, 90vh)",
75
+ backgroundColor: "#fff",
76
+ borderRadius: "20px",
77
+ overflow: "hidden",
78
+ position: "relative",
79
+ boxShadow: "0 25px 50px -12px rgba(0,0,0,0.25)"
80
+ });
81
+ const closeBtn = document.createElement("button");
82
+ closeBtn.innerHTML = "\xD7";
83
+ Object.assign(closeBtn.style, {
84
+ position: "absolute",
85
+ right: "15px",
86
+ top: "10px",
87
+ fontSize: "24px",
88
+ border: "none",
89
+ background: "none",
90
+ cursor: "pointer",
91
+ color: "#999",
92
+ zIndex: "1"
93
+ });
94
+ closeBtn.onclick = () => {
95
+ this.close();
96
+ options?.onCancel?.();
97
+ };
98
+ this.iframe = document.createElement("iframe");
99
+ this.iframe.src = finalUrl;
100
+ Object.assign(this.iframe.style, {
101
+ width: "100%",
102
+ height: "100%",
103
+ border: "none"
104
+ });
105
+ container.appendChild(closeBtn);
106
+ container.appendChild(this.iframe);
107
+ this.modal.appendChild(container);
108
+ document.body.appendChild(this.modal);
109
+ this.messageHandler = (event) => {
110
+ if (options?.allowedOrigin && options.allowedOrigin !== "*") {
111
+ if (event.origin !== options.allowedOrigin) {
112
+ return;
113
+ }
114
+ }
115
+ const data = event.data;
116
+ if (!data || typeof data !== "object" || !data.type) {
117
+ return;
118
+ }
119
+ switch (data.type) {
120
+ case "PAYMENT_SUCCESS":
121
+ options?.onSuccess?.(data.orderId);
122
+ setTimeout(() => this.close(), 2e3);
123
+ break;
124
+ case "PAYMENT_CANCELLED":
125
+ options?.onCancel?.(data.orderId);
126
+ break;
127
+ case "PAYMENT_RESIZE":
128
+ if (data.height && container) {
129
+ const maxHeight = window.innerHeight * 0.9;
130
+ const newHeight = Math.min(data.height, maxHeight);
131
+ container.style.height = `${newHeight}px`;
132
+ }
133
+ break;
134
+ case "PAYMENT_CLOSE":
135
+ this.close();
136
+ options?.onClose?.();
137
+ break;
138
+ }
139
+ };
140
+ window.addEventListener("message", this.messageHandler);
141
+ }
142
+ /**
143
+ * Close the payment modal
144
+ */
145
+ close() {
146
+ if (typeof window === "undefined") return;
147
+ if (this.messageHandler) {
148
+ window.removeEventListener("message", this.messageHandler);
149
+ this.messageHandler = null;
150
+ }
151
+ if (this.modal && this.modal.parentNode) {
152
+ this.modal.parentNode.removeChild(this.modal);
153
+ }
154
+ this.modal = null;
155
+ this.iframe = null;
156
+ }
157
+ /**
158
+ * Poll order status from integrator's API endpoint
159
+ * @param statusUrl - The integrator's API endpoint to check order status
160
+ * @param options - Polling options
161
+ * @returns Promise that resolves when order is paid or rejects on timeout/failure
162
+ */
163
+ async pollOrderStatus(statusUrl, options) {
164
+ const interval = options?.interval || 3e3;
165
+ const timeout = options?.timeout || 3e5;
166
+ const startTime = Date.now();
167
+ return new Promise((resolve, reject) => {
168
+ const poll = async () => {
169
+ try {
170
+ const response = await fetch(statusUrl);
171
+ if (!response.ok) {
172
+ throw new Error(`Status check failed: ${response.status}`);
173
+ }
174
+ const status = await response.json();
175
+ options?.onStatusChange?.(status);
176
+ if (status.status === "PAID") {
177
+ resolve(status);
178
+ return;
179
+ }
180
+ if (status.status === "CANCELLED" || status.status === "FAILED") {
181
+ reject(new Error(`Order ${status.status.toLowerCase()}`));
182
+ return;
183
+ }
184
+ if (Date.now() - startTime > timeout) {
185
+ reject(new Error("Polling timeout"));
186
+ return;
187
+ }
188
+ setTimeout(poll, interval);
189
+ } catch (error) {
190
+ if (Date.now() - startTime > timeout) {
191
+ reject(error);
192
+ return;
193
+ }
194
+ setTimeout(poll, interval);
195
+ }
196
+ };
197
+ poll();
198
+ });
199
+ }
200
+ };
201
+ function createPaymentUI() {
202
+ return new PaymentUI();
203
+ }
204
+ // Annotate the CommonJS export names for ESM import in node:
205
+ 0 && (module.exports = {
206
+ PaymentUI,
207
+ createPaymentUI
208
+ });
209
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"sourcesContent":["/**\n * Youidian Payment SDK - Client Module\n * 用于浏览器端集成,包含支付弹窗、状态轮询等功能\n * 不依赖 Node.js crypto 模块\n */\n\n/**\n * Payment event types from checkout pages\n */\nexport type PaymentEventType = 'PAYMENT_SUCCESS' | 'PAYMENT_CANCELLED' | 'PAYMENT_CLOSE' | 'PAYMENT_RESIZE';\n\n/**\n * Payment event data from postMessage\n */\nexport interface PaymentEventData {\n type: PaymentEventType;\n orderId?: string;\n height?: number;\n}\n\n/**\n * Order status response\n */\nexport interface OrderStatus {\n orderId: string;\n status: 'PENDING' | 'PAID' | 'CANCELLED' | 'REFUNDED' | 'FAILED';\n paidAt?: string;\n channelTransactionId?: string;\n}\n\n/**\n * Payment UI Options\n */\nexport interface PaymentUIOptions {\n locale?: string;\n onSuccess?: (orderId?: string) => void;\n onCancel?: (orderId?: string) => void;\n onClose?: () => void;\n /** Origin to validate postMessage (defaults to '*', set for security) */\n allowedOrigin?: string;\n}\n\n/**\n * Poll Options\n */\nexport interface PollOptions {\n /** Polling interval in ms (default: 3000) */\n interval?: number;\n /** Timeout in ms (default: 300000 = 5 minutes) */\n timeout?: number;\n /** Callback on each status check */\n onStatusChange?: (status: OrderStatus) => void;\n}\n\n/**\n * Client-side Payment UI Helper\n * 浏览器端支付 UI 辅助类,用于弹出支付窗口和轮询订单状态\n */\nexport class PaymentUI {\n private iframe: HTMLIFrameElement | null = null;\n private modal: HTMLDivElement | null = null;\n private messageHandler: ((event: MessageEvent) => void) | null = null;\n\n /**\n * Opens the payment checkout page in an iframe modal.\n * @param checkoutUrl - The checkout page URL\n * @param options - UI options\n */\n openPayment(checkoutUrl: string, options?: PaymentUIOptions) {\n if (typeof document === 'undefined') return; // Server-side guard\n if (this.modal) return; // Prevent multiple modals\n\n let finalUrl = checkoutUrl;\n if (options?.locale) {\n try {\n const url = new URL(checkoutUrl);\n if (!url.pathname.startsWith(`/${options.locale}/`)) {\n url.pathname = `/${options.locale}${url.pathname}`;\n finalUrl = url.toString();\n }\n } catch (_e) {\n // Fallback if URL is relative or invalid\n if (!checkoutUrl.startsWith(`/${options.locale}/`)) {\n finalUrl = `/${options.locale}${checkoutUrl.startsWith('/') ? '' : '/'}${checkoutUrl}`;\n }\n }\n }\n\n // Create Modal Overlay\n this.modal = document.createElement('div');\n Object.assign(this.modal.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n backgroundColor: 'rgba(0,0,0,0.5)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: '9999',\n transition: 'opacity 0.3s ease'\n });\n\n // Create Container\n const container = document.createElement('div');\n Object.assign(container.style, {\n width: '450px',\n height: 'min(600px, 90vh)',\n backgroundColor: '#fff',\n borderRadius: '20px',\n overflow: 'hidden',\n position: 'relative',\n boxShadow: '0 25px 50px -12px rgba(0,0,0,0.25)'\n });\n\n // Create Close Button\n const closeBtn = document.createElement('button');\n closeBtn.innerHTML = '×';\n Object.assign(closeBtn.style, {\n position: 'absolute',\n right: '15px',\n top: '10px',\n fontSize: '24px',\n border: 'none',\n background: 'none',\n cursor: 'pointer',\n color: '#999',\n zIndex: '1'\n });\n closeBtn.onclick = () => {\n this.close();\n options?.onCancel?.();\n };\n\n // Create Iframe\n this.iframe = document.createElement('iframe');\n this.iframe.src = finalUrl;\n Object.assign(this.iframe.style, {\n width: '100%',\n height: '100%',\n border: 'none'\n });\n\n container.appendChild(closeBtn);\n container.appendChild(this.iframe);\n this.modal.appendChild(container);\n document.body.appendChild(this.modal);\n\n // Listen for messages from checkout page\n this.messageHandler = (event: MessageEvent) => {\n // Validate origin if specified\n if (options?.allowedOrigin && options.allowedOrigin !== '*') {\n if (event.origin !== options.allowedOrigin) {\n return;\n }\n }\n\n const data = event.data as PaymentEventData;\n\n if (!data || typeof data !== 'object' || !data.type) {\n return;\n }\n\n switch (data.type) {\n case 'PAYMENT_SUCCESS':\n options?.onSuccess?.(data.orderId);\n // Auto-close after success callback\n setTimeout(() => this.close(), 2000);\n break;\n case 'PAYMENT_CANCELLED':\n options?.onCancel?.(data.orderId);\n break;\n case 'PAYMENT_RESIZE':\n if (data.height && container) {\n // Limit max height to 90% of viewport\n const maxHeight = window.innerHeight * 0.9;\n const newHeight = Math.min(data.height, maxHeight);\n container.style.height = `${newHeight}px`;\n }\n break;\n case 'PAYMENT_CLOSE':\n this.close();\n options?.onClose?.();\n break;\n }\n };\n window.addEventListener('message', this.messageHandler);\n }\n\n /**\n * Close the payment modal\n */\n close() {\n if (typeof window === 'undefined') return;\n\n if (this.messageHandler) {\n window.removeEventListener('message', this.messageHandler);\n this.messageHandler = null;\n }\n if (this.modal && this.modal.parentNode) {\n this.modal.parentNode.removeChild(this.modal);\n }\n this.modal = null;\n this.iframe = null;\n }\n\n /**\n * Poll order status from integrator's API endpoint\n * @param statusUrl - The integrator's API endpoint to check order status\n * @param options - Polling options\n * @returns Promise that resolves when order is paid or rejects on timeout/failure\n */\n async pollOrderStatus(statusUrl: string, options?: PollOptions): Promise<OrderStatus> {\n const interval = options?.interval || 3000;\n const timeout = options?.timeout || 300000;\n const startTime = Date.now();\n\n return new Promise((resolve, reject) => {\n const poll = async () => {\n try {\n const response = await fetch(statusUrl);\n if (!response.ok) {\n throw new Error(`Status check failed: ${response.status}`);\n }\n\n const status: OrderStatus = await response.json();\n options?.onStatusChange?.(status);\n\n if (status.status === 'PAID') {\n resolve(status);\n return;\n }\n\n if (status.status === 'CANCELLED' || status.status === 'FAILED') {\n reject(new Error(`Order ${status.status.toLowerCase()}`));\n return;\n }\n\n // Check timeout\n if (Date.now() - startTime > timeout) {\n reject(new Error('Polling timeout'));\n return;\n }\n\n // Continue polling\n setTimeout(poll, interval);\n } catch (error) {\n // On network error, continue polling unless timeout\n if (Date.now() - startTime > timeout) {\n reject(error);\n return;\n }\n setTimeout(poll, interval);\n }\n };\n\n poll();\n });\n }\n}\n\n/**\n * Convenience function to create a PaymentUI instance\n */\nexport function createPaymentUI(): PaymentUI {\n return new PaymentUI();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0DO,IAAM,YAAN,MAAgB;AAAA,EAAhB;AACH,wBAAQ,UAAmC;AAC3C,wBAAQ,SAA+B;AACvC,wBAAQ,kBAAyD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjE,YAAY,aAAqB,SAA4B;AACzD,QAAI,OAAO,aAAa,YAAa;AACrC,QAAI,KAAK,MAAO;AAEhB,QAAI,WAAW;AACf,QAAI,SAAS,QAAQ;AACjB,UAAI;AACA,cAAM,MAAM,IAAI,IAAI,WAAW;AAC/B,YAAI,CAAC,IAAI,SAAS,WAAW,IAAI,QAAQ,MAAM,GAAG,GAAG;AACjD,cAAI,WAAW,IAAI,QAAQ,MAAM,GAAG,IAAI,QAAQ;AAChD,qBAAW,IAAI,SAAS;AAAA,QAC5B;AAAA,MACJ,SAAS,IAAI;AAET,YAAI,CAAC,YAAY,WAAW,IAAI,QAAQ,MAAM,GAAG,GAAG;AAChD,qBAAW,IAAI,QAAQ,MAAM,GAAG,YAAY,WAAW,GAAG,IAAI,KAAK,GAAG,GAAG,WAAW;AAAA,QACxF;AAAA,MACJ;AAAA,IACJ;AAGA,SAAK,QAAQ,SAAS,cAAc,KAAK;AACzC,WAAO,OAAO,KAAK,MAAM,OAAO;AAAA,MAC5B,UAAU;AAAA,MACV,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,iBAAiB;AAAA,MACjB,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,YAAY;AAAA,IAChB,CAAC;AAGD,UAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,WAAO,OAAO,UAAU,OAAO;AAAA,MAC3B,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,iBAAiB;AAAA,MACjB,cAAc;AAAA,MACd,UAAU;AAAA,MACV,UAAU;AAAA,MACV,WAAW;AAAA,IACf,CAAC;AAGD,UAAM,WAAW,SAAS,cAAc,QAAQ;AAChD,aAAS,YAAY;AACrB,WAAO,OAAO,SAAS,OAAO;AAAA,MAC1B,UAAU;AAAA,MACV,OAAO;AAAA,MACP,KAAK;AAAA,MACL,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,QAAQ;AAAA,IACZ,CAAC;AACD,aAAS,UAAU,MAAM;AACrB,WAAK,MAAM;AACX,eAAS,WAAW;AAAA,IACxB;AAGA,SAAK,SAAS,SAAS,cAAc,QAAQ;AAC7C,SAAK,OAAO,MAAM;AAClB,WAAO,OAAO,KAAK,OAAO,OAAO;AAAA,MAC7B,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,IACZ,CAAC;AAED,cAAU,YAAY,QAAQ;AAC9B,cAAU,YAAY,KAAK,MAAM;AACjC,SAAK,MAAM,YAAY,SAAS;AAChC,aAAS,KAAK,YAAY,KAAK,KAAK;AAGpC,SAAK,iBAAiB,CAAC,UAAwB;AAE3C,UAAI,SAAS,iBAAiB,QAAQ,kBAAkB,KAAK;AACzD,YAAI,MAAM,WAAW,QAAQ,eAAe;AACxC;AAAA,QACJ;AAAA,MACJ;AAEA,YAAM,OAAO,MAAM;AAEnB,UAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,CAAC,KAAK,MAAM;AACjD;AAAA,MACJ;AAEA,cAAQ,KAAK,MAAM;AAAA,QACf,KAAK;AACD,mBAAS,YAAY,KAAK,OAAO;AAEjC,qBAAW,MAAM,KAAK,MAAM,GAAG,GAAI;AACnC;AAAA,QACJ,KAAK;AACD,mBAAS,WAAW,KAAK,OAAO;AAChC;AAAA,QACJ,KAAK;AACD,cAAI,KAAK,UAAU,WAAW;AAE1B,kBAAM,YAAY,OAAO,cAAc;AACvC,kBAAM,YAAY,KAAK,IAAI,KAAK,QAAQ,SAAS;AACjD,sBAAU,MAAM,SAAS,GAAG,SAAS;AAAA,UACzC;AACA;AAAA,QACJ,KAAK;AACD,eAAK,MAAM;AACX,mBAAS,UAAU;AACnB;AAAA,MACR;AAAA,IACJ;AACA,WAAO,iBAAiB,WAAW,KAAK,cAAc;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AACJ,QAAI,OAAO,WAAW,YAAa;AAEnC,QAAI,KAAK,gBAAgB;AACrB,aAAO,oBAAoB,WAAW,KAAK,cAAc;AACzD,WAAK,iBAAiB;AAAA,IAC1B;AACA,QAAI,KAAK,SAAS,KAAK,MAAM,YAAY;AACrC,WAAK,MAAM,WAAW,YAAY,KAAK,KAAK;AAAA,IAChD;AACA,SAAK,QAAQ;AACb,SAAK,SAAS;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBAAgB,WAAmB,SAA6C;AAClF,UAAM,WAAW,SAAS,YAAY;AACtC,UAAM,UAAU,SAAS,WAAW;AACpC,UAAM,YAAY,KAAK,IAAI;AAE3B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,YAAM,OAAO,YAAY;AACrB,YAAI;AACA,gBAAM,WAAW,MAAM,MAAM,SAAS;AACtC,cAAI,CAAC,SAAS,IAAI;AACd,kBAAM,IAAI,MAAM,wBAAwB,SAAS,MAAM,EAAE;AAAA,UAC7D;AAEA,gBAAM,SAAsB,MAAM,SAAS,KAAK;AAChD,mBAAS,iBAAiB,MAAM;AAEhC,cAAI,OAAO,WAAW,QAAQ;AAC1B,oBAAQ,MAAM;AACd;AAAA,UACJ;AAEA,cAAI,OAAO,WAAW,eAAe,OAAO,WAAW,UAAU;AAC7D,mBAAO,IAAI,MAAM,SAAS,OAAO,OAAO,YAAY,CAAC,EAAE,CAAC;AACxD;AAAA,UACJ;AAGA,cAAI,KAAK,IAAI,IAAI,YAAY,SAAS;AAClC,mBAAO,IAAI,MAAM,iBAAiB,CAAC;AACnC;AAAA,UACJ;AAGA,qBAAW,MAAM,QAAQ;AAAA,QAC7B,SAAS,OAAO;AAEZ,cAAI,KAAK,IAAI,IAAI,YAAY,SAAS;AAClC,mBAAO,KAAK;AACZ;AAAA,UACJ;AACA,qBAAW,MAAM,QAAQ;AAAA,QAC7B;AAAA,MACJ;AAEA,WAAK;AAAA,IACT,CAAC;AAAA,EACL;AACJ;AAKO,SAAS,kBAA6B;AACzC,SAAO,IAAI,UAAU;AACzB;","names":[]}
@@ -0,0 +1,185 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+
5
+ // src/client.ts
6
+ var PaymentUI = class {
7
+ constructor() {
8
+ __publicField(this, "iframe", null);
9
+ __publicField(this, "modal", null);
10
+ __publicField(this, "messageHandler", null);
11
+ }
12
+ /**
13
+ * Opens the payment checkout page in an iframe modal.
14
+ * @param checkoutUrl - The checkout page URL
15
+ * @param options - UI options
16
+ */
17
+ openPayment(checkoutUrl, options) {
18
+ if (typeof document === "undefined") return;
19
+ if (this.modal) return;
20
+ let finalUrl = checkoutUrl;
21
+ if (options?.locale) {
22
+ try {
23
+ const url = new URL(checkoutUrl);
24
+ if (!url.pathname.startsWith(`/${options.locale}/`)) {
25
+ url.pathname = `/${options.locale}${url.pathname}`;
26
+ finalUrl = url.toString();
27
+ }
28
+ } catch (_e) {
29
+ if (!checkoutUrl.startsWith(`/${options.locale}/`)) {
30
+ finalUrl = `/${options.locale}${checkoutUrl.startsWith("/") ? "" : "/"}${checkoutUrl}`;
31
+ }
32
+ }
33
+ }
34
+ this.modal = document.createElement("div");
35
+ Object.assign(this.modal.style, {
36
+ position: "fixed",
37
+ top: "0",
38
+ left: "0",
39
+ width: "100%",
40
+ height: "100%",
41
+ backgroundColor: "rgba(0,0,0,0.5)",
42
+ display: "flex",
43
+ alignItems: "center",
44
+ justifyContent: "center",
45
+ zIndex: "9999",
46
+ transition: "opacity 0.3s ease"
47
+ });
48
+ const container = document.createElement("div");
49
+ Object.assign(container.style, {
50
+ width: "450px",
51
+ height: "min(600px, 90vh)",
52
+ backgroundColor: "#fff",
53
+ borderRadius: "20px",
54
+ overflow: "hidden",
55
+ position: "relative",
56
+ boxShadow: "0 25px 50px -12px rgba(0,0,0,0.25)"
57
+ });
58
+ const closeBtn = document.createElement("button");
59
+ closeBtn.innerHTML = "\xD7";
60
+ Object.assign(closeBtn.style, {
61
+ position: "absolute",
62
+ right: "15px",
63
+ top: "10px",
64
+ fontSize: "24px",
65
+ border: "none",
66
+ background: "none",
67
+ cursor: "pointer",
68
+ color: "#999",
69
+ zIndex: "1"
70
+ });
71
+ closeBtn.onclick = () => {
72
+ this.close();
73
+ options?.onCancel?.();
74
+ };
75
+ this.iframe = document.createElement("iframe");
76
+ this.iframe.src = finalUrl;
77
+ Object.assign(this.iframe.style, {
78
+ width: "100%",
79
+ height: "100%",
80
+ border: "none"
81
+ });
82
+ container.appendChild(closeBtn);
83
+ container.appendChild(this.iframe);
84
+ this.modal.appendChild(container);
85
+ document.body.appendChild(this.modal);
86
+ this.messageHandler = (event) => {
87
+ if (options?.allowedOrigin && options.allowedOrigin !== "*") {
88
+ if (event.origin !== options.allowedOrigin) {
89
+ return;
90
+ }
91
+ }
92
+ const data = event.data;
93
+ if (!data || typeof data !== "object" || !data.type) {
94
+ return;
95
+ }
96
+ switch (data.type) {
97
+ case "PAYMENT_SUCCESS":
98
+ options?.onSuccess?.(data.orderId);
99
+ setTimeout(() => this.close(), 2e3);
100
+ break;
101
+ case "PAYMENT_CANCELLED":
102
+ options?.onCancel?.(data.orderId);
103
+ break;
104
+ case "PAYMENT_RESIZE":
105
+ if (data.height && container) {
106
+ const maxHeight = window.innerHeight * 0.9;
107
+ const newHeight = Math.min(data.height, maxHeight);
108
+ container.style.height = `${newHeight}px`;
109
+ }
110
+ break;
111
+ case "PAYMENT_CLOSE":
112
+ this.close();
113
+ options?.onClose?.();
114
+ break;
115
+ }
116
+ };
117
+ window.addEventListener("message", this.messageHandler);
118
+ }
119
+ /**
120
+ * Close the payment modal
121
+ */
122
+ close() {
123
+ if (typeof window === "undefined") return;
124
+ if (this.messageHandler) {
125
+ window.removeEventListener("message", this.messageHandler);
126
+ this.messageHandler = null;
127
+ }
128
+ if (this.modal && this.modal.parentNode) {
129
+ this.modal.parentNode.removeChild(this.modal);
130
+ }
131
+ this.modal = null;
132
+ this.iframe = null;
133
+ }
134
+ /**
135
+ * Poll order status from integrator's API endpoint
136
+ * @param statusUrl - The integrator's API endpoint to check order status
137
+ * @param options - Polling options
138
+ * @returns Promise that resolves when order is paid or rejects on timeout/failure
139
+ */
140
+ async pollOrderStatus(statusUrl, options) {
141
+ const interval = options?.interval || 3e3;
142
+ const timeout = options?.timeout || 3e5;
143
+ const startTime = Date.now();
144
+ return new Promise((resolve, reject) => {
145
+ const poll = async () => {
146
+ try {
147
+ const response = await fetch(statusUrl);
148
+ if (!response.ok) {
149
+ throw new Error(`Status check failed: ${response.status}`);
150
+ }
151
+ const status = await response.json();
152
+ options?.onStatusChange?.(status);
153
+ if (status.status === "PAID") {
154
+ resolve(status);
155
+ return;
156
+ }
157
+ if (status.status === "CANCELLED" || status.status === "FAILED") {
158
+ reject(new Error(`Order ${status.status.toLowerCase()}`));
159
+ return;
160
+ }
161
+ if (Date.now() - startTime > timeout) {
162
+ reject(new Error("Polling timeout"));
163
+ return;
164
+ }
165
+ setTimeout(poll, interval);
166
+ } catch (error) {
167
+ if (Date.now() - startTime > timeout) {
168
+ reject(error);
169
+ return;
170
+ }
171
+ setTimeout(poll, interval);
172
+ }
173
+ };
174
+ poll();
175
+ });
176
+ }
177
+ };
178
+ function createPaymentUI() {
179
+ return new PaymentUI();
180
+ }
181
+ export {
182
+ PaymentUI,
183
+ createPaymentUI
184
+ };
185
+ //# sourceMappingURL=client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"sourcesContent":["/**\n * Youidian Payment SDK - Client Module\n * 用于浏览器端集成,包含支付弹窗、状态轮询等功能\n * 不依赖 Node.js crypto 模块\n */\n\n/**\n * Payment event types from checkout pages\n */\nexport type PaymentEventType = 'PAYMENT_SUCCESS' | 'PAYMENT_CANCELLED' | 'PAYMENT_CLOSE' | 'PAYMENT_RESIZE';\n\n/**\n * Payment event data from postMessage\n */\nexport interface PaymentEventData {\n type: PaymentEventType;\n orderId?: string;\n height?: number;\n}\n\n/**\n * Order status response\n */\nexport interface OrderStatus {\n orderId: string;\n status: 'PENDING' | 'PAID' | 'CANCELLED' | 'REFUNDED' | 'FAILED';\n paidAt?: string;\n channelTransactionId?: string;\n}\n\n/**\n * Payment UI Options\n */\nexport interface PaymentUIOptions {\n locale?: string;\n onSuccess?: (orderId?: string) => void;\n onCancel?: (orderId?: string) => void;\n onClose?: () => void;\n /** Origin to validate postMessage (defaults to '*', set for security) */\n allowedOrigin?: string;\n}\n\n/**\n * Poll Options\n */\nexport interface PollOptions {\n /** Polling interval in ms (default: 3000) */\n interval?: number;\n /** Timeout in ms (default: 300000 = 5 minutes) */\n timeout?: number;\n /** Callback on each status check */\n onStatusChange?: (status: OrderStatus) => void;\n}\n\n/**\n * Client-side Payment UI Helper\n * 浏览器端支付 UI 辅助类,用于弹出支付窗口和轮询订单状态\n */\nexport class PaymentUI {\n private iframe: HTMLIFrameElement | null = null;\n private modal: HTMLDivElement | null = null;\n private messageHandler: ((event: MessageEvent) => void) | null = null;\n\n /**\n * Opens the payment checkout page in an iframe modal.\n * @param checkoutUrl - The checkout page URL\n * @param options - UI options\n */\n openPayment(checkoutUrl: string, options?: PaymentUIOptions) {\n if (typeof document === 'undefined') return; // Server-side guard\n if (this.modal) return; // Prevent multiple modals\n\n let finalUrl = checkoutUrl;\n if (options?.locale) {\n try {\n const url = new URL(checkoutUrl);\n if (!url.pathname.startsWith(`/${options.locale}/`)) {\n url.pathname = `/${options.locale}${url.pathname}`;\n finalUrl = url.toString();\n }\n } catch (_e) {\n // Fallback if URL is relative or invalid\n if (!checkoutUrl.startsWith(`/${options.locale}/`)) {\n finalUrl = `/${options.locale}${checkoutUrl.startsWith('/') ? '' : '/'}${checkoutUrl}`;\n }\n }\n }\n\n // Create Modal Overlay\n this.modal = document.createElement('div');\n Object.assign(this.modal.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n backgroundColor: 'rgba(0,0,0,0.5)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: '9999',\n transition: 'opacity 0.3s ease'\n });\n\n // Create Container\n const container = document.createElement('div');\n Object.assign(container.style, {\n width: '450px',\n height: 'min(600px, 90vh)',\n backgroundColor: '#fff',\n borderRadius: '20px',\n overflow: 'hidden',\n position: 'relative',\n boxShadow: '0 25px 50px -12px rgba(0,0,0,0.25)'\n });\n\n // Create Close Button\n const closeBtn = document.createElement('button');\n closeBtn.innerHTML = '×';\n Object.assign(closeBtn.style, {\n position: 'absolute',\n right: '15px',\n top: '10px',\n fontSize: '24px',\n border: 'none',\n background: 'none',\n cursor: 'pointer',\n color: '#999',\n zIndex: '1'\n });\n closeBtn.onclick = () => {\n this.close();\n options?.onCancel?.();\n };\n\n // Create Iframe\n this.iframe = document.createElement('iframe');\n this.iframe.src = finalUrl;\n Object.assign(this.iframe.style, {\n width: '100%',\n height: '100%',\n border: 'none'\n });\n\n container.appendChild(closeBtn);\n container.appendChild(this.iframe);\n this.modal.appendChild(container);\n document.body.appendChild(this.modal);\n\n // Listen for messages from checkout page\n this.messageHandler = (event: MessageEvent) => {\n // Validate origin if specified\n if (options?.allowedOrigin && options.allowedOrigin !== '*') {\n if (event.origin !== options.allowedOrigin) {\n return;\n }\n }\n\n const data = event.data as PaymentEventData;\n\n if (!data || typeof data !== 'object' || !data.type) {\n return;\n }\n\n switch (data.type) {\n case 'PAYMENT_SUCCESS':\n options?.onSuccess?.(data.orderId);\n // Auto-close after success callback\n setTimeout(() => this.close(), 2000);\n break;\n case 'PAYMENT_CANCELLED':\n options?.onCancel?.(data.orderId);\n break;\n case 'PAYMENT_RESIZE':\n if (data.height && container) {\n // Limit max height to 90% of viewport\n const maxHeight = window.innerHeight * 0.9;\n const newHeight = Math.min(data.height, maxHeight);\n container.style.height = `${newHeight}px`;\n }\n break;\n case 'PAYMENT_CLOSE':\n this.close();\n options?.onClose?.();\n break;\n }\n };\n window.addEventListener('message', this.messageHandler);\n }\n\n /**\n * Close the payment modal\n */\n close() {\n if (typeof window === 'undefined') return;\n\n if (this.messageHandler) {\n window.removeEventListener('message', this.messageHandler);\n this.messageHandler = null;\n }\n if (this.modal && this.modal.parentNode) {\n this.modal.parentNode.removeChild(this.modal);\n }\n this.modal = null;\n this.iframe = null;\n }\n\n /**\n * Poll order status from integrator's API endpoint\n * @param statusUrl - The integrator's API endpoint to check order status\n * @param options - Polling options\n * @returns Promise that resolves when order is paid or rejects on timeout/failure\n */\n async pollOrderStatus(statusUrl: string, options?: PollOptions): Promise<OrderStatus> {\n const interval = options?.interval || 3000;\n const timeout = options?.timeout || 300000;\n const startTime = Date.now();\n\n return new Promise((resolve, reject) => {\n const poll = async () => {\n try {\n const response = await fetch(statusUrl);\n if (!response.ok) {\n throw new Error(`Status check failed: ${response.status}`);\n }\n\n const status: OrderStatus = await response.json();\n options?.onStatusChange?.(status);\n\n if (status.status === 'PAID') {\n resolve(status);\n return;\n }\n\n if (status.status === 'CANCELLED' || status.status === 'FAILED') {\n reject(new Error(`Order ${status.status.toLowerCase()}`));\n return;\n }\n\n // Check timeout\n if (Date.now() - startTime > timeout) {\n reject(new Error('Polling timeout'));\n return;\n }\n\n // Continue polling\n setTimeout(poll, interval);\n } catch (error) {\n // On network error, continue polling unless timeout\n if (Date.now() - startTime > timeout) {\n reject(error);\n return;\n }\n setTimeout(poll, interval);\n }\n };\n\n poll();\n });\n }\n}\n\n/**\n * Convenience function to create a PaymentUI instance\n */\nexport function createPaymentUI(): PaymentUI {\n return new PaymentUI();\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+ export { OrderStatus as ClientOrderStatus, PaymentEventData, PaymentEventType, PaymentUI, PaymentUIOptions, PollOptions, createPaymentUI } from './client.mjs';
2
+ export { CreateOrderParams, CreateOrderResponse, OrderStatus, PaymentCallbackData, PaymentClient, PaymentClientOptions, PaymentNotification, Product, ProductEntitlements, ProductPrice } from './server.mjs';
@@ -0,0 +1,2 @@
1
+ export { OrderStatus as ClientOrderStatus, PaymentEventData, PaymentEventType, PaymentUI, PaymentUIOptions, PollOptions, createPaymentUI } from './client.js';
2
+ export { CreateOrderParams, CreateOrderResponse, OrderStatus, PaymentCallbackData, PaymentClient, PaymentClientOptions, PaymentNotification, Product, ProductEntitlements, ProductPrice } from './server.js';