@paynext/sdk 0.0.163 → 0.0.165
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/README.md +7 -0
- package/dist/index.d.ts +38 -1
- package/dist/index.es.js +220 -48
- package/dist/index.umd.js +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -120,6 +120,13 @@ interface LoadedResult {
|
|
|
120
120
|
success: boolean
|
|
121
121
|
error?: CheckoutError
|
|
122
122
|
}
|
|
123
|
+
|
|
124
|
+
interface AttemptResult {
|
|
125
|
+
paymentMethod: PaymentMethod
|
|
126
|
+
cardType: string
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
Use `result.cardType` inside `onCheckoutAttempt` to track the backend-reported brand (`'visa'`, `'maestro'`, etc.) for card and wallet payments. PayPal and Venmo attempts emit an empty string because no card brand is involved.
|
|
123
130
|
```
|
|
124
131
|
|
|
125
132
|
### Add a Submit Button Icon
|
package/dist/index.d.ts
CHANGED
|
@@ -352,13 +352,37 @@ declare enum PaymentStatus {
|
|
|
352
352
|
|
|
353
353
|
export declare class PayNextCheckout {
|
|
354
354
|
private cdnInstance;
|
|
355
|
+
private iframeInstance;
|
|
355
356
|
private initPromise;
|
|
357
|
+
private mode;
|
|
356
358
|
constructor();
|
|
357
359
|
private initialize;
|
|
358
360
|
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;
|
|
359
383
|
mount(containerId: string, config: PayNextConfig): Promise<void>;
|
|
360
384
|
unmount(): Promise<void>;
|
|
361
|
-
updateConfig(config:
|
|
385
|
+
updateConfig(config: Partial<PayNextConfig>): Promise<void>;
|
|
362
386
|
static preload(envType: 'develop' | 'staging' | 'sandbox' | 'production'): Promise<void>;
|
|
363
387
|
}
|
|
364
388
|
|
|
@@ -379,10 +403,23 @@ export declare interface PayNextConfig {
|
|
|
379
403
|
_themeExplicit?: boolean;
|
|
380
404
|
}
|
|
381
405
|
|
|
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
|
+
|
|
382
415
|
export declare const PayNextSDK: {
|
|
383
416
|
preload: typeof PayNextCheckout.preload;
|
|
384
417
|
};
|
|
385
418
|
|
|
419
|
+
export declare const PayNextSDKIframe: {
|
|
420
|
+
preload: typeof PayNextCheckoutIframe.preload;
|
|
421
|
+
};
|
|
422
|
+
|
|
386
423
|
export declare interface StylesConfig {
|
|
387
424
|
Input?: InputStyles;
|
|
388
425
|
SubmitButton?: ISubmitButtonStyles;
|
package/dist/index.es.js
CHANGED
|
@@ -1,47 +1,213 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
var f = Object.defineProperty;
|
|
2
|
+
var p = (o, t, e) => t in o ? f(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
|
|
3
|
+
var s = (o, t, e) => p(o, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
const h = "https://cdn-sdk-dev.paynext.com/checkout.html", u = "https://cdn-sdk.paynext.com/checkout.html", w = {
|
|
5
|
+
develop: "https://cdn-sdk-dev.paynext.com",
|
|
6
|
+
production: "https://cdn-sdk.paynext.com"
|
|
7
|
+
};
|
|
8
|
+
class l {
|
|
9
|
+
constructor() {
|
|
10
|
+
s(this, "iframe", null);
|
|
11
|
+
s(this, "container", null);
|
|
12
|
+
s(this, "config", null);
|
|
13
|
+
s(this, "messageHandlers", /* @__PURE__ */ new Map());
|
|
14
|
+
s(this, "pendingRequests", /* @__PURE__ */ new Map());
|
|
15
|
+
s(this, "isReady", !1);
|
|
16
|
+
s(this, "allowedOrigin", "");
|
|
17
|
+
this.handleMessage = this.handleMessage.bind(this);
|
|
18
|
+
}
|
|
19
|
+
// generate unique request ID
|
|
20
|
+
generateRequestId() {
|
|
21
|
+
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
22
|
+
}
|
|
23
|
+
// send message to iframe
|
|
24
|
+
sendMessage(t, e) {
|
|
25
|
+
return new Promise((n, i) => {
|
|
26
|
+
if (!this.iframe || !this.iframe.contentWindow) {
|
|
27
|
+
i(new Error("Iframe not initialized"));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const a = this.generateRequestId(), c = { type: t, payload: e, requestId: a };
|
|
31
|
+
this.pendingRequests.set(a, { resolve: n, reject: i }), setTimeout(() => {
|
|
32
|
+
this.pendingRequests.has(a) && (this.pendingRequests.delete(a), i(new Error(`Request timeout: ${t}`)));
|
|
33
|
+
}, 3e4), this.iframe.contentWindow.postMessage(c, this.allowedOrigin);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// handle messages from iframe
|
|
37
|
+
handleMessage(t) {
|
|
38
|
+
if (t.origin !== this.allowedOrigin) {
|
|
39
|
+
console.warn("[PayNext Iframe] Message from unauthorized origin:", t.origin);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const e = t.data;
|
|
43
|
+
if (!(!e.type || !e.type.startsWith("paynext:"))) {
|
|
44
|
+
if (e.requestId && this.pendingRequests.has(e.requestId)) {
|
|
45
|
+
const { resolve: n } = this.pendingRequests.get(e.requestId);
|
|
46
|
+
this.pendingRequests.delete(e.requestId), n(e.payload);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
switch (e.type) {
|
|
50
|
+
case "paynext:ready":
|
|
51
|
+
this.isReady = !0, console.log("[PayNext Iframe] SDK ready");
|
|
52
|
+
break;
|
|
53
|
+
case "paynext:loaded":
|
|
54
|
+
this.config?.onCheckoutLoaded && this.config.onCheckoutLoaded(e.payload);
|
|
55
|
+
break;
|
|
56
|
+
case "paynext:attempt":
|
|
57
|
+
this.config?.onCheckoutAttempt && this.config.onCheckoutAttempt(e.payload);
|
|
58
|
+
break;
|
|
59
|
+
case "paynext:complete":
|
|
60
|
+
this.config?.onCheckoutComplete && this.config.onCheckoutComplete(e.payload);
|
|
61
|
+
break;
|
|
62
|
+
case "paynext:fail":
|
|
63
|
+
this.config?.onCheckoutFail && this.config.onCheckoutFail(e.payload);
|
|
64
|
+
break;
|
|
65
|
+
case "paynext:error":
|
|
66
|
+
console.error("[PayNext Iframe] Error:", e.payload);
|
|
67
|
+
break;
|
|
68
|
+
case "paynext:resize":
|
|
69
|
+
this.iframe && e.payload?.height && (this.iframe.style.height = `${e.payload.height}px`);
|
|
70
|
+
break;
|
|
71
|
+
default:
|
|
72
|
+
console.warn("[PayNext Iframe] Unknown message type:", e.type);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// create and configure iframe
|
|
77
|
+
createIframe(t) {
|
|
78
|
+
const e = t.environment?.toLowerCase()?.includes("develop") || t.environment?.toLowerCase()?.includes("staging") ? "develop" : "production";
|
|
79
|
+
this.allowedOrigin = w[e];
|
|
80
|
+
const n = document.createElement("iframe"), i = e === "develop" ? h : u;
|
|
81
|
+
return 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(
|
|
82
|
+
"allow-scripts",
|
|
83
|
+
// required for SDK execution
|
|
84
|
+
"allow-same-origin",
|
|
85
|
+
// required for postMessage
|
|
86
|
+
"allow-forms",
|
|
87
|
+
// required for form submission
|
|
88
|
+
"allow-popups",
|
|
89
|
+
// required for 3DS redirects
|
|
90
|
+
"allow-popups-to-escape-sandbox",
|
|
91
|
+
// required for payment popups
|
|
92
|
+
"allow-top-navigation-by-user-activation"
|
|
93
|
+
// required for redirects
|
|
94
|
+
), n.setAttribute("referrerpolicy", "strict-origin-when-cross-origin"), n.setAttribute("importance", "high"), n;
|
|
95
|
+
}
|
|
96
|
+
// wait for iframe to be ready
|
|
97
|
+
async waitForReady(t = 1e4) {
|
|
98
|
+
const e = Date.now();
|
|
99
|
+
for (; !this.isReady; ) {
|
|
100
|
+
if (Date.now() - e > t)
|
|
101
|
+
throw new Error("Iframe initialization timeout");
|
|
102
|
+
await new Promise((n) => setTimeout(n, 100));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// mount checkout in iframe
|
|
106
|
+
async mount(t, e) {
|
|
107
|
+
try {
|
|
108
|
+
const n = document.getElementById(t);
|
|
109
|
+
if (!n)
|
|
110
|
+
throw new Error(`Container element "${t}" not found`);
|
|
111
|
+
this.container = n, this.config = e, this.iframe && await this.unmount(), this.iframe = this.createIframe(e), window.addEventListener("message", this.handleMessage), n.innerHTML = "", n.appendChild(this.iframe), await new Promise((i, a) => {
|
|
112
|
+
const c = setTimeout(() => {
|
|
113
|
+
a(new Error("Iframe load timeout"));
|
|
114
|
+
}, 1e4);
|
|
115
|
+
this.iframe.onload = () => {
|
|
116
|
+
clearTimeout(c), i();
|
|
117
|
+
}, this.iframe.onerror = () => {
|
|
118
|
+
clearTimeout(c), a(new Error("Iframe failed to load"));
|
|
119
|
+
};
|
|
120
|
+
}), await this.waitForReady(), await this.sendMessage("paynext:mount", {
|
|
121
|
+
config: {
|
|
122
|
+
...e,
|
|
123
|
+
// remove callbacks from config sent to iframe
|
|
124
|
+
onCheckoutLoaded: void 0,
|
|
125
|
+
onCheckoutAttempt: void 0,
|
|
126
|
+
onCheckoutComplete: void 0,
|
|
127
|
+
onCheckoutFail: void 0
|
|
128
|
+
}
|
|
129
|
+
}), console.log("[PayNext Iframe] Checkout mounted successfully");
|
|
130
|
+
} catch (n) {
|
|
131
|
+
throw console.error("[PayNext Iframe] Mount failed:", n), await this.unmount(), n;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// unmount checkout
|
|
135
|
+
async unmount() {
|
|
136
|
+
try {
|
|
137
|
+
this.iframe && (this.isReady && await this.sendMessage(
|
|
138
|
+
"paynext:unmount"
|
|
139
|
+
/* UNMOUNT */
|
|
140
|
+
).catch(() => {
|
|
141
|
+
}), 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");
|
|
142
|
+
} catch (t) {
|
|
143
|
+
console.error("[PayNext Iframe] Unmount failed:", t);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// update configuration
|
|
147
|
+
async updateConfig(t) {
|
|
148
|
+
if (!this.isReady)
|
|
149
|
+
throw new Error("Iframe not ready");
|
|
150
|
+
this.config = { ...this.config, ...t }, await this.sendMessage("paynext:updateConfig", {
|
|
151
|
+
config: {
|
|
152
|
+
...t,
|
|
153
|
+
onCheckoutLoaded: void 0,
|
|
154
|
+
onCheckoutAttempt: void 0,
|
|
155
|
+
onCheckoutComplete: void 0,
|
|
156
|
+
onCheckoutFail: void 0
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
// preload iframe (optional optimization)
|
|
161
|
+
static async preload(t) {
|
|
162
|
+
const n = (t?.toLowerCase()?.includes("develop") || t?.toLowerCase()?.includes("staging") ? "develop" : "production") === "develop" ? h : u, i = document.createElement("link");
|
|
163
|
+
i.rel = "preconnect", i.href = new URL(n).origin, document.head.appendChild(i);
|
|
164
|
+
const a = document.createElement("link");
|
|
165
|
+
a.rel = "dns-prefetch", a.href = new URL(n).origin, document.head.appendChild(a);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const P = {
|
|
169
|
+
preload: l.preload
|
|
170
|
+
}, y = "https://cdn-sdk-dev.paynext.com/index.cdn.js", g = "https://cdn-sdk.paynext.com/index.cdn.js";
|
|
171
|
+
let r = null, d = null;
|
|
172
|
+
async function m(o) {
|
|
173
|
+
if (d)
|
|
174
|
+
return d;
|
|
175
|
+
if (r)
|
|
176
|
+
return r;
|
|
177
|
+
const t = o?.toLowerCase()?.includes("develop") || o?.toLowerCase()?.includes("staging") ? "develop" : "production";
|
|
178
|
+
return r = new Promise((e, n) => {
|
|
13
179
|
if (typeof window > "u") {
|
|
14
|
-
|
|
180
|
+
n(new Error("PayNext SDK can only be loaded in browser environment"));
|
|
15
181
|
return;
|
|
16
182
|
}
|
|
17
183
|
if (window.PayNextSDK) {
|
|
18
|
-
console.log("[PayNext CDN] SDK already loaded from cache"),
|
|
184
|
+
console.log("[PayNext CDN] SDK already loaded from cache"), d = window.PayNextSDK, e(d);
|
|
19
185
|
return;
|
|
20
186
|
}
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
}, document.head.appendChild(o);
|
|
34
|
-
}), i;
|
|
187
|
+
const i = document.createElement("script");
|
|
188
|
+
i.src = t === "develop" ? y : g, i.crossOrigin = "*", i.async = !0, i.onload = () => {
|
|
189
|
+
const a = window.PayNextSDK;
|
|
190
|
+
if (!a) {
|
|
191
|
+
console.error("[PayNext CDN] PayNextSDK not found in window after load"), r = null, document.head.removeChild(i), n(new Error("PayNextSDK not found in global scope after loading"));
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
d = a, e(a);
|
|
195
|
+
}, i.onerror = (a) => {
|
|
196
|
+
console.error("[PayNext CDN] Failed to load script:", a), r = null, document.head.removeChild(i), n(new Error("Failed to load PayNext SDK script from CDN"));
|
|
197
|
+
}, document.head.appendChild(i);
|
|
198
|
+
}), r;
|
|
35
199
|
}
|
|
36
|
-
class
|
|
200
|
+
class C {
|
|
37
201
|
constructor() {
|
|
38
|
-
|
|
39
|
-
|
|
202
|
+
s(this, "cdnInstance", null);
|
|
203
|
+
s(this, "iframeInstance", null);
|
|
204
|
+
s(this, "initPromise", null);
|
|
205
|
+
s(this, "mode", "direct");
|
|
40
206
|
}
|
|
41
207
|
// initialize
|
|
42
|
-
async initialize(
|
|
208
|
+
async initialize(t) {
|
|
43
209
|
try {
|
|
44
|
-
if (this.initPromise = await
|
|
210
|
+
if (this.initPromise = await m(t), !this.initPromise.PayNextCheckout)
|
|
45
211
|
throw new Error("PayNextCheckout not found in CDN module");
|
|
46
212
|
this.cdnInstance = new this.initPromise.PayNextCheckout();
|
|
47
213
|
} catch (e) {
|
|
@@ -55,31 +221,37 @@ class h {
|
|
|
55
221
|
if (!this.cdnInstance)
|
|
56
222
|
throw new Error("SDK instance not created");
|
|
57
223
|
}
|
|
58
|
-
// mount
|
|
59
|
-
async mount(
|
|
60
|
-
return await this.initialize(e.environment), this.waitForReady(), this.cdnInstance?.mount(
|
|
224
|
+
// mount with iframe mode support
|
|
225
|
+
async mount(t, e) {
|
|
226
|
+
return e.iframeMode === !0 ? (this.mode = "iframe", this.iframeInstance || (this.iframeInstance = new l()), this.iframeInstance.mount(t, e)) : (this.mode = "direct", await this.initialize(e.environment), this.waitForReady(), this.cdnInstance?.mount(t, e));
|
|
61
227
|
}
|
|
62
|
-
// unmount
|
|
228
|
+
// unmount with mode detection
|
|
63
229
|
async unmount() {
|
|
230
|
+
if (this.mode === "iframe" && this.iframeInstance)
|
|
231
|
+
return this.iframeInstance.unmount();
|
|
64
232
|
if (this.waitForReady(), this.cdnInstance?.unmount)
|
|
65
233
|
return this.cdnInstance.unmount();
|
|
66
234
|
}
|
|
67
|
-
// update config
|
|
68
|
-
async updateConfig(
|
|
235
|
+
// update config with mode detection
|
|
236
|
+
async updateConfig(t) {
|
|
237
|
+
if (this.mode === "iframe" && this.iframeInstance)
|
|
238
|
+
return this.iframeInstance.updateConfig(t);
|
|
69
239
|
if (this.waitForReady(), this.cdnInstance?.updateConfig)
|
|
70
|
-
return this.cdnInstance.updateConfig(
|
|
240
|
+
return this.cdnInstance.updateConfig(t);
|
|
71
241
|
}
|
|
72
242
|
// preload (optional optimization)
|
|
73
|
-
static async preload(
|
|
74
|
-
await
|
|
243
|
+
static async preload(t, e) {
|
|
244
|
+
e?.iframeMode ? await l.preload(t) : await m(t);
|
|
75
245
|
}
|
|
76
246
|
}
|
|
77
|
-
const
|
|
78
|
-
preload:
|
|
247
|
+
const I = {
|
|
248
|
+
preload: C.preload
|
|
79
249
|
};
|
|
80
|
-
var
|
|
250
|
+
var x = /* @__PURE__ */ ((o) => (o.PAYPAL = "PAYPAL", o.APPLE_PAY = "APPLEPAY", o.GOOGLE_PAY = "GPAY", o.CARD = "CARD", o.VENMO = "VENMO", o))(x || {});
|
|
81
251
|
export {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
252
|
+
C as PayNextCheckout,
|
|
253
|
+
l as PayNextCheckoutIframe,
|
|
254
|
+
I as PayNextSDK,
|
|
255
|
+
P as PayNextSDKIframe,
|
|
256
|
+
x as PaymentMethod
|
|
85
257
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(a,s){typeof exports=="object"&&typeof module<"u"?s(exports):typeof define=="function"&&define.amd?define(["exports"],s):(a=typeof globalThis<"u"?globalThis:a||self,s(a["PayNext SDK"]={}))})(this,(function(a){"use strict";var k=Object.defineProperty;var I=(a,s,c)=>s in a?k(a,s,{enumerable:!0,configurable:!0,writable:!0,value:c}):a[s]=c;var r=(a,s,c)=>I(a,typeof s!="symbol"?s+"":s,c);const s="https://cdn-sdk-dev.paynext.com/checkout.html",c="https://cdn-sdk.paynext.com/checkout.html",w={develop:"https://cdn-sdk-dev.paynext.com",production:"https://cdn-sdk.paynext.com"};class u{constructor(){r(this,"iframe",null);r(this,"container",null);r(this,"config",null);r(this,"messageHandlers",new Map);r(this,"pendingRequests",new Map);r(this,"isReady",!1);r(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((n,i)=>{if(!this.iframe||!this.iframe.contentWindow){i(new Error("Iframe not initialized"));return}const o=this.generateRequestId(),m={type:t,payload:e,requestId:o};this.pendingRequests.set(o,{resolve:n,reject:i}),setTimeout(()=>{this.pendingRequests.has(o)&&(this.pendingRequests.delete(o),i(new Error(`Request timeout: ${t}`)))},3e4),this.iframe.contentWindow.postMessage(m,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:n}=this.pendingRequests.get(e.requestId);this.pendingRequests.delete(e.requestId),n(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){const e=t.environment?.toLowerCase()?.includes("develop")||t.environment?.toLowerCase()?.includes("staging")?"develop":"production";this.allowedOrigin=w[e];const n=document.createElement("iframe"),i=e==="develop"?s:c;return 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("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(n=>setTimeout(n,100))}}async mount(t,e){try{const n=document.getElementById(t);if(!n)throw new Error(`Container element "${t}" not found`);this.container=n,this.config=e,this.iframe&&await this.unmount(),this.iframe=this.createIframe(e),window.addEventListener("message",this.handleMessage),n.innerHTML="",n.appendChild(this.iframe),await new Promise((i,o)=>{const m=setTimeout(()=>{o(new Error("Iframe load timeout"))},1e4);this.iframe.onload=()=>{clearTimeout(m),i()},this.iframe.onerror=()=>{clearTimeout(m),o(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(n){throw console.error("[PayNext Iframe] Mount failed:",n),await this.unmount(),n}}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 n=(t?.toLowerCase()?.includes("develop")||t?.toLowerCase()?.includes("staging")?"develop":"production")==="develop"?s:c,i=document.createElement("link");i.rel="preconnect",i.href=new URL(n).origin,document.head.appendChild(i);const o=document.createElement("link");o.rel="dns-prefetch",o.href=new URL(n).origin,document.head.appendChild(o)}}const g={preload:u.preload},C="https://cdn-sdk-dev.paynext.com/index.cdn.js",P="https://cdn-sdk.paynext.com/index.cdn.js";let l=null,h=null;async function f(d){if(h)return h;if(l)return l;const t=d?.toLowerCase()?.includes("develop")||d?.toLowerCase()?.includes("staging")?"develop":"production";return l=new Promise((e,n)=>{if(typeof window>"u"){n(new Error("PayNext SDK can only be loaded in browser environment"));return}if(window.PayNextSDK){console.log("[PayNext CDN] SDK already loaded from cache"),h=window.PayNextSDK,e(h);return}const i=document.createElement("script");i.src=t==="develop"?C:P,i.crossOrigin="*",i.async=!0,i.onload=()=>{const o=window.PayNextSDK;if(!o){console.error("[PayNext CDN] PayNextSDK not found in window after load"),l=null,document.head.removeChild(i),n(new Error("PayNextSDK not found in global scope after loading"));return}h=o,e(o)},i.onerror=o=>{console.error("[PayNext CDN] Failed to load script:",o),l=null,document.head.removeChild(i),n(new Error("Failed to load PayNext SDK script from CDN"))},document.head.appendChild(i)}),l}class p{constructor(){r(this,"cdnInstance",null);r(this,"iframeInstance",null);r(this,"initPromise",null);r(this,"mode","direct")}async initialize(t){try{if(this.initPromise=await f(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 u),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 u.preload(t):await f(t)}}const x={preload:p.preload};var y=(d=>(d.PAYPAL="PAYPAL",d.APPLE_PAY="APPLEPAY",d.GOOGLE_PAY="GPAY",d.CARD="CARD",d.VENMO="VENMO",d))(y||{});a.PayNextCheckout=p,a.PayNextCheckoutIframe=u,a.PayNextSDK=x,a.PayNextSDKIframe=g,a.PaymentMethod=y,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paynext/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.165",
|
|
4
4
|
"description": "PayNext SDK - Payment processing with automatic CDN loading",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.es.js",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"scripts": {
|
|
35
35
|
"type-check": "tsc --noEmit",
|
|
36
36
|
"format": "yarn type-check && yarn lint && yarn prettier",
|
|
37
|
-
"preview": "PREVIEW=true vite --host",
|
|
38
|
-
"preview:cdn": "yarn wrangler dev",
|
|
37
|
+
"preview": "PREVIEW=true NODE_ENV=development vite --host",
|
|
39
38
|
"preview-host": "PREVIEW=true yarn build-preview && vite preview --host",
|
|
39
|
+
"preview:cdn": "yarn wrangler dev",
|
|
40
40
|
"build-preview": "PREVIEW=true yarn build",
|
|
41
41
|
"build": "tsc -b && vite build",
|
|
42
42
|
"build:cdn": "CDN=true tsc -b && CDN=true vite build",
|