@paynext/sdk 0.0.163 → 0.0.164

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,14 +352,18 @@ 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;
359
- mount(containerId: string, config: PayNextConfig): Promise<void>;
361
+ mount(containerId: string, config: PayNextConfigExtended): Promise<void>;
360
362
  unmount(): Promise<void>;
361
- updateConfig(config: any): Promise<void>;
362
- static preload(envType: 'develop' | 'staging' | 'sandbox' | 'production'): Promise<void>;
363
+ updateConfig(config: Partial<PayNextConfigExtended>): Promise<void>;
364
+ static preload(envType: 'develop' | 'staging' | 'sandbox' | 'production', options?: {
365
+ iframeMode?: boolean;
366
+ }): Promise<void>;
363
367
  }
364
368
 
365
369
  export declare interface PayNextConfig {
@@ -379,6 +383,15 @@ export declare interface PayNextConfig {
379
383
  _themeExplicit?: boolean;
380
384
  }
381
385
 
386
+ declare interface PayNextConfigExtended extends PayNextConfig {
387
+ /**
388
+ * Enable PCI-compliant iframe mode
389
+ * @default false
390
+ * @description When true, checkout will be rendered in isolated iframe for better PCI compliance
391
+ */
392
+ iframeMode?: boolean;
393
+ }
394
+
382
395
  export declare const PayNextSDK: {
383
396
  preload: typeof PayNextCheckout.preload;
384
397
  };
package/dist/index.es.js CHANGED
@@ -1,47 +1,211 @@
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 l = "https://cdn-sdk-dev.paynext.com/checkout.html", h = "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 u {
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" ? l : h;
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" ? l : h, 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 y = "https://cdn-sdk-dev.paynext.com/index.cdn.js", g = "https://cdn-sdk.paynext.com/index.cdn.js";
169
+ let r = null, d = null;
170
+ async function m(o) {
171
+ if (d)
172
+ return d;
173
+ if (r)
174
+ return r;
175
+ const t = o?.toLowerCase()?.includes("develop") || o?.toLowerCase()?.includes("staging") ? "develop" : "production";
176
+ return r = new Promise((e, n) => {
13
177
  if (typeof window > "u") {
14
- s(new Error("PayNext SDK can only be loaded in browser environment"));
178
+ n(new Error("PayNext SDK can only be loaded in browser environment"));
15
179
  return;
16
180
  }
17
181
  if (window.PayNextSDK) {
18
- console.log("[PayNext CDN] SDK already loaded from cache"), a = window.PayNextSDK, e(a);
182
+ console.log("[PayNext CDN] SDK already loaded from cache"), d = window.PayNextSDK, e(d);
19
183
  return;
20
184
  }
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;
185
+ const i = document.createElement("script");
186
+ i.src = t === "develop" ? y : g, i.crossOrigin = "*", i.async = !0, i.onload = () => {
187
+ const a = window.PayNextSDK;
188
+ if (!a) {
189
+ 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"));
190
+ return;
191
+ }
192
+ d = a, e(a);
193
+ }, i.onerror = (a) => {
194
+ 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"));
195
+ }, document.head.appendChild(i);
196
+ }), r;
35
197
  }
36
- class h {
198
+ class C {
37
199
  constructor() {
38
- d(this, "cdnInstance", null);
39
- d(this, "initPromise", null);
200
+ s(this, "cdnInstance", null);
201
+ s(this, "iframeInstance", null);
202
+ s(this, "initPromise", null);
203
+ s(this, "mode", "direct");
40
204
  }
41
205
  // initialize
42
- async initialize(n) {
206
+ async initialize(t) {
43
207
  try {
44
- if (this.initPromise = await c(n), !this.initPromise.PayNextCheckout)
208
+ if (this.initPromise = await m(t), !this.initPromise.PayNextCheckout)
45
209
  throw new Error("PayNextCheckout not found in CDN module");
46
210
  this.cdnInstance = new this.initPromise.PayNextCheckout();
47
211
  } catch (e) {
@@ -55,31 +219,35 @@ class h {
55
219
  if (!this.cdnInstance)
56
220
  throw new Error("SDK instance not created");
57
221
  }
58
- // mount
59
- async mount(n, e) {
60
- return await this.initialize(e.environment), this.waitForReady(), this.cdnInstance?.mount(n, e);
222
+ // mount with iframe mode support
223
+ async mount(t, e) {
224
+ 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));
61
225
  }
62
- // unmount
226
+ // unmount with mode detection
63
227
  async unmount() {
228
+ if (this.mode === "iframe" && this.iframeInstance)
229
+ return this.iframeInstance.unmount();
64
230
  if (this.waitForReady(), this.cdnInstance?.unmount)
65
231
  return this.cdnInstance.unmount();
66
232
  }
67
- // update config
68
- async updateConfig(n) {
233
+ // update config with mode detection
234
+ async updateConfig(t) {
235
+ if (this.mode === "iframe" && this.iframeInstance)
236
+ return this.iframeInstance.updateConfig(t);
69
237
  if (this.waitForReady(), this.cdnInstance?.updateConfig)
70
- return this.cdnInstance.updateConfig(n);
238
+ return this.cdnInstance.updateConfig(t);
71
239
  }
72
240
  // preload (optional optimization)
73
- static async preload(n) {
74
- await c(n);
241
+ static async preload(t, e) {
242
+ e?.iframeMode ? await u.preload(t) : await m(t);
75
243
  }
76
244
  }
77
- const m = {
78
- preload: h.preload
245
+ const P = {
246
+ preload: C.preload
79
247
  };
80
- var y = /* @__PURE__ */ ((t) => (t.PAYPAL = "PAYPAL", t.APPLE_PAY = "APPLEPAY", t.GOOGLE_PAY = "GPAY", t.CARD = "CARD", t.VENMO = "VENMO", t))(y || {});
248
+ var x = /* @__PURE__ */ ((o) => (o.PAYPAL = "PAYPAL", o.APPLE_PAY = "APPLEPAY", o.GOOGLE_PAY = "GPAY", o.CARD = "CARD", o.VENMO = "VENMO", o))(x || {});
81
249
  export {
82
- h as PayNextCheckout,
83
- m as PayNextSDK,
84
- y as PaymentMethod
250
+ C as PayNextCheckout,
251
+ P as PayNextSDK,
252
+ x as PaymentMethod
85
253
  };
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 P=Object.defineProperty;var k=(a,s,c)=>s in a?P(a,s,{enumerable:!0,configurable:!0,writable:!0,value:c}):a[s]=c;var r=(a,s,c)=>k(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 m{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(),u={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(u,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 u=setTimeout(()=>{o(new Error("Iframe load timeout"))},1e4);this.iframe.onload=()=>{clearTimeout(u),i()},this.iframe.onerror=()=>{clearTimeout(u),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="https://cdn-sdk-dev.paynext.com/index.cdn.js",C="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"?g:C,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 m),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 m.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.PayNextSDK=x,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.164",
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",