flintn-checkout 0.0.8 → 0.0.10

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,15 +1,19 @@
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
+ > **Note:** for local/non-production use, pass `origin` (e.g. `origin: 'http://localhost:3000'`).
9
10
 
10
- ## Quick Start
11
+ ## Iframe Checkout
12
+
13
+ Full checkout UI rendered inside a single iframe. Includes card form, express payments (Apple Pay, Google Pay, PayPal), and 3DS handling.
14
+
15
+ **React**
11
16
 
12
- ### React
13
17
  ```tsx
14
18
  import { useFlintNPayment } from 'flintn-checkout/react';
15
19
 
@@ -25,9 +29,6 @@ function Checkout() {
25
29
  console.log('Payment failed:', result.error);
26
30
  }
27
31
  },
28
- onExpressPayment: (result) => {
29
- console.log('Express payment:', result);
30
- },
31
32
  });
32
33
 
33
34
  return (
@@ -38,11 +39,12 @@ function Checkout() {
38
39
  }
39
40
  ```
40
41
 
41
- ### Vanilla JavaScript
42
+ **Vanilla JavaScript**
43
+
42
44
  ```javascript
43
- import { FlintNPayment } from 'flintn-checkout';
45
+ import { createFlintNPayment } from 'flintn-checkout';
44
46
 
45
- const payment = new FlintNPayment({
47
+ const payment = createFlintNPayment({
46
48
  config: {
47
49
  clientSessionId: 'your_client_session_id',
48
50
  },
@@ -53,9 +55,6 @@ const payment = new FlintNPayment({
53
55
  console.log('Payment failed:', result.error);
54
56
  }
55
57
  },
56
- onExpressPayment: (result) => {
57
- console.log('Express payment:', result);
58
- },
59
58
  onReady: () => {
60
59
  console.log('Widget ready');
61
60
  },
@@ -64,11 +63,12 @@ const payment = new FlintNPayment({
64
63
 
65
64
  payment.mount('#payment-container');
66
65
 
67
- // Cleanup when done
68
- payment.unmount();
66
+ // Later, when you want to tear the widget down (e.g. on route change):
67
+ // payment.unmount();
69
68
  ```
70
69
 
