@inflow_pay/sdk 0.2.0 → 0.4.0
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/CHANGELOG.md +65 -0
- package/README.md +264 -8
- package/dist/{payment-sdk-DRIfoXw9.js → payment-sdk-CvXfOxY6.js} +6 -5
- package/dist/payment-sdk-CvXfOxY6.js.map +1 -0
- package/dist/{payment-sdk-DCTbabp6.mjs → payment-sdk-DK3VOIGL.mjs} +12 -5
- package/dist/payment-sdk-DK3VOIGL.mjs.map +1 -0
- package/dist/react.cjs +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.esm.js +12 -12
- package/dist/react.esm.js.map +1 -1
- package/dist/react.umd.js +11 -10
- package/dist/react.umd.js.map +1 -1
- package/dist/sdk.cjs +1 -1
- package/dist/sdk.cjs.map +1 -1
- package/dist/sdk.d.ts +3 -2
- package/dist/sdk.esm.js +3 -3
- package/dist/sdk.esm.js.map +1 -1
- package/dist/sdk.umd.js +12 -11
- package/dist/sdk.umd.js.map +1 -1
- package/package.json +2 -1
- package/dist/payment-sdk-DCTbabp6.mjs.map +0 -1
- package/dist/payment-sdk-DRIfoXw9.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.3.0] - 2026-01-21
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Dynamic Height Calculation**: Iframe now automatically adjusts its height based on content using postMessage communication
|
|
14
|
+
- Eliminates unnecessary empty space when no error/success messages are displayed
|
|
15
|
+
- Prevents overflow when messages appear
|
|
16
|
+
- Smooth height transitions with CSS animations
|
|
17
|
+
- Height is calculated and sent from iframe to parent SDK when content changes
|
|
18
|
+
|
|
19
|
+
## [0.2.0] - 2026-01-21
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- **Skeleton Loader with Shimmer Effect**: Beautiful loading state that matches the SDK structure
|
|
23
|
+
- Shimmer animation effect for better UX
|
|
24
|
+
- Dark mode support with adaptive colors
|
|
25
|
+
- Automatically hides when iframe is ready
|
|
26
|
+
- **Initial Height Fix**: Fixed iframe height to prevent overflow and empty space issues
|
|
27
|
+
- Set minimum height to accommodate content
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- Fixed iframe visibility issue where loader would show on top of iframe
|
|
31
|
+
- Fixed empty space issue when centering SDK in flex containers
|
|
32
|
+
- Fixed disclaimer overflow when general error/success messages appear
|
|
33
|
+
|
|
34
|
+
## [0.1.0] - 2026-01-20
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
- **Customization Properties**: Comprehensive styling API for customizing the payment form
|
|
38
|
+
- Input container styling (backgroundColor, borderColor, borderRadius, borderEnabled)
|
|
39
|
+
- Input field styling (textColor, placeholderColor, backgroundColor, borders)
|
|
40
|
+
- Button styling with hover and disabled states
|
|
41
|
+
- General error and success message styling
|
|
42
|
+
- Theme support (light/dark mode overrides)
|
|
43
|
+
- Custom font family selection
|
|
44
|
+
- Custom button text
|
|
45
|
+
- Custom input placeholders
|
|
46
|
+
- **Enhanced Type Safety**: Added proper TypeScript types for styling properties
|
|
47
|
+
- `FontWeight` type: Supports numeric (100-900) and keyword values ('normal', 'bold', 'lighter', 'bolder')
|
|
48
|
+
- `Opacity` type: Supports both number (0-1) and string ('0.5', '50%') values
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
- **Button Border Logic**: Fixed inconsistent border behavior
|
|
52
|
+
- Borders now only apply when `borderEnabled: true` is explicitly set
|
|
53
|
+
- Previously, borders would appear if `borderColor` was provided without `borderEnabled`
|
|
54
|
+
- Matches the behavior of `inputContainer` border logic
|
|
55
|
+
|
|
56
|
+
## [0.0.1]
|
|
57
|
+
|
|
58
|
+
### Added
|
|
59
|
+
- Initial release of the SDK with iframe-based payment flow
|
|
60
|
+
- React and vanilla JavaScript support
|
|
61
|
+
- Basic payment processing
|
|
62
|
+
- 3D Secure (3DS) support
|
|
63
|
+
- TypeScript definitions
|
|
64
|
+
- Secure iframe-based card form
|
|
65
|
+
- Automatic 3DS handling
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# InflowPay
|
|
1
|
+
# InflowPay Iframe-based Payment SDK
|
|
2
2
|
|
|
3
|
-
Accept card payments with a pre-built, secure payment form.
|
|
3
|
+
Accept card payments with a pre-built, secure payment form. Uses an iframe-based architecture for enhanced security and easy integration.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -28,7 +28,7 @@ Or use via CDN (UMD build):
|
|
|
28
28
|
|
|
29
29
|
## Quick Start
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
Get started with the iframe-based SDK:
|
|
32
32
|
|
|
33
33
|
```javascript
|
|
34
34
|
import { InflowPayProvider } from '@inflow_pay/sdk';
|
|
@@ -105,6 +105,25 @@ const cardElement = provider.createCardElement({
|
|
|
105
105
|
paymentId: 'pay_xxx', // Required
|
|
106
106
|
container: '#card-container', // Required (CSS selector or HTMLElement)
|
|
107
107
|
|
|
108
|
+
// Styling (optional)
|
|
109
|
+
style: {
|
|
110
|
+
fontFamily: 'Inter',
|
|
111
|
+
button: {
|
|
112
|
+
backgroundColor: '#0070F3',
|
|
113
|
+
textColor: '#FFFFFF'
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
// Custom button text (optional)
|
|
118
|
+
buttonText: 'Complete Payment',
|
|
119
|
+
|
|
120
|
+
// Custom placeholders (optional)
|
|
121
|
+
placeholders: {
|
|
122
|
+
cardNumber: '1234 5678 9012 3456',
|
|
123
|
+
expiry: 'MM/YY',
|
|
124
|
+
cvc: 'CVC'
|
|
125
|
+
},
|
|
126
|
+
|
|
108
127
|
// Callbacks (same as React SDK)
|
|
109
128
|
onReady: () => {
|
|
110
129
|
// Card element is mounted and ready
|
|
@@ -167,7 +186,6 @@ cardElement.destroy();
|
|
|
167
186
|
|
|
168
187
|
<script src="https://cdn.inflowpay.com/sdk/v2/sdk.umd.js"></script>
|
|
169
188
|
<script>
|
|
170
|
-
// Same API as React SDK!
|
|
171
189
|
// SDK is available as window.InflowPaySDK
|
|
172
190
|
const provider = new InflowPaySDK.InflowPayProvider({
|
|
173
191
|
config: { apiKey: 'inflow_pub_xxx' }
|
|
@@ -255,14 +273,14 @@ See [API documentation](https://docs.inflowpay.com/v0/reference/createpayment) f
|
|
|
255
273
|
|
|
256
274
|
## Migration from React SDK
|
|
257
275
|
|
|
258
|
-
The SDK
|
|
276
|
+
The iframe-based SDK maintains similar component APIs, but **styling has changed**. You have two options:
|
|
259
277
|
|
|
260
278
|
### Option 1: Keep Using React (Recommended for React Apps)
|
|
261
279
|
|
|
262
|
-
If you're using React, you can use the React components
|
|
280
|
+
If you're using React, you can use the React components with a similar API:
|
|
263
281
|
|
|
264
282
|
```tsx
|
|
265
|
-
//
|
|
283
|
+
// Change the import path
|
|
266
284
|
import { InflowPayProvider, CardElement } from '@inflow_pay/sdk/react';
|
|
267
285
|
|
|
268
286
|
function App() {
|
|
@@ -270,6 +288,14 @@ function App() {
|
|
|
270
288
|
<InflowPayProvider config={{ apiKey: 'inflow_pub_xxx' }}>
|
|
271
289
|
<CardElement
|
|
272
290
|
paymentId={paymentId}
|
|
291
|
+
style={{
|
|
292
|
+
// ⚠️ Styling API has changed - see Styling section below
|
|
293
|
+
fontFamily: 'Inter',
|
|
294
|
+
button: {
|
|
295
|
+
backgroundColor: '#0070F3',
|
|
296
|
+
textColor: '#FFFFFF'
|
|
297
|
+
}
|
|
298
|
+
}}
|
|
273
299
|
onComplete={(result) => {
|
|
274
300
|
if (result.status === 'CHECKOUT_SUCCESS') {
|
|
275
301
|
window.location.href = '/success';
|
|
@@ -281,7 +307,7 @@ function App() {
|
|
|
281
307
|
}
|
|
282
308
|
```
|
|
283
309
|
|
|
284
|
-
**
|
|
310
|
+
**Important:** The component API is similar, but **styling customization has changed**. See the [Styling](#styling) section for the new styling structure.
|
|
285
311
|
|
|
286
312
|
### Option 2: Vanilla JavaScript (For Non-React Apps)
|
|
287
313
|
|
|
@@ -312,6 +338,7 @@ cardElement.mount();
|
|
|
312
338
|
- Explicit `container` prop (CSS selector or HTMLElement) instead of JSX
|
|
313
339
|
- Call `mount()` explicitly instead of automatic React mounting
|
|
314
340
|
- Same callbacks, same status codes, same error handling
|
|
341
|
+
- **Styling API has changed** - see [Styling](#styling) section for details
|
|
315
342
|
|
|
316
343
|
## TypeScript
|
|
317
344
|
|
|
@@ -339,6 +366,224 @@ const cardElement = provider.createCardElement({
|
|
|
339
366
|
});
|
|
340
367
|
```
|
|
341
368
|
|
|
369
|
+
## Styling
|
|
370
|
+
|
|
371
|
+
The iframe-based SDK provides a comprehensive styling API to match your brand. **Note: The styling structure is different from the original React SDK.** All styles are fully typed with TypeScript.
|
|
372
|
+
|
|
373
|
+
### Basic Styling
|
|
374
|
+
|
|
375
|
+
```javascript
|
|
376
|
+
const cardElement = provider.createCardElement({
|
|
377
|
+
paymentId: 'pay_xxx',
|
|
378
|
+
container: '#card-container',
|
|
379
|
+
style: {
|
|
380
|
+
fontFamily: 'Inter',
|
|
381
|
+
fillParent: true,
|
|
382
|
+
inputContainer: {
|
|
383
|
+
backgroundColor: '#F5F5F5',
|
|
384
|
+
borderRadius: '8px',
|
|
385
|
+
borderEnabled: true,
|
|
386
|
+
borderColor: '#E0E0E0'
|
|
387
|
+
},
|
|
388
|
+
input: {
|
|
389
|
+
textColor: '#1A1A1A',
|
|
390
|
+
placeholderColor: '#999999'
|
|
391
|
+
},
|
|
392
|
+
button: {
|
|
393
|
+
backgroundColor: '#0070F3',
|
|
394
|
+
textColor: '#FFFFFF',
|
|
395
|
+
borderRadius: '8px',
|
|
396
|
+
fontSize: '16px',
|
|
397
|
+
fontWeight: 600,
|
|
398
|
+
opacity: 1,
|
|
399
|
+
hover: {
|
|
400
|
+
backgroundColor: '#0051CC'
|
|
401
|
+
},
|
|
402
|
+
disabled: {
|
|
403
|
+
opacity: 0.5
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Theme Support (Light/Dark Mode)
|
|
411
|
+
|
|
412
|
+
The SDK automatically adapts to the user's system preference, but you can also provide theme-specific overrides:
|
|
413
|
+
|
|
414
|
+
```javascript
|
|
415
|
+
style: {
|
|
416
|
+
// Base styles (apply to both themes)
|
|
417
|
+
fontFamily: 'Inter',
|
|
418
|
+
button: {
|
|
419
|
+
backgroundColor: '#0070F3',
|
|
420
|
+
textColor: '#FFFFFF'
|
|
421
|
+
},
|
|
422
|
+
// Light mode overrides
|
|
423
|
+
light: {
|
|
424
|
+
inputContainer: {
|
|
425
|
+
backgroundColor: '#FFFFFF',
|
|
426
|
+
borderColor: '#E0E0E0'
|
|
427
|
+
},
|
|
428
|
+
input: {
|
|
429
|
+
textColor: '#1A1A1A'
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
// Dark mode overrides
|
|
433
|
+
dark: {
|
|
434
|
+
inputContainer: {
|
|
435
|
+
backgroundColor: '#1A1A1A',
|
|
436
|
+
borderColor: '#333333'
|
|
437
|
+
},
|
|
438
|
+
input: {
|
|
439
|
+
textColor: '#FFFFFF',
|
|
440
|
+
backgroundColor: '#2A2A2A'
|
|
441
|
+
},
|
|
442
|
+
button: {
|
|
443
|
+
backgroundColor: '#0066CC'
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### Available Font Families
|
|
450
|
+
|
|
451
|
+
```typescript
|
|
452
|
+
type FontFamily =
|
|
453
|
+
| 'DM Sans'
|
|
454
|
+
| 'Inter'
|
|
455
|
+
| 'Poppins'
|
|
456
|
+
| 'Nunito'
|
|
457
|
+
| 'Work Sans'
|
|
458
|
+
| 'Manrope'
|
|
459
|
+
| 'Rubik'
|
|
460
|
+
| 'Karla'
|
|
461
|
+
| 'Figtree'
|
|
462
|
+
| 'Outfit'
|
|
463
|
+
| 'Space Grotesk'
|
|
464
|
+
| 'Urbanist';
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Complete Styling API
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
interface CSSProperties {
|
|
471
|
+
fontFamily?: FontFamily;
|
|
472
|
+
fillParent?: boolean;
|
|
473
|
+
|
|
474
|
+
// Input container (wrapper around all inputs)
|
|
475
|
+
inputContainer?: {
|
|
476
|
+
backgroundColor?: string;
|
|
477
|
+
borderColor?: string;
|
|
478
|
+
borderEnabled?: boolean; // Must be true to show border
|
|
479
|
+
borderRadius?: string;
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
// Individual input fields
|
|
483
|
+
input?: {
|
|
484
|
+
backgroundColor?: string;
|
|
485
|
+
borderColor?: string;
|
|
486
|
+
borderEnabled?: boolean;
|
|
487
|
+
borderRadius?: string;
|
|
488
|
+
textColor?: string;
|
|
489
|
+
placeholderColor?: string;
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
// Button styles
|
|
493
|
+
button?: {
|
|
494
|
+
backgroundColor?: string;
|
|
495
|
+
textColor?: string;
|
|
496
|
+
borderRadius?: string;
|
|
497
|
+
borderColor?: string;
|
|
498
|
+
borderEnabled?: boolean; // Must be true to show border
|
|
499
|
+
fontSize?: string;
|
|
500
|
+
fontWeight?: FontWeight;
|
|
501
|
+
opacity?: Opacity;
|
|
502
|
+
hover?: ButtonBaseStyles; // Hover state
|
|
503
|
+
disabled?: ButtonBaseStyles; // Disabled state
|
|
504
|
+
loaderColor?: string;
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
// General messages (errors/success)
|
|
508
|
+
generalError?: {
|
|
509
|
+
textColor?: string;
|
|
510
|
+
backgroundColor?: string;
|
|
511
|
+
borderEnabled?: boolean;
|
|
512
|
+
borderRadius?: string;
|
|
513
|
+
borderColor?: string;
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
generalSuccess?: {
|
|
517
|
+
textColor?: string;
|
|
518
|
+
backgroundColor?: string;
|
|
519
|
+
borderEnabled?: boolean;
|
|
520
|
+
borderRadius?: string;
|
|
521
|
+
borderColor?: string;
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
// Other colors
|
|
525
|
+
disclaimerColor?: string;
|
|
526
|
+
fieldErrorColor?: string;
|
|
527
|
+
|
|
528
|
+
// Theme-specific overrides
|
|
529
|
+
light?: ThemeStyles;
|
|
530
|
+
dark?: ThemeStyles;
|
|
531
|
+
}
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Custom Placeholders
|
|
535
|
+
|
|
536
|
+
```javascript
|
|
537
|
+
placeholders: {
|
|
538
|
+
cardNumber: '1234 5678 9012 3456',
|
|
539
|
+
expiry: 'MM/YY',
|
|
540
|
+
cvc: 'CVC'
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
### Custom Button Text
|
|
545
|
+
|
|
546
|
+
```javascript
|
|
547
|
+
buttonText: 'Pay Now'
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### React Example with Styling
|
|
551
|
+
|
|
552
|
+
```tsx
|
|
553
|
+
import { InflowPayProvider, CardElement } from '@inflow_pay/sdk/react';
|
|
554
|
+
|
|
555
|
+
function App() {
|
|
556
|
+
return (
|
|
557
|
+
<InflowPayProvider config={{ apiKey: 'inflow_pub_xxx' }}>
|
|
558
|
+
<CardElement
|
|
559
|
+
paymentId="pay_xxx"
|
|
560
|
+
style={{
|
|
561
|
+
fontFamily: 'Inter',
|
|
562
|
+
fillParent: true,
|
|
563
|
+
button: {
|
|
564
|
+
backgroundColor: '#0070F3',
|
|
565
|
+
textColor: '#FFFFFF',
|
|
566
|
+
borderRadius: '8px',
|
|
567
|
+
fontWeight: 600
|
|
568
|
+
},
|
|
569
|
+
dark: {
|
|
570
|
+
button: {
|
|
571
|
+
backgroundColor: '#0066CC'
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}}
|
|
575
|
+
buttonText="Complete Payment"
|
|
576
|
+
onComplete={(result) => {
|
|
577
|
+
if (result.status === 'CHECKOUT_SUCCESS') {
|
|
578
|
+
alert('Payment successful!');
|
|
579
|
+
}
|
|
580
|
+
}}
|
|
581
|
+
/>
|
|
582
|
+
</InflowPayProvider>
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
```
|
|
586
|
+
|
|
342
587
|
## Security
|
|
343
588
|
|
|
344
589
|
- ✅ Card data is tokenized before reaching your server (PCI compliant)
|
|
@@ -347,11 +592,22 @@ const cardElement = provider.createCardElement({
|
|
|
347
592
|
- ✅ All requests over HTTPS
|
|
348
593
|
- ✅ Iframe isolation for security
|
|
349
594
|
|
|
595
|
+
## Features
|
|
596
|
+
|
|
597
|
+
- ✅ **Dynamic Height**: Automatically adjusts iframe height based on content
|
|
598
|
+
- ✅ **Skeleton Loader**: Beautiful loading state with shimmer effect
|
|
599
|
+
- ✅ **Dark Mode Support**: Automatic theme detection with manual overrides
|
|
600
|
+
- ✅ **TypeScript**: Full type definitions included
|
|
601
|
+
- ✅ **Responsive**: Works on all screen sizes
|
|
602
|
+
- ✅ **Accessible**: WCAG compliant
|
|
603
|
+
- ✅ **Secure**: PCI compliant, iframe isolation
|
|
604
|
+
|
|
350
605
|
## Support
|
|
351
606
|
|
|
352
607
|
- **Documentation:** https://docs.inflowpay.com/v0/reference/createpayment
|
|
353
608
|
- **Email:** support@inflowpay.com
|
|
354
609
|
- **GitHub:** https://github.com/inflowpay/sdk
|
|
610
|
+
- **Changelog:** See [CHANGELOG.md](./CHANGELOG.md) for version history
|
|
355
611
|
|
|
356
612
|
## License
|
|
357
613
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";class
|
|
1
|
+
"use strict";class w{constructor(e){if(this.iframe=null,this.messageListener=null,this.containerElement=null,this.config=e,this.iframeUrl=e.iframeUrl||"http://localhost:3000/iframe/checkout",this.environment=this.getEnvironmentFromApiKey(e.apiKey||""),this.usePopup=!e.container,e.container)if(typeof e.container=="string"){if(this.containerElement=document.querySelector(e.container),!this.containerElement)throw new Error(`Container not found: ${e.container}`)}else this.containerElement=e.container}init(){this.iframe||(this.createIframe(),this.addMessageListener())}createIframe(){const e=new URL(this.iframeUrl);this.config.apiKey&&e.searchParams.set("apiKey",this.config.apiKey),this.config.config?.paymentId&&e.searchParams.set("paymentId",this.config.config.paymentId);const t=e.toString();if(this.usePopup){const i=document.createElement("div");i.id="inflowpay-sdk-overlay",i.style.cssText=`
|
|
2
2
|
position: fixed;
|
|
3
3
|
top: 0;
|
|
4
4
|
left: 0;
|
|
@@ -41,11 +41,12 @@
|
|
|
41
41
|
`,this.iframe.setAttribute("allow","payment"),n.appendChild(s),n.appendChild(this.iframe),i.appendChild(n),document.body.appendChild(i),this.showLoader(n),i.addEventListener("click",o=>{o.target===i&&this.close()})}else{if(!this.containerElement)throw new Error("Container element is required for inline mode");if(this.containerElement.innerHTML="",this.containerElement instanceof HTMLElement){const s=this.containerElement.getAttribute("style")||"";s.includes("min-height")||(this.containerElement.style.minHeight="196px"),s.includes("position")||(this.containerElement.style.position="relative"),s.includes("overflow")||(this.containerElement.style.overflow="hidden")}this.iframe=document.createElement("iframe"),this.iframe.src=t;const i=this.config.config?.style?.fillParent?"100%":"344px",n=this.config.config?.style?.fillParent?"none":"100%";this.iframe.style.cssText=`
|
|
42
42
|
width: ${i};
|
|
43
43
|
max-width: ${n};
|
|
44
|
-
height:
|
|
44
|
+
height: 196px;
|
|
45
45
|
min-height: 196px;
|
|
46
46
|
border: none;
|
|
47
47
|
display: block;
|
|
48
|
-
|
|
48
|
+
transition: height 0.2s ease;
|
|
49
|
+
`,this.iframe.setAttribute("allow","payment"),this.containerElement.appendChild(this.iframe),this.showLoader(this.containerElement)}}addMessageListener(){this.messageListener=e=>{const t=new URL(this.iframeUrl).origin;let n=e.origin===t;if(n||((this.environment==="sandbox"||this.environment==="development")&&(n=(e.origin.includes("localhost")||e.origin.includes("127.0.0.1"))&&(t.includes("localhost")||t.includes("127.0.0.1"))),n||(n=e.origin==="https://dev.api.inflowpay.com"||e.origin==="https://pre-prod.api.inflowpay.xyz"||e.origin==="https://api.inflowpay.xyz")),!n){this.config.debug&&console.warn("[SDK] Rejected message from unauthorized origin:",e.origin);return}const s=e.data;if(!(!s||!s.type))switch(s.type){case"iframe-ready":this.hideLoader(),this.sendConfigToIframe();break;case"content-height":if(s.height&&this.iframe){const o=Math.max(s.height,196);this.iframe.style.height=`${o}px`,this.containerElement&&(this.containerElement.style.minHeight=`${o}px`)}break;case"close":this.close();break;case"success":this.config.onSuccess&&this.config.onSuccess(s.data);break;case"error":this.config.onError&&this.config.onError(s.data);break;case"3ds-required":this.config.debug&&console.log("[SDK] Received 3DS request:",s.threeDsSessionUrl),s.threeDsSessionUrl?(this.config.debug&&console.log("[SDK] Opening 3DS modal..."),this.open3DSModal(s.threeDsSessionUrl).then(o=>{if(this.config.debug&&console.log("[SDK] 3DS modal closed, result:",o),this.iframe&&this.iframe.contentWindow){const r=this.getTargetOrigin();this.iframe.contentWindow.postMessage({type:"3ds-result",success:o,paymentId:s.paymentId||this.config.config?.paymentId},r)}})):this.config.debug&&console.error("[SDK] 3DS required but no threeDsSessionUrl provided");break;default:this.config.debug&&console.log("SDK: Received message:",s)}},window.addEventListener("message",this.messageListener)}sendConfigToIframe(){if(!this.iframe||!this.iframe.contentWindow){this.iframe&&(this.iframe.onload=()=>{this.sendConfigToIframe()});return}const e={type:"sdkData",config:{...this.config.config||{},paymentId:this.config.config?.paymentId},data:{apiKey:this.config.apiKey}},t=this.getTargetOrigin();this.iframe.contentWindow.postMessage(e,t)}showLoader(e){this.iframe&&(this.iframe.style.display="none");const t=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches,i=t?"#2d2d2d":"#F5F5F5",n=t?"#3d3d3d":"#E5E5E5",o=`linear-gradient(90deg, ${n} 25%, ${t?"#4d4d4d":"#F0F0F0"} 50%, ${n} 75%)`,r=document.createElement("div");r.id="inflowpay-loader";const u=this.config.config?.style?.fillParent?"100%":"344px";r.style.cssText=`
|
|
49
50
|
position: absolute;
|
|
50
51
|
top: 0;
|
|
51
52
|
left: 0;
|
|
@@ -173,5 +174,5 @@
|
|
|
173
174
|
width: 100%;
|
|
174
175
|
height: 100%;
|
|
175
176
|
border: none;
|
|
176
|
-
`,r.setAttribute("allow","payment"),r.setAttribute("sandbox","allow-forms allow-scripts allow-same-origin allow-popups"),o.appendChild(r),n.appendChild(s),n.appendChild(o),i.appendChild(n),document.body.appendChild(i);const u=i.querySelector("#inflowpay-3ds-close"),c=()=>{i.remove(),window.removeEventListener("message",l),t(!1)};u?.addEventListener("click",c);const l=a=>{if(!a.data)return;const p=["https://dev.api.inflowpay.com","https://pre-prod.api.inflowpay.xyz","https://api.inflowpay.xyz"];if(this.environment==="sandbox"||this.environment==="development"){if(!(a.origin.includes("localhost")||a.origin.includes("127.0.0.1"))){if(!p.includes(a.origin)){this.config.debug&&console.warn("[SDK] Rejected 3DS message from unauthorized origin:",a.origin);return}}}else if(!p.includes(a.origin)){this.config.debug&&console.warn("[SDK] Rejected 3DS message from unauthorized origin:",a.origin);return}const d=a.data,m=d.type==="THREE_DS_COMPLETE"||d.type==="3ds-complete",h=d.status==="success",f=d.status==="failed"||d.status==="failure";if(m&&h){i.remove(),window.removeEventListener("message",l),t(!0);return}if(h&&!m){i.remove(),window.removeEventListener("message",l),t(!0);return}if(m&&f||d.type==="3ds-failed"||f){i.remove(),window.removeEventListener("message",l),t(!1);return}};window.addEventListener("message",l)})}getTargetOrigin(){return this.environment==="production"||this.environment==="preprod"?new URL(this.iframeUrl).origin:"*"}getEnvironmentFromApiKey(e){return!e||e.includes("_local_")||e.startsWith("inflow_local_")?"sandbox":e.includes("_prod_")&&!e.includes("_preprod_")?"production":e.includes("_preprod_")||e.startsWith("inflow_preprod_")?"preprod":e.includes("_dev_")?"development":"sandbox"}destroy(){this.close()}}class b{constructor(e,t){this.mounted=!1;let i;if(typeof t.container=="string"){if(i=document.querySelector(t.container),!i)throw new Error(`Container not found: ${t.container}`)}else i=t.container;this.container=i,this.sdk=new
|
|
177
|
-
//# sourceMappingURL=payment-sdk-
|
|
177
|
+
`,r.setAttribute("allow","payment"),r.setAttribute("sandbox","allow-forms allow-scripts allow-same-origin allow-popups"),o.appendChild(r),n.appendChild(s),n.appendChild(o),i.appendChild(n),document.body.appendChild(i);const u=i.querySelector("#inflowpay-3ds-close"),c=()=>{i.remove(),window.removeEventListener("message",l),t(!1)};u?.addEventListener("click",c);const l=a=>{if(!a.data)return;const p=["https://dev.api.inflowpay.com","https://pre-prod.api.inflowpay.xyz","https://api.inflowpay.xyz"];if(this.environment==="sandbox"||this.environment==="development"){if(!(a.origin.includes("localhost")||a.origin.includes("127.0.0.1"))){if(!p.includes(a.origin)){this.config.debug&&console.warn("[SDK] Rejected 3DS message from unauthorized origin:",a.origin);return}}}else if(!p.includes(a.origin)){this.config.debug&&console.warn("[SDK] Rejected 3DS message from unauthorized origin:",a.origin);return}const d=a.data,m=d.type==="THREE_DS_COMPLETE"||d.type==="3ds-complete",h=d.status==="success",f=d.status==="failed"||d.status==="failure";if(m&&h){i.remove(),window.removeEventListener("message",l),t(!0);return}if(h&&!m){i.remove(),window.removeEventListener("message",l),t(!0);return}if(m&&f||d.type==="3ds-failed"||f){i.remove(),window.removeEventListener("message",l),t(!1);return}};window.addEventListener("message",l)})}getTargetOrigin(){return this.environment==="production"||this.environment==="preprod"?new URL(this.iframeUrl).origin:"*"}getEnvironmentFromApiKey(e){return!e||e.includes("_local_")||e.startsWith("inflow_local_")?"sandbox":e.includes("_prod_")&&!e.includes("_preprod_")?"production":e.includes("_preprod_")||e.startsWith("inflow_preprod_")?"preprod":e.includes("_dev_")?"development":"sandbox"}destroy(){this.close()}}class b{constructor(e,t){this.mounted=!1;let i;if(typeof t.container=="string"){if(i=document.querySelector(t.container),!i)throw new Error(`Container not found: ${t.container}`)}else i=t.container;this.container=i,this.sdk=new w({iframeUrl:e.iframeUrl,apiKey:e.apiKey,container:this.container,config:{paymentId:t.paymentId,...t.style&&{style:t.style},...t.buttonText&&{buttonText:t.buttonText},...t.placeholders&&{placeholders:t.placeholders}},onSuccess:n=>{t.onComplete&&t.onComplete({status:n?.data?.transaction?.status||"CHECKOUT_SUCCESS",data:n})},onError:n=>{t.onError?t.onError(n):t.onComplete&&t.onComplete({status:"PAYMENT_FAILED",error:n})},onClose:()=>{t.onClose&&t.onClose()}})}mount(){if(this.mounted)throw new Error("CardElement is already mounted");this.sdk.init(),this.mounted=!0}destroy(){this.mounted&&(this.sdk.destroy(),this.mounted=!1)}}class E{constructor(e){if(!e.apiKey||typeof e.apiKey!="string")throw new Error("API key is required");let t=e.iframeUrl;const i=this.getEnvironmentFromApiKey(e.apiKey);t||(i==="production"?t="https://api.inflowpay.xyz/iframe/checkout":i==="preprod"?t="https://pre-prod.api.inflowpay.xyz/iframe/checkout":i==="development"?t="https://dev.api.inflowpay.com/iframe/checkout":t="http://localhost:3000/iframe/checkout");const n=e.debug??!1;n&&(i==="production"||i==="preprod")&&console.warn("[InflowPay SDK] Debug mode is not allowed in production/pre-prod environments. Debug mode disabled.");const s=n&&(i==="sandbox"||i==="development");this.config={apiKey:e.apiKey,iframeUrl:t,timeout:e.timeout??3e4,debug:s}}createCardElement(e){return new b(this.config,e)}getIframeUrl(){return this.config.iframeUrl}getApiKey(){return this.config.apiKey}getEnvironmentFromApiKey(e){return e.includes("_local_")||e.startsWith("inflow_local_")?"sandbox":e.includes("_prod_")&&!e.includes("_preprod_")?"production":e.includes("_preprod_")||e.startsWith("inflow_preprod_")?"preprod":e.includes("_dev_")?"development":"sandbox"}}exports.CardElement=b;exports.PaymentSDK=E;exports.SDK=w;
|
|
178
|
+
//# sourceMappingURL=payment-sdk-CvXfOxY6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment-sdk-CvXfOxY6.js","sources":["../src/sdk.ts","../src/card-element.ts","../src/payment-sdk.ts"],"sourcesContent":["/**\n * InflowPay SDK v2 - Iframe-based Payment SDK\n * \n * This SDK creates an iframe and communicates with a React payment application\n * using postMessage API for secure cross-origin communication.\n */\n\nimport type { SDKConfig, IframeMessage } from './types';\n\nexport class SDK {\n private iframe: HTMLIFrameElement | null = null;\n private iframeUrl: string;\n private config: SDKConfig;\n private messageListener: ((event: MessageEvent) => void) | null = null;\n private containerElement: HTMLElement | null = null;\n private usePopup: boolean;\n private environment: 'sandbox' | 'production' | 'development' | 'preprod';\n\n constructor(config: SDKConfig) {\n this.config = config;\n this.iframeUrl = config.iframeUrl || 'http://localhost:3000/iframe/checkout';\n this.environment = this.getEnvironmentFromApiKey(config.apiKey || '');\n\n // Determine if we should use popup or inline\n this.usePopup = !config.container;\n\n // Resolve container if provided\n if (config.container) {\n if (typeof config.container === 'string') {\n this.containerElement = document.querySelector(config.container);\n if (!this.containerElement) {\n throw new Error(`Container not found: ${config.container}`);\n }\n } else {\n this.containerElement = config.container;\n }\n }\n }\n\n /**\n * Initialize and open the payment iframe\n */\n init(): void {\n if (this.iframe) {\n return;\n }\n\n this.createIframe();\n this.addMessageListener();\n }\n\n /**\n * Create and append the iframe to the document\n */\n private createIframe(): void {\n // Build iframe URL with API key and paymentId as query parameters\n const url = new URL(this.iframeUrl);\n if (this.config.apiKey) {\n url.searchParams.set('apiKey', this.config.apiKey);\n }\n if (this.config.config?.paymentId) {\n url.searchParams.set('paymentId', this.config.config.paymentId);\n }\n const iframeSrc = url.toString();\n\n if (this.usePopup) {\n // Create overlay for popup mode\n const overlay = document.createElement('div');\n overlay.id = 'inflowpay-sdk-overlay';\n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 999999;\n `;\n\n // Create iframe container\n const container = document.createElement('div');\n container.style.cssText = `\n position: relative;\n width: 90%;\n max-width: 500px;\n height: 90%;\n max-height: 600px;\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n `;\n\n // Create close button\n const closeButton = document.createElement('button');\n closeButton.innerHTML = '×';\n closeButton.style.cssText = `\n position: absolute;\n top: 10px;\n right: 10px;\n width: 30px;\n height: 30px;\n border: none;\n background: transparent;\n font-size: 24px;\n cursor: pointer;\n z-index: 1000000;\n color: #333;\n display: flex;\n align-items: center;\n justify-content: center;\n `;\n closeButton.onclick = () => this.close();\n\n // Create iframe\n this.iframe = document.createElement('iframe');\n this.iframe.src = iframeSrc;\n this.iframe.style.cssText = `\n width: 100%;\n height: 100%;\n border: none;\n border-radius: 8px;\n `;\n this.iframe.setAttribute('allow', 'payment');\n\n // Assemble structure\n container.appendChild(closeButton);\n container.appendChild(this.iframe);\n overlay.appendChild(container);\n document.body.appendChild(overlay);\n\n // Show loader\n this.showLoader(container);\n\n // Close on overlay click (but not on container click)\n overlay.addEventListener('click', (e) => {\n if (e.target === overlay) {\n this.close();\n }\n });\n } else {\n // Inline mode - mount directly in container\n if (!this.containerElement) {\n throw new Error('Container element is required for inline mode');\n }\n\n // Clear container\n this.containerElement.innerHTML = '';\n\n // Set container styles for seamless integration\n if (this.containerElement instanceof HTMLElement) {\n const currentStyle = this.containerElement.getAttribute('style') || '';\n if (!currentStyle.includes('min-height')) {\n this.containerElement.style.minHeight = '196px';\n }\n if (!currentStyle.includes('position')) {\n this.containerElement.style.position = 'relative';\n }\n if (!currentStyle.includes('overflow')) {\n this.containerElement.style.overflow = 'hidden';\n }\n }\n\n // Create iframe\n this.iframe = document.createElement('iframe');\n this.iframe.src = iframeSrc;\n\n const iframeWidth = this.config.config?.style?.fillParent ? '100%' : '344px';\n const iframeMaxWidth = this.config.config?.style?.fillParent ? 'none' : '100%';\n\n this.iframe.style.cssText = `\n width: ${iframeWidth};\n max-width: ${iframeMaxWidth};\n height: 196px;\n min-height: 196px;\n border: none;\n display: block;\n transition: height 0.2s ease;\n `;\n\n this.iframe.setAttribute('allow', 'payment');\n\n // Append to container\n this.containerElement.appendChild(this.iframe);\n\n // Show loader\n this.showLoader(this.containerElement);\n }\n }\n\n /**\n * Add message listener for communication with iframe\n */\n private addMessageListener(): void {\n this.messageListener = (event: MessageEvent) => {\n const allowedOrigin = new URL(this.iframeUrl).origin;\n const isExactMatch = event.origin === allowedOrigin;\n\n let isAllowedOrigin = isExactMatch;\n\n if (!isAllowedOrigin) {\n if (this.environment === 'sandbox' || this.environment === 'development') {\n const isLocalhostDev =\n (event.origin.includes('localhost') || event.origin.includes('127.0.0.1')) &&\n (allowedOrigin.includes('localhost') || allowedOrigin.includes('127.0.0.1'));\n isAllowedOrigin = isLocalhostDev;\n }\n\n if (!isAllowedOrigin) {\n const isAllowedApiOrigin =\n event.origin === 'https://dev.api.inflowpay.com' ||\n event.origin === 'https://pre-prod.api.inflowpay.xyz' ||\n event.origin === 'https://api.inflowpay.xyz';\n isAllowedOrigin = isAllowedApiOrigin;\n }\n }\n\n if (!isAllowedOrigin) {\n if (this.config.debug) {\n console.warn('[SDK] Rejected message from unauthorized origin:', event.origin);\n }\n return;\n }\n\n const data = event.data as IframeMessage;\n\n if (!data || !data.type) {\n return;\n }\n\n switch (data.type) {\n case 'iframe-ready':\n // Wait for iframe's javascript to be ready before sending config\n this.hideLoader();\n this.sendConfigToIframe();\n break;\n\n case 'content-height':\n // Adjust iframe height based on content\n if (data.height && this.iframe) {\n const height = Math.max(data.height, 196); // Minimum 196px\n this.iframe.style.height = `${height}px`;\n if (this.containerElement) {\n this.containerElement.style.minHeight = `${height}px`;\n }\n }\n break;\n\n case 'close':\n this.close();\n break;\n\n case 'success':\n if (this.config.onSuccess) {\n this.config.onSuccess(data.data);\n }\n break;\n\n case 'error':\n if (this.config.onError) {\n this.config.onError(data.data);\n }\n break;\n\n case '3ds-required':\n // Iframe requests SDK to open 3DS popup\n if (this.config.debug) {\n console.log('[SDK] Received 3DS request:', data.threeDsSessionUrl);\n }\n if (data.threeDsSessionUrl) {\n if (this.config.debug) {\n console.log('[SDK] Opening 3DS modal...');\n }\n this.open3DSModal(data.threeDsSessionUrl).then((success) => {\n if (this.config.debug) {\n console.log('[SDK] 3DS modal closed, result:', success);\n }\n if (this.iframe && this.iframe.contentWindow) {\n const targetOrigin = this.getTargetOrigin();\n this.iframe.contentWindow.postMessage({\n type: '3ds-result',\n success: success,\n paymentId: data.paymentId || this.config.config?.paymentId,\n }, targetOrigin);\n }\n });\n } else {\n if (this.config.debug) {\n console.error('[SDK] 3DS required but no threeDsSessionUrl provided');\n }\n }\n break;\n\n default:\n if (this.config.debug) {\n console.log('SDK: Received message:', data);\n }\n }\n };\n\n window.addEventListener('message', this.messageListener);\n }\n\n /**\n * Send configuration to the iframe\n */\n private sendConfigToIframe(): void {\n if (!this.iframe || !this.iframe.contentWindow) {\n // Wait for iframe to load\n if (this.iframe) {\n this.iframe.onload = () => {\n this.sendConfigToIframe();\n };\n }\n return;\n }\n\n const message: IframeMessage = {\n type: 'sdkData',\n config: {\n ...(this.config.config || {}),\n paymentId: this.config.config?.paymentId\n },\n data: {\n apiKey: this.config.apiKey,\n },\n };\n\n const targetOrigin = this.getTargetOrigin();\n this.iframe.contentWindow.postMessage(message, targetOrigin);\n }\n\n /**\n * Show skeleton loader while iframe is connecting\n */\n private showLoader(container: HTMLElement): void {\n // Hide iframe while loader is showing\n if (this.iframe) {\n this.iframe.style.display = 'none';\n }\n \n // Detect dark mode\n const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;\n \n // Color scheme based on dark mode\n const inputBgColor = isDarkMode ? '#2d2d2d' : '#F5F5F5';\n const shimmerBase = isDarkMode ? '#3d3d3d' : '#E5E5E5';\n const shimmerLight = isDarkMode ? '#4d4d4d' : '#F0F0F0';\n const shimmerGradient = `linear-gradient(90deg, ${shimmerBase} 25%, ${shimmerLight} 50%, ${shimmerBase} 75%)`;\n \n const loader = document.createElement('div');\n loader.id = 'inflowpay-loader';\n \n // Get container width to match SDK structure\n const containerWidth = this.config.config?.style?.fillParent ? '100%' : '344px';\n \n loader.style.cssText = `\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 1000;\n padding: 20px;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: center;\n font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n `;\n\n // Skeleton card element container (matching .inflowpay-card-element)\n const skeletonCard = document.createElement('div');\n skeletonCard.style.cssText = `\n width: ${containerWidth};\n max-width: 100%;\n margin: 0 auto;\n font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n `;\n\n // Input container skeleton (matching .inflowpay-card-inp-wrap)\n const inputWrap = document.createElement('div');\n inputWrap.style.cssText = `\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n background-color: ${inputBgColor};\n padding: 8px;\n border-radius: 8px;\n margin-bottom: 20px;\n `;\n\n // Card number skeleton (flex: 1)\n const cardNumberSkeleton = document.createElement('div');\n cardNumberSkeleton.className = 'inflowpay-skeleton';\n cardNumberSkeleton.style.cssText = `\n flex: 1;\n min-width: 0;\n height: 32px;\n border-radius: 6px;\n background: ${shimmerGradient};\n background-size: 200% 100%;\n animation: inflowpay-shimmer 1.5s infinite;\n `;\n\n // Expiry skeleton (21.5% width)\n const expirySkeleton = document.createElement('div');\n expirySkeleton.className = 'inflowpay-skeleton';\n expirySkeleton.style.cssText = `\n width: 21.5%;\n flex-shrink: 0;\n height: 32px;\n border-radius: 6px;\n background: ${shimmerGradient};\n background-size: 200% 100%;\n animation: inflowpay-shimmer 1.5s infinite;\n `;\n\n // CVC skeleton (17.5% width)\n const cvcSkeleton = document.createElement('div');\n cvcSkeleton.className = 'inflowpay-skeleton';\n cvcSkeleton.style.cssText = `\n width: 17.5%;\n flex-shrink: 0;\n height: 32px;\n border-radius: 6px;\n background: ${shimmerGradient};\n background-size: 200% 100%;\n animation: inflowpay-shimmer 1.5s infinite;\n `;\n\n inputWrap.appendChild(cardNumberSkeleton);\n inputWrap.appendChild(expirySkeleton);\n inputWrap.appendChild(cvcSkeleton);\n\n // Button skeleton (matching .inflowpay-button)\n const buttonSkeleton = document.createElement('div');\n buttonSkeleton.className = 'inflowpay-skeleton';\n buttonSkeleton.style.cssText = `\n width: 100%;\n height: 42px;\n border-radius: 8px;\n background: ${shimmerGradient};\n background-size: 200% 100%;\n animation: inflowpay-shimmer 1.5s infinite;\n margin-bottom: 16px;\n `;\n\n // Disclaimer skeleton (matching .inflowpay-disclaimer)\n const disclaimerSkeleton = document.createElement('div');\n disclaimerSkeleton.style.cssText = `\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n width: 100%;\n margin-top: 16px;\n `;\n\n const disclaimerIconSkeleton = document.createElement('div');\n disclaimerIconSkeleton.className = 'inflowpay-skeleton';\n disclaimerIconSkeleton.style.cssText = `\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: ${shimmerGradient};\n background-size: 200% 100%;\n animation: inflowpay-shimmer 1.5s infinite;\n `;\n\n const disclaimerTextSkeleton = document.createElement('div');\n disclaimerTextSkeleton.className = 'inflowpay-skeleton';\n disclaimerTextSkeleton.style.cssText = `\n width: 80%;\n height: 16px;\n border-radius: 4px;\n background: ${shimmerGradient};\n background-size: 200% 100%;\n animation: inflowpay-shimmer 1.5s infinite;\n `;\n\n disclaimerSkeleton.appendChild(disclaimerIconSkeleton);\n disclaimerSkeleton.appendChild(disclaimerTextSkeleton);\n\n skeletonCard.appendChild(inputWrap);\n skeletonCard.appendChild(buttonSkeleton);\n skeletonCard.appendChild(disclaimerSkeleton);\n loader.appendChild(skeletonCard);\n\n // Add shimmer animation keyframes\n if (!document.getElementById('inflowpay-loader-styles')) {\n const style = document.createElement('style');\n style.id = 'inflowpay-loader-styles';\n style.textContent = `\n @keyframes inflowpay-shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n }\n `;\n document.head.appendChild(style);\n }\n\n container.appendChild(loader);\n }\n\n /**\n * Hide loader\n */\n private hideLoader(): void {\n const loader = document.getElementById('inflowpay-loader');\n if (loader) {\n loader.remove();\n }\n \n // Show iframe again when loader is hidden\n if (this.iframe) {\n this.iframe.style.display = '';\n }\n }\n\n /**\n * Close the iframe and cleanup\n */\n private close(): void {\n if (this.config.onClose) {\n this.config.onClose();\n }\n\n // Hide loader\n this.hideLoader();\n\n // Remove message listener\n if (this.messageListener) {\n window.removeEventListener('message', this.messageListener);\n this.messageListener = null;\n }\n\n if (this.usePopup) {\n // Remove overlay\n const overlay = document.getElementById('inflowpay-sdk-overlay');\n if (overlay) {\n overlay.remove();\n }\n } else {\n // Clear container\n if (this.containerElement) {\n this.containerElement.innerHTML = '';\n }\n }\n\n this.iframe = null;\n }\n\n /**\n * Open 3DS authentication modal\n * Called when iframe requests 3DS authentication\n */\n private open3DSModal(challengeUrl: string): Promise<boolean> {\n if (this.config.debug) {\n console.log('[SDK] open3DSModal called with URL:', challengeUrl);\n }\n return new Promise((resolve) => {\n // Create overlay\n const overlay = document.createElement('div');\n overlay.id = 'inflowpay-3ds-overlay';\n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.7);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 999999;\n `;\n\n // Create modal\n const modal = document.createElement('div');\n modal.style.cssText = `\n position: relative;\n width: 90%;\n max-width: 500px;\n height: 90%;\n max-height: 600px;\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n display: flex;\n flex-direction: column;\n `;\n\n // Create header\n const header = document.createElement('div');\n header.style.cssText = `\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 15px 20px;\n border-bottom: 1px solid #e5e5e5;\n `;\n header.innerHTML = `\n <h3 style=\"margin: 0; font-size: 18px; font-weight: 600;\">Secure Payment Authentication</h3>\n <button id=\"inflowpay-3ds-close\" style=\"background: none; border: none; font-size: 24px; cursor: pointer; padding: 0; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; color: #333;\">×</button>\n `;\n\n // Create content with iframe\n const content = document.createElement('div');\n content.style.cssText = `\n flex: 1;\n position: relative;\n overflow: hidden;\n `;\n const iframe = document.createElement('iframe');\n iframe.src = challengeUrl;\n iframe.style.cssText = `\n width: 100%;\n height: 100%;\n border: none;\n `;\n iframe.setAttribute('allow', 'payment');\n iframe.setAttribute('sandbox', 'allow-forms allow-scripts allow-same-origin allow-popups');\n content.appendChild(iframe);\n\n modal.appendChild(header);\n modal.appendChild(content);\n overlay.appendChild(modal);\n document.body.appendChild(overlay);\n\n // Close button handler\n const closeBtn = overlay.querySelector('#inflowpay-3ds-close');\n const closeHandler = () => {\n overlay.remove();\n window.removeEventListener('message', messageHandler);\n resolve(false);\n };\n closeBtn?.addEventListener('click', closeHandler);\n\n const messageHandler = (event: MessageEvent) => {\n if (!event.data) return;\n\n const allowed3DSOrigins = [\n 'https://dev.api.inflowpay.com',\n 'https://pre-prod.api.inflowpay.xyz',\n 'https://api.inflowpay.xyz',\n ];\n\n if (this.environment === 'sandbox' || this.environment === 'development') {\n if (event.origin.includes('localhost') || event.origin.includes('127.0.0.1')) {\n // Allow localhost in dev/sandbox\n } else if (!allowed3DSOrigins.includes(event.origin)) {\n if (this.config.debug) {\n console.warn('[SDK] Rejected 3DS message from unauthorized origin:', event.origin);\n }\n return;\n }\n } else {\n if (!allowed3DSOrigins.includes(event.origin)) {\n if (this.config.debug) {\n console.warn('[SDK] Rejected 3DS message from unauthorized origin:', event.origin);\n }\n return;\n }\n }\n\n const data = event.data;\n const is3DSComplete = data.type === 'THREE_DS_COMPLETE' || data.type === '3ds-complete';\n const isSuccess = data.status === 'success';\n const isFailure = data.status === 'failed' || data.status === 'failure';\n\n // Success case\n if (is3DSComplete && isSuccess) {\n overlay.remove();\n window.removeEventListener('message', messageHandler);\n resolve(true);\n return;\n }\n\n // Also handle legacy format\n if (isSuccess && !is3DSComplete) {\n overlay.remove();\n window.removeEventListener('message', messageHandler);\n resolve(true);\n return;\n }\n\n // Failure case\n if ((is3DSComplete && isFailure) || data.type === '3ds-failed' || isFailure) {\n overlay.remove();\n window.removeEventListener('message', messageHandler);\n resolve(false);\n return;\n }\n };\n\n window.addEventListener('message', messageHandler);\n });\n }\n\n /**\n * Get target origin for postMessage based on environment\n * In production/pre-prod: use exact origin for security\n * In dev/sandbox: use wildcard for development flexibility\n */\n private getTargetOrigin(): string {\n if (this.environment === 'production' || this.environment === 'preprod') {\n return new URL(this.iframeUrl).origin;\n }\n return '*';\n }\n\n /**\n * Detect environment from API key\n */\n private getEnvironmentFromApiKey(apiKey: string): 'sandbox' | 'production' | 'development' | 'preprod' {\n if (!apiKey) return 'sandbox';\n if (apiKey.includes('_local_') || apiKey.startsWith('inflow_local_')) {\n return 'sandbox';\n } else if (apiKey.includes('_prod_') && !apiKey.includes('_preprod_')) {\n return 'production';\n } else if (apiKey.includes('_preprod_') || apiKey.startsWith('inflow_preprod_')) {\n return 'preprod';\n } else if (apiKey.includes('_dev_')) {\n return 'development';\n }\n return 'sandbox';\n }\n\n /**\n * Public method to close the iframe\n */\n public destroy(): void {\n this.close();\n }\n}\n\n","/**\n * CardElement - Iframe-based payment element\n * \n * Mounts an iframe with the payment checkout form\n */\n\nimport { SDK } from './sdk';\n\nimport type { CSSProperties } from './types';\n\nexport interface CardElementOptions {\n /** Container element or CSS selector where the iframe will be mounted */\n container: string | HTMLElement;\n /** Payment ID for this transaction */\n paymentId: string;\n /** Callback when payment completes */\n onComplete?: (result: { status: string; data?: any; error?: any }) => void;\n /** Callback when payment fails */\n onError?: (error: any) => void;\n /** Callback when user closes the payment */\n onClose?: () => void;\n /** Custom styling for the card element */\n style?: CSSProperties;\n /** Custom button text (default: \"Complete Payment\") */\n buttonText?: string;\n /** Custom placeholder text for inputs */\n placeholders?: {\n cardNumber?: string;\n expiry?: string;\n cvc?: string;\n };\n}\n\ninterface InternalSDKConfig {\n apiKey: string;\n iframeUrl: string;\n timeout: number;\n debug: boolean;\n}\n\nexport class CardElement {\n private sdk: SDK;\n private container: HTMLElement;\n private mounted: boolean = false;\n\n constructor(\n config: InternalSDKConfig,\n options: CardElementOptions\n ) {\n let containerElement: HTMLElement | null;\n if (typeof options.container === 'string') {\n containerElement = document.querySelector(options.container);\n if (!containerElement) {\n throw new Error(`Container not found: ${options.container}`);\n }\n } else {\n containerElement = options.container;\n }\n this.container = containerElement;\n\n this.sdk = new SDK({\n iframeUrl: config.iframeUrl,\n apiKey: config.apiKey,\n container: this.container,\n config: {\n paymentId: options.paymentId,\n ...(options.style && { style: options.style }),\n ...(options.buttonText && { buttonText: options.buttonText }),\n ...(options.placeholders && { placeholders: options.placeholders }),\n },\n onSuccess: (data) => {\n if (options.onComplete) {\n options.onComplete({\n status: data?.data?.transaction?.status || 'CHECKOUT_SUCCESS',\n data: data,\n });\n }\n },\n onError: (error) => {\n if (options.onError) {\n options.onError(error);\n } else if (options.onComplete) {\n options.onComplete({\n status: 'PAYMENT_FAILED',\n error: error,\n });\n }\n },\n onClose: () => {\n if (options.onClose) {\n options.onClose();\n }\n },\n });\n }\n\n /**\n * Mount the CardElement to the DOM\n * This will create and display the iframe\n */\n mount(): void {\n if (this.mounted) {\n throw new Error('CardElement is already mounted');\n }\n\n this.sdk.init();\n this.mounted = true;\n }\n\n /**\n * Destroy the CardElement and cleanup\n */\n destroy(): void {\n if (this.mounted) {\n this.sdk.destroy();\n this.mounted = false;\n }\n }\n}\n","/**\n * InflowPay Payment SDK v2\n * \n * Provider class that manages global SDK configuration\n * Similar to the original SDK but uses iframe-based payment flow\n */\n\nimport type { SDKConfig, PaymentConfig, CSSProperties } from './types';\nimport { CardElement } from './card-element';\n\nexport interface PaymentSDKConfig {\n /** Public API key */\n apiKey: string;\n /** Backend API URL (optional, auto-detected from API key) */\n iframeUrl?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /** Enable debug logging (default: false, only allowed in local/dev environments) */\n debug?: boolean;\n}\n\nexport class PaymentSDK {\n private config: PaymentSDKConfig & { iframeUrl: string; timeout: number; debug: boolean };\n\n /**\n * Initialize the InflowPay Payment SDK\n * \n * @param config - SDK configuration\n * \n * @example\n * ```typescript\n * const sdk = new PaymentSDK({\n * apiKey: 'inflow_pub_local_xxx'\n * });\n * ```\n */\n constructor(config: PaymentSDKConfig) {\n // Validate API key\n if (!config.apiKey || typeof config.apiKey !== 'string') {\n throw new Error('API key is required');\n }\n\n // Auto-detect iframe URL from API key if not provided\n let iframeUrl = config.iframeUrl;\n const environment = this.getEnvironmentFromApiKey(config.apiKey);\n \n if (!iframeUrl) {\n if (environment === 'production') {\n iframeUrl = 'https://api.inflowpay.xyz/iframe/checkout';\n } else if (environment === 'preprod') {\n iframeUrl = 'https://pre-prod.api.inflowpay.xyz/iframe/checkout';\n } else if (environment === 'development') {\n iframeUrl = 'https://dev.api.inflowpay.com/iframe/checkout';\n } else {\n // sandbox/local\n iframeUrl = 'http://localhost:3000/iframe/checkout';\n }\n }\n\n // Validate debug mode - only allowed in local/dev environments\n const requestedDebug = config.debug ?? false;\n if (requestedDebug && (environment === 'production' || environment === 'preprod')) {\n console.warn('[InflowPay SDK] Debug mode is not allowed in production/pre-prod environments. Debug mode disabled.');\n }\n const debug = requestedDebug && (environment === 'sandbox' || environment === 'development');\n\n this.config = {\n apiKey: config.apiKey,\n iframeUrl,\n timeout: config.timeout ?? 30000,\n debug,\n };\n }\n\n /**\n * Create a CardElement for iframe-based payment UI\n * \n * @param options - CardElement configuration\n * @returns CardElement instance\n * \n * @example\n * ```typescript\n * const cardElement = sdk.createCardElement({\n * container: '#card-container',\n * paymentId: 'pay_123',\n * onComplete: (result) => {\n * if (result.status === 'CHECKOUT_SUCCESS') {\n * window.location.href = '/success';\n * }\n * }\n * });\n * \n * cardElement.mount();\n * ```\n */\n createCardElement(options: {\n container: string | HTMLElement;\n paymentId: string;\n style?: CSSProperties;\n buttonText?: string;\n placeholders?: {\n cardNumber?: string;\n expiry?: string;\n cvc?: string;\n };\n onComplete?: (result: { status: string; data?: any; error?: any }) => void;\n onError?: (error: any) => void;\n onClose?: () => void;\n }): CardElement {\n return new CardElement(this.config, options);\n }\n\n /**\n * Get the iframe URL being used\n */\n getIframeUrl(): string {\n return this.config.iframeUrl;\n }\n\n /**\n * Get the API key\n */\n getApiKey(): string {\n return this.config.apiKey;\n }\n\n /**\n * Auto-detect environment from API key\n */\n private getEnvironmentFromApiKey(apiKey: string): 'sandbox' | 'production' | 'development' | 'preprod' {\n if (apiKey.includes('_local_') || apiKey.startsWith('inflow_local_')) {\n return 'sandbox';\n } else if (apiKey.includes('_prod_') && !apiKey.includes('_preprod_')) {\n return 'production';\n } else if (apiKey.includes('_preprod_') || apiKey.startsWith('inflow_preprod_')) {\n return 'preprod';\n } else if (apiKey.includes('_dev_')) {\n return 'development';\n }\n return 'sandbox';\n }\n}\n\n"],"names":["SDK","config","url","iframeSrc","overlay","container","closeButton","e","currentStyle","iframeWidth","iframeMaxWidth","event","allowedOrigin","isAllowedOrigin","data","height","success","targetOrigin","message","isDarkMode","inputBgColor","shimmerBase","shimmerGradient","loader","containerWidth","skeletonCard","inputWrap","cardNumberSkeleton","expirySkeleton","cvcSkeleton","buttonSkeleton","disclaimerSkeleton","disclaimerIconSkeleton","disclaimerTextSkeleton","style","challengeUrl","resolve","modal","header","content","iframe","closeBtn","closeHandler","messageHandler","allowed3DSOrigins","is3DSComplete","isSuccess","isFailure","apiKey","CardElement","options","containerElement","error","PaymentSDK","iframeUrl","environment","requestedDebug","debug"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class w {
|
|
2
2
|
constructor(e) {
|
|
3
3
|
if (this.iframe = null, this.messageListener = null, this.containerElement = null, this.config = e, this.iframeUrl = e.iframeUrl || "http://localhost:3000/iframe/checkout", this.environment = this.getEnvironmentFromApiKey(e.apiKey || ""), this.usePopup = !e.container, e.container)
|
|
4
4
|
if (typeof e.container == "string") {
|
|
@@ -81,10 +81,11 @@ class x {
|
|
|
81
81
|
this.iframe.style.cssText = `
|
|
82
82
|
width: ${i};
|
|
83
83
|
max-width: ${n};
|
|
84
|
-
height:
|
|
84
|
+
height: 196px;
|
|
85
85
|
min-height: 196px;
|
|
86
86
|
border: none;
|
|
87
87
|
display: block;
|
|
88
|
+
transition: height 0.2s ease;
|
|
88
89
|
`, this.iframe.setAttribute("allow", "payment"), this.containerElement.appendChild(this.iframe), this.showLoader(this.containerElement);
|
|
89
90
|
}
|
|
90
91
|
}
|
|
@@ -105,6 +106,12 @@ class x {
|
|
|
105
106
|
case "iframe-ready":
|
|
106
107
|
this.hideLoader(), this.sendConfigToIframe();
|
|
107
108
|
break;
|
|
109
|
+
case "content-height":
|
|
110
|
+
if (s.height && this.iframe) {
|
|
111
|
+
const o = Math.max(s.height, 196);
|
|
112
|
+
this.iframe.style.height = `${o}px`, this.containerElement && (this.containerElement.style.minHeight = `${o}px`);
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
108
115
|
case "close":
|
|
109
116
|
this.close();
|
|
110
117
|
break;
|
|
@@ -416,7 +423,7 @@ class b {
|
|
|
416
423
|
throw new Error(`Container not found: ${t.container}`);
|
|
417
424
|
} else
|
|
418
425
|
i = t.container;
|
|
419
|
-
this.container = i, this.sdk = new
|
|
426
|
+
this.container = i, this.sdk = new w({
|
|
420
427
|
iframeUrl: e.iframeUrl,
|
|
421
428
|
apiKey: e.apiKey,
|
|
422
429
|
container: this.container,
|
|
@@ -534,6 +541,6 @@ class E {
|
|
|
534
541
|
export {
|
|
535
542
|
b as C,
|
|
536
543
|
E as P,
|
|
537
|
-
|
|
544
|
+
w as S
|
|
538
545
|
};
|
|
539
|
-
//# sourceMappingURL=payment-sdk-
|
|
546
|
+
//# sourceMappingURL=payment-sdk-DK3VOIGL.mjs.map
|