flintn-checkout 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,13 +1,15 @@
1
1
  # flintn-checkout
2
2
 
3
- FlintN Payment SDK — Iframe-based payment widget with postMessage communication.
3
+ FlintN Payment SDK — Embed payment forms via iframe checkout or headless hosted fields.
4
4
 
5
5
  ## Installation
6
6
  ```bash
7
7
  npm install flintn-checkout
8
8
  ```
9
9
 
10
- ## Quick Start
10
+ ## Iframe Checkout
11
+
12
+ Full checkout UI rendered inside a single iframe. Includes card form, express payments (Apple Pay, Google Pay, PayPal), and 3DS handling.
11
13
 
12
14
  ### React
13
15
  ```tsx
@@ -25,14 +27,11 @@ function Checkout() {
25
27
  console.log('Payment failed:', result.error);
26
28
  }
27
29
  },
28
- onExpressPayment: (result) => {
29
- console.log('Express payment:', result);
30
- },
31
30
  });
32
31
 
33
32
  return (
34
33
  <div style={{ display: 'flex', justifyContent: 'center' }}>
35
- <div ref={containerRef} style={{ width: '100%', height: '600px' }} />
34
+ <div ref={containerRef} style={{ width: '100%', maxWidth: 440 }} />
36
35
  </div>
37
36
  );
38
37
  }
@@ -53,9 +52,6 @@ const payment = new FlintNPayment({
53
52
  console.log('Payment failed:', result.error);
54
53
  }
55
54
  },
56
- onExpressPayment: (result) => {
57
- console.log('Express payment:', result);
58
- },
59
55
  onReady: () => {
60
56
  console.log('Widget ready');
61
57
  },
@@ -76,7 +72,7 @@ payment.unmount();
76
72
  <title>FlintN Checkout</title>
77
73
  </head>
78
74
  <body>
79
- <div id="payment-container" style="max-width: 440px; height: 600px; margin: 0 auto;"></div>
75
+ <div id="payment-container" style="max-width: 440px; margin: 0 auto;"></div>
80
76
 
81
77
  <script type="module">
82
78
  import { FlintNPayment } from 'flintn-checkout';
@@ -96,27 +92,36 @@ payment.unmount();
96
92
  </html>
97
93
  ```
98
94
 
95
+ ## Container Sizing
96
+
97
+ The widget auto-sizes to fit its content — you only need to set a width on the container. Height is managed by the SDK and updates automatically as the form changes state (loading, express view, card form, success).
98
+
99
+ ```tsx
100
+ <div ref={containerRef} style={{ width: '100%', maxWidth: 440 }} />
101
+ ```
102
+
103
+ Do **not** set a fixed `height` on the container — it will leave empty space below the widget when content is shorter than your hardcoded value, and the iframe never scrolls internally.
104
+
99
105
  ## Configuration
100
106
 
101
107
  | Option | Type | Required | Default | Description |
102
108
  |--------|------|----------|---------|-------------|
103
- | `clientSessionId` | `string` | | — | Client session ID from backend |
104
- | `formFields` | `FormFields` | | — | Form field visibility and requirements |
105
- | `styles` | `FormStyles` | | — | Custom styles for the checkout form |
106
- | `successRedirectUrl` | `string` | | — | Redirect URL after successful payment |
109
+ | `config` | `FlintNConfig` | Yes | — | Checkout configuration |
110
+ | `onPayment` | `(result: PaymentResult) => void` | No | — | Card payment result callback |
111
+ | `onReady` | `() => void` | No | — | Widget loaded and ready |
112
+ | `onError` | `(error: PaymentError) => void` | No | — | SDK initialization error |
113
+ | `debug` | `boolean` | No | `false` | Enable console debug logs |
107
114
 
108
- > **Note:** `formFields` only applies when using Primer as the payment provider.
115
+ ### FlintNConfig
109
116
 
110
- ## Callbacks
117
+ | Property | Type | Required | Description |
118
+ |----------|------|----------|-------------|
119
+ | `clientSessionId` | `string` | Yes | Client session ID from backend |
120
+ | `formFields` | `FormFields` | No | Form field visibility and requirements |
121
+ | `styles` | `FormStyles` | No | Custom styles for the checkout form |
122
+ | `successRedirectUrl` | `string` | No | Redirect URL after successful payment |
111
123
 
