@melio-eng/web-sdk 1.0.36-pr.67.71c92f3 → 1.0.36-pr.69.063a65a

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.
@@ -0,0 +1,15 @@
1
+ import { CheckoutFlowConfig, Environment } from '../types.js';
2
+ import { Flow } from './Flow.js';
3
+ /**
4
+ * CheckoutFlow - loads the Melio checkout experience without requiring authentication.
5
+ * Used by partners (e.g. Xero) to embed the payment checkout in their payer experience.
6
+ *
7
+ * The host page can call `submit()` on this flow instance to trigger the checkout submission.
8
+ * The component will then emit a 'checkoutSubmit' event with a JWT token containing the
9
+ * tokenized payment details.
10
+ */
11
+ export declare class CheckoutFlow extends Flow {
12
+ private allowPaymentMethod;
13
+ constructor(containerId: string, config: CheckoutFlowConfig, partnerName: string, environment: Environment, branchOverride?: string);
14
+ protected constructFlowUrl(baseUrl: string): string;
15
+ }
@@ -0,0 +1,23 @@
1
+ import { Flow } from './Flow.js';
2
+ /**
3
+ * CheckoutFlow - loads the Melio checkout experience without requiring authentication.
4
+ * Used by partners (e.g. Xero) to embed the payment checkout in their payer experience.
5
+ *
6
+ * The host page can call `submit()` on this flow instance to trigger the checkout submission.
7
+ * The component will then emit a 'checkoutSubmit' event with a JWT token containing the
8
+ * tokenized payment details.
9
+ */
10
+ export class CheckoutFlow extends Flow {
11
+ constructor(containerId, config, partnerName, environment, branchOverride) {
12
+ super(containerId, config, partnerName, environment, branchOverride);
13
+ this.allowPaymentMethod = config.allowPaymentMethod || ['card', 'ach'];
14
+ }
15
+ constructFlowUrl(baseUrl) {
16
+ const params = new URLSearchParams({
17
+ externalOrigin: this.partnerName,
18
+ allowPaymentMethod: this.allowPaymentMethod.join(','),
19
+ parentOrigin: window.location.origin,
20
+ });
21
+ return `${baseUrl}/${this.partnerName}/ar/checkout?${params.toString()}`;
22
+ }
23
+ }
@@ -1,4 +1,4 @@
1
- import { FlowInstance, FlowEventType, FlowEventCallback, FlowCompletionData, NavigationData, BaseFlowConfig, Environment, ErrorData } from '../types.js';
1
+ import { FlowInstance, FlowEventType, FlowEventCallback, FlowCompletionData, NavigationData, BaseFlowConfig, Environment, ErrorData, CheckoutSubmitData } from '../types.js';
2
2
  /**
3
3
  * Flow class implementation for handling iframe flows and events
4
4
  */
