@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 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: any): Promise<void>;
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 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) => {
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
- s(new Error("PayNext SDK can only be loaded in browser environment"));
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"), a = window.PayNextSDK, e(a);
184
+ console.log("[PayNext CDN] SDK already loaded from cache"), d = window.PayNextSDK, e(d);
19
185
  return;
20
186
  }
21
- const o = document.createElement("script");
22
- o.src = n === "develop" ? w : P, o.crossOrigin = "*", o.async = !0, o.onload = () => {
23
- setTimeout(() => {
24
- const r = window.PayNextSDK;
25
- if (!r) {
26
- 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"));
27
- return;
28
- }
29
- a = r, e(r);
30
- }, 10);
31
- }, o.onerror = (r) => {
32
- 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"));
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 h {
200
+ class C {
37
201
  constructor() {
38
- d(this, "cdnInstance", null);
39
- d(this, "initPromise", null);
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(n) {
208
+ async initialize(t) {
43
209
  try {
44
- if (this.initPromise = await c(n), !this.initPromise.PayNextCheckout)
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(n, e) {
60
- return await this.initialize(e.environment), this.waitForReady(), this.cdnInstance?.mount(n, e);
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(n) {
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(n);
240
+ return this.cdnInstance.updateConfig(t);
71
241
  }
72
242
  // preload (optional optimization)
73
- static async preload(n) {
74
- await c(n);
243
+ static async preload(t, e) {
244
+ e?.iframeMode ? await l.preload(t) : await m(t);
75
245
  }
76
246
  }
77
- const m = {
78
- preload: h.preload
247
+ const I = {
248
+ preload: C.preload
79
249
  };
80
- var y = /* @__PURE__ */ ((t) => (t.PAYPAL = "PAYPAL", t.APPLE_PAY = "APPLEPAY", t.GOOGLE_PAY = "GPAY", t.CARD = "CARD", t.VENMO = "VENMO", t))(y || {});
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
- h as PayNextCheckout,
83
- m as PayNextSDK,
84
- y as PaymentMethod
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(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 m=(e,n,a)=>n in e?w(e,n,{enumerable:!0,configurable:!0,writable:!0,value:a}):e[n]=a;var l=(e,n,a)=>m(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,u)=>{if(typeof window>"u"){u(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=()=>{setTimeout(()=>{const c=window.PayNextSDK;if(!c){console.error("[PayNext CDN] PayNextSDK not found in window after load"),d=null,document.head.removeChild(r),u(new Error("PayNextSDK not found in global scope after loading"));return}s=c,i(c)},10)},r.onerror=c=>{console.error("[PayNext CDN] Failed to load script:",c),d=null,document.head.removeChild(r),u(new Error("Failed to load PayNext SDK script from CDN"))},document.head.appendChild(r)}),d}class y{constructor(){l(this,"cdnInstance",null);l(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"})}));
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.163",
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",