112
- | Callback | Description |
113
- |----------|-------------|
114
- | `onPayment` | Fired when card payment completes (success or error) |
115
- | `onExpressPayment` | Fired when express payment completes (Apple Pay, Google Pay, PayPal) |
116
- | `onReady` | Fired when widget is loaded and ready |
117
- | `onError` | Fired on SDK initialization error |
118
-
119
- ## React Hook Return Values
124
+ ### React Hook Return Values
120
125
 
121
126
  | Value | Type | Description |
122
127
  |-------|------|-------------|
@@ -125,7 +130,227 @@ payment.unmount();
125
130
  | `paymentResult` | `PaymentResult \| null` | Result after payment attempt |
126
131
  | `error` | `PaymentError \| null` | SDK error if any |
127
132
 
128
- ## Types
133
+ ---
134
+
135
+ ## Hosted Fields
136
+
137
+ Individual PCI-compliant input fields rendered as separate iframes. You control the layout, labels, and error display — the SDK handles card data securely.
138
+
139
+ Each field (card number, expiry, CVV) is a separate iframe. Raw card data never touches your page.
140
+
141
+ ### React
142
+ ```tsx
143
+ import { useState } from 'react';
144
+ import { useFlintNFields } from 'flintn-checkout/react';
145
+
146
+ function CheckoutForm() {
147
+ const [cardholderName, setCardholderName] = useState('');
148
+
149
+ const {
150
+ cardNumberRef,
151
+ expiryRef,
152
+ cvvRef,
153
+ isReady,
154
+ fieldErrors,
155
+ cardBrand,
156
+ paymentResult,
157
+ submit,
158
+ error,
159
+ } = useFlintNFields({
160
+ config: {
161
+ clientSessionId: 'your_client_session_id',
162
+ styles: {
163
+ inputBorderRadius: '8px',
164
+ inputBorderFocusColor: '#6366f1',
165
+ },
166
+ },
167
+ onPayment: (result) => {
168
+ if (result.status === 'PAYMENT_SUCCESS') {
169
+ console.log('Payment succeeded:', result.data);
170
+ }
171
+ },
172
+ debug: true,
173
+ });
174
+
175
+ const handleSubmit = async (e: React.FormEvent) => {
176
+ e.preventDefault();
177
+ const result = await submit({ cardholderName });
178
+ console.log('Payment result:', result);
179
+ };
180
+
181
+ return (
182
+ <form onSubmit={handleSubmit}>
183
+ <label>Card Number {cardBrand && `(${cardBrand})`}</label>
184
+ <div ref={cardNumberRef} style={{ height: 40, marginBottom: 4 }} />
185
+ {fieldErrors['card-number'] && (
186
+ <span style={{ color: 'red' }}>{fieldErrors['card-number']}</span>
187
+ )}
188
+
189
+ <div style={{ display: 'flex', gap: 12 }}>
190
+ <div style={{ flex: 1 }}>
191
+ <label>Expiry</label>
192
+ <div ref={expiryRef} style={{ height: 40, marginBottom: 4 }} />
193
+ {fieldErrors['expiry'] && (
194
+ <span style={{ color: 'red' }}>{fieldErrors['expiry']}</span>
195
+ )}
196
+ </div>
197
+ <div style={{ flex: 1 }}>
198
+ <label>CVV</label>
199
+ <div ref={cvvRef} style={{ height: 40, marginBottom: 4 }} />
200
+ {fieldErrors['cvv'] && (
201
+ <span style={{ color: 'red' }}>{fieldErrors['cvv']}</span>
202
+ )}
203
+ </div>
204
+ </div>
205
+
206
+ <label>Cardholder Name</label>
207
+ <input
208
+ value={cardholderName}
209
+ onChange={(e) => setCardholderName(e.target.value)}
210
+ placeholder="John Doe"
211
+ />
212
+
213
+ <button type="submit" disabled={!isReady}>
214
+ {isReady ? 'Pay' : 'Loading...'}
215
+ </button>
216
+
217
+ {error && <div style={{ color: 'red' }}>{error.message}</div>}
218
+ {paymentResult?.status === 'PAYMENT_ERROR' && paymentResult.error && (
219
+ <div style={{ color: 'red' }}>{paymentResult.error.message}</div>
220
+ )}
221
+ </form>
222
+ );
223
+ }
224
+ ```
225
+
226
+ ### Vanilla JavaScript
227
+ ```javascript
228
+ import { FlintNFields } from 'flintn-checkout';
229
+
230
+ const fields = new FlintNFields({
231
+ config: {
232
+ clientSessionId: 'your_client_session_id',
233
+ styles: {
234
+ inputBorderRadius: '8px',
235
+ inputBorderFocusColor: '#6366f1',
236
+ },
237
+ },
238
+ onReady: () => console.log('All fields ready'),
239
+ onPayment: (result) => console.log('Payment result:', result),
240
+ onChange: (event) => console.log(`${event.fieldType}:`, event),
241
+ debug: true,
242
+ });
243
+
244
+ const cardNumber = fields.createField('card-number', { placeholder: '4111 1111 1111 1111' });
245
+ const expiry = fields.createField('expiry', { placeholder: 'MM/YY' });
246
+ const cvv = fields.createField('cvv', { placeholder: 'CVC' });
247
+
248
+ cardNumber.mount('#card-number');
249
+ expiry.mount('#expiry');
250
+ cvv.mount('#cvv');
251
+
252
+ // Validate
253
+ const validation = await fields.validate();
254
+ if (validation.isValid) {
255
+ const result = await fields.submit({ cardholderName: 'John Doe' });
256
+ }
257
+
258
+ // Cleanup
259
+ fields.unmount();
260
+ ```
261
+
262
+ ### Hosted Fields Options (Vanilla JS)
263
+
264
+ | Option | Type | Required | Default | Description |
265
+ |--------|------|----------|---------|-------------|
266
+ | `config` | `FlintNFieldsConfig` | Yes | — | Fields configuration |
267
+ | `onPayment` | `(result: PaymentResult) => void` | No | — | Payment result callback |
268
+ | `onReady` | `() => void` | No | — | All fields loaded and ready |
269
+ | `onChange` | `(event: FieldChangeEvent) => void` | No | — | Field value changed |
270
+ | `onFocus` | `(fieldType: TFieldType) => void` | No | — | Field gained focus |
271
+ | `onBlur` | `(fieldType: TFieldType, state: FieldState) => void` | No | — | Field lost focus |
272
+ | `onError` | `(error: PaymentError) => void` | No | — | SDK initialization error |
273
+ | `debug` | `boolean` | No | `false` | Enable console debug logs |
274
+
275
+ ### FlintNFieldsConfig
276
+
277
+ | Property | Type | Required | Description |
278
+ |----------|------|----------|-------------|
279
+ | `clientSessionId` | `string` | Yes | Client session ID from backend |
280
+ | `styles` | `FormStyles` | No | Styles applied to all hosted field inputs |
281
+
282
+ ### React Hook Options
283
+
284
+ The `useFlintNFields` hook accepts `config`, `onPayment`, and `debug` from the options above. It manages `onReady`, `onChange`, `onFocus`, `onBlur`, and `onError` internally and exposes them as return values instead.
285
+
286
+ Additional React-only options:
287
+
288
+ | Option | Type | Description |
289
+ |--------|------|-------------|
290
+ | `fields.cardNumber` | `FieldOptions \| false` | Card number field options, or `false` to skip |
291
+ | `fields.expiry` | `FieldOptions \| false` | Expiry field options, or `false` to skip |
292
+ | `fields.cvv` | `FieldOptions \| false` | CVV field options, or `false` to skip |
293
+ | `onChange` | `(event: FieldChangeEvent) => void` | Optional additional callback |
294
+ | `onFocus` | `(fieldType: TFieldType) => void` | Optional additional callback |
295
+ | `onBlur` | `(fieldType: TFieldType, state: FieldState) => void` | Optional additional callback |
296
+
297
+ ### FieldOptions
298
+
299
+ | Property | Type | Default | Description |
300
+ |----------|------|---------|-------------|
301
+ | `placeholder` | `string` | Field-specific default | Input placeholder text |
302
+ | `disabled` | `boolean` | `false` | Disable the input |
303
+
304
+ ### React Hook Return Values
305
+
306
+ | Value | Type | Description |
307
+ |-------|------|-------------|
308
+ | `cardNumberRef` | `RefObject<HTMLDivElement>` | Ref for card number container |
309
+ | `expiryRef` | `RefObject<HTMLDivElement>` | Ref for expiry container |
310
+ | `cvvRef` | `RefObject<HTMLDivElement>` | Ref for CVV container |
311
+ | `isReady` | `boolean` | All fields loaded and ready |
312
+ | `fieldErrors` | `Partial<Record<TFieldType, string \| null>>` | Per-field validation errors (populated after first submit) |
313
+ | `fieldStates` | `Partial<Record<TFieldType, FieldState>>` | Per-field state (always up to date) |
314
+ | `cardBrand` | `string \| null` | Detected card brand (e.g. `"visa"`, `"mastercard"`) |
315
+ | `paymentResult` | `PaymentResult \| null` | Result after payment attempt |
316
+ | `error` | `PaymentError \| null` | SDK error if any |
317
+ | `validate` | `() => Promise<FieldsValidationResult>` | Validate all fields |
318
+ | `submit` | `(options?: SubmitOptions) => Promise<PaymentResult>` | Validate and submit payment |
319
+ | `focusField` | `(fieldType: TFieldType) => void` | Focus a field programmatically |
320
+ | `clearField` | `(fieldType: TFieldType) => void` | Clear a field |
321
+ | `clearAll` | `() => void` | Clear all fields |
322
+
323
+ ### Validation Behavior
324
+
325
+ Validation mirrors react-hook-form `mode: 'onSubmit'`:
326
+
327
+ - Before first submit: `fieldErrors` is always `{}`
328
+ - After first submit: errors update on every field change (revalidation)
329
+ - Card number changes trigger CVV revalidation (CVV length depends on card brand)
330
+ - All three fields (card number, expiry, CVV) are required — submitting with a missing field returns a `MISSING_FIELDS` error
331
+
332
+ ### Field Types
333
+
334
+ | Value | Description |
335
+ |-------|-------------|
336
+ | `'card-number'` | Card number input with automatic formatting and brand detection |
337
+ | `'expiry'` | Expiry date input (MM/YY format) |
338
+ | `'cvv'` | CVV/CVC input (3 or 4 digits depending on card brand) |
339
+
340
+ ### Individual Field Methods (Vanilla JS)
341
+
342
+ | Method | Description |
343
+ |--------|-------------|
344
+ | `field.mount(selector)` | Mount field into a DOM element |
345
+ | `field.unmount()` | Remove field from DOM |
346
+ | `field.focus()` | Focus the field |
347
+ | `field.clear()` | Clear the field value |
348
+ | `field.getState()` | Get current field state |
349
+ | `field.getFieldType()` | Get the field type |
350
+
351
+ ---
352
+
353
+ ## Shared Types
129
354
 
