@paynext/sdk 0.0.173 → 1.0.1
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.
- package/dist/index.d.ts +1 -38
- package/dist/index.es.js +44 -384
- package/dist/index.umd.js +1 -150
- package/package.json +1 -1
- package/dist/checkout.html +0 -259
package/dist/index.d.ts
CHANGED
|
@@ -352,37 +352,13 @@ declare enum PaymentStatus {
|
|
|
352
352
|
|
|
353
353
|
export declare class PayNextCheckout {
|
|
354
354
|
private cdnInstance;
|
|
355
|
-
private iframeInstance;
|
|
356
355
|
private initPromise;
|
|
357
|
-
private mode;
|
|
358
356
|
constructor();
|
|
359
357
|
private initialize;
|
|
360
358
|
private waitForReady;
|
|
361
|
-
mount(containerId: string, config: PayNextConfigExtended): Promise<void>;
|
|
362
|
-
unmount(): Promise<void>;
|
|
363
|
-
updateConfig(config: Partial<PayNextConfigExtended>): Promise<void>;
|
|
364
|
-
static preload(envType: 'develop' | 'staging' | 'sandbox' | 'production', options?: {
|
|
365
|
-
iframeMode?: boolean;
|
|
366
|
-
}): Promise<void>;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
export declare class PayNextCheckoutIframe {
|
|
370
|
-
private iframe;
|
|
371
|
-
private container;
|
|
372
|
-
private config;
|
|
373
|
-
private messageHandlers;
|
|
374
|
-
private pendingRequests;
|
|
375
|
-
private isReady;
|
|
376
|
-
private allowedOrigin;
|
|
377
|
-
constructor();
|
|
378
|
-
private generateRequestId;
|
|
379
|
-
private sendMessage;
|
|
380
|
-
private handleMessage;
|
|
381
|
-
private createIframe;
|
|
382
|
-
private waitForReady;
|
|
383
359
|
mount(containerId: string, config: PayNextConfig): Promise<void>;
|
|
384
360
|
unmount(): Promise<void>;
|
|
385
|
-
updateConfig(config:
|
|
361
|
+
updateConfig(config: any): Promise<void>;
|
|
386
362
|
static preload(envType: 'develop' | 'staging' | 'sandbox' | 'production'): Promise<void>;
|
|
387
363
|
}
|
|
388
364
|
|
|
@@ -403,23 +379,10 @@ export declare interface PayNextConfig {
|
|
|
403
379
|
_themeExplicit?: boolean;
|
|
404
380
|
}
|
|
405
381
|
|
|
406
|
-
export declare interface PayNextConfigExtended extends PayNextConfig {
|
|
407
|
-
/**
|
|
408
|
-
* Enable PCI-compliant iframe mode
|
|
409
|
-
* @default false
|
|
410
|
-
* @description When true, checkout will be rendered in isolated iframe for better PCI compliance
|
|
411
|
-
*/
|
|
412
|
-
iframeMode?: boolean;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
382
|
export declare const PayNextSDK: {
|
|
416
383
|
preload: typeof PayNextCheckout.preload;
|
|
417
384
|
};
|
|
418
385
|
|
|
419
|
-
export declare const PayNextSDKIframe: {
|
|
420
|
-
preload: typeof PayNextCheckoutIframe.preload;
|
|
421
|
-
};
|
|
422
|
-
|
|
423
386
|
export declare interface StylesConfig {
|
|
424
387
|
Input?: InputStyles;
|
|
425
388
|
SubmitButton?: ISubmitButtonStyles;
|
package/dist/index.es.js
CHANGED
|
@@ -1,379 +1,45 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
14
|
-
<title>PayNext Checkout</title>
|
|
15
|
-
<style>
|
|
16
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
17
|
-
html, body { width: 100%; height: 100%; overflow: hidden; }
|
|
18
|
-
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
|
19
|
-
#checkout-container { width: 100%; min-height: 100%; }
|
|
20
|
-
.loading { display: flex; align-items: center; justify-content: center; min-height: 400px; color: #666; font-size: 14px; }
|
|
21
|
-
.loading::after { content: '...'; animation: dots 1.5s steps(4, end) infinite; }
|
|
22
|
-
@keyframes dots { 0%, 20% { content: '.'; } 40% { content: '..'; } 60%, 100% { content: '...'; } }
|
|
23
|
-
.error { color: #e53e3e; padding: 20px; text-align: center; }
|
|
24
|
-
</style>
|
|
25
|
-
</head>
|
|
26
|
-
<body>
|
|
27
|
-
<div id="checkout-container"><div class="loading">Loading checkout</div></div>
|
|
28
|
-
<script type="module">
|
|
29
|
-
const MessageType = {
|
|
30
|
-
MOUNT: 'paynext:mount', UNMOUNT: 'paynext:unmount', UPDATE_CONFIG: 'paynext:updateConfig',
|
|
31
|
-
READY: 'paynext:ready', LOADED: 'paynext:loaded', ATTEMPT: 'paynext:attempt',
|
|
32
|
-
COMPLETE: 'paynext:complete', FAIL: 'paynext:fail', ERROR: 'paynext:error', RESIZE: 'paynext:resize'
|
|
33
|
-
}
|
|
34
|
-
let checkout = null, parentOrigin = null, config = null
|
|
35
|
-
|
|
36
|
-
function sendToParent(type, payload, requestId) {
|
|
37
|
-
if (!parentOrigin) return
|
|
38
|
-
window.parent.postMessage({ type, payload, requestId }, parentOrigin)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function showError(message) {
|
|
42
|
-
document.getElementById('checkout-container').innerHTML =
|
|
43
|
-
'<div class="error"><strong>Error:</strong> ' + message + '</div>'
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
window.addEventListener('message', async (event) => {
|
|
47
|
-
const data = event.data
|
|
48
|
-
if (!parentOrigin) parentOrigin = event.origin
|
|
49
|
-
if (event.origin !== parentOrigin || !data.type?.startsWith('paynext:')) return
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
switch (data.type) {
|
|
53
|
-
case MessageType.MOUNT:
|
|
54
|
-
if (data.payload?.config) {
|
|
55
|
-
config = data.payload.config
|
|
56
|
-
|
|
57
|
-
try {
|
|
58
|
-
// Load SDK from CDN
|
|
59
|
-
// CDN version exports to window.PayNextSDK
|
|
60
|
-
if (!window.PayNextSDK) {
|
|
61
|
-
// Load SDK script if not already loaded
|
|
62
|
-
await new Promise((resolve, reject) => {
|
|
63
|
-
const script = document.createElement('script')
|
|
64
|
-
script.src = '${a}'
|
|
65
|
-
script.onload = resolve
|
|
66
|
-
script.onerror = reject
|
|
67
|
-
document.head.appendChild(script)
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const { PayNextCheckout } = window.PayNextSDK || {}
|
|
72
|
-
|
|
73
|
-
if (!PayNextCheckout) {
|
|
74
|
-
throw new Error('PayNextCheckout not found in window.PayNextSDK')
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
checkout = new PayNextCheckout()
|
|
78
|
-
await checkout.mount('checkout-container', {
|
|
79
|
-
...config,
|
|
80
|
-
onCheckoutLoaded: (result) => {
|
|
81
|
-
sendToParent(MessageType.LOADED, result, data.requestId)
|
|
82
|
-
notifyResize()
|
|
83
|
-
},
|
|
84
|
-
onCheckoutAttempt: (result) => sendToParent(MessageType.ATTEMPT, result),
|
|
85
|
-
onCheckoutComplete: (result) => sendToParent(MessageType.COMPLETE, result),
|
|
86
|
-
onCheckoutFail: (error) => sendToParent(MessageType.FAIL, error)
|
|
87
|
-
})
|
|
88
|
-
sendToParent(MessageType.READY, { success: true }, data.requestId)
|
|
89
|
-
setupResizeObserver()
|
|
90
|
-
} catch (importError) {
|
|
91
|
-
console.error('[Iframe] Failed to load SDK:', importError)
|
|
92
|
-
showError('Failed to load PayNext SDK: ' + importError.message)
|
|
93
|
-
sendToParent(MessageType.ERROR, {
|
|
94
|
-
message: 'SDK import failed: ' + importError.message,
|
|
95
|
-
stack: importError.stack
|
|
96
|
-
}, data.requestId)
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
break
|
|
100
|
-
|
|
101
|
-
case MessageType.UNMOUNT:
|
|
102
|
-
if (checkout) {
|
|
103
|
-
await checkout.unmount()
|
|
104
|
-
checkout = null
|
|
105
|
-
}
|
|
106
|
-
sendToParent(MessageType.READY, { success: true }, data.requestId)
|
|
107
|
-
break
|
|
108
|
-
|
|
109
|
-
case MessageType.UPDATE_CONFIG:
|
|
110
|
-
if (checkout && data.payload?.config) {
|
|
111
|
-
await checkout.updateConfig(data.payload.config)
|
|
112
|
-
sendToParent(MessageType.READY, { success: true }, data.requestId)
|
|
113
|
-
}
|
|
114
|
-
break
|
|
115
|
-
}
|
|
116
|
-
} catch (error) {
|
|
117
|
-
console.error('[Iframe] Error:', error)
|
|
118
|
-
sendToParent(MessageType.ERROR, {
|
|
119
|
-
message: error.message,
|
|
120
|
-
stack: error.stack
|
|
121
|
-
}, data.requestId)
|
|
122
|
-
}
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
function setupResizeObserver() {
|
|
126
|
-
new ResizeObserver(entries => {
|
|
127
|
-
for (const entry of entries) {
|
|
128
|
-
sendToParent(MessageType.RESIZE, { height: entry.contentRect.height })
|
|
129
|
-
}
|
|
130
|
-
}).observe(document.body)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function notifyResize() {
|
|
134
|
-
sendToParent(MessageType.RESIZE, { height: document.body.scrollHeight })
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
window.addEventListener('load', () => {
|
|
138
|
-
console.log('[Iframe] Iframe loaded, sending ready message')
|
|
139
|
-
setTimeout(() => {
|
|
140
|
-
window.parent.postMessage(
|
|
141
|
-
{ type: MessageType.READY, payload: { success: true } },
|
|
142
|
-
'*'
|
|
143
|
-
)
|
|
144
|
-
}, 100)
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
window.addEventListener('error', (event) => {
|
|
148
|
-
console.error('[Iframe] Global error:', event.error)
|
|
149
|
-
sendToParent(MessageType.ERROR, {
|
|
150
|
-
message: event.error?.message || 'Unknown error',
|
|
151
|
-
stack: event.error?.stack
|
|
152
|
-
})
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
console.log('[Iframe] PayNext Checkout iframe initialized, SDK URL: ${a}')
|
|
156
|
-
<\/script>
|
|
157
|
-
</body>
|
|
158
|
-
</html>`;
|
|
159
|
-
}
|
|
160
|
-
class f {
|
|
161
|
-
constructor() {
|
|
162
|
-
r(this, "iframe", null);
|
|
163
|
-
r(this, "container", null);
|
|
164
|
-
r(this, "config", null);
|
|
165
|
-
r(this, "messageHandlers", /* @__PURE__ */ new Map());
|
|
166
|
-
r(this, "pendingRequests", /* @__PURE__ */ new Map());
|
|
167
|
-
r(this, "isReady", !1);
|
|
168
|
-
r(this, "allowedOrigin", "");
|
|
169
|
-
this.handleMessage = this.handleMessage.bind(this);
|
|
170
|
-
}
|
|
171
|
-
// generate unique request ID
|
|
172
|
-
generateRequestId() {
|
|
173
|
-
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
174
|
-
}
|
|
175
|
-
// send message to iframe
|
|
176
|
-
sendMessage(t, e) {
|
|
177
|
-
return new Promise((o, n) => {
|
|
178
|
-
if (!this.iframe || !this.iframe.contentWindow) {
|
|
179
|
-
n(new Error("Iframe not initialized"));
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
const i = this.generateRequestId(), s = { type: t, payload: e, requestId: i };
|
|
183
|
-
this.pendingRequests.set(i, { resolve: o, reject: n }), setTimeout(() => {
|
|
184
|
-
this.pendingRequests.has(i) && (this.pendingRequests.delete(i), n(new Error(`Request timeout: ${t}`)));
|
|
185
|
-
}, 3e4), this.iframe.contentWindow.postMessage(s, this.allowedOrigin);
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
// handle messages from iframe
|
|
189
|
-
handleMessage(t) {
|
|
190
|
-
if (t.origin !== this.allowedOrigin) {
|
|
191
|
-
console.warn("[PayNext Iframe] Message from unauthorized origin:", t.origin);
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
const e = t.data;
|
|
195
|
-
if (!(!e.type || !e.type.startsWith("paynext:"))) {
|
|
196
|
-
if (e.requestId && this.pendingRequests.has(e.requestId)) {
|
|
197
|
-
const { resolve: o } = this.pendingRequests.get(e.requestId);
|
|
198
|
-
this.pendingRequests.delete(e.requestId), o(e.payload);
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
switch (e.type) {
|
|
202
|
-
case "paynext:ready":
|
|
203
|
-
this.isReady = !0, console.log("[PayNext Iframe] SDK ready");
|
|
204
|
-
break;
|
|
205
|
-
case "paynext:loaded":
|
|
206
|
-
this.config?.onCheckoutLoaded && this.config.onCheckoutLoaded(e.payload);
|
|
207
|
-
break;
|
|
208
|
-
case "paynext:attempt":
|
|
209
|
-
this.config?.onCheckoutAttempt && this.config.onCheckoutAttempt(e.payload);
|
|
210
|
-
break;
|
|
211
|
-
case "paynext:complete":
|
|
212
|
-
this.config?.onCheckoutComplete && this.config.onCheckoutComplete(e.payload);
|
|
213
|
-
break;
|
|
214
|
-
case "paynext:fail":
|
|
215
|
-
this.config?.onCheckoutFail && this.config.onCheckoutFail(e.payload);
|
|
216
|
-
break;
|
|
217
|
-
case "paynext:error":
|
|
218
|
-
console.error("[PayNext Iframe] Error:", e.payload);
|
|
219
|
-
break;
|
|
220
|
-
case "paynext:resize":
|
|
221
|
-
this.iframe && e.payload?.height && (this.iframe.style.height = `${e.payload.height}px`);
|
|
222
|
-
break;
|
|
223
|
-
default:
|
|
224
|
-
console.warn("[PayNext Iframe] Unknown message type:", e.type);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
// create and configure iframe
|
|
229
|
-
createIframe(t, e = !1) {
|
|
230
|
-
const o = t.environment?.toLowerCase()?.includes("develop") || t.environment?.toLowerCase()?.includes("staging") ? "develop" : "production";
|
|
231
|
-
this.allowedOrigin = e ? window.location.origin : C[o];
|
|
232
|
-
const n = document.createElement("iframe"), i = o === "develop" ? h : p, s = o === "develop" ? "https://cdn-sdk-dev.paynext.com/index.cdn.js" : "https://cdn-sdk.paynext.com/index.cdn.js";
|
|
233
|
-
return e ? (console.log("[PayNext Iframe] Using inline iframe mode (embedded HTML)"), console.log("[PayNext Iframe] SDK will load from:", s), n.srcdoc = P(s)) : (console.log("[PayNext Iframe] Using CDN iframe mode"), console.log("[PayNext Iframe] Loading iframe from:", i), n.src = i), n.style.border = "none", n.style.width = "100%", n.style.minHeight = "400px", n.style.display = "block", n.allow = "payment *", n.sandbox.add(
|
|
234
|
-
"allow-scripts",
|
|
235
|
-
// required for SDK execution
|
|
236
|
-
"allow-same-origin",
|
|
237
|
-
// required for postMessage
|
|
238
|
-
"allow-forms",
|
|
239
|
-
// required for form submission
|
|
240
|
-
"allow-popups",
|
|
241
|
-
// required for 3DS redirects
|
|
242
|
-
"allow-popups-to-escape-sandbox",
|
|
243
|
-
// required for payment popups
|
|
244
|
-
"allow-top-navigation-by-user-activation"
|
|
245
|
-
// required for redirects
|
|
246
|
-
), n.setAttribute("referrerpolicy", "strict-origin-when-cross-origin"), n.setAttribute("importance", "high"), n;
|
|
247
|
-
}
|
|
248
|
-
// wait for iframe to be ready
|
|
249
|
-
async waitForReady(t = 1e4) {
|
|
250
|
-
const e = Date.now();
|
|
251
|
-
for (; !this.isReady; ) {
|
|
252
|
-
if (Date.now() - e > t)
|
|
253
|
-
throw new Error("Iframe initialization timeout");
|
|
254
|
-
await new Promise((o) => setTimeout(o, 100));
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
// mount checkout in iframe
|
|
258
|
-
async mount(t, e) {
|
|
259
|
-
try {
|
|
260
|
-
const o = document.getElementById(t);
|
|
261
|
-
if (!o)
|
|
262
|
-
throw new Error(`Container element "${t}" not found`);
|
|
263
|
-
this.container = o, this.config = e, this.iframe && await this.unmount();
|
|
264
|
-
const n = e.environment?.toLowerCase()?.includes("develop") || e.environment?.toLowerCase()?.includes("staging") ? "develop" : "production", i = n === "develop" ? h : p, s = window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1" || window.location.hostname.startsWith("192.168.") || window.location.hostname.endsWith(".local");
|
|
265
|
-
let l = s;
|
|
266
|
-
if (!s && n === "develop")
|
|
267
|
-
try {
|
|
268
|
-
const m = new AbortController(), u = setTimeout(() => m.abort(), 2e3);
|
|
269
|
-
await fetch(i, {
|
|
270
|
-
method: "HEAD",
|
|
271
|
-
signal: m.signal,
|
|
272
|
-
cache: "no-cache"
|
|
273
|
-
}), clearTimeout(u), l = !1, console.log("[PayNext Iframe] CDN is available, using remote iframe");
|
|
274
|
-
} catch {
|
|
275
|
-
l = !0, console.warn("[PayNext Iframe] CDN not available, using inline fallback mode");
|
|
276
|
-
}
|
|
277
|
-
l && (console.log("[PayNext Iframe] Using inline fallback mode"), console.log("[PayNext Iframe] Reason:", s ? "localhost detected" : "CDN not available")), this.iframe = this.createIframe(e, l), window.addEventListener("message", this.handleMessage), o.innerHTML = "", o.appendChild(this.iframe), await new Promise((m, u) => {
|
|
278
|
-
const y = setTimeout(() => {
|
|
279
|
-
u(new Error("Iframe load timeout"));
|
|
280
|
-
}, 1e4);
|
|
281
|
-
this.iframe.onload = () => {
|
|
282
|
-
clearTimeout(y), m();
|
|
283
|
-
}, this.iframe.onerror = () => {
|
|
284
|
-
clearTimeout(y), u(new Error("Iframe failed to load"));
|
|
285
|
-
};
|
|
286
|
-
}), await this.waitForReady(), await this.sendMessage("paynext:mount", {
|
|
287
|
-
config: {
|
|
288
|
-
...e,
|
|
289
|
-
// remove callbacks from config sent to iframe
|
|
290
|
-
onCheckoutLoaded: void 0,
|
|
291
|
-
onCheckoutAttempt: void 0,
|
|
292
|
-
onCheckoutComplete: void 0,
|
|
293
|
-
onCheckoutFail: void 0
|
|
294
|
-
}
|
|
295
|
-
}), console.log("[PayNext Iframe] Checkout mounted successfully");
|
|
296
|
-
} catch (o) {
|
|
297
|
-
throw console.error("[PayNext Iframe] Mount failed:", o), await this.unmount(), o;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
// unmount checkout
|
|
301
|
-
async unmount() {
|
|
302
|
-
try {
|
|
303
|
-
this.iframe && (this.isReady && await this.sendMessage(
|
|
304
|
-
"paynext:unmount"
|
|
305
|
-
/* UNMOUNT */
|
|
306
|
-
).catch(() => {
|
|
307
|
-
}), this.iframe.parentNode && this.iframe.parentNode.removeChild(this.iframe), this.iframe = null), window.removeEventListener("message", this.handleMessage), this.container && (this.container.innerHTML = "", this.container = null), this.isReady = !1, this.config = null, this.pendingRequests.clear(), this.messageHandlers.clear(), console.log("[PayNext Iframe] Checkout unmounted");
|
|
308
|
-
} catch (t) {
|
|
309
|
-
console.error("[PayNext Iframe] Unmount failed:", t);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
// update configuration
|
|
313
|
-
async updateConfig(t) {
|
|
314
|
-
if (!this.isReady)
|
|
315
|
-
throw new Error("Iframe not ready");
|
|
316
|
-
this.config = { ...this.config, ...t }, await this.sendMessage("paynext:updateConfig", {
|
|
317
|
-
config: {
|
|
318
|
-
...t,
|
|
319
|
-
onCheckoutLoaded: void 0,
|
|
320
|
-
onCheckoutAttempt: void 0,
|
|
321
|
-
onCheckoutComplete: void 0,
|
|
322
|
-
onCheckoutFail: void 0
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
// preload iframe (optional optimization)
|
|
327
|
-
static async preload(t) {
|
|
328
|
-
const o = (t?.toLowerCase()?.includes("develop") || t?.toLowerCase()?.includes("staging") ? "develop" : "production") === "develop" ? h : p, n = document.createElement("link");
|
|
329
|
-
n.rel = "preconnect", n.href = new URL(o).origin, document.head.appendChild(n);
|
|
330
|
-
const i = document.createElement("link");
|
|
331
|
-
i.rel = "dns-prefetch", i.href = new URL(o).origin, document.head.appendChild(i);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
const R = {
|
|
335
|
-
preload: f.preload
|
|
336
|
-
}, k = "https://cdn-sdk-dev.paynext.com/index.cdn.js", I = "https://cdn-sdk.paynext.com/index.cdn.js";
|
|
337
|
-
let d = null, c = null;
|
|
338
|
-
async function g(a) {
|
|
339
|
-
if (c)
|
|
340
|
-
return c;
|
|
341
|
-
if (d)
|
|
342
|
-
return d;
|
|
343
|
-
const t = a?.toLowerCase()?.includes("develop") || a?.toLowerCase()?.includes("staging") ? "develop" : "production";
|
|
344
|
-
return d = new Promise((e, o) => {
|
|
1
|
+
var l = Object.defineProperty;
|
|
2
|
+
var u = (t, n, e) => n in t ? l(t, n, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[n] = e;
|
|
3
|
+
var d = (t, n, e) => u(t, typeof n != "symbol" ? n + "" : n, e);
|
|
4
|
+
const w = "https://cdn-sdk-dev.paynext.com/index.cdn.js", P = "https://cdn-sdk.paynext.com/index.cdn.js";
|
|
5
|
+
let i = null, a = null;
|
|
6
|
+
async function c(t) {
|
|
7
|
+
if (a)
|
|
8
|
+
return a;
|
|
9
|
+
if (i)
|
|
10
|
+
return i;
|
|
11
|
+
const n = t?.toLowerCase()?.includes("develop") || t?.toLowerCase()?.includes("staging") ? "develop" : "production";
|
|
12
|
+
return i = new Promise((e, s) => {
|
|
345
13
|
if (typeof window > "u") {
|
|
346
|
-
|
|
14
|
+
s(new Error("PayNext SDK can only be loaded in browser environment"));
|
|
347
15
|
return;
|
|
348
16
|
}
|
|
349
17
|
if (window.PayNextSDK) {
|
|
350
|
-
console.log("[PayNext CDN] SDK already loaded from cache"),
|
|
18
|
+
console.log("[PayNext CDN] SDK already loaded from cache"), a = window.PayNextSDK, e(a);
|
|
351
19
|
return;
|
|
352
20
|
}
|
|
353
|
-
const
|
|
354
|
-
|
|
355
|
-
const
|
|
356
|
-
if (!
|
|
357
|
-
console.error("[PayNext CDN] PayNextSDK not found in window after load"),
|
|
21
|
+
const o = document.createElement("script");
|
|
22
|
+
o.src = n === "develop" ? w : P, o.crossOrigin = "*", o.async = !0, o.onload = () => {
|
|
23
|
+
const r = window.PayNextSDK;
|
|
24
|
+
if (!r) {
|
|
25
|
+
console.error("[PayNext CDN] PayNextSDK not found in window after load"), i = null, document.head.removeChild(o), s(new Error("PayNextSDK not found in global scope after loading"));
|
|
358
26
|
return;
|
|
359
27
|
}
|
|
360
|
-
|
|
361
|
-
},
|
|
362
|
-
console.error("[PayNext CDN] Failed to load script:",
|
|
363
|
-
}, document.head.appendChild(
|
|
364
|
-
}),
|
|
28
|
+
a = r, e(r);
|
|
29
|
+
}, o.onerror = (r) => {
|
|
30
|
+
console.error("[PayNext CDN] Failed to load script:", r), i = null, document.head.removeChild(o), s(new Error("Failed to load PayNext SDK script from CDN"));
|
|
31
|
+
}, document.head.appendChild(o);
|
|
32
|
+
}), i;
|
|
365
33
|
}
|
|
366
|
-
class
|
|
34
|
+
class h {
|
|
367
35
|
constructor() {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
r(this, "initPromise", null);
|
|
371
|
-
r(this, "mode", "direct");
|
|
36
|
+
d(this, "cdnInstance", null);
|
|
37
|
+
d(this, "initPromise", null);
|
|
372
38
|
}
|
|
373
39
|
// initialize
|
|
374
|
-
async initialize(
|
|
40
|
+
async initialize(n) {
|
|
375
41
|
try {
|
|
376
|
-
if (this.initPromise = await
|
|
42
|
+
if (this.initPromise = await c(n), !this.initPromise.PayNextCheckout)
|
|
377
43
|
throw new Error("PayNextCheckout not found in CDN module");
|
|
378
44
|
this.cdnInstance = new this.initPromise.PayNextCheckout();
|
|
379
45
|
} catch (e) {
|
|
@@ -387,37 +53,31 @@ class E {
|
|
|
387
53
|
if (!this.cdnInstance)
|
|
388
54
|
throw new Error("SDK instance not created");
|
|
389
55
|
}
|
|
390
|
-
// mount
|
|
391
|
-
async mount(
|
|
392
|
-
return
|
|
56
|
+
// mount
|
|
57
|
+
async mount(n, e) {
|
|
58
|
+
return await this.initialize(e.environment), this.waitForReady(), this.cdnInstance?.mount(n, e);
|
|
393
59
|
}
|
|
394
|
-
// unmount
|
|
60
|
+
// unmount
|
|
395
61
|
async unmount() {
|
|
396
|
-
if (this.mode === "iframe" && this.iframeInstance)
|
|
397
|
-
return this.iframeInstance.unmount();
|
|
398
62
|
if (this.waitForReady(), this.cdnInstance?.unmount)
|
|
399
63
|
return this.cdnInstance.unmount();
|
|
400
64
|
}
|
|
401
|
-
// update config
|
|
402
|
-
async updateConfig(
|
|
403
|
-
if (this.mode === "iframe" && this.iframeInstance)
|
|
404
|
-
return this.iframeInstance.updateConfig(t);
|
|
65
|
+
// update config
|
|
66
|
+
async updateConfig(n) {
|
|
405
67
|
if (this.waitForReady(), this.cdnInstance?.updateConfig)
|
|
406
|
-
return this.cdnInstance.updateConfig(
|
|
68
|
+
return this.cdnInstance.updateConfig(n);
|
|
407
69
|
}
|
|
408
70
|
// preload (optional optimization)
|
|
409
|
-
static async preload(
|
|
410
|
-
|
|
71
|
+
static async preload(n) {
|
|
72
|
+
await c(n);
|
|
411
73
|
}
|
|
412
74
|
}
|
|
413
|
-
const
|
|
414
|
-
preload:
|
|
75
|
+
const m = {
|
|
76
|
+
preload: h.preload
|
|
415
77
|
};
|
|
416
|
-
var
|
|
78
|
+
var y = /* @__PURE__ */ ((t) => (t.PAYPAL = "PAYPAL", t.APPLE_PAY = "APPLEPAY", t.GOOGLE_PAY = "GPAY", t.CARD = "CARD", t.VENMO = "VENMO", t))(y || {});
|
|
417
79
|
export {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
R as PayNextSDKIframe,
|
|
422
|
-
N as PaymentMethod
|
|
80
|
+
h as PayNextCheckout,
|
|
81
|
+
m as PayNextSDK,
|
|
82
|
+
y as PaymentMethod
|
|
423
83
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1,150 +1 @@
|
|
|
1
|
-
(function(
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>PayNext Checkout</title>
|
|
7
|
-
<style>
|
|
8
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
9
|
-
html, body { width: 100%; height: 100%; overflow: hidden; }
|
|
10
|
-
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
|
|
11
|
-
#checkout-container { width: 100%; min-height: 100%; }
|
|
12
|
-
.loading { display: flex; align-items: center; justify-content: center; min-height: 400px; color: #666; font-size: 14px; }
|
|
13
|
-
.loading::after { content: '...'; animation: dots 1.5s steps(4, end) infinite; }
|
|
14
|
-
@keyframes dots { 0%, 20% { content: '.'; } 40% { content: '..'; } 60%, 100% { content: '...'; } }
|
|
15
|
-
.error { color: #e53e3e; padding: 20px; text-align: center; }
|
|
16
|
-
</style>
|
|
17
|
-
</head>
|
|
18
|
-
<body>
|
|
19
|
-
<div id="checkout-container"><div class="loading">Loading checkout</div></div>
|
|
20
|
-
<script type="module">
|
|
21
|
-
const MessageType = {
|
|
22
|
-
MOUNT: 'paynext:mount', UNMOUNT: 'paynext:unmount', UPDATE_CONFIG: 'paynext:updateConfig',
|
|
23
|
-
READY: 'paynext:ready', LOADED: 'paynext:loaded', ATTEMPT: 'paynext:attempt',
|
|
24
|
-
COMPLETE: 'paynext:complete', FAIL: 'paynext:fail', ERROR: 'paynext:error', RESIZE: 'paynext:resize'
|
|
25
|
-
}
|
|
26
|
-
let checkout = null, parentOrigin = null, config = null
|
|
27
|
-
|
|
28
|
-
function sendToParent(type, payload, requestId) {
|
|
29
|
-
if (!parentOrigin) return
|
|
30
|
-
window.parent.postMessage({ type, payload, requestId }, parentOrigin)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function showError(message) {
|
|
34
|
-
document.getElementById('checkout-container').innerHTML =
|
|
35
|
-
'<div class="error"><strong>Error:</strong> ' + message + '</div>'
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
window.addEventListener('message', async (event) => {
|
|
39
|
-
const data = event.data
|
|
40
|
-
if (!parentOrigin) parentOrigin = event.origin
|
|
41
|
-
if (event.origin !== parentOrigin || !data.type?.startsWith('paynext:')) return
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
switch (data.type) {
|
|
45
|
-
case MessageType.MOUNT:
|
|
46
|
-
if (data.payload?.config) {
|
|
47
|
-
config = data.payload.config
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
// Load SDK from CDN
|
|
51
|
-
// CDN version exports to window.PayNextSDK
|
|
52
|
-
if (!window.PayNextSDK) {
|
|
53
|
-
// Load SDK script if not already loaded
|
|
54
|
-
await new Promise((resolve, reject) => {
|
|
55
|
-
const script = document.createElement('script')
|
|
56
|
-
script.src = '${s}'
|
|
57
|
-
script.onload = resolve
|
|
58
|
-
script.onerror = reject
|
|
59
|
-
document.head.appendChild(script)
|
|
60
|
-
})
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const { PayNextCheckout } = window.PayNextSDK || {}
|
|
64
|
-
|
|
65
|
-
if (!PayNextCheckout) {
|
|
66
|
-
throw new Error('PayNextCheckout not found in window.PayNextSDK')
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
checkout = new PayNextCheckout()
|
|
70
|
-
await checkout.mount('checkout-container', {
|
|
71
|
-
...config,
|
|
72
|
-
onCheckoutLoaded: (result) => {
|
|
73
|
-
sendToParent(MessageType.LOADED, result, data.requestId)
|
|
74
|
-
notifyResize()
|
|
75
|
-
},
|
|
76
|
-
onCheckoutAttempt: (result) => sendToParent(MessageType.ATTEMPT, result),
|
|
77
|
-
onCheckoutComplete: (result) => sendToParent(MessageType.COMPLETE, result),
|
|
78
|
-
onCheckoutFail: (error) => sendToParent(MessageType.FAIL, error)
|
|
79
|
-
})
|
|
80
|
-
sendToParent(MessageType.READY, { success: true }, data.requestId)
|
|
81
|
-
setupResizeObserver()
|
|
82
|
-
} catch (importError) {
|
|
83
|
-
console.error('[Iframe] Failed to load SDK:', importError)
|
|
84
|
-
showError('Failed to load PayNext SDK: ' + importError.message)
|
|
85
|
-
sendToParent(MessageType.ERROR, {
|
|
86
|
-
message: 'SDK import failed: ' + importError.message,
|
|
87
|
-
stack: importError.stack
|
|
88
|
-
}, data.requestId)
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
break
|
|
92
|
-
|
|
93
|
-
case MessageType.UNMOUNT:
|
|
94
|
-
if (checkout) {
|
|
95
|
-
await checkout.unmount()
|
|
96
|
-
checkout = null
|
|
97
|
-
}
|
|
98
|
-
sendToParent(MessageType.READY, { success: true }, data.requestId)
|
|
99
|
-
break
|
|
100
|
-
|
|
101
|
-
case MessageType.UPDATE_CONFIG:
|
|
102
|
-
if (checkout && data.payload?.config) {
|
|
103
|
-
await checkout.updateConfig(data.payload.config)
|
|
104
|
-
sendToParent(MessageType.READY, { success: true }, data.requestId)
|
|
105
|
-
}
|
|
106
|
-
break
|
|
107
|
-
}
|
|
108
|
-
} catch (error) {
|
|
109
|
-
console.error('[Iframe] Error:', error)
|
|
110
|
-
sendToParent(MessageType.ERROR, {
|
|
111
|
-
message: error.message,
|
|
112
|
-
stack: error.stack
|
|
113
|
-
}, data.requestId)
|
|
114
|
-
}
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
function setupResizeObserver() {
|
|
118
|
-
new ResizeObserver(entries => {
|
|
119
|
-
for (const entry of entries) {
|
|
120
|
-
sendToParent(MessageType.RESIZE, { height: entry.contentRect.height })
|
|
121
|
-
}
|
|
122
|
-
}).observe(document.body)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function notifyResize() {
|
|
126
|
-
sendToParent(MessageType.RESIZE, { height: document.body.scrollHeight })
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
window.addEventListener('load', () => {
|
|
130
|
-
console.log('[Iframe] Iframe loaded, sending ready message')
|
|
131
|
-
setTimeout(() => {
|
|
132
|
-
window.parent.postMessage(
|
|
133
|
-
{ type: MessageType.READY, payload: { success: true } },
|
|
134
|
-
'*'
|
|
135
|
-
)
|
|
136
|
-
}, 100)
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
window.addEventListener('error', (event) => {
|
|
140
|
-
console.error('[Iframe] Global error:', event.error)
|
|
141
|
-
sendToParent(MessageType.ERROR, {
|
|
142
|
-
message: event.error?.message || 'Unknown error',
|
|
143
|
-
stack: event.error?.stack
|
|
144
|
-
})
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
console.log('[Iframe] PayNext Checkout iframe initialized, SDK URL: ${s}')
|
|
148
|
-
<\/script>
|
|
149
|
-
</body>
|
|
150
|
-
</html>`}class h{constructor(){d(this,"iframe",null);d(this,"container",null);d(this,"config",null);d(this,"messageHandlers",new Map);d(this,"pendingRequests",new Map);d(this,"isReady",!1);d(this,"allowedOrigin","");this.handleMessage=this.handleMessage.bind(this)}generateRequestId(){return`${Date.now()}-${Math.random().toString(36).substr(2,9)}`}sendMessage(t,e){return new Promise((o,n)=>{if(!this.iframe||!this.iframe.contentWindow){n(new Error("Iframe not initialized"));return}const a=this.generateRequestId(),l={type:t,payload:e,requestId:a};this.pendingRequests.set(a,{resolve:o,reject:n}),setTimeout(()=>{this.pendingRequests.has(a)&&(this.pendingRequests.delete(a),n(new Error(`Request timeout: ${t}`)))},3e4),this.iframe.contentWindow.postMessage(l,this.allowedOrigin)})}handleMessage(t){if(t.origin!==this.allowedOrigin){console.warn("[PayNext Iframe] Message from unauthorized origin:",t.origin);return}const e=t.data;if(!(!e.type||!e.type.startsWith("paynext:"))){if(e.requestId&&this.pendingRequests.has(e.requestId)){const{resolve:o}=this.pendingRequests.get(e.requestId);this.pendingRequests.delete(e.requestId),o(e.payload);return}switch(e.type){case"paynext:ready":this.isReady=!0,console.log("[PayNext Iframe] SDK ready");break;case"paynext:loaded":this.config?.onCheckoutLoaded&&this.config.onCheckoutLoaded(e.payload);break;case"paynext:attempt":this.config?.onCheckoutAttempt&&this.config.onCheckoutAttempt(e.payload);break;case"paynext:complete":this.config?.onCheckoutComplete&&this.config.onCheckoutComplete(e.payload);break;case"paynext:fail":this.config?.onCheckoutFail&&this.config.onCheckoutFail(e.payload);break;case"paynext:error":console.error("[PayNext Iframe] Error:",e.payload);break;case"paynext:resize":this.iframe&&e.payload?.height&&(this.iframe.style.height=`${e.payload.height}px`);break;default:console.warn("[PayNext Iframe] Unknown message type:",e.type)}}}createIframe(t,e=!1){const o=t.environment?.toLowerCase()?.includes("develop")||t.environment?.toLowerCase()?.includes("staging")?"develop":"production";this.allowedOrigin=e?window.location.origin:C[o];const n=document.createElement("iframe"),a=o==="develop"?r:c,l=o==="develop"?"https://cdn-sdk-dev.paynext.com/index.cdn.js":"https://cdn-sdk.paynext.com/index.cdn.js";return e?(console.log("[PayNext Iframe] Using inline iframe mode (embedded HTML)"),console.log("[PayNext Iframe] SDK will load from:",l),n.srcdoc=k(l)):(console.log("[PayNext Iframe] Using CDN iframe mode"),console.log("[PayNext Iframe] Loading iframe from:",a),n.src=a),n.style.border="none",n.style.width="100%",n.style.minHeight="400px",n.style.display="block",n.allow="payment *",n.sandbox.add("allow-scripts","allow-same-origin","allow-forms","allow-popups","allow-popups-to-escape-sandbox","allow-top-navigation-by-user-activation"),n.setAttribute("referrerpolicy","strict-origin-when-cross-origin"),n.setAttribute("importance","high"),n}async waitForReady(t=1e4){const e=Date.now();for(;!this.isReady;){if(Date.now()-e>t)throw new Error("Iframe initialization timeout");await new Promise(o=>setTimeout(o,100))}}async mount(t,e){try{const o=document.getElementById(t);if(!o)throw new Error(`Container element "${t}" not found`);this.container=o,this.config=e,this.iframe&&await this.unmount();const n=e.environment?.toLowerCase()?.includes("develop")||e.environment?.toLowerCase()?.includes("staging")?"develop":"production",a=n==="develop"?r:c,l=window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"||window.location.hostname.startsWith("192.168.")||window.location.hostname.endsWith(".local");let p=l;if(!l&&n==="develop")try{const f=new AbortController,y=setTimeout(()=>f.abort(),2e3);await fetch(a,{method:"HEAD",signal:f.signal,cache:"no-cache"}),clearTimeout(y),p=!1,console.log("[PayNext Iframe] CDN is available, using remote iframe")}catch{p=!0,console.warn("[PayNext Iframe] CDN not available, using inline fallback mode")}p&&(console.log("[PayNext Iframe] Using inline fallback mode"),console.log("[PayNext Iframe] Reason:",l?"localhost detected":"CDN not available")),this.iframe=this.createIframe(e,p),window.addEventListener("message",this.handleMessage),o.innerHTML="",o.appendChild(this.iframe),await new Promise((f,y)=>{const P=setTimeout(()=>{y(new Error("Iframe load timeout"))},1e4);this.iframe.onload=()=>{clearTimeout(P),f()},this.iframe.onerror=()=>{clearTimeout(P),y(new Error("Iframe failed to load"))}}),await this.waitForReady(),await this.sendMessage("paynext:mount",{config:{...e,onCheckoutLoaded:void 0,onCheckoutAttempt:void 0,onCheckoutComplete:void 0,onCheckoutFail:void 0}}),console.log("[PayNext Iframe] Checkout mounted successfully")}catch(o){throw console.error("[PayNext Iframe] Mount failed:",o),await this.unmount(),o}}async unmount(){try{this.iframe&&(this.isReady&&await this.sendMessage("paynext:unmount").catch(()=>{}),this.iframe.parentNode&&this.iframe.parentNode.removeChild(this.iframe),this.iframe=null),window.removeEventListener("message",this.handleMessage),this.container&&(this.container.innerHTML="",this.container=null),this.isReady=!1,this.config=null,this.pendingRequests.clear(),this.messageHandlers.clear(),console.log("[PayNext Iframe] Checkout unmounted")}catch(t){console.error("[PayNext Iframe] Unmount failed:",t)}}async updateConfig(t){if(!this.isReady)throw new Error("Iframe not ready");this.config={...this.config,...t},await this.sendMessage("paynext:updateConfig",{config:{...t,onCheckoutLoaded:void 0,onCheckoutAttempt:void 0,onCheckoutComplete:void 0,onCheckoutFail:void 0}})}static async preload(t){const o=(t?.toLowerCase()?.includes("develop")||t?.toLowerCase()?.includes("staging")?"develop":"production")==="develop"?r:c,n=document.createElement("link");n.rel="preconnect",n.href=new URL(o).origin,document.head.appendChild(n);const a=document.createElement("link");a.rel="dns-prefetch",a.href=new URL(o).origin,document.head.appendChild(a)}}const I={preload:h.preload},N="https://cdn-sdk-dev.paynext.com/index.cdn.js",v="https://cdn-sdk.paynext.com/index.cdn.js";let u=null,m=null;async function g(s){if(m)return m;if(u)return u;const t=s?.toLowerCase()?.includes("develop")||s?.toLowerCase()?.includes("staging")?"develop":"production";return u=new Promise((e,o)=>{if(typeof window>"u"){o(new Error("PayNext SDK can only be loaded in browser environment"));return}if(window.PayNextSDK){console.log("[PayNext CDN] SDK already loaded from cache"),m=window.PayNextSDK,e(m);return}const n=document.createElement("script");n.src=t==="develop"?N:v,n.crossOrigin="*",n.async=!0,n.onload=()=>{const a=window.PayNextSDK;if(!a){console.error("[PayNext CDN] PayNextSDK not found in window after load"),u=null,document.head.removeChild(n),o(new Error("PayNextSDK not found in global scope after loading"));return}m=a,e(a)},n.onerror=a=>{console.error("[PayNext CDN] Failed to load script:",a),u=null,document.head.removeChild(n),o(new Error("Failed to load PayNext SDK script from CDN"))},document.head.appendChild(n)}),u}class w{constructor(){d(this,"cdnInstance",null);d(this,"iframeInstance",null);d(this,"initPromise",null);d(this,"mode","direct")}async initialize(t){try{if(this.initPromise=await g(t),!this.initPromise.PayNextCheckout)throw new Error("PayNextCheckout not found in CDN module");this.cdnInstance=new this.initPromise.PayNextCheckout}catch(e){throw console.error("[PayNext CDN] Failed to initialize:",e),e}}waitForReady(){if(!this.initPromise)throw new Error("SDK initialization not started");if(!this.cdnInstance)throw new Error("SDK instance not created")}async mount(t,e){return e.iframeMode===!0?(this.mode="iframe",this.iframeInstance||(this.iframeInstance=new h),this.iframeInstance.mount(t,e)):(this.mode="direct",await this.initialize(e.environment),this.waitForReady(),this.cdnInstance?.mount(t,e))}async unmount(){if(this.mode==="iframe"&&this.iframeInstance)return this.iframeInstance.unmount();if(this.waitForReady(),this.cdnInstance?.unmount)return this.cdnInstance.unmount()}async updateConfig(t){if(this.mode==="iframe"&&this.iframeInstance)return this.iframeInstance.updateConfig(t);if(this.waitForReady(),this.cdnInstance?.updateConfig)return this.cdnInstance.updateConfig(t)}static async preload(t,e){e?.iframeMode?await h.preload(t):await g(t)}}const E={preload:w.preload};var x=(s=>(s.PAYPAL="PAYPAL",s.APPLE_PAY="APPLEPAY",s.GOOGLE_PAY="GPAY",s.CARD="CARD",s.VENMO="VENMO",s))(x||{});i.PayNextCheckout=w,i.PayNextCheckoutIframe=h,i.PayNextSDK=E,i.PayNextSDKIframe=I,i.PaymentMethod=x,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(e,n){typeof exports=="object"&&typeof module<"u"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(e=typeof globalThis<"u"?globalThis:e||self,n(e["PayNext SDK"]={}))})(this,(function(e){"use strict";var w=Object.defineProperty;var N=(e,n,a)=>n in e?w(e,n,{enumerable:!0,configurable:!0,writable:!0,value:a}):e[n]=a;var u=(e,n,a)=>N(e,typeof n!="symbol"?n+"":n,a);const n="https://cdn-sdk-dev.paynext.com/index.cdn.js",a="https://cdn-sdk.paynext.com/index.cdn.js";let d=null,s=null;async function P(t){if(s)return s;if(d)return d;const o=t?.toLowerCase()?.includes("develop")||t?.toLowerCase()?.includes("staging")?"develop":"production";return d=new Promise((i,l)=>{if(typeof window>"u"){l(new Error("PayNext SDK can only be loaded in browser environment"));return}if(window.PayNextSDK){console.log("[PayNext CDN] SDK already loaded from cache"),s=window.PayNextSDK,i(s);return}const r=document.createElement("script");r.src=o==="develop"?n:a,r.crossOrigin="*",r.async=!0,r.onload=()=>{const c=window.PayNextSDK;if(!c){console.error("[PayNext CDN] PayNextSDK not found in window after load"),d=null,document.head.removeChild(r),l(new Error("PayNextSDK not found in global scope after loading"));return}s=c,i(c)},r.onerror=c=>{console.error("[PayNext CDN] Failed to load script:",c),d=null,document.head.removeChild(r),l(new Error("Failed to load PayNext SDK script from CDN"))},document.head.appendChild(r)}),d}class y{constructor(){u(this,"cdnInstance",null);u(this,"initPromise",null)}async initialize(o){try{if(this.initPromise=await P(o),!this.initPromise.PayNextCheckout)throw new Error("PayNextCheckout not found in CDN module");this.cdnInstance=new this.initPromise.PayNextCheckout}catch(i){throw console.error("[PayNext CDN] Failed to initialize:",i),i}}waitForReady(){if(!this.initPromise)throw new Error("SDK initialization not started");if(!this.cdnInstance)throw new Error("SDK instance not created")}async mount(o,i){return await this.initialize(i.environment),this.waitForReady(),this.cdnInstance?.mount(o,i)}async unmount(){if(this.waitForReady(),this.cdnInstance?.unmount)return this.cdnInstance.unmount()}async updateConfig(o){if(this.waitForReady(),this.cdnInstance?.updateConfig)return this.cdnInstance.updateConfig(o)}static async preload(o){await P(o)}}const h={preload:y.preload};var f=(t=>(t.PAYPAL="PAYPAL",t.APPLE_PAY="APPLEPAY",t.GOOGLE_PAY="GPAY",t.CARD="CARD",t.VENMO="VENMO",t))(f||{});e.PayNextCheckout=y,e.PayNextSDK=h,e.PaymentMethod=f,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
CHANGED
package/dist/checkout.html
DELETED
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>PayNext Checkout - Iframe Mode</title>
|
|
7
|
-
|
|
8
|
-
<!-- Security headers -->
|
|
9
|
-
<meta http-equiv="X-Content-Type-Options" content="nosniff">
|
|
10
|
-
<meta http-equiv="X-Frame-Options" content="ALLOW-FROM *">
|
|
11
|
-
<meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin">
|
|
12
|
-
|
|
13
|
-
<!-- CSP for iframe -->
|
|
14
|
-
<meta http-equiv="Content-Security-Policy"
|
|
15
|
-
content="default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src *; frame-ancestors *;">
|
|
16
|
-
|
|
17
|
-
<style>
|
|
18
|
-
* {
|
|
19
|
-
margin: 0;
|
|
20
|
-
padding: 0;
|
|
21
|
-
box-sizing: border-box;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
html, body {
|
|
25
|
-
width: 100%;
|
|
26
|
-
height: 100%;
|
|
27
|
-
overflow: hidden;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
body {
|
|
31
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
#checkout-container {
|
|
35
|
-
width: 100%;
|
|
36
|
-
min-height: 100%;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/* Loading state */
|
|
40
|
-
.loading {
|
|
41
|
-
display: flex;
|
|
42
|
-
align-items: center;
|
|
43
|
-
justify-content: center;
|
|
44
|
-
min-height: 400px;
|
|
45
|
-
color: #666;
|
|
46
|
-
font-size: 14px;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.loading::after {
|
|
50
|
-
content: '...';
|
|
51
|
-
animation: dots 1.5s steps(4, end) infinite;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
@keyframes dots {
|
|
55
|
-
0%, 20% { content: '.'; }
|
|
56
|
-
40% { content: '..'; }
|
|
57
|
-
60%, 100% { content: '...'; }
|
|
58
|
-
}
|
|
59
|
-
</style>
|
|
60
|
-
</head>
|
|
61
|
-
<body>
|
|
62
|
-
<div id="checkout-container">
|
|
63
|
-
<div class="loading">Loading checkout</div>
|
|
64
|
-
</div>
|
|
65
|
-
|
|
66
|
-
<script type="module">
|
|
67
|
-
// Message types for parent communication
|
|
68
|
-
const MessageType = {
|
|
69
|
-
INIT: 'paynext:init',
|
|
70
|
-
MOUNT: 'paynext:mount',
|
|
71
|
-
UNMOUNT: 'paynext:unmount',
|
|
72
|
-
UPDATE_CONFIG: 'paynext:updateConfig',
|
|
73
|
-
READY: 'paynext:ready',
|
|
74
|
-
LOADED: 'paynext:loaded',
|
|
75
|
-
ATTEMPT: 'paynext:attempt',
|
|
76
|
-
COMPLETE: 'paynext:complete',
|
|
77
|
-
FAIL: 'paynext:fail',
|
|
78
|
-
ERROR: 'paynext:error',
|
|
79
|
-
RESIZE: 'paynext:resize'
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
let checkout = null
|
|
83
|
-
let parentOrigin = null
|
|
84
|
-
let config = null
|
|
85
|
-
|
|
86
|
-
// Send message to parent
|
|
87
|
-
function sendToParent(type, payload, requestId) {
|
|
88
|
-
if (!parentOrigin) {
|
|
89
|
-
console.error('[Iframe] Parent origin not set')
|
|
90
|
-
return
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
window.parent.postMessage(
|
|
94
|
-
{ type, payload, requestId },
|
|
95
|
-
parentOrigin
|
|
96
|
-
)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Handle messages from parent
|
|
100
|
-
window.addEventListener('message', async (event) => {
|
|
101
|
-
const data = event.data
|
|
102
|
-
|
|
103
|
-
// Store parent origin on first message
|
|
104
|
-
if (!parentOrigin) {
|
|
105
|
-
parentOrigin = event.origin
|
|
106
|
-
console.log('[Iframe] Parent origin set to:', parentOrigin)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Validate origin
|
|
110
|
-
if (event.origin !== parentOrigin) {
|
|
111
|
-
console.warn('[Iframe] Message from unauthorized origin:', event.origin)
|
|
112
|
-
return
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (!data.type || !data.type.startsWith('paynext:')) {
|
|
116
|
-
return
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
switch (data.type) {
|
|
121
|
-
case MessageType.MOUNT:
|
|
122
|
-
console.log('[Iframe] Mount request received')
|
|
123
|
-
|
|
124
|
-
if (data.payload?.config) {
|
|
125
|
-
config = data.payload.config
|
|
126
|
-
|
|
127
|
-
// Load SDK from CDN
|
|
128
|
-
// CDN version exports to window.PayNextSDK
|
|
129
|
-
if (!window.PayNextSDK) {
|
|
130
|
-
await new Promise((resolve, reject) => {
|
|
131
|
-
const script = document.createElement('script')
|
|
132
|
-
script.src = './index.cdn.js'
|
|
133
|
-
script.onload = resolve
|
|
134
|
-
script.onerror = reject
|
|
135
|
-
document.head.appendChild(script)
|
|
136
|
-
})
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const { PayNextCheckout } = window.PayNextSDK || {}
|
|
140
|
-
|
|
141
|
-
if (!PayNextCheckout) {
|
|
142
|
-
throw new Error('PayNextCheckout not found in window.PayNextSDK')
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
checkout = new PayNextCheckout()
|
|
146
|
-
|
|
147
|
-
// Mount checkout
|
|
148
|
-
await checkout.mount('checkout-container', {
|
|
149
|
-
...config,
|
|
150
|
-
// Override callbacks to send messages to parent
|
|
151
|
-
onCheckoutLoaded: (result) => {
|
|
152
|
-
sendToParent(MessageType.LOADED, result, data.requestId)
|
|
153
|
-
notifyResize()
|
|
154
|
-
},
|
|
155
|
-
onCheckoutAttempt: (result) => {
|
|
156
|
-
sendToParent(MessageType.ATTEMPT, result)
|
|
157
|
-
},
|
|
158
|
-
onCheckoutComplete: (result) => {
|
|
159
|
-
sendToParent(MessageType.COMPLETE, result)
|
|
160
|
-
},
|
|
161
|
-
onCheckoutFail: (error) => {
|
|
162
|
-
sendToParent(MessageType.FAIL, error)
|
|
163
|
-
}
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
// Send success response
|
|
167
|
-
sendToParent(MessageType.READY, { success: true }, data.requestId)
|
|
168
|
-
|
|
169
|
-
// Setup resize observer
|
|
170
|
-
setupResizeObserver()
|
|
171
|
-
}
|
|
172
|
-
break
|
|
173
|
-
|
|
174
|
-
case MessageType.UNMOUNT:
|
|
175
|
-
console.log('[Iframe] Unmount request received')
|
|
176
|
-
|
|
177
|
-
if (checkout) {
|
|
178
|
-
await checkout.unmount()
|
|
179
|
-
checkout = null
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
sendToParent(MessageType.READY, { success: true }, data.requestId)
|
|
183
|
-
break
|
|
184
|
-
|
|
185
|
-
case MessageType.UPDATE_CONFIG:
|
|
186
|
-
console.log('[Iframe] Update config request received')
|
|
187
|
-
|
|
188
|
-
if (checkout && data.payload?.config) {
|
|
189
|
-
await checkout.updateConfig(data.payload.config)
|
|
190
|
-
sendToParent(MessageType.READY, { success: true }, data.requestId)
|
|
191
|
-
}
|
|
192
|
-
break
|
|
193
|
-
|
|
194
|
-
default:
|
|
195
|
-
console.warn('[Iframe] Unknown message type:', data.type)
|
|
196
|
-
}
|
|
197
|
-
} catch (error) {
|
|
198
|
-
console.error('[Iframe] Error handling message:', error)
|
|
199
|
-
sendToParent(MessageType.ERROR, {
|
|
200
|
-
message: error.message,
|
|
201
|
-
stack: error.stack
|
|
202
|
-
}, data.requestId)
|
|
203
|
-
}
|
|
204
|
-
})
|
|
205
|
-
|
|
206
|
-
// Setup resize observer to notify parent of height changes
|
|
207
|
-
function setupResizeObserver() {
|
|
208
|
-
const resizeObserver = new ResizeObserver((entries) => {
|
|
209
|
-
for (const entry of entries) {
|
|
210
|
-
const height = entry.contentRect.height
|
|
211
|
-
sendToParent(MessageType.RESIZE, { height })
|
|
212
|
-
}
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
resizeObserver.observe(document.body)
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Notify parent of current height
|
|
219
|
-
function notifyResize() {
|
|
220
|
-
const height = document.body.scrollHeight
|
|
221
|
-
sendToParent(MessageType.RESIZE, { height })
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Send ready message when iframe loads
|
|
225
|
-
window.addEventListener('load', () => {
|
|
226
|
-
console.log('[Iframe] Iframe loaded and ready')
|
|
227
|
-
|
|
228
|
-
// Wait a bit for parent to setup message listener
|
|
229
|
-
setTimeout(() => {
|
|
230
|
-
// Send ready to any origin initially
|
|
231
|
-
window.parent.postMessage(
|
|
232
|
-
{ type: MessageType.READY, payload: { success: true } },
|
|
233
|
-
'*'
|
|
234
|
-
)
|
|
235
|
-
}, 100)
|
|
236
|
-
})
|
|
237
|
-
|
|
238
|
-
// Log errors
|
|
239
|
-
window.addEventListener('error', (event) => {
|
|
240
|
-
console.error('[Iframe] Runtime error:', event.error)
|
|
241
|
-
sendToParent(MessageType.ERROR, {
|
|
242
|
-
message: event.error?.message || 'Unknown error',
|
|
243
|
-
stack: event.error?.stack
|
|
244
|
-
})
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
window.addEventListener('unhandledrejection', (event) => {
|
|
248
|
-
console.error('[Iframe] Unhandled promise rejection:', event.reason)
|
|
249
|
-
sendToParent(MessageType.ERROR, {
|
|
250
|
-
message: event.reason?.message || 'Unhandled promise rejection',
|
|
251
|
-
stack: event.reason?.stack
|
|
252
|
-
})
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
console.log('[Iframe] PayNext Checkout iframe initialized')
|
|
256
|
-
</script>
|
|
257
|
-
</body>
|
|
258
|
-
</html>
|
|
259
|
-
|