71
- ### HTML
70
+ **HTML**
71
+
72
72
  ```html
73
73
  <!DOCTYPE html>
74
74
  <html>
@@ -79,9 +79,9 @@ payment.unmount();
79
79
  <div id="payment-container" style="max-width: 440px; margin: 0 auto;"></div>
80
80
 
81
81
  <script type="module">
82
- import { FlintNPayment } from 'flintn-checkout';
82
+ import { createFlintNPayment } from 'flintn-checkout';
83
83
 
84
- const payment = new FlintNPayment({
84
+ const payment = createFlintNPayment({
85
85
  config: {
86
86
  clientSessionId: 'your_client_session_id',
87
87
  },
@@ -110,23 +110,22 @@ Do **not** set a fixed `height` on the container — it will leave empty space b
110
110
 
111
111
  | Option | Type | Required | Default | Description |
112
112
  |--------|------|----------|---------|-------------|
113
- | `clientSessionId` | `string` | | — | Client session ID from backend |
114
- | `formFields` | `FormFields` | | — | Form field visibility and requirements |
115
- | `styles` | `FormStyles` | | — | Custom styles for the checkout form |
116
- | `successRedirectUrl` | `string` | | — | Redirect URL after successful payment |
113
+ | `config` | `FlintNConfig` | Yes | — | Checkout configuration |
114
+ | `onPayment` | `(result: PaymentResult) => void` | No | — | Card payment result callback |
115
+ | `onReady` | `() => void` | No | — | Widget loaded and ready |
116
+ | `onError` | `(error: PaymentError) => void` | No | — | SDK initialization error |
117
+ | `debug` | `boolean` | No | `false` | Enable console debug logs |
117
118
 
118
- > **Note:** `formFields` only applies when using Primer as the payment provider.
119
+ ### FlintNConfig
119
120
 
120
- ## Callbacks
121
+ | Property | Type | Required | Description |
122
+ |----------|------|----------|-------------|
123
+ | `clientSessionId` | `string` | Yes | Client session ID from backend |
124
+ | `formFields` | `FormFields` | No | Form field visibility and requirements |
125
+ | `styles` | `FormStyles` | No | Custom styles for the checkout form |
126
+ | `successRedirectUrl` | `string` | No | Redirect URL after successful payment |
121
127
 
122
- | Callback | Description |
123
- |----------|-------------|
124
- | `onPayment` | Fired when card payment completes (success or error) |
125
- | `onExpressPayment` | Fired when express payment completes (Apple Pay, Google Pay, PayPal) |
126
- | `onReady` | Fired when widget is loaded and ready |
127
- | `onError` | Fired on SDK initialization error |
128
-
129
- ## React Hook Return Values
128
+ ### React Hook Return Values
130
129
 
131
130
  | Value | Type | Description |
132
131
  |-------|------|-------------|
@@ -135,7 +134,229 @@ Do **not** set a fixed `height` on the container — it will leave empty space b
135
134
  | `paymentResult` | `PaymentResult \| null` | Result after payment attempt |
136
135
  | `error` | `PaymentError \| null` | SDK error if any |
137
136
 
138
- ## Types
137
+ ---
138
+
139
+ ## Hosted Fields
140
+
141
+ Individual PCI-compliant input fields rendered as separate iframes. You control the layout, labels, and error display — the SDK handles card data securely.
142
+
143
+ Each field (card number, expiry, CVV) is a separate iframe. Raw card data never touches your page.
144
+
145
+ **React**
146
+
147
+ ```tsx
148
+ import { useState } from 'react';
149
+ import { useFlintNFields } from 'flintn-checkout/react';
150
+
151
+ function CheckoutForm() {
152
+ const [cardholderName, setCardholderName] = useState('');
153
+
154
+ const {
155
+ cardNumberRef,
156
+ expiryRef,
157
+ cvvRef,
158
+ isReady,
159
+ fieldErrors,
160
+ cardBrand,
161
+ paymentResult,
162
+ submit,
163
+ error,
164
+ } = useFlintNFields({
165
+ config: {
166
+ clientSessionId: 'your_client_session_id',
167
+ styles: {
168
+ inputBorderRadius: '8px',
169
+ inputBorderFocusColor: '#6366f1',
170
+ },
171
+ },
172
+ onPayment: (result) => {
173
+ if (result.status === 'PAYMENT_SUCCESS') {
174
+ console.log('Payment succeeded:', result.data);
175
+ }
176
+ },
177
+ debug: true,
178
+ });
179
+
180
+ const handleSubmit = async (e: React.FormEvent) => {
181
+ e.preventDefault();
182
+ const result = await submit({ cardholderName });
183
+ console.log('Payment result:', result);
184
+ };
185
+
186
+ return (
187
+ <form onSubmit={handleSubmit}>
188
+ <label>Card Number {cardBrand && `(${cardBrand})`}</label>
189
+ <div ref={cardNumberRef} style={{ height: 40, marginBottom: 4 }} />
190
+ {fieldErrors['card-number'] && (
191
+ <span style={{ color: 'red' }}>{fieldErrors['card-number']}</span>
192
+ )}
193
+
194
+ <div style={{ display: 'flex', gap: 12 }}>
195
+ <div style={{ flex: 1 }}>
196
+ <label>Expiry</label>
197
+ <div ref={expiryRef} style={{ height: 40, marginBottom: 4 }} />
198
+ {fieldErrors['expiry'] && (
199
+ <span style={{ color: 'red' }}>{fieldErrors['expiry']}</span>
200
+ )}
201
+ </div>
202
+ <div style={{ flex: 1 }}>
203
+ <label>CVV</label>
204
+ <div ref={cvvRef} style={{ height: 40, marginBottom: 4 }} />
205
+ {fieldErrors['cvv'] && (
206
+ <span style={{ color: 'red' }}>{fieldErrors['cvv']}</span>
207
+ )}
208
+ </div>
209
+ </div>
210
+
211
+ <label>Cardholder Name</label>
212
+ <input
213
+ value={cardholderName}
214
+ onChange={(e) => setCardholderName(e.target.value)}
215
+ placeholder="John Doe"
216
+ />
217
+
218
+ <button type="submit" disabled={!isReady}>
219
+ {isReady ? 'Pay' : 'Loading...'}
220
+ </button>
221
+
222
+ {error && <div style={{ color: 'red' }}>{error.message}</div>}
223
+ {paymentResult?.status === 'PAYMENT_ERROR' && paymentResult.error && (
224
+ <div style={{ color: 'red' }}>{paymentResult.error.message}</div>
225
+ )}
226
+ </form>
227
+ );
228
+ }
229
+ ```
230
+
231
+ **Vanilla JavaScript**
232
+
233
+ ```javascript
234
+ import { createFlintNFields } from 'flintn-checkout';
235
+
236
+ const fields = createFlintNFields({
237
+ config: {
238
+ clientSessionId: 'your_client_session_id',
239
+ styles: {
240
+ inputBorderRadius: '8px',
241
+ inputBorderFocusColor: '#6366f1',
242
+ },
243
+ },
244
+ onReady: () => console.log('All fields ready'),
245
+ onPayment: (result) => console.log('Payment result:', result),
246
+ onChange: (event) => console.log(`${event.fieldType}:`, event),
247
+ debug: true,
248
+ });
249
+
250
+ const cardNumber = fields.createField('card-number', { placeholder: '4111 1111 1111 1111' });
251
+ const expiry = fields.createField('expiry', { placeholder: 'MM/YY' });
252
+ const cvv = fields.createField('cvv', { placeholder: 'CVC' });
253
+
254
+ cardNumber.mount('#card-number');
255
+ expiry.mount('#expiry');
256
+ cvv.mount('#cvv');
257
+
258
+ // Validate
259
+ const validation = await fields.validate();
260
+ if (validation.isValid) {
261
+ const result = await fields.submit({ cardholderName: 'John Doe' });
262
+ }
263
+
264
+ // Cleanup (call when you're done with the form)
265
+ // fields.unmount();
266
+ ```
267
+
268
+ ### Hosted Fields Options (Vanilla JS)
269
+
270
+ | Option | Type | Required | Default | Description |
271
+ |--------|------|----------|---------|-------------|
272
+ | `config` | `FlintNFieldsConfig` | Yes | — | Fields configuration |
273
+ | `onPayment` | `(result: PaymentResult) => void` | No | — | Payment result callback |
274
+ | `onReady` | `() => void` | No | — | All fields loaded and ready |
275
+ | `onChange` | `(event: FieldChangeEvent) => void` | No | — | Field value changed |
276
+ | `onFocus` | `(fieldType: TFieldType) => void` | No | — | Field gained focus |
277
+ | `onBlur` | `(fieldType: TFieldType, state: FieldState) => void` | No | — | Field lost focus |
278
+ | `onError` | `(error: PaymentError) => void` | No | — | SDK initialization error |
279
+ | `debug` | `boolean` | No | `false` | Enable console debug logs |
280
+
281
+ ### FlintNFieldsConfig
282
+
283
+ | Property | Type | Required | Description |
284
+ |----------|------|----------|-------------|
285
+ | `clientSessionId` | `string` | Yes | Client session ID from backend |
286
+ | `styles` | `FormStyles` | No | Styles applied to all hosted field inputs |
287
+
288
+ ### React Hook Options
289
+
290
+ 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.
291
+
292
+ Additional React-only options:
293
+
294
+ | Option | Type | Description |
295
+ |--------|------|-------------|
296
+ | `fields.cardNumber` | `FieldOptions \| false` | Card number field options, or `false` to skip |
297
+ | `fields.expiry` | `FieldOptions \| false` | Expiry field options, or `false` to skip |
298
+ | `fields.cvv` | `FieldOptions \| false` | CVV field options, or `false` to skip |
299
+ | `onChange` | `(event: FieldChangeEvent) => void` | Optional additional callback |
300
+ | `onFocus` | `(fieldType: TFieldType) => void` | Optional additional callback |
301
+ | `onBlur` | `(fieldType: TFieldType, state: FieldState) => void` | Optional additional callback |
302
+
303
+ ### FieldOptions
304
+
305
+ | Property | Type | Default | Description |
306
+ |----------|------|---------|-------------|
307
+ | `placeholder` | `string` | Field-specific default | Input placeholder text |
308
+ | `disabled` | `boolean` | `false` | Disable the input |
309
+
310
+ ### React Hook Return Values
311
+
312
+ | Value | Type | Description |
313
+ |-------|------|-------------|
314
+ | `cardNumberRef` | `RefObject<HTMLDivElement>` | Ref for card number container |
315
+ | `expiryRef` | `RefObject<HTMLDivElement>` | Ref for expiry container |
316
+ | `cvvRef` | `RefObject<HTMLDivElement>` | Ref for CVV container |
317
+ | `isReady` | `boolean` | All fields loaded and ready |
318
+ | `fieldErrors` | `Partial<Record<TFieldType, string \| null>>` | Per-field validation errors (populated after first submit) |
319
+ | `fieldStates` | `Partial<Record<TFieldType, FieldState>>` | Per-field state (always up to date) |
320
+ | `cardBrand` | `string \| null` | Detected card brand (e.g. `"visa"`, `"mastercard"`) |
321
+ | `paymentResult` | `PaymentResult \| null` | Result after payment attempt |
322
+ | `error` | `PaymentError \| null` | SDK error if any |
323
+ | `validate` | `() => Promise<FieldsValidationResult>` | Validate all fields |
324
+ | `submit` | `(options?: SubmitOptions) => Promise<PaymentResult>` | Validate and submit payment |
325
+ | `focusField` | `(fieldType: TFieldType) => void` | Focus a field programmatically |
326
+ | `clearField` | `(fieldType: TFieldType) => void` | Clear a field |
327
+ | `clearAll` | `() => void` | Clear all fields |
328
+
329
+ ### Validation Behavior
330
+
331
+ Validation mirrors react-hook-form `mode: 'onSubmit'`:
332
+
333
+ - Before first submit: `fieldErrors` is always `{}`
334
+ - After first submit: errors update on every field change (revalidation)
335
+ - Card number changes trigger CVV revalidation (CVV length depends on card brand)
336
+ - All three fields (card number, expiry, CVV) are required — submitting with a missing field returns a `MISSING_FIELDS` error
337
+
338
+ ### Field Types
339
+
340
+ | Value | Description |
341
+ |-------|-------------|
342
+ | `'card-number'` | Card number input with automatic formatting and brand detection |
343
+ | `'expiry'` | Expiry date input (MM/YY format) |
344
+ | `'cvv'` | CVV/CVC input (3 or 4 digits depending on card brand) |
345
+
346
+ ### Individual Field Methods (Vanilla JS)
347
+
348
+ | Method | Description |
349
+ |--------|-------------|
350
+ | `field.mount(selector)` | Mount field into a DOM element |
351
+ | `field.unmount()` | Remove field from DOM |
352
+ | `field.focus()` | Focus the field |
353
+ | `field.clear()` | Clear the field value |
354
+ | `field.getState()` | Get current field state |
355
+ | `field.getFieldType()` | Get the field type |
356
+
357
+ ---
358
+
359
+ ## Shared Types
139
360
 
140
361
  ### PaymentResult
141
362
  ```typescript