130
355
  ### PaymentResult
131
356
  ```typescript
@@ -147,12 +372,42 @@ interface PaymentError {
147
372
  }
148
373
  ```
149
374
 
375
+ ### FieldState
376
+ ```typescript
377
+ interface FieldState {
378
+ isEmpty: boolean;
379
+ isValid: boolean;
380
+ isFocused: boolean;
381
+ error: string | null;
382
+ }
383
+ ```
384
+
385
+ ### FieldChangeEvent
386
+ ```typescript
387
+ interface FieldChangeEvent {
388
+ fieldType: 'card-number' | 'expiry' | 'cvv';
389
+ isEmpty: boolean;
390
+ isValid: boolean;
391
+ isFocused: boolean;
392
+ error: string | null;
393
+ cardBrand?: string; // Only for card-number
394
+ }
395
+ ```
396
+
397
+ ### FieldsValidationResult
398
+ ```typescript
399
+ interface FieldsValidationResult {
400
+ isValid: boolean;
401
+ errors: Partial<Record<'card-number' | 'expiry' | 'cvv', string | null>>;
402
+ }
403
+ ```
404
+
150
405
  ### FormFields
151
406
  ```typescript
152
407
  interface FormFields {
153
- isEmailVisible?: boolean; // Primer only
408
+ isEmailVisible?: boolean; // Primer only
154
409
  isCardholderNameRequired?: boolean; // Primer only
155
- formVariant?: 'DEFAULT' | 'LIST';
410
+ formVariant?: 'DEFAULT' | 'LIST' | 'RADIO';
156
411
  }
157
412
  ```
