@paypercut/checkout-js 1.0.12 → 1.0.13
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 +183 -10
- package/dist/index.cjs +47 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +34 -3
- package/dist/index.mjs +47 -1
- package/dist/index.mjs.map +1 -1
- package/dist/paypercut-checkout.iife.min.js +1 -1
- package/dist/paypercut-checkout.iife.min.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,6 +17,8 @@ A lightweight, framework-agnostic JavaScript SDK for embedding Paypercut Checkou
|
|
|
17
17
|
- [Quick Start](#quick-start)
|
|
18
18
|
- [API Reference](#api-reference)
|
|
19
19
|
- [Events](#events)
|
|
20
|
+
- [Form Validation for Wallet Payments](#form-validation-for-wallet-payments)
|
|
21
|
+
- [Types](#types)
|
|
20
22
|
- [Usage Examples](#usage-examples)
|
|
21
23
|
- [Vanilla JavaScript](#vanilla-javascript-cdn)
|
|
22
24
|
- [TypeScript / ESM](#typescript--esm)
|
|
@@ -54,12 +56,12 @@ pnpm add @paypercut/checkout-js
|
|
|
54
56
|
|
|
55
57
|
```html
|
|
56
58
|
<!-- jsDelivr (recommended with SRI) -->
|
|
57
|
-
<script src="https://cdn.jsdelivr.net/npm/@paypercut/checkout-js@1.0.
|
|
59
|
+
<script src="https://cdn.jsdelivr.net/npm/@paypercut/checkout-js@1.0.13/dist/paypercut-checkout.iife.min.js"
|
|
58
60
|
integrity="sha384-..."
|
|
59
61
|
crossorigin="anonymous"></script>
|
|
60
62
|
|
|
61
63
|
<!-- or UNPKG -->
|
|
62
|
-
<script src="https://unpkg.com/@paypercut/checkout-js@1.0.
|
|
64
|
+
<script src="https://unpkg.com/@paypercut/checkout-js@1.0.13/dist/paypercut-checkout.iife.min.js"></script>
|
|
63
65
|
```
|
|
64
66
|
|
|
65
67
|
---
|
|
@@ -118,14 +120,15 @@ Creates a new checkout instance.
|
|
|
118
120
|
|
|
119
121
|
#### Options
|
|
120
122
|
|
|
121
|
-
| Option
|
|
122
|
-
|
|
123
|
-
| `id`
|
|
124
|
-
| `containerId`
|
|
125
|
-
| `locale`
|
|
126
|
-
| `
|
|
123
|
+
| Option | Type | Required | Default | Description |
|
|
124
|
+
|------------------|------|----------|---------|-------------|
|
|
125
|
+
| `id` | `string` | Yes | — | Checkout session identifier (e.g., `CHK_12345`) |
|
|
126
|
+
| `containerId` | `string \| HTMLElement` | Yes | — | CSS selector or element where iframe mounts |
|
|
127
|
+
| `locale` | `string` | No | `'auto'` | Locale for checkout UI. Options: `'auto'`, `'en'`, `'en-GB'`, `'bg'`, `'bg-BG'` |
|
|
128
|
+
| `lang` | `string` | No | `'auto'` | Locale for checkout UI. Options: `'auto'`, `'en'`, `'en-GB'`, `'bg'`, `'bg-BG'` |
|
|
129
|
+
| `ui_mode` | `'hosted' \| 'embedded'` | No | `'embedded'` | UI mode for checkout display |
|
|
127
130
|
| `wallet_options` | `string[]` | No | `['apple_pay', 'google_pay']` | Digital wallet options. Pass `[]` to disable all wallets |
|
|
128
|
-
| `form_only`
|
|
131
|
+
| `form_only` | `boolean` | No | `false` | Show only payment form (no Pay Now button - use external button with `submit()`) |
|
|
129
132
|
|
|
130
133
|
#### Examples
|
|
131
134
|
|
|
@@ -145,6 +148,7 @@ const checkout = PaypercutCheckout({
|
|
|
145
148
|
id: 'CHK_12345',
|
|
146
149
|
containerId: '#checkout-container',
|
|
147
150
|
locale: 'en', // 'auto' | 'en' | 'en-GB' | 'bg' | 'bg-BG'
|
|
151
|
+
lang: 'en', // 'auto' | 'en' | 'en-GB' | 'bg' | 'bg-BG'
|
|
148
152
|
ui_mode: 'embedded', // 'hosted' | 'embedded'
|
|
149
153
|
wallet_options: ['apple_pay', 'google_pay'], // Can be empty array [] or contain one/both options
|
|
150
154
|
form_only: false // Set true to hide Pay Now button (use external button)
|
|
@@ -398,6 +402,175 @@ checkout.on('error', (err) => {
|
|
|
398
402
|
- `threeds_error`: forwards `payload.error` when available; otherwise the raw message data.
|
|
399
403
|
- `threeds_*` non-error events: payload is forwarded as-is from Hosted Checkout (shape may evolve).
|
|
400
404
|
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Form Validation for Wallet Payments
|
|
408
|
+
|
|
409
|
+
When using Apple Pay or Google Pay, you may need to validate your own form fields (e.g., email, shipping address) before the wallet payment sheet opens. The SDK provides a `form_validation` event and methods to control this flow.
|
|
410
|
+
|
|
411
|
+
### How It Works
|
|
412
|
+
|
|
413
|
+
1. User clicks Apple Pay or Google Pay button in the checkout
|
|
414
|
+
2. SDK emits `form_validation` event to your code
|
|
415
|
+
3. You validate your form and call either:
|
|
416
|
+
- `completeFormValidation(wallet)` - allows wallet to proceed
|
|
417
|
+
- `failFormValidation(wallet, errors)` - blocks wallet, you show your own errors
|
|
418
|
+
4. If validation passes, the wallet payment sheet opens
|
|
419
|
+
|
|
420
|
+
### Event: `form_validation`
|
|
421
|
+
|
|
422
|
+
| Property | Type | Description |
|
|
423
|
+
|----------|------|-------------|
|
|
424
|
+
| `checkoutId` | `string` | The checkout session ID |
|
|
425
|
+
| `wallet` | `'apple_pay' \| 'google_pay'` | Which wallet button was clicked |
|
|
426
|
+
|
|
427
|
+
### Methods
|
|
428
|
+
|
|
429
|
+
#### `completeFormValidation(wallet)`
|
|
430
|
+
|
|
431
|
+
Call this when your form is valid. The wallet payment sheet will open.
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
checkout.completeFormValidation('google_pay');
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
#### `failFormValidation(wallet, errors?)`
|
|
438
|
+
|
|
439
|
+
Call this when your form has errors. The wallet will not open, and you should display your own error messages.
|
|
440
|
+
|
|
441
|
+
```typescript
|
|
442
|
+
checkout.failFormValidation('apple_pay', [
|
|
443
|
+
{ code: 'invalid_email', message: 'Please enter a valid email address' },
|
|
444
|
+
{ code: 'missing_address', message: 'Shipping address is required' }
|
|
445
|
+
]);
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Basic Example
|
|
449
|
+
|
|
450
|
+
```typescript
|
|
451
|
+
import { PaypercutCheckout, SdkEvent } from '@paypercut/checkout-js';
|
|
452
|
+
|
|
453
|
+
const checkout = PaypercutCheckout({
|
|
454
|
+
id: 'CHK_12345',
|
|
455
|
+
containerId: '#checkout',
|
|
456
|
+
wallet_options: ['apple_pay', 'google_pay']
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
// Handle form validation for wallet payments
|
|
460
|
+
checkout.on(SdkEvent.FormValidation, ({ wallet, checkoutId }) => {
|
|
461
|
+
// Validate your own form fields
|
|
462
|
+
const email = document.getElementById('email').value;
|
|
463
|
+
const isEmailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
464
|
+
|
|
465
|
+
if (isEmailValid) {
|
|
466
|
+
// Form is valid - allow wallet to proceed
|
|
467
|
+
checkout.completeFormValidation(wallet);
|
|
468
|
+
} else {
|
|
469
|
+
// Form has errors - block wallet and show your errors
|
|
470
|
+
document.getElementById('email-error').textContent = 'Please enter a valid email';
|
|
471
|
+
checkout.failFormValidation(wallet, [
|
|
472
|
+
{ code: 'invalid_email', message: 'Please enter a valid email' }
|
|
473
|
+
]);
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
checkout.render();
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### React Example
|
|
481
|
+
|
|
482
|
+
```tsx
|
|
483
|
+
import { useEffect, useRef, useState } from 'react';
|
|
484
|
+
import { PaypercutCheckout, CheckoutInstance, SdkEvent } from '@paypercut/checkout-js';
|
|
485
|
+
|
|
486
|
+
export function CheckoutWithForm({ checkoutId }: { checkoutId: string }) {
|
|
487
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
488
|
+
const checkoutRef = useRef<CheckoutInstance | null>(null);
|
|
489
|
+
const [email, setEmail] = useState('');
|
|
490
|
+
const [emailError, setEmailError] = useState('');
|
|
491
|
+
|
|
492
|
+
useEffect(() => {
|
|
493
|
+
if (!containerRef.current) return;
|
|
494
|
+
|
|
495
|
+
const checkout = PaypercutCheckout({
|
|
496
|
+
id: checkoutId,
|
|
497
|
+
containerId: containerRef.current,
|
|
498
|
+
wallet_options: ['apple_pay', 'google_pay']
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
// Handle wallet form validation
|
|
502
|
+
checkout.on(SdkEvent.FormValidation, ({ wallet }) => {
|
|
503
|
+
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
504
|
+
|
|
505
|
+
if (isValid) {
|
|
506
|
+
setEmailError('');
|
|
507
|
+
checkout.completeFormValidation(wallet);
|
|
508
|
+
} else {
|
|
509
|
+
setEmailError('Please enter a valid email address');
|
|
510
|
+
checkout.failFormValidation(wallet, [
|
|
511
|
+
{ code: 'invalid_email', message: 'Invalid email' }
|
|
512
|
+
]);
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
checkout.on('success', (payload) => {
|
|
517
|
+
console.log('Payment successful:', payload.payment_method);
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
checkout.render();
|
|
521
|
+
checkoutRef.current = checkout;
|
|
522
|
+
|
|
523
|
+
return () => checkout.destroy();
|
|
524
|
+
}, [checkoutId, email]);
|
|
525
|
+
|
|
526
|
+
return (
|
|
527
|
+
<div>
|
|
528
|
+
{/* Your custom form fields */}
|
|
529
|
+
<div>
|
|
530
|
+
<label htmlFor="email">Email</label>
|
|
531
|
+
<input
|
|
532
|
+
id="email"
|
|
533
|
+
type="email"
|
|
534
|
+
value={email}
|
|
535
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
536
|
+
placeholder="your@email.com"
|
|
537
|
+
/>
|
|
538
|
+
{emailError && <span style={{ color: 'red' }}>{emailError}</span>}
|
|
539
|
+
</div>
|
|
540
|
+
|
|
541
|
+
{/* Checkout iframe */}
|
|
542
|
+
<div ref={containerRef} />
|
|
543
|
+
</div>
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Timeout Behavior
|
|
549
|
+
|
|
550
|
+
If you don't respond to the `form_validation` event within 10 seconds, the SDK will:
|
|
551
|
+
1. Emit an `error` event with code `form_validation_timeout`
|
|
552
|
+
2. Block the wallet payment from starting
|
|
553
|
+
|
|
554
|
+
This ensures the checkout doesn't hang indefinitely if the handler is not implemented.
|
|
555
|
+
|
|
556
|
+
### When to Use
|
|
557
|
+
|
|
558
|
+
Use form validation when you have:
|
|
559
|
+
- Custom email/phone fields outside the checkout iframe
|
|
560
|
+
- Shipping address forms that must be filled before payment
|
|
561
|
+
- Terms & conditions checkboxes that must be accepted
|
|
562
|
+
- Any other merchant-side validation requirements
|
|
563
|
+
|
|
564
|
+
If you don't need to validate anything, you can simply auto-approve:
|
|
565
|
+
|
|
566
|
+
```typescript
|
|
567
|
+
checkout.on('form_validation', ({ wallet }) => {
|
|
568
|
+
// No validation needed - always allow wallet to proceed
|
|
569
|
+
checkout.completeFormValidation(wallet);
|
|
570
|
+
});
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
---
|
|
401
574
|
|
|
402
575
|
## Types
|
|
403
576
|
|
|
@@ -562,7 +735,7 @@ Tip: Prefer subscribing with the SdkEvent enum for stronger typing.
|
|
|
562
735
|
<body>
|
|
563
736
|
<div id="checkout"></div>
|
|
564
737
|
|
|
565
|
-
<script src="https://cdn.jsdelivr.net/npm/@paypercut/checkout-js@1.0.
|
|
738
|
+
<script src="https://cdn.jsdelivr.net/npm/@paypercut/checkout-js@1.0.13/dist/paypercut-checkout.iife.min.js"></script>
|
|
566
739
|
<script>
|
|
567
740
|
const checkout = PaypercutCheckout({
|
|
568
741
|
id: 'CHK_12345',
|
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.
|
|
87
|
+
version: "1.0.13",
|
|
88
88
|
defaultCheckoutOrigin: 'https://buy.paypercut.io',
|
|
89
89
|
allowedOrigins: [
|
|
90
90
|
'https://buy.paypercut.io',
|
|
@@ -279,6 +279,7 @@ exports.SdkEvent = void 0;
|
|
|
279
279
|
SdkEvent["ThreeDSError"] = "threeds_error";
|
|
280
280
|
SdkEvent["ThreeDSCanceled"] = "threeds_canceled";
|
|
281
281
|
SdkEvent["ThreeDSStarted"] = "threeds_started";
|
|
282
|
+
SdkEvent["FormValidation"] = "form_validation";
|
|
282
283
|
})(exports.SdkEvent || (exports.SdkEvent = {}));
|
|
283
284
|
|
|
284
285
|
/**
|
|
@@ -309,6 +310,11 @@ class CheckoutImpl {
|
|
|
309
310
|
const normalizedLocale = normalizeLocale(this.options.locale);
|
|
310
311
|
url.searchParams.set('locale', normalizedLocale);
|
|
311
312
|
}
|
|
313
|
+
// Add lang parameter
|
|
314
|
+
if (this.options.lang) {
|
|
315
|
+
const normalizedLocale = normalizeLocale(this.options.lang);
|
|
316
|
+
url.searchParams.set('lang', normalizedLocale);
|
|
317
|
+
}
|
|
312
318
|
// Add ui_mode parameter (default to 'embedded')
|
|
313
319
|
{
|
|
314
320
|
const selected = validateUIMode(this.options.ui_mode ?? exports.UIMode.EMBEDDED);
|
|
@@ -417,6 +423,13 @@ class CheckoutImpl {
|
|
|
417
423
|
this.close3DSModal();
|
|
418
424
|
this.emitter.emit(exports.SdkEvent.ThreeDSError, data.error);
|
|
419
425
|
break;
|
|
426
|
+
case 'FORM_VALIDATION':
|
|
427
|
+
// Wallet button clicked - emit event for merchant to validate their form
|
|
428
|
+
this.emitter.emit(exports.SdkEvent.FormValidation, {
|
|
429
|
+
checkoutId: data.checkoutId,
|
|
430
|
+
wallet: data.wallet,
|
|
431
|
+
});
|
|
432
|
+
break;
|
|
420
433
|
}
|
|
421
434
|
}
|
|
422
435
|
/**
|
|
@@ -629,6 +642,39 @@ class CheckoutImpl {
|
|
|
629
642
|
isMounted() {
|
|
630
643
|
return this.mounted;
|
|
631
644
|
}
|
|
645
|
+
/**
|
|
646
|
+
* Complete form validation successfully - allows wallet payment to proceed.
|
|
647
|
+
* Call this in response to 'form_validation' event when merchant form is valid.
|
|
648
|
+
*/
|
|
649
|
+
completeFormValidation(wallet) {
|
|
650
|
+
if (!this.mounted) {
|
|
651
|
+
console.warn('[PaypercutCheckout] Cannot complete form validation: not mounted');
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
this.postToIframe({
|
|
655
|
+
type: 'FORM_VALIDATION_COMPLETED',
|
|
656
|
+
checkoutId: this.options.id,
|
|
657
|
+
wallet,
|
|
658
|
+
status: 'success',
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Fail form validation - prevents wallet payment from starting.
|
|
663
|
+
* Call this in response to 'form_validation' event when merchant form has errors.
|
|
664
|
+
*/
|
|
665
|
+
failFormValidation(wallet, errors) {
|
|
666
|
+
if (!this.mounted) {
|
|
667
|
+
console.warn('[PaypercutCheckout] Cannot fail form validation: not mounted');
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
this.postToIframe({
|
|
671
|
+
type: 'FORM_VALIDATION_COMPLETED',
|
|
672
|
+
checkoutId: this.options.id,
|
|
673
|
+
wallet,
|
|
674
|
+
status: 'failed',
|
|
675
|
+
errors,
|
|
676
|
+
});
|
|
677
|
+
}
|
|
632
678
|
}
|
|
633
679
|
/**
|
|
634
680
|
* Factory function that works both as callable and constructable.
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/utils/emitter.ts","../src/config.ts","../src/types/locales.ts","../src/types/checkout.ts","../src/index.ts"],"sourcesContent":["/**\n * Simple event emitter for handling checkout events\n * Supports subscribing, unsubscribing, and emitting events\n */\nexport class Emitter<T extends string = string> {\n private handlers = new Map<T, Set<Function>>();\n\n /**\n * Subscribe to an event\n * @param event - Event name to listen to\n * @param handler - Callback function to execute when event is emitted\n * @returns Unsubscribe function\n */\n on(event: T, handler: Function): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n /**\n * Subscribe to an event that auto-unsubscribes after first emission\n *\n * Common use case: waiting for 'loaded' event or handling first 'success'.\n * Without this helper, developers would need to manually unsubscribe inside\n * their handler, which is error-prone and leads to memory leaks if forgotten.\n *\n * @param event - Event name to listen to\n * @param handler - Callback function to execute when event is emitted\n * @returns Unsubscribe function\n */\n once(event: T, handler: Function): () => void {\n const wrappedHandler = (...args: any[]) => {\n handler(...args);\n this.off(event, wrappedHandler);\n };\n return this.on(event, wrappedHandler);\n }\n\n /**\n * Unsubscribe from an event\n * @param event - Event name to stop listening to\n * @param handler - Callback function to remove\n */\n off(event: T, handler: Function): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n /**\n * Emit an event with optional arguments\n * @param event - Event name to emit\n * @param args - Arguments to pass to event handlers\n */\n emit(event: T, ...args: any[]): void {\n this.handlers.get(event)?.forEach(h => {\n try {\n h(...args);\n } catch (err) {\n console.error(`[Emitter] Error in ${event} handler:`, err);\n }\n });\n }\n\n /**\n * Clear all event handlers\n */\n clear(): void {\n this.handlers.clear();\n }\n}\n\n","/**\n * Build-time configuration\n * \n * This file is processed at build time with different values for:\n * - Production build (for merchants)\n * - Internal build (for team development)\n */\n\n/**\n * Build mode - replaced at build time\n */\ndeclare const __BUILD_MODE__: 'production' | 'internal';\n\n/**\n * SDK version - replaced at build time\n */\ndeclare const __VERSION__: string;\n\n/**\n * Configuration interface\n */\nexport interface BuildConfig {\n /** SDK version */\n version: string;\n \n /** Build mode */\n mode: 'production' | 'internal';\n \n /** Default checkout origin (production URL) */\n defaultCheckoutOrigin: string;\n \n /** Allowed origins for postMessage validation */\n allowedOrigins: string[];\n \n /** Whether hostedCheckoutUrl override is allowed */\n allowOriginOverride: boolean;\n}\n\n/**\n * Production configuration (for merchants)\n */\nconst productionConfig: BuildConfig = {\n version: __VERSION__,\n mode: 'production',\n defaultCheckoutOrigin: 'https://buy.paypercut.io',\n allowedOrigins: [\n 'https://buy.paypercut.io',\n ],\n allowOriginOverride: false\n};\n\n/**\n * Internal configuration (for team development)\n */\nconst internalConfig: BuildConfig = {\n version: __VERSION__,\n mode: 'internal',\n defaultCheckoutOrigin: 'https://buy.paypercut.io',\n allowedOrigins: [\n 'https://buy.paypercut.io',\n 'http://localhost:3000',\n 'http://localhost:3001',\n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001'\n ],\n allowOriginOverride: true\n};\n\n/**\n * Active configuration (selected at build time)\n */\nexport const config: BuildConfig = __BUILD_MODE__ === 'internal' \n ? internalConfig \n : productionConfig;\n\n/**\n * Helper to check if origin is allowed\n */\nexport function isOriginAllowed(origin: string): boolean {\n return config.allowedOrigins.includes(origin);\n}\n\n/**\n * Get the checkout origin (with optional override for internal builds)\n */\nexport function getCheckoutOrigin(override?: string): string {\n // Only allow override in internal builds\n if (override && config.allowOriginOverride) {\n return override;\n }\n \n return config.defaultCheckoutOrigin;\n}\n\n","/**\n * Supported locales for Paypercut Checkout\n * \n * @remarks\n * Single source of truth for all supported locale codes.\n * \n * Supported languages:\n * - Bulgarian: 'bg', 'bg-BG'\n * - English: 'en', 'en-GB'\n * - Greek: 'el', 'el-GR'\n * - Romanian: 'ro', 'ro-RO'\n * - Croatian: 'hr', 'hr-HR'\n * - Polish: 'pl', 'pl-PL'\n * - Czech: 'cs', 'cs-CZ'\n * - Slovenian: 'sl', 'sl-SI'\n * - Slovak: 'sk', 'sk-SK'\n * \n * @example\n * ```typescript\n * const checkout = PaypercutCheckout({\n * locale: 'bg' // or 'bg-BG', 'en', 'en-GB', etc.\n * });\n * ```\n */\nexport const LOCALES = [\n 'bg', 'bg-BG',\n 'en', 'en-GB',\n 'el', 'el-GR',\n 'ro', 'ro-RO',\n 'hr', 'hr-HR',\n 'pl', 'pl-PL',\n 'cs', 'cs-CZ',\n 'sl', 'sl-SI',\n 'sk', 'sk-SK',\n] as const;\n\n/**\n * Locale type - union of all supported locale codes plus 'auto'\n * @example\n * ```typescript\n * const locale: Locale = 'bg';\n * const autoLocale: Locale = 'auto';\n * ```\n */\nexport type Locale = typeof LOCALES[number] | 'auto';\n\n/**\n * Fast runtime check using Set for O(1) lookup\n * @internal\n */\nconst LOCALE_SET: ReadonlySet<string> = new Set(LOCALES);\n\n/**\n * Normalize and validate locale\n * \n * @param locale - Locale code to normalize\n * @returns Normalized locale code or 'en' as fallback\n * \n * @remarks\n * - 'auto' or empty → 'en'\n * - Unsupported locale → 'en' with console warning\n * - Supported locale → original value\n * \n * @example\n * ```typescript\n * normalizeLocale('auto') // → 'en'\n * normalizeLocale('bg') // → 'bg'\n * normalizeLocale('de') // → 'en' (with warning)\n * ```\n */\nexport function normalizeLocale(locale: string | Locale): typeof LOCALES[number] | 'en' {\n if (!locale || locale === 'auto') return 'en';\n if (LOCALE_SET.has(locale)) return locale as typeof LOCALES[number];\n console.warn(`[PaypercutCheckout] Locale \"${locale}\" is not supported. Falling back to \"en\".`);\n return 'en';\n}\n\n","import { Locale } from './locales';\n\n/**\n * UI mode for checkout\n */\nexport enum UIMode {\n /** Embedded mode - checkout embedded in merchant page */\n EMBEDDED = 'embedded',\n}\n\n/**\n * Type guard for UIMode\n */\nexport function isValidUIMode(value: string): value is UIMode {\n return Object.values(UIMode).includes(value as UIMode);\n}\n\n/**\n * Payment method types\n */\nexport enum PaymentMethod {\n /** Card payment (credit/debit) */\n CARD = 'card',\n}\n\n/**\n * Type guard for PaymentMethod\n */\nexport function isValidPaymentMethod(value: string): value is PaymentMethod {\n return Object.values(PaymentMethod).includes(value as PaymentMethod);\n}\n\n/**\n * Wallet options for digital wallets\n */\nexport enum WalletOption {\n /** Apple Pay */\n APPLE_PAY = 'apple_pay',\n /** Google Pay */\n GOOGLE_PAY = 'google_pay',\n}\n\n/**\n * Type guard for WalletOption\n */\nexport function isValidWalletOption(value: string): value is WalletOption {\n return Object.values(WalletOption).includes(value as WalletOption);\n}\n\n/**\n * Validate payment methods array\n */\nexport function validatePaymentMethods(methods: string[]): PaymentMethod[] {\n const validated: PaymentMethod[] = [];\n\n for (const method of methods) {\n if (isValidPaymentMethod(method)) {\n validated.push(method as PaymentMethod);\n } else {\n console.warn(`[PaypercutCheckout] Invalid payment method: \"${method}\". Skipping.`);\n }\n }\n\n // Default to card if no valid methods\n if (validated.length === 0) {\n console.warn('[PaypercutCheckout] No valid payment methods provided. Defaulting to \"card\".');\n validated.push(PaymentMethod.CARD);\n }\n\n return validated;\n}\n\n/**\n * Validate wallet options array\n */\nexport function validateWalletOptions(options: string[]): WalletOption[] {\n const validated: WalletOption[] = [];\n\n for (const option of options) {\n if (isValidWalletOption(option)) {\n validated.push(option as WalletOption);\n } else {\n console.warn(`[PaypercutCheckout] Invalid wallet option: \"${option}\". Skipping.`);\n }\n }\n\n return validated;\n}\n\n/**\n * Validate UI mode\n */\nexport function validateUIMode(mode: string | undefined): UIMode | undefined {\n if (!mode) {\n return undefined;\n }\n\n if (isValidUIMode(mode)) {\n return mode as UIMode;\n }\n\n console.warn(\n `[PaypercutCheckout] Invalid ui_mode: \"${mode}\". Valid options: ${Object.values(UIMode).join(', ')}`,\n );\n return undefined;\n}\n\n/**\n * Configuration options for PaypercutCheckout\n */\nexport interface PaypercutCheckoutOptions {\n /** Checkout session identifier (e.g., 'CHK_12345') */\n id: string;\n\n /** CSS selector or HTMLElement where iframe mounts (required) */\n containerId: string | HTMLElement;\n\n /**\n * Optional: Custom hosted checkout URL (only available in internal builds)\n * Production builds will ignore this option for security\n */\n hostedCheckoutUrl?: string;\n\n /**\n * Optional: Locale for checkout UI\n * @default 'en'\n */\n locale?: Locale | string;\n\n /**\n * Optional: UI mode for checkout\n */\n ui_mode?: UIMode | `${UIMode}`;\n\n /**\n * Optional: Payment methods to enable\n * @default ['card']\n */\n payment_methods?: (PaymentMethod | `${PaymentMethod}`)[];\n\n /**\n * Optional: Digital wallet options\n * Can include both or just one\n * Default behaviour - shows both\n */\n wallet_options?: (WalletOption | `${WalletOption}`)[] | [];\n\n /**\n * Optional: Show only the payment form without header/footer\n * @default false\n */\n form_only?: boolean;\n\n /**\n * Optional: Appearance options\n */\n appearance?: {\n preset?: 'inline' | 'modal';\n theme?: 'light' | 'dark' | 'none' | 'flat';\n variables: {};\n rules: {};\n labels: 'floating' | 'above' | 'none';\n };\n}\n\n/**\n * Event names that can be emitted by the checkout\n */\nexport type EventName =\n | 'loaded' // iframe finished loading\n | 'success' // payment successful\n | 'error' // payment or system error\n | 'expired' // checkout expired or already paid\n | 'resize' // checkout expired or already paid\n | 'threeds_complete' // checkout paid successfully\n | 'threeds_error' // checkout threeds error\n | 'threeds_canceled' // checkout threeds canceled\n | 'threeds_started'; // checkout threeds started\n\n/**\n * Preferred enum for SDK event names (use instead of hardcoded strings)\n */\nexport enum SdkEvent {\n Loaded = 'loaded',\n Success = 'success',\n Error = 'error',\n Expired = 'expired',\n Resize = 'resize',\n ThreeDSComplete = 'threeds_complete',\n ThreeDSError = 'threeds_error',\n ThreeDSCanceled = 'threeds_canceled',\n ThreeDSStarted = 'threeds_started',\n}\n\n/**\n * Checkout instance interface\n */\nexport interface CheckoutInstance {\n /** Mount and render the iframe into the container */\n render(): void;\n\n /** Submit payment - sends message to hosted checkout to confirm payment */\n submit(): void;\n\n /** Destroy instance and cleanup all listeners */\n destroy(): void;\n\n /** Subscribe to events. Returns unsubscribe function */\n on(event: EventName | SdkEvent, handler: (...args: any[]) => void): () => void;\n\n /** Subscribe to event that auto-unsubscribes after first emission */\n once(event: EventName | SdkEvent, handler: (...args: any[]) => void): () => void;\n\n /** Unsubscribe from events */\n off(event: EventName | SdkEvent, handler: (...args: any[]) => void): void;\n\n /** Check if checkout is currently mounted */\n isMounted(): boolean;\n}\n\n/**\n * PaypercutCheckout static interface (callable and constructable)\n */\nexport interface PaypercutCheckoutStatic {\n /** Callable factory function */\n (options: PaypercutCheckoutOptions): CheckoutInstance;\n\n /** Constructor support */\n new (options: PaypercutCheckoutOptions): CheckoutInstance;\n\n /** SDK version */\n version: string;\n}\n","import { Emitter } from './utils/emitter';\nimport { config, isOriginAllowed, getCheckoutOrigin } from './config';\n\nimport {\n PaypercutCheckoutOptions,\n CheckoutInstance,\n PaypercutCheckoutStatic,\n EventName,\n SdkEvent,\n validatePaymentMethods,\n validateWalletOptions,\n validateUIMode,\n UIMode,\n} from './types';\nimport { normalizeLocale } from './types';\n\n// Re-export types and enums for consumers\nexport type { PaypercutCheckoutOptions, CheckoutInstance, PaypercutCheckoutStatic, EventName };\n\nexport { UIMode, PaymentMethod, WalletOption } from './types/checkout';\n\n// Re-export SDK event enums for consumers\nexport { SdkEvent } from './types/checkout';\n\nexport type { Locale } from './types/locales';\nexport { LOCALES } from './types/locales';\n\n/**\n * Internal implementation of CheckoutInstance\n */\nclass CheckoutImpl implements CheckoutInstance {\n private emitter = new Emitter<EventName>();\n private mounted = false;\n private destroyed = false;\n private iframe: HTMLIFrameElement | null = null;\n private messageHandler: (evt: MessageEvent) => void;\n\n // 3DS Modal state\n private threeDSModal: HTMLDivElement | null = null;\n private threeDSIframe: HTMLIFrameElement | null = null;\n\n constructor(private options: PaypercutCheckoutOptions) {\n // Bind message handler\n this.messageHandler = this.onMessage.bind(this);\n window.addEventListener('message', this.messageHandler);\n }\n\n /**\n * Build the iframe source URL with query parameters\n */\n private buildSrc(): string {\n const baseUrl = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n const url = new URL(`/c/${this.options.id}`, baseUrl);\n\n // Add locale parameter\n if (this.options.locale) {\n const normalizedLocale = normalizeLocale(this.options.locale);\n url.searchParams.set('locale', normalizedLocale);\n }\n\n // Add ui_mode parameter (default to 'embedded')\n {\n const selected = validateUIMode(this.options.ui_mode ?? UIMode.EMBEDDED);\n if (selected) {\n url.searchParams.set('ui_mode', selected);\n }\n }\n\n // Add payment_methods parameters (repeated for each method)\n if (this.options.payment_methods && this.options.payment_methods.length > 0) {\n const validatedMethods = validatePaymentMethods(this.options.payment_methods as string[]);\n validatedMethods.forEach((method) => {\n url.searchParams.append('payment_methods', method);\n });\n }\n\n // Add wallet_options parameters (repeated for each wallet)\n // If wallet_options is explicitly set (even as empty array), we need to pass it\n if (this.options.wallet_options !== undefined) {\n if (this.options.wallet_options.length === 0) {\n // Explicit empty array means \"no wallets\" - pass null (coerced to \"null\" string)\n url.searchParams.set('wallet_options', null as unknown as string);\n } else {\n const validatedWallets = validateWalletOptions(this.options.wallet_options as string[]);\n validatedWallets.forEach((wallet) => {\n url.searchParams.append('wallet_options', wallet);\n });\n }\n }\n\n if (this.options.appearance?.preset) {\n url.searchParams.set('preset', this.options.appearance.preset);\n }\n\n if (this.options.form_only !== undefined) {\n url.searchParams.set('form_only', String(this.options.form_only));\n }\n\n return url.toString();\n }\n\n /**\n * Get the container element from selector or HTMLElement\n */\n private getContainer(): HTMLElement {\n const container =\n typeof this.options.containerId === 'string'\n ? document.querySelector(this.options.containerId)\n : this.options.containerId;\n\n if (!container) {\n throw new Error(`Container not found: ${this.options.containerId}`);\n }\n\n return container as HTMLElement;\n }\n\n /**\n * Handle incoming postMessage events from iframe\n */\n private onMessage(evt: MessageEvent): void {\n // Validate origin against allowed origins (build-time whitelist)\n if (!isOriginAllowed(evt.origin)) {\n return;\n }\n\n // Validate structure\n const data = evt.data;\n if (!data || typeof data !== 'object' || !('type' in data)) {\n return;\n }\n\n // Filter messages by checkout session ID to prevent cross-instance message handling\n // This ensures each checkout instance only processes its own messages\n if (data.checkoutId && data.checkoutId !== this.options.id) {\n return; // Message is for a different checkout instance\n }\n\n // Handle specific events\n switch (data.type) {\n case 'CHECKOUT_LOADED':\n this.emitter.emit(SdkEvent.Loaded);\n break;\n case 'CHECKOUT_SUCCESS':\n const { payment_method = {} } = data;\n this.emitter.emit(SdkEvent.Success, { payment_method });\n break;\n case 'CHECKOUT_ERROR':\n // Forward error payload (if provided) to SDK consumers\n this.emitter.emit(SdkEvent.Error, (data && (data as any).error) ?? data);\n break;\n case 'CHECKOUT_EXPIRED':\n this.emitter.emit(SdkEvent.Expired);\n break;\n case 'CHECKOUT_RESIZE':\n this.emitter.emit(SdkEvent.Resize, data.height);\n this.handleResize(data.height);\n break;\n case 'THREEDS_START_FLOW':\n this.show3DSModal(data);\n this.emitter.emit(SdkEvent.ThreeDSStarted);\n break;\n case 'THREEDS_READY':\n this.handle3DSReady();\n break;\n case 'THREEDS_COMPLETE':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSComplete);\n break;\n case 'THREEDS_CANCELED':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSCanceled);\n break;\n case 'THREEDS_ERROR':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSError, data.error);\n break;\n }\n }\n\n /**\n * Render the checkout iframe into the container\n */\n render(): void {\n if (this.mounted) {\n return;\n }\n\n try {\n const container = this.getContainer();\n\n // Create iframe\n this.iframe = document.createElement('iframe');\n this.iframe.id = 'paypercut-checkout-iframe';\n this.iframe.src = this.buildSrc();\n this.iframe.allow = 'payment *; clipboard-write';\n this.iframe.setAttribute('frameborder', '0');\n // Allow Payment Request API inside iframe and necessary sandbox permissions for wallets\n this.iframe.setAttribute('allowpaymentrequest', 'true');\n this.iframe.setAttribute(\n 'sandbox',\n 'allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox',\n );\n\n // Apply default styles - just construct URL and assign to iframe\n Object.assign(this.iframe.style, {\n width: '100%',\n height: '100%',\n border: 'none',\n display: 'block',\n });\n\n // Listen for iframe load event (fallback)\n // This ensures 'loaded' event is always emitted even if hosted checkout\n // doesn't send CHECKOUT_LOADED message\n /*this.iframe.addEventListener('load', () => {\n this.emitter.emit('loaded');\n });*/\n\n container.appendChild(this.iframe);\n this.mounted = true;\n } catch (err) {\n console.error('[PaypercutCheckout] Failed to render:', err);\n throw err;\n }\n }\n\n /**\n * Submit payment - sends message to hosted checkout to confirm payment\n */\n submit(): void {\n if (!this.mounted) {\n return;\n }\n\n try {\n this.postToIframe({\n type: 'START_PROCESSING',\n checkoutId: this.options.id,\n });\n } catch (err) {\n console.error('[PaypercutCheckout] Failed to submit payment:', err);\n throw err;\n }\n }\n\n /**\n * Send message to hosted/embedded checkout iframe - used for submit payment and communicating 3DS events\n */\n private postToIframe(message: any): void {\n if (!this.iframe?.contentWindow) {\n console.error('[PaypercutCheckout] Cannot post message: iframe not mounted');\n return;\n }\n\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n this.iframe.contentWindow.postMessage(message, checkoutOrigin);\n }\n\n /**\n * Handle CHECKOUT_RESIZE message - resize iframe to match content height\n */\n private handleResize(height: unknown): void {\n if (!this.iframe || typeof height !== 'number' || height <= 0) {\n return;\n }\n\n // Set iframe height to match content\n this.iframe.style.height = `${height}px`;\n }\n\n /**\n * Show 3DS modal with challenge/decoupled flow\n */\n private show3DSModal(data: {\n sessionId: string;\n step: 'challenge' | 'decoupled_waiting';\n challengeUrl?: string;\n acsTransactionId?: string;\n threeDSVersion?: string;\n cardBrand?: string;\n liveMode?: boolean;\n }): void {\n // Create modal backdrop\n this.threeDSModal = document.createElement('div');\n this.threeDSModal.id = 'paypercut-3ds-modal';\n Object.assign(this.threeDSModal.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: '999999',\n background: 'rgba(0, 0, 0, 0.4)',\n });\n\n // Create iframe for 3DS page\n this.threeDSIframe = document.createElement('iframe');\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n\n // Build URL: baseUrl/c/{checkoutId}/threeds with query params\n const threeDSUrl = new URL(`/c/${this.options.id}/threeds`, checkoutOrigin);\n threeDSUrl.searchParams.set('sessionId', data.sessionId);\n threeDSUrl.searchParams.set('step', data.step);\n\n if (data.challengeUrl) {\n threeDSUrl.searchParams.set('challengeUrl', data.challengeUrl);\n }\n if (data.acsTransactionId) {\n threeDSUrl.searchParams.set('acsTransactionId', data.acsTransactionId);\n }\n if (data.threeDSVersion) {\n threeDSUrl.searchParams.set('threeDSVersion', data.threeDSVersion);\n }\n // Always include liveMode; default to false when undefined\n threeDSUrl.searchParams.set('liveMode', String(data.liveMode ?? false));\n\n this.threeDSIframe.src = threeDSUrl.toString();\n this.threeDSIframe.allow = 'payment *';\n this.threeDSIframe.setAttribute('frameborder', '0');\n\n // Fixed dimensions: follow 3DS component size (500x500)\n Object.assign(this.threeDSIframe.style, {\n minWidth: '400px',\n minHeight: '400px',\n border: 'none',\n borderRadius: '8px',\n display: 'block',\n background: 'transparent',\n });\n\n // Append iframe directly to modal backdrop\n this.threeDSModal.appendChild(this.threeDSIframe);\n document.body.appendChild(this.threeDSModal);\n\n // Store 3DS data for later use\n (this as any).pending3DSData = data;\n }\n\n /**\n * Handle THREEDS_READY message - send THREEDS_INIT with challenge data\n */\n private handle3DSReady(): void {\n const data = (this as any).pending3DSData;\n if (!data || !this.threeDSIframe?.contentWindow) {\n console.error('[PaypercutCheckout] No pending 3DS data or iframe not ready');\n return;\n }\n\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n this.threeDSIframe.contentWindow.postMessage(\n {\n type: 'THREEDS_INIT',\n checkoutId: this.options.id,\n },\n checkoutOrigin,\n );\n }\n\n /**\n * Close 3DS modal and cleanup\n */\n private close3DSModal(): void {\n if (this.threeDSModal) {\n this.threeDSModal.remove();\n this.threeDSModal = null;\n }\n\n this.threeDSIframe = null;\n delete (this as any).pending3DSData;\n }\n\n /**\n * Destroy the checkout instance and cleanup (idempotent)\n */\n destroy(): void {\n // Early return if already destroyed\n if (this.destroyed) {\n return;\n }\n\n // Remove iframe from DOM\n if (this.iframe) {\n try {\n this.iframe.remove();\n this.iframe = null;\n } catch (err) {\n console.error('[PaypercutCheckout] Error removing iframe:', err);\n }\n }\n\n // Cleanup 3DS modal if open\n this.close3DSModal();\n\n // Only set mounted = false after successful DOM removal\n this.mounted = false;\n this.destroyed = true;\n\n // Cleanup event listeners\n window.removeEventListener('message', this.messageHandler);\n this.emitter.clear();\n }\n\n /**\n * Subscribe to an event\n */\n on(event: EventName, handler: (...args: any[]) => void): () => void {\n return this.emitter.on(event, handler);\n }\n\n /**\n * Subscribe to event that auto-unsubscribes after first emission\n */\n once(event: EventName, handler: (...args: any[]) => void): () => void {\n return this.emitter.once(event, handler);\n }\n\n /**\n * Unsubscribe from an event\n */\n off(event: EventName, handler: (...args: any[]) => void): void {\n this.emitter.off(event, handler);\n }\n\n /**\n * Check if checkout is currently mounted\n */\n isMounted(): boolean {\n return this.mounted;\n }\n}\n\n/**\n * Factory function that works both as callable and constructable.\n * Always returns a new CheckoutImpl instance - no prototype manipulation needed.\n */\nconst PaypercutCheckout: PaypercutCheckoutStatic = function (\n this: unknown,\n options: PaypercutCheckoutOptions,\n): CheckoutInstance {\n // Always return a new instance, regardless of how it's called\n return new CheckoutImpl(options);\n} as unknown as PaypercutCheckoutStatic;\n\n// Add static version property\n(PaypercutCheckout as any).version = config.version;\n\n// Export as default and named\nexport default PaypercutCheckout;\nexport { PaypercutCheckout };\n"],"names":["UIMode","PaymentMethod","WalletOption","SdkEvent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/utils/emitter.ts","../src/config.ts","../src/types/locales.ts","../src/types/checkout.ts","../src/index.ts"],"sourcesContent":["/**\n * Simple event emitter for handling checkout events\n * Supports subscribing, unsubscribing, and emitting events\n */\nexport class Emitter<T extends string = string> {\n private handlers = new Map<T, Set<Function>>();\n\n /**\n * Subscribe to an event\n * @param event - Event name to listen to\n * @param handler - Callback function to execute when event is emitted\n * @returns Unsubscribe function\n */\n on(event: T, handler: Function): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n /**\n * Subscribe to an event that auto-unsubscribes after first emission\n *\n * Common use case: waiting for 'loaded' event or handling first 'success'.\n * Without this helper, developers would need to manually unsubscribe inside\n * their handler, which is error-prone and leads to memory leaks if forgotten.\n *\n * @param event - Event name to listen to\n * @param handler - Callback function to execute when event is emitted\n * @returns Unsubscribe function\n */\n once(event: T, handler: Function): () => void {\n const wrappedHandler = (...args: any[]) => {\n handler(...args);\n this.off(event, wrappedHandler);\n };\n return this.on(event, wrappedHandler);\n }\n\n /**\n * Unsubscribe from an event\n * @param event - Event name to stop listening to\n * @param handler - Callback function to remove\n */\n off(event: T, handler: Function): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n /**\n * Emit an event with optional arguments\n * @param event - Event name to emit\n * @param args - Arguments to pass to event handlers\n */\n emit(event: T, ...args: any[]): void {\n this.handlers.get(event)?.forEach(h => {\n try {\n h(...args);\n } catch (err) {\n console.error(`[Emitter] Error in ${event} handler:`, err);\n }\n });\n }\n\n /**\n * Clear all event handlers\n */\n clear(): void {\n this.handlers.clear();\n }\n}\n\n","/**\n * Build-time configuration\n * \n * This file is processed at build time with different values for:\n * - Production build (for merchants)\n * - Internal build (for team development)\n */\n\n/**\n * Build mode - replaced at build time\n */\ndeclare const __BUILD_MODE__: 'production' | 'internal';\n\n/**\n * SDK version - replaced at build time\n */\ndeclare const __VERSION__: string;\n\n/**\n * Configuration interface\n */\nexport interface BuildConfig {\n /** SDK version */\n version: string;\n \n /** Build mode */\n mode: 'production' | 'internal';\n \n /** Default checkout origin (production URL) */\n defaultCheckoutOrigin: string;\n \n /** Allowed origins for postMessage validation */\n allowedOrigins: string[];\n \n /** Whether hostedCheckoutUrl override is allowed */\n allowOriginOverride: boolean;\n}\n\n/**\n * Production configuration (for merchants)\n */\nconst productionConfig: BuildConfig = {\n version: __VERSION__,\n mode: 'production',\n defaultCheckoutOrigin: 'https://buy.paypercut.io',\n allowedOrigins: [\n 'https://buy.paypercut.io',\n ],\n allowOriginOverride: false\n};\n\n/**\n * Internal configuration (for team development)\n */\nconst internalConfig: BuildConfig = {\n version: __VERSION__,\n mode: 'internal',\n defaultCheckoutOrigin: 'https://buy.paypercut.io',\n allowedOrigins: [\n 'https://buy.paypercut.io',\n 'http://localhost:3000',\n 'http://localhost:3001',\n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001'\n ],\n allowOriginOverride: true\n};\n\n/**\n * Active configuration (selected at build time)\n */\nexport const config: BuildConfig = __BUILD_MODE__ === 'internal' \n ? internalConfig \n : productionConfig;\n\n/**\n * Helper to check if origin is allowed\n */\nexport function isOriginAllowed(origin: string): boolean {\n return config.allowedOrigins.includes(origin);\n}\n\n/**\n * Get the checkout origin (with optional override for internal builds)\n */\nexport function getCheckoutOrigin(override?: string): string {\n // Only allow override in internal builds\n if (override && config.allowOriginOverride) {\n return override;\n }\n \n return config.defaultCheckoutOrigin;\n}\n\n","/**\n * Supported locales for Paypercut Checkout\n *\n * @remarks\n * Single source of truth for all supported locale codes.\n *\n * Supported languages:\n * - Bulgarian: 'bg', 'bg-BG'\n * - English: 'en', 'en-GB'\n * - Greek: 'el', 'el-GR'\n * - Romanian: 'ro', 'ro-RO'\n * - Croatian: 'hr', 'hr-HR'\n * - Polish: 'pl', 'pl-PL'\n * - Czech: 'cs', 'cs-CZ'\n * - Slovenian: 'sl', 'sl-SI'\n * - Slovak: 'sk', 'sk-SK'\n *\n * @example\n * ```typescript\n * const checkout = PaypercutCheckout({\n * locale: 'bg' // or 'bg-BG', 'en', 'en-GB', etc.\n * });\n * ```\n */\nexport const LOCALES = [\n 'bg', 'bg-BG',\n 'en', 'en-GB',\n 'el', 'el-GR',\n 'ro', 'ro-RO',\n 'hr', 'hr-HR',\n 'pl', 'pl-PL',\n 'cs', 'cs-CZ',\n 'sl', 'sl-SI',\n 'sk', 'sk-SK',\n] as const;\n\n/**\n * Locale type - union of all supported locale codes plus 'auto'\n * @example\n * ```typescript\n * const locale: Locale = 'bg';\n * const lang: Locale = 'bg';\n * const autoLocale: Locale = 'auto';\n * ```\n */\nexport type Locale = typeof LOCALES[number] | 'auto';\n\n/**\n * Fast runtime check using Set for O(1) lookup\n * @internal\n */\nconst LOCALE_SET: ReadonlySet<string> = new Set(LOCALES);\n\n/**\n * Normalize and validate locale\n *\n * @param locale - Locale code to normalize\n * @returns Normalized locale code or 'en' as fallback\n *\n * @remarks\n * - 'auto' or empty → 'en'\n * - Unsupported locale → 'en' with console warning\n * - Supported locale → original value\n *\n * @example\n * ```typescript\n * normalizeLocale('auto') // → 'en'\n * normalizeLocale('bg') // → 'bg'\n * normalizeLocale('de') // → 'en' (with warning)\n * ```\n */\nexport function normalizeLocale(locale: string | Locale): typeof LOCALES[number] | 'en' {\n if (!locale || locale === 'auto') return 'en';\n if (LOCALE_SET.has(locale)) return locale as typeof LOCALES[number];\n console.warn(`[PaypercutCheckout] Locale \"${locale}\" is not supported. Falling back to \"en\".`);\n return 'en';\n}\n\n","import { Locale } from './locales';\n\n/**\n * UI mode for checkout\n */\nexport enum UIMode {\n /** Embedded mode - checkout embedded in merchant page */\n EMBEDDED = 'embedded',\n}\n\n/**\n * Type guard for UIMode\n */\nexport function isValidUIMode(value: string): value is UIMode {\n return Object.values(UIMode).includes(value as UIMode);\n}\n\n/**\n * Payment method types\n */\nexport enum PaymentMethod {\n /** Card payment (credit/debit) */\n CARD = 'card',\n}\n\n/**\n * Type guard for PaymentMethod\n */\nexport function isValidPaymentMethod(value: string): value is PaymentMethod {\n return Object.values(PaymentMethod).includes(value as PaymentMethod);\n}\n\n/**\n * Wallet options for digital wallets\n */\nexport enum WalletOption {\n /** Apple Pay */\n APPLE_PAY = 'apple_pay',\n /** Google Pay */\n GOOGLE_PAY = 'google_pay',\n}\n\n/**\n * Type guard for WalletOption\n */\nexport function isValidWalletOption(value: string): value is WalletOption {\n return Object.values(WalletOption).includes(value as WalletOption);\n}\n\n/**\n * Validate payment methods array\n */\nexport function validatePaymentMethods(methods: string[]): PaymentMethod[] {\n const validated: PaymentMethod[] = [];\n\n for (const method of methods) {\n if (isValidPaymentMethod(method)) {\n validated.push(method as PaymentMethod);\n } else {\n console.warn(`[PaypercutCheckout] Invalid payment method: \"${method}\". Skipping.`);\n }\n }\n\n // Default to card if no valid methods\n if (validated.length === 0) {\n console.warn('[PaypercutCheckout] No valid payment methods provided. Defaulting to \"card\".');\n validated.push(PaymentMethod.CARD);\n }\n\n return validated;\n}\n\n/**\n * Validate wallet options array\n */\nexport function validateWalletOptions(options: string[]): WalletOption[] {\n const validated: WalletOption[] = [];\n\n for (const option of options) {\n if (isValidWalletOption(option)) {\n validated.push(option as WalletOption);\n } else {\n console.warn(`[PaypercutCheckout] Invalid wallet option: \"${option}\". Skipping.`);\n }\n }\n\n return validated;\n}\n\n/**\n * Validate UI mode\n */\nexport function validateUIMode(mode: string | undefined): UIMode | undefined {\n if (!mode) {\n return undefined;\n }\n\n if (isValidUIMode(mode)) {\n return mode as UIMode;\n }\n\n console.warn(\n `[PaypercutCheckout] Invalid ui_mode: \"${mode}\". Valid options: ${Object.values(UIMode).join(', ')}`,\n );\n return undefined;\n}\n\n/**\n * Configuration options for PaypercutCheckout\n */\nexport interface PaypercutCheckoutOptions {\n /** Checkout session identifier (e.g., 'CHK_12345') */\n id: string;\n\n /** CSS selector or HTMLElement where iframe mounts (required) */\n containerId: string | HTMLElement;\n\n /**\n * Optional: Custom hosted checkout URL (only available in internal builds)\n * Production builds will ignore this option for security\n */\n hostedCheckoutUrl?: string;\n\n /**\n * Optional: Locale for checkout UI\n * @default 'en'\n */\n locale?: Locale | string;\n\n /**\n * Optional: Language for checkout UI\n * @default 'en'\n */\n lang?: Locale | string;\n\n /**\n * Optional: UI mode for checkout\n */\n ui_mode?: UIMode | `${UIMode}`;\n\n /**\n * Optional: Payment methods to enable\n * @default ['card']\n */\n payment_methods?: (PaymentMethod | `${PaymentMethod}`)[];\n\n /**\n * Optional: Digital wallet options\n * Can include both or just one\n * Default behaviour - shows both\n */\n wallet_options?: (WalletOption | `${WalletOption}`)[] | [];\n\n /**\n * Optional: Show only the payment form without header/footer\n * @default false\n */\n form_only?: boolean;\n\n /**\n * Optional: Appearance options\n */\n appearance?: {\n preset?: 'inline' | 'modal';\n theme?: 'light' | 'dark' | 'none' | 'flat';\n variables: {};\n rules: {};\n labels: 'floating' | 'above' | 'none';\n };\n}\n\n/**\n * Wallet type for form validation\n */\nexport type WalletType = 'apple_pay' | 'google_pay';\n\n/**\n * Form validation event payload\n */\nexport interface FormValidationPayload {\n checkoutId: string;\n wallet: WalletType;\n}\n\n/**\n * Event names that can be emitted by the checkout\n */\nexport type EventName =\n | 'loaded' // iframe finished loading\n | 'success' // payment successful\n | 'error' // payment or system error\n | 'expired' // checkout expired or already paid\n | 'resize' // checkout expired or already paid\n | 'threeds_complete' // checkout paid successfully\n | 'threeds_error' // checkout threeds error\n | 'threeds_canceled' // checkout threeds canceled\n | 'threeds_started' // checkout threeds started\n | 'form_validation'; // wallet button clicked, merchant should validate form\n\n/**\n * Preferred enum for SDK event names (use instead of hardcoded strings)\n */\nexport enum SdkEvent {\n Loaded = 'loaded',\n Success = 'success',\n Error = 'error',\n Expired = 'expired',\n Resize = 'resize',\n ThreeDSComplete = 'threeds_complete',\n ThreeDSError = 'threeds_error',\n ThreeDSCanceled = 'threeds_canceled',\n ThreeDSStarted = 'threeds_started',\n FormValidation = 'form_validation',\n}\n\n/**\n * Form validation error for failFormValidation\n */\nexport interface FormValidationError {\n code?: string;\n message?: string;\n}\n\n/**\n * Checkout instance interface\n */\nexport interface CheckoutInstance {\n /** Mount and render the iframe into the container */\n render(): void;\n\n /** Submit payment - sends message to hosted checkout to confirm payment */\n submit(): void;\n\n /** Destroy instance and cleanup all listeners */\n destroy(): void;\n\n /** Subscribe to events. Returns unsubscribe function */\n on(event: EventName | SdkEvent, handler: (...args: any[]) => void): () => void;\n\n /** Subscribe to event that auto-unsubscribes after first emission */\n once(event: EventName | SdkEvent, handler: (...args: any[]) => void): () => void;\n\n /** Unsubscribe from events */\n off(event: EventName | SdkEvent, handler: (...args: any[]) => void): void;\n\n /** Check if checkout is currently mounted */\n isMounted(): boolean;\n\n /**\n * Complete form validation successfully - allows wallet payment to proceed.\n * Call this in response to 'form_validation' event when merchant form is valid.\n * @param wallet - The wallet type that requested validation ('apple_pay' | 'google_pay')\n */\n completeFormValidation(wallet: WalletType): void;\n\n /**\n * Fail form validation - prevents wallet payment from starting.\n * Call this in response to 'form_validation' event when merchant form has errors.\n * @param wallet - The wallet type that requested validation ('apple_pay' | 'google_pay')\n * @param errors - Optional array of validation errors to pass back\n */\n failFormValidation(wallet: WalletType, errors?: FormValidationError[]): void;\n}\n\n/**\n * PaypercutCheckout static interface (callable and constructable)\n */\nexport interface PaypercutCheckoutStatic {\n /** Callable factory function */\n (options: PaypercutCheckoutOptions): CheckoutInstance;\n\n /** Constructor support */\n new (options: PaypercutCheckoutOptions): CheckoutInstance;\n\n /** SDK version */\n version: string;\n}\n","import { Emitter } from './utils/emitter';\nimport { config, isOriginAllowed, getCheckoutOrigin } from './config';\n\nimport {\n PaypercutCheckoutOptions,\n CheckoutInstance,\n PaypercutCheckoutStatic,\n EventName,\n SdkEvent,\n validatePaymentMethods,\n validateWalletOptions,\n validateUIMode,\n UIMode,\n WalletType,\n FormValidationError,\n} from './types';\nimport { normalizeLocale } from './types';\n\n// Re-export types and enums for consumers\nexport type { PaypercutCheckoutOptions, CheckoutInstance, PaypercutCheckoutStatic, EventName, WalletType, FormValidationError };\n\nexport { UIMode, PaymentMethod, WalletOption } from './types/checkout';\n\n// Re-export SDK event enums for consumers\nexport { SdkEvent } from './types/checkout';\n\nexport type { Locale } from './types/locales';\nexport { LOCALES } from './types/locales';\n\n/**\n * Internal implementation of CheckoutInstance\n */\nclass CheckoutImpl implements CheckoutInstance {\n private emitter = new Emitter<EventName>();\n private mounted = false;\n private destroyed = false;\n private iframe: HTMLIFrameElement | null = null;\n private messageHandler: (evt: MessageEvent) => void;\n\n // 3DS Modal state\n private threeDSModal: HTMLDivElement | null = null;\n private threeDSIframe: HTMLIFrameElement | null = null;\n\n constructor(private options: PaypercutCheckoutOptions) {\n // Bind message handler\n this.messageHandler = this.onMessage.bind(this);\n window.addEventListener('message', this.messageHandler);\n }\n\n /**\n * Build the iframe source URL with query parameters\n */\n private buildSrc(): string {\n const baseUrl = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n const url = new URL(`/c/${this.options.id}`, baseUrl);\n\n // Add locale parameter\n if (this.options.locale) {\n const normalizedLocale = normalizeLocale(this.options.locale);\n url.searchParams.set('locale', normalizedLocale);\n }\n\n // Add lang parameter\n if (this.options.lang) {\n const normalizedLocale = normalizeLocale(this.options.lang);\n url.searchParams.set('lang', normalizedLocale);\n }\n\n // Add ui_mode parameter (default to 'embedded')\n {\n const selected = validateUIMode(this.options.ui_mode ?? UIMode.EMBEDDED);\n if (selected) {\n url.searchParams.set('ui_mode', selected);\n }\n }\n\n // Add payment_methods parameters (repeated for each method)\n if (this.options.payment_methods && this.options.payment_methods.length > 0) {\n const validatedMethods = validatePaymentMethods(this.options.payment_methods as string[]);\n validatedMethods.forEach((method) => {\n url.searchParams.append('payment_methods', method);\n });\n }\n\n // Add wallet_options parameters (repeated for each wallet)\n // If wallet_options is explicitly set (even as empty array), we need to pass it\n if (this.options.wallet_options !== undefined) {\n if (this.options.wallet_options.length === 0) {\n // Explicit empty array means \"no wallets\" - pass null (coerced to \"null\" string)\n url.searchParams.set('wallet_options', null as unknown as string);\n } else {\n const validatedWallets = validateWalletOptions(this.options.wallet_options as string[]);\n validatedWallets.forEach((wallet) => {\n url.searchParams.append('wallet_options', wallet);\n });\n }\n }\n\n if (this.options.appearance?.preset) {\n url.searchParams.set('preset', this.options.appearance.preset);\n }\n\n if (this.options.form_only !== undefined) {\n url.searchParams.set('form_only', String(this.options.form_only));\n }\n\n return url.toString();\n }\n\n /**\n * Get the container element from selector or HTMLElement\n */\n private getContainer(): HTMLElement {\n const container =\n typeof this.options.containerId === 'string'\n ? document.querySelector(this.options.containerId)\n : this.options.containerId;\n\n if (!container) {\n throw new Error(`Container not found: ${this.options.containerId}`);\n }\n\n return container as HTMLElement;\n }\n\n /**\n * Handle incoming postMessage events from iframe\n */\n private onMessage(evt: MessageEvent): void {\n // Validate origin against allowed origins (build-time whitelist)\n if (!isOriginAllowed(evt.origin)) {\n return;\n }\n\n // Validate structure\n const data = evt.data;\n if (!data || typeof data !== 'object' || !('type' in data)) {\n return;\n }\n\n // Filter messages by checkout session ID to prevent cross-instance message handling\n // This ensures each checkout instance only processes its own messages\n if (data.checkoutId && data.checkoutId !== this.options.id) {\n return; // Message is for a different checkout instance\n }\n\n // Handle specific events\n switch (data.type) {\n case 'CHECKOUT_LOADED':\n this.emitter.emit(SdkEvent.Loaded);\n break;\n case 'CHECKOUT_SUCCESS':\n const { payment_method = {} } = data;\n this.emitter.emit(SdkEvent.Success, { payment_method });\n break;\n case 'CHECKOUT_ERROR':\n // Forward error payload (if provided) to SDK consumers\n this.emitter.emit(SdkEvent.Error, (data && (data as any).error) ?? data);\n break;\n case 'CHECKOUT_EXPIRED':\n this.emitter.emit(SdkEvent.Expired);\n break;\n case 'CHECKOUT_RESIZE':\n this.emitter.emit(SdkEvent.Resize, data.height);\n this.handleResize(data.height);\n break;\n case 'THREEDS_START_FLOW':\n this.show3DSModal(data);\n this.emitter.emit(SdkEvent.ThreeDSStarted);\n break;\n case 'THREEDS_READY':\n this.handle3DSReady();\n break;\n case 'THREEDS_COMPLETE':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSComplete);\n break;\n case 'THREEDS_CANCELED':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSCanceled);\n break;\n case 'THREEDS_ERROR':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSError, data.error);\n break;\n case 'FORM_VALIDATION':\n // Wallet button clicked - emit event for merchant to validate their form\n this.emitter.emit(SdkEvent.FormValidation, {\n checkoutId: data.checkoutId,\n wallet: data.wallet as WalletType,\n });\n break;\n }\n }\n\n /**\n * Render the checkout iframe into the container\n */\n render(): void {\n if (this.mounted) {\n return;\n }\n\n try {\n const container = this.getContainer();\n\n // Create iframe\n this.iframe = document.createElement('iframe');\n this.iframe.id = 'paypercut-checkout-iframe';\n this.iframe.src = this.buildSrc();\n this.iframe.allow = 'payment *; clipboard-write';\n this.iframe.setAttribute('frameborder', '0');\n // Allow Payment Request API inside iframe and necessary sandbox permissions for wallets\n this.iframe.setAttribute('allowpaymentrequest', 'true');\n this.iframe.setAttribute(\n 'sandbox',\n 'allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox',\n );\n\n // Apply default styles - just construct URL and assign to iframe\n Object.assign(this.iframe.style, {\n width: '100%',\n height: '100%',\n border: 'none',\n display: 'block',\n });\n\n // Listen for iframe load event (fallback)\n // This ensures 'loaded' event is always emitted even if hosted checkout\n // doesn't send CHECKOUT_LOADED message\n /*this.iframe.addEventListener('load', () => {\n this.emitter.emit('loaded');\n });*/\n\n container.appendChild(this.iframe);\n this.mounted = true;\n } catch (err) {\n console.error('[PaypercutCheckout] Failed to render:', err);\n throw err;\n }\n }\n\n /**\n * Submit payment - sends message to hosted checkout to confirm payment\n */\n submit(): void {\n if (!this.mounted) {\n return;\n }\n\n try {\n this.postToIframe({\n type: 'START_PROCESSING',\n checkoutId: this.options.id,\n });\n } catch (err) {\n console.error('[PaypercutCheckout] Failed to submit payment:', err);\n throw err;\n }\n }\n\n /**\n * Send message to hosted/embedded checkout iframe - used for submit payment and communicating 3DS events\n */\n private postToIframe(message: any): void {\n if (!this.iframe?.contentWindow) {\n console.error('[PaypercutCheckout] Cannot post message: iframe not mounted');\n return;\n }\n\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n this.iframe.contentWindow.postMessage(message, checkoutOrigin);\n }\n\n /**\n * Handle CHECKOUT_RESIZE message - resize iframe to match content height\n */\n private handleResize(height: unknown): void {\n if (!this.iframe || typeof height !== 'number' || height <= 0) {\n return;\n }\n\n // Set iframe height to match content\n this.iframe.style.height = `${height}px`;\n }\n\n /**\n * Show 3DS modal with challenge/decoupled flow\n */\n private show3DSModal(data: {\n sessionId: string;\n step: 'challenge' | 'decoupled_waiting';\n challengeUrl?: string;\n acsTransactionId?: string;\n threeDSVersion?: string;\n cardBrand?: string;\n liveMode?: boolean;\n }): void {\n // Create modal backdrop\n this.threeDSModal = document.createElement('div');\n this.threeDSModal.id = 'paypercut-3ds-modal';\n Object.assign(this.threeDSModal.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: '999999',\n background: 'rgba(0, 0, 0, 0.4)',\n });\n\n // Create iframe for 3DS page\n this.threeDSIframe = document.createElement('iframe');\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n\n // Build URL: baseUrl/c/{checkoutId}/threeds with query params\n const threeDSUrl = new URL(`/c/${this.options.id}/threeds`, checkoutOrigin);\n threeDSUrl.searchParams.set('sessionId', data.sessionId);\n threeDSUrl.searchParams.set('step', data.step);\n\n if (data.challengeUrl) {\n threeDSUrl.searchParams.set('challengeUrl', data.challengeUrl);\n }\n if (data.acsTransactionId) {\n threeDSUrl.searchParams.set('acsTransactionId', data.acsTransactionId);\n }\n if (data.threeDSVersion) {\n threeDSUrl.searchParams.set('threeDSVersion', data.threeDSVersion);\n }\n // Always include liveMode; default to false when undefined\n threeDSUrl.searchParams.set('liveMode', String(data.liveMode ?? false));\n\n this.threeDSIframe.src = threeDSUrl.toString();\n this.threeDSIframe.allow = 'payment *';\n this.threeDSIframe.setAttribute('frameborder', '0');\n\n // Fixed dimensions: follow 3DS component size (500x500)\n Object.assign(this.threeDSIframe.style, {\n minWidth: '400px',\n minHeight: '400px',\n border: 'none',\n borderRadius: '8px',\n display: 'block',\n background: 'transparent',\n });\n\n // Append iframe directly to modal backdrop\n this.threeDSModal.appendChild(this.threeDSIframe);\n document.body.appendChild(this.threeDSModal);\n\n // Store 3DS data for later use\n (this as any).pending3DSData = data;\n }\n\n /**\n * Handle THREEDS_READY message - send THREEDS_INIT with challenge data\n */\n private handle3DSReady(): void {\n const data = (this as any).pending3DSData;\n if (!data || !this.threeDSIframe?.contentWindow) {\n console.error('[PaypercutCheckout] No pending 3DS data or iframe not ready');\n return;\n }\n\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n this.threeDSIframe.contentWindow.postMessage(\n {\n type: 'THREEDS_INIT',\n checkoutId: this.options.id,\n },\n checkoutOrigin,\n );\n }\n\n /**\n * Close 3DS modal and cleanup\n */\n private close3DSModal(): void {\n if (this.threeDSModal) {\n this.threeDSModal.remove();\n this.threeDSModal = null;\n }\n\n this.threeDSIframe = null;\n delete (this as any).pending3DSData;\n }\n\n /**\n * Destroy the checkout instance and cleanup (idempotent)\n */\n destroy(): void {\n // Early return if already destroyed\n if (this.destroyed) {\n return;\n }\n\n // Remove iframe from DOM\n if (this.iframe) {\n try {\n this.iframe.remove();\n this.iframe = null;\n } catch (err) {\n console.error('[PaypercutCheckout] Error removing iframe:', err);\n }\n }\n\n // Cleanup 3DS modal if open\n this.close3DSModal();\n\n // Only set mounted = false after successful DOM removal\n this.mounted = false;\n this.destroyed = true;\n\n // Cleanup event listeners\n window.removeEventListener('message', this.messageHandler);\n this.emitter.clear();\n }\n\n /**\n * Subscribe to an event\n */\n on(event: EventName, handler: (...args: any[]) => void): () => void {\n return this.emitter.on(event, handler);\n }\n\n /**\n * Subscribe to event that auto-unsubscribes after first emission\n */\n once(event: EventName, handler: (...args: any[]) => void): () => void {\n return this.emitter.once(event, handler);\n }\n\n /**\n * Unsubscribe from an event\n */\n off(event: EventName, handler: (...args: any[]) => void): void {\n this.emitter.off(event, handler);\n }\n\n /**\n * Check if checkout is currently mounted\n */\n isMounted(): boolean {\n return this.mounted;\n }\n\n /**\n * Complete form validation successfully - allows wallet payment to proceed.\n * Call this in response to 'form_validation' event when merchant form is valid.\n */\n completeFormValidation(wallet: WalletType): void {\n if (!this.mounted) {\n console.warn('[PaypercutCheckout] Cannot complete form validation: not mounted');\n return;\n }\n\n this.postToIframe({\n type: 'FORM_VALIDATION_COMPLETED',\n checkoutId: this.options.id,\n wallet,\n status: 'success',\n });\n }\n\n /**\n * Fail form validation - prevents wallet payment from starting.\n * Call this in response to 'form_validation' event when merchant form has errors.\n */\n failFormValidation(wallet: WalletType, errors?: FormValidationError[]): void {\n if (!this.mounted) {\n console.warn('[PaypercutCheckout] Cannot fail form validation: not mounted');\n return;\n }\n\n this.postToIframe({\n type: 'FORM_VALIDATION_COMPLETED',\n checkoutId: this.options.id,\n wallet,\n status: 'failed',\n errors,\n });\n }\n}\n\n/**\n * Factory function that works both as callable and constructable.\n * Always returns a new CheckoutImpl instance - no prototype manipulation needed.\n */\nconst PaypercutCheckout: PaypercutCheckoutStatic = function (\n this: unknown,\n options: PaypercutCheckoutOptions,\n): CheckoutInstance {\n // Always return a new instance, regardless of how it's called\n return new CheckoutImpl(options);\n} as unknown as PaypercutCheckoutStatic;\n\n// Add static version property\n(PaypercutCheckout as any).version = config.version;\n\n// Export as default and named\nexport default PaypercutCheckout;\nexport { PaypercutCheckout };\n"],"names":["UIMode","PaymentMethod","WalletOption","SdkEvent"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ declare const LOCALES: readonly ["bg", "bg-BG", "en", "en-GB", "el", "el-GR", "r
|
|
|
28
28
|
* @example
|
|
29
29
|
* ```typescript
|
|
30
30
|
* const locale: Locale = 'bg';
|
|
31
|
+
* const lang: Locale = 'bg';
|
|
31
32
|
* const autoLocale: Locale = 'auto';
|
|
32
33
|
* ```
|
|
33
34
|
*/
|
|
@@ -74,6 +75,11 @@ interface PaypercutCheckoutOptions {
|
|
|
74
75
|
* @default 'en'
|
|
75
76
|
*/
|
|
76
77
|
locale?: Locale | string;
|
|
78
|
+
/**
|
|
79
|
+
* Optional: Language for checkout UI
|
|
80
|
+
* @default 'en'
|
|
81
|
+
*/
|
|
82
|
+
lang?: Locale | string;
|
|
77
83
|
/**
|
|
78
84
|
* Optional: UI mode for checkout
|
|
79
85
|
*/
|
|
@@ -105,10 +111,14 @@ interface PaypercutCheckoutOptions {
|
|
|
105
111
|
labels: 'floating' | 'above' | 'none';
|
|
106
112
|
};
|
|
107
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Wallet type for form validation
|
|
116
|
+
*/
|
|
117
|
+
type WalletType = 'apple_pay' | 'google_pay';
|
|
108
118
|
/**
|
|
109
119
|
* Event names that can be emitted by the checkout
|
|
110
120
|
*/
|
|
111
|
-
type EventName = 'loaded' | 'success' | 'error' | 'expired' | 'resize' | 'threeds_complete' | 'threeds_error' | 'threeds_canceled' | 'threeds_started';
|
|
121
|
+
type EventName = 'loaded' | 'success' | 'error' | 'expired' | 'resize' | 'threeds_complete' | 'threeds_error' | 'threeds_canceled' | 'threeds_started' | 'form_validation';
|
|
112
122
|
/**
|
|
113
123
|
* Preferred enum for SDK event names (use instead of hardcoded strings)
|
|
114
124
|
*/
|
|
@@ -121,7 +131,15 @@ declare enum SdkEvent {
|
|
|
121
131
|
ThreeDSComplete = "threeds_complete",
|
|
122
132
|
ThreeDSError = "threeds_error",
|
|
123
133
|
ThreeDSCanceled = "threeds_canceled",
|
|
124
|
-
ThreeDSStarted = "threeds_started"
|
|
134
|
+
ThreeDSStarted = "threeds_started",
|
|
135
|
+
FormValidation = "form_validation"
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Form validation error for failFormValidation
|
|
139
|
+
*/
|
|
140
|
+
interface FormValidationError {
|
|
141
|
+
code?: string;
|
|
142
|
+
message?: string;
|
|
125
143
|
}
|
|
126
144
|
/**
|
|
127
145
|
* Checkout instance interface
|
|
@@ -141,6 +159,19 @@ interface CheckoutInstance {
|
|
|
141
159
|
off(event: EventName | SdkEvent, handler: (...args: any[]) => void): void;
|
|
142
160
|
/** Check if checkout is currently mounted */
|
|
143
161
|
isMounted(): boolean;
|
|
162
|
+
/**
|
|
163
|
+
* Complete form validation successfully - allows wallet payment to proceed.
|
|
164
|
+
* Call this in response to 'form_validation' event when merchant form is valid.
|
|
165
|
+
* @param wallet - The wallet type that requested validation ('apple_pay' | 'google_pay')
|
|
166
|
+
*/
|
|
167
|
+
completeFormValidation(wallet: WalletType): void;
|
|
168
|
+
/**
|
|
169
|
+
* Fail form validation - prevents wallet payment from starting.
|
|
170
|
+
* Call this in response to 'form_validation' event when merchant form has errors.
|
|
171
|
+
* @param wallet - The wallet type that requested validation ('apple_pay' | 'google_pay')
|
|
172
|
+
* @param errors - Optional array of validation errors to pass back
|
|
173
|
+
*/
|
|
174
|
+
failFormValidation(wallet: WalletType, errors?: FormValidationError[]): void;
|
|
144
175
|
}
|
|
145
176
|
/**
|
|
146
177
|
* PaypercutCheckout static interface (callable and constructable)
|
|
@@ -161,4 +192,4 @@ interface PaypercutCheckoutStatic {
|
|
|
161
192
|
declare const PaypercutCheckout: PaypercutCheckoutStatic;
|
|
162
193
|
|
|
163
194
|
export { LOCALES, PaymentMethod, PaypercutCheckout, SdkEvent, UIMode, WalletOption, PaypercutCheckout as default };
|
|
164
|
-
export type { CheckoutInstance, EventName, Locale, PaypercutCheckoutOptions, PaypercutCheckoutStatic };
|
|
195
|
+
export type { CheckoutInstance, EventName, FormValidationError, Locale, PaypercutCheckoutOptions, PaypercutCheckoutStatic, WalletType };
|
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.
|
|
83
|
+
version: "1.0.13",
|
|
84
84
|
defaultCheckoutOrigin: 'https://buy.paypercut.io',
|
|
85
85
|
allowedOrigins: [
|
|
86
86
|
'https://buy.paypercut.io',
|
|
@@ -275,6 +275,7 @@ var SdkEvent;
|
|
|
275
275
|
SdkEvent["ThreeDSError"] = "threeds_error";
|
|
276
276
|
SdkEvent["ThreeDSCanceled"] = "threeds_canceled";
|
|
277
277
|
SdkEvent["ThreeDSStarted"] = "threeds_started";
|
|
278
|
+
SdkEvent["FormValidation"] = "form_validation";
|
|
278
279
|
})(SdkEvent || (SdkEvent = {}));
|
|
279
280
|
|
|
280
281
|
/**
|
|
@@ -305,6 +306,11 @@ class CheckoutImpl {
|
|
|
305
306
|
const normalizedLocale = normalizeLocale(this.options.locale);
|
|
306
307
|
url.searchParams.set('locale', normalizedLocale);
|
|
307
308
|
}
|
|
309
|
+
// Add lang parameter
|
|
310
|
+
if (this.options.lang) {
|
|
311
|
+
const normalizedLocale = normalizeLocale(this.options.lang);
|
|
312
|
+
url.searchParams.set('lang', normalizedLocale);
|
|
313
|
+
}
|
|
308
314
|
// Add ui_mode parameter (default to 'embedded')
|
|
309
315
|
{
|
|
310
316
|
const selected = validateUIMode(this.options.ui_mode ?? UIMode.EMBEDDED);
|
|
@@ -413,6 +419,13 @@ class CheckoutImpl {
|
|
|
413
419
|
this.close3DSModal();
|
|
414
420
|
this.emitter.emit(SdkEvent.ThreeDSError, data.error);
|
|
415
421
|
break;
|
|
422
|
+
case 'FORM_VALIDATION':
|
|
423
|
+
// Wallet button clicked - emit event for merchant to validate their form
|
|
424
|
+
this.emitter.emit(SdkEvent.FormValidation, {
|
|
425
|
+
checkoutId: data.checkoutId,
|
|
426
|
+
wallet: data.wallet,
|
|
427
|
+
});
|
|
428
|
+
break;
|
|
416
429
|
}
|
|
417
430
|
}
|
|
418
431
|
/**
|
|
@@ -625,6 +638,39 @@ class CheckoutImpl {
|
|
|
625
638
|
isMounted() {
|
|
626
639
|
return this.mounted;
|
|
627
640
|
}
|
|
641
|
+
/**
|
|
642
|
+
* Complete form validation successfully - allows wallet payment to proceed.
|
|
643
|
+
* Call this in response to 'form_validation' event when merchant form is valid.
|
|
644
|
+
*/
|
|
645
|
+
completeFormValidation(wallet) {
|
|
646
|
+
if (!this.mounted) {
|
|
647
|
+
console.warn('[PaypercutCheckout] Cannot complete form validation: not mounted');
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
this.postToIframe({
|
|
651
|
+
type: 'FORM_VALIDATION_COMPLETED',
|
|
652
|
+
checkoutId: this.options.id,
|
|
653
|
+
wallet,
|
|
654
|
+
status: 'success',
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Fail form validation - prevents wallet payment from starting.
|
|
659
|
+
* Call this in response to 'form_validation' event when merchant form has errors.
|
|
660
|
+
*/
|
|
661
|
+
failFormValidation(wallet, errors) {
|
|
662
|
+
if (!this.mounted) {
|
|
663
|
+
console.warn('[PaypercutCheckout] Cannot fail form validation: not mounted');
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
this.postToIframe({
|
|
667
|
+
type: 'FORM_VALIDATION_COMPLETED',
|
|
668
|
+
checkoutId: this.options.id,
|
|
669
|
+
wallet,
|
|
670
|
+
status: 'failed',
|
|
671
|
+
errors,
|
|
672
|
+
});
|
|
673
|
+
}
|
|
628
674
|
}
|
|
629
675
|
/**
|
|
630
676
|
* Factory function that works both as callable and constructable.
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/utils/emitter.ts","../src/config.ts","../src/types/locales.ts","../src/types/checkout.ts","../src/index.ts"],"sourcesContent":["/**\n * Simple event emitter for handling checkout events\n * Supports subscribing, unsubscribing, and emitting events\n */\nexport class Emitter<T extends string = string> {\n private handlers = new Map<T, Set<Function>>();\n\n /**\n * Subscribe to an event\n * @param event - Event name to listen to\n * @param handler - Callback function to execute when event is emitted\n * @returns Unsubscribe function\n */\n on(event: T, handler: Function): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n /**\n * Subscribe to an event that auto-unsubscribes after first emission\n *\n * Common use case: waiting for 'loaded' event or handling first 'success'.\n * Without this helper, developers would need to manually unsubscribe inside\n * their handler, which is error-prone and leads to memory leaks if forgotten.\n *\n * @param event - Event name to listen to\n * @param handler - Callback function to execute when event is emitted\n * @returns Unsubscribe function\n */\n once(event: T, handler: Function): () => void {\n const wrappedHandler = (...args: any[]) => {\n handler(...args);\n this.off(event, wrappedHandler);\n };\n return this.on(event, wrappedHandler);\n }\n\n /**\n * Unsubscribe from an event\n * @param event - Event name to stop listening to\n * @param handler - Callback function to remove\n */\n off(event: T, handler: Function): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n /**\n * Emit an event with optional arguments\n * @param event - Event name to emit\n * @param args - Arguments to pass to event handlers\n */\n emit(event: T, ...args: any[]): void {\n this.handlers.get(event)?.forEach(h => {\n try {\n h(...args);\n } catch (err) {\n console.error(`[Emitter] Error in ${event} handler:`, err);\n }\n });\n }\n\n /**\n * Clear all event handlers\n */\n clear(): void {\n this.handlers.clear();\n }\n}\n\n","/**\n * Build-time configuration\n * \n * This file is processed at build time with different values for:\n * - Production build (for merchants)\n * - Internal build (for team development)\n */\n\n/**\n * Build mode - replaced at build time\n */\ndeclare const __BUILD_MODE__: 'production' | 'internal';\n\n/**\n * SDK version - replaced at build time\n */\ndeclare const __VERSION__: string;\n\n/**\n * Configuration interface\n */\nexport interface BuildConfig {\n /** SDK version */\n version: string;\n \n /** Build mode */\n mode: 'production' | 'internal';\n \n /** Default checkout origin (production URL) */\n defaultCheckoutOrigin: string;\n \n /** Allowed origins for postMessage validation */\n allowedOrigins: string[];\n \n /** Whether hostedCheckoutUrl override is allowed */\n allowOriginOverride: boolean;\n}\n\n/**\n * Production configuration (for merchants)\n */\nconst productionConfig: BuildConfig = {\n version: __VERSION__,\n mode: 'production',\n defaultCheckoutOrigin: 'https://buy.paypercut.io',\n allowedOrigins: [\n 'https://buy.paypercut.io',\n ],\n allowOriginOverride: false\n};\n\n/**\n * Internal configuration (for team development)\n */\nconst internalConfig: BuildConfig = {\n version: __VERSION__,\n mode: 'internal',\n defaultCheckoutOrigin: 'https://buy.paypercut.io',\n allowedOrigins: [\n 'https://buy.paypercut.io',\n 'http://localhost:3000',\n 'http://localhost:3001',\n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001'\n ],\n allowOriginOverride: true\n};\n\n/**\n * Active configuration (selected at build time)\n */\nexport const config: BuildConfig = __BUILD_MODE__ === 'internal' \n ? internalConfig \n : productionConfig;\n\n/**\n * Helper to check if origin is allowed\n */\nexport function isOriginAllowed(origin: string): boolean {\n return config.allowedOrigins.includes(origin);\n}\n\n/**\n * Get the checkout origin (with optional override for internal builds)\n */\nexport function getCheckoutOrigin(override?: string): string {\n // Only allow override in internal builds\n if (override && config.allowOriginOverride) {\n return override;\n }\n \n return config.defaultCheckoutOrigin;\n}\n\n","/**\n * Supported locales for Paypercut Checkout\n * \n * @remarks\n * Single source of truth for all supported locale codes.\n * \n * Supported languages:\n * - Bulgarian: 'bg', 'bg-BG'\n * - English: 'en', 'en-GB'\n * - Greek: 'el', 'el-GR'\n * - Romanian: 'ro', 'ro-RO'\n * - Croatian: 'hr', 'hr-HR'\n * - Polish: 'pl', 'pl-PL'\n * - Czech: 'cs', 'cs-CZ'\n * - Slovenian: 'sl', 'sl-SI'\n * - Slovak: 'sk', 'sk-SK'\n * \n * @example\n * ```typescript\n * const checkout = PaypercutCheckout({\n * locale: 'bg' // or 'bg-BG', 'en', 'en-GB', etc.\n * });\n * ```\n */\nexport const LOCALES = [\n 'bg', 'bg-BG',\n 'en', 'en-GB',\n 'el', 'el-GR',\n 'ro', 'ro-RO',\n 'hr', 'hr-HR',\n 'pl', 'pl-PL',\n 'cs', 'cs-CZ',\n 'sl', 'sl-SI',\n 'sk', 'sk-SK',\n] as const;\n\n/**\n * Locale type - union of all supported locale codes plus 'auto'\n * @example\n * ```typescript\n * const locale: Locale = 'bg';\n * const autoLocale: Locale = 'auto';\n * ```\n */\nexport type Locale = typeof LOCALES[number] | 'auto';\n\n/**\n * Fast runtime check using Set for O(1) lookup\n * @internal\n */\nconst LOCALE_SET: ReadonlySet<string> = new Set(LOCALES);\n\n/**\n * Normalize and validate locale\n * \n * @param locale - Locale code to normalize\n * @returns Normalized locale code or 'en' as fallback\n * \n * @remarks\n * - 'auto' or empty → 'en'\n * - Unsupported locale → 'en' with console warning\n * - Supported locale → original value\n * \n * @example\n * ```typescript\n * normalizeLocale('auto') // → 'en'\n * normalizeLocale('bg') // → 'bg'\n * normalizeLocale('de') // → 'en' (with warning)\n * ```\n */\nexport function normalizeLocale(locale: string | Locale): typeof LOCALES[number] | 'en' {\n if (!locale || locale === 'auto') return 'en';\n if (LOCALE_SET.has(locale)) return locale as typeof LOCALES[number];\n console.warn(`[PaypercutCheckout] Locale \"${locale}\" is not supported. Falling back to \"en\".`);\n return 'en';\n}\n\n","import { Locale } from './locales';\n\n/**\n * UI mode for checkout\n */\nexport enum UIMode {\n /** Embedded mode - checkout embedded in merchant page */\n EMBEDDED = 'embedded',\n}\n\n/**\n * Type guard for UIMode\n */\nexport function isValidUIMode(value: string): value is UIMode {\n return Object.values(UIMode).includes(value as UIMode);\n}\n\n/**\n * Payment method types\n */\nexport enum PaymentMethod {\n /** Card payment (credit/debit) */\n CARD = 'card',\n}\n\n/**\n * Type guard for PaymentMethod\n */\nexport function isValidPaymentMethod(value: string): value is PaymentMethod {\n return Object.values(PaymentMethod).includes(value as PaymentMethod);\n}\n\n/**\n * Wallet options for digital wallets\n */\nexport enum WalletOption {\n /** Apple Pay */\n APPLE_PAY = 'apple_pay',\n /** Google Pay */\n GOOGLE_PAY = 'google_pay',\n}\n\n/**\n * Type guard for WalletOption\n */\nexport function isValidWalletOption(value: string): value is WalletOption {\n return Object.values(WalletOption).includes(value as WalletOption);\n}\n\n/**\n * Validate payment methods array\n */\nexport function validatePaymentMethods(methods: string[]): PaymentMethod[] {\n const validated: PaymentMethod[] = [];\n\n for (const method of methods) {\n if (isValidPaymentMethod(method)) {\n validated.push(method as PaymentMethod);\n } else {\n console.warn(`[PaypercutCheckout] Invalid payment method: \"${method}\". Skipping.`);\n }\n }\n\n // Default to card if no valid methods\n if (validated.length === 0) {\n console.warn('[PaypercutCheckout] No valid payment methods provided. Defaulting to \"card\".');\n validated.push(PaymentMethod.CARD);\n }\n\n return validated;\n}\n\n/**\n * Validate wallet options array\n */\nexport function validateWalletOptions(options: string[]): WalletOption[] {\n const validated: WalletOption[] = [];\n\n for (const option of options) {\n if (isValidWalletOption(option)) {\n validated.push(option as WalletOption);\n } else {\n console.warn(`[PaypercutCheckout] Invalid wallet option: \"${option}\". Skipping.`);\n }\n }\n\n return validated;\n}\n\n/**\n * Validate UI mode\n */\nexport function validateUIMode(mode: string | undefined): UIMode | undefined {\n if (!mode) {\n return undefined;\n }\n\n if (isValidUIMode(mode)) {\n return mode as UIMode;\n }\n\n console.warn(\n `[PaypercutCheckout] Invalid ui_mode: \"${mode}\". Valid options: ${Object.values(UIMode).join(', ')}`,\n );\n return undefined;\n}\n\n/**\n * Configuration options for PaypercutCheckout\n */\nexport interface PaypercutCheckoutOptions {\n /** Checkout session identifier (e.g., 'CHK_12345') */\n id: string;\n\n /** CSS selector or HTMLElement where iframe mounts (required) */\n containerId: string | HTMLElement;\n\n /**\n * Optional: Custom hosted checkout URL (only available in internal builds)\n * Production builds will ignore this option for security\n */\n hostedCheckoutUrl?: string;\n\n /**\n * Optional: Locale for checkout UI\n * @default 'en'\n */\n locale?: Locale | string;\n\n /**\n * Optional: UI mode for checkout\n */\n ui_mode?: UIMode | `${UIMode}`;\n\n /**\n * Optional: Payment methods to enable\n * @default ['card']\n */\n payment_methods?: (PaymentMethod | `${PaymentMethod}`)[];\n\n /**\n * Optional: Digital wallet options\n * Can include both or just one\n * Default behaviour - shows both\n */\n wallet_options?: (WalletOption | `${WalletOption}`)[] | [];\n\n /**\n * Optional: Show only the payment form without header/footer\n * @default false\n */\n form_only?: boolean;\n\n /**\n * Optional: Appearance options\n */\n appearance?: {\n preset?: 'inline' | 'modal';\n theme?: 'light' | 'dark' | 'none' | 'flat';\n variables: {};\n rules: {};\n labels: 'floating' | 'above' | 'none';\n };\n}\n\n/**\n * Event names that can be emitted by the checkout\n */\nexport type EventName =\n | 'loaded' // iframe finished loading\n | 'success' // payment successful\n | 'error' // payment or system error\n | 'expired' // checkout expired or already paid\n | 'resize' // checkout expired or already paid\n | 'threeds_complete' // checkout paid successfully\n | 'threeds_error' // checkout threeds error\n | 'threeds_canceled' // checkout threeds canceled\n | 'threeds_started'; // checkout threeds started\n\n/**\n * Preferred enum for SDK event names (use instead of hardcoded strings)\n */\nexport enum SdkEvent {\n Loaded = 'loaded',\n Success = 'success',\n Error = 'error',\n Expired = 'expired',\n Resize = 'resize',\n ThreeDSComplete = 'threeds_complete',\n ThreeDSError = 'threeds_error',\n ThreeDSCanceled = 'threeds_canceled',\n ThreeDSStarted = 'threeds_started',\n}\n\n/**\n * Checkout instance interface\n */\nexport interface CheckoutInstance {\n /** Mount and render the iframe into the container */\n render(): void;\n\n /** Submit payment - sends message to hosted checkout to confirm payment */\n submit(): void;\n\n /** Destroy instance and cleanup all listeners */\n destroy(): void;\n\n /** Subscribe to events. Returns unsubscribe function */\n on(event: EventName | SdkEvent, handler: (...args: any[]) => void): () => void;\n\n /** Subscribe to event that auto-unsubscribes after first emission */\n once(event: EventName | SdkEvent, handler: (...args: any[]) => void): () => void;\n\n /** Unsubscribe from events */\n off(event: EventName | SdkEvent, handler: (...args: any[]) => void): void;\n\n /** Check if checkout is currently mounted */\n isMounted(): boolean;\n}\n\n/**\n * PaypercutCheckout static interface (callable and constructable)\n */\nexport interface PaypercutCheckoutStatic {\n /** Callable factory function */\n (options: PaypercutCheckoutOptions): CheckoutInstance;\n\n /** Constructor support */\n new (options: PaypercutCheckoutOptions): CheckoutInstance;\n\n /** SDK version */\n version: string;\n}\n","import { Emitter } from './utils/emitter';\nimport { config, isOriginAllowed, getCheckoutOrigin } from './config';\n\nimport {\n PaypercutCheckoutOptions,\n CheckoutInstance,\n PaypercutCheckoutStatic,\n EventName,\n SdkEvent,\n validatePaymentMethods,\n validateWalletOptions,\n validateUIMode,\n UIMode,\n} from './types';\nimport { normalizeLocale } from './types';\n\n// Re-export types and enums for consumers\nexport type { PaypercutCheckoutOptions, CheckoutInstance, PaypercutCheckoutStatic, EventName };\n\nexport { UIMode, PaymentMethod, WalletOption } from './types/checkout';\n\n// Re-export SDK event enums for consumers\nexport { SdkEvent } from './types/checkout';\n\nexport type { Locale } from './types/locales';\nexport { LOCALES } from './types/locales';\n\n/**\n * Internal implementation of CheckoutInstance\n */\nclass CheckoutImpl implements CheckoutInstance {\n private emitter = new Emitter<EventName>();\n private mounted = false;\n private destroyed = false;\n private iframe: HTMLIFrameElement | null = null;\n private messageHandler: (evt: MessageEvent) => void;\n\n // 3DS Modal state\n private threeDSModal: HTMLDivElement | null = null;\n private threeDSIframe: HTMLIFrameElement | null = null;\n\n constructor(private options: PaypercutCheckoutOptions) {\n // Bind message handler\n this.messageHandler = this.onMessage.bind(this);\n window.addEventListener('message', this.messageHandler);\n }\n\n /**\n * Build the iframe source URL with query parameters\n */\n private buildSrc(): string {\n const baseUrl = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n const url = new URL(`/c/${this.options.id}`, baseUrl);\n\n // Add locale parameter\n if (this.options.locale) {\n const normalizedLocale = normalizeLocale(this.options.locale);\n url.searchParams.set('locale', normalizedLocale);\n }\n\n // Add ui_mode parameter (default to 'embedded')\n {\n const selected = validateUIMode(this.options.ui_mode ?? UIMode.EMBEDDED);\n if (selected) {\n url.searchParams.set('ui_mode', selected);\n }\n }\n\n // Add payment_methods parameters (repeated for each method)\n if (this.options.payment_methods && this.options.payment_methods.length > 0) {\n const validatedMethods = validatePaymentMethods(this.options.payment_methods as string[]);\n validatedMethods.forEach((method) => {\n url.searchParams.append('payment_methods', method);\n });\n }\n\n // Add wallet_options parameters (repeated for each wallet)\n // If wallet_options is explicitly set (even as empty array), we need to pass it\n if (this.options.wallet_options !== undefined) {\n if (this.options.wallet_options.length === 0) {\n // Explicit empty array means \"no wallets\" - pass null (coerced to \"null\" string)\n url.searchParams.set('wallet_options', null as unknown as string);\n } else {\n const validatedWallets = validateWalletOptions(this.options.wallet_options as string[]);\n validatedWallets.forEach((wallet) => {\n url.searchParams.append('wallet_options', wallet);\n });\n }\n }\n\n if (this.options.appearance?.preset) {\n url.searchParams.set('preset', this.options.appearance.preset);\n }\n\n if (this.options.form_only !== undefined) {\n url.searchParams.set('form_only', String(this.options.form_only));\n }\n\n return url.toString();\n }\n\n /**\n * Get the container element from selector or HTMLElement\n */\n private getContainer(): HTMLElement {\n const container =\n typeof this.options.containerId === 'string'\n ? document.querySelector(this.options.containerId)\n : this.options.containerId;\n\n if (!container) {\n throw new Error(`Container not found: ${this.options.containerId}`);\n }\n\n return container as HTMLElement;\n }\n\n /**\n * Handle incoming postMessage events from iframe\n */\n private onMessage(evt: MessageEvent): void {\n // Validate origin against allowed origins (build-time whitelist)\n if (!isOriginAllowed(evt.origin)) {\n return;\n }\n\n // Validate structure\n const data = evt.data;\n if (!data || typeof data !== 'object' || !('type' in data)) {\n return;\n }\n\n // Filter messages by checkout session ID to prevent cross-instance message handling\n // This ensures each checkout instance only processes its own messages\n if (data.checkoutId && data.checkoutId !== this.options.id) {\n return; // Message is for a different checkout instance\n }\n\n // Handle specific events\n switch (data.type) {\n case 'CHECKOUT_LOADED':\n this.emitter.emit(SdkEvent.Loaded);\n break;\n case 'CHECKOUT_SUCCESS':\n const { payment_method = {} } = data;\n this.emitter.emit(SdkEvent.Success, { payment_method });\n break;\n case 'CHECKOUT_ERROR':\n // Forward error payload (if provided) to SDK consumers\n this.emitter.emit(SdkEvent.Error, (data && (data as any).error) ?? data);\n break;\n case 'CHECKOUT_EXPIRED':\n this.emitter.emit(SdkEvent.Expired);\n break;\n case 'CHECKOUT_RESIZE':\n this.emitter.emit(SdkEvent.Resize, data.height);\n this.handleResize(data.height);\n break;\n case 'THREEDS_START_FLOW':\n this.show3DSModal(data);\n this.emitter.emit(SdkEvent.ThreeDSStarted);\n break;\n case 'THREEDS_READY':\n this.handle3DSReady();\n break;\n case 'THREEDS_COMPLETE':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSComplete);\n break;\n case 'THREEDS_CANCELED':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSCanceled);\n break;\n case 'THREEDS_ERROR':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSError, data.error);\n break;\n }\n }\n\n /**\n * Render the checkout iframe into the container\n */\n render(): void {\n if (this.mounted) {\n return;\n }\n\n try {\n const container = this.getContainer();\n\n // Create iframe\n this.iframe = document.createElement('iframe');\n this.iframe.id = 'paypercut-checkout-iframe';\n this.iframe.src = this.buildSrc();\n this.iframe.allow = 'payment *; clipboard-write';\n this.iframe.setAttribute('frameborder', '0');\n // Allow Payment Request API inside iframe and necessary sandbox permissions for wallets\n this.iframe.setAttribute('allowpaymentrequest', 'true');\n this.iframe.setAttribute(\n 'sandbox',\n 'allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox',\n );\n\n // Apply default styles - just construct URL and assign to iframe\n Object.assign(this.iframe.style, {\n width: '100%',\n height: '100%',\n border: 'none',\n display: 'block',\n });\n\n // Listen for iframe load event (fallback)\n // This ensures 'loaded' event is always emitted even if hosted checkout\n // doesn't send CHECKOUT_LOADED message\n /*this.iframe.addEventListener('load', () => {\n this.emitter.emit('loaded');\n });*/\n\n container.appendChild(this.iframe);\n this.mounted = true;\n } catch (err) {\n console.error('[PaypercutCheckout] Failed to render:', err);\n throw err;\n }\n }\n\n /**\n * Submit payment - sends message to hosted checkout to confirm payment\n */\n submit(): void {\n if (!this.mounted) {\n return;\n }\n\n try {\n this.postToIframe({\n type: 'START_PROCESSING',\n checkoutId: this.options.id,\n });\n } catch (err) {\n console.error('[PaypercutCheckout] Failed to submit payment:', err);\n throw err;\n }\n }\n\n /**\n * Send message to hosted/embedded checkout iframe - used for submit payment and communicating 3DS events\n */\n private postToIframe(message: any): void {\n if (!this.iframe?.contentWindow) {\n console.error('[PaypercutCheckout] Cannot post message: iframe not mounted');\n return;\n }\n\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n this.iframe.contentWindow.postMessage(message, checkoutOrigin);\n }\n\n /**\n * Handle CHECKOUT_RESIZE message - resize iframe to match content height\n */\n private handleResize(height: unknown): void {\n if (!this.iframe || typeof height !== 'number' || height <= 0) {\n return;\n }\n\n // Set iframe height to match content\n this.iframe.style.height = `${height}px`;\n }\n\n /**\n * Show 3DS modal with challenge/decoupled flow\n */\n private show3DSModal(data: {\n sessionId: string;\n step: 'challenge' | 'decoupled_waiting';\n challengeUrl?: string;\n acsTransactionId?: string;\n threeDSVersion?: string;\n cardBrand?: string;\n liveMode?: boolean;\n }): void {\n // Create modal backdrop\n this.threeDSModal = document.createElement('div');\n this.threeDSModal.id = 'paypercut-3ds-modal';\n Object.assign(this.threeDSModal.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: '999999',\n background: 'rgba(0, 0, 0, 0.4)',\n });\n\n // Create iframe for 3DS page\n this.threeDSIframe = document.createElement('iframe');\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n\n // Build URL: baseUrl/c/{checkoutId}/threeds with query params\n const threeDSUrl = new URL(`/c/${this.options.id}/threeds`, checkoutOrigin);\n threeDSUrl.searchParams.set('sessionId', data.sessionId);\n threeDSUrl.searchParams.set('step', data.step);\n\n if (data.challengeUrl) {\n threeDSUrl.searchParams.set('challengeUrl', data.challengeUrl);\n }\n if (data.acsTransactionId) {\n threeDSUrl.searchParams.set('acsTransactionId', data.acsTransactionId);\n }\n if (data.threeDSVersion) {\n threeDSUrl.searchParams.set('threeDSVersion', data.threeDSVersion);\n }\n // Always include liveMode; default to false when undefined\n threeDSUrl.searchParams.set('liveMode', String(data.liveMode ?? false));\n\n this.threeDSIframe.src = threeDSUrl.toString();\n this.threeDSIframe.allow = 'payment *';\n this.threeDSIframe.setAttribute('frameborder', '0');\n\n // Fixed dimensions: follow 3DS component size (500x500)\n Object.assign(this.threeDSIframe.style, {\n minWidth: '400px',\n minHeight: '400px',\n border: 'none',\n borderRadius: '8px',\n display: 'block',\n background: 'transparent',\n });\n\n // Append iframe directly to modal backdrop\n this.threeDSModal.appendChild(this.threeDSIframe);\n document.body.appendChild(this.threeDSModal);\n\n // Store 3DS data for later use\n (this as any).pending3DSData = data;\n }\n\n /**\n * Handle THREEDS_READY message - send THREEDS_INIT with challenge data\n */\n private handle3DSReady(): void {\n const data = (this as any).pending3DSData;\n if (!data || !this.threeDSIframe?.contentWindow) {\n console.error('[PaypercutCheckout] No pending 3DS data or iframe not ready');\n return;\n }\n\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n this.threeDSIframe.contentWindow.postMessage(\n {\n type: 'THREEDS_INIT',\n checkoutId: this.options.id,\n },\n checkoutOrigin,\n );\n }\n\n /**\n * Close 3DS modal and cleanup\n */\n private close3DSModal(): void {\n if (this.threeDSModal) {\n this.threeDSModal.remove();\n this.threeDSModal = null;\n }\n\n this.threeDSIframe = null;\n delete (this as any).pending3DSData;\n }\n\n /**\n * Destroy the checkout instance and cleanup (idempotent)\n */\n destroy(): void {\n // Early return if already destroyed\n if (this.destroyed) {\n return;\n }\n\n // Remove iframe from DOM\n if (this.iframe) {\n try {\n this.iframe.remove();\n this.iframe = null;\n } catch (err) {\n console.error('[PaypercutCheckout] Error removing iframe:', err);\n }\n }\n\n // Cleanup 3DS modal if open\n this.close3DSModal();\n\n // Only set mounted = false after successful DOM removal\n this.mounted = false;\n this.destroyed = true;\n\n // Cleanup event listeners\n window.removeEventListener('message', this.messageHandler);\n this.emitter.clear();\n }\n\n /**\n * Subscribe to an event\n */\n on(event: EventName, handler: (...args: any[]) => void): () => void {\n return this.emitter.on(event, handler);\n }\n\n /**\n * Subscribe to event that auto-unsubscribes after first emission\n */\n once(event: EventName, handler: (...args: any[]) => void): () => void {\n return this.emitter.once(event, handler);\n }\n\n /**\n * Unsubscribe from an event\n */\n off(event: EventName, handler: (...args: any[]) => void): void {\n this.emitter.off(event, handler);\n }\n\n /**\n * Check if checkout is currently mounted\n */\n isMounted(): boolean {\n return this.mounted;\n }\n}\n\n/**\n * Factory function that works both as callable and constructable.\n * Always returns a new CheckoutImpl instance - no prototype manipulation needed.\n */\nconst PaypercutCheckout: PaypercutCheckoutStatic = function (\n this: unknown,\n options: PaypercutCheckoutOptions,\n): CheckoutInstance {\n // Always return a new instance, regardless of how it's called\n return new CheckoutImpl(options);\n} as unknown as PaypercutCheckoutStatic;\n\n// Add static version property\n(PaypercutCheckout as any).version = config.version;\n\n// Export as default and named\nexport default PaypercutCheckout;\nexport { PaypercutCheckout };\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/utils/emitter.ts","../src/config.ts","../src/types/locales.ts","../src/types/checkout.ts","../src/index.ts"],"sourcesContent":["/**\n * Simple event emitter for handling checkout events\n * Supports subscribing, unsubscribing, and emitting events\n */\nexport class Emitter<T extends string = string> {\n private handlers = new Map<T, Set<Function>>();\n\n /**\n * Subscribe to an event\n * @param event - Event name to listen to\n * @param handler - Callback function to execute when event is emitted\n * @returns Unsubscribe function\n */\n on(event: T, handler: Function): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n /**\n * Subscribe to an event that auto-unsubscribes after first emission\n *\n * Common use case: waiting for 'loaded' event or handling first 'success'.\n * Without this helper, developers would need to manually unsubscribe inside\n * their handler, which is error-prone and leads to memory leaks if forgotten.\n *\n * @param event - Event name to listen to\n * @param handler - Callback function to execute when event is emitted\n * @returns Unsubscribe function\n */\n once(event: T, handler: Function): () => void {\n const wrappedHandler = (...args: any[]) => {\n handler(...args);\n this.off(event, wrappedHandler);\n };\n return this.on(event, wrappedHandler);\n }\n\n /**\n * Unsubscribe from an event\n * @param event - Event name to stop listening to\n * @param handler - Callback function to remove\n */\n off(event: T, handler: Function): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n /**\n * Emit an event with optional arguments\n * @param event - Event name to emit\n * @param args - Arguments to pass to event handlers\n */\n emit(event: T, ...args: any[]): void {\n this.handlers.get(event)?.forEach(h => {\n try {\n h(...args);\n } catch (err) {\n console.error(`[Emitter] Error in ${event} handler:`, err);\n }\n });\n }\n\n /**\n * Clear all event handlers\n */\n clear(): void {\n this.handlers.clear();\n }\n}\n\n","/**\n * Build-time configuration\n * \n * This file is processed at build time with different values for:\n * - Production build (for merchants)\n * - Internal build (for team development)\n */\n\n/**\n * Build mode - replaced at build time\n */\ndeclare const __BUILD_MODE__: 'production' | 'internal';\n\n/**\n * SDK version - replaced at build time\n */\ndeclare const __VERSION__: string;\n\n/**\n * Configuration interface\n */\nexport interface BuildConfig {\n /** SDK version */\n version: string;\n \n /** Build mode */\n mode: 'production' | 'internal';\n \n /** Default checkout origin (production URL) */\n defaultCheckoutOrigin: string;\n \n /** Allowed origins for postMessage validation */\n allowedOrigins: string[];\n \n /** Whether hostedCheckoutUrl override is allowed */\n allowOriginOverride: boolean;\n}\n\n/**\n * Production configuration (for merchants)\n */\nconst productionConfig: BuildConfig = {\n version: __VERSION__,\n mode: 'production',\n defaultCheckoutOrigin: 'https://buy.paypercut.io',\n allowedOrigins: [\n 'https://buy.paypercut.io',\n ],\n allowOriginOverride: false\n};\n\n/**\n * Internal configuration (for team development)\n */\nconst internalConfig: BuildConfig = {\n version: __VERSION__,\n mode: 'internal',\n defaultCheckoutOrigin: 'https://buy.paypercut.io',\n allowedOrigins: [\n 'https://buy.paypercut.io',\n 'http://localhost:3000',\n 'http://localhost:3001',\n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001'\n ],\n allowOriginOverride: true\n};\n\n/**\n * Active configuration (selected at build time)\n */\nexport const config: BuildConfig = __BUILD_MODE__ === 'internal' \n ? internalConfig \n : productionConfig;\n\n/**\n * Helper to check if origin is allowed\n */\nexport function isOriginAllowed(origin: string): boolean {\n return config.allowedOrigins.includes(origin);\n}\n\n/**\n * Get the checkout origin (with optional override for internal builds)\n */\nexport function getCheckoutOrigin(override?: string): string {\n // Only allow override in internal builds\n if (override && config.allowOriginOverride) {\n return override;\n }\n \n return config.defaultCheckoutOrigin;\n}\n\n","/**\n * Supported locales for Paypercut Checkout\n *\n * @remarks\n * Single source of truth for all supported locale codes.\n *\n * Supported languages:\n * - Bulgarian: 'bg', 'bg-BG'\n * - English: 'en', 'en-GB'\n * - Greek: 'el', 'el-GR'\n * - Romanian: 'ro', 'ro-RO'\n * - Croatian: 'hr', 'hr-HR'\n * - Polish: 'pl', 'pl-PL'\n * - Czech: 'cs', 'cs-CZ'\n * - Slovenian: 'sl', 'sl-SI'\n * - Slovak: 'sk', 'sk-SK'\n *\n * @example\n * ```typescript\n * const checkout = PaypercutCheckout({\n * locale: 'bg' // or 'bg-BG', 'en', 'en-GB', etc.\n * });\n * ```\n */\nexport const LOCALES = [\n 'bg', 'bg-BG',\n 'en', 'en-GB',\n 'el', 'el-GR',\n 'ro', 'ro-RO',\n 'hr', 'hr-HR',\n 'pl', 'pl-PL',\n 'cs', 'cs-CZ',\n 'sl', 'sl-SI',\n 'sk', 'sk-SK',\n] as const;\n\n/**\n * Locale type - union of all supported locale codes plus 'auto'\n * @example\n * ```typescript\n * const locale: Locale = 'bg';\n * const lang: Locale = 'bg';\n * const autoLocale: Locale = 'auto';\n * ```\n */\nexport type Locale = typeof LOCALES[number] | 'auto';\n\n/**\n * Fast runtime check using Set for O(1) lookup\n * @internal\n */\nconst LOCALE_SET: ReadonlySet<string> = new Set(LOCALES);\n\n/**\n * Normalize and validate locale\n *\n * @param locale - Locale code to normalize\n * @returns Normalized locale code or 'en' as fallback\n *\n * @remarks\n * - 'auto' or empty → 'en'\n * - Unsupported locale → 'en' with console warning\n * - Supported locale → original value\n *\n * @example\n * ```typescript\n * normalizeLocale('auto') // → 'en'\n * normalizeLocale('bg') // → 'bg'\n * normalizeLocale('de') // → 'en' (with warning)\n * ```\n */\nexport function normalizeLocale(locale: string | Locale): typeof LOCALES[number] | 'en' {\n if (!locale || locale === 'auto') return 'en';\n if (LOCALE_SET.has(locale)) return locale as typeof LOCALES[number];\n console.warn(`[PaypercutCheckout] Locale \"${locale}\" is not supported. Falling back to \"en\".`);\n return 'en';\n}\n\n","import { Locale } from './locales';\n\n/**\n * UI mode for checkout\n */\nexport enum UIMode {\n /** Embedded mode - checkout embedded in merchant page */\n EMBEDDED = 'embedded',\n}\n\n/**\n * Type guard for UIMode\n */\nexport function isValidUIMode(value: string): value is UIMode {\n return Object.values(UIMode).includes(value as UIMode);\n}\n\n/**\n * Payment method types\n */\nexport enum PaymentMethod {\n /** Card payment (credit/debit) */\n CARD = 'card',\n}\n\n/**\n * Type guard for PaymentMethod\n */\nexport function isValidPaymentMethod(value: string): value is PaymentMethod {\n return Object.values(PaymentMethod).includes(value as PaymentMethod);\n}\n\n/**\n * Wallet options for digital wallets\n */\nexport enum WalletOption {\n /** Apple Pay */\n APPLE_PAY = 'apple_pay',\n /** Google Pay */\n GOOGLE_PAY = 'google_pay',\n}\n\n/**\n * Type guard for WalletOption\n */\nexport function isValidWalletOption(value: string): value is WalletOption {\n return Object.values(WalletOption).includes(value as WalletOption);\n}\n\n/**\n * Validate payment methods array\n */\nexport function validatePaymentMethods(methods: string[]): PaymentMethod[] {\n const validated: PaymentMethod[] = [];\n\n for (const method of methods) {\n if (isValidPaymentMethod(method)) {\n validated.push(method as PaymentMethod);\n } else {\n console.warn(`[PaypercutCheckout] Invalid payment method: \"${method}\". Skipping.`);\n }\n }\n\n // Default to card if no valid methods\n if (validated.length === 0) {\n console.warn('[PaypercutCheckout] No valid payment methods provided. Defaulting to \"card\".');\n validated.push(PaymentMethod.CARD);\n }\n\n return validated;\n}\n\n/**\n * Validate wallet options array\n */\nexport function validateWalletOptions(options: string[]): WalletOption[] {\n const validated: WalletOption[] = [];\n\n for (const option of options) {\n if (isValidWalletOption(option)) {\n validated.push(option as WalletOption);\n } else {\n console.warn(`[PaypercutCheckout] Invalid wallet option: \"${option}\". Skipping.`);\n }\n }\n\n return validated;\n}\n\n/**\n * Validate UI mode\n */\nexport function validateUIMode(mode: string | undefined): UIMode | undefined {\n if (!mode) {\n return undefined;\n }\n\n if (isValidUIMode(mode)) {\n return mode as UIMode;\n }\n\n console.warn(\n `[PaypercutCheckout] Invalid ui_mode: \"${mode}\". Valid options: ${Object.values(UIMode).join(', ')}`,\n );\n return undefined;\n}\n\n/**\n * Configuration options for PaypercutCheckout\n */\nexport interface PaypercutCheckoutOptions {\n /** Checkout session identifier (e.g., 'CHK_12345') */\n id: string;\n\n /** CSS selector or HTMLElement where iframe mounts (required) */\n containerId: string | HTMLElement;\n\n /**\n * Optional: Custom hosted checkout URL (only available in internal builds)\n * Production builds will ignore this option for security\n */\n hostedCheckoutUrl?: string;\n\n /**\n * Optional: Locale for checkout UI\n * @default 'en'\n */\n locale?: Locale | string;\n\n /**\n * Optional: Language for checkout UI\n * @default 'en'\n */\n lang?: Locale | string;\n\n /**\n * Optional: UI mode for checkout\n */\n ui_mode?: UIMode | `${UIMode}`;\n\n /**\n * Optional: Payment methods to enable\n * @default ['card']\n */\n payment_methods?: (PaymentMethod | `${PaymentMethod}`)[];\n\n /**\n * Optional: Digital wallet options\n * Can include both or just one\n * Default behaviour - shows both\n */\n wallet_options?: (WalletOption | `${WalletOption}`)[] | [];\n\n /**\n * Optional: Show only the payment form without header/footer\n * @default false\n */\n form_only?: boolean;\n\n /**\n * Optional: Appearance options\n */\n appearance?: {\n preset?: 'inline' | 'modal';\n theme?: 'light' | 'dark' | 'none' | 'flat';\n variables: {};\n rules: {};\n labels: 'floating' | 'above' | 'none';\n };\n}\n\n/**\n * Wallet type for form validation\n */\nexport type WalletType = 'apple_pay' | 'google_pay';\n\n/**\n * Form validation event payload\n */\nexport interface FormValidationPayload {\n checkoutId: string;\n wallet: WalletType;\n}\n\n/**\n * Event names that can be emitted by the checkout\n */\nexport type EventName =\n | 'loaded' // iframe finished loading\n | 'success' // payment successful\n | 'error' // payment or system error\n | 'expired' // checkout expired or already paid\n | 'resize' // checkout expired or already paid\n | 'threeds_complete' // checkout paid successfully\n | 'threeds_error' // checkout threeds error\n | 'threeds_canceled' // checkout threeds canceled\n | 'threeds_started' // checkout threeds started\n | 'form_validation'; // wallet button clicked, merchant should validate form\n\n/**\n * Preferred enum for SDK event names (use instead of hardcoded strings)\n */\nexport enum SdkEvent {\n Loaded = 'loaded',\n Success = 'success',\n Error = 'error',\n Expired = 'expired',\n Resize = 'resize',\n ThreeDSComplete = 'threeds_complete',\n ThreeDSError = 'threeds_error',\n ThreeDSCanceled = 'threeds_canceled',\n ThreeDSStarted = 'threeds_started',\n FormValidation = 'form_validation',\n}\n\n/**\n * Form validation error for failFormValidation\n */\nexport interface FormValidationError {\n code?: string;\n message?: string;\n}\n\n/**\n * Checkout instance interface\n */\nexport interface CheckoutInstance {\n /** Mount and render the iframe into the container */\n render(): void;\n\n /** Submit payment - sends message to hosted checkout to confirm payment */\n submit(): void;\n\n /** Destroy instance and cleanup all listeners */\n destroy(): void;\n\n /** Subscribe to events. Returns unsubscribe function */\n on(event: EventName | SdkEvent, handler: (...args: any[]) => void): () => void;\n\n /** Subscribe to event that auto-unsubscribes after first emission */\n once(event: EventName | SdkEvent, handler: (...args: any[]) => void): () => void;\n\n /** Unsubscribe from events */\n off(event: EventName | SdkEvent, handler: (...args: any[]) => void): void;\n\n /** Check if checkout is currently mounted */\n isMounted(): boolean;\n\n /**\n * Complete form validation successfully - allows wallet payment to proceed.\n * Call this in response to 'form_validation' event when merchant form is valid.\n * @param wallet - The wallet type that requested validation ('apple_pay' | 'google_pay')\n */\n completeFormValidation(wallet: WalletType): void;\n\n /**\n * Fail form validation - prevents wallet payment from starting.\n * Call this in response to 'form_validation' event when merchant form has errors.\n * @param wallet - The wallet type that requested validation ('apple_pay' | 'google_pay')\n * @param errors - Optional array of validation errors to pass back\n */\n failFormValidation(wallet: WalletType, errors?: FormValidationError[]): void;\n}\n\n/**\n * PaypercutCheckout static interface (callable and constructable)\n */\nexport interface PaypercutCheckoutStatic {\n /** Callable factory function */\n (options: PaypercutCheckoutOptions): CheckoutInstance;\n\n /** Constructor support */\n new (options: PaypercutCheckoutOptions): CheckoutInstance;\n\n /** SDK version */\n version: string;\n}\n","import { Emitter } from './utils/emitter';\nimport { config, isOriginAllowed, getCheckoutOrigin } from './config';\n\nimport {\n PaypercutCheckoutOptions,\n CheckoutInstance,\n PaypercutCheckoutStatic,\n EventName,\n SdkEvent,\n validatePaymentMethods,\n validateWalletOptions,\n validateUIMode,\n UIMode,\n WalletType,\n FormValidationError,\n} from './types';\nimport { normalizeLocale } from './types';\n\n// Re-export types and enums for consumers\nexport type { PaypercutCheckoutOptions, CheckoutInstance, PaypercutCheckoutStatic, EventName, WalletType, FormValidationError };\n\nexport { UIMode, PaymentMethod, WalletOption } from './types/checkout';\n\n// Re-export SDK event enums for consumers\nexport { SdkEvent } from './types/checkout';\n\nexport type { Locale } from './types/locales';\nexport { LOCALES } from './types/locales';\n\n/**\n * Internal implementation of CheckoutInstance\n */\nclass CheckoutImpl implements CheckoutInstance {\n private emitter = new Emitter<EventName>();\n private mounted = false;\n private destroyed = false;\n private iframe: HTMLIFrameElement | null = null;\n private messageHandler: (evt: MessageEvent) => void;\n\n // 3DS Modal state\n private threeDSModal: HTMLDivElement | null = null;\n private threeDSIframe: HTMLIFrameElement | null = null;\n\n constructor(private options: PaypercutCheckoutOptions) {\n // Bind message handler\n this.messageHandler = this.onMessage.bind(this);\n window.addEventListener('message', this.messageHandler);\n }\n\n /**\n * Build the iframe source URL with query parameters\n */\n private buildSrc(): string {\n const baseUrl = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n const url = new URL(`/c/${this.options.id}`, baseUrl);\n\n // Add locale parameter\n if (this.options.locale) {\n const normalizedLocale = normalizeLocale(this.options.locale);\n url.searchParams.set('locale', normalizedLocale);\n }\n\n // Add lang parameter\n if (this.options.lang) {\n const normalizedLocale = normalizeLocale(this.options.lang);\n url.searchParams.set('lang', normalizedLocale);\n }\n\n // Add ui_mode parameter (default to 'embedded')\n {\n const selected = validateUIMode(this.options.ui_mode ?? UIMode.EMBEDDED);\n if (selected) {\n url.searchParams.set('ui_mode', selected);\n }\n }\n\n // Add payment_methods parameters (repeated for each method)\n if (this.options.payment_methods && this.options.payment_methods.length > 0) {\n const validatedMethods = validatePaymentMethods(this.options.payment_methods as string[]);\n validatedMethods.forEach((method) => {\n url.searchParams.append('payment_methods', method);\n });\n }\n\n // Add wallet_options parameters (repeated for each wallet)\n // If wallet_options is explicitly set (even as empty array), we need to pass it\n if (this.options.wallet_options !== undefined) {\n if (this.options.wallet_options.length === 0) {\n // Explicit empty array means \"no wallets\" - pass null (coerced to \"null\" string)\n url.searchParams.set('wallet_options', null as unknown as string);\n } else {\n const validatedWallets = validateWalletOptions(this.options.wallet_options as string[]);\n validatedWallets.forEach((wallet) => {\n url.searchParams.append('wallet_options', wallet);\n });\n }\n }\n\n if (this.options.appearance?.preset) {\n url.searchParams.set('preset', this.options.appearance.preset);\n }\n\n if (this.options.form_only !== undefined) {\n url.searchParams.set('form_only', String(this.options.form_only));\n }\n\n return url.toString();\n }\n\n /**\n * Get the container element from selector or HTMLElement\n */\n private getContainer(): HTMLElement {\n const container =\n typeof this.options.containerId === 'string'\n ? document.querySelector(this.options.containerId)\n : this.options.containerId;\n\n if (!container) {\n throw new Error(`Container not found: ${this.options.containerId}`);\n }\n\n return container as HTMLElement;\n }\n\n /**\n * Handle incoming postMessage events from iframe\n */\n private onMessage(evt: MessageEvent): void {\n // Validate origin against allowed origins (build-time whitelist)\n if (!isOriginAllowed(evt.origin)) {\n return;\n }\n\n // Validate structure\n const data = evt.data;\n if (!data || typeof data !== 'object' || !('type' in data)) {\n return;\n }\n\n // Filter messages by checkout session ID to prevent cross-instance message handling\n // This ensures each checkout instance only processes its own messages\n if (data.checkoutId && data.checkoutId !== this.options.id) {\n return; // Message is for a different checkout instance\n }\n\n // Handle specific events\n switch (data.type) {\n case 'CHECKOUT_LOADED':\n this.emitter.emit(SdkEvent.Loaded);\n break;\n case 'CHECKOUT_SUCCESS':\n const { payment_method = {} } = data;\n this.emitter.emit(SdkEvent.Success, { payment_method });\n break;\n case 'CHECKOUT_ERROR':\n // Forward error payload (if provided) to SDK consumers\n this.emitter.emit(SdkEvent.Error, (data && (data as any).error) ?? data);\n break;\n case 'CHECKOUT_EXPIRED':\n this.emitter.emit(SdkEvent.Expired);\n break;\n case 'CHECKOUT_RESIZE':\n this.emitter.emit(SdkEvent.Resize, data.height);\n this.handleResize(data.height);\n break;\n case 'THREEDS_START_FLOW':\n this.show3DSModal(data);\n this.emitter.emit(SdkEvent.ThreeDSStarted);\n break;\n case 'THREEDS_READY':\n this.handle3DSReady();\n break;\n case 'THREEDS_COMPLETE':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSComplete);\n break;\n case 'THREEDS_CANCELED':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSCanceled);\n break;\n case 'THREEDS_ERROR':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSError, data.error);\n break;\n case 'FORM_VALIDATION':\n // Wallet button clicked - emit event for merchant to validate their form\n this.emitter.emit(SdkEvent.FormValidation, {\n checkoutId: data.checkoutId,\n wallet: data.wallet as WalletType,\n });\n break;\n }\n }\n\n /**\n * Render the checkout iframe into the container\n */\n render(): void {\n if (this.mounted) {\n return;\n }\n\n try {\n const container = this.getContainer();\n\n // Create iframe\n this.iframe = document.createElement('iframe');\n this.iframe.id = 'paypercut-checkout-iframe';\n this.iframe.src = this.buildSrc();\n this.iframe.allow = 'payment *; clipboard-write';\n this.iframe.setAttribute('frameborder', '0');\n // Allow Payment Request API inside iframe and necessary sandbox permissions for wallets\n this.iframe.setAttribute('allowpaymentrequest', 'true');\n this.iframe.setAttribute(\n 'sandbox',\n 'allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox',\n );\n\n // Apply default styles - just construct URL and assign to iframe\n Object.assign(this.iframe.style, {\n width: '100%',\n height: '100%',\n border: 'none',\n display: 'block',\n });\n\n // Listen for iframe load event (fallback)\n // This ensures 'loaded' event is always emitted even if hosted checkout\n // doesn't send CHECKOUT_LOADED message\n /*this.iframe.addEventListener('load', () => {\n this.emitter.emit('loaded');\n });*/\n\n container.appendChild(this.iframe);\n this.mounted = true;\n } catch (err) {\n console.error('[PaypercutCheckout] Failed to render:', err);\n throw err;\n }\n }\n\n /**\n * Submit payment - sends message to hosted checkout to confirm payment\n */\n submit(): void {\n if (!this.mounted) {\n return;\n }\n\n try {\n this.postToIframe({\n type: 'START_PROCESSING',\n checkoutId: this.options.id,\n });\n } catch (err) {\n console.error('[PaypercutCheckout] Failed to submit payment:', err);\n throw err;\n }\n }\n\n /**\n * Send message to hosted/embedded checkout iframe - used for submit payment and communicating 3DS events\n */\n private postToIframe(message: any): void {\n if (!this.iframe?.contentWindow) {\n console.error('[PaypercutCheckout] Cannot post message: iframe not mounted');\n return;\n }\n\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n this.iframe.contentWindow.postMessage(message, checkoutOrigin);\n }\n\n /**\n * Handle CHECKOUT_RESIZE message - resize iframe to match content height\n */\n private handleResize(height: unknown): void {\n if (!this.iframe || typeof height !== 'number' || height <= 0) {\n return;\n }\n\n // Set iframe height to match content\n this.iframe.style.height = `${height}px`;\n }\n\n /**\n * Show 3DS modal with challenge/decoupled flow\n */\n private show3DSModal(data: {\n sessionId: string;\n step: 'challenge' | 'decoupled_waiting';\n challengeUrl?: string;\n acsTransactionId?: string;\n threeDSVersion?: string;\n cardBrand?: string;\n liveMode?: boolean;\n }): void {\n // Create modal backdrop\n this.threeDSModal = document.createElement('div');\n this.threeDSModal.id = 'paypercut-3ds-modal';\n Object.assign(this.threeDSModal.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: '999999',\n background: 'rgba(0, 0, 0, 0.4)',\n });\n\n // Create iframe for 3DS page\n this.threeDSIframe = document.createElement('iframe');\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n\n // Build URL: baseUrl/c/{checkoutId}/threeds with query params\n const threeDSUrl = new URL(`/c/${this.options.id}/threeds`, checkoutOrigin);\n threeDSUrl.searchParams.set('sessionId', data.sessionId);\n threeDSUrl.searchParams.set('step', data.step);\n\n if (data.challengeUrl) {\n threeDSUrl.searchParams.set('challengeUrl', data.challengeUrl);\n }\n if (data.acsTransactionId) {\n threeDSUrl.searchParams.set('acsTransactionId', data.acsTransactionId);\n }\n if (data.threeDSVersion) {\n threeDSUrl.searchParams.set('threeDSVersion', data.threeDSVersion);\n }\n // Always include liveMode; default to false when undefined\n threeDSUrl.searchParams.set('liveMode', String(data.liveMode ?? false));\n\n this.threeDSIframe.src = threeDSUrl.toString();\n this.threeDSIframe.allow = 'payment *';\n this.threeDSIframe.setAttribute('frameborder', '0');\n\n // Fixed dimensions: follow 3DS component size (500x500)\n Object.assign(this.threeDSIframe.style, {\n minWidth: '400px',\n minHeight: '400px',\n border: 'none',\n borderRadius: '8px',\n display: 'block',\n background: 'transparent',\n });\n\n // Append iframe directly to modal backdrop\n this.threeDSModal.appendChild(this.threeDSIframe);\n document.body.appendChild(this.threeDSModal);\n\n // Store 3DS data for later use\n (this as any).pending3DSData = data;\n }\n\n /**\n * Handle THREEDS_READY message - send THREEDS_INIT with challenge data\n */\n private handle3DSReady(): void {\n const data = (this as any).pending3DSData;\n if (!data || !this.threeDSIframe?.contentWindow) {\n console.error('[PaypercutCheckout] No pending 3DS data or iframe not ready');\n return;\n }\n\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n this.threeDSIframe.contentWindow.postMessage(\n {\n type: 'THREEDS_INIT',\n checkoutId: this.options.id,\n },\n checkoutOrigin,\n );\n }\n\n /**\n * Close 3DS modal and cleanup\n */\n private close3DSModal(): void {\n if (this.threeDSModal) {\n this.threeDSModal.remove();\n this.threeDSModal = null;\n }\n\n this.threeDSIframe = null;\n delete (this as any).pending3DSData;\n }\n\n /**\n * Destroy the checkout instance and cleanup (idempotent)\n */\n destroy(): void {\n // Early return if already destroyed\n if (this.destroyed) {\n return;\n }\n\n // Remove iframe from DOM\n if (this.iframe) {\n try {\n this.iframe.remove();\n this.iframe = null;\n } catch (err) {\n console.error('[PaypercutCheckout] Error removing iframe:', err);\n }\n }\n\n // Cleanup 3DS modal if open\n this.close3DSModal();\n\n // Only set mounted = false after successful DOM removal\n this.mounted = false;\n this.destroyed = true;\n\n // Cleanup event listeners\n window.removeEventListener('message', this.messageHandler);\n this.emitter.clear();\n }\n\n /**\n * Subscribe to an event\n */\n on(event: EventName, handler: (...args: any[]) => void): () => void {\n return this.emitter.on(event, handler);\n }\n\n /**\n * Subscribe to event that auto-unsubscribes after first emission\n */\n once(event: EventName, handler: (...args: any[]) => void): () => void {\n return this.emitter.once(event, handler);\n }\n\n /**\n * Unsubscribe from an event\n */\n off(event: EventName, handler: (...args: any[]) => void): void {\n this.emitter.off(event, handler);\n }\n\n /**\n * Check if checkout is currently mounted\n */\n isMounted(): boolean {\n return this.mounted;\n }\n\n /**\n * Complete form validation successfully - allows wallet payment to proceed.\n * Call this in response to 'form_validation' event when merchant form is valid.\n */\n completeFormValidation(wallet: WalletType): void {\n if (!this.mounted) {\n console.warn('[PaypercutCheckout] Cannot complete form validation: not mounted');\n return;\n }\n\n this.postToIframe({\n type: 'FORM_VALIDATION_COMPLETED',\n checkoutId: this.options.id,\n wallet,\n status: 'success',\n });\n }\n\n /**\n * Fail form validation - prevents wallet payment from starting.\n * Call this in response to 'form_validation' event when merchant form has errors.\n */\n failFormValidation(wallet: WalletType, errors?: FormValidationError[]): void {\n if (!this.mounted) {\n console.warn('[PaypercutCheckout] Cannot fail form validation: not mounted');\n return;\n }\n\n this.postToIframe({\n type: 'FORM_VALIDATION_COMPLETED',\n checkoutId: this.options.id,\n wallet,\n status: 'failed',\n errors,\n });\n }\n}\n\n/**\n * Factory function that works both as callable and constructable.\n * Always returns a new CheckoutImpl instance - no prototype manipulation needed.\n */\nconst PaypercutCheckout: PaypercutCheckoutStatic = function (\n this: unknown,\n options: PaypercutCheckoutOptions,\n): CheckoutInstance {\n // Always return a new instance, regardless of how it's called\n return new CheckoutImpl(options);\n} as unknown as PaypercutCheckoutStatic;\n\n// Add static version property\n(PaypercutCheckout as any).version = config.version;\n\n// Export as default and named\nexport default PaypercutCheckout;\nexport { PaypercutCheckout };\n"],"names":[],"mappings":"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"}
|
|
@@ -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=(...
|
|
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.13",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)),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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paypercut-checkout.iife.min.js","sources":["../src/utils/emitter.ts","../src/config.ts","../src/types/locales.ts","../src/types/checkout.ts","../src/index.ts"],"sourcesContent":["/**\n * Simple event emitter for handling checkout events\n * Supports subscribing, unsubscribing, and emitting events\n */\nexport class Emitter<T extends string = string> {\n private handlers = new Map<T, Set<Function>>();\n\n /**\n * Subscribe to an event\n * @param event - Event name to listen to\n * @param handler - Callback function to execute when event is emitted\n * @returns Unsubscribe function\n */\n on(event: T, handler: Function): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n /**\n * Subscribe to an event that auto-unsubscribes after first emission\n *\n * Common use case: waiting for 'loaded' event or handling first 'success'.\n * Without this helper, developers would need to manually unsubscribe inside\n * their handler, which is error-prone and leads to memory leaks if forgotten.\n *\n * @param event - Event name to listen to\n * @param handler - Callback function to execute when event is emitted\n * @returns Unsubscribe function\n */\n once(event: T, handler: Function): () => void {\n const wrappedHandler = (...args: any[]) => {\n handler(...args);\n this.off(event, wrappedHandler);\n };\n return this.on(event, wrappedHandler);\n }\n\n /**\n * Unsubscribe from an event\n * @param event - Event name to stop listening to\n * @param handler - Callback function to remove\n */\n off(event: T, handler: Function): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n /**\n * Emit an event with optional arguments\n * @param event - Event name to emit\n * @param args - Arguments to pass to event handlers\n */\n emit(event: T, ...args: any[]): void {\n this.handlers.get(event)?.forEach(h => {\n try {\n h(...args);\n } catch (err) {\n console.error(`[Emitter] Error in ${event} handler:`, err);\n }\n });\n }\n\n /**\n * Clear all event handlers\n */\n clear(): void {\n this.handlers.clear();\n }\n}\n\n","/**\n * Build-time configuration\n * \n * This file is processed at build time with different values for:\n * - Production build (for merchants)\n * - Internal build (for team development)\n */\n\n/**\n * Build mode - replaced at build time\n */\ndeclare const __BUILD_MODE__: 'production' | 'internal';\n\n/**\n * SDK version - replaced at build time\n */\ndeclare const __VERSION__: string;\n\n/**\n * Configuration interface\n */\nexport interface BuildConfig {\n /** SDK version */\n version: string;\n \n /** Build mode */\n mode: 'production' | 'internal';\n \n /** Default checkout origin (production URL) */\n defaultCheckoutOrigin: string;\n \n /** Allowed origins for postMessage validation */\n allowedOrigins: string[];\n \n /** Whether hostedCheckoutUrl override is allowed */\n allowOriginOverride: boolean;\n}\n\n/**\n * Production configuration (for merchants)\n */\nconst productionConfig: BuildConfig = {\n version: __VERSION__,\n mode: 'production',\n defaultCheckoutOrigin: 'https://buy.paypercut.io',\n allowedOrigins: [\n 'https://buy.paypercut.io',\n ],\n allowOriginOverride: false\n};\n\n/**\n * Internal configuration (for team development)\n */\nconst internalConfig: BuildConfig = {\n version: __VERSION__,\n mode: 'internal',\n defaultCheckoutOrigin: 'https://buy.paypercut.io',\n allowedOrigins: [\n 'https://buy.paypercut.io',\n 'http://localhost:3000',\n 'http://localhost:3001',\n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001'\n ],\n allowOriginOverride: true\n};\n\n/**\n * Active configuration (selected at build time)\n */\nexport const config: BuildConfig = __BUILD_MODE__ === 'internal' \n ? internalConfig \n : productionConfig;\n\n/**\n * Helper to check if origin is allowed\n */\nexport function isOriginAllowed(origin: string): boolean {\n return config.allowedOrigins.includes(origin);\n}\n\n/**\n * Get the checkout origin (with optional override for internal builds)\n */\nexport function getCheckoutOrigin(override?: string): string {\n // Only allow override in internal builds\n if (override && config.allowOriginOverride) {\n return override;\n }\n \n return config.defaultCheckoutOrigin;\n}\n\n","/**\n * Supported locales for Paypercut Checkout\n * \n * @remarks\n * Single source of truth for all supported locale codes.\n * \n * Supported languages:\n * - Bulgarian: 'bg', 'bg-BG'\n * - English: 'en', 'en-GB'\n * - Greek: 'el', 'el-GR'\n * - Romanian: 'ro', 'ro-RO'\n * - Croatian: 'hr', 'hr-HR'\n * - Polish: 'pl', 'pl-PL'\n * - Czech: 'cs', 'cs-CZ'\n * - Slovenian: 'sl', 'sl-SI'\n * - Slovak: 'sk', 'sk-SK'\n * \n * @example\n * ```typescript\n * const checkout = PaypercutCheckout({\n * locale: 'bg' // or 'bg-BG', 'en', 'en-GB', etc.\n * });\n * ```\n */\nexport const LOCALES = [\n 'bg', 'bg-BG',\n 'en', 'en-GB',\n 'el', 'el-GR',\n 'ro', 'ro-RO',\n 'hr', 'hr-HR',\n 'pl', 'pl-PL',\n 'cs', 'cs-CZ',\n 'sl', 'sl-SI',\n 'sk', 'sk-SK',\n] as const;\n\n/**\n * Locale type - union of all supported locale codes plus 'auto'\n * @example\n * ```typescript\n * const locale: Locale = 'bg';\n * const autoLocale: Locale = 'auto';\n * ```\n */\nexport type Locale = typeof LOCALES[number] | 'auto';\n\n/**\n * Fast runtime check using Set for O(1) lookup\n * @internal\n */\nconst LOCALE_SET: ReadonlySet<string> = new Set(LOCALES);\n\n/**\n * Normalize and validate locale\n * \n * @param locale - Locale code to normalize\n * @returns Normalized locale code or 'en' as fallback\n * \n * @remarks\n * - 'auto' or empty → 'en'\n * - Unsupported locale → 'en' with console warning\n * - Supported locale → original value\n * \n * @example\n * ```typescript\n * normalizeLocale('auto') // → 'en'\n * normalizeLocale('bg') // → 'bg'\n * normalizeLocale('de') // → 'en' (with warning)\n * ```\n */\nexport function normalizeLocale(locale: string | Locale): typeof LOCALES[number] | 'en' {\n if (!locale || locale === 'auto') return 'en';\n if (LOCALE_SET.has(locale)) return locale as typeof LOCALES[number];\n console.warn(`[PaypercutCheckout] Locale \"${locale}\" is not supported. Falling back to \"en\".`);\n return 'en';\n}\n\n","import { Locale } from './locales';\n\n/**\n * UI mode for checkout\n */\nexport enum UIMode {\n /** Embedded mode - checkout embedded in merchant page */\n EMBEDDED = 'embedded',\n}\n\n/**\n * Type guard for UIMode\n */\nexport function isValidUIMode(value: string): value is UIMode {\n return Object.values(UIMode).includes(value as UIMode);\n}\n\n/**\n * Payment method types\n */\nexport enum PaymentMethod {\n /** Card payment (credit/debit) */\n CARD = 'card',\n}\n\n/**\n * Type guard for PaymentMethod\n */\nexport function isValidPaymentMethod(value: string): value is PaymentMethod {\n return Object.values(PaymentMethod).includes(value as PaymentMethod);\n}\n\n/**\n * Wallet options for digital wallets\n */\nexport enum WalletOption {\n /** Apple Pay */\n APPLE_PAY = 'apple_pay',\n /** Google Pay */\n GOOGLE_PAY = 'google_pay',\n}\n\n/**\n * Type guard for WalletOption\n */\nexport function isValidWalletOption(value: string): value is WalletOption {\n return Object.values(WalletOption).includes(value as WalletOption);\n}\n\n/**\n * Validate payment methods array\n */\nexport function validatePaymentMethods(methods: string[]): PaymentMethod[] {\n const validated: PaymentMethod[] = [];\n\n for (const method of methods) {\n if (isValidPaymentMethod(method)) {\n validated.push(method as PaymentMethod);\n } else {\n console.warn(`[PaypercutCheckout] Invalid payment method: \"${method}\". Skipping.`);\n }\n }\n\n // Default to card if no valid methods\n if (validated.length === 0) {\n console.warn('[PaypercutCheckout] No valid payment methods provided. Defaulting to \"card\".');\n validated.push(PaymentMethod.CARD);\n }\n\n return validated;\n}\n\n/**\n * Validate wallet options array\n */\nexport function validateWalletOptions(options: string[]): WalletOption[] {\n const validated: WalletOption[] = [];\n\n for (const option of options) {\n if (isValidWalletOption(option)) {\n validated.push(option as WalletOption);\n } else {\n console.warn(`[PaypercutCheckout] Invalid wallet option: \"${option}\". Skipping.`);\n }\n }\n\n return validated;\n}\n\n/**\n * Validate UI mode\n */\nexport function validateUIMode(mode: string | undefined): UIMode | undefined {\n if (!mode) {\n return undefined;\n }\n\n if (isValidUIMode(mode)) {\n return mode as UIMode;\n }\n\n console.warn(\n `[PaypercutCheckout] Invalid ui_mode: \"${mode}\". Valid options: ${Object.values(UIMode).join(', ')}`,\n );\n return undefined;\n}\n\n/**\n * Configuration options for PaypercutCheckout\n */\nexport interface PaypercutCheckoutOptions {\n /** Checkout session identifier (e.g., 'CHK_12345') */\n id: string;\n\n /** CSS selector or HTMLElement where iframe mounts (required) */\n containerId: string | HTMLElement;\n\n /**\n * Optional: Custom hosted checkout URL (only available in internal builds)\n * Production builds will ignore this option for security\n */\n hostedCheckoutUrl?: string;\n\n /**\n * Optional: Locale for checkout UI\n * @default 'en'\n */\n locale?: Locale | string;\n\n /**\n * Optional: UI mode for checkout\n */\n ui_mode?: UIMode | `${UIMode}`;\n\n /**\n * Optional: Payment methods to enable\n * @default ['card']\n */\n payment_methods?: (PaymentMethod | `${PaymentMethod}`)[];\n\n /**\n * Optional: Digital wallet options\n * Can include both or just one\n * Default behaviour - shows both\n */\n wallet_options?: (WalletOption | `${WalletOption}`)[] | [];\n\n /**\n * Optional: Show only the payment form without header/footer\n * @default false\n */\n form_only?: boolean;\n\n /**\n * Optional: Appearance options\n */\n appearance?: {\n preset?: 'inline' | 'modal';\n theme?: 'light' | 'dark' | 'none' | 'flat';\n variables: {};\n rules: {};\n labels: 'floating' | 'above' | 'none';\n };\n}\n\n/**\n * Event names that can be emitted by the checkout\n */\nexport type EventName =\n | 'loaded' // iframe finished loading\n | 'success' // payment successful\n | 'error' // payment or system error\n | 'expired' // checkout expired or already paid\n | 'resize' // checkout expired or already paid\n | 'threeds_complete' // checkout paid successfully\n | 'threeds_error' // checkout threeds error\n | 'threeds_canceled' // checkout threeds canceled\n | 'threeds_started'; // checkout threeds started\n\n/**\n * Preferred enum for SDK event names (use instead of hardcoded strings)\n */\nexport enum SdkEvent {\n Loaded = 'loaded',\n Success = 'success',\n Error = 'error',\n Expired = 'expired',\n Resize = 'resize',\n ThreeDSComplete = 'threeds_complete',\n ThreeDSError = 'threeds_error',\n ThreeDSCanceled = 'threeds_canceled',\n ThreeDSStarted = 'threeds_started',\n}\n\n/**\n * Checkout instance interface\n */\nexport interface CheckoutInstance {\n /** Mount and render the iframe into the container */\n render(): void;\n\n /** Submit payment - sends message to hosted checkout to confirm payment */\n submit(): void;\n\n /** Destroy instance and cleanup all listeners */\n destroy(): void;\n\n /** Subscribe to events. Returns unsubscribe function */\n on(event: EventName | SdkEvent, handler: (...args: any[]) => void): () => void;\n\n /** Subscribe to event that auto-unsubscribes after first emission */\n once(event: EventName | SdkEvent, handler: (...args: any[]) => void): () => void;\n\n /** Unsubscribe from events */\n off(event: EventName | SdkEvent, handler: (...args: any[]) => void): void;\n\n /** Check if checkout is currently mounted */\n isMounted(): boolean;\n}\n\n/**\n * PaypercutCheckout static interface (callable and constructable)\n */\nexport interface PaypercutCheckoutStatic {\n /** Callable factory function */\n (options: PaypercutCheckoutOptions): CheckoutInstance;\n\n /** Constructor support */\n new (options: PaypercutCheckoutOptions): CheckoutInstance;\n\n /** SDK version */\n version: string;\n}\n","import { Emitter } from './utils/emitter';\nimport { config, isOriginAllowed, getCheckoutOrigin } from './config';\n\nimport {\n PaypercutCheckoutOptions,\n CheckoutInstance,\n PaypercutCheckoutStatic,\n EventName,\n SdkEvent,\n validatePaymentMethods,\n validateWalletOptions,\n validateUIMode,\n UIMode,\n} from './types';\nimport { normalizeLocale } from './types';\n\n// Re-export types and enums for consumers\nexport type { PaypercutCheckoutOptions, CheckoutInstance, PaypercutCheckoutStatic, EventName };\n\nexport { UIMode, PaymentMethod, WalletOption } from './types/checkout';\n\n// Re-export SDK event enums for consumers\nexport { SdkEvent } from './types/checkout';\n\nexport type { Locale } from './types/locales';\nexport { LOCALES } from './types/locales';\n\n/**\n * Internal implementation of CheckoutInstance\n */\nclass CheckoutImpl implements CheckoutInstance {\n private emitter = new Emitter<EventName>();\n private mounted = false;\n private destroyed = false;\n private iframe: HTMLIFrameElement | null = null;\n private messageHandler: (evt: MessageEvent) => void;\n\n // 3DS Modal state\n private threeDSModal: HTMLDivElement | null = null;\n private threeDSIframe: HTMLIFrameElement | null = null;\n\n constructor(private options: PaypercutCheckoutOptions) {\n // Bind message handler\n this.messageHandler = this.onMessage.bind(this);\n window.addEventListener('message', this.messageHandler);\n }\n\n /**\n * Build the iframe source URL with query parameters\n */\n private buildSrc(): string {\n const baseUrl = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n const url = new URL(`/c/${this.options.id}`, baseUrl);\n\n // Add locale parameter\n if (this.options.locale) {\n const normalizedLocale = normalizeLocale(this.options.locale);\n url.searchParams.set('locale', normalizedLocale);\n }\n\n // Add ui_mode parameter (default to 'embedded')\n {\n const selected = validateUIMode(this.options.ui_mode ?? UIMode.EMBEDDED);\n if (selected) {\n url.searchParams.set('ui_mode', selected);\n }\n }\n\n // Add payment_methods parameters (repeated for each method)\n if (this.options.payment_methods && this.options.payment_methods.length > 0) {\n const validatedMethods = validatePaymentMethods(this.options.payment_methods as string[]);\n validatedMethods.forEach((method) => {\n url.searchParams.append('payment_methods', method);\n });\n }\n\n // Add wallet_options parameters (repeated for each wallet)\n // If wallet_options is explicitly set (even as empty array), we need to pass it\n if (this.options.wallet_options !== undefined) {\n if (this.options.wallet_options.length === 0) {\n // Explicit empty array means \"no wallets\" - pass null (coerced to \"null\" string)\n url.searchParams.set('wallet_options', null as unknown as string);\n } else {\n const validatedWallets = validateWalletOptions(this.options.wallet_options as string[]);\n validatedWallets.forEach((wallet) => {\n url.searchParams.append('wallet_options', wallet);\n });\n }\n }\n\n if (this.options.appearance?.preset) {\n url.searchParams.set('preset', this.options.appearance.preset);\n }\n\n if (this.options.form_only !== undefined) {\n url.searchParams.set('form_only', String(this.options.form_only));\n }\n\n return url.toString();\n }\n\n /**\n * Get the container element from selector or HTMLElement\n */\n private getContainer(): HTMLElement {\n const container =\n typeof this.options.containerId === 'string'\n ? document.querySelector(this.options.containerId)\n : this.options.containerId;\n\n if (!container) {\n throw new Error(`Container not found: ${this.options.containerId}`);\n }\n\n return container as HTMLElement;\n }\n\n /**\n * Handle incoming postMessage events from iframe\n */\n private onMessage(evt: MessageEvent): void {\n // Validate origin against allowed origins (build-time whitelist)\n if (!isOriginAllowed(evt.origin)) {\n return;\n }\n\n // Validate structure\n const data = evt.data;\n if (!data || typeof data !== 'object' || !('type' in data)) {\n return;\n }\n\n // Filter messages by checkout session ID to prevent cross-instance message handling\n // This ensures each checkout instance only processes its own messages\n if (data.checkoutId && data.checkoutId !== this.options.id) {\n return; // Message is for a different checkout instance\n }\n\n // Handle specific events\n switch (data.type) {\n case 'CHECKOUT_LOADED':\n this.emitter.emit(SdkEvent.Loaded);\n break;\n case 'CHECKOUT_SUCCESS':\n const { payment_method = {} } = data;\n this.emitter.emit(SdkEvent.Success, { payment_method });\n break;\n case 'CHECKOUT_ERROR':\n // Forward error payload (if provided) to SDK consumers\n this.emitter.emit(SdkEvent.Error, (data && (data as any).error) ?? data);\n break;\n case 'CHECKOUT_EXPIRED':\n this.emitter.emit(SdkEvent.Expired);\n break;\n case 'CHECKOUT_RESIZE':\n this.emitter.emit(SdkEvent.Resize, data.height);\n this.handleResize(data.height);\n break;\n case 'THREEDS_START_FLOW':\n this.show3DSModal(data);\n this.emitter.emit(SdkEvent.ThreeDSStarted);\n break;\n case 'THREEDS_READY':\n this.handle3DSReady();\n break;\n case 'THREEDS_COMPLETE':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSComplete);\n break;\n case 'THREEDS_CANCELED':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSCanceled);\n break;\n case 'THREEDS_ERROR':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSError, data.error);\n break;\n }\n }\n\n /**\n * Render the checkout iframe into the container\n */\n render(): void {\n if (this.mounted) {\n return;\n }\n\n try {\n const container = this.getContainer();\n\n // Create iframe\n this.iframe = document.createElement('iframe');\n this.iframe.id = 'paypercut-checkout-iframe';\n this.iframe.src = this.buildSrc();\n this.iframe.allow = 'payment *; clipboard-write';\n this.iframe.setAttribute('frameborder', '0');\n // Allow Payment Request API inside iframe and necessary sandbox permissions for wallets\n this.iframe.setAttribute('allowpaymentrequest', 'true');\n this.iframe.setAttribute(\n 'sandbox',\n 'allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox',\n );\n\n // Apply default styles - just construct URL and assign to iframe\n Object.assign(this.iframe.style, {\n width: '100%',\n height: '100%',\n border: 'none',\n display: 'block',\n });\n\n // Listen for iframe load event (fallback)\n // This ensures 'loaded' event is always emitted even if hosted checkout\n // doesn't send CHECKOUT_LOADED message\n /*this.iframe.addEventListener('load', () => {\n this.emitter.emit('loaded');\n });*/\n\n container.appendChild(this.iframe);\n this.mounted = true;\n } catch (err) {\n console.error('[PaypercutCheckout] Failed to render:', err);\n throw err;\n }\n }\n\n /**\n * Submit payment - sends message to hosted checkout to confirm payment\n */\n submit(): void {\n if (!this.mounted) {\n return;\n }\n\n try {\n this.postToIframe({\n type: 'START_PROCESSING',\n checkoutId: this.options.id,\n });\n } catch (err) {\n console.error('[PaypercutCheckout] Failed to submit payment:', err);\n throw err;\n }\n }\n\n /**\n * Send message to hosted/embedded checkout iframe - used for submit payment and communicating 3DS events\n */\n private postToIframe(message: any): void {\n if (!this.iframe?.contentWindow) {\n console.error('[PaypercutCheckout] Cannot post message: iframe not mounted');\n return;\n }\n\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n this.iframe.contentWindow.postMessage(message, checkoutOrigin);\n }\n\n /**\n * Handle CHECKOUT_RESIZE message - resize iframe to match content height\n */\n private handleResize(height: unknown): void {\n if (!this.iframe || typeof height !== 'number' || height <= 0) {\n return;\n }\n\n // Set iframe height to match content\n this.iframe.style.height = `${height}px`;\n }\n\n /**\n * Show 3DS modal with challenge/decoupled flow\n */\n private show3DSModal(data: {\n sessionId: string;\n step: 'challenge' | 'decoupled_waiting';\n challengeUrl?: string;\n acsTransactionId?: string;\n threeDSVersion?: string;\n cardBrand?: string;\n liveMode?: boolean;\n }): void {\n // Create modal backdrop\n this.threeDSModal = document.createElement('div');\n this.threeDSModal.id = 'paypercut-3ds-modal';\n Object.assign(this.threeDSModal.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: '999999',\n background: 'rgba(0, 0, 0, 0.4)',\n });\n\n // Create iframe for 3DS page\n this.threeDSIframe = document.createElement('iframe');\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n\n // Build URL: baseUrl/c/{checkoutId}/threeds with query params\n const threeDSUrl = new URL(`/c/${this.options.id}/threeds`, checkoutOrigin);\n threeDSUrl.searchParams.set('sessionId', data.sessionId);\n threeDSUrl.searchParams.set('step', data.step);\n\n if (data.challengeUrl) {\n threeDSUrl.searchParams.set('challengeUrl', data.challengeUrl);\n }\n if (data.acsTransactionId) {\n threeDSUrl.searchParams.set('acsTransactionId', data.acsTransactionId);\n }\n if (data.threeDSVersion) {\n threeDSUrl.searchParams.set('threeDSVersion', data.threeDSVersion);\n }\n // Always include liveMode; default to false when undefined\n threeDSUrl.searchParams.set('liveMode', String(data.liveMode ?? false));\n\n this.threeDSIframe.src = threeDSUrl.toString();\n this.threeDSIframe.allow = 'payment *';\n this.threeDSIframe.setAttribute('frameborder', '0');\n\n // Fixed dimensions: follow 3DS component size (500x500)\n Object.assign(this.threeDSIframe.style, {\n minWidth: '400px',\n minHeight: '400px',\n border: 'none',\n borderRadius: '8px',\n display: 'block',\n background: 'transparent',\n });\n\n // Append iframe directly to modal backdrop\n this.threeDSModal.appendChild(this.threeDSIframe);\n document.body.appendChild(this.threeDSModal);\n\n // Store 3DS data for later use\n (this as any).pending3DSData = data;\n }\n\n /**\n * Handle THREEDS_READY message - send THREEDS_INIT with challenge data\n */\n private handle3DSReady(): void {\n const data = (this as any).pending3DSData;\n if (!data || !this.threeDSIframe?.contentWindow) {\n console.error('[PaypercutCheckout] No pending 3DS data or iframe not ready');\n return;\n }\n\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n this.threeDSIframe.contentWindow.postMessage(\n {\n type: 'THREEDS_INIT',\n checkoutId: this.options.id,\n },\n checkoutOrigin,\n );\n }\n\n /**\n * Close 3DS modal and cleanup\n */\n private close3DSModal(): void {\n if (this.threeDSModal) {\n this.threeDSModal.remove();\n this.threeDSModal = null;\n }\n\n this.threeDSIframe = null;\n delete (this as any).pending3DSData;\n }\n\n /**\n * Destroy the checkout instance and cleanup (idempotent)\n */\n destroy(): void {\n // Early return if already destroyed\n if (this.destroyed) {\n return;\n }\n\n // Remove iframe from DOM\n if (this.iframe) {\n try {\n this.iframe.remove();\n this.iframe = null;\n } catch (err) {\n console.error('[PaypercutCheckout] Error removing iframe:', err);\n }\n }\n\n // Cleanup 3DS modal if open\n this.close3DSModal();\n\n // Only set mounted = false after successful DOM removal\n this.mounted = false;\n this.destroyed = true;\n\n // Cleanup event listeners\n window.removeEventListener('message', this.messageHandler);\n this.emitter.clear();\n }\n\n /**\n * Subscribe to an event\n */\n on(event: EventName, handler: (...args: any[]) => void): () => void {\n return this.emitter.on(event, handler);\n }\n\n /**\n * Subscribe to event that auto-unsubscribes after first emission\n */\n once(event: EventName, handler: (...args: any[]) => void): () => void {\n return this.emitter.once(event, handler);\n }\n\n /**\n * Unsubscribe from an event\n */\n off(event: EventName, handler: (...args: any[]) => void): void {\n this.emitter.off(event, handler);\n }\n\n /**\n * Check if checkout is currently mounted\n */\n isMounted(): boolean {\n return this.mounted;\n }\n}\n\n/**\n * Factory function that works both as callable and constructable.\n * Always returns a new CheckoutImpl instance - no prototype manipulation needed.\n */\nconst PaypercutCheckout: PaypercutCheckoutStatic = function (\n this: unknown,\n options: PaypercutCheckoutOptions,\n): CheckoutInstance {\n // Always return a new instance, regardless of how it's called\n return new CheckoutImpl(options);\n} as unknown as PaypercutCheckoutStatic;\n\n// Add static version property\n(PaypercutCheckout as any).version = config.version;\n\n// Export as default and named\nexport default PaypercutCheckout;\nexport { PaypercutCheckout };\n"],"names":["Emitter","constructor","this","handlers","Map","on","event","handler","has","set","Set","get","add","off","once","wrappedHandler","args","delete","emit","forEach","h","err","console","error","clear","config","version","defaultCheckoutOrigin","allowedOrigins","getCheckoutOrigin","override","LOCALE_SET","UIMode","PaymentMethod","WalletOption","SdkEvent","isValidPaymentMethod","value","Object","values","includes","isValidWalletOption","validateUIMode","mode","warn","join","CheckoutImpl","options","emitter","mounted","destroyed","iframe","threeDSModal","threeDSIframe","messageHandler","onMessage","bind","window","addEventListener","buildSrc","baseUrl","hostedCheckoutUrl","url","URL","id","locale","normalizedLocale","searchParams","selected","ui_mode","EMBEDDED","payment_methods","length","methods","validated","method","push","CARD","validatePaymentMethods","append","undefined","wallet_options","option","validateWalletOptions","wallet","appearance","preset","form_only","String","toString","getContainer","container","containerId","document","querySelector","Error","evt","origin","data","checkoutId","type","Loaded","payment_method","Success","Expired","Resize","height","handleResize","show3DSModal","ThreeDSStarted","handle3DSReady","postToIframe","close3DSModal","ThreeDSComplete","ThreeDSCanceled","ThreeDSError","render","createElement","src","allow","setAttribute","assign","style","width","border","display","appendChild","submit","message","contentWindow","checkoutOrigin","postMessage","position","top","left","alignItems","justifyContent","zIndex","background","threeDSUrl","sessionId","step","challengeUrl","acsTransactionId","threeDSVersion","liveMode","minWidth","minHeight","borderRadius","body","pending3DSData","remove","destroy","removeEventListener","isMounted","PaypercutCheckout"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"paypercut-checkout.iife.min.js","sources":["../src/utils/emitter.ts","../src/config.ts","../src/types/locales.ts","../src/types/checkout.ts","../src/index.ts"],"sourcesContent":["/**\n * Simple event emitter for handling checkout events\n * Supports subscribing, unsubscribing, and emitting events\n */\nexport class Emitter<T extends string = string> {\n private handlers = new Map<T, Set<Function>>();\n\n /**\n * Subscribe to an event\n * @param event - Event name to listen to\n * @param handler - Callback function to execute when event is emitted\n * @returns Unsubscribe function\n */\n on(event: T, handler: Function): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n /**\n * Subscribe to an event that auto-unsubscribes after first emission\n *\n * Common use case: waiting for 'loaded' event or handling first 'success'.\n * Without this helper, developers would need to manually unsubscribe inside\n * their handler, which is error-prone and leads to memory leaks if forgotten.\n *\n * @param event - Event name to listen to\n * @param handler - Callback function to execute when event is emitted\n * @returns Unsubscribe function\n */\n once(event: T, handler: Function): () => void {\n const wrappedHandler = (...args: any[]) => {\n handler(...args);\n this.off(event, wrappedHandler);\n };\n return this.on(event, wrappedHandler);\n }\n\n /**\n * Unsubscribe from an event\n * @param event - Event name to stop listening to\n * @param handler - Callback function to remove\n */\n off(event: T, handler: Function): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n /**\n * Emit an event with optional arguments\n * @param event - Event name to emit\n * @param args - Arguments to pass to event handlers\n */\n emit(event: T, ...args: any[]): void {\n this.handlers.get(event)?.forEach(h => {\n try {\n h(...args);\n } catch (err) {\n console.error(`[Emitter] Error in ${event} handler:`, err);\n }\n });\n }\n\n /**\n * Clear all event handlers\n */\n clear(): void {\n this.handlers.clear();\n }\n}\n\n","/**\n * Build-time configuration\n * \n * This file is processed at build time with different values for:\n * - Production build (for merchants)\n * - Internal build (for team development)\n */\n\n/**\n * Build mode - replaced at build time\n */\ndeclare const __BUILD_MODE__: 'production' | 'internal';\n\n/**\n * SDK version - replaced at build time\n */\ndeclare const __VERSION__: string;\n\n/**\n * Configuration interface\n */\nexport interface BuildConfig {\n /** SDK version */\n version: string;\n \n /** Build mode */\n mode: 'production' | 'internal';\n \n /** Default checkout origin (production URL) */\n defaultCheckoutOrigin: string;\n \n /** Allowed origins for postMessage validation */\n allowedOrigins: string[];\n \n /** Whether hostedCheckoutUrl override is allowed */\n allowOriginOverride: boolean;\n}\n\n/**\n * Production configuration (for merchants)\n */\nconst productionConfig: BuildConfig = {\n version: __VERSION__,\n mode: 'production',\n defaultCheckoutOrigin: 'https://buy.paypercut.io',\n allowedOrigins: [\n 'https://buy.paypercut.io',\n ],\n allowOriginOverride: false\n};\n\n/**\n * Internal configuration (for team development)\n */\nconst internalConfig: BuildConfig = {\n version: __VERSION__,\n mode: 'internal',\n defaultCheckoutOrigin: 'https://buy.paypercut.io',\n allowedOrigins: [\n 'https://buy.paypercut.io',\n 'http://localhost:3000',\n 'http://localhost:3001',\n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001'\n ],\n allowOriginOverride: true\n};\n\n/**\n * Active configuration (selected at build time)\n */\nexport const config: BuildConfig = __BUILD_MODE__ === 'internal' \n ? internalConfig \n : productionConfig;\n\n/**\n * Helper to check if origin is allowed\n */\nexport function isOriginAllowed(origin: string): boolean {\n return config.allowedOrigins.includes(origin);\n}\n\n/**\n * Get the checkout origin (with optional override for internal builds)\n */\nexport function getCheckoutOrigin(override?: string): string {\n // Only allow override in internal builds\n if (override && config.allowOriginOverride) {\n return override;\n }\n \n return config.defaultCheckoutOrigin;\n}\n\n","/**\n * Supported locales for Paypercut Checkout\n *\n * @remarks\n * Single source of truth for all supported locale codes.\n *\n * Supported languages:\n * - Bulgarian: 'bg', 'bg-BG'\n * - English: 'en', 'en-GB'\n * - Greek: 'el', 'el-GR'\n * - Romanian: 'ro', 'ro-RO'\n * - Croatian: 'hr', 'hr-HR'\n * - Polish: 'pl', 'pl-PL'\n * - Czech: 'cs', 'cs-CZ'\n * - Slovenian: 'sl', 'sl-SI'\n * - Slovak: 'sk', 'sk-SK'\n *\n * @example\n * ```typescript\n * const checkout = PaypercutCheckout({\n * locale: 'bg' // or 'bg-BG', 'en', 'en-GB', etc.\n * });\n * ```\n */\nexport const LOCALES = [\n 'bg', 'bg-BG',\n 'en', 'en-GB',\n 'el', 'el-GR',\n 'ro', 'ro-RO',\n 'hr', 'hr-HR',\n 'pl', 'pl-PL',\n 'cs', 'cs-CZ',\n 'sl', 'sl-SI',\n 'sk', 'sk-SK',\n] as const;\n\n/**\n * Locale type - union of all supported locale codes plus 'auto'\n * @example\n * ```typescript\n * const locale: Locale = 'bg';\n * const lang: Locale = 'bg';\n * const autoLocale: Locale = 'auto';\n * ```\n */\nexport type Locale = typeof LOCALES[number] | 'auto';\n\n/**\n * Fast runtime check using Set for O(1) lookup\n * @internal\n */\nconst LOCALE_SET: ReadonlySet<string> = new Set(LOCALES);\n\n/**\n * Normalize and validate locale\n *\n * @param locale - Locale code to normalize\n * @returns Normalized locale code or 'en' as fallback\n *\n * @remarks\n * - 'auto' or empty → 'en'\n * - Unsupported locale → 'en' with console warning\n * - Supported locale → original value\n *\n * @example\n * ```typescript\n * normalizeLocale('auto') // → 'en'\n * normalizeLocale('bg') // → 'bg'\n * normalizeLocale('de') // → 'en' (with warning)\n * ```\n */\nexport function normalizeLocale(locale: string | Locale): typeof LOCALES[number] | 'en' {\n if (!locale || locale === 'auto') return 'en';\n if (LOCALE_SET.has(locale)) return locale as typeof LOCALES[number];\n console.warn(`[PaypercutCheckout] Locale \"${locale}\" is not supported. Falling back to \"en\".`);\n return 'en';\n}\n\n","import { Locale } from './locales';\n\n/**\n * UI mode for checkout\n */\nexport enum UIMode {\n /** Embedded mode - checkout embedded in merchant page */\n EMBEDDED = 'embedded',\n}\n\n/**\n * Type guard for UIMode\n */\nexport function isValidUIMode(value: string): value is UIMode {\n return Object.values(UIMode).includes(value as UIMode);\n}\n\n/**\n * Payment method types\n */\nexport enum PaymentMethod {\n /** Card payment (credit/debit) */\n CARD = 'card',\n}\n\n/**\n * Type guard for PaymentMethod\n */\nexport function isValidPaymentMethod(value: string): value is PaymentMethod {\n return Object.values(PaymentMethod).includes(value as PaymentMethod);\n}\n\n/**\n * Wallet options for digital wallets\n */\nexport enum WalletOption {\n /** Apple Pay */\n APPLE_PAY = 'apple_pay',\n /** Google Pay */\n GOOGLE_PAY = 'google_pay',\n}\n\n/**\n * Type guard for WalletOption\n */\nexport function isValidWalletOption(value: string): value is WalletOption {\n return Object.values(WalletOption).includes(value as WalletOption);\n}\n\n/**\n * Validate payment methods array\n */\nexport function validatePaymentMethods(methods: string[]): PaymentMethod[] {\n const validated: PaymentMethod[] = [];\n\n for (const method of methods) {\n if (isValidPaymentMethod(method)) {\n validated.push(method as PaymentMethod);\n } else {\n console.warn(`[PaypercutCheckout] Invalid payment method: \"${method}\". Skipping.`);\n }\n }\n\n // Default to card if no valid methods\n if (validated.length === 0) {\n console.warn('[PaypercutCheckout] No valid payment methods provided. Defaulting to \"card\".');\n validated.push(PaymentMethod.CARD);\n }\n\n return validated;\n}\n\n/**\n * Validate wallet options array\n */\nexport function validateWalletOptions(options: string[]): WalletOption[] {\n const validated: WalletOption[] = [];\n\n for (const option of options) {\n if (isValidWalletOption(option)) {\n validated.push(option as WalletOption);\n } else {\n console.warn(`[PaypercutCheckout] Invalid wallet option: \"${option}\". Skipping.`);\n }\n }\n\n return validated;\n}\n\n/**\n * Validate UI mode\n */\nexport function validateUIMode(mode: string | undefined): UIMode | undefined {\n if (!mode) {\n return undefined;\n }\n\n if (isValidUIMode(mode)) {\n return mode as UIMode;\n }\n\n console.warn(\n `[PaypercutCheckout] Invalid ui_mode: \"${mode}\". Valid options: ${Object.values(UIMode).join(', ')}`,\n );\n return undefined;\n}\n\n/**\n * Configuration options for PaypercutCheckout\n */\nexport interface PaypercutCheckoutOptions {\n /** Checkout session identifier (e.g., 'CHK_12345') */\n id: string;\n\n /** CSS selector or HTMLElement where iframe mounts (required) */\n containerId: string | HTMLElement;\n\n /**\n * Optional: Custom hosted checkout URL (only available in internal builds)\n * Production builds will ignore this option for security\n */\n hostedCheckoutUrl?: string;\n\n /**\n * Optional: Locale for checkout UI\n * @default 'en'\n */\n locale?: Locale | string;\n\n /**\n * Optional: Language for checkout UI\n * @default 'en'\n */\n lang?: Locale | string;\n\n /**\n * Optional: UI mode for checkout\n */\n ui_mode?: UIMode | `${UIMode}`;\n\n /**\n * Optional: Payment methods to enable\n * @default ['card']\n */\n payment_methods?: (PaymentMethod | `${PaymentMethod}`)[];\n\n /**\n * Optional: Digital wallet options\n * Can include both or just one\n * Default behaviour - shows both\n */\n wallet_options?: (WalletOption | `${WalletOption}`)[] | [];\n\n /**\n * Optional: Show only the payment form without header/footer\n * @default false\n */\n form_only?: boolean;\n\n /**\n * Optional: Appearance options\n */\n appearance?: {\n preset?: 'inline' | 'modal';\n theme?: 'light' | 'dark' | 'none' | 'flat';\n variables: {};\n rules: {};\n labels: 'floating' | 'above' | 'none';\n };\n}\n\n/**\n * Wallet type for form validation\n */\nexport type WalletType = 'apple_pay' | 'google_pay';\n\n/**\n * Form validation event payload\n */\nexport interface FormValidationPayload {\n checkoutId: string;\n wallet: WalletType;\n}\n\n/**\n * Event names that can be emitted by the checkout\n */\nexport type EventName =\n | 'loaded' // iframe finished loading\n | 'success' // payment successful\n | 'error' // payment or system error\n | 'expired' // checkout expired or already paid\n | 'resize' // checkout expired or already paid\n | 'threeds_complete' // checkout paid successfully\n | 'threeds_error' // checkout threeds error\n | 'threeds_canceled' // checkout threeds canceled\n | 'threeds_started' // checkout threeds started\n | 'form_validation'; // wallet button clicked, merchant should validate form\n\n/**\n * Preferred enum for SDK event names (use instead of hardcoded strings)\n */\nexport enum SdkEvent {\n Loaded = 'loaded',\n Success = 'success',\n Error = 'error',\n Expired = 'expired',\n Resize = 'resize',\n ThreeDSComplete = 'threeds_complete',\n ThreeDSError = 'threeds_error',\n ThreeDSCanceled = 'threeds_canceled',\n ThreeDSStarted = 'threeds_started',\n FormValidation = 'form_validation',\n}\n\n/**\n * Form validation error for failFormValidation\n */\nexport interface FormValidationError {\n code?: string;\n message?: string;\n}\n\n/**\n * Checkout instance interface\n */\nexport interface CheckoutInstance {\n /** Mount and render the iframe into the container */\n render(): void;\n\n /** Submit payment - sends message to hosted checkout to confirm payment */\n submit(): void;\n\n /** Destroy instance and cleanup all listeners */\n destroy(): void;\n\n /** Subscribe to events. Returns unsubscribe function */\n on(event: EventName | SdkEvent, handler: (...args: any[]) => void): () => void;\n\n /** Subscribe to event that auto-unsubscribes after first emission */\n once(event: EventName | SdkEvent, handler: (...args: any[]) => void): () => void;\n\n /** Unsubscribe from events */\n off(event: EventName | SdkEvent, handler: (...args: any[]) => void): void;\n\n /** Check if checkout is currently mounted */\n isMounted(): boolean;\n\n /**\n * Complete form validation successfully - allows wallet payment to proceed.\n * Call this in response to 'form_validation' event when merchant form is valid.\n * @param wallet - The wallet type that requested validation ('apple_pay' | 'google_pay')\n */\n completeFormValidation(wallet: WalletType): void;\n\n /**\n * Fail form validation - prevents wallet payment from starting.\n * Call this in response to 'form_validation' event when merchant form has errors.\n * @param wallet - The wallet type that requested validation ('apple_pay' | 'google_pay')\n * @param errors - Optional array of validation errors to pass back\n */\n failFormValidation(wallet: WalletType, errors?: FormValidationError[]): void;\n}\n\n/**\n * PaypercutCheckout static interface (callable and constructable)\n */\nexport interface PaypercutCheckoutStatic {\n /** Callable factory function */\n (options: PaypercutCheckoutOptions): CheckoutInstance;\n\n /** Constructor support */\n new (options: PaypercutCheckoutOptions): CheckoutInstance;\n\n /** SDK version */\n version: string;\n}\n","import { Emitter } from './utils/emitter';\nimport { config, isOriginAllowed, getCheckoutOrigin } from './config';\n\nimport {\n PaypercutCheckoutOptions,\n CheckoutInstance,\n PaypercutCheckoutStatic,\n EventName,\n SdkEvent,\n validatePaymentMethods,\n validateWalletOptions,\n validateUIMode,\n UIMode,\n WalletType,\n FormValidationError,\n} from './types';\nimport { normalizeLocale } from './types';\n\n// Re-export types and enums for consumers\nexport type { PaypercutCheckoutOptions, CheckoutInstance, PaypercutCheckoutStatic, EventName, WalletType, FormValidationError };\n\nexport { UIMode, PaymentMethod, WalletOption } from './types/checkout';\n\n// Re-export SDK event enums for consumers\nexport { SdkEvent } from './types/checkout';\n\nexport type { Locale } from './types/locales';\nexport { LOCALES } from './types/locales';\n\n/**\n * Internal implementation of CheckoutInstance\n */\nclass CheckoutImpl implements CheckoutInstance {\n private emitter = new Emitter<EventName>();\n private mounted = false;\n private destroyed = false;\n private iframe: HTMLIFrameElement | null = null;\n private messageHandler: (evt: MessageEvent) => void;\n\n // 3DS Modal state\n private threeDSModal: HTMLDivElement | null = null;\n private threeDSIframe: HTMLIFrameElement | null = null;\n\n constructor(private options: PaypercutCheckoutOptions) {\n // Bind message handler\n this.messageHandler = this.onMessage.bind(this);\n window.addEventListener('message', this.messageHandler);\n }\n\n /**\n * Build the iframe source URL with query parameters\n */\n private buildSrc(): string {\n const baseUrl = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n const url = new URL(`/c/${this.options.id}`, baseUrl);\n\n // Add locale parameter\n if (this.options.locale) {\n const normalizedLocale = normalizeLocale(this.options.locale);\n url.searchParams.set('locale', normalizedLocale);\n }\n\n // Add lang parameter\n if (this.options.lang) {\n const normalizedLocale = normalizeLocale(this.options.lang);\n url.searchParams.set('lang', normalizedLocale);\n }\n\n // Add ui_mode parameter (default to 'embedded')\n {\n const selected = validateUIMode(this.options.ui_mode ?? UIMode.EMBEDDED);\n if (selected) {\n url.searchParams.set('ui_mode', selected);\n }\n }\n\n // Add payment_methods parameters (repeated for each method)\n if (this.options.payment_methods && this.options.payment_methods.length > 0) {\n const validatedMethods = validatePaymentMethods(this.options.payment_methods as string[]);\n validatedMethods.forEach((method) => {\n url.searchParams.append('payment_methods', method);\n });\n }\n\n // Add wallet_options parameters (repeated for each wallet)\n // If wallet_options is explicitly set (even as empty array), we need to pass it\n if (this.options.wallet_options !== undefined) {\n if (this.options.wallet_options.length === 0) {\n // Explicit empty array means \"no wallets\" - pass null (coerced to \"null\" string)\n url.searchParams.set('wallet_options', null as unknown as string);\n } else {\n const validatedWallets = validateWalletOptions(this.options.wallet_options as string[]);\n validatedWallets.forEach((wallet) => {\n url.searchParams.append('wallet_options', wallet);\n });\n }\n }\n\n if (this.options.appearance?.preset) {\n url.searchParams.set('preset', this.options.appearance.preset);\n }\n\n if (this.options.form_only !== undefined) {\n url.searchParams.set('form_only', String(this.options.form_only));\n }\n\n return url.toString();\n }\n\n /**\n * Get the container element from selector or HTMLElement\n */\n private getContainer(): HTMLElement {\n const container =\n typeof this.options.containerId === 'string'\n ? document.querySelector(this.options.containerId)\n : this.options.containerId;\n\n if (!container) {\n throw new Error(`Container not found: ${this.options.containerId}`);\n }\n\n return container as HTMLElement;\n }\n\n /**\n * Handle incoming postMessage events from iframe\n */\n private onMessage(evt: MessageEvent): void {\n // Validate origin against allowed origins (build-time whitelist)\n if (!isOriginAllowed(evt.origin)) {\n return;\n }\n\n // Validate structure\n const data = evt.data;\n if (!data || typeof data !== 'object' || !('type' in data)) {\n return;\n }\n\n // Filter messages by checkout session ID to prevent cross-instance message handling\n // This ensures each checkout instance only processes its own messages\n if (data.checkoutId && data.checkoutId !== this.options.id) {\n return; // Message is for a different checkout instance\n }\n\n // Handle specific events\n switch (data.type) {\n case 'CHECKOUT_LOADED':\n this.emitter.emit(SdkEvent.Loaded);\n break;\n case 'CHECKOUT_SUCCESS':\n const { payment_method = {} } = data;\n this.emitter.emit(SdkEvent.Success, { payment_method });\n break;\n case 'CHECKOUT_ERROR':\n // Forward error payload (if provided) to SDK consumers\n this.emitter.emit(SdkEvent.Error, (data && (data as any).error) ?? data);\n break;\n case 'CHECKOUT_EXPIRED':\n this.emitter.emit(SdkEvent.Expired);\n break;\n case 'CHECKOUT_RESIZE':\n this.emitter.emit(SdkEvent.Resize, data.height);\n this.handleResize(data.height);\n break;\n case 'THREEDS_START_FLOW':\n this.show3DSModal(data);\n this.emitter.emit(SdkEvent.ThreeDSStarted);\n break;\n case 'THREEDS_READY':\n this.handle3DSReady();\n break;\n case 'THREEDS_COMPLETE':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSComplete);\n break;\n case 'THREEDS_CANCELED':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSCanceled);\n break;\n case 'THREEDS_ERROR':\n this.postToIframe(data);\n this.close3DSModal();\n this.emitter.emit(SdkEvent.ThreeDSError, data.error);\n break;\n case 'FORM_VALIDATION':\n // Wallet button clicked - emit event for merchant to validate their form\n this.emitter.emit(SdkEvent.FormValidation, {\n checkoutId: data.checkoutId,\n wallet: data.wallet as WalletType,\n });\n break;\n }\n }\n\n /**\n * Render the checkout iframe into the container\n */\n render(): void {\n if (this.mounted) {\n return;\n }\n\n try {\n const container = this.getContainer();\n\n // Create iframe\n this.iframe = document.createElement('iframe');\n this.iframe.id = 'paypercut-checkout-iframe';\n this.iframe.src = this.buildSrc();\n this.iframe.allow = 'payment *; clipboard-write';\n this.iframe.setAttribute('frameborder', '0');\n // Allow Payment Request API inside iframe and necessary sandbox permissions for wallets\n this.iframe.setAttribute('allowpaymentrequest', 'true');\n this.iframe.setAttribute(\n 'sandbox',\n 'allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox',\n );\n\n // Apply default styles - just construct URL and assign to iframe\n Object.assign(this.iframe.style, {\n width: '100%',\n height: '100%',\n border: 'none',\n display: 'block',\n });\n\n // Listen for iframe load event (fallback)\n // This ensures 'loaded' event is always emitted even if hosted checkout\n // doesn't send CHECKOUT_LOADED message\n /*this.iframe.addEventListener('load', () => {\n this.emitter.emit('loaded');\n });*/\n\n container.appendChild(this.iframe);\n this.mounted = true;\n } catch (err) {\n console.error('[PaypercutCheckout] Failed to render:', err);\n throw err;\n }\n }\n\n /**\n * Submit payment - sends message to hosted checkout to confirm payment\n */\n submit(): void {\n if (!this.mounted) {\n return;\n }\n\n try {\n this.postToIframe({\n type: 'START_PROCESSING',\n checkoutId: this.options.id,\n });\n } catch (err) {\n console.error('[PaypercutCheckout] Failed to submit payment:', err);\n throw err;\n }\n }\n\n /**\n * Send message to hosted/embedded checkout iframe - used for submit payment and communicating 3DS events\n */\n private postToIframe(message: any): void {\n if (!this.iframe?.contentWindow) {\n console.error('[PaypercutCheckout] Cannot post message: iframe not mounted');\n return;\n }\n\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n this.iframe.contentWindow.postMessage(message, checkoutOrigin);\n }\n\n /**\n * Handle CHECKOUT_RESIZE message - resize iframe to match content height\n */\n private handleResize(height: unknown): void {\n if (!this.iframe || typeof height !== 'number' || height <= 0) {\n return;\n }\n\n // Set iframe height to match content\n this.iframe.style.height = `${height}px`;\n }\n\n /**\n * Show 3DS modal with challenge/decoupled flow\n */\n private show3DSModal(data: {\n sessionId: string;\n step: 'challenge' | 'decoupled_waiting';\n challengeUrl?: string;\n acsTransactionId?: string;\n threeDSVersion?: string;\n cardBrand?: string;\n liveMode?: boolean;\n }): void {\n // Create modal backdrop\n this.threeDSModal = document.createElement('div');\n this.threeDSModal.id = 'paypercut-3ds-modal';\n Object.assign(this.threeDSModal.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: '999999',\n background: 'rgba(0, 0, 0, 0.4)',\n });\n\n // Create iframe for 3DS page\n this.threeDSIframe = document.createElement('iframe');\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n\n // Build URL: baseUrl/c/{checkoutId}/threeds with query params\n const threeDSUrl = new URL(`/c/${this.options.id}/threeds`, checkoutOrigin);\n threeDSUrl.searchParams.set('sessionId', data.sessionId);\n threeDSUrl.searchParams.set('step', data.step);\n\n if (data.challengeUrl) {\n threeDSUrl.searchParams.set('challengeUrl', data.challengeUrl);\n }\n if (data.acsTransactionId) {\n threeDSUrl.searchParams.set('acsTransactionId', data.acsTransactionId);\n }\n if (data.threeDSVersion) {\n threeDSUrl.searchParams.set('threeDSVersion', data.threeDSVersion);\n }\n // Always include liveMode; default to false when undefined\n threeDSUrl.searchParams.set('liveMode', String(data.liveMode ?? false));\n\n this.threeDSIframe.src = threeDSUrl.toString();\n this.threeDSIframe.allow = 'payment *';\n this.threeDSIframe.setAttribute('frameborder', '0');\n\n // Fixed dimensions: follow 3DS component size (500x500)\n Object.assign(this.threeDSIframe.style, {\n minWidth: '400px',\n minHeight: '400px',\n border: 'none',\n borderRadius: '8px',\n display: 'block',\n background: 'transparent',\n });\n\n // Append iframe directly to modal backdrop\n this.threeDSModal.appendChild(this.threeDSIframe);\n document.body.appendChild(this.threeDSModal);\n\n // Store 3DS data for later use\n (this as any).pending3DSData = data;\n }\n\n /**\n * Handle THREEDS_READY message - send THREEDS_INIT with challenge data\n */\n private handle3DSReady(): void {\n const data = (this as any).pending3DSData;\n if (!data || !this.threeDSIframe?.contentWindow) {\n console.error('[PaypercutCheckout] No pending 3DS data or iframe not ready');\n return;\n }\n\n const checkoutOrigin = getCheckoutOrigin(this.options.hostedCheckoutUrl);\n this.threeDSIframe.contentWindow.postMessage(\n {\n type: 'THREEDS_INIT',\n checkoutId: this.options.id,\n },\n checkoutOrigin,\n );\n }\n\n /**\n * Close 3DS modal and cleanup\n */\n private close3DSModal(): void {\n if (this.threeDSModal) {\n this.threeDSModal.remove();\n this.threeDSModal = null;\n }\n\n this.threeDSIframe = null;\n delete (this as any).pending3DSData;\n }\n\n /**\n * Destroy the checkout instance and cleanup (idempotent)\n */\n destroy(): void {\n // Early return if already destroyed\n if (this.destroyed) {\n return;\n }\n\n // Remove iframe from DOM\n if (this.iframe) {\n try {\n this.iframe.remove();\n this.iframe = null;\n } catch (err) {\n console.error('[PaypercutCheckout] Error removing iframe:', err);\n }\n }\n\n // Cleanup 3DS modal if open\n this.close3DSModal();\n\n // Only set mounted = false after successful DOM removal\n this.mounted = false;\n this.destroyed = true;\n\n // Cleanup event listeners\n window.removeEventListener('message', this.messageHandler);\n this.emitter.clear();\n }\n\n /**\n * Subscribe to an event\n */\n on(event: EventName, handler: (...args: any[]) => void): () => void {\n return this.emitter.on(event, handler);\n }\n\n /**\n * Subscribe to event that auto-unsubscribes after first emission\n */\n once(event: EventName, handler: (...args: any[]) => void): () => void {\n return this.emitter.once(event, handler);\n }\n\n /**\n * Unsubscribe from an event\n */\n off(event: EventName, handler: (...args: any[]) => void): void {\n this.emitter.off(event, handler);\n }\n\n /**\n * Check if checkout is currently mounted\n */\n isMounted(): boolean {\n return this.mounted;\n }\n\n /**\n * Complete form validation successfully - allows wallet payment to proceed.\n * Call this in response to 'form_validation' event when merchant form is valid.\n */\n completeFormValidation(wallet: WalletType): void {\n if (!this.mounted) {\n console.warn('[PaypercutCheckout] Cannot complete form validation: not mounted');\n return;\n }\n\n this.postToIframe({\n type: 'FORM_VALIDATION_COMPLETED',\n checkoutId: this.options.id,\n wallet,\n status: 'success',\n });\n }\n\n /**\n * Fail form validation - prevents wallet payment from starting.\n * Call this in response to 'form_validation' event when merchant form has errors.\n */\n failFormValidation(wallet: WalletType, errors?: FormValidationError[]): void {\n if (!this.mounted) {\n console.warn('[PaypercutCheckout] Cannot fail form validation: not mounted');\n return;\n }\n\n this.postToIframe({\n type: 'FORM_VALIDATION_COMPLETED',\n checkoutId: this.options.id,\n wallet,\n status: 'failed',\n errors,\n });\n }\n}\n\n/**\n * Factory function that works both as callable and constructable.\n * Always returns a new CheckoutImpl instance - no prototype manipulation needed.\n */\nconst PaypercutCheckout: PaypercutCheckoutStatic = function (\n this: unknown,\n options: PaypercutCheckoutOptions,\n): CheckoutInstance {\n // Always return a new instance, regardless of how it's called\n return new CheckoutImpl(options);\n} as unknown as PaypercutCheckoutStatic;\n\n// Add static version property\n(PaypercutCheckout as any).version = config.version;\n\n// Export as default and named\nexport default PaypercutCheckout;\nexport { PaypercutCheckout };\n"],"names":["Emitter","constructor","this","handlers","Map","on","event","handler","has","set","Set","get","add","off","once","wrappedHandler","args","delete","emit","forEach","h","err","console","error","clear","config","version","defaultCheckoutOrigin","allowedOrigins","getCheckoutOrigin","override","LOCALE_SET","normalizeLocale","locale","warn","UIMode","PaymentMethod","WalletOption","SdkEvent","isValidPaymentMethod","value","Object","values","includes","isValidWalletOption","validateUIMode","mode","join","CheckoutImpl","options","emitter","mounted","destroyed","iframe","threeDSModal","threeDSIframe","messageHandler","onMessage","bind","window","addEventListener","buildSrc","baseUrl","hostedCheckoutUrl","url","URL","id","normalizedLocale","searchParams","lang","selected","ui_mode","EMBEDDED","payment_methods","length","methods","validated","method","push","CARD","validatePaymentMethods","append","undefined","wallet_options","option","validateWalletOptions","wallet","appearance","preset","form_only","String","toString","getContainer","container","containerId","document","querySelector","Error","evt","origin","data","checkoutId","type","Loaded","payment_method","Success","Expired","Resize","height","handleResize","show3DSModal","ThreeDSStarted","handle3DSReady","postToIframe","close3DSModal","ThreeDSComplete","ThreeDSCanceled","ThreeDSError","FormValidation","render","createElement","src","allow","setAttribute","assign","style","width","border","display","appendChild","submit","message","contentWindow","checkoutOrigin","postMessage","position","top","left","alignItems","justifyContent","zIndex","background","threeDSUrl","sessionId","step","challengeUrl","acsTransactionId","threeDSVersion","liveMode","minWidth","minHeight","borderRadius","body","pending3DSData","remove","destroy","removeEventListener","isMounted","completeFormValidation","status","failFormValidation","errors","PaypercutCheckout"],"mappings":"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"}
|