@@ -157,12 +378,42 @@ interface PaymentError {
157
378
  }
158
379
  ```
159
380
 
381
+ ### FieldState
382
+ ```typescript
383
+ interface FieldState {
384
+ isEmpty: boolean;
385
+ isValid: boolean;
386
+ isFocused: boolean;
387
+ error: string | null;
388
+ }
389
+ ```
390
+
391
+ ### FieldChangeEvent
392
+ ```typescript
393
+ interface FieldChangeEvent {
394
+ fieldType: 'card-number' | 'expiry' | 'cvv';
395
+ isEmpty: boolean;
396
+ isValid: boolean;
397
+ isFocused: boolean;
398
+ error: string | null;
399
+ cardBrand?: string; // Only for card-number
400
+ }
401
+ ```
402
+
403
+ ### FieldsValidationResult
404
+ ```typescript
405
+ interface FieldsValidationResult {
406
+ isValid: boolean;
407
+ errors: Partial<Record<'card-number' | 'expiry' | 'cvv', string | null>>;
408
+ }
409
+ ```
410
+
160
411
  ### FormFields
161
412
  ```typescript
162
413
  interface FormFields {
163
- isEmailVisible?: boolean; // Primer only
414
+ isEmailVisible?: boolean; // Primer only
164
415
  isCardholderNameRequired?: boolean; // Primer only
165
- formVariant?: 'DEFAULT' | 'LIST';
416
+ formVariant?: 'DEFAULT' | 'LIST' | 'RADIO';
166
417
  }
