@paypercut/checkout-js 1.0.14 → 1.0.16

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
@@ -56,19 +56,19 @@ pnpm add @paypercut/checkout-js
56
56
 
57
57
  ```html
58
58
  <!-- jsDelivr (recommended with SRI) -->
59
- <script src="https://cdn.jsdelivr.net/npm/@paypercut/checkout-js@1.0.14/dist/paypercut-checkout.iife.min.js"
59
+ <script src="https://cdn.jsdelivr.net/npm/@paypercut/checkout-js@1.0.16/dist/paypercut-checkout.iife.min.js"
60
60
  integrity="sha384-..."
61
61
  crossorigin="anonymous"></script>
62
62
 
63
63
  <!-- or UNPKG -->
64
- <script src="https://unpkg.com/@paypercut/checkout-js@1.0.14/dist/paypercut-checkout.iife.min.js"></script>
64
+ <script src="https://unpkg.com/@paypercut/checkout-js@1.0.16/dist/paypercut-checkout.iife.min.js"></script>
65
65
  ```
66
66
 
67
67
  ---
68
68
 
69
69
  ## Quick Start
70
70
 
71
- This returns a checkout session ID like `CHK_12345`.
71
+ This returns a checkout session ID like `01KB23M9EC960C50G3AH14FTTT`.
72
72
 
73
73
  ### 1. Embed the Checkout
74
74
 
@@ -79,7 +79,7 @@ import { PaypercutCheckout } from '@paypercut/checkout-js';
79
79
 
80
80
  // Initialize the checkout
81
81
  const checkout = PaypercutCheckout({
82
- id: 'CHK_12345', // Your checkout session ID from step 1
82
+ id: '01KB23M9EC960C50G3AH14FTTT', // Your checkout session ID from step 1
83
83
  containerId: '#checkout' // CSS selector or HTMLElement
84
84
  });
85
85
 
@@ -122,7 +122,7 @@ Creates a new checkout instance.
122
122
 
123
123
  | Option | Type | Required | Default | Description |
124
124
  |------------------|------|----------|---------|----------------------------------------------------------------------------------------------------------------------------|
125
- | `id` | `string` | Yes | — | Checkout session identifier (e.g., `CHK_12345`) |
125
+ | `id` | `string` | Yes | — | Checkout session identifier (e.g., `01KB23M9EC960C50G3AH14FTTT`) |
126
126
  | `containerId` | `string \| HTMLElement` | Yes | — | CSS selector or element where iframe mounts |
127
127
  | `locale` | `string` | No | `'auto'` | Locale for checkout UI. Options: `'auto'`, `'en'`, `'en-GB'`, `'bg'`, `'bg-BG'` |
128
128
  | `lang` | `string` | No | `'auto'` | Locale for checkout UI. Options: `'auto'`, `'en'`, `'en-GB'`, `'bg'`, `'bg-BG'` |
@@ -130,6 +130,8 @@ Creates a new checkout instance.
130
130
  | `wallet_options` | `string[]` | No | `['apple_pay', 'google_pay']` | Digital wallet options. Pass `[]` to disable all wallets |
131
131
  | `form_only` | `boolean` | No | `false` | Show only payment form (no Pay Now button - use external button with `submit()`) |
132
132
  | `validate_form` | `boolean` | No | `false` | This indicates that Google Pay/Apple Pay flow to proceed you need to confirm form validation. For EMBEDDED checkouts only) |
133
+ | `appearance` | `object` | No | `undefined` | Appearance configuration for the checkout UI |
134
+ | `appearance.preset` | `'modal' \| 'inline'` | No | `undefined` | Controls checkout layout preset. `'modal'` shows the order summary (TotalCard) and header inside the iframe — use when rendering in a modal/dialog. `'inline'` hides the TotalCard — use when the merchant renders their own order summary outside the checkout. |
133
135
 
134
136
  #### Examples
135
137
 
@@ -137,7 +139,7 @@ Creates a new checkout instance.
137
139
 
138
140
  ```typescript
139
141
  const checkout = PaypercutCheckout({
140
- id: 'CHK_12345',
142
+ id: '01KB23M9EC960C50G3AH14FTTT',
141
143
  containerId: '#checkout-container'
142
144
  });
143
145
  ```