158
413
 
@@ -181,52 +436,59 @@ interface FormStyles {
181
436
 
182
437
  ### FormStyles Reference
183
438
 
184
- | Property | Description |
185
- |----------|-------------|
186
- | `loaderColor` | Color of the loading spinner |
187
- | `backgroundColor` | Background color of the checkout form |
188
- | `expressButtonsSpacing` | Spacing between express payment buttons (Apple Pay, Google Pay, PayPal) |
189
- | `inputBackgroundColor` | Background color of input fields |
190
- | `inputBorderRadius` | Border radius of input fields |
191
- | `inputBorderColor` | Default border color of input fields |
192
- | `inputBorderHoverColor` | Border color of input fields on hover |
193
- | `inputBorderFocusColor` | Border color of input fields on focus |
194
- | `inputBorderErrorColor` | Border color of input fields in error state |
195
- | `errorMessageColor` | Color of error messages below inputs |
196
- | `buttonColor` | Background color of the submit button |
197
- | `buttonHoverColor` | Background color of the submit button on hover/active |
198
- | `buttonBorderRadius` | Border radius of the submit button |
199
- | `buttonText` | Custom text for the submit button (overrides default "Pay $X.XX") |
200
- | `cardButtonColor` | Background color of the "Credit or Debit Card" button (LIST variant only) |
201
- | `cardButtonHoverColor` | Hover/active color of the card button (LIST variant only) |
202
- | `cardButtonText` | Custom text for the card button (LIST variant only) |
439
+ | Property | Iframe Checkout | Hosted Fields | Description |
440
+ |----------|:-:|:-:|-------------|
441
+ | `loaderColor` | | | Loading spinner color |
442
+ | `backgroundColor` | | | Form background color |
443
+ | `expressButtonsSpacing` | ✅ | — | Spacing between express payment buttons |
444
+ | `inputBackgroundColor` | | | Input field background color |
445
+ | `inputBorderRadius` | | | Input field border radius |
446
+ | `inputBorderColor` | | | Default input border color |
447
+ | `inputBorderHoverColor` | | | Input border color on hover |
448
+ | `inputBorderFocusColor` | | | Input border color on focus |
449
+ | `inputBorderErrorColor` | | | Input border color in error state |
450
+ | `errorMessageColor` | | | Error message text color |
451
+ | `buttonColor` | | | Submit button background color |
452
+ | `buttonHoverColor` | | | Submit button hover color |
453
+ | `buttonBorderRadius` | | | Submit button border radius |
454
+ | `buttonText` | | | Custom submit button text |
455
+ | `cardButtonColor` | | | Card button color (LIST variant) |
456
+ | `cardButtonHoverColor` | | | Card button hover color (LIST variant) |
457
+ | `cardButtonText` | | | Custom card button text (LIST variant) |
203
458
 
204
459
  ## Form Variants
205
460
 
206
- The checkout form supports two layout variants via `formFields.formVariant`:
461
+ The iframe checkout supports three layout variants via `formFields.formVariant`:
207
462
 
208
- - **DEFAULT** — Express payment methods shown above the card form with dividers
209
- - **LIST** — Express payment methods shown as a list with a "Credit or Debit Card" button; clicking it navigates to the card form with a back arrow
463
+ - **DEFAULT** — Express payment methods shown above the card form with dividers.
464
+ - **LIST** — Express payment methods shown first; users tap a "Credit or Debit Card" button to navigate to the card form, with a back arrow to return to the express view.
465
+ - **RADIO** — Express payments and the card form are presented as two radio options ("Fast checkout" and "Card payment"). Selecting a radio expands its section and collapses the other. The card payment radio shows accepted card brand logos inline with its label.
466
+
467
+ LIST and RADIO automatically fall back to the DEFAULT layout when no express payment methods are available, since there's nothing to toggle between. The `cardButtonColor`, `cardButtonHoverColor`, and `cardButtonText` style overrides apply only to the LIST variant's "Credit or Debit Card" button.
210
468
 
211
469
  ## Supported Payment Methods
212
470
 
213
- - 💳 Credit/Debit Cards (Visa, Mastercard, Amex, Discover)
214
- - 🍎 Apple Pay
215
- - 🔵 Google Pay
216
- - 🟡 PayPal
471
+ ### Iframe Checkout
472
+ - Credit/Debit Cards (Visa, Mastercard, Amex, Discover)
473
+ - Apple Pay
474
+ - Google Pay
475
+ - PayPal
476
+
477
+ ### Hosted Fields
478
+ - Credit/Debit Cards (Visa, Mastercard, Amex, Discover)
217
479
 
218
480
  ## Debug Mode
219
481
 
220
482
  Enable debug logs in console:
221
483
  ```typescript
222
- // React
484
+ // Iframe Checkout
223
485
  useFlintNPayment({
224
486
  config: { clientSessionId: '...' },
225
487
  debug: true,
226
488
  });
227
489
 
228
- // Vanilla JS
229
- new FlintNPayment({
490
+ // Hosted Fields
491
+ useFlintNFields({
230
492
  config: { clientSessionId: '...' },
231
493
  debug: true,
232
494
  });
package/dist/index.d.mts CHANGED
@@ -7,11 +7,13 @@ declare const EventType: {
7
7
  readonly PAYMENT_ERROR: "PAYMENT_ERROR";
8
8
  readonly PAYMENT_CANCELLED: "PAYMENT_CANCELLED";
9
9
  readonly REDIRECT: "REDIRECT";
10
+ readonly RESIZE: "RESIZE";
10
11
  };
11
12
  type TEventType = (typeof EventType)[keyof typeof EventType];
12
13
  declare const CheckoutFormVariant: {
13
14
  readonly DEFAULT: "DEFAULT";
14
15
  readonly LIST: "LIST";
16
+ readonly RADIO: "RADIO";
15
17
  };
16
18
  type TCheckoutFormVariant = (typeof CheckoutFormVariant)[keyof typeof CheckoutFormVariant];
17
19
  interface FormFields {
@@ -65,24 +67,109 @@ interface FlintNPaymentOptions {
65
67
  onError?: (error: PaymentError) => void;
66
68
  debug?: boolean;
67
69
  }
70
+ declare const FieldType: {
71
+ readonly CARD_NUMBER: "card-number";
72
+ readonly EXPIRY: "expiry";
73
+ readonly CVV: "cvv";
74
+ };
75
+ type TFieldType = (typeof FieldType)[keyof typeof FieldType];
76
+ declare const FieldEventType: {
77
+ readonly FIELD_CONFIG: "FIELD_CONFIG";
78
+ readonly FIELD_VALIDATE: "FIELD_VALIDATE";
79
+ readonly FIELD_SUBMIT: "FIELD_SUBMIT";
80
+ readonly FIELD_FOCUS_REQUEST: "FIELD_FOCUS_REQUEST";
81
+ readonly FIELD_CLEAR: "FIELD_CLEAR";
82
+ readonly FIELD_READY: "FIELD_READY";
83
+ readonly FIELD_CHANGE: "FIELD_CHANGE";
84
+ readonly FIELD_FOCUS: "FIELD_FOCUS";
85
+ readonly FIELD_BLUR: "FIELD_BLUR";
86
+ readonly FIELD_VALIDATION: "FIELD_VALIDATION";
87
+ readonly FIELD_SUBMIT_RESULT: "FIELD_SUBMIT_RESULT";
88
+ readonly FIELD_HEIGHT: "FIELD_HEIGHT";
89
+ };
90
+ type TFieldEventType = (typeof FieldEventType)[keyof typeof FieldEventType];
91
+ interface FieldOptions {
92
+ placeholder?: string;
93
+ disabled?: boolean;
94
+ }
95
+ interface FieldState {
96
+ isEmpty: boolean;
97
+ isValid: boolean;
98
+ isFocused: boolean;
99
+ error: string | null;
100
+ }
101
+ interface FieldChangeEvent {
102
+ fieldType: TFieldType;
103
+ isEmpty: boolean;
104
+ isValid: boolean;
105
+ isFocused: boolean;
106
+ error: string | null;
107
+ cardBrand?: string;
108
+ }
109
+ interface FieldValidationResult {
110
+ fieldType: TFieldType;
111
+ isValid: boolean;
112
+ error: string | null;
113
+ }
114
+ interface FieldsValidationResult {
115
+ isValid: boolean;
116
+ errors: Partial<Record<TFieldType, string | null>>;
117
+ }
118
+ interface SubmitOptions {
119
+ cardholderName?: string;
120
+ }
121
+ interface FlintNFieldsConfig {
122
+ clientSessionId: string;
123
+ styles?: FormStyles;
124
+ }
125
+ interface FlintNFieldsOptions {
126
+ origin?: string;
127
+ config: FlintNFieldsConfig;
128
+ onPayment?: (result: PaymentResult) => void;
129
+ onReady?: () => void;
130
+ onChange?: (event: FieldChangeEvent) => void;
131
+ onFocus?: (fieldType: TFieldType) => void;
132
+ onBlur?: (fieldType: TFieldType, state: FieldState) => void;
133
+ onError?: (error: PaymentError) => void;
134
+ debug?: boolean;
135
+ }
68
136
 
69
- declare class FlintNPayment {
70
- private options;
71
- private origin;
72
- private iframe;
73
- private container;
74
- private isReady;
75
- private messageHandler;
76
- constructor(options: FlintNPaymentOptions);
137
+ interface FlintNPayment {
77
138
  mount(selector: string | HTMLElement): void;
78
139
  unmount(): void;
79
140
  getIsReady(): boolean;
80
- private handleMessage;
81
- private isValidRedirectUrl;
82
- private handlePaymentResult;
83
- private sendConfig;
84
- private log;
85
141
  }
142
+ declare function createFlintNPayment(options: FlintNPaymentOptions): FlintNPayment;
143
+
144
+ interface FlintNFieldInternalCallbacks {
145
+ onReady: (fieldType: TFieldType) => void;
146
+ onChange: (event: FieldChangeEvent) => void;
147
+ onFocus: (fieldType: TFieldType) => void;
148
+ onBlur: (fieldType: TFieldType, state: FieldState) => void;
149
+ onHeight: (fieldType: TFieldType, height: number) => void;
150
+ }
151
+ interface FlintNField {
152
+ mount(selector: string | HTMLElement): void;
153
+ unmount(): void;
154
+ focus(): void;
155
+ clear(): void;
156
+ getState(): FieldState;
157
+ getFieldType(): TFieldType;
158
+ _sendMessage(type: string, payload: unknown): void;
159
+ _getIframe(): HTMLIFrameElement | null;
160
+ _handleMessage(type: string, payload: Record<string, unknown>): void;
161
+ }
162
+ declare function createFlintNField(fieldType: TFieldType, origin: string, clientSessionId: string, options: FieldOptions, callbacks: FlintNFieldInternalCallbacks, debug?: boolean, formStyles?: FormStyles): FlintNField;
163
+
164
+ interface FlintNFields {
165
+ createField(fieldType: TFieldType, options?: FieldOptions): FlintNField;
166
+ getField(fieldType: TFieldType): FlintNField | undefined;
167
+ validate(): Promise<FieldsValidationResult>;
168
+ submit(options?: SubmitOptions, skipValidation?: boolean): Promise<PaymentResult>;
169
+ unmount(): void;
170
+ getIsReady(): boolean;
171
+ }
172
+ declare function createFlintNFields(options: FlintNFieldsOptions): FlintNFields;
86
173
 
87
174
  declare const parseOrigin: (origin: string) => string;
88
175
  declare const buildIframeSrc: (origin: string) => string;
@@ -92,4 +179,4 @@ declare const validateConfig: (config: {
92
179
  }) => void;
93
180
  declare const sanitizeToken: (token: string) => string;
94
181
 
95
- export { CheckoutFormVariant, EventType, type FlintNConfig, FlintNPayment, type FlintNPaymentOptions, type FormFields, type FormStyles, type PaymentError, type PaymentResult, type TCheckoutFormVariant, type TEventType, buildIframeSrc, createIframeElement, parseOrigin, sanitizeToken, validateConfig };
182
+ export { CheckoutFormVariant, EventType, type FieldChangeEvent, FieldEventType, type FieldOptions, type FieldState, FieldType, type FieldValidationResult, type FieldsValidationResult, type FlintNConfig, type FlintNField, type FlintNFieldInternalCallbacks, type FlintNFields, type FlintNFieldsConfig, type FlintNFieldsOptions, type FlintNPayment, type FlintNPaymentOptions, type FormFields, type FormStyles, type PaymentError, type PaymentResult, type SubmitOptions, type TCheckoutFormVariant, type TEventType, type TFieldEventType, type TFieldType, buildIframeSrc, createFlintNField, createFlintNFields, createFlintNPayment, createIframeElement, parseOrigin, sanitizeToken, validateConfig };