167
418
  ```
168
419
 
@@ -191,52 +442,59 @@ interface FormStyles {
191
442
 
192
443
  ### FormStyles Reference
193
444
 
194
- | Property | Description |
195
- |----------|-------------|
196
- | `loaderColor` | Color of the loading spinner |
197
- | `backgroundColor` | Background color of the checkout form |
198
- | `expressButtonsSpacing` | Spacing between express payment buttons (Apple Pay, Google Pay, PayPal) |
199
- | `inputBackgroundColor` | Background color of input fields |
200
- | `inputBorderRadius` | Border radius of input fields |
201
- | `inputBorderColor` | Default border color of input fields |
202
- | `inputBorderHoverColor` | Border color of input fields on hover |
203
- | `inputBorderFocusColor` | Border color of input fields on focus |
204
- | `inputBorderErrorColor` | Border color of input fields in error state |
205
- | `errorMessageColor` | Color of error messages below inputs |
206
- | `buttonColor` | Background color of the submit button |
207
- | `buttonHoverColor` | Background color of the submit button on hover/active |
208
- | `buttonBorderRadius` | Border radius of the submit button |
209
- | `buttonText` | Custom text for the submit button (overrides default "Pay $X.XX") |
210
- | `cardButtonColor` | Background color of the "Credit or Debit Card" button (LIST variant only) |
211
- | `cardButtonHoverColor` | Hover/active color of the card button (LIST variant only) |
212
- | `cardButtonText` | Custom text for the card button (LIST variant only) |
445
+ | Property | Iframe Checkout | Hosted Fields | Description |
446
+ |----------|:-:|:-:|-------------|
447
+ | `loaderColor` | | | Loading spinner color |
448
+ | `backgroundColor` | | | Form background color |
449
+ | `expressButtonsSpacing` | ✅ | — | Spacing between express payment buttons |
450
+ | `inputBackgroundColor` | | | Input field background color |
451
+ | `inputBorderRadius` | | | Input field border radius |
452
+ | `inputBorderColor` | | | Default input border color |
453
+ | `inputBorderHoverColor` | | | Input border color on hover |
454
+ | `inputBorderFocusColor` | | | Input border color on focus |
455
+ | `inputBorderErrorColor` | | | Input border color in error state |
456
+ | `errorMessageColor` | | | Error message text color |
457
+ | `buttonColor` | | | Submit button background color |
458
+ | `buttonHoverColor` | | | Submit button hover color |
459
+ | `buttonBorderRadius` | | | Submit button border radius |
460
+ | `buttonText` | | | Custom submit button text |
461
+ | `cardButtonColor` | | | Card button color (LIST variant) |
462
+ | `cardButtonHoverColor` | | | Card button hover color (LIST variant) |
463
+ | `cardButtonText` | | | Custom card button text (LIST variant) |
213
464
 
214
465
  ## Form Variants
215
466
 
216
- The checkout form supports two layout variants via `formFields.formVariant`:
467
+ The iframe checkout supports three layout variants via `formFields.formVariant`:
217
468
 
218
- - **DEFAULT** — Express payment methods shown above the card form with dividers
219
- - **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
469
+ - **DEFAULT** — Express payment methods shown above the card form with dividers.
470
+ - **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.
471
+ - **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.
472
+
473
+ 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.
220
474
 
221
475
  ## Supported Payment Methods
222
476
 
223
- - 💳 Credit/Debit Cards (Visa, Mastercard, Amex, Discover)
224
- - 🍎 Apple Pay
225
- - 🔵 Google Pay
226
- - 🟡 PayPal
477
+ ### Iframe Checkout
478
+ - Credit/Debit Cards (Visa, Mastercard, Amex, Discover)
479
+ - Apple Pay
480
+ - Google Pay
481
+ - PayPal
482
+
483
+ ### Hosted Fields
484
+ - Credit/Debit Cards (Visa, Mastercard, Amex, Discover)
227
485
 
228
486
  ## Debug Mode
229
487
 
230
488
  Enable debug logs in console:
231
489
  ```typescript
