flintn-checkout 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,7 +18,7 @@ Full checkout UI rendered inside a single iframe. Includes card form, express pa
18
18
  import { useFlintNPayment } from 'flintn-checkout/react';
19
19
 
20
20
  function Checkout() {
21
- const { containerRef, isReady, paymentResult, error } = useFlintNPayment({
21
+ const { containerRef, isReady, paymentResult, events, error } = useFlintNPayment({
22
22
  config: {
23
23
  clientSessionId: 'your_client_session_id',
24
24
  },
@@ -29,6 +29,12 @@ function Checkout() {
29
29
  console.log('Payment failed:', result.error);
30
30
  }
31
31
  },
32
+ onEvent: (event) => {
33
+ // Per-attempt analytics — fires for every payment attempt outcome
34
+ // (initiated, soft/hard decline, 3DS, cancel, network error, success)
35
+ // and for UI navigation in the LIST and RADIO variants (form entered/exited).
36
+ console.log('Event:', event.type, event.event);
37
+ },
32
38
  });
33
39
 
34
40
  return (
@@ -55,6 +61,9 @@ const payment = createFlintNPayment({
55
61
  console.log('Payment failed:', result.error);
56
62
  }
57
63
  },
64
+ onEvent: (event) => {
65
+ console.log('Event:', event.type, event.event);
66
+ },
58
67
  onReady: () => {
59
68
  console.log('Widget ready');
60
69
  },
@@ -88,6 +97,9 @@ payment.mount('#payment-container');
88
97
  onPayment: (result) => {
89
98
  console.log('Payment result:', result);
90
99
  },
100
+ onEvent: (event) => {
101
+ console.log('Event:', event);
102
+ },
91
103
  });
92
104
 
93
105
  payment.mount('#payment-container');
@@ -96,6 +108,114 @@ payment.mount('#payment-container');
96
108
  </html>
97
109
  ```
98
110
 
111
+ ## Events — terminal vs per-attempt
112
+
113
+ The SDK fires two streams of events. Use the one that fits your use case:
114
+
115
+ ### `onPayment` — terminal (session-final)
116
+
117
+ Fires **once** when the checkout session reaches a final state. Use this for redirecting, marking the order done, sending receipts, and conversion-failure analytics.
118
+
119
+ ```ts
120
+ onPayment(result: PaymentResult)
121
+ ```
122
+
123
+ Fires when:
124
+ - Payment succeeds → `status: 'PAYMENT_SUCCESS'`
125
+ - Session cannot continue (non-retryable decline, network error, SDK error, missing payment id, 3DS failure) → `status: 'PAYMENT_ERROR'`
126
+
127
+ **Does not fire** for soft declines, hard declines with a retryable session, or buyer cancellations — the buyer can still try another card or method.
128
+
129
+ ### `onEvent` — per-attempt analytics
130
+
131
+ Fires for **every payment attempt outcome**, including ones where the session continues. Use for funnel analytics, retry tracking, A/B test instrumentation, fraud signals.
132
+
133
+ ```ts
134
+ onEvent(event: CheckoutEvent)
135
+ ```
136
+
137
+ `CheckoutEvent` is a union of two event kinds, discriminated by `type` (the `isAttemptEvent` / `isUIEvent` guards are also exported):
138
+
139
+ - `PaymentAttempt` — `type: 'PAYMENT_ATTEMPT_EVENT'`, a payment attempt outcome
140
+ - `PaymentUI` — `type: 'PAYMENT_UI_EVENT'`, card form entered/exited (LIST and RADIO variants)
141
+
142
+ Every event carries a `timestamp` (epoch ms) and the `clientSessionId`.
143
+
144
+ For attempt events, the `event` discriminator describes what happened at this step:
145
+
146
+ | `event` | When | Terminal `onPayment` follows? |
147
+ |---|---|---|
148
+ | `'INITIATED'` | Buyer clicked Pay / Apple Pay / PayPal and validation passed | — |
149
+ | `'THREE_DS_INITIATED'` | Authorize returned `THREE_DS_INITIATED`; 3DS challenge is opening | — |
150
+ | `'AUTHORIZED'` | Authorize succeeded | ✅ `PAYMENT_SUCCESS` |
151
+ | `'SOFT_DECLINE'` | Decline with `decline_type: SOFT_DECLINE` — buyer can retry | only if session is non-retryable |
152
+ | `'HARD_DECLINE'` | Decline with `decline_type: HARD_DECLINE` — card permanently bad | only if session is non-retryable |
153
+ | `'CANCELLED'` | Buyer dismissed Apple Pay sheet / closed PayPal popup / closed 3DS dialog | — |
154
+ | `'NETWORK_ERROR'` | Authorize HTTP failure, SDK crashed, missing token, unknown status | ✅ `PAYMENT_ERROR` |
155
+
156
+ A terminal `onPayment` event always fires *after* the corresponding `onEvent` for `AUTHORIZED` / `NETWORK_ERROR` / non-retryable declines / 3DS failures.
157
+
158
+ For UI events (LIST and RADIO variants), `view` is the view that became active:
159
+
160
+ | `event` | When | `view` |
161
+ |---|---|---|
162
+ | `'FORM_ENTERED'` | Buyer opened the card form ("Credit or Debit Card" button / "Card payment" radio) | `'CARD'` |
163
+ | `'FORM_EXITED'` | Buyer returned to express (back arrow / "Fast checkout" radio) | `'EXPRESS'` |
164
+
165
+ **Example funnel — soft decline → retry success:**
166
+
167
+ ```
168
+ onEvent → { event: 'INITIATED', method: 'PAYMENT_CARD' }
169
+ onEvent → { event: 'SOFT_DECLINE', method: 'PAYMENT_CARD', code: 'do_not_honor', message: 'Payment declined.' }
170
+ // buyer retries with another card
171
+ onEvent → { event: 'INITIATED', method: 'PAYMENT_CARD' }
172
+ onEvent → { event: 'AUTHORIZED', method: 'PAYMENT_CARD', paymentId: 'pay_...' }
173
+ onPayment → { status: 'PAYMENT_SUCCESS', data: 'pay_...' }
174
+ ```
175
+
176
+ **Example — Apple Pay buyer cancel (DEFAULT variant):**
177
+
178
+ ```
179
+ onEvent → { event: 'INITIATED', method: 'APPLE_PAY' }
180
+ onEvent → { event: 'CANCELLED', method: 'APPLE_PAY', message: 'Buyer dismissed Apple Pay' }
181
+ // no onPayment — session stays alive, buyer can pick another method
182
+ ```
183
+
184
+ **Example — PayPal popup → 3DS → success:**
185
+
186
+ ```
187
+ onEvent → { event: 'INITIATED', method: 'PAYPAL' }
188
+ onEvent → { event: 'THREE_DS_INITIATED', method: 'PAYPAL', paymentId: 'pay_...' }
189
+ onEvent → { event: 'AUTHORIZED', method: 'PAYPAL', paymentId: 'pay_...' }
190
+ onPayment → { status: 'PAYMENT_SUCCESS', data: 'pay_...' }
191
+ ```
192
+
193
+ (Every event also carries `type`, `timestamp`, and `clientSessionId` — omitted above for brevity.)
194
+
195
+ ### `events` (React) — accumulated log
196
+
197
+ The `useFlintNPayment` hook also exposes `events: CheckoutEvent[]` — every event since mount, useful for rendering a per-attempt UI without wiring `onEvent` manually:
198
+
199
+ ```tsx
200
+ import { isAttemptEvent } from 'flintn-checkout';
201
+
202
+ const { events } = useFlintNPayment({ ... });
203
+
204
+ return (
205
+ <ul>
206
+ {events.map((e, i) =>
207
+ isAttemptEvent(e) ? (
208
+ <li key={i}>[{e.method}] {e.event} {e.code && `— ${e.code}`}</li>
209
+ ) : (
210
+ <li key={i}>[UI] {e.event} → {e.view}</li>
211
+ ),
212
+ )}
213
+ </ul>
214
+ );
215
+ ```
216
+
217
+ The list resets when the checkout remounts (e.g. new `clientSessionId`).
218
+
99
219
  ## Container Sizing
100
220
 
101
221
  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).
@@ -111,7 +231,8 @@ Do **not** set a fixed `height` on the container — it will leave empty space b
111
231
  | Option | Type | Required | Default | Description |
112
232
  |--------|------|----------|---------|-------------|
113
233
  | `config` | `FlintNConfig` | Yes | — | Checkout configuration |
114
- | `onPayment` | `(result: PaymentResult) => void` | No | — | Payment result callback (success, error, cancelled) |
234
+ | `onPayment` | `(result: PaymentResult) => void` | No | — | Terminal session result (success / error) |
235
+ | `onEvent` | `(event: CheckoutEvent) => void` | No | — | Per-attempt analytics signal |
115
236
  | `onReady` | `() => void` | No | — | Widget loaded and ready |
116
237
  | `onError` | `(error: PaymentError) => void` | No | — | SDK initialization error |
117
238
  | `debug` | `boolean` | No | `false` | Enable console debug logs |
@@ -131,7 +252,8 @@ Do **not** set a fixed `height` on the container — it will leave empty space b
131
252
  |-------|------|-------------|
132
253
  | `containerRef` | `RefObject<HTMLDivElement>` | Ref to attach to container element |
133
254
  | `isReady` | `boolean` | Widget is loaded and ready |
134
- | `paymentResult` | `PaymentResult \| null` | Result after payment attempt |
255
+ | `paymentResult` | `PaymentResult \| null` | Result after terminal `onPayment` event |
256
+ | `events` | `CheckoutEvent[]` | Per-attempt event log (accumulated since mount) |
135
257
  | `error` | `PaymentError \| null` | SDK error if any |
136
258
 
137
259
  ---
@@ -142,6 +264,8 @@ Individual PCI-compliant input fields rendered as separate iframes. You control
142
264
 
143
265
  Each field (card number, expiry, CVV) is a separate iframe. Raw card data never touches your page.
144
266
 
267
+ > **Note:** Hosted Fields emits only the terminal `onPayment` event — there is no `onEvent` per-attempt stream. Use Iframe Checkout if you need granular attempt analytics.
268
+
145
269
  **React**
146
270
 
147
271
  ```tsx
@@ -378,6 +502,68 @@ interface PaymentError {
378
502
  }
379
503
  ```
380
504
 
505
+ ### CheckoutEvent
506
+
507
+ ```typescript
508
+ type CheckoutEvent = PaymentAttempt | PaymentUI;
509
+ ```
510
+
511
+ ### PaymentAttempt
512
+
513
+ ```typescript
514
+ interface PaymentAttempt {
515
+ type: 'PAYMENT_ATTEMPT_EVENT';
516
+ event:
517
+ | 'INITIATED'
518
+ | 'THREE_DS_INITIATED'
519
+ | 'AUTHORIZED'
520
+ | 'SOFT_DECLINE'
521
+ | 'HARD_DECLINE'
522
+ | 'CANCELLED'
523
+ | 'NETWORK_ERROR';
524
+ method:
525
+ | 'PAYMENT_CARD'
526
+ | 'GOOGLE_PAY'
527
+ | 'APPLE_PAY'
528
+ | 'PAYPAL'
529
+ | 'BANK_ACCOUNT'
530
+ | 'OTHER';
531
+ paymentId?: string; // Set when the backend has minted a payment id (auth response, 3DS, approve)
532
+ code?: string; // Processor decline code or internal error code (FNT-EC-*, FORBIDDEN, PAYPAL_ERROR, THREE_DS_FAILED, …)
533
+ message?: string; // Translated merchant-facing message for the code
534
+ timestamp: number; // Epoch ms, stamped at emit time
535
+ clientSessionId?: string; // Session the event belongs to
536
+ }
537
+ ```
538
+
539
+ ### PaymentUI
540
+
541
+ ```typescript
542
+ interface PaymentUI {
543
+ type: 'PAYMENT_UI_EVENT';
544
+ event: 'FORM_ENTERED' | 'FORM_EXITED';
545
+ view: 'EXPRESS' | 'CARD'; // The view that became active
546
+ timestamp: number;
547
+ clientSessionId?: string;
548
+ }
549
+ ```
550
+
551
+ Const-object accessors are also exported if you prefer typed comparisons over string literals:
552
+
553
+ ```ts
554
+ import { PaymentAttemptResult, PaymentMethod, isAttemptEvent } from 'flintn-checkout';
555
+
556
+ onEvent: (e) => {
557
+ if (
558
+ isAttemptEvent(e) &&
559
+ e.event === PaymentAttemptResult.SOFT_DECLINE &&
560
+ e.method === PaymentMethod.PAYMENT_CARD
561
+ ) {
562
+ analytics.track('soft_decline_card', { code: e.code });
563
+ }
564
+ }
565
+ ```
566
+
381
567
  ### FieldState
382
568
  ```typescript
383
569
  interface FieldState {
@@ -467,10 +653,24 @@ interface FormStyles {
467
653
  The iframe checkout supports three layout variants via `formFields.formVariant`:
468
654
 
469
655
  - **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.
656
+ - **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. Toggling emits `FORM_ENTERED` / `FORM_EXITED` UI events.
657
+ - **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. Selecting a radio emits `FORM_ENTERED` / `FORM_EXITED` UI events.
658
+
659
+ LIST and RADIO automatically fall back to the DEFAULT layout when no express payment methods are available, since there's nothing to toggle between (and no UI events fire). The `cardButtonColor`, `cardButtonHoverColor`, and `cardButtonText` style overrides apply only to the LIST variant's "Credit or Debit Card" button.
660
+
661
+ ### Cancel-message behavior across variants
662
+
663
+ Express buttons (Apple Pay, PayPal) and the 3DS dialog can all be cancelled by the buyer. When that happens, an inline cancel message is shown in the card form **only when the card form is currently visible**:
664
+
665
+ | Variant | Apple Pay / PayPal cancel | 3DS dialog close |
666
+ |---|---|---|
667
+ | `DEFAULT` | Inline message shown | Inline message shown |
668
+ | `LIST` (EXPRESS view) | No inline message (form hidden) | No inline message |
669
+ | `LIST` (CARD view, after toggle) | Not reachable — cancel originates from EXPRESS view | Inline message shown |
670
+ | `RADIO` (EXPRESS active) | No inline message | No inline message |
671
+ | `RADIO` (CARD active) | Not reachable — cancel originates from EXPRESS view | Inline message shown |
472
672
 
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.
673
+ Every cancellation still emits a `CANCELLED` `onEvent` regardless of variant, so analytics is unaffected.
474
674
 
475
675
  ## Supported Payment Methods
476
676
 
package/dist/index.d.mts CHANGED
@@ -1,6 +1,8 @@
1
1
  declare const EventType: {
2
2
  readonly WIDGET_READY: "WIDGET_READY";
3
3
  readonly WIDGET_CONFIG: "WIDGET_CONFIG";
4
+ readonly PAYMENT_ATTEMPT: "PAYMENT_ATTEMPT_EVENT";
5
+ readonly PAYMENT_UI: "PAYMENT_UI_EVENT";
4
6
  readonly PAYMENT: "PAYMENT";
5
7
  readonly PAYMENT_SUCCESS: "PAYMENT_SUCCESS";
6
8
  readonly PAYMENT_ERROR: "PAYMENT_ERROR";
@@ -45,6 +47,55 @@ interface FlintNConfig {
45
47
  styles?: FormStyles;
46
48
  successRedirectUrl?: string;
47
49
  }
50
+ declare const PaymentMethod: {
51
+ readonly PAYMENT_CARD: "PAYMENT_CARD";
52
+ readonly GOOGLE_PAY: "GOOGLE_PAY";
53
+ readonly APPLE_PAY: "APPLE_PAY";
54
+ readonly PAYPAL: "PAYPAL";
55
+ readonly BANK_ACCOUNT: "BANK_ACCOUNT";
56
+ readonly OTHER: "OTHER";
57
+ };
58
+ type TPaymentMethod = (typeof PaymentMethod)[keyof typeof PaymentMethod];
59
+ declare const PaymentAttemptResult: {
60
+ readonly INITIATED: "INITIATED";
61
+ readonly THREE_DS_INITIATED: "THREE_DS_INITIATED";
62
+ readonly AUTHORIZED: "AUTHORIZED";
63
+ readonly SOFT_DECLINE: "SOFT_DECLINE";
64
+ readonly HARD_DECLINE: "HARD_DECLINE";
65
+ readonly CANCELLED: "CANCELLED";
66
+ readonly NETWORK_ERROR: "NETWORK_ERROR";
67
+ };
68
+ type TPaymentAttemptResult = (typeof PaymentAttemptResult)[keyof typeof PaymentAttemptResult];
69
+ declare const PaymentUIEvent: {
70
+ readonly FORM_ENTERED: "FORM_ENTERED";
71
+ readonly FORM_EXITED: "FORM_EXITED";
72
+ };
73
+ type TPaymentUIEvent = (typeof PaymentUIEvent)[keyof typeof PaymentUIEvent];
74
+ declare const CheckoutView: {
75
+ readonly EXPRESS: "EXPRESS";
76
+ readonly CARD: "CARD";
77
+ };
78
+ type TCheckoutView = (typeof CheckoutView)[keyof typeof CheckoutView];
79
+ interface PaymentAttempt {
80
+ type: typeof EventType.PAYMENT_ATTEMPT;
81
+ event: TPaymentAttemptResult;
82
+ method: TPaymentMethod;
83
+ paymentId?: string;
84
+ code?: string;
85
+ message?: string;
86
+ timestamp: number;
87
+ clientSessionId?: string;
88
+ }
89
+ interface PaymentUI {
90
+ type: typeof EventType.PAYMENT_UI;
91
+ event: TPaymentUIEvent;
92
+ view: TCheckoutView;
93
+ timestamp: number;
94
+ clientSessionId?: string;
95
+ }
96
+ type CheckoutEvent = PaymentAttempt | PaymentUI;
97
+ declare const isAttemptEvent: (e: CheckoutEvent) => e is PaymentAttempt;
98
+ declare const isUIEvent: (e: CheckoutEvent) => e is PaymentUI;
48
99
  interface PaymentResult {
49
100
  status: 'PAYMENT_SUCCESS' | 'PAYMENT_ERROR' | 'PAYMENT_CANCELLED';
50
101
  data?: string;
@@ -61,6 +112,7 @@ interface FlintNPaymentOptions {
61
112
  origin?: string;
62
113
  config: FlintNConfig;
63
114
  onPayment?: (result: PaymentResult) => void;
115
+ onEvent?: (event: CheckoutEvent) => void;
64
116
  onReady?: () => void;
65
117
  onError?: (error: PaymentError) => void;
66
118
  debug?: boolean;
@@ -178,4 +230,4 @@ declare const validateConfig: (config: {
178
230
  }) => void;
179
231
  declare const sanitizeToken: (token: string) => string;
180
232
 
181
- 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 };
233
+ export { type CheckoutEvent, CheckoutFormVariant, CheckoutView, 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 PaymentAttempt, PaymentAttemptResult, type PaymentError, PaymentMethod, type PaymentResult, type PaymentUI, PaymentUIEvent, type SubmitOptions, type TCheckoutFormVariant, type TCheckoutView, type TEventType, type TFieldEventType, type TFieldType, type TPaymentAttemptResult, type TPaymentMethod, type TPaymentUIEvent, buildIframeSrc, createFlintNField, createFlintNFields, createFlintNPayment, createIframeElement, isAttemptEvent, isUIEvent, parseOrigin, sanitizeToken, validateConfig };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  declare const EventType: {
2
2
  readonly WIDGET_READY: "WIDGET_READY";
3
3
  readonly WIDGET_CONFIG: "WIDGET_CONFIG";
4
+ readonly PAYMENT_ATTEMPT: "PAYMENT_ATTEMPT_EVENT";
5
+ readonly PAYMENT_UI: "PAYMENT_UI_EVENT";
4
6
  readonly PAYMENT: "PAYMENT";
5
7
  readonly PAYMENT_SUCCESS: "PAYMENT_SUCCESS";
6
8
  readonly PAYMENT_ERROR: "PAYMENT_ERROR";
@@ -45,6 +47,55 @@ interface FlintNConfig {
45
47
  styles?: FormStyles;
46
48
  successRedirectUrl?: string;
47
49
  }
50
+ declare const PaymentMethod: {
51
+ readonly PAYMENT_CARD: "PAYMENT_CARD";
52
+ readonly GOOGLE_PAY: "GOOGLE_PAY";
53
+ readonly APPLE_PAY: "APPLE_PAY";
54
+ readonly PAYPAL: "PAYPAL";
55
+ readonly BANK_ACCOUNT: "BANK_ACCOUNT";
56
+ readonly OTHER: "OTHER";
57
+ };
58
+ type TPaymentMethod = (typeof PaymentMethod)[keyof typeof PaymentMethod];
59
+ declare const PaymentAttemptResult: {
60
+ readonly INITIATED: "INITIATED";
61
+ readonly THREE_DS_INITIATED: "THREE_DS_INITIATED";
62
+ readonly AUTHORIZED: "AUTHORIZED";
63
+ readonly SOFT_DECLINE: "SOFT_DECLINE";
64
+ readonly HARD_DECLINE: "HARD_DECLINE";
65
+ readonly CANCELLED: "CANCELLED";
66
+ readonly NETWORK_ERROR: "NETWORK_ERROR";
67
+ };
68
+ type TPaymentAttemptResult = (typeof PaymentAttemptResult)[keyof typeof PaymentAttemptResult];
69
+ declare const PaymentUIEvent: {
70
+ readonly FORM_ENTERED: "FORM_ENTERED";
71
+ readonly FORM_EXITED: "FORM_EXITED";
72
+ };
73
+ type TPaymentUIEvent = (typeof PaymentUIEvent)[keyof typeof PaymentUIEvent];
74
+ declare const CheckoutView: {
75
+ readonly EXPRESS: "EXPRESS";
76
+ readonly CARD: "CARD";
77
+ };
78
+ type TCheckoutView = (typeof CheckoutView)[keyof typeof CheckoutView];
79
+ interface PaymentAttempt {
80
+ type: typeof EventType.PAYMENT_ATTEMPT;
81
+ event: TPaymentAttemptResult;
82
+ method: TPaymentMethod;
83
+ paymentId?: string;
84
+ code?: string;
85
+ message?: string;
86
+ timestamp: number;
87
+ clientSessionId?: string;
88
+ }
89
+ interface PaymentUI {
90
+ type: typeof EventType.PAYMENT_UI;
91
+ event: TPaymentUIEvent;
92
+ view: TCheckoutView;
93
+ timestamp: number;
94
+ clientSessionId?: string;
95
+ }
96
+ type CheckoutEvent = PaymentAttempt | PaymentUI;
97
+ declare const isAttemptEvent: (e: CheckoutEvent) => e is PaymentAttempt;
98
+ declare const isUIEvent: (e: CheckoutEvent) => e is PaymentUI;
48
99
  interface PaymentResult {
49
100
  status: 'PAYMENT_SUCCESS' | 'PAYMENT_ERROR' | 'PAYMENT_CANCELLED';
50
101
  data?: string;
@@ -61,6 +112,7 @@ interface FlintNPaymentOptions {
61
112
  origin?: string;
62
113
  config: FlintNConfig;
63
114
  onPayment?: (result: PaymentResult) => void;
115
+ onEvent?: (event: CheckoutEvent) => void;
64
116
  onReady?: () => void;
65
117
  onError?: (error: PaymentError) => void;
66
118
  debug?: boolean;
@@ -178,4 +230,4 @@ declare const validateConfig: (config: {
178
230
  }) => void;
179
231
  declare const sanitizeToken: (token: string) => string;
180
232
 
181
- 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 };
233
+ export { type CheckoutEvent, CheckoutFormVariant, CheckoutView, 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 PaymentAttempt, PaymentAttemptResult, type PaymentError, PaymentMethod, type PaymentResult, type PaymentUI, PaymentUIEvent, type SubmitOptions, type TCheckoutFormVariant, type TCheckoutView, type TEventType, type TFieldEventType, type TFieldType, type TPaymentAttemptResult, type TPaymentMethod, type TPaymentUIEvent, buildIframeSrc, createFlintNField, createFlintNFields, createFlintNPayment, createIframeElement, isAttemptEvent, isUIEvent, parseOrigin, sanitizeToken, validateConfig };
package/dist/index.js CHANGED
@@ -21,14 +21,20 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  CheckoutFormVariant: () => CheckoutFormVariant,
24
+ CheckoutView: () => CheckoutView,
24
25
  EventType: () => EventType,
25
26
  FieldEventType: () => FieldEventType,
26
27
  FieldType: () => FieldType,
28
+ PaymentAttemptResult: () => PaymentAttemptResult,
29
+ PaymentMethod: () => PaymentMethod,
30
+ PaymentUIEvent: () => PaymentUIEvent,
27
31
  buildIframeSrc: () => buildIframeSrc,
28
32
  createFlintNField: () => createFlintNField,
29
33
  createFlintNFields: () => createFlintNFields,
30
34
  createFlintNPayment: () => createFlintNPayment,
31
35
  createIframeElement: () => createIframeElement,
36
+ isAttemptEvent: () => isAttemptEvent,
37
+ isUIEvent: () => isUIEvent,
32
38
  parseOrigin: () => parseOrigin,
33
39
  sanitizeToken: () => sanitizeToken,
34
40
  validateConfig: () => validateConfig
@@ -39,6 +45,8 @@ module.exports = __toCommonJS(index_exports);
39
45
  var EventType = {
40
46
  WIDGET_READY: "WIDGET_READY",
41
47
  WIDGET_CONFIG: "WIDGET_CONFIG",
48
+ PAYMENT_ATTEMPT: "PAYMENT_ATTEMPT_EVENT",
49
+ PAYMENT_UI: "PAYMENT_UI_EVENT",
42
50
  PAYMENT: "PAYMENT",
43
51
  PAYMENT_SUCCESS: "PAYMENT_SUCCESS",
44
52
  PAYMENT_ERROR: "PAYMENT_ERROR",
@@ -51,6 +59,33 @@ var CheckoutFormVariant = {
51
59
  LIST: "LIST",
52
60
  RADIO: "RADIO"
53
61
  };
62
+ var PaymentMethod = {
63
+ PAYMENT_CARD: "PAYMENT_CARD",
64
+ GOOGLE_PAY: "GOOGLE_PAY",
65
+ APPLE_PAY: "APPLE_PAY",
66
+ PAYPAL: "PAYPAL",
67
+ BANK_ACCOUNT: "BANK_ACCOUNT",
68
+ OTHER: "OTHER"
69
+ };
70
+ var PaymentAttemptResult = {
71
+ INITIATED: "INITIATED",
72
+ THREE_DS_INITIATED: "THREE_DS_INITIATED",
73
+ AUTHORIZED: "AUTHORIZED",
74
+ SOFT_DECLINE: "SOFT_DECLINE",
75
+ HARD_DECLINE: "HARD_DECLINE",
76
+ CANCELLED: "CANCELLED",
77
+ NETWORK_ERROR: "NETWORK_ERROR"
78
+ };
79
+ var PaymentUIEvent = {
80
+ FORM_ENTERED: "FORM_ENTERED",
81
+ FORM_EXITED: "FORM_EXITED"
82
+ };
83
+ var CheckoutView = {
84
+ EXPRESS: "EXPRESS",
85
+ CARD: "CARD"
86
+ };
87
+ var isAttemptEvent = (e) => e.type === EventType.PAYMENT_ATTEMPT;
88
+ var isUIEvent = (e) => e.type === EventType.PAYMENT_UI;
54
89
  var FieldType = {
55
90
  CARD_NUMBER: "card-number",
56
91
  EXPIRY: "expiry",
@@ -183,6 +218,18 @@ function createFlintNPayment(options) {
183
218
  sendConfig();
184
219
  options.onReady?.();
185
220
  break;
221
+ case EventType.PAYMENT_ATTEMPT:
222
+ options.onEvent?.({
223
+ type: EventType.PAYMENT_ATTEMPT,
224
+ ...payload
225
+ });
226
+ break;
227
+ case EventType.PAYMENT_UI:
228
+ options.onEvent?.({
229
+ type: EventType.PAYMENT_UI,
230
+ ...payload
231
+ });
232
+ break;
186
233
  case EventType.PAYMENT:
187
234
  options.onPayment?.(payload);
188
235
  break;
@@ -629,14 +676,20 @@ function createFlintNFields(options) {
629
676
  // Annotate the CommonJS export names for ESM import in node:
630
677
  0 && (module.exports = {
631
678
  CheckoutFormVariant,
679
+ CheckoutView,
632
680
  EventType,
633
681
  FieldEventType,
634
682
  FieldType,
683
+ PaymentAttemptResult,
684
+ PaymentMethod,
685
+ PaymentUIEvent,
635
686
  buildIframeSrc,
636
687
  createFlintNField,
637
688
  createFlintNFields,
638
689
  createFlintNPayment,
639
690
  createIframeElement,
691
+ isAttemptEvent,
692
+ isUIEvent,
640
693
  parseOrigin,
641
694
  sanitizeToken,
642
695
  validateConfig
package/dist/index.mjs CHANGED
@@ -2,6 +2,8 @@
2
2
  var EventType = {
3
3
  WIDGET_READY: "WIDGET_READY",
4
4
  WIDGET_CONFIG: "WIDGET_CONFIG",
5
+ PAYMENT_ATTEMPT: "PAYMENT_ATTEMPT_EVENT",
6
+ PAYMENT_UI: "PAYMENT_UI_EVENT",
5
7
  PAYMENT: "PAYMENT",
6
8
  PAYMENT_SUCCESS: "PAYMENT_SUCCESS",
7
9
  PAYMENT_ERROR: "PAYMENT_ERROR",
@@ -14,6 +16,33 @@ var CheckoutFormVariant = {
14
16
  LIST: "LIST",
15
17
  RADIO: "RADIO"
16
18
  };
19
+ var PaymentMethod = {
20
+ PAYMENT_CARD: "PAYMENT_CARD",
21
+ GOOGLE_PAY: "GOOGLE_PAY",
22
+ APPLE_PAY: "APPLE_PAY",
23
+ PAYPAL: "PAYPAL",
24
+ BANK_ACCOUNT: "BANK_ACCOUNT",
25
+ OTHER: "OTHER"
26
+ };
27
+ var PaymentAttemptResult = {
28
+ INITIATED: "INITIATED",
29
+ THREE_DS_INITIATED: "THREE_DS_INITIATED",
30
+ AUTHORIZED: "AUTHORIZED",
31
+ SOFT_DECLINE: "SOFT_DECLINE",
32
+ HARD_DECLINE: "HARD_DECLINE",
33
+ CANCELLED: "CANCELLED",
34
+ NETWORK_ERROR: "NETWORK_ERROR"
35
+ };
36
+ var PaymentUIEvent = {
37
+ FORM_ENTERED: "FORM_ENTERED",
38
+ FORM_EXITED: "FORM_EXITED"
39
+ };
40
+ var CheckoutView = {
41
+ EXPRESS: "EXPRESS",
42
+ CARD: "CARD"
43
+ };
44
+ var isAttemptEvent = (e) => e.type === EventType.PAYMENT_ATTEMPT;
45
+ var isUIEvent = (e) => e.type === EventType.PAYMENT_UI;
17
46
  var FieldType = {
18
47
  CARD_NUMBER: "card-number",
19
48
  EXPIRY: "expiry",
@@ -146,6 +175,18 @@ function createFlintNPayment(options) {
146
175
  sendConfig();
147
176
  options.onReady?.();
148
177
  break;
178
+ case EventType.PAYMENT_ATTEMPT:
179
+ options.onEvent?.({
180
+ type: EventType.PAYMENT_ATTEMPT,
181
+ ...payload
182
+ });
183
+ break;
184
+ case EventType.PAYMENT_UI:
185
+ options.onEvent?.({
186
+ type: EventType.PAYMENT_UI,
187
+ ...payload
188
+ });
189
+ break;
149
190
  case EventType.PAYMENT:
150
191
  options.onPayment?.(payload);
151
192
  break;
@@ -591,14 +632,20 @@ function createFlintNFields(options) {
591
632
  }
592
633
  export {
593
634
  CheckoutFormVariant,
635
+ CheckoutView,
594
636
  EventType,
595
637
  FieldEventType,
596
638
  FieldType,
639
+ PaymentAttemptResult,
640
+ PaymentMethod,
641
+ PaymentUIEvent,
597
642
  buildIframeSrc,
598
643
  createFlintNField,
599
644
  createFlintNFields,
600
645
  createFlintNPayment,
601
646
  createIframeElement,
647
+ isAttemptEvent,
648
+ isUIEvent,
602
649
  parseOrigin,
603
650
  sanitizeToken,
604
651
  validateConfig
package/dist/react.d.mts CHANGED
@@ -1,3 +1,15 @@
1
+ declare const EventType: {
2
+ readonly WIDGET_READY: "WIDGET_READY";
3
+ readonly WIDGET_CONFIG: "WIDGET_CONFIG";
4
+ readonly PAYMENT_ATTEMPT: "PAYMENT_ATTEMPT_EVENT";
5
+ readonly PAYMENT_UI: "PAYMENT_UI_EVENT";
6
+ readonly PAYMENT: "PAYMENT";
7
+ readonly PAYMENT_SUCCESS: "PAYMENT_SUCCESS";
8
+ readonly PAYMENT_ERROR: "PAYMENT_ERROR";
9
+ readonly PAYMENT_CANCELLED: "PAYMENT_CANCELLED";
10
+ readonly REDIRECT: "REDIRECT";
11
+ readonly RESIZE: "RESIZE";
12
+ };
1
13
  declare const CheckoutFormVariant: {
2
14
  readonly DEFAULT: "DEFAULT";
3
15
  readonly LIST: "LIST";
@@ -34,6 +46,53 @@ interface FlintNConfig {
34
46
  styles?: FormStyles;
35
47
  successRedirectUrl?: string;
36
48
  }
49
+ declare const PaymentMethod: {
50
+ readonly PAYMENT_CARD: "PAYMENT_CARD";
51
+ readonly GOOGLE_PAY: "GOOGLE_PAY";
52
+ readonly APPLE_PAY: "APPLE_PAY";
53
+ readonly PAYPAL: "PAYPAL";
54
+ readonly BANK_ACCOUNT: "BANK_ACCOUNT";
55
+ readonly OTHER: "OTHER";
56
+ };
57
+ type TPaymentMethod = (typeof PaymentMethod)[keyof typeof PaymentMethod];
58
+ declare const PaymentAttemptResult: {
59
+ readonly INITIATED: "INITIATED";
60
+ readonly THREE_DS_INITIATED: "THREE_DS_INITIATED";
61
+ readonly AUTHORIZED: "AUTHORIZED";
62
+ readonly SOFT_DECLINE: "SOFT_DECLINE";
63
+ readonly HARD_DECLINE: "HARD_DECLINE";
64
+ readonly CANCELLED: "CANCELLED";
65
+ readonly NETWORK_ERROR: "NETWORK_ERROR";
66
+ };
67
+ type TPaymentAttemptResult = (typeof PaymentAttemptResult)[keyof typeof PaymentAttemptResult];
68
+ declare const PaymentUIEvent: {
69
+ readonly FORM_ENTERED: "FORM_ENTERED";
70
+ readonly FORM_EXITED: "FORM_EXITED";
71
+ };
72
+ type TPaymentUIEvent = (typeof PaymentUIEvent)[keyof typeof PaymentUIEvent];
73
+ declare const CheckoutView: {
74
+ readonly EXPRESS: "EXPRESS";
75
+ readonly CARD: "CARD";
76
+ };
77
+ type TCheckoutView = (typeof CheckoutView)[keyof typeof CheckoutView];
78
+ interface PaymentAttempt {
79
+ type: typeof EventType.PAYMENT_ATTEMPT;
80
+ event: TPaymentAttemptResult;
81
+ method: TPaymentMethod;
82
+ paymentId?: string;
83
+ code?: string;
84
+ message?: string;
85
+ timestamp: number;
86
+ clientSessionId?: string;
87
+ }
88
+ interface PaymentUI {
89
+ type: typeof EventType.PAYMENT_UI;
90
+ event: TPaymentUIEvent;
91
+ view: TCheckoutView;
92
+ timestamp: number;
93
+ clientSessionId?: string;
94
+ }
95
+ type CheckoutEvent = PaymentAttempt | PaymentUI;
37
96
  interface PaymentResult {
38
97
  status: 'PAYMENT_SUCCESS' | 'PAYMENT_ERROR' | 'PAYMENT_CANCELLED';
39
98
  data?: string;
@@ -50,6 +109,7 @@ interface FlintNPaymentOptions {
50
109
  origin?: string;
51
110
  config: FlintNConfig;
52
111
  onPayment?: (result: PaymentResult) => void;
112
+ onEvent?: (event: CheckoutEvent) => void;
53
113
  onReady?: () => void;
54
114
  onError?: (error: PaymentError) => void;
55
115
  debug?: boolean;
@@ -101,22 +161,13 @@ interface FlintNFieldsOptions {
101
161
  debug?: boolean;
102
162
  }
103
163
 
104
- /**
105
- * Options for the useFlintNPayment hook.
106
- *
107
- * Extends FlintNPaymentOptions but omits `onReady` and `onError` callbacks
108
- * as they are managed internally by the hook. Use the returned `isReady`
109
- * and `error` values instead.
110
- *
111
- * All other FlintNPaymentOptions fields (config, onPayment, debug)
112
- * can be passed directly.
113
- */
114
164
  interface UseFlintNPaymentOptions extends Omit<FlintNPaymentOptions, 'onReady' | 'onError'> {
115
165
  }
116
166
  interface UseFlintNPaymentReturn {
117
167
  containerRef: React.RefObject<HTMLDivElement | null>;
118
168
  isReady: boolean;
119
169
  paymentResult: PaymentResult | null;
170
+ events: Array<CheckoutEvent>;
120
171
  error: PaymentError | null;
121
172
  }
122
173
  declare function useFlintNPayment(options: UseFlintNPaymentOptions): UseFlintNPaymentReturn;
package/dist/react.d.ts CHANGED
@@ -1,3 +1,15 @@
1
+ declare const EventType: {
2
+ readonly WIDGET_READY: "WIDGET_READY";
3
+ readonly WIDGET_CONFIG: "WIDGET_CONFIG";
4
+ readonly PAYMENT_ATTEMPT: "PAYMENT_ATTEMPT_EVENT";
5
+ readonly PAYMENT_UI: "PAYMENT_UI_EVENT";
6
+ readonly PAYMENT: "PAYMENT";
7
+ readonly PAYMENT_SUCCESS: "PAYMENT_SUCCESS";
8
+ readonly PAYMENT_ERROR: "PAYMENT_ERROR";
9
+ readonly PAYMENT_CANCELLED: "PAYMENT_CANCELLED";
10
+ readonly REDIRECT: "REDIRECT";
11
+ readonly RESIZE: "RESIZE";
12
+ };
1
13
  declare const CheckoutFormVariant: {
2
14
  readonly DEFAULT: "DEFAULT";
3
15
  readonly LIST: "LIST";
@@ -34,6 +46,53 @@ interface FlintNConfig {
34
46
  styles?: FormStyles;
35
47
  successRedirectUrl?: string;
36
48
  }
49
+ declare const PaymentMethod: {
50
+ readonly PAYMENT_CARD: "PAYMENT_CARD";
51
+ readonly GOOGLE_PAY: "GOOGLE_PAY";
52
+ readonly APPLE_PAY: "APPLE_PAY";
53
+ readonly PAYPAL: "PAYPAL";
54
+ readonly BANK_ACCOUNT: "BANK_ACCOUNT";
55
+ readonly OTHER: "OTHER";
56
+ };
57
+ type TPaymentMethod = (typeof PaymentMethod)[keyof typeof PaymentMethod];
58
+ declare const PaymentAttemptResult: {
59
+ readonly INITIATED: "INITIATED";
60
+ readonly THREE_DS_INITIATED: "THREE_DS_INITIATED";
61
+ readonly AUTHORIZED: "AUTHORIZED";
62
+ readonly SOFT_DECLINE: "SOFT_DECLINE";
63
+ readonly HARD_DECLINE: "HARD_DECLINE";
64
+ readonly CANCELLED: "CANCELLED";
65
+ readonly NETWORK_ERROR: "NETWORK_ERROR";
66
+ };
67
+ type TPaymentAttemptResult = (typeof PaymentAttemptResult)[keyof typeof PaymentAttemptResult];
68
+ declare const PaymentUIEvent: {
69
+ readonly FORM_ENTERED: "FORM_ENTERED";
70
+ readonly FORM_EXITED: "FORM_EXITED";
71
+ };
72
+ type TPaymentUIEvent = (typeof PaymentUIEvent)[keyof typeof PaymentUIEvent];
73
+ declare const CheckoutView: {
74
+ readonly EXPRESS: "EXPRESS";
75
+ readonly CARD: "CARD";
76
+ };
77
+ type TCheckoutView = (typeof CheckoutView)[keyof typeof CheckoutView];
78
+ interface PaymentAttempt {
79
+ type: typeof EventType.PAYMENT_ATTEMPT;
80
+ event: TPaymentAttemptResult;
81
+ method: TPaymentMethod;
82
+ paymentId?: string;
83
+ code?: string;
84
+ message?: string;
85
+ timestamp: number;
86
+ clientSessionId?: string;
87
+ }
88
+ interface PaymentUI {
89
+ type: typeof EventType.PAYMENT_UI;
90
+ event: TPaymentUIEvent;
91
+ view: TCheckoutView;
92
+ timestamp: number;
93
+ clientSessionId?: string;
94
+ }
95
+ type CheckoutEvent = PaymentAttempt | PaymentUI;
37
96
  interface PaymentResult {
38
97
  status: 'PAYMENT_SUCCESS' | 'PAYMENT_ERROR' | 'PAYMENT_CANCELLED';
39
98
  data?: string;
@@ -50,6 +109,7 @@ interface FlintNPaymentOptions {
50
109
  origin?: string;
51
110
  config: FlintNConfig;
52
111
  onPayment?: (result: PaymentResult) => void;
112
+ onEvent?: (event: CheckoutEvent) => void;
53
113
  onReady?: () => void;
54
114
  onError?: (error: PaymentError) => void;
55
115
  debug?: boolean;
@@ -101,22 +161,13 @@ interface FlintNFieldsOptions {
101
161
  debug?: boolean;
102
162
  }
103
163
 
104
- /**
105
- * Options for the useFlintNPayment hook.
106
- *
107
- * Extends FlintNPaymentOptions but omits `onReady` and `onError` callbacks
108
- * as they are managed internally by the hook. Use the returned `isReady`
109
- * and `error` values instead.
110
- *
111
- * All other FlintNPaymentOptions fields (config, onPayment, debug)
112
- * can be passed directly.
113
- */
114
164
  interface UseFlintNPaymentOptions extends Omit<FlintNPaymentOptions, 'onReady' | 'onError'> {
115
165
  }
116
166
  interface UseFlintNPaymentReturn {
117
167
  containerRef: React.RefObject<HTMLDivElement | null>;
118
168
  isReady: boolean;
119
169
  paymentResult: PaymentResult | null;
170
+ events: Array<CheckoutEvent>;
120
171
  error: PaymentError | null;
121
172
  }
122
173
  declare function useFlintNPayment(options: UseFlintNPaymentOptions): UseFlintNPaymentReturn;
package/dist/react.js CHANGED
@@ -32,6 +32,8 @@ var import_react = require("react");
32
32
  var EventType = {
33
33
  WIDGET_READY: "WIDGET_READY",
34
34
  WIDGET_CONFIG: "WIDGET_CONFIG",
35
+ PAYMENT_ATTEMPT: "PAYMENT_ATTEMPT_EVENT",
36
+ PAYMENT_UI: "PAYMENT_UI_EVENT",
35
37
  PAYMENT: "PAYMENT",
36
38
  PAYMENT_SUCCESS: "PAYMENT_SUCCESS",
37
39
  PAYMENT_ERROR: "PAYMENT_ERROR",
@@ -171,6 +173,18 @@ function createFlintNPayment(options) {
171
173
  sendConfig();
172
174
  options.onReady?.();
173
175
  break;
176
+ case EventType.PAYMENT_ATTEMPT:
177
+ options.onEvent?.({
178
+ type: EventType.PAYMENT_ATTEMPT,
179
+ ...payload
180
+ });
181
+ break;
182
+ case EventType.PAYMENT_UI:
183
+ options.onEvent?.({
184
+ type: EventType.PAYMENT_UI,
185
+ ...payload
186
+ });
187
+ break;
174
188
  case EventType.PAYMENT:
175
189
  options.onPayment?.(payload);
176
190
  break;
@@ -226,18 +240,20 @@ function useFlintNPayment(options) {
226
240
  const containerRef = (0, import_react.useRef)(null);
227
241
  const paymentRef = (0, import_react.useRef)(null);
228
242
  const onPaymentRef = (0, import_react.useRef)(options.onPayment);
243
+ const onEventRef = (0, import_react.useRef)(options.onEvent);
229
244
  const [isReady, setIsReady] = (0, import_react.useState)(false);
230
- const [paymentResult, setPaymentResult] = (0, import_react.useState)(
231
- null
232
- );
245
+ const [paymentResult, setPaymentResult] = (0, import_react.useState)(null);
246
+ const [events, setEvents] = (0, import_react.useState)([]);
233
247
  const [error, setError] = (0, import_react.useState)(null);
234
248
  (0, import_react.useEffect)(() => {
235
249
  onPaymentRef.current = options.onPayment;
236
- }, [options.onPayment]);
250
+ onEventRef.current = options.onEvent;
251
+ }, [options.onPayment, options.onEvent]);
237
252
  (0, import_react.useEffect)(() => {
238
253
  if (!containerRef.current) return;
239
254
  setIsReady(false);
240
255
  setPaymentResult(null);
256
+ setEvents([]);
241
257
  setError(null);
242
258
  paymentRef.current = createFlintNPayment({
243
259
  ...options,
@@ -246,6 +262,10 @@ function useFlintNPayment(options) {
246
262
  setPaymentResult(result);
247
263
  onPaymentRef.current?.(result);
248
264
  },
265
+ onEvent: (event) => {
266
+ setEvents((prev) => [...prev, event]);
267
+ onEventRef.current?.(event);
268
+ },
249
269
  onError: (err) => setError(err)
250
270
  });
251
271
  paymentRef.current.mount(containerRef.current);
@@ -265,6 +285,7 @@ function useFlintNPayment(options) {
265
285
  containerRef,
266
286
  isReady,
267
287
  paymentResult,
288
+ events,
268
289
  error
269
290
  };
270
291
  }
package/dist/react.mjs CHANGED
@@ -5,6 +5,8 @@ import { useEffect, useRef, useState } from "react";
5
5
  var EventType = {
6
6
  WIDGET_READY: "WIDGET_READY",
7
7
  WIDGET_CONFIG: "WIDGET_CONFIG",
8
+ PAYMENT_ATTEMPT: "PAYMENT_ATTEMPT_EVENT",
9
+ PAYMENT_UI: "PAYMENT_UI_EVENT",
8
10
  PAYMENT: "PAYMENT",
9
11
  PAYMENT_SUCCESS: "PAYMENT_SUCCESS",
10
12
  PAYMENT_ERROR: "PAYMENT_ERROR",
@@ -144,6 +146,18 @@ function createFlintNPayment(options) {
144
146
  sendConfig();
145
147
  options.onReady?.();
146
148
  break;
149
+ case EventType.PAYMENT_ATTEMPT:
150
+ options.onEvent?.({
151
+ type: EventType.PAYMENT_ATTEMPT,
152
+ ...payload
153
+ });
154
+ break;
155
+ case EventType.PAYMENT_UI:
156
+ options.onEvent?.({
157
+ type: EventType.PAYMENT_UI,
158
+ ...payload
159
+ });
160
+ break;
147
161
  case EventType.PAYMENT:
148
162
  options.onPayment?.(payload);
149
163
  break;
@@ -199,18 +213,20 @@ function useFlintNPayment(options) {
199
213
  const containerRef = useRef(null);
200
214
  const paymentRef = useRef(null);
201
215
  const onPaymentRef = useRef(options.onPayment);
216
+ const onEventRef = useRef(options.onEvent);
202
217
  const [isReady, setIsReady] = useState(false);
203
- const [paymentResult, setPaymentResult] = useState(
204
- null
205
- );
218
+ const [paymentResult, setPaymentResult] = useState(null);
219
+ const [events, setEvents] = useState([]);
206
220
  const [error, setError] = useState(null);
207
221
  useEffect(() => {
208
222
  onPaymentRef.current = options.onPayment;
209
- }, [options.onPayment]);
223
+ onEventRef.current = options.onEvent;
224
+ }, [options.onPayment, options.onEvent]);
210
225
  useEffect(() => {
211
226
  if (!containerRef.current) return;
212
227
  setIsReady(false);
213
228
  setPaymentResult(null);
229
+ setEvents([]);
214
230
  setError(null);
215
231
  paymentRef.current = createFlintNPayment({
216
232
  ...options,
@@ -219,6 +235,10 @@ function useFlintNPayment(options) {
219
235
  setPaymentResult(result);
220
236
  onPaymentRef.current?.(result);
221
237
  },
238
+ onEvent: (event) => {
239
+ setEvents((prev) => [...prev, event]);
240
+ onEventRef.current?.(event);
241
+ },
222
242
  onError: (err) => setError(err)
223
243
  });
224
244
  paymentRef.current.mount(containerRef.current);
@@ -238,6 +258,7 @@ function useFlintNPayment(options) {
238
258
  containerRef,
239
259
  isReady,
240
260
  paymentResult,
261
+ events,
241
262
  error
242
263
  };
243
264
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flintn-checkout",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "description": "FlintN Payment SDK — drop-in iframe checkout for card payments and wallets with localization and theming.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",