@starfish-codes/hellgate 3.8.1 → 3.9.1

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.
Files changed (31) hide show
  1. package/dist/3ds/typings.d.ts +1 -0
  2. package/dist/__tests__/test-utils.d.ts +11 -0
  3. package/dist/card/card-handler.d.ts +30 -8
  4. package/dist/card/coordinator/card-handler-coordinator.d.ts +34 -0
  5. package/dist/card/coordinator/index.d.ts +2 -0
  6. package/dist/card/coordinator/typings.d.ts +36 -0
  7. package/dist/card/typings.d.ts +14 -3
  8. package/dist/card/ui/elements/base-element.d.ts +3 -3
  9. package/dist/card/ui/elements/card-expiration-month.d.ts +9 -0
  10. package/dist/card/ui/elements/card-expiration-year.d.ts +9 -0
  11. package/dist/card/ui/elements/utils.d.ts +5 -2
  12. package/dist/card/ui/iframe/elements/base-element.d.ts +3 -2
  13. package/dist/card/ui/iframe/elements/card-expiration-month.d.ts +10 -0
  14. package/dist/card/ui/iframe/elements/card-expiration-year.d.ts +9 -0
  15. package/dist/card/ui/iframe/elements/text-element.d.ts +1 -0
  16. package/dist/card/ui/iframe/index.d.ts +1 -0
  17. package/dist/card/ui/iframe/utils.d.ts +1 -0
  18. package/dist/card/ui/typings.d.ts +10 -6
  19. package/dist/coordinator/coordinator.d.ts +38 -0
  20. package/dist/coordinator/iframe/constants.d.ts +1 -0
  21. package/dist/coordinator/iframe/iframe-coordinator.d.ts +33 -0
  22. package/dist/coordinator/iframe/iframe.d.ts +1 -0
  23. package/dist/coordinator/iframe/index.d.ts +2 -0
  24. package/dist/coordinator/index.d.ts +3 -0
  25. package/dist/coordinator/typings.d.ts +39 -0
  26. package/dist/hellgate-sdk.mjs +515 -1132
  27. package/dist/hellgate-sdk.umd.js +1 -1
  28. package/dist/hellgate.d.ts +5 -2
  29. package/dist/session/session.d.ts +1 -1
  30. package/dist/utils.d.ts +1 -0
  31. package/package.json +6 -5