232
- // React
490
+ // Iframe Checkout
233
491
  useFlintNPayment({
234
492
  config: { clientSessionId: '...' },
235
493
  debug: true,
236
494
  });
237
495
 
238
- // Vanilla JS
239
- new FlintNPayment({
496
+ // Hosted Fields
497
+ useFlintNFields({
240
498
  config: { clientSessionId: '...' },
241
499
  debug: true,
242
500
  });
package/dist/index.d.mts CHANGED
@@ -13,6 +13,7 @@ type TEventType = (typeof EventType)[keyof typeof EventType];
13
13
  declare const CheckoutFormVariant: {
14
14
  readonly DEFAULT: "DEFAULT";
15
15
  readonly LIST: "LIST";
16
+ readonly RADIO: "RADIO";
16
17
  };
17
18
  type TCheckoutFormVariant = (typeof CheckoutFormVariant)[keyof typeof CheckoutFormVariant];
18
19
  interface FormFields {
@@ -66,24 +67,109 @@ interface FlintNPaymentOptions {
66
67
  onError?: (error: PaymentError) => void;
67
68
  debug?: boolean;
68
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
+ }
69
136
 
70
- declare class FlintNPayment {
71
- private options;
72
- private origin;
73
- private iframe;
74
- private container;
75
- private isReady;
76
- private messageHandler;
77
- constructor(options: FlintNPaymentOptions);
137
+ interface FlintNPayment {
78
138
  mount(selector: string | HTMLElement): void;
79
139
  unmount(): void;
80
140
  getIsReady(): boolean;
81
- private handleMessage;
82
- private isValidRedirectUrl;
83
- private handlePaymentResult;
84
- private sendConfig;
85
- private log;
86
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;
87
173
 
88
174
  declare const parseOrigin: (origin: string) => string;
89
175
  declare const buildIframeSrc: (origin: string) => string;
@@ -93,4 +179,4 @@ declare const validateConfig: (config: {
93
179
  }) => void;
94
180
  declare const sanitizeToken: (token: string) => string;
95
181
 
96
- 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 };