@primer-io/primer-js 0.3.7 → 0.3.8

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.
@@ -288,6 +288,10 @@ export type CardFormComponentProps = {
288
288
  clientOptions?: ClientOptionsContextType;
289
289
  /** Headless utils for accessing server configuration */
290
290
  headlessUtils?: HeadlessUtilsContextType;
291
+ /** Analytics utils for sending analytics events */
292
+ analyticsUtils?: AnalyticsContextType;
293
+ /** Events controller from context for receiving forwarded events */
294
+ contextEventsController?: EventsContextType;
291
295
  /** Determines whether to show the cardholder name field
292
296
  Uses client configuration with fallback to default (true) */
293
297
  shouldShowCardholderName?: boolean;
@@ -347,6 +351,8 @@ export type PaymentMethodComponentProps = {
347
351
  disabled?: boolean;
348
352
  /** */
349
353
  paymentMethods?: PaymentMethodsContextType;
354
+ /** Analytics utils for sending analytics events */
355
+ analyticsUtils?: AnalyticsContextType;
350
356
  };
351
357
 
352
358
  export type PaymentMethodContainerComponentProps = {
@@ -450,6 +456,10 @@ Falls back to localized default if not explicitly set. */
450
456
  variant?: string;
451
457
  /** Whether the button is disabled. */
452
458
  disabled?: boolean;
459
+ /** */
460
+ analyticsUtils?: AnalyticsContextType;
461
+ /** */
462
+ contextEventsController?: EventsContextType;
453
463
  };
454
464
 
455
465
  export type CardNetworkSelectorComponentProps = {
@@ -944,7 +954,11 @@ export type CustomElements = {
944
954
 
945
955
  /**
946
956
  * A form submit button component for card forms.
947
- * Provides a consistent submit button with translation support.
957
+ *
958
+ * Provides a consistent submit button with translation support and configurable visibility.
959
+ * When `submitButton.useBuiltInButton` is set to `false`, the component will not render
960
+ * any DOM elements, allowing external buttons to handle form submission by dispatching
961
+ * the `primer:card-submit` event.
948
962
  * ---
949
963
  *
950
964
  */
@@ -747,6 +747,14 @@ export interface VaultData {
747
747
  customerId: string;
748
748
  }
749
749
  type EventListener$1 = (event?: Event) => void;
750
+ export interface AnalyticsUtils {
751
+ environment: string;
752
+ primerAccountId?: string;
753
+ checkoutSessionId: string;
754
+ clientSessionId?: string;
755
+ clientSessionToken?: string;
756
+ sdkVersion?: string;
757
+ }
750
758
  export interface PrimerHeadlessCheckout {
751
759
  createPaymentMethodManager(type: "PAYMENT_CARD", options?: PaymentMethodManagerOptions): Promise<ICardPaymentMethodManager | null>;
752
760
  createPaymentMethodManager(type: "PAYPAL" | "GOOGLE_PAY" | "APPLE_PAY", options?: PaymentMethodManagerOptions): Promise<INativePaymentMethodManager | null>;
@@ -755,6 +763,7 @@ export interface PrimerHeadlessCheckout {
755
763
  createPaymentMethodManager(type: PaymentMethodType, options?: PaymentMethodManagerOptions): Promise<IRedirectPaymentMethodManager | null>;
756
764
  createVaultManager(): HeadlessVaultManager;
757
765
  getSDKUtilities(): HeadlessSDKUtilities;
766
+ getAnalyticsUtils?: () => AnalyticsUtils;
758
767
  configure?: (options: Omit<HeadlessUniversalCheckoutOptions, "clientSessionCachingEnabled">) => void;
759
768
  getAssetsManager(): IAssetsManager;
760
769
  start: () => Promise<void>;
@@ -937,6 +946,13 @@ export interface PrimerCheckoutOptions {
937
946
  clientToken?: string;
938
947
  locale?: string;
939
948
  apiVersion?: APIVersionOption;
949
+ /**
950
+ * Specifies the merchant's domain for Apple Pay domain validation.
951
+ * If not provided, defaults to window.location.hostname.
952
+ * This is particularly useful when the checkout is hosted on a different domain
953
+ * than the merchant's registered Apple Pay domain.
954
+ */
955
+ merchantDomain?: string;
940
956
  card?: {
941
957
  cardholderName?: {
942
958
  required?: boolean;
@@ -971,8 +987,40 @@ export interface PrimerCheckoutOptions {
971
987
  };
972
988
  publishableKey?: string;
973
989
  } & Record<string, unknown>;
990
+ /**
991
+ * Configuration for the submit button behavior in Primer.js components.
992
+ */
974
993
  submitButton?: {
994
+ /**
995
+ * Whether to show the order amount on the submit button.
996
+ * When true, displays formatted amount next to button text (e.g., "Pay $12.34").
997
+ * @default false
998
+ */
975
999
  amountVisible?: boolean;
1000
+ /**
1001
+ * Whether to render the built-in submit button component.
1002
+ *
1003
+ * When `true` (default): The component renders the standard Primer submit button.
1004
+ * When `false`: No DOM elements are created, allowing external buttons to handle
1005
+ * form submission by dispatching the 'primer:card-submit' event.
1006
+ *
1007
+ * @example
1008
+ * // Hide built-in button and use external button
1009
+ * const options = {
1010
+ * submitButton: {
1011
+ * useBuiltInButton: false
1012
+ * }
1013
+ * };
1014
+ *
1015
+ * // External button should dispatch this event to submit
1016
+ * const submitEvent = new CustomEvent('primer:card-submit', {
1017
+ * bubbles: true,
1018
+ * composed: true
1019
+ * });
1020
+ *
1021
+ * @default true
1022
+ */
1023
+ useBuiltInButton?: boolean;
976
1024
  };
977
1025
  sdkCore?: boolean;
978
1026
  disabledPayments?: boolean;
@@ -1104,11 +1152,18 @@ export declare class PrimerJS {
1104
1152
  */
1105
1153
  handlePaymentFailure(error: PrimerClientError, payment?: Payment): void;
1106
1154
  }
1155
+ export interface CardSubmitResult {
1156
+ success?: boolean;
1157
+ token?: string;
1158
+ analyticsId?: string;
1159
+ paymentId?: string;
1160
+ [key: string]: unknown;
1161
+ }
1107
1162
  export interface CardSubmitSuccessPayload {
1108
- result: unknown;
1163
+ result: CardSubmitResult;
1109
1164
  }
1110
1165
  export interface CardSubmitErrorsPayload {
1111
- errors: unknown;
1166
+ errors: InputValidationError[];
1112
1167
  }
1113
1168
  export interface CardSubmitPayload {
1114
1169
  source?: string;
@@ -1146,9 +1201,19 @@ declare class PrimerEventsController implements ReactiveController {
1146
1201
  dispatchCheckoutInitialized(checkoutInstance: PrimerJS): void;
1147
1202
  dispatchCardNetworkChange(network: CardNetworksContextType): void;
1148
1203
  dispatchCardSubmit(source?: string): void;
1149
- dispatchFormSubmitSuccess(result: unknown): void;
1150
- dispatchFormSubmitErrors(errors: unknown): void;
1204
+ dispatchFormSubmitSuccess(result: CardSubmitResult): void;
1205
+ dispatchFormSubmitErrors(errors: InputValidationError[]): void;
1206
+ /**
1207
+ * Handle external card submit events and forward them through the event system.
1208
+ * This method provides a centralized way to process external card submission events
1209
+ * that come from custom buttons or external triggers.
1210
+ *
1211
+ * @param eventDetails - The event details to forward, including source information
1212
+ */
1213
+ handleExternalCardSubmit(eventDetails: CardSubmitPayload): void;
1151
1214
  }
1215
+ export type AnalyticsContextType = AnalyticsUtils | null;
1216
+ export type EventsContextType = PrimerEventsController | null;
1152
1217
  export type HeadlessUtilsContextType = HeadlessSDKUtilities | null;
1153
1218
  export type KlarnaCategoriesContextType = {
1154
1219
  categories: KlarnaPaymentMethodCategory[];
@@ -1291,6 +1356,8 @@ declare class SDKContextController implements ReactiveController {
1291
1356
  private headlessUtilsProvider;
1292
1357
  private klarnaCategoriesProvider;
1293
1358
  private computedStylesProvider;
1359
+ private analyticsProvider;
1360
+ private eventsProvider;
1294
1361
  constructor(host: PrimerCheckoutType);
1295
1362
  hostConnected(): void;
1296
1363
  /**
@@ -1313,8 +1380,15 @@ declare class SDKContextController implements ReactiveController {
1313
1380
  setKlarnaCategories(value: KlarnaCategoriesContextType): void;
1314
1381
  setClientOptions(value: PrimerCheckoutOptions | null): void;
1315
1382
  setHeadlessUtils(value: HeadlessUtilsContextType): void;
1383
+ setAnalyticsUtils(value: AnalyticsContextType): void;
1384
+ getAnalyticsUtils(): AnalyticsContextType | undefined;
1316
1385
  setComputedStyles(value: CSSStyleDeclaration): void;
1317
1386
  setVaultManagerCvv(value: VaultItemContextType): void;
1387
+ /**
1388
+ * Updates the events context.
1389
+ * @param value The new events controller.
1390
+ */
1391
+ setEventsController(value: EventsContextType): void;
1318
1392
  }
1319
1393
  export type SdkStateAction = {
1320
1394
  type: "START_PROCESSING";
@@ -1541,6 +1615,7 @@ export declare class PrimerCheckoutComponent extends LitElement implements Prime
1541
1615
  private previousLoadingState;
1542
1616
  private hasAssignedContent;
1543
1617
  private _loadingTimeoutId;
1618
+ private _eventListenerController;
1544
1619
  locale?: LocaleCode;
1545
1620
  private onSlotChange;
1546
1621
  sdkContextController: SDKContextController;
@@ -1551,10 +1626,16 @@ export declare class PrimerCheckoutComponent extends LitElement implements Prime
1551
1626
  cardNetworkController: CardNetworkController;
1552
1627
  achPaymentEventsController: AchPaymentEventsController;
1553
1628
  constructor();
1629
+ connectedCallback(): void;
1554
1630
  attributeChangedCallback(attrName: string, oldVal: string, newVal: string): void;
1555
1631
  disconnectedCallback(): void;
1556
1632
  willUpdate(changedProperties: PropertyValues): void;
1557
1633
  updated(): void;
1634
+ /**
1635
+ * Handle external primer:card-submit events by forwarding them through the events controller
1636
+ * Uses AbortController signal to prevent circular event loops more safely
1637
+ */
1638
+ private handleExternalCardSubmit;
1558
1639
  /**
1559
1640
  * Check if the loading state has changed and update the CSS loader visibility accordingly.
1560
1641
  * This method is called after each update cycle to detect when loading is complete.
@@ -2114,6 +2195,20 @@ declare class PaymentMethodComponent extends LitElement {
2114
2195
  type: PaymentMethodType | undefined;
2115
2196
  disabled: boolean;
2116
2197
  paymentMethods: PaymentMethodsContextType;
2198
+ /**
2199
+ * Analytics utils for sending analytics events
2200
+ */
2201
+ analyticsUtils: AnalyticsContextType;
2202
+ /**
2203
+ * Sends PAYMENT_METHOD_SELECTION analytics event when user clicks on payment method
2204
+ * @private
2205
+ */
2206
+ private sendPaymentMethodSelectionEvent;
2207
+ /**
2208
+ * Handle interaction events on payment method component
2209
+ * @private
2210
+ */
2211
+ private handleClick;
2117
2212
  render(): typeof nothing | import("lit-html").TemplateResult<1>;
2118
2213
  }
2119
2214
  declare global {
@@ -2186,7 +2281,7 @@ declare class AchPaymentComponent extends LitElement {
2186
2281
  private _handleDeclineMandate;
2187
2282
  private renderForm;
2188
2283
  private renderMandate;
2189
- render(): TemplateResult | typeof nothing | undefined;
2284
+ render(): typeof nothing | TemplateResult | undefined;
2190
2285
  }
2191
2286
  declare global {
2192
2287
  interface HTMLElementTagNameMap {
@@ -2728,6 +2823,11 @@ declare class CardFormComponent extends LitElement {
2728
2823
  */
2729
2824
  private hasAssignedContent;
2730
2825
  private selectedCardNetwork;
2826
+ /**
2827
+ * Flag to track if PAYMENT_METHOD_SELECTION event has been sent
2828
+ * @private
2829
+ */
2830
+ private paymentMethodSelectionSent;
2731
2831
  /**
2732
2832
  * Payment managers injected from context
2733
2833
  */
@@ -2740,6 +2840,14 @@ declare class CardFormComponent extends LitElement {
2740
2840
  * Headless utils for accessing server configuration
2741
2841
  */
2742
2842
  headlessUtils: HeadlessUtilsContextType;
2843
+ /**
2844
+ * Analytics utils for sending analytics events
2845
+ */
2846
+ analyticsUtils: AnalyticsContextType;
2847
+ /**
2848
+ * Events controller from context for receiving forwarded events
2849
+ */
2850
+ contextEventsController: EventsContextType;
2743
2851
  /**
2744
2852
  * Context provider for card form data
2745
2853
  */
@@ -2758,6 +2866,14 @@ declare class CardFormComponent extends LitElement {
2758
2866
  * Events controller for dispatching form events
2759
2867
  */
2760
2868
  private readonly eventsController;
2869
+ /**
2870
+ * External event listener reference for cleanup
2871
+ */
2872
+ private _contextCardSubmitListener;
2873
+ /**
2874
+ * Flag to prevent circular event loop when handling events
2875
+ */
2876
+ private _isHandlingContextEvent;
2761
2877
  /**
2762
2878
  * Registry for input controllers to enable context-driven meta state management
2763
2879
  */
@@ -2766,6 +2882,22 @@ declare class CardFormComponent extends LitElement {
2766
2882
  * Task to set up the card form with hosted inputs
2767
2883
  */
2768
2884
  private readonly setupCardFormTask;
2885
+ /**
2886
+ * Sends PAYMENT_METHOD_SELECTION analytics event when user first interacts with card form
2887
+ * @private
2888
+ */
2889
+ private sendPaymentMethodSelectionEvent;
2890
+ /**
2891
+ * Checks if all required fields are filled and sends PAYMENT_DETAILS_ENTERED event
2892
+ * @private
2893
+ */
2894
+ private checkAndSendPaymentDetailsEnteredEvent;
2895
+ private paymentDetailsEnteredSent;
2896
+ /**
2897
+ * Sends PAYMENT_DETAILS_ENTERED analytics event when all payment details are complete and valid
2898
+ * @private
2899
+ */
2900
+ private sendPaymentDetailsEnteredEvent;
2769
2901
  connectedCallback(): void;
2770
2902
  disconnectedCallback(): void;
2771
2903
  /**
@@ -2778,6 +2910,19 @@ declare class CardFormComponent extends LitElement {
2778
2910
  * This is a backup method to catch all possible submission events
2779
2911
  */
2780
2912
  private handleDirectSubmit;
2913
+ /**
2914
+ * Sets up event listeners for context-forwarded events
2915
+ */
2916
+ private setupContextEventListeners;
2917
+ /**
2918
+ * Cleans up context event listeners
2919
+ */
2920
+ private cleanupContextEventListeners;
2921
+ /**
2922
+ * Handles primer:card-submit events received from the events context
2923
+ * This allows the card form to respond to external submit triggers
2924
+ */
2925
+ private handleContextCardSubmit;
2781
2926
  /**
2782
2927
  * Determines if a button is a submit button based on its attributes
2783
2928
  */
@@ -2853,6 +2998,11 @@ declare class HostedInputController<T extends HostedInputHost> implements Reacti
2853
2998
  * Focuses the input, whether it's a hosted input or standard input
2854
2999
  */
2855
3000
  focusInput(): void;
3001
+ /**
3002
+ * Notifies the card form context about user interaction for analytics tracking
3003
+ * @private
3004
+ */
3005
+ private notifyUserInteraction;
2856
3006
  /**
2857
3007
  * Returns the hosted input from the card form context based on the type.
2858
3008
  * For 'cardholderName', no hosted input is provided so we return a fallback indicator.
@@ -2942,6 +3092,7 @@ export interface CardFormContext {
2942
3092
  propagateValidationErrors: (errors: InputValidationError[]) => void;
2943
3093
  registerInputController: (inputType: HostedInputType, controller: IHostedInputController) => void;
2944
3094
  unregisterInputController: (inputType: HostedInputType) => void;
3095
+ onUserInteraction: () => void;
2945
3096
  }
2946
3097
  /**
2947
3098
  * Translation configuration object
@@ -3091,7 +3242,28 @@ declare global {
3091
3242
  }
3092
3243
  /**
3093
3244
  * A form submit button component for card forms.
3094
- * Provides a consistent submit button with translation support.
3245
+ *
3246
+ * Provides a consistent submit button with translation support and configurable visibility.
3247
+ * When `submitButton.useBuiltInButton` is set to `false`, the component will not render
3248
+ * any DOM elements, allowing external buttons to handle form submission by dispatching
3249
+ * the `primer:card-submit` event.
3250
+ *
3251
+ * @example
3252
+ * // Default behavior - renders the built-in submit button
3253
+ * <primer-card-form-submit></primer-card-form-submit>
3254
+ *
3255
+ * @example
3256
+ * // External button integration - hides the built-in button
3257
+ * // Configure with submitButton.useBuiltInButton: false
3258
+ * // External button should dispatch 'primer:card-submit' event
3259
+ * const externalButton = document.getElementById('my-button');
3260
+ * externalButton.addEventListener('click', () => {
3261
+ * const submitEvent = new CustomEvent('primer:card-submit', {
3262
+ * bubbles: true,
3263
+ * composed: true
3264
+ * });
3265
+ * document.querySelector('primer-card-form-submit').dispatchEvent(submitEvent);
3266
+ * });
3095
3267
  */
3096
3268
  declare class CardFormSubmitComponent extends LitElement {
3097
3269
  static styles: import("lit").CSSResult[];
@@ -3107,6 +3279,8 @@ declare class CardFormSubmitComponent extends LitElement {
3107
3279
  clientOptions: ClientOptionsContextType;
3108
3280
  sdkState: SdkStateContextType;
3109
3281
  cardFormContext: CardFormContext | null;
3282
+ analyticsUtils: AnalyticsContextType;
3283
+ contextEventsController: EventsContextType;
3110
3284
  /**
3111
3285
  * The button variant to use.
3112
3286
  * @default "primary"
@@ -3117,8 +3291,19 @@ declare class CardFormSubmitComponent extends LitElement {
3117
3291
  * @default false
3118
3292
  */
3119
3293
  disabled: boolean;
3294
+ /**
3295
+ * Gets the submit button configuration from client options.
3296
+ * Returns the configuration object or null if not set.
3297
+ */
3298
+ private get submitButtonConfig();
3299
+ /**
3300
+ * Determines if the built-in submit button should be rendered.
3301
+ * When false, no DOM elements are created allowing external button integration.
3302
+ * @returns true if the built-in button should be shown, false otherwise
3303
+ */
3304
+ private get shouldShowBuiltInButton();
3120
3305
  private handleClick;
3121
- render(): import("lit-html").TemplateResult<1>;
3306
+ render(): typeof nothing | import("lit-html").TemplateResult<1>;
3122
3307
  }
3123
3308
  declare global {
3124
3309
  interface HTMLElementTagNameMap {