@paynext/sdk 0.0.164 → 0.0.166
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 +46 -3
- package/dist/index.d.ts +25 -1
- package/dist/index.es.js +13 -9
- package/dist/index.umd.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript SDK for integrating PayNext payment processing with full type safety and multiple payment methods support.
|
|
4
4
|
|
|
5
|
+
## 🛡️ NEW: PCI-Compliant Iframe Mode
|
|
6
|
+
|
|
7
|
+
Enable iframe mode for enhanced PCI compliance by adding one parameter:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
await checkout.mount('checkout-container', {
|
|
11
|
+
clientToken: 'your-token',
|
|
12
|
+
environment: 'production',
|
|
13
|
+
apiVersion: 'v1',
|
|
14
|
+
iframeMode: true, // 🛡️ Isolates payment data in secure iframe
|
|
15
|
+
})
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Benefits:** Reduced PCI scope, isolated processing, XSS protection. See [Iframe Quick Start](./IFRAME_QUICKSTART.md) for details.
|
|
19
|
+
|
|
5
20
|
## Installation
|
|
6
21
|
|
|
7
22
|
```bash
|
|
@@ -101,10 +116,11 @@ export const CheckoutComponent: FC<Readonly<IProps>> = (props) => {
|
|
|
101
116
|
## Configuration
|
|
102
117
|
|
|
103
118
|
```typescript
|
|
104
|
-
interface PayNextConfig {
|
|
119
|
+
interface PayNextConfigExtended extends PayNextConfig {
|
|
105
120
|
clientToken: string
|
|
106
121
|
apiVersion: string
|
|
107
|
-
environment: 'sandbox' | 'production'
|
|
122
|
+
environment: 'develop' | 'staging' | 'sandbox' | 'production'
|
|
123
|
+
iframeMode?: boolean // 🛡️ Enable PCI-compliant iframe mode (default: false)
|
|
108
124
|
variant?: 'default' | 'compact'
|
|
109
125
|
locale?: Locale
|
|
110
126
|
translate?: CheckoutTranslate
|
|
@@ -194,4 +210,31 @@ The SDK supports recent versions of all major browsers:
|
|
|
194
210
|
|
|
195
211
|
## Security
|
|
196
212
|
|
|
197
|
-
PCI
|
|
213
|
+
### PCI Compliance
|
|
214
|
+
|
|
215
|
+
**Iframe Mode (Recommended)**: Enables PCI-compliant iframe isolation for reduced compliance scope.
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
await checkout.mount('checkout-container', {
|
|
219
|
+
iframeMode: true, // Isolates payment data processing
|
|
220
|
+
// ... other config
|
|
221
|
+
})
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Content Security Policy
|
|
225
|
+
|
|
226
|
+
For iframe mode, add to your HTML:
|
|
227
|
+
|
|
228
|
+
```html
|
|
229
|
+
<meta http-equiv="Content-Security-Policy"
|
|
230
|
+
content="frame-src https://cdn-sdk.paynext.com https://cdn-sdk-dev.paynext.com;">
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Security Features
|
|
234
|
+
|
|
235
|
+
- PCI DSS Level 1 compliant
|
|
236
|
+
- End-to-end encryption (TLS 1.3)
|
|
237
|
+
- Tokenization of sensitive data
|
|
238
|
+
- No sensitive payment data stored locally
|
|
239
|
+
- Optional iframe isolation for reduced PCI scope
|
|
240
|
+
- Sandbox iframe security attributes (when iframe mode enabled)
|
package/dist/index.d.ts
CHANGED
|
@@ -366,6 +366,26 @@ export declare class PayNextCheckout {
|
|
|
366
366
|
}): Promise<void>;
|
|
367
367
|
}
|
|
368
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
|
+
mount(containerId: string, config: PayNextConfig): Promise<void>;
|
|
384
|
+
unmount(): Promise<void>;
|
|
385
|
+
updateConfig(config: Partial<PayNextConfig>): Promise<void>;
|
|
386
|
+
static preload(envType: 'develop' | 'staging' | 'sandbox' | 'production'): Promise<void>;
|
|
387
|
+
}
|
|
388
|
+
|
|
369
389
|
export declare interface PayNextConfig {
|
|
370
390
|
clientToken: string;
|
|
371
391
|
environment: TEnvironment;
|
|
@@ -383,7 +403,7 @@ export declare interface PayNextConfig {
|
|
|
383
403
|
_themeExplicit?: boolean;
|
|
384
404
|
}
|
|
385
405
|
|
|
386
|
-
declare interface PayNextConfigExtended extends PayNextConfig {
|
|
406
|
+
export declare interface PayNextConfigExtended extends PayNextConfig {
|
|
387
407
|
/**
|
|
388
408
|
* Enable PCI-compliant iframe mode
|
|
389
409
|
* @default false
|
|
@@ -396,6 +416,10 @@ export declare const PayNextSDK: {
|
|
|
396
416
|
preload: typeof PayNextCheckout.preload;
|
|
397
417
|
};
|
|
398
418
|
|
|
419
|
+
export declare const PayNextSDKIframe: {
|
|
420
|
+
preload: typeof PayNextCheckoutIframe.preload;
|
|
421
|
+
};
|
|
422
|
+
|
|
399
423
|
export declare interface StylesConfig {
|
|
400
424
|
Input?: InputStyles;
|
|
401
425
|
SubmitButton?: ISubmitButtonStyles;
|
package/dist/index.es.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
var f = Object.defineProperty;
|
|
2
2
|
var p = (o, t, e) => t in o ? f(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
|
|
3
3
|
var s = (o, t, e) => p(o, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
-
const
|
|
4
|
+
const h = "https://cdn-sdk-dev.paynext.com/checkout.html", u = "https://cdn-sdk.paynext.com/checkout.html", w = {
|
|
5
5
|
develop: "https://cdn-sdk-dev.paynext.com",
|
|
6
6
|
production: "https://cdn-sdk.paynext.com"
|
|
7
7
|
};
|
|
8
|
-
class
|
|
8
|
+
class l {
|
|
9
9
|
constructor() {
|
|
10
10
|
s(this, "iframe", null);
|
|
11
11
|
s(this, "container", null);
|
|
@@ -77,7 +77,7 @@ class u {
|
|
|
77
77
|
createIframe(t) {
|
|
78
78
|
const e = t.environment?.toLowerCase()?.includes("develop") || t.environment?.toLowerCase()?.includes("staging") ? "develop" : "production";
|
|
79
79
|
this.allowedOrigin = w[e];
|
|
80
|
-
const n = document.createElement("iframe"), i = e === "develop" ?
|
|
80
|
+
const n = document.createElement("iframe"), i = e === "develop" ? h : u;
|
|
81
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
82
|
"allow-scripts",
|
|
83
83
|
// required for SDK execution
|
|
@@ -159,13 +159,15 @@ class u {
|
|
|
159
159
|
}
|
|
160
160
|
// preload iframe (optional optimization)
|
|
161
161
|
static async preload(t) {
|
|
162
|
-
const n = (t?.toLowerCase()?.includes("develop") || t?.toLowerCase()?.includes("staging") ? "develop" : "production") === "develop" ?
|
|
162
|
+
const n = (t?.toLowerCase()?.includes("develop") || t?.toLowerCase()?.includes("staging") ? "develop" : "production") === "develop" ? h : u, i = document.createElement("link");
|
|
163
163
|
i.rel = "preconnect", i.href = new URL(n).origin, document.head.appendChild(i);
|
|
164
164
|
const a = document.createElement("link");
|
|
165
165
|
a.rel = "dns-prefetch", a.href = new URL(n).origin, document.head.appendChild(a);
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
-
const
|
|
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";
|
|
169
171
|
let r = null, d = null;
|
|
170
172
|
async function m(o) {
|
|
171
173
|
if (d)
|
|
@@ -221,7 +223,7 @@ class C {
|
|
|
221
223
|
}
|
|
222
224
|
// mount with iframe mode support
|
|
223
225
|
async mount(t, e) {
|
|
224
|
-
return e.iframeMode === !0 ? (this.mode = "iframe", this.iframeInstance || (this.iframeInstance = new
|
|
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));
|
|
225
227
|
}
|
|
226
228
|
// unmount with mode detection
|
|
227
229
|
async unmount() {
|
|
@@ -239,15 +241,17 @@ class C {
|
|
|
239
241
|
}
|
|
240
242
|
// preload (optional optimization)
|
|
241
243
|
static async preload(t, e) {
|
|
242
|
-
e?.iframeMode ? await
|
|
244
|
+
e?.iframeMode ? await l.preload(t) : await m(t);
|
|
243
245
|
}
|
|
244
246
|
}
|
|
245
|
-
const
|
|
247
|
+
const I = {
|
|
246
248
|
preload: C.preload
|
|
247
249
|
};
|
|
248
250
|
var x = /* @__PURE__ */ ((o) => (o.PAYPAL = "PAYPAL", o.APPLE_PAY = "APPLEPAY", o.GOOGLE_PAY = "GPAY", o.CARD = "CARD", o.VENMO = "VENMO", o))(x || {});
|
|
249
251
|
export {
|
|
250
252
|
C as PayNextCheckout,
|
|
251
|
-
|
|
253
|
+
l as PayNextCheckoutIframe,
|
|
254
|
+
I as PayNextSDK,
|
|
255
|
+
P as PayNextSDKIframe,
|
|
252
256
|
x as PaymentMethod
|
|
253
257
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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
|
|
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"})}));
|