@@ -146,14 +148,17 @@ const checkout = PaypercutCheckout({
146
148
 
147
149
  ```typescript
148
150
  const checkout = PaypercutCheckout({
149
- id: 'CHK_12345',
151
+ id: '01KB23M9EC960C50G3AH14FTTT',
150
152
  containerId: '#checkout-container',
151
153
  locale: 'en', // 'auto' | 'en' | 'en-GB' | 'bg' | 'bg-BG'
152
154
  lang: 'en', // 'auto' | 'en' | 'en-GB' | 'bg' | 'bg-BG'
153
155
  ui_mode: 'embedded', // 'hosted' | 'embedded'
154
156
  wallet_options: ['apple_pay', 'google_pay'], // Can be empty array [] or contain one/both options
155
157
  form_only: false, // Set true to hide Pay Now button (use external button),
156
- validate_form: true // Set true to require form validation before wallet payment
158
+ validate_form: true, // Set true to require form validation before wallet payment
159
+ appearance: {
160
+ preset: 'modal', // 'modal' | 'inline' — 'modal' shows TotalCard + header, 'inline' hides them
161
+ },
157
162
  });
158
163
  ```
159
164
 
@@ -161,7 +166,7 @@ const checkout = PaypercutCheckout({
161
166
 
162
167
  ```typescript
163
168
  const checkout = PaypercutCheckout({
164
- id: 'CHK_12345',
169
+ id: '01KB23M9EC960C50G3AH14FTTT',
165
170
  containerId: '#checkout-container',
166
171
  wallet_options: [] // No Apple Pay or Google Pay buttons
167
172
  });
@@ -171,7 +176,7 @@ const checkout = PaypercutCheckout({
171
176
 
172
177
  ```typescript
173
178
  const checkout = PaypercutCheckout({
174
- id: 'CHK_12345',
179
+ id: '01KB23M9EC960C50G3AH14FTTT',
175
180
  containerId: '#checkout-container',
176
181
  wallet_options: ['apple_pay'] // Only Apple Pay, no Google Pay
177
182
  });
@@ -181,7 +186,7 @@ const checkout = PaypercutCheckout({
181
186
 
182
187
  ```typescript
183
188
  const checkout = PaypercutCheckout({
184
- id: 'CHK_12345',
189
+ id: '01KB23M9EC960C50G3AH14FTTT',
185
190
  containerId: '#checkout-container',
186
191
  form_only: true // No Pay Now button inside checkout
187
192
  });
@@ -277,7 +282,7 @@ Subscribe to events using the `on()` method. You can use string event names or t
277
282
  **Using string event names:**
278
283
 
279
284
  ```ts
280
- const checkout = PaypercutCheckout({ id: 'CHK_12345', containerId: '#checkout' });
285
+ const checkout = PaypercutCheckout({ id: '01KB23M9EC960C50G3AH14FTTT', containerId: '#checkout' });
281
286
 
282
287
  checkout.on('loaded', () => {
283
288
  console.log('Checkout loaded');
@@ -305,7 +310,7 @@ checkout.on('expired', () => {
305
310
  ```ts
306
311
  import { PaypercutCheckout, SdkEvent } from '@paypercut/checkout-js';
307
312
 
308
- const checkout = PaypercutCheckout({ id: 'CHK_12345', containerId: '#checkout' });
313
+ const checkout = PaypercutCheckout({ id: '01KB23M9EC960C50G3AH14FTTT', containerId: '#checkout' });
309
314
 
310
315
  checkout.on(SdkEvent.Loaded, () => {
311
316
  console.log('Checkout loaded');
@@ -452,7 +457,7 @@ checkout.failFormValidation('apple_pay', [
452
457
  import { PaypercutCheckout, SdkEvent } from '@paypercut/checkout-js';
453
458
 
454
459
  const checkout = PaypercutCheckout({
455
- id: 'CHK_12345',
460
+ id: '01KB23M9EC960C50G3AH14FTTT',
456
461
  containerId: '#checkout',
457
462
  wallet_options: ['apple_pay', 'google_pay']
458
463
  });
@@ -633,7 +638,7 @@ type ApiErrorPayload =
633
638
 
634
639
  ```json
635
640
  {
636
- "checkoutId": "CHK_12345",
641
+ "checkoutId": "01KB23M9EC960C50G3AH14FTTT",
637
642
  "code": "card_validation_error",
638
643
  "message": "Card details are incomplete or invalid",
639
644
  "status_code": 400,
@@ -696,28 +701,28 @@ The SDK forwards whatever Hosted Checkout sends for 3DS events. Shapes may evolv
696
701
  // threeds_started
697
702
  {
698
703
  type: 'THREEDS_START_FLOW',
699
- checkoutId: 'CHK_12345',
704
+ checkoutId: '01KB23M9EC960C50G3AH14FTTT',
700
705
  // additional context as provided by Hosted Checkout (e.g., method, acsUrl)
701
706
  }
702
707
 
703
708
  // threeds_complete
704
709
  {
705
710
  type: 'THREEDS_COMPLETE',
706
- checkoutId: 'CHK_12345',
711
+ checkoutId: '01KB23M9EC960C50G3AH14FTTT',
707
712
  // authentication result context (e.g., status: 'Y' | 'A' | 'C' | 'D')
708
713
  }
709
714
 
710
715
  // threeds_canceled
711
716
  {
712
717
  type: 'THREEDS_CANCELED',
713
- checkoutId: 'CHK_12345',
718
+ checkoutId: '01KB23M9EC960C50G3AH14FTTT',
714
719
  }
715
720
 
716
721
  // threeds_error (non-terminal)
717
722
  // Note: terminal failures will also be emitted on `error` with ApiErrorPayload
718
723
  {
719
724
  type: 'THREEDS_ERROR',
720
- checkoutId: 'CHK_12345',
725
+ checkoutId: '01KB23M9EC960C50G3AH14FTTT',
721
726
  error?: ApiErrorPayload,
722
727
  }
723
728
  ```
@@ -738,10 +743,10 @@ Tip: Prefer subscribing with the SdkEvent enum for stronger typing.
738
743
  <body>
739
744
  <div id="checkout"></div>
740
745
 
741
- <script src="https://cdn.jsdelivr.net/npm/@paypercut/checkout-js@1.0.14/dist/paypercut-checkout.iife.min.js"></script>
746
+ <script src="https://cdn.jsdelivr.net/npm/@paypercut/checkout-js@1.0.16/dist/paypercut-checkout.iife.min.js"></script>
742
747
  <script>
743
748
  const checkout = PaypercutCheckout({
744
- id: 'CHK_12345',
749
+ id: '01KB23M9EC960C50G3AH14FTTT',
745
750
  containerId: '#checkout',
746
751
  locale: 'en',
747
752
  ui_mode: 'embedded',
@@ -769,7 +774,7 @@ Tip: Prefer subscribing with the SdkEvent enum for stronger typing.
769
774
  import { PaypercutCheckout } from '@paypercut/checkout-js';
770
775
 
771
776
  const checkout = PaypercutCheckout({
772
- id: 'CHK_12345',
777
+ id: '01KB23M9EC960C50G3AH14FTTT',
773
778
  containerId: '#checkout',
774
779
  locale: 'auto',
775
780
  ui_mode: 'embedded',
@@ -1001,7 +1006,7 @@ The SDK automatically resizes the iframe to match the checkout content height. T
1001
1006
 
1002
1007
  ```javascript
1003
1008
  const checkout = PaypercutCheckout({
1004
- id: 'CHK_12345',
1009
+ id: '01KB23M9EC960C50G3AH14FTTT',
1005
1010
  containerId: '#checkout-mount'
1006
1011
  });
1007
1012
  checkout.render();
@@ -1084,7 +1089,7 @@ async function loadCheckout() {
1084
1089
  // Load when user clicks pay button
1085
1090
  payButton.addEventListener('click', async () => {
1086
1091
  const PaypercutCheckout = await loadCheckout();
1087
- const checkout = PaypercutCheckout({ id: 'CHK_12345' });
1092
+ const checkout = PaypercutCheckout({ id: '01KB23M9EC960C50G3AH14FTTT' });
1088
1093
  checkout.render();
1089
1094
  });
1090
1095
  ```
package/dist/index.cjs CHANGED
@@ -84,7 +84,7 @@ class Emitter {
84
84
  * Production configuration (for merchants)
85
85
  */
86
86
  const productionConfig = {
87
- version: "1.0.14",
87
+ version: "1.0.16",
88
88
  defaultCheckoutOrigin: 'https://buy.paypercut.io',
89
89
  allowedOrigins: [
90
90
  'https://buy.paypercut.io',
package/dist/index.mjs CHANGED
@@ -80,7 +80,7 @@ class Emitter {
80
80
  * Production configuration (for merchants)
81
81
  */
82
82
  const productionConfig = {
83
- version: "1.0.14",
83
+ version: "1.0.16",
84
84
  defaultCheckoutOrigin: 'https://buy.paypercut.io',
85
85
  allowedOrigins: [
86
86
  'https://buy.paypercut.io',
@@ -1,2 +1,2 @@
1
- var PaypercutCheckout=function(){"use strict";class e{constructor(){this.handlers=new Map}on(e,t){return this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t),()=>this.off(e,t)}once(e,t){const s=(...o)=>{t(...o),this.off(e,s)};return this.on(e,s)}off(e,t){this.handlers.get(e)?.delete(t)}emit(e,...t){this.handlers.get(e)?.forEach(s=>{try{s(...t)}catch(t){console.error(`[Emitter] Error in ${e} handler:`,t)}})}clear(){this.handlers.clear()}}const t={version:"1.0.14",defaultCheckoutOrigin:"https://buy.paypercut.io",allowedOrigins:["https://buy.paypercut.io"]};function s(e){return t.defaultCheckoutOrigin}const o=new Set(["bg","bg-BG","en","en-GB","el","el-GR","ro","ro-RO","hr","hr-HR","pl","pl-PL","cs","cs-CZ","sl","sl-SI","sk","sk-SK"]);function i(e){return e&&"auto"!==e?o.has(e)?e:(console.warn(`[PaypercutCheckout] Locale "${e}" is not supported. Falling back to "en".`),"en"):"en"}var r,a,n,h;function c(e){return Object.values(a).includes(e)}function d(e){return Object.values(n).includes(e)}function l(e){var t;if(e)return t=e,Object.values(r).includes(t)?e:void console.warn(`[PaypercutCheckout] Invalid ui_mode: "${e}". Valid options: ${Object.values(r).join(", ")}`)}!function(e){e.EMBEDDED="embedded"}(r||(r={})),function(e){e.CARD="card"}(a||(a={})),function(e){e.APPLE_PAY="apple_pay",e.GOOGLE_PAY="google_pay"}(n||(n={})),function(e){e.Loaded="loaded",e.Success="success",e.Error="error",e.Expired="expired",e.Resize="resize",e.ThreeDSComplete="threeds_complete",e.ThreeDSError="threeds_error",e.ThreeDSCanceled="threeds_canceled",e.ThreeDSStarted="threeds_started",e.FormValidation="form_validation"}(h||(h={}));class m{constructor(t){this.options=t,this.emitter=new e,this.mounted=!1,this.destroyed=!1,this.iframe=null,this.threeDSModal=null,this.threeDSIframe=null,this.messageHandler=this.onMessage.bind(this),window.addEventListener("message",this.messageHandler)}buildSrc(){const e=s(this.options.hostedCheckoutUrl),t=new URL(`/c/${this.options.id}`,e);if(this.options.locale){const e=i(this.options.locale);t.searchParams.set("locale",e)}if(this.options.lang){const e=i(this.options.lang);t.searchParams.set("lang",e)}{const e=l(this.options.ui_mode??r.EMBEDDED);e&&t.searchParams.set("ui_mode",e)}if(this.options.payment_methods&&this.options.payment_methods.length>0){(function(e){const t=[];for(const s of e)c(s)?t.push(s):console.warn(`[PaypercutCheckout] Invalid payment method: "${s}". Skipping.`);return 0===t.length&&(console.warn('[PaypercutCheckout] No valid payment methods provided. Defaulting to "card".'),t.push(a.CARD)),t})(this.options.payment_methods).forEach(e=>{t.searchParams.append("payment_methods",e)})}if(void 0!==this.options.wallet_options)if(0===this.options.wallet_options.length)t.searchParams.set("wallet_options",null);else{(function(e){const t=[];for(const s of e)d(s)?t.push(s):console.warn(`[PaypercutCheckout] Invalid wallet option: "${s}". Skipping.`);return t})(this.options.wallet_options).forEach(e=>{t.searchParams.append("wallet_options",e)})}return this.options.appearance?.preset&&t.searchParams.set("preset",this.options.appearance.preset),void 0!==this.options.form_only&&t.searchParams.set("form_only",String(this.options.form_only)),void 0!==this.options.validate_form&&t.searchParams.set("validate_form",String(this.options.validate_form)),t.toString()}getContainer(){const e="string"==typeof this.options.containerId?document.querySelector(this.options.containerId):this.options.containerId;if(!e)throw new Error(`Container not found: ${this.options.containerId}`);return e}onMessage(e){if(s=e.origin,!t.allowedOrigins.includes(s))return;var s;const o=e.data;if(o&&"object"==typeof o&&"type"in o&&(!o.checkoutId||o.checkoutId===this.options.id))switch(o.type){case"CHECKOUT_LOADED":this.emitter.emit(h.Loaded);break;case"CHECKOUT_SUCCESS":const{payment_method:e={}}=o;this.emitter.emit(h.Success,{payment_method:e});break;case"CHECKOUT_ERROR":this.emitter.emit(h.Error,(o&&o.error)??o);break;case"CHECKOUT_EXPIRED":this.emitter.emit(h.Expired);break;case"CHECKOUT_RESIZE":this.emitter.emit(h.Resize,o.height),this.handleResize(o.height);break;case"THREEDS_START_FLOW":this.show3DSModal(o),this.emitter.emit(h.ThreeDSStarted);break;case"THREEDS_READY":this.handle3DSReady();break;case"THREEDS_COMPLETE":this.postToIframe(o),this.close3DSModal(),this.emitter.emit(h.ThreeDSComplete);break;case"THREEDS_CANCELED":this.postToIframe(o),this.close3DSModal(),this.emitter.emit(h.ThreeDSCanceled);break;case"THREEDS_ERROR":this.postToIframe(o),this.close3DSModal(),this.emitter.emit(h.ThreeDSError,o.error);break;case"FORM_VALIDATION":this.emitter.emit(h.FormValidation,{checkoutId:o.checkoutId,wallet:o.wallet})}}render(){if(!this.mounted)try{const e=this.getContainer();this.iframe=document.createElement("iframe"),this.iframe.id="paypercut-checkout-iframe",this.iframe.src=this.buildSrc(),this.iframe.allow="payment *; clipboard-write",this.iframe.setAttribute("frameborder","0"),this.iframe.setAttribute("allowpaymentrequest","true"),this.iframe.setAttribute("sandbox","allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox"),Object.assign(this.iframe.style,{width:"100%",height:"100%",border:"none",display:"block"}),e.appendChild(this.iframe),this.mounted=!0}catch(e){throw console.error("[PaypercutCheckout] Failed to render:",e),e}}submit(){if(this.mounted)try{this.postToIframe({type:"START_PROCESSING",checkoutId:this.options.id})}catch(e){throw console.error("[PaypercutCheckout] Failed to submit payment:",e),e}}postToIframe(e){if(!this.iframe?.contentWindow)return void console.error("[PaypercutCheckout] Cannot post message: iframe not mounted");const t=s(this.options.hostedCheckoutUrl);this.iframe.contentWindow.postMessage(e,t)}handleResize(e){!this.iframe||"number"!=typeof e||e<=0||(this.iframe.style.height=`${e}px`)}show3DSModal(e){this.threeDSModal=document.createElement("div"),this.threeDSModal.id="paypercut-3ds-modal",Object.assign(this.threeDSModal.style,{position:"fixed",top:"0",left:"0",width:"100%",height:"100%",display:"flex",alignItems:"center",justifyContent:"center",zIndex:"999999",background:"rgba(0, 0, 0, 0.4)"}),this.threeDSIframe=document.createElement("iframe");const t=s(this.options.hostedCheckoutUrl),o=new URL(`/c/${this.options.id}/threeds`,t);o.searchParams.set("sessionId",e.sessionId),o.searchParams.set("step",e.step),e.challengeUrl&&o.searchParams.set("challengeUrl",e.challengeUrl),e.acsTransactionId&&o.searchParams.set("acsTransactionId",e.acsTransactionId),e.threeDSVersion&&o.searchParams.set("threeDSVersion",e.threeDSVersion),o.searchParams.set("liveMode",String(e.liveMode??!1)),this.threeDSIframe.src=o.toString(),this.threeDSIframe.allow="payment *",this.threeDSIframe.setAttribute("frameborder","0"),Object.assign(this.threeDSIframe.style,{minWidth:"400px",minHeight:"400px",border:"none",borderRadius:"8px",display:"block",background:"transparent"}),this.threeDSModal.appendChild(this.threeDSIframe),document.body.appendChild(this.threeDSModal),this.pending3DSData=e}handle3DSReady(){if(!this.pending3DSData||!this.threeDSIframe?.contentWindow)return void console.error("[PaypercutCheckout] No pending 3DS data or iframe not ready");const e=s(this.options.hostedCheckoutUrl);this.threeDSIframe.contentWindow.postMessage({type:"THREEDS_INIT",checkoutId:this.options.id},e)}close3DSModal(){this.threeDSModal&&(this.threeDSModal.remove(),this.threeDSModal=null),this.threeDSIframe=null,delete this.pending3DSData}destroy(){if(!this.destroyed){if(this.iframe)try{this.iframe.remove(),this.iframe=null}catch(e){console.error("[PaypercutCheckout] Error removing iframe:",e)}this.close3DSModal(),this.mounted=!1,this.destroyed=!0,window.removeEventListener("message",this.messageHandler),this.emitter.clear()}}on(e,t){return this.emitter.on(e,t)}once(e,t){return this.emitter.once(e,t)}off(e,t){this.emitter.off(e,t)}isMounted(){return this.mounted}completeFormValidation(e){this.mounted?this.postToIframe({type:"FORM_VALIDATION_COMPLETED",checkoutId:this.options.id,wallet:e,status:"success"}):console.warn("[PaypercutCheckout] Cannot complete form validation: not mounted")}failFormValidation(e,t){this.mounted?this.postToIframe({type:"FORM_VALIDATION_COMPLETED",checkoutId:this.options.id,wallet:e,status:"failed",errors:t}):console.warn("[PaypercutCheckout] Cannot fail form validation: not mounted")}}const p=function(e){return new m(e)};return p.version=t.version,p}();
1
+ var PaypercutCheckout=function(){"use strict";class e{constructor(){this.handlers=new Map}on(e,t){return this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t),()=>this.off(e,t)}once(e,t){const s=(...o)=>{t(...o),this.off(e,s)};return this.on(e,s)}off(e,t){this.handlers.get(e)?.delete(t)}emit(e,...t){this.handlers.get(e)?.forEach(s=>{try{s(...t)}catch(t){console.error(`[Emitter] Error in ${e} handler:`,t)}})}clear(){this.handlers.clear()}}const t={version:"1.0.16",defaultCheckoutOrigin:"https://buy.paypercut.io",allowedOrigins:["https://buy.paypercut.io"]};function s(e){return t.defaultCheckoutOrigin}const o=new Set(["bg","bg-BG","en","en-GB","el","el-GR","ro","ro-RO","hr","hr-HR","pl","pl-PL","cs","cs-CZ","sl","sl-SI","sk","sk-SK"]);function i(e){return e&&"auto"!==e?o.has(e)?e:(console.warn(`[PaypercutCheckout] Locale "${e}" is not supported. Falling back to "en".`),"en"):"en"}var r,a,n,h;function c(e){return Object.values(a).includes(e)}function d(e){return Object.values(n).includes(e)}function l(e){var t;if(e)return t=e,Object.values(r).includes(t)?e:void console.warn(`[PaypercutCheckout] Invalid ui_mode: "${e}". Valid options: ${Object.values(r).join(", ")}`)}!function(e){e.EMBEDDED="embedded"}(r||(r={})),function(e){e.CARD="card"}(a||(a={})),function(e){e.APPLE_PAY="apple_pay",e.GOOGLE_PAY="google_pay"}(n||(n={})),function(e){e.Loaded="loaded",e.Success="success",e.Error="error",e.Expired="expired",e.Resize="resize",e.ThreeDSComplete="threeds_complete",e.ThreeDSError="threeds_error",e.ThreeDSCanceled="threeds_canceled",e.ThreeDSStarted="threeds_started",e.FormValidation="form_validation"}(h||(h={}));class m{constructor(t){this.options=t,this.emitter=new e,this.mounted=!1,this.destroyed=!1,this.iframe=null,this.threeDSModal=null,this.threeDSIframe=null,this.messageHandler=this.onMessage.bind(this),window.addEventListener("message",this.messageHandler)}buildSrc(){const e=s(this.options.hostedCheckoutUrl),t=new URL(`/c/${this.options.id}`,e);if(this.options.locale){const e=i(this.options.locale);t.searchParams.set("locale",e)}if(this.options.lang){const e=i(this.options.lang);t.searchParams.set("lang",e)}{const e=l(this.options.ui_mode??r.EMBEDDED);e&&t.searchParams.set("ui_mode",e)}if(this.options.payment_methods&&this.options.payment_methods.length>0){(function(e){const t=[];for(const s of e)c(s)?t.push(s):console.warn(`[PaypercutCheckout] Invalid payment method: "${s}". Skipping.`);return 0===t.length&&(console.warn('[PaypercutCheckout] No valid payment methods provided. Defaulting to "card".'),t.push(a.CARD)),t})(this.options.payment_methods).forEach(e=>{t.searchParams.append("payment_methods",e)})}if(void 0!==this.options.wallet_options)if(0===this.options.wallet_options.length)t.searchParams.set("wallet_options",null);else{(function(e){const t=[];for(const s of e)d(s)?t.push(s):console.warn(`[PaypercutCheckout] Invalid wallet option: "${s}". Skipping.`);return t})(this.options.wallet_options).forEach(e=>{t.searchParams.append("wallet_options",e)})}return this.options.appearance?.preset&&t.searchParams.set("preset",this.options.appearance.preset),void 0!==this.options.form_only&&t.searchParams.set("form_only",String(this.options.form_only)),void 0!==this.options.validate_form&&t.searchParams.set("validate_form",String(this.options.validate_form)),t.toString()}getContainer(){const e="string"==typeof this.options.containerId?document.querySelector(this.options.containerId):this.options.containerId;if(!e)throw new Error(`Container not found: ${this.options.containerId}`);return e}onMessage(e){if(s=e.origin,!t.allowedOrigins.includes(s))return;var s;const o=e.data;if(o&&"object"==typeof o&&"type"in o&&(!o.checkoutId||o.checkoutId===this.options.id))switch(o.type){case"CHECKOUT_LOADED":this.emitter.emit(h.Loaded);break;case"CHECKOUT_SUCCESS":const{payment_method:e={}}=o;this.emitter.emit(h.Success,{payment_method:e});break;case"CHECKOUT_ERROR":this.emitter.emit(h.Error,(o&&o.error)??o);break;case"CHECKOUT_EXPIRED":this.emitter.emit(h.Expired);break;case"CHECKOUT_RESIZE":this.emitter.emit(h.Resize,o.height),this.handleResize(o.height);break;case"THREEDS_START_FLOW":this.show3DSModal(o),this.emitter.emit(h.ThreeDSStarted);break;case"THREEDS_READY":this.handle3DSReady();break;case"THREEDS_COMPLETE":this.postToIframe(o),this.close3DSModal(),this.emitter.emit(h.ThreeDSComplete);break;case"THREEDS_CANCELED":this.postToIframe(o),this.close3DSModal(),this.emitter.emit(h.ThreeDSCanceled);break;case"THREEDS_ERROR":this.postToIframe(o),this.close3DSModal(),this.emitter.emit(h.ThreeDSError,o.error);break;case"FORM_VALIDATION":this.emitter.emit(h.FormValidation,{checkoutId:o.checkoutId,wallet:o.wallet})}}render(){if(!this.mounted)try{const e=this.getContainer();this.iframe=document.createElement("iframe"),this.iframe.id="paypercut-checkout-iframe",this.iframe.src=this.buildSrc(),this.iframe.allow="payment *; clipboard-write",this.iframe.setAttribute("frameborder","0"),this.iframe.setAttribute("allowpaymentrequest","true"),this.iframe.setAttribute("sandbox","allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox"),Object.assign(this.iframe.style,{width:"100%",height:"100%",border:"none",display:"block"}),e.appendChild(this.iframe),this.mounted=!0}catch(e){throw console.error("[PaypercutCheckout] Failed to render:",e),e}}submit(){if(this.mounted)try{this.postToIframe({type:"START_PROCESSING",checkoutId:this.options.id})}catch(e){throw console.error("[PaypercutCheckout] Failed to submit payment:",e),e}}postToIframe(e){if(!this.iframe?.contentWindow)return void console.error("[PaypercutCheckout] Cannot post message: iframe not mounted");const t=s(this.options.hostedCheckoutUrl);this.iframe.contentWindow.postMessage(e,t)}handleResize(e){!this.iframe||"number"!=typeof e||e<=0||(this.iframe.style.height=`${e}px`)}show3DSModal(e){this.threeDSModal=document.createElement("div"),this.threeDSModal.id="paypercut-3ds-modal",Object.assign(this.threeDSModal.style,{position:"fixed",top:"0",left:"0",width:"100%",height:"100%",display:"flex",alignItems:"center",justifyContent:"center",zIndex:"999999",background:"rgba(0, 0, 0, 0.4)"}),this.threeDSIframe=document.createElement("iframe");const t=s(this.options.hostedCheckoutUrl),o=new URL(`/c/${this.options.id}/threeds`,t);o.searchParams.set("sessionId",e.sessionId),o.searchParams.set("step",e.step),e.challengeUrl&&o.searchParams.set("challengeUrl",e.challengeUrl),e.acsTransactionId&&o.searchParams.set("acsTransactionId",e.acsTransactionId),e.threeDSVersion&&o.searchParams.set("threeDSVersion",e.threeDSVersion),o.searchParams.set("liveMode",String(e.liveMode??!1)),this.threeDSIframe.src=o.toString(),this.threeDSIframe.allow="payment *",this.threeDSIframe.setAttribute("frameborder","0"),Object.assign(this.threeDSIframe.style,{minWidth:"400px",minHeight:"400px",border:"none",borderRadius:"8px",display:"block",background:"transparent"}),this.threeDSModal.appendChild(this.threeDSIframe),document.body.appendChild(this.threeDSModal),this.pending3DSData=e}handle3DSReady(){if(!this.pending3DSData||!this.threeDSIframe?.contentWindow)return void console.error("[PaypercutCheckout] No pending 3DS data or iframe not ready");const e=s(this.options.hostedCheckoutUrl);this.threeDSIframe.contentWindow.postMessage({type:"THREEDS_INIT",checkoutId:this.options.id},e)}close3DSModal(){this.threeDSModal&&(this.threeDSModal.remove(),this.threeDSModal=null),this.threeDSIframe=null,delete this.pending3DSData}destroy(){if(!this.destroyed){if(this.iframe)try{this.iframe.remove(),this.iframe=null}catch(e){console.error("[PaypercutCheckout] Error removing iframe:",e)}this.close3DSModal(),this.mounted=!1,this.destroyed=!0,window.removeEventListener("message",this.messageHandler),this.emitter.clear()}}on(e,t){return this.emitter.on(e,t)}once(e,t){return this.emitter.once(e,t)}off(e,t){this.emitter.off(e,t)}isMounted(){return this.mounted}completeFormValidation(e){this.mounted?this.postToIframe({type:"FORM_VALIDATION_COMPLETED",checkoutId:this.options.id,wallet:e,status:"success"}):console.warn("[PaypercutCheckout] Cannot complete form validation: not mounted")}failFormValidation(e,t){this.mounted?this.postToIframe({type:"FORM_VALIDATION_COMPLETED",checkoutId:this.options.id,wallet:e,status:"failed",errors:t}):console.warn("[PaypercutCheckout] Cannot fail form validation: not mounted")}}const p=function(e){return new m(e)};return p.version=t.version,p}();
2
2
  //# sourceMappingURL=paypercut-checkout.iife.min.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paypercut/checkout-js",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "Lightweight JavaScript SDK for Paypercut Checkout",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",