@@ -39,6 +39,9 @@ export declare class Flow implements FlowInstance {
39
39
  protected emit(event: 'error', data: ErrorData): void;
40
40
  protected emit(event: 'onboardingCompleted'): void;
41
41
  protected emit(event: 'onboardingRequired'): void;
42
+ protected emit(event: 'paymentSucceeded', data: FlowCompletionData): void;
43
+ protected emit(event: 'paymentFailed', data: ErrorData): void;
44
+ protected emit(event: 'checkoutSubmit', data: CheckoutSubmitData): void;
42
45
  /**
43
46
  * Register an event listener
44
47
  */
@@ -51,6 +54,9 @@ export declare class Flow implements FlowInstance {
51
54
  on(event: 'loaded', callback: () => void): void;
52
55
  on(event: 'onboardingCompleted', callback: () => void): void;
53
56
  on(event: 'onboardingRequired', callback: () => void): void;
57
+ on(event: 'paymentSucceeded', callback: (data: FlowCompletionData) => void): void;
58
+ on(event: 'paymentFailed', callback: (data: ErrorData) => void): void;
59
+ on(event: 'checkoutSubmit', callback: (data: CheckoutSubmitData) => void): void;
54
60
  /**
55
61
  * Remove an event listener
56
62
  */
@@ -59,4 +65,9 @@ export declare class Flow implements FlowInstance {
59
65
  * Close the flow and clean up resources
60
66
  */
61
67
  close(): void;
68
+ /**
69
+ * Send the paymentIntent JWT token to the checkout iframe to trigger submission.
70
+ * @param token - The paymentIntent JWT token created by the partner's backend via Melio API
71
+ */
72
+ submit(token: string): void;
62
73
  }
@@ -61,7 +61,10 @@ export class Flow {
61
61
  // Add post message handlers for internal events - setHeight, scroll etc
62
62
  // Also need to implement callbacks for flow completed exit etc in the platform-app
63
63
  this.messageHandler = (event) => {
64
- if (!/melio\.com|melioservices\.com/.test(event.origin)) {
64
+ if (!/melio\.com|melioservices\.com|localhost/.test(event.origin)) {
65
+ return;
66
+ }
67
+ if (this.iframe && event.source !== this.iframe.contentWindow) {
65
68
  return;
66
69
  }
67
70
  const { type, ...data } = event.data;
@@ -92,6 +95,15 @@ export class Flow {
92
95
  case 'PAYMENT_SCHEDULED':
93
96
  this.emit('completed', { flowName: 'payment', ...data });
94
97
  break;
98
+ case 'PAYMENT_SUCCEEDED':
99
+ this.emit('paymentSucceeded', data);
100
+ break;
101
+ case 'PAYMENT_FAILED':
102
+ this.emit('paymentFailed', data);
103
+ break;
104
+ case 'CHECKOUT_SUBMIT_RESULT':
105
+ this.emit('checkoutSubmit', data);
106
+ break;
95
107
  case 'MELIO_ERROR':
96
108
  if (data.code === 'failed_to_sync_bills') {
97
109
  this.emit('error', { errorCode: 'billsSyncFailed' });
@@ -153,4 +165,13 @@ export class Flow {
153
165
  }
154
166
  this.eventListeners.clear();
155
167
  }
168
+ /**
169
+ * Send the paymentIntent JWT token to the checkout iframe to trigger submission.
170
+ * @param token - The paymentIntent JWT token created by the partner's backend via Melio API
171
+ */
172
+ submit(token) {
173
+ if (this.iframe?.contentWindow) {
174
+ this.iframe.contentWindow.postMessage({ type: 'CHECKOUT_SUBMIT', payload: { token } }, '*');
175
+ }
176
+ }
156
177
  }
@@ -1,3 +1,4 @@
1
+ export { CheckoutFlow } from './CheckoutFlow.js';
1
2
  export { Flow } from './Flow.js';
2
3
  export { InitFlow } from './InitFlow.js';
3
4
  export { OnboardingFlow } from './OnboardingFlow.js';
@@ -1,3 +1,4 @@
1
+ export { CheckoutFlow } from './CheckoutFlow.js';
1
2
  export { Flow } from './Flow.js';
2
3
  export { InitFlow } from './InitFlow.js';
3
4
  export { OnboardingFlow } from './OnboardingFlow.js';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { InitOptions, OnboardingConfig, SettingsConfig, FlowInstance, PaymentsDashboardConfig, PayFlowConfig, InitFlowInstance } from './types.js';
1
+ import { InitOptions, OnboardingConfig, SettingsConfig, FlowInstance, PaymentsDashboardConfig, PayFlowConfig, CheckoutFlowConfig, InitFlowInstance } from './types.js';
2
2
  /**
3
3
  * Main SDK implementation - now partner agnostic
4
4
  */
@@ -10,6 +10,11 @@ export declare class MelioSDK implements MelioSDK {
10
10
  private authCode;
11
11
  private initFlow;
12
12
  constructor();
13
+ /**
14
+ * Configure the SDK without triggering authentication.
15
+ * Use this for unauthenticated flows like checkout.
16
+ */
17
+ configure(options: Pick<InitOptions, 'partnerName' | 'environment' | 'branchOverride'>): void;
13
18
  /**
14
19
  * Initialize the SDK - triggers auth event without creating iframe
15
20
  */
@@ -30,6 +35,11 @@ export declare class MelioSDK implements MelioSDK {
30
35
  * Launch the payments dashboard flow
31
36
  */
32
37
  openPaymentsDashboard(config: PaymentsDashboardConfig): FlowInstance;
38
+ /**
39
+ * Launch the checkout flow for guest payment.
40
+ * Does not require init().
41
+ */
42
+ openCheckoutFlow(config: CheckoutFlowConfig): FlowInstance;
33
43
  }
34
44
  /**
35
45
  * Export the SDK instance
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { InitFlow, OnboardingFlow, PayFlow, SettingsFlow, PaymentsDashboardFlow, isEmptyString, } from './flows/index.js';
1
+ import { CheckoutFlow, InitFlow, OnboardingFlow, PayFlow, SettingsFlow, PaymentsDashboardFlow, isEmptyString, } from './flows/index.js';
2
2
  /**
3
3
  * Main SDK implementation - now partner agnostic
4
4
  */
@@ -11,6 +11,15 @@ export class MelioSDK {
11
11
  this.authCode = '';
12
12
  this.initFlow = null;
13
13
  }
14
+ /**
15
+ * Configure the SDK without triggering authentication.
16
+ * Use this for unauthenticated flows like checkout.
17
+ */
18
+ configure(options) {
19
+ this.partnerName = options.partnerName;
20
+ this.environment = options.environment || 'production';
21
+ this.branchOverride = options.branchOverride;
22
+ }
14
23
  /**
15
24
  * Initialize the SDK - triggers auth event without creating iframe
16
25
  */
@@ -79,6 +88,18 @@ export class MelioSDK {
79
88
  flow.initialize();
80
89
  return flow;
81
90
  }
91
+ /**
92
+ * Launch the checkout flow for guest payment.
93
+ * Does not require init().
94
+ */
95
+ openCheckoutFlow(config) {
96
+ if (isEmptyString(this.partnerName)) {
97
+ throw new Error('Partner name is required. Please call init() or set partnerName before opening checkout flow.');
98
+ }
99
+ const flow = new CheckoutFlow(config.containerId, config, this.partnerName, this.environment, this.branchOverride);
100
+ flow.initialize();
101
+ return flow;
102
+ }
82
103
  }
83
104
  /**
84
105
  * Export the SDK instance
package/dist/types.d.ts CHANGED
@@ -55,6 +55,19 @@ export interface OnboardingConfig extends BaseFlowConfig {
55
55
  export interface PayFlowConfig extends BaseFlowConfig {
56
56
  billIds: Array<string>;
57
57
  }
58
+ /**
59
+ * Allowed payment methods for the checkout flow
60
+ */
61
+ export type AllowedPaymentMethod = 'card' | 'ach';
62
+ /**
63
+ * Configuration for checkout flow.
64
+ * Used by partners (e.g. Xero) to embed the payment checkout in their payer experience.
65
+ * Does not require prior authentication.
66
+ */
67
+ export interface CheckoutFlowConfig extends BaseFlowConfig {
68
+ /** Allowed payment methods. Defaults to ['card', 'ach'] if not specified */
69
+ allowPaymentMethod?: AllowedPaymentMethod[];
70
+ }
58
71
  /**
59
72
  * Configuration for settings flow
60
73
  */
@@ -88,6 +101,13 @@ export interface FlowCompletionData {
88
101
  flowName: 'onboarding' | 'payment';
89
102
  [key: string]: any;
90
103
  }
104
+ /**
105
+ * Data returned when checkout submission is complete.
106
+ */
107
+ export interface CheckoutSubmitData {
108
+ /** Result payload from the checkout submission */
109
+ [key: string]: any;
110
+ }
91
111
  /**
92
112
  * Flow error data.
93
113
  * billsSyncFailed could be returned if the following cases:
@@ -101,11 +121,11 @@ export interface ErrorData {
101
121
  /**
102
122
  * Event types that can be listened to
103
123
  */
104
- export type FlowEventType = 'completed' | 'exit' | 'navigated' | 'authenticationSucceeded' | 'authenticationFailed' | 'error' | 'loaded' | 'onboardingCompleted' | 'onboardingRequired';
124
+ export type FlowEventType = 'completed' | 'exit' | 'navigated' | 'authenticationSucceeded' | 'authenticationFailed' | 'error' | 'loaded' | 'onboardingCompleted' | 'onboardingRequired' | 'paymentSucceeded' | 'paymentFailed' | 'checkoutSubmit';
105
125
  /**
106
126
  * Event callback function types
107
127
  */
108
- export type FlowEventCallback = ((data: FlowCompletionData | NavigationData | ErrorData) => void) | (() => void);
128
+ export type FlowEventCallback = ((data: FlowCompletionData | NavigationData | ErrorData | CheckoutSubmitData) => void) | (() => void);
109
129
  /**
110
130
  * Flow instance interface for event handling
111
131
  */
@@ -124,6 +144,9 @@ export interface FlowInstance {
124
144
  on(event: 'loaded', callback: () => void): void;
125
145
  on(event: 'onboardingCompleted', callback: () => void): void;
126
146
  on(event: 'onboardingRequired', callback: () => void): void;
147
+ on(event: 'paymentSucceeded', callback: (data: FlowCompletionData) => void): void;
148
+ on(event: 'paymentFailed', callback: (data: ErrorData) => void): void;
149
+ on(event: 'checkoutSubmit', callback: (data: CheckoutSubmitData) => void): void;
127
150
  /**
128
151
  * Remove an event listener for this flow
129
152
  * @param event - The event type to remove listener for
@@ -134,6 +157,12 @@ export interface FlowInstance {
134
157
  * Close the flow and clean up resources
135
158
  */
136
159
  close(): void;
160
+ /**
161
+ * Trigger the checkout submit from the host.
162
+ * Sends the paymentIntent JWT token to the checkout component.
163
+ * @param token - The paymentIntent JWT token created by the partner's backend via Melio API
164
+ */
165
+ submit(token: string): void;
137
166
  }
138
167
  export interface InitFlowInstance {
139
168
  /**
@@ -183,4 +212,11 @@ export interface MelioSDK {
183
212
  * @returns Flow instance for event handling
184
213
  */
185
214
  openPaymentsDashboard(config: PaymentsDashboardConfig): FlowInstance;
215
+ /**
216
+ * Launch the checkout flow for guest payment.
217
+ * Does not require init().
218
+ * @param config - Configuration for the checkout flow
219
+ * @returns Flow instance for event handling
220
+ */
221
+ openCheckoutFlow(config: CheckoutFlowConfig): FlowInstance;
186
222
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@melio-eng/web-sdk",
3
- "version": "1.0.36-pr.67.71c92f3",
3
+ "version": "1.0.36-pr.69.063a65a",
4
4
  "description": "Melio Web SDK - Embed core Melio workflows directly into partner UI with minimal effort",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -20,7 +20,8 @@
20
20
  "prepublishOnly": "npm run build && npm run docs",
21
21
  "examples": "serve . -p 3009",
22
22
  "examples:basic": "serve . -p 3009 && echo 'Open http://localhost:3009/examples/basic-usage.html'",
23
- "examples:bill-pay": "serve . -p 3009 && echo 'Open http://localhost:3009/examples/bill-pay-example.html'"
23
+ "examples:bill-pay": "serve . -p 3009 && echo 'Open http://localhost:3009/examples/bill-pay-example.html'",
24
+ "examples:checkout": "serve . -p 3009 && echo 'Open http://localhost:3009/examples/checkout-example.html'"
24
25
  },
25
26
  "keywords": [
26
27
  "melio",