@@ -26,6 +26,7 @@ export type Do3DSChallengeActionDTO = {
26
26
  action: '3ds_challenge';
27
27
  result: {
28
28
  requestor_trans_id: string;
29
+ requestorTransId?: string;
29
30
  event: string;
30
31
  param?: string;
31
32
  };
@@ -1,2 +1,13 @@
1
1
  export declare function wait(milliseconds: number): Promise<void>;
2
2
  export declare function fill(input: HTMLInputElement, value: string): void;
3
+ export declare const HELLGATE_BASE_URL: string;
4
+ type CreateHellgateSessionParams = {
5
+ bypass_identification?: boolean;
6
+ };
7
+ export declare function createHellgateSession(params: CreateHellgateSessionParams): Promise<{
8
+ session_id: string;
9
+ }>;
10
+ export declare function refreshHellgateSession(): Promise<{
11
+ session_id: string;
12
+ }>;
13
+ export {};
@@ -1,20 +1,43 @@
1
1
  import { CompleteActionResult, HellgateSession } from '../session';
2
+ import { Coordinator } from '../coordinator';
2
3
  import { CreateCardFieldsOptions, CreateCardFormOptions, PaymentAdditionalData, RefreshSecurityCodeSessionStateDTO, TokenizeCardSessionStateDTO, TokenizedData } from './typings';
3
4
  import { CardElement, CardExpirationDateElement, CardNumberElement, CardVerificationCodeElement, TextElement } from './ui/elements';
5
+ import { CardElementBase } from './ui/elements/base-element';
6
+ import { CardExpirationMonthElement } from './ui/elements/card-expiration-month';
7
+ import { CardExpirationYearElement } from './ui/elements/card-expiration-year';
4
8
  import { ChangeEvent, ElementBaseOptions } from './ui/typings';
5
- export type FormFieldState = Omit<ChangeEvent<never>['data'], 'type'>;
9
+ export type FormFieldState = Omit<ChangeEvent['data'], 'type'>;
6
10
  export type CardHandlerSessionInitState = TokenizeCardSessionStateDTO | RefreshSecurityCodeSessionStateDTO;
11
+ type FormField<T extends CardElementBase<any, any>> = {
12
+ element: T;
13
+ state: FormFieldState;
14
+ };
15
+ type ElementsMap = {
16
+ card: FormField<CardElement>;
17
+ cardNumber: FormField<CardNumberElement>;
18
+ cardExpirationDate: FormField<CardExpirationDateElement>;
19
+ cardExpirationMonth: FormField<CardExpirationMonthElement>;
20
+ cardExpirationYear: FormField<CardExpirationYearElement>;
21
+ cardVerificationCode: FormField<CardVerificationCodeElement>;
22
+ };
7
23
  export declare class HellgateCardHandler {
8
24
  session: HellgateSession<CardHandlerSessionInitState>;
25
+ private coordinator;
9
26
  state: FormFieldState;
10
- private cardElements;
27
+ cardElements: Partial<ElementsMap>;
11
28
  private textElements;
12
29
  private stateChangeHandlers;
13
30
  readonly cvcOnlyEnabled: boolean;
14
- static init(session: HellgateSession<CardHandlerSessionInitState>): Promise<HellgateCardHandler>;
15
- constructor(session: HellgateSession<CardHandlerSessionInitState>);
31
+ static init(session: HellgateSession<CardHandlerSessionInitState>, coordinator: Coordinator): Promise<HellgateCardHandler>;
32
+ constructor(session: HellgateSession<CardHandlerSessionInitState>, coordinator: Coordinator);
16
33
  createForm: (options?: CreateCardFormOptions) => CardElement;
17
- createFormFields: (options?: CreateCardFieldsOptions) => {
34
+ createFormFields(options: CreateCardFieldsOptions<'separate'>): {
35
+ cardNumber: CardNumberElement;
36
+ expiryMonth: CardExpirationMonthElement;
37
+ expiryYear: CardExpirationYearElement;
38
+ securityCode: CardVerificationCodeElement;
39
+ };
40
+ createFormFields(options: CreateCardFieldsOptions<'combined'>): {
18
41
  cardNumber: CardNumberElement;
19
42
  expiryDate: CardExpirationDateElement;
20
43
  securityCode: CardVerificationCodeElement;
@@ -27,13 +50,12 @@ export declare class HellgateCardHandler {
27
50
  dispose: () => void;
28
51
  process: (additionalData?: PaymentAdditionalData) => Promise<CompleteActionResult>;
29
52
  private refreshSecurityCode;
30
- private getFormValue;
31
53
  private hasFormElements;
32
54
  private disableFormElements;
33
- private extractAdditionalData;
34
- private encryptCardData;
35
55
  private addElementStateListener;
36
56
  updateFormState(): void;
37
57
  private createFieldDefaultState;
58
+ private serializeAdditionalData;
38
59
  private getCardDataValidationError;
39
60
  }
61
+ export {};
@@ -0,0 +1,34 @@
1
+ import { CompleteActionResult, HellgateSession } from '../../session';
2
+ import { FormFieldState } from '../card-handler';
3
+ import { PaymentAdditionalDataDTO, TokenizedData } from '../typings';
4
+ type FormField<Value = string> = {
5
+ value?: Value;
6
+ state: FormFieldState;
7
+ };
8
+ type ElementsMap = {
9
+ card: FormField<{
10
+ number: string;
11
+ expiry_date: string;
12
+ cvc: string;
13
+ }>;
14
+ cardNumber: FormField;
15
+ cardExpirationDate: FormField;
16
+ cardExpirationMonth: FormField;
17
+ cardExpirationYear: FormField;
18
+ cardVerificationCode: FormField;
19
+ } & Record<string, FormField>;
20
+ export declare class CardHandlerCoordinator {
21
+ private session;
22
+ private cardElements;
23
+ constructor(session: HellgateSession);
24
+ tokenize: (additionalData: PaymentAdditionalDataDTO) => Promise<TokenizedData>;
25
+ process: (additionalData?: PaymentAdditionalDataDTO) => Promise<CompleteActionResult>;
26
+ refreshSecurityCode(): Promise<CompleteActionResult>;
27
+ onElementChange: (key: keyof ElementsMap | string, data: FormFieldState) => void;
28
+ dispose(): void;
29
+ private getFormValue;
30
+ private extractAdditionalData;
31
+ private encryptCardData;
32
+ private extractAdditionalDataStringValue;
33
+ }
34
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from './card-handler-coordinator';
2
+ export * from './typings';
@@ -0,0 +1,36 @@
1
+ import { CompleteActionResult } from '../../session';
2
+ import { FormFieldState } from '../card-handler';
3
+ import { PaymentAdditionalDataDTO, TokenizedData } from '../typings';
4
+ export type CardHandlerToCoordinatorMessage = {
5
+ type: 'card:tokenize';
6
+ additionalData?: PaymentAdditionalDataDTO;
7
+ } | {
8
+ type: 'card:process';
9
+ additionalData?: PaymentAdditionalDataDTO;
10
+ } | {
11
+ type: 'card:refresh_security_code';
12
+ };
13
+ export type CoordinatorToCardHandlerMessage = {
14
+ type: 'card:tokenize:response';
15
+ success: boolean;
16
+ result: TokenizedData | null;
17
+ error?: string;
18
+ } | {
19
+ type: 'card:process:response';
20
+ success: boolean;
21
+ result: CompleteActionResult | null;
22
+ error?: string;
23
+ } | {
24
+ type: 'card:refresh_security_code:response';
25
+ success: boolean;
26
+ result: CompleteActionResult | null;
27
+ error?: string;
28
+ };
29
+ export type ElementToCoordinatorMessage = {
30
+ type: 'element:change';
31
+ data: {
32
+ element: string;
33
+ key: string;
34
+ state: FormFieldState;
35
+ };
36
+ };
@@ -6,13 +6,23 @@ export type CreateCardFormOptions = Pick<ElementBaseOptions, 'style' | 'disabled
6
6
  icon?: IconPosition;
7
7
  schemes?: CardSchema[];
8
8
  };
9
- export type CreateCardFieldsOptions = Pick<ElementBaseOptions, 'style' | 'disabled' | 'autocomplete'> & {
9
+ export type ExpiryDateElementType = 'combined' | 'separate';
10
+ export type CreateCardFieldsOptions<T extends ExpiryDateElementType = 'combined'> = Pick<ElementBaseOptions, 'style' | 'disabled' | 'autocomplete'> & {
10
11
  cardNumber?: ElementBaseOptions;
11
- expiryDate?: ElementBaseOptions;
12
12
  securityCode?: ElementBaseOptions;
13
13
  schemes?: CardSchema[];
14
- };
14
+ } & (T extends 'separate' ? {
15
+ expiryDateElement: 'separate';
16
+ expiryMonth?: ElementBaseOptions;
17
+ expiryYear?: ElementBaseOptions;
18
+ } : {
19
+ expiryDateElement?: 'combined';
20
+ expiryDate?: ElementBaseOptions;
21
+ });
15
22
  export type AdditionalDataValue = string | TextElement;
23
+ export type AdditionalDataValueDTO = string | {
24
+ key: string;
25
+ };
16
26
  export type PaymentAdditionalData<FieldValue = AdditionalDataValue> = {
17
27
  cardholder_name?: FieldValue;
18
28
  email?: FieldValue;
@@ -25,6 +35,7 @@ export type PaymentAdditionalData<FieldValue = AdditionalDataValue> = {
25
35
  country?: FieldValue;
26
36
  };
27
37
  };
38
+ export type PaymentAdditionalDataDTO = PaymentAdditionalData<AdditionalDataValueDTO>;
28
39
  export type ElementsCardData = {
29
40
  number: string | null;
30
41
  expiration_month: number | null;
@@ -8,15 +8,15 @@ export declare abstract class CardElementBase<Value, IframeValue = string> {
8
8
  protected abstract type: ElementType;
9
9
  protected abstract extractValue: (rawValue: IframeValue | null) => Value | null;
10
10
  protected abstract putValue: (rawValue: Value | null) => IframeValue | null;
11
- constructor(options: ElementBaseOptions<Value>, key?: string);
11
+ key: string;
12
+ constructor(options: ElementBaseOptions<Value>);
12
13
  mount(selector: string | Element): Promise<void>;
13
14
  update: ({ ...data }: ElementBaseOptions<Value>) => Promise<void>;
14
15
  clear: () => void;
15
16
  focus: () => void;
16
17
  blur: () => void;
17
18
  unmount: () => void;
18
- on<T extends EventType>(eventType: T, listener: (event: FindByType<Explicit<CardElementEvents<never>>, T>['data']) => void): Subscription;
19
- secureValue(key: string): Value | null;
19
+ on<T extends EventType>(eventType: T, listener: (event: FindByType<Explicit<CardElementEvents>, T>['data']) => void): Subscription;
20
20
  private emitEvent;
21
21
  private iframePostMessage;
22
22
  }
@@ -0,0 +1,9 @@
1
+ import { ElementType } from '../typings';
2
+ import { CardElementBase } from './base-element';
3
+ export declare class CardExpirationMonthElement extends CardElementBase<number> {
4
+ protected type: ElementType;
5
+ protected extractValue: typeof extractExpiryMonthValue;
6
+ protected putValue: typeof putExpiryMonthValue;
7
+ }
8
+ export declare function extractExpiryMonthValue(rawValue: string | null): number | null;
9
+ export declare function putExpiryMonthValue(rawValue: number | null): string | null;
@@ -0,0 +1,9 @@
1
+ import { ElementType } from '../typings';
2
+ import { CardElementBase } from './base-element';
3
+ export declare class CardExpirationYearElement extends CardElementBase<number> {
4
+ protected type: ElementType;
5
+ protected extractValue: typeof extractExpiryYearValue;
6
+ protected putValue: typeof putExpiryYearValue;
7
+ }
8
+ export declare function extractExpiryYearValue(rawValue: string | null): number | null;
9
+ export declare function putExpiryYearValue(rawValue: number | null): string | null;
@@ -1,6 +1,8 @@
1
1
  import { ElementBaseOptions } from '../typings';
2
2
  import { CardElement } from './card';
3
3
  import { CardExpirationDateElement } from './card-expiration-date';
4
+ import { CardExpirationMonthElement } from './card-expiration-month';
5
+ import { CardExpirationYearElement } from './card-expiration-year';
4
6
  import { CardNumberElement } from './card-number';
5
7
  import { CardVerificationCodeElement } from './card-verification-code';
6
8
  import { TextElement } from './text-element';
@@ -8,9 +10,10 @@ type Elements = {
8
10
  card: CardElement;
9
11
  cardNumber: CardNumberElement;
10
12
  cardExpirationDate: CardExpirationDateElement;
13
+ cardExpirationMonth: CardExpirationMonthElement;
14
+ cardExpirationYear: CardExpirationYearElement;
11
15
  cardVerificationCode: CardVerificationCodeElement;
12
16
  text: TextElement;
13
17
  };
14
- export declare function createElement<T extends keyof Elements>(type: T, options: ElementBaseOptions, key?: string): Elements[T];
15
- export declare function uid(): string;
18
+ export declare function createElement<T extends keyof Elements>(type: T, options: ElementBaseOptions): Elements[T];
16
19
  export {};
@@ -3,7 +3,6 @@ import { FactoryArg, InputMask, Masked } from 'imask';
3
3
  import { BaseElement, CardElementEvents, ElementBaseOptions, ElementEventListener, ElementMetadata, ElementType, EventType, Subscription } from '../../typings';
4
4
  export type PostMessageOptions = {
5
5
  postMessageOrigin: string;
6
- postMessageRoot: Window;
7
6
  };
8
7
  export declare abstract class IframeCardElementBase implements BaseElement<ElementBaseOptions, CardElementEvents<string>, string> {
9
8
  protected rootNode: Element;
@@ -16,9 +15,10 @@ export declare abstract class IframeCardElementBase implements BaseElement<Eleme
16
15
  protected abstract options: ElementBaseOptions;
17
16
  protected abstract inputMaskOptions: FactoryArg;
18
17
  protected inputMask?: InputMask<FactoryArg>;
19
- private id;
18
+ protected id: string;
20
19
  cardType?: CreditCardType;
21
20
  value: null;
21
+ private channel;
22
22
  constructor(rootNode: Element, postMessageOptions: PostMessageOptions);
23
23
  mount(): Promise<void>;
24
24
  unmount(): void;
@@ -29,6 +29,7 @@ export declare abstract class IframeCardElementBase implements BaseElement<Eleme
29
29
  updateState(): void;
30
30
  update(options: ElementBaseOptions): Promise<void>;
31
31
  on<T extends EventType>(eventType: T, listener: ElementEventListener<CardElementEvents<string>, T>): Subscription;
32
+ protected get key(): string;
32
33
  private emitEvent;
33
34
  protected validate(masked: Masked): ElementMetadata;
34
35
  protected renderHTML(): string;
@@ -0,0 +1,10 @@
1
+ import { FactoryArg, Masked } from 'imask';
2
+ import { ElementBaseOptions, ElementMetadata, ElementType, ITextElement } from '../../typings';
3
+ import { IframeCardElementBase } from './base-element';
4
+ export declare class IframeCardExpirationMonth extends IframeCardElementBase implements ITextElement {
5
+ readonly type: ElementType;
6
+ protected options: ElementBaseOptions;
7
+ compiledMask?: Masked;
8
+ protected inputMaskOptions: FactoryArg;
9
+ protected validate(masked: Masked): ElementMetadata;
10
+ }
@@ -0,0 +1,9 @@
1
+ import { FactoryArg, Masked } from 'imask';
2
+ import { ElementBaseOptions, ElementMetadata, ElementType, ITextElement } from '../../typings';
3
+ import { IframeCardElementBase } from './base-element';
4
+ export declare class IframeCardExpirationYear extends IframeCardElementBase implements ITextElement {
5
+ readonly type: ElementType;
6
+ protected options: ElementBaseOptions;
7
+ protected inputMaskOptions: FactoryArg;
8
+ protected validate(masked: Masked): ElementMetadata;
9
+ }
@@ -5,4 +5,5 @@ export declare class IframeTextElement extends IframeCardElementBase implements
5
5
  readonly type: ElementType;
6
6
  protected options: ElementBaseOptions;
7
7
  protected inputMaskOptions: FactoryArg;
8
+ protected get key(): string;
8
9
  }
@@ -1 +1,2 @@
1
1
  export * from './iframe';
2
+ export { parseURLSearchParams } from './utils';
@@ -21,4 +21,5 @@ export declare function generateElementId(type: ElementType): string;
21
21
  export declare function mergeOptions(options1: ElementBaseOptions, options2: ElementBaseOptions): ElementBaseOptions;
22
22
  export declare function mergeStyles(style1: ElementStyle, style2: ElementStyle): ElementStyle;
23
23
  export declare function applyStyle(id: string, { fonts, ...styles }: ElementStyle): void;
24
+ export declare function uid(): string;
24
25
  export {};
@@ -7,18 +7,21 @@ type EventType = 'ready' | 'change' | 'focus' | 'blur' | 'keydown';
7
7
  export declare const EVENT_TYPES: EventType[];
8
8
  type BaseEvent<T extends EventType, TData = unknown> = {
9
9
  type: T;
10
+ id: string;
10
11
  element: ElementType;
11
12
  } & (TData extends object ? {
12
13
  data: TData;
13
14
  } : unknown);
14
- type ReadyEvent = BaseEvent<'ready'>;
15
- type ChangeEvent<Value> = BaseEvent<'change', {
15
+ type ReadyEvent = BaseEvent<'ready', {
16
+ key: string;
17
+ }>;
18
+ type ChangeEvent<Value = never> = BaseEvent<'change', {
16
19
  empty: boolean;
17
20
  complete: boolean;
18
21
  valid?: boolean;
19
22
  error?: string;
20
23
  errorCode?: CardValidationError;
21
- value: Value extends never ? never : Value | null;
24
+ value?: Value extends never ? never : Value | null;
22
25
  }>;
23
26
  type InputFocusEvent = BaseEvent<'focus'>;
24
27
  type InputBlurEvent = BaseEvent<'blur'>;
@@ -26,11 +29,11 @@ type InputKeydownEvent = BaseEvent<'keydown', {
26
29
  key: ListenableKey;
27
30
  } & Pick<KeyboardEvent, 'altKey' | 'ctrlKey' | 'shiftKey' | 'metaKey'>>;
28
31
  type BaseElementEvents = ReadyEvent | InputFocusEvent | InputBlurEvent | InputKeydownEvent;
29
- type CardElementEvents<Value> = BaseElementEvents | ChangeEvent<Value>;
32
+ type CardElementEvents<Value = never> = BaseElementEvents | ChangeEvent<Value>;
30
33
  /**
31
34
  * Utility type that helps find a Union type based on a `type` property
32
35
  */
33
- type FindByType<Union, Type extends EventType> = Union extends {
36
+ type FindByType<Union, Type extends string> = Union extends {
34
37
  type: Type;
35
38
  } ? Union : never;
36
39
  type ElementEventListener<Events, Type extends EventType> = (event: FindByType<Events, Type>) => void;
@@ -38,7 +41,7 @@ interface Subscription {
38
41
  unsubscribe(): void;
39
42
  }
40
43
  export type { BaseElementEvents, BaseEvent, CardElementEvents, ChangeEvent, ElementEventListener, EventType, FindByType, InputBlurEvent, InputFocusEvent, InputKeydownEvent, ReadyEvent, Subscription, };
41
- export type ElementType = 'card' | 'cardNumber' | 'cardExpirationDate' | 'cardVerificationCode' | 'text';
44
+ export type ElementType = 'card' | 'cardNumber' | 'cardExpirationDate' | 'cardExpirationMonth' | 'cardExpirationYear' | 'cardVerificationCode' | 'text';
42
45
  export declare const ELEMENT_TYPES: ElementType[];
43
46
  export declare enum CardValidationError {
44
47
  NOT_COMPLETE = "NOT_COMPLETE",
@@ -76,6 +79,7 @@ export type ElementBaseOptions<Value = unknown> = {
76
79
  schemes?: CardSchema[];
77
80
  value?: Value;
78
81
  cardType?: string;
82
+ expiryYear?: string;
79
83
  };
80
84
  /**
81
85
  * Card brands type
@@ -0,0 +1,38 @@
1
+ import { FindByType } from '../card/ui/typings';
2
+ import { CoordinatorToParentMessage, ParentToCoordinatorMessage } from './typings';
3
+ /**
4
+ * Coordinator lives on the parent (merchant) page.
5
+ *
6
+ * It creates a hidden iframe with `?type=coordinator` that hosts the
7
+ * IframeCoordinator. All sensitive card operations (data collection,
8
+ * encryption, API calls) happen inside that iframe — card data never
9
+ * crosses the iframe boundary back to the merchant page.
10
+ *
11
+ * Communication with the iframe uses window.postMessage, carrying only
12
+ * commands and validation state — never card data.
13
+ */
14
+ export declare class Coordinator {
15
+ private iframe;
16
+ private iframeBaseUrl;
17
+ private messageHandler;
18
+ constructor();
19
+ /**
20
+ * Mount the coordinator iframe into the DOM and wait until it is
21
+ * fully initialised (receives `coordinator:ready` from the iframe with the session state).
22
+ *
23
+ * The iframe is hidden — it has no visual presence on the page.
24
+ * It serves purely as an isolated execution environment for secure
25
+ * card-data handling.
26
+ */
27
+ init: (sessionId: string, baseUrl: string, abortCtrl?: AbortController) => Promise<void>;
28
+ /**
29
+ * Send a command to the coordinator iframe.
30
+ * Only commands and configuration — never card data.
31
+ */
32
+ postMessage(message: ParentToCoordinatorMessage): void;
33
+ onMessage<T extends CoordinatorToParentMessage['type']>(type: T, callback: (message: FindByType<CoordinatorToParentMessage, T>) => void): void;
34
+ /**
35
+ * Clean up the coordinator iframe and all associated resources.
36
+ */
37
+ dispose(): void;
38
+ }
@@ -0,0 +1 @@
1
+ export declare const COORDINATOR_IFRAME_CHANNEL_NAME = "coordinator-channel";
@@ -0,0 +1,33 @@
1
+ /**
2
+ * IframeCoordinator lives entirely within the iframe isolation layer.
3
+ *
4
+ * It coordinates all card form elements via the Channel Messaging API,
5
+ * combines and validates card data within the iframe, encrypts sensitive
6
+ * data, and makes direct API calls to the Hellgate backend.
7
+ *
8
+ * SECURITY: Card data NEVER crosses the iframe boundary.
9
+ * - Card form elements send raw values only to the coordinator (same origin, via MessagePort)
10
+ * - The coordinator encrypts data and communicates with the backend directly
11
+ * - Only validation state (empty, complete, valid) is sent to the parent via postMessage
12
+ */
13
+ export declare class IframeCoordinator {
14
+ private parentOrigin;
15
+ private cardHandlerCoordinator;
16
+ private session;
17
+ private channel;
18
+ constructor(sessionId: string, apiBaseUrl: string, parentOrigin: string);
19
+ init: () => Promise<void>;
20
+ private setupChannelListener;
21
+ /**
22
+ * Listen for messages from the parent CardHandler.
23
+ * Only commands and configuration cross this boundary - never card data.
24
+ */
25
+ private setupParentMessageListener;
26
+ private handleParentMessage;
27
+ /**
28
+ * Send a message to the parent CardHandler.
29
+ * Only validation state and results - never card data.
30
+ */
31
+ private postMessageToParent;
32
+ dispose(): void;
33
+ }
@@ -0,0 +1 @@
1
+ export declare function initCoordinatorIframe(sessionId: string, apiBaseUrl: string, origin: string): void;
@@ -0,0 +1,2 @@
1
+ export { initCoordinatorIframe } from './iframe';
2
+ export { IframeCoordinator } from './iframe-coordinator';
@@ -0,0 +1,3 @@
1
+ export { Coordinator } from './coordinator';
2
+ export { IframeCoordinator } from './iframe/iframe-coordinator';
3
+ export type { CoordinatorFormState, CoordinatorToParentMessage, ParentToCoordinatorMessage, } from './typings';
@@ -0,0 +1,39 @@
1
+ import { CardHandlerToCoordinatorMessage, CoordinatorToCardHandlerMessage } from '../card/coordinator/typings';
2
+ import { SessionStateDTO } from '../session';
3
+ /**
4
+ * Message types sent FROM the parent CardHandler TO the coordinator iframe
5
+ * via window.postMessage (crosses iframe boundary)
6
+ *
7
+ * IMPORTANT: No card data flows through these messages.
8
+ * Only commands and configuration are sent.
9
+ */
10
+ export type ParentToCoordinatorMessage = {
11
+ type: 'coordinator:init';
12
+ sessionId: string;
13
+ baseUrl: string;
14
+ } | {
15
+ type: 'coordinator:dispose';
16
+ } | CardHandlerToCoordinatorMessage;
17
+ /**
18
+ * Message types sent FROM the coordinator iframe TO the parent CardHandler
19
+ * via window.postMessage (crosses iframe boundary)
20
+ *
21
+ * IMPORTANT: No card data flows through these messages.
22
+ * Only validation state and tokenization results are sent.
23
+ */
24
+ export type CoordinatorToParentMessage = {
25
+ type: 'coordinator:ready';
26
+ } | {
27
+ type: 'coordinator:error';
28
+ error: unknown;
29
+ } | {
30
+ type: 'coordinator:session_state_change';
31
+ state: SessionStateDTO;
32
+ } | CoordinatorToCardHandlerMessage;
33
+ export type CoordinatorFormState = {
34
+ empty: boolean;
35
+ complete: boolean;
36
+ valid: boolean;
37
+ error?: string;
38
+ errorCode?: string;
39
+ };