flintn-checkout 0.0.15 → 0.0.17
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 +155 -7
- package/dist/index.d.mts +161 -1
- package/dist/index.d.ts +161 -1
- package/dist/index.js +1250 -7
- package/dist/index.mjs +1245 -7
- package/dist/react.d.mts +39 -0
- package/dist/react.d.ts +39 -0
- package/dist/react.js +1300 -9
- package/dist/react.mjs +1300 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -265,7 +265,12 @@ Individual PCI-compliant input fields rendered as separate iframes. You control
|
|
|
265
265
|
|
|
266
266
|
Each field (card number, expiry, CVV) is a separate iframe. Raw card data never touches your page.
|
|
267
267
|
|
|
268
|
-
|
|
268
|
+
When a card payment requires 3DS, the SDK shows the bank's challenge in a
|
|
269
|
+
**modal dialog on your page**. The buyer can dismiss it, which surfaces as a
|
|
270
|
+
`THREE_DS_CANCELLED` payment error. While the challenge is open, the
|
|
271
|
+
`submit()` promise stays pending with a 10-minute timeout.
|
|
272
|
+
|
|
273
|
+
> **Note:** For card fields, Hosted Fields emits only the terminal `onPayment` event. The express buttons additionally emit per-attempt wallet analytics via the top-level `onEvent` callback (same `onPayment` / `onEvent` split as Iframe Checkout) — see "Express buttons" below. For full per-attempt analytics across the card form too, use Iframe Checkout.
|
|
269
274
|
|
|
270
275
|
**React**
|
|
271
276
|
|
|
@@ -326,7 +331,11 @@ function CheckoutForm() {
|
|
|
326
331
|
</div>
|
|
327
332
|
<div style={{ flex: 1 }}>
|
|
328
333
|
<label>CVV</label>
|
|
329
|
-
|
|
334
|
+
{/* position/zIndex let the CVV helper panel overlay content below */}
|
|
335
|
+
<div
|
|
336
|
+
ref={cvvRef}
|
|
337
|
+
style={{ height: 40, marginBottom: 4, position: 'relative', zIndex: 1 }}
|
|
338
|
+
/>
|
|
330
339
|
{fieldErrors['cvv'] && (
|
|
331
340
|
<span style={{ color: 'red' }}>{fieldErrors['cvv']}</span>
|
|
332
341
|
)}
|
|
@@ -374,7 +383,7 @@ const fields = createFlintNFields({
|
|
|
374
383
|
|
|
375
384
|
const cardNumber = fields.createField('card-number', { placeholder: '4111 1111 1111 1111' });
|
|
376
385
|
const expiry = fields.createField('expiry', { placeholder: 'MM/YY' });
|
|
377
|
-
const cvv = fields.createField('cvv'
|
|
386
|
+
const cvv = fields.createField('cvv');
|
|
378
387
|
|
|
379
388
|
cardNumber.mount('#card-number');
|
|
380
389
|
expiry.mount('#expiry');
|
|
@@ -424,12 +433,13 @@ Additional React-only options:
|
|
|
424
433
|
| `onChange` | `(event: FieldChangeEvent) => void` | Optional additional callback |
|
|
425
434
|
| `onFocus` | `(fieldType: TFieldType) => void` | Optional additional callback |
|
|
426
435
|
| `onBlur` | `(fieldType: TFieldType, state: FieldState) => void` | Optional additional callback |
|
|
436
|
+
| `onEvent` | `(event: ExpressAttempt) => void` | Per-attempt wallet analytics from the express buttons (see "Express buttons") |
|
|
427
437
|
|
|
428
438
|
### FieldOptions
|
|
429
439
|
|
|
430
440
|
| Property | Type | Default | Description |
|
|
431
441
|
|----------|------|---------|-------------|
|
|
432
|
-
| `placeholder` | `string` |
|
|
442
|
+
| `placeholder` | `string` | `'1234 1234 1234 1234'` / `'MM/YY'` / `'***'` | Input placeholder text |
|
|
433
443
|
| `disabled` | `boolean` | `false` | Disable the input |
|
|
434
444
|
|
|
435
445
|
### React Hook Return Values
|
|
@@ -439,6 +449,10 @@ Additional React-only options:
|
|
|
439
449
|
| `cardNumberRef` | `RefObject<HTMLDivElement>` | Ref for card number container |
|
|
440
450
|
| `expiryRef` | `RefObject<HTMLDivElement>` | Ref for expiry container |
|
|
441
451
|
| `cvvRef` | `RefObject<HTMLDivElement>` | Ref for CVV container |
|
|
452
|
+
| `applePayRef` | `RefObject<HTMLDivElement>` | Ref for the Apple Pay button container (attaching it enables the wallet) |
|
|
453
|
+
| `googlePayRef` | `RefObject<HTMLDivElement>` | Ref for the Google Pay button container (attaching it enables the wallet) |
|
|
454
|
+
| `payPalRef` | `RefObject<HTMLDivElement>` | Ref for the PayPal button container (attaching it enables the wallet) |
|
|
455
|
+
| `expressAvailable` | `boolean` | True once wallet detection settles and at least one express button is renderable |
|
|
442
456
|
| `isReady` | `boolean` | All fields loaded and ready |
|
|
443
457
|
| `fieldErrors` | `Partial<Record<TFieldType, string \| null>>` | Per-field validation errors (populated after first submit) |
|
|
444
458
|
| `fieldStates` | `Partial<Record<TFieldType, FieldState>>` | Per-field state (always up to date) |
|
|
@@ -459,6 +473,7 @@ Validation mirrors react-hook-form `mode: 'onSubmit'`:
|
|
|
459
473
|
- After first submit: errors update on every field change (revalidation)
|
|
460
474
|
- Card number changes trigger CVV revalidation (CVV length depends on card brand)
|
|
461
475
|
- All three fields (card number, expiry, CVV) are required — submitting with a missing field returns a `MISSING_FIELDS` error
|
|
476
|
+
- The CVV field ships a built-in helper: tapping the card icon expands a “where to find CVV” panel below the input. The field iframe grows to fit it, so keep the CVV container at a fixed `height` with `position: relative; z-index: 1` — the open panel then overlays the content below (like a popover) instead of pushing your layout
|
|
462
477
|
|
|
463
478
|
### Field Types
|
|
464
479
|
|
|
@@ -466,7 +481,7 @@ Validation mirrors react-hook-form `mode: 'onSubmit'`:
|
|
|
466
481
|
|-------|-------------|
|
|
467
482
|
| `'card-number'` | Card number input with automatic formatting and brand detection |
|
|
468
483
|
| `'expiry'` | Expiry date input (MM/YY format) |
|
|
469
|
-
| `'cvv'` | CVV/CVC input (3 or 4 digits depending on card brand) |
|
|
484
|
+
| `'cvv'` | CVV/CVC input (3 or 4 digits depending on card brand). Includes a built-in “where to find CVV” helper: tapping the card icon expands an explainer panel below the input |
|
|
470
485
|
|
|
471
486
|
### Individual Field Methods (Vanilla JS)
|
|
472
487
|
|
|
@@ -479,6 +494,105 @@ Validation mirrors react-hook-form `mode: 'onSubmit'`:
|
|
|
479
494
|
| `field.getState()` | Get current field state |
|
|
480
495
|
| `field.getFieldType()` | Get the field type |
|
|
481
496
|
|
|
497
|
+
### Express buttons (Apple Pay / Google Pay / PayPal)
|
|
498
|
+
|
|
499
|
+
Hosted Fields can also render **fast checkout buttons** so buyers can pay with a
|
|
500
|
+
wallet instead of typing card details. The buttons render **directly into your
|
|
501
|
+
DOM** — one element per wallet, no iframe. Your page's own layout sizes and
|
|
502
|
+
positions each button; wallet UI (the Apple Pay sheet or desktop QR modal, the
|
|
503
|
+
Google Pay sheet, the PayPal popup) overlays your page natively. Only encrypted
|
|
504
|
+
wallet tokens pass through the page; they are authorized against the
|
|
505
|
+
session-scoped payments API, so no API key ever reaches the browser. Terminal
|
|
506
|
+
results arrive through the **same `onPayment`** callback as the card `submit()`.
|
|
507
|
+
|
|
508
|
+
**React**
|
|
509
|
+
|
|
510
|
+
```tsx
|
|
511
|
+
import { useFlintNFields } from 'flintn-checkout/react';
|
|
512
|
+
|
|
513
|
+
function CheckoutForm() {
|
|
514
|
+
const {
|
|
515
|
+
cardNumberRef, expiryRef, cvvRef,
|
|
516
|
+
applePayRef, googlePayRef, payPalRef, // one container per wallet
|
|
517
|
+
expressAvailable, // true once ≥1 wallet button is renderable
|
|
518
|
+
submit,
|
|
519
|
+
} = useFlintNFields({
|
|
520
|
+
config: { clientSessionId: 'your_client_session_id' },
|
|
521
|
+
onPayment: (result) => {
|
|
522
|
+
if (result.status === 'PAYMENT_SUCCESS') console.log('Paid:', result.data);
|
|
523
|
+
},
|
|
524
|
+
onEvent: (e) => console.log('express attempt:', e.event, e.method),
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
return (
|
|
528
|
+
<form onSubmit={(e) => { e.preventDefault(); submit(); }}>
|
|
529
|
+
{/* attach a ref to enable that wallet; unavailable wallets render
|
|
530
|
+
nothing — collapse empty containers via CSS if they carry spacing */}
|
|
531
|
+
<div ref={applePayRef} />
|
|
532
|
+
<div ref={googlePayRef} />
|
|
533
|
+
<div ref={payPalRef} />
|
|
534
|
+
{expressAvailable && <div className="divider">or pay by card</div>}
|
|
535
|
+
|
|
536
|
+
<div ref={cardNumberRef} style={{ height: 40 }} />
|
|
537
|
+
<div ref={expiryRef} style={{ height: 40 }} />
|
|
538
|
+
<div ref={cvvRef} style={{ height: 40 }} />
|
|
539
|
+
<button type="submit">Pay</button>
|
|
540
|
+
</form>
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
**Vanilla JavaScript**
|
|
546
|
+
|
|
547
|
+
```javascript
|
|
548
|
+
import { createFlintNFields } from 'flintn-checkout';
|
|
549
|
+
|
|
550
|
+
const fields = createFlintNFields({
|
|
551
|
+
config: { clientSessionId: 'your_client_session_id' },
|
|
552
|
+
onPayment: (result) => console.log('Payment result:', result),
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
const express = fields.createExpressButtons({
|
|
556
|
+
onCapability: (cap) => console.log('available wallets:', cap),
|
|
557
|
+
onEvent: (attempt) => console.log('express attempt:', attempt),
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
await express.mountExpressButtons([
|
|
561
|
+
{ method: 'APPLE_PAY', elementSelector: '#apple-pay' },
|
|
562
|
+
{ method: 'GOOGLE_PAY', elementSelector: '#google-pay' },
|
|
563
|
+
{ method: 'PAYPAL', elementSelector: '#paypal' },
|
|
564
|
+
]);
|
|
565
|
+
|
|
566
|
+
// unmount a single wallet, or all of them
|
|
567
|
+
express.unmountExpressButton('APPLE_PAY');
|
|
568
|
+
express.unmountAllExpressButtons();
|
|
569
|
+
|
|
570
|
+
// card fields as usual
|
|
571
|
+
fields.createField('card-number').mount('#card-number');
|
|
572
|
+
fields.createField('expiry').mount('#expiry');
|
|
573
|
+
fields.createField('cvv').mount('#cvv');
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
Notes:
|
|
577
|
+
|
|
578
|
+
- **No `submit()` for express.** Wallet buttons self-trigger (the buyer taps Apple
|
|
579
|
+
Pay and the sheet opens). Success/error come through `onPayment`; per-attempt
|
|
580
|
+
analytics through the top-level `onEvent` (React) /
|
|
581
|
+
`createExpressButtons({ onEvent })` (vanilla).
|
|
582
|
+
- **Availability.** Buttons for methods that are unavailable on this
|
|
583
|
+
device/session are silently skipped at mount — their containers just stay
|
|
584
|
+
empty. `expressAvailable` (React) / the `onCapability` callback (vanilla)
|
|
585
|
+
gate your "or pay by card" divider.
|
|
586
|
+
- **Which wallets appear** is driven entirely by the merchant session config
|
|
587
|
+
(`payment_methods`) intersected with device support — there is no client-side
|
|
588
|
+
allow-list.
|
|
589
|
+
- **3DS** for wallet payments is handled automatically via a popup (make sure the
|
|
590
|
+
buyer's click isn't intercepted by a popup blocker).
|
|
591
|
+
- **Apple Pay domain registration.** Your live domain must be registered with
|
|
592
|
+
Apple (handled during merchant onboarding) — merchant validation runs against
|
|
593
|
+
the domain the buttons render on. On non-Safari browsers Apple's JS SDK shows
|
|
594
|
+
its QR-code modal over your page. Google Pay and PayPal have no such limits.
|
|
595
|
+
|
|
482
596
|
---
|
|
483
597
|
|
|
484
598
|
## Shared Types
|
|
@@ -503,6 +617,39 @@ interface PaymentError {
|
|
|
503
617
|
}
|
|
504
618
|
```
|
|
505
619
|
|
|
620
|
+
### Error handling
|
|
621
|
+
|
|
622
|
+
Errors surface through three separate channels — don't conflate them:
|
|
623
|
+
|
|
624
|
+
| Channel | What lands there | Show as |
|
|
625
|
+
|---------|------------------|---------|
|
|
626
|
+
| `error` / `onError` | Infrastructure: SDK failed to initialize, a container is missing, the session config couldn't load | Page-level banner ("checkout unavailable / session expired") |
|
|
627
|
+
| `paymentResult` / `onPayment` with `PAYMENT_ERROR` | A payment attempt failed (card or wallet) | Inline payment error, offer retry |
|
|
628
|
+
| `fieldErrors` | Per-field validation (populated after the first `submit()`/`validate()`) | Messages next to each field |
|
|
629
|
+
|
|
630
|
+
Common `code` values:
|
|
631
|
+
|
|
632
|
+
| Code | Channel | Meaning |
|
|
633
|
+
|------|---------|---------|
|
|
634
|
+
| `INIT_ERROR` | error | SDK could not initialize (missing `clientSessionId`, bad `origin`) |
|
|
635
|
+
| `MOUNT_ERROR` | error | A field/button container was not found or failed to mount |
|
|
636
|
+
| `SESSION_EXPIRED` (and other API codes) | error or payment | Passed through from the payments API as-is |
|
|
637
|
+
| `CONFIG_ERROR` | error | Session config failed to load and the API gave no code |
|
|
638
|
+
| `NETWORK_ERROR` / `HTTP_<status>` / `INVALID_RESPONSE` | error or payment | Network failure / HTTP error without an API code / malformed response |
|
|
639
|
+
| `VALIDATION_ERROR` | payment | `submit()` blocked by field validation (details in `fieldErrors`) |
|
|
640
|
+
| `MISSING_FIELDS` / `NOT_INITIALIZED` / `SUBMIT_IN_PROGRESS` / `SUBMIT_TIMEOUT` | payment | Card `submit()` preconditions / duplicate call / no response in time (30s) |
|
|
641
|
+
| `THREE_DS_TIMEOUT` | payment | A 3DS challenge stayed unresolved for 10 minutes |
|
|
642
|
+
| `PAYMENT_DECLINED` / processor decline codes | payment | Declined; the processor's own code is passed through when present |
|
|
643
|
+
| `PAYMENT_FAILED` | payment | Non-declined failure (including unexpected 3DS outcomes) |
|
|
644
|
+
| `APPLE_PAY_SDK_ERROR` / `GOOGLE_PAY_SDK_ERROR` / `PAYPAL_ERROR` | payment | The wallet SDK failed mid-flow |
|
|
645
|
+
| `PAYPAL_MISSING_PAYMENT_ID` | payment | PayPal approved but no payment id was captured (anomaly) |
|
|
646
|
+
| `THREE_DS_FAILED` / `THREE_DS_CANCELLED` | payment | Challenge declined / dismissed by the buyer |
|
|
647
|
+
| `THREE_DS_POPUP_BLOCKED` | payment | Express buttons only — the wallet 3DS window was blocked by the browser |
|
|
648
|
+
|
|
649
|
+
Worth handling specifically: `SESSION_EXPIRED` (create a fresh session and remount),
|
|
650
|
+
`THREE_DS_POPUP_BLOCKED` (ask the buyer to allow popups), `VALIDATION_ERROR`
|
|
651
|
+
(highlight fields from `fieldErrors`). Everything else is safely generic.
|
|
652
|
+
|
|
506
653
|
### CheckoutEvent
|
|
507
654
|
|
|
508
655
|
```typescript
|
|
@@ -683,8 +830,8 @@ on `createField` (or the `fields` prop of `useFlintNFields`) instead.
|
|
|
683
830
|
| `loaderColor` | ✅ | — | Loading spinner color |
|
|
684
831
|
| `backgroundColor` | ✅ | — | Form background color |
|
|
685
832
|
| `lightLogos` | ✅ | — | Use light logo variants in the safe-checkout row (for dark backgrounds) |
|
|
686
|
-
| `expressButtonsSpacing` | ✅ | — | Spacing between express payment buttons |
|
|
687
|
-
| `expressButtonsBorderRadius` | ✅ |
|
|
833
|
+
| `expressButtonsSpacing` | ✅ | — | Spacing between express payment buttons. Not applicable to Hosted Fields — the buttons render into your own containers, so spacing is your page's layout |
|
|
834
|
+
| `expressButtonsBorderRadius` | ✅ | ✅ | Corner radius for express buttons — Apple Pay, Google Pay, PayPal, and the "Credit or debit card" button in the LIST variant (e.g. `8px`). In Hosted Fields it applies to all wallet buttons at once |
|
|
688
835
|
| `inputBackgroundColor` | ✅ | ✅ | Input field background color |
|
|
689
836
|
| `inputBorderRadius` | ✅ | ✅ | Input field border radius |
|
|
690
837
|
| `inputBorderColor` | ✅ | ✅ | Default input border color |
|
|
@@ -754,6 +901,7 @@ Every cancellation still emits a `CANCELLED` `onEvent` regardless of variant, so
|
|
|
754
901
|
|
|
755
902
|
### Hosted Fields
|
|
756
903
|
- Credit/Debit Cards (Visa, Mastercard, Amex, Discover)
|
|
904
|
+
- Apple Pay, Google Pay, PayPal (via the express buttons — see "Express buttons" above)
|
|
757
905
|
|
|
758
906
|
## Debug Mode
|
|
759
907
|
|
package/dist/index.d.mts
CHANGED
|
@@ -171,6 +171,8 @@ declare const FieldEventType: {
|
|
|
171
171
|
readonly FIELD_VALIDATION: "FIELD_VALIDATION";
|
|
172
172
|
readonly FIELD_SUBMIT_RESULT: "FIELD_SUBMIT_RESULT";
|
|
173
173
|
readonly FIELD_HEIGHT: "FIELD_HEIGHT";
|
|
174
|
+
readonly FIELD_THREE_DS_REQUIRED: "FIELD_THREE_DS_REQUIRED";
|
|
175
|
+
readonly FIELD_THREE_DS_RESULT: "FIELD_THREE_DS_RESULT";
|
|
174
176
|
};
|
|
175
177
|
type TFieldEventType = (typeof FieldEventType)[keyof typeof FieldEventType];
|
|
176
178
|
interface FieldOptions {
|
|
@@ -200,8 +202,31 @@ interface FieldsValidationResult {
|
|
|
200
202
|
isValid: boolean;
|
|
201
203
|
errors: Partial<Record<TFieldType, string | null>>;
|
|
202
204
|
}
|
|
205
|
+
interface SubmitBillingAddress {
|
|
206
|
+
addressLine1?: string;
|
|
207
|
+
addressLine2?: string;
|
|
208
|
+
city?: string;
|
|
209
|
+
state?: string;
|
|
210
|
+
postalCode?: string;
|
|
211
|
+
country?: string;
|
|
212
|
+
}
|
|
203
213
|
interface SubmitOptions {
|
|
204
214
|
cardholderName?: string;
|
|
215
|
+
email?: string;
|
|
216
|
+
billingAddress?: SubmitBillingAddress;
|
|
217
|
+
}
|
|
218
|
+
interface ExpressCapability {
|
|
219
|
+
applePay: boolean;
|
|
220
|
+
googlePay: boolean;
|
|
221
|
+
paypal: boolean;
|
|
222
|
+
}
|
|
223
|
+
interface ExpressAttempt {
|
|
224
|
+
event: TPaymentAttemptResult;
|
|
225
|
+
method: TPaymentMethod;
|
|
226
|
+
paymentId?: string;
|
|
227
|
+
code?: string;
|
|
228
|
+
message?: string;
|
|
229
|
+
timestamp: number;
|
|
205
230
|
}
|
|
206
231
|
interface FlintNFieldsConfig {
|
|
207
232
|
clientSessionId: string;
|
|
@@ -247,9 +272,144 @@ interface FlintNField {
|
|
|
247
272
|
}
|
|
248
273
|
declare function createFlintNField(fieldType: TFieldType, origin: string, clientSessionId: string, options: FieldOptions, callbacks: FlintNFieldInternalCallbacks, debug?: boolean, formStyles?: FormStyles): FlintNField;
|
|
249
274
|
|
|
275
|
+
declare const EXPRESS_BUTTON_HEIGHT = 40;
|
|
276
|
+
declare const ExpressMethod: {
|
|
277
|
+
readonly APPLE_PAY: "APPLE_PAY";
|
|
278
|
+
readonly GOOGLE_PAY: "GOOGLE_PAY";
|
|
279
|
+
readonly PAYPAL: "PAYPAL";
|
|
280
|
+
};
|
|
281
|
+
type TExpressMethod = (typeof ExpressMethod)[keyof typeof ExpressMethod];
|
|
282
|
+
/** One entry per wallet button: which method goes into which element. */
|
|
283
|
+
interface ExpressButtonMount {
|
|
284
|
+
method: TExpressMethod;
|
|
285
|
+
/** CSS selector or the element itself. The button fills the element. */
|
|
286
|
+
elementSelector: string | HTMLElement;
|
|
287
|
+
}
|
|
288
|
+
interface FlintNExpressButtonsOptions {
|
|
289
|
+
config: {
|
|
290
|
+
clientSessionId: string;
|
|
291
|
+
};
|
|
292
|
+
origin?: string;
|
|
293
|
+
apiUrl?: string;
|
|
294
|
+
buttonBorderRadius?: number;
|
|
295
|
+
onPayment?: (result: PaymentResult) => void;
|
|
296
|
+
onEvent?: (event: ExpressAttempt) => void;
|
|
297
|
+
onCapability?: (capability: ExpressCapability) => void;
|
|
298
|
+
onError?: (error: PaymentError) => void;
|
|
299
|
+
debug?: boolean;
|
|
300
|
+
}
|
|
301
|
+
interface FlintNExpressButtons {
|
|
302
|
+
mountExpressButtons(buttons: ExpressButtonMount[]): Promise<void>;
|
|
303
|
+
unmountExpressButton(method: TExpressMethod): void;
|
|
304
|
+
unmountAllExpressButtons(): void;
|
|
305
|
+
}
|
|
306
|
+
interface ApplePayConfig {
|
|
307
|
+
country_code: string;
|
|
308
|
+
supported_networks: string[];
|
|
309
|
+
merchant_capabilities: string[];
|
|
310
|
+
display_name: string;
|
|
311
|
+
merchant_identifier?: string;
|
|
312
|
+
}
|
|
313
|
+
interface GooglePayConfig {
|
|
314
|
+
environment: string;
|
|
315
|
+
gateway: string;
|
|
316
|
+
gateway_merchant_id: string;
|
|
317
|
+
merchant_id?: string;
|
|
318
|
+
merchant_name?: string;
|
|
319
|
+
country_code?: string;
|
|
320
|
+
}
|
|
321
|
+
interface PayPalConfig {
|
|
322
|
+
client_id: string;
|
|
323
|
+
merchant_id?: string;
|
|
324
|
+
}
|
|
325
|
+
interface SessionConfig {
|
|
326
|
+
session: {
|
|
327
|
+
amount: number;
|
|
328
|
+
currency_code: string;
|
|
329
|
+
};
|
|
330
|
+
payment_methods: string[];
|
|
331
|
+
apple_pay_config?: ApplePayConfig;
|
|
332
|
+
google_pay_config?: GooglePayConfig;
|
|
333
|
+
paypal_config?: PayPalConfig;
|
|
334
|
+
}
|
|
335
|
+
declare const AuthorizedStatus: {
|
|
336
|
+
readonly PENDING: "PENDING";
|
|
337
|
+
readonly AUTHORIZED: "AUTHORIZED";
|
|
338
|
+
readonly FAILED: "FAILED";
|
|
339
|
+
readonly DECLINED: "DECLINED";
|
|
340
|
+
readonly THREE_DS_INITIATED: "THREE_DS_INITIATED";
|
|
341
|
+
};
|
|
342
|
+
type TAuthorizedStatus = (typeof AuthorizedStatus)[keyof typeof AuthorizedStatus];
|
|
343
|
+
interface AuthorizeResponse {
|
|
344
|
+
id: string;
|
|
345
|
+
status: TAuthorizedStatus;
|
|
346
|
+
required_action?: {
|
|
347
|
+
type: string;
|
|
348
|
+
redirect_url: string;
|
|
349
|
+
};
|
|
350
|
+
status_reason?: {
|
|
351
|
+
decline_reason?: string;
|
|
352
|
+
message?: string;
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
interface ApplePayToken {
|
|
356
|
+
payment_data: {
|
|
357
|
+
data: string;
|
|
358
|
+
header: {
|
|
359
|
+
ephemeral_public_key: string;
|
|
360
|
+
public_key_hash: string;
|
|
361
|
+
transaction_id: string;
|
|
362
|
+
};
|
|
363
|
+
signature: string;
|
|
364
|
+
version: string;
|
|
365
|
+
};
|
|
366
|
+
payment_method: {
|
|
367
|
+
display_name: string;
|
|
368
|
+
network: string;
|
|
369
|
+
type: string;
|
|
370
|
+
};
|
|
371
|
+
transaction_identifier: string;
|
|
372
|
+
}
|
|
373
|
+
interface GooglePayToken {
|
|
374
|
+
token: string;
|
|
375
|
+
}
|
|
376
|
+
/** Terminal-ish callbacks the wallet flows report into (mirrors the iframe's ExpressAuthorizeHandlers). */
|
|
377
|
+
interface WalletAuthorizeHandlers {
|
|
378
|
+
onAuthorized: (paymentId: string) => void;
|
|
379
|
+
onThreeDs: (redirectUrl: string, paymentId: string) => void;
|
|
380
|
+
onFailed: (code: string, message: string, paymentId?: string) => void;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Express fast-checkout buttons (Apple Pay / Google Pay / PayPal) rendered
|
|
385
|
+
* DIRECTLY into the merchant's DOM — one element per wallet, Yuno-style.
|
|
386
|
+
* There is no iframe: wallet SDKs load on the merchant page, wallet UI
|
|
387
|
+
* (Apple Pay QR modal, payment sheets) overlays the page natively, and the
|
|
388
|
+
* page's own layout sizes the buttons. Only encrypted wallet tokens pass
|
|
389
|
+
* through the page; they are authorized against the session-scoped payments
|
|
390
|
+
* API (no API key in the browser).
|
|
391
|
+
*/
|
|
392
|
+
declare function createFlintNExpressButtons(options: FlintNExpressButtonsOptions): FlintNExpressButtons;
|
|
393
|
+
|
|
394
|
+
declare const deriveApiUrl: (payOrigin: string) => string;
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Per-instance express options; session/origin/onPayment come from the fields
|
|
398
|
+
* instance, and button styling comes from `config.styles`
|
|
399
|
+
* (expressButtonsBorderRadius).
|
|
400
|
+
*/
|
|
401
|
+
type ExpressButtonsOptions = Pick<FlintNExpressButtonsOptions, 'apiUrl' | 'onEvent' | 'onCapability'>;
|
|
250
402
|
interface FlintNFields {
|
|
251
403
|
createField(fieldType: TFieldType, options?: FieldOptions): FlintNField;
|
|
252
404
|
getField(fieldType: TFieldType): FlintNField | undefined;
|
|
405
|
+
/**
|
|
406
|
+
* Create the express fast-checkout buttons (Apple Pay / Google Pay /
|
|
407
|
+
* PayPal), rendered directly into merchant-owned elements (one per wallet —
|
|
408
|
+
* see `mountExpressButtons`). Terminal results flow through the same
|
|
409
|
+
* `onPayment` callback as the card `submit()`; per-attempt analytics and
|
|
410
|
+
* capability flags are delivered via the options passed here.
|
|
411
|
+
*/
|
|
412
|
+
createExpressButtons(options?: ExpressButtonsOptions): FlintNExpressButtons;
|
|
253
413
|
validate(): Promise<FieldsValidationResult>;
|
|
254
414
|
submit(options?: SubmitOptions, skipValidation?: boolean): Promise<PaymentResult>;
|
|
255
415
|
unmount(): void;
|
|
@@ -265,4 +425,4 @@ declare const validateConfig: (config: {
|
|
|
265
425
|
}) => void;
|
|
266
426
|
declare const sanitizeToken: (token: string) => string;
|
|
267
427
|
|
|
268
|
-
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 FormPlaceholders, 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 };
|
|
428
|
+
export { type ApplePayConfig, type ApplePayToken, type AuthorizeResponse, AuthorizedStatus, type CheckoutEvent, CheckoutFormVariant, CheckoutView, EXPRESS_BUTTON_HEIGHT, EventType, type ExpressAttempt, type ExpressButtonMount, type ExpressButtonsOptions, type ExpressCapability, ExpressMethod, type FieldChangeEvent, FieldEventType, type FieldOptions, type FieldState, FieldType, type FieldValidationResult, type FieldsValidationResult, type FlintNConfig, type FlintNExpressButtons, type FlintNExpressButtonsOptions, type FlintNField, type FlintNFieldInternalCallbacks, type FlintNFields, type FlintNFieldsConfig, type FlintNFieldsOptions, type FlintNPayment, type FlintNPaymentOptions, type FormFields, type FormPlaceholders, type FormStyles, type GooglePayConfig, type GooglePayToken, type PayPalConfig, type PaymentAttempt, PaymentAttemptResult, type PaymentError, PaymentMethod, type PaymentResult, type PaymentUI, PaymentUIEvent, type SessionConfig, type SubmitBillingAddress, type SubmitOptions, type TAuthorizedStatus, type TCheckoutFormVariant, type TCheckoutView, type TEventType, type TExpressMethod, type TFieldEventType, type TFieldType, type TPaymentAttemptResult, type TPaymentMethod, type TPaymentUIEvent, type WalletAuthorizeHandlers, buildIframeSrc, createFlintNExpressButtons, createFlintNField, createFlintNFields, createFlintNPayment, createIframeElement, deriveApiUrl, isAttemptEvent, isUIEvent, parseOrigin, sanitizeToken, validateConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -171,6 +171,8 @@ declare const FieldEventType: {
|
|
|
171
171
|
readonly FIELD_VALIDATION: "FIELD_VALIDATION";
|
|
172
172
|
readonly FIELD_SUBMIT_RESULT: "FIELD_SUBMIT_RESULT";
|
|
173
173
|
readonly FIELD_HEIGHT: "FIELD_HEIGHT";
|
|
174
|
+
readonly FIELD_THREE_DS_REQUIRED: "FIELD_THREE_DS_REQUIRED";
|
|
175
|
+
readonly FIELD_THREE_DS_RESULT: "FIELD_THREE_DS_RESULT";
|
|
174
176
|
};
|
|
175
177
|
type TFieldEventType = (typeof FieldEventType)[keyof typeof FieldEventType];
|
|
176
178
|
interface FieldOptions {
|
|
@@ -200,8 +202,31 @@ interface FieldsValidationResult {
|
|
|
200
202
|
isValid: boolean;
|
|
201
203
|
errors: Partial<Record<TFieldType, string | null>>;
|
|
202
204
|
}
|
|
205
|
+
interface SubmitBillingAddress {
|
|
206
|
+
addressLine1?: string;
|
|
207
|
+
addressLine2?: string;
|
|
208
|
+
city?: string;
|
|
209
|
+
state?: string;
|
|
210
|
+
postalCode?: string;
|
|
211
|
+
country?: string;
|
|
212
|
+
}
|
|
203
213
|
interface SubmitOptions {
|
|
204
214
|
cardholderName?: string;
|
|
215
|
+
email?: string;
|
|
216
|
+
billingAddress?: SubmitBillingAddress;
|
|
217
|
+
}
|
|
218
|
+
interface ExpressCapability {
|
|
219
|
+
applePay: boolean;
|
|
220
|
+
googlePay: boolean;
|
|
221
|
+
paypal: boolean;
|
|
222
|
+
}
|
|
223
|
+
interface ExpressAttempt {
|
|
224
|
+
event: TPaymentAttemptResult;
|
|
225
|
+
method: TPaymentMethod;
|
|
226
|
+
paymentId?: string;
|
|
227
|
+
code?: string;
|
|
228
|
+
message?: string;
|
|
229
|
+
timestamp: number;
|
|
205
230
|
}
|
|
206
231
|
interface FlintNFieldsConfig {
|
|
207
232
|
clientSessionId: string;
|
|
@@ -247,9 +272,144 @@ interface FlintNField {
|
|
|
247
272
|
}
|
|
248
273
|
declare function createFlintNField(fieldType: TFieldType, origin: string, clientSessionId: string, options: FieldOptions, callbacks: FlintNFieldInternalCallbacks, debug?: boolean, formStyles?: FormStyles): FlintNField;
|
|
249
274
|
|
|
275
|
+
declare const EXPRESS_BUTTON_HEIGHT = 40;
|
|
276
|
+
declare const ExpressMethod: {
|
|
277
|
+
readonly APPLE_PAY: "APPLE_PAY";
|
|
278
|
+
readonly GOOGLE_PAY: "GOOGLE_PAY";
|
|
279
|
+
readonly PAYPAL: "PAYPAL";
|
|
280
|
+
};
|
|
281
|
+
type TExpressMethod = (typeof ExpressMethod)[keyof typeof ExpressMethod];
|
|
282
|
+
/** One entry per wallet button: which method goes into which element. */
|
|
283
|
+
interface ExpressButtonMount {
|
|
284
|
+
method: TExpressMethod;
|
|
285
|
+
/** CSS selector or the element itself. The button fills the element. */
|
|
286
|
+
elementSelector: string | HTMLElement;
|
|
287
|
+
}
|
|
288
|
+
interface FlintNExpressButtonsOptions {
|
|
289
|
+
config: {
|
|
290
|
+
clientSessionId: string;
|
|
291
|
+
};
|
|
292
|
+
origin?: string;
|
|
293
|
+
apiUrl?: string;
|
|
294
|
+
buttonBorderRadius?: number;
|
|
295
|
+
onPayment?: (result: PaymentResult) => void;
|
|
296
|
+
onEvent?: (event: ExpressAttempt) => void;
|
|
297
|
+
onCapability?: (capability: ExpressCapability) => void;
|
|
298
|
+
onError?: (error: PaymentError) => void;
|
|
299
|
+
debug?: boolean;
|
|
300
|
+
}
|
|
301
|
+
interface FlintNExpressButtons {
|
|
302
|
+
mountExpressButtons(buttons: ExpressButtonMount[]): Promise<void>;
|
|
303
|
+
unmountExpressButton(method: TExpressMethod): void;
|
|
304
|
+
unmountAllExpressButtons(): void;
|
|
305
|
+
}
|
|
306
|
+
interface ApplePayConfig {
|
|
307
|
+
country_code: string;
|
|
308
|
+
supported_networks: string[];
|
|
309
|
+
merchant_capabilities: string[];
|
|
310
|
+
display_name: string;
|
|
311
|
+
merchant_identifier?: string;
|
|
312
|
+
}
|
|
313
|
+
interface GooglePayConfig {
|
|
314
|
+
environment: string;
|
|
315
|
+
gateway: string;
|
|
316
|
+
gateway_merchant_id: string;
|
|
317
|
+
merchant_id?: string;
|
|
318
|
+
merchant_name?: string;
|
|
319
|
+
country_code?: string;
|
|
320
|
+
}
|
|
321
|
+
interface PayPalConfig {
|
|
322
|
+
client_id: string;
|
|
323
|
+
merchant_id?: string;
|
|
324
|
+
}
|
|
325
|
+
interface SessionConfig {
|
|
326
|
+
session: {
|
|
327
|
+
amount: number;
|
|
328
|
+
currency_code: string;
|
|
329
|
+
};
|
|
330
|
+
payment_methods: string[];
|
|
331
|
+
apple_pay_config?: ApplePayConfig;
|
|
332
|
+
google_pay_config?: GooglePayConfig;
|
|
333
|
+
paypal_config?: PayPalConfig;
|
|
334
|
+
}
|
|
335
|
+
declare const AuthorizedStatus: {
|
|
336
|
+
readonly PENDING: "PENDING";
|
|
337
|
+
readonly AUTHORIZED: "AUTHORIZED";
|
|
338
|
+
readonly FAILED: "FAILED";
|
|
339
|
+
readonly DECLINED: "DECLINED";
|
|
340
|
+
readonly THREE_DS_INITIATED: "THREE_DS_INITIATED";
|
|
341
|
+
};
|
|
342
|
+
type TAuthorizedStatus = (typeof AuthorizedStatus)[keyof typeof AuthorizedStatus];
|
|
343
|
+
interface AuthorizeResponse {
|
|
344
|
+
id: string;
|
|
345
|
+
status: TAuthorizedStatus;
|
|
346
|
+
required_action?: {
|
|
347
|
+
type: string;
|
|
348
|
+
redirect_url: string;
|
|
349
|
+
};
|
|
350
|
+
status_reason?: {
|
|
351
|
+
decline_reason?: string;
|
|
352
|
+
message?: string;
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
interface ApplePayToken {
|
|
356
|
+
payment_data: {
|
|
357
|
+
data: string;
|
|
358
|
+
header: {
|
|
359
|
+
ephemeral_public_key: string;
|
|
360
|
+
public_key_hash: string;
|
|
361
|
+
transaction_id: string;
|
|
362
|
+
};
|
|
363
|
+
signature: string;
|
|
364
|
+
version: string;
|
|
365
|
+
};
|
|
366
|
+
payment_method: {
|
|
367
|
+
display_name: string;
|
|
368
|
+
network: string;
|
|
369
|
+
type: string;
|
|
370
|
+
};
|
|
371
|
+
transaction_identifier: string;
|
|
372
|
+
}
|
|
373
|
+
interface GooglePayToken {
|
|
374
|
+
token: string;
|
|
375
|
+
}
|
|
376
|
+
/** Terminal-ish callbacks the wallet flows report into (mirrors the iframe's ExpressAuthorizeHandlers). */
|
|
377
|
+
interface WalletAuthorizeHandlers {
|
|
378
|
+
onAuthorized: (paymentId: string) => void;
|
|
379
|
+
onThreeDs: (redirectUrl: string, paymentId: string) => void;
|
|
380
|
+
onFailed: (code: string, message: string, paymentId?: string) => void;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Express fast-checkout buttons (Apple Pay / Google Pay / PayPal) rendered
|
|
385
|
+
* DIRECTLY into the merchant's DOM — one element per wallet, Yuno-style.
|
|
386
|
+
* There is no iframe: wallet SDKs load on the merchant page, wallet UI
|
|
387
|
+
* (Apple Pay QR modal, payment sheets) overlays the page natively, and the
|
|
388
|
+
* page's own layout sizes the buttons. Only encrypted wallet tokens pass
|
|
389
|
+
* through the page; they are authorized against the session-scoped payments
|
|
390
|
+
* API (no API key in the browser).
|
|
391
|
+
*/
|
|
392
|
+
declare function createFlintNExpressButtons(options: FlintNExpressButtonsOptions): FlintNExpressButtons;
|
|
393
|
+
|
|
394
|
+
declare const deriveApiUrl: (payOrigin: string) => string;
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Per-instance express options; session/origin/onPayment come from the fields
|
|
398
|
+
* instance, and button styling comes from `config.styles`
|
|
399
|
+
* (expressButtonsBorderRadius).
|
|
400
|
+
*/
|
|
401
|
+
type ExpressButtonsOptions = Pick<FlintNExpressButtonsOptions, 'apiUrl' | 'onEvent' | 'onCapability'>;
|
|
250
402
|
interface FlintNFields {
|
|
251
403
|
createField(fieldType: TFieldType, options?: FieldOptions): FlintNField;
|
|
252
404
|
getField(fieldType: TFieldType): FlintNField | undefined;
|
|
405
|
+
/**
|
|
406
|
+
* Create the express fast-checkout buttons (Apple Pay / Google Pay /
|
|
407
|
+
* PayPal), rendered directly into merchant-owned elements (one per wallet —
|
|
408
|
+
* see `mountExpressButtons`). Terminal results flow through the same
|
|
409
|
+
* `onPayment` callback as the card `submit()`; per-attempt analytics and
|
|
410
|
+
* capability flags are delivered via the options passed here.
|
|
411
|
+
*/
|
|
412
|
+
createExpressButtons(options?: ExpressButtonsOptions): FlintNExpressButtons;
|
|
253
413
|
validate(): Promise<FieldsValidationResult>;
|
|
254
414
|
submit(options?: SubmitOptions, skipValidation?: boolean): Promise<PaymentResult>;
|
|
255
415
|
unmount(): void;
|
|
@@ -265,4 +425,4 @@ declare const validateConfig: (config: {
|
|
|
265
425
|
}) => void;
|
|
266
426
|
declare const sanitizeToken: (token: string) => string;
|
|
267
427
|
|
|
268
|
-
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 FormPlaceholders, 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 };
|
|
428
|
+
export { type ApplePayConfig, type ApplePayToken, type AuthorizeResponse, AuthorizedStatus, type CheckoutEvent, CheckoutFormVariant, CheckoutView, EXPRESS_BUTTON_HEIGHT, EventType, type ExpressAttempt, type ExpressButtonMount, type ExpressButtonsOptions, type ExpressCapability, ExpressMethod, type FieldChangeEvent, FieldEventType, type FieldOptions, type FieldState, FieldType, type FieldValidationResult, type FieldsValidationResult, type FlintNConfig, type FlintNExpressButtons, type FlintNExpressButtonsOptions, type FlintNField, type FlintNFieldInternalCallbacks, type FlintNFields, type FlintNFieldsConfig, type FlintNFieldsOptions, type FlintNPayment, type FlintNPaymentOptions, type FormFields, type FormPlaceholders, type FormStyles, type GooglePayConfig, type GooglePayToken, type PayPalConfig, type PaymentAttempt, PaymentAttemptResult, type PaymentError, PaymentMethod, type PaymentResult, type PaymentUI, PaymentUIEvent, type SessionConfig, type SubmitBillingAddress, type SubmitOptions, type TAuthorizedStatus, type TCheckoutFormVariant, type TCheckoutView, type TEventType, type TExpressMethod, type TFieldEventType, type TFieldType, type TPaymentAttemptResult, type TPaymentMethod, type TPaymentUIEvent, type WalletAuthorizeHandlers, buildIframeSrc, createFlintNExpressButtons, createFlintNField, createFlintNFields, createFlintNPayment, createIframeElement, deriveApiUrl, isAttemptEvent, isUIEvent, parseOrigin, sanitizeToken, validateConfig };
|