@amos.com/amos-js 0.9.9 → 0.9.11

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/dist/index.mjs CHANGED
@@ -85,41 +85,82 @@ function i(e) {
85
85
  //#endregion
86
86
  //#region src/types.ts
87
87
  function a(e) {
88
+ if (!e || typeof e != "object") return;
89
+ let t = {};
90
+ for (let [n, r] of Object.entries(e)) {
91
+ if (typeof r == "string") {
92
+ if (r.length === 0) continue;
93
+ t[n] = r;
94
+ continue;
95
+ }
96
+ typeof r == "number" && Number.isFinite(r) && (t[n] = r);
97
+ }
98
+ return Object.keys(t).length > 0 ? t : void 0;
99
+ }
100
+ function o(e) {
101
+ let t = {};
102
+ if (e.buttonstyle !== void 0 && (t.buttonstyle = e.buttonstyle), e.type !== void 0 && (t.type = e.type), e.locale !== void 0 && (t.locale = e.locale), e.style !== void 0) {
103
+ let n = a(e.style);
104
+ n && (t.style = n);
105
+ }
106
+ return t;
107
+ }
108
+ function s(e) {
109
+ let t = {};
110
+ if (e.buttonType !== void 0 && (t.buttonType = e.buttonType), e.buttonColor !== void 0 && (t.buttonColor = e.buttonColor), e.buttonRadius !== void 0 && (t.buttonRadius = e.buttonRadius), e.buttonSizeMode !== void 0 && (t.buttonSizeMode = e.buttonSizeMode), e.buttonLocale !== void 0 && (t.buttonLocale = e.buttonLocale), e.buttonBorderType !== void 0 && (t.buttonBorderType = e.buttonBorderType), e.style !== void 0) {
111
+ let n = a(e.style);
112
+ n && (t.style = n);
113
+ }
114
+ return t;
115
+ }
116
+ function c(e) {
88
117
  return e;
89
118
  }
90
119
  //#endregion
91
120
  //#region src/messaging.ts
92
- function o(e) {
121
+ function l(e) {
93
122
  return new URL(e.src).origin;
94
123
  }
95
- function s(e) {
96
- e?.contentWindow && e.contentWindow.postMessage(a({ type: "PARENT_ACKNOWLEDGED_IFRAME_READY" }), o(e));
124
+ function u(e) {
125
+ e?.contentWindow && e.contentWindow.postMessage(c({ type: "PARENT_ACKNOWLEDGED_IFRAME_READY" }), l(e));
97
126
  }
98
- function c({ iframe: e, appearance: t = {} }) {
99
- e?.contentWindow && e.contentWindow.postMessage(a({
127
+ function d({ iframe: e, appearance: t = {} }) {
128
+ e?.contentWindow && e.contentWindow.postMessage(c({
100
129
  type: "UPDATE_APPEARANCE",
101
130
  appearance: t
102
- }), o(e));
103
- }
104
- function l({ iframe: e, amount: t }) {
105
- e?.contentWindow && e.contentWindow.postMessage(a({
131
+ }), l(e));
132
+ }
133
+ function f({ iframe: e, props: t }) {
134
+ e?.contentWindow && e.contentWindow.postMessage(c({
135
+ type: "UPDATE_APPLE_PAY_BUTTON",
136
+ props: o(t)
137
+ }), l(e));
138
+ }
139
+ function p({ iframe: e, props: t }) {
140
+ e?.contentWindow && e.contentWindow.postMessage(c({
141
+ type: "UPDATE_GOOGLE_PAY_BUTTON",
142
+ props: s(t)
143
+ }), l(e));
144
+ }
145
+ function m({ iframe: e, amount: t }) {
146
+ e?.contentWindow && e.contentWindow.postMessage(c({
106
147
  type: "UPDATE_AMOUNT",
107
148
  amount: t
108
- }), o(e));
149
+ }), l(e));
109
150
  }
110
- function u({ iframe: e, merchantName: t }) {
111
- e?.contentWindow && e.contentWindow.postMessage(a({
151
+ function h({ iframe: e, merchantName: t }) {
152
+ e?.contentWindow && e.contentWindow.postMessage(c({
112
153
  type: "UPDATE_MERCHANT_NAME",
113
154
  merchantName: t
114
- }), o(e));
155
+ }), l(e));
115
156
  }
116
- function d({ iframe: e }) {
157
+ function g({ iframe: e }) {
117
158
  let t = crypto.randomUUID();
118
159
  return new Promise((n) => {
119
- e?.contentWindow && e.contentWindow.postMessage(a({
160
+ e?.contentWindow && e.contentWindow.postMessage(c({
120
161
  type: "VALIDATE_FORM",
121
162
  requestId: t
122
- }), o(e));
163
+ }), l(e));
123
164
  let r = setTimeout(() => {
124
165
  window.removeEventListener("message", i), n(!1);
125
166
  }, 5e3);
@@ -129,71 +170,77 @@ function d({ iframe: e }) {
129
170
  window.addEventListener("message", i);
130
171
  });
131
172
  }
132
- function f({ iframe: e }) {
133
- e?.contentWindow && e.contentWindow.postMessage(a({ type: "RESET_FORM" }), o(e));
173
+ function _({ iframe: e }) {
174
+ e?.contentWindow && e.contentWindow.postMessage(c({ type: "RESET_FORM" }), l(e));
134
175
  }
135
- function p({ iframe: e, token: t }) {
176
+ function v({ iframe: e, token: t }) {
136
177
  if (!e?.contentWindow) return;
137
178
  let { payment_intent_id: n } = r(t).payload;
138
- e.contentWindow.postMessage(a({
179
+ e.contentWindow.postMessage(c({
139
180
  type: "CONFIRM_PAYMENT_INTENT",
140
181
  token: t,
141
182
  id: n ?? void 0
142
- }), o(e));
183
+ }), l(e));
143
184
  }
144
- function m({ iframe: e, token: t }) {
185
+ function y({ iframe: e, token: t }) {
145
186
  if (!e?.contentWindow) return;
146
187
  let { setup_intent_id: n } = r(t).payload;
147
- e.contentWindow.postMessage(a({
188
+ e.contentWindow.postMessage(c({
148
189
  type: "CONFIRM_SETUP_INTENT",
149
190
  token: t,
150
191
  id: n ?? void 0
151
- }), o(e));
192
+ }), l(e));
152
193
  }
153
- function h({ iframe: e, result: t }) {
154
- e?.contentWindow && e.contentWindow.postMessage(a({
194
+ function b({ iframe: e, result: t }) {
195
+ e?.contentWindow && e.contentWindow.postMessage(c({
155
196
  type: "CONFIRMATION_RESULT",
156
197
  result: t
157
- }), o(e));
198
+ }), l(e));
158
199
  }
159
200
  //#endregion
160
201
  //#region src/apple-pay.ts
161
- function g(e) {
202
+ function x(e) {
162
203
  return `${i(e)}/iframe/apple-pay?token=${e}`;
163
204
  }
164
- function _() {
205
+ function S() {
165
206
  return "40px";
166
207
  }
167
- function v(e) {
168
- e.contentWindow?.postMessage(a({ type: "APPLE_PAY_CANCEL" }), o(e));
208
+ function C(e) {
209
+ e.contentWindow?.postMessage(c({ type: "APPLE_PAY_CANCEL" }), l(e));
169
210
  }
170
- function y(e, r) {
211
+ function w(e, r) {
171
212
  let i = { ...r };
172
213
  function a() {
173
- l({
214
+ m({
174
215
  iframe: e,
175
216
  amount: i.amount
176
217
  });
177
218
  }
178
219
  function o() {
179
- u({
220
+ h({
180
221
  iframe: e,
181
222
  merchantName: i.merchantName
182
223
  });
183
224
  }
184
- function d(r) {
225
+ function s() {
226
+ f({
227
+ iframe: e,
228
+ props: i
229
+ });
230
+ }
231
+ function c(r) {
185
232
  if (r.source === e.contentWindow) switch (r.data.type) {
186
233
  case "IFRAME_READY":
187
- s(e), c({
234
+ u(e), d({
188
235
  iframe: e,
189
236
  appearance: i.appearance
190
- }), a(), o();
237
+ }), a(), o(), s();
191
238
  break;
192
239
  case "UPDATE_HEIGHT":
193
240
  i.onHeightChange?.(r.data.height);
194
241
  break;
195
242
  case "UPDATE_APPEARANCE":
196
- c({
243
+ d({
197
244
  iframe: e,
198
245
  appearance: r.data.appearance
199
246
  });
@@ -203,7 +250,7 @@ function y(e, r) {
203
250
  break;
204
251
  case "APPLE_PAY_WINDOW_OPEN":
205
252
  t({ onCancel: () => {
206
- v(e), n();
253
+ C(e), n();
207
254
  } });
208
255
  break;
209
256
  case "APPLE_PAY_WINDOW_CLOSE":
@@ -214,7 +261,7 @@ function y(e, r) {
214
261
  paymentIntentCreateAttributes: r.data.paymentIntentCreateAttributes,
215
262
  customerCreateAttributes: r.data.customerCreateAttributes
216
263
  }).then((t) => {
217
- p({
264
+ v({
218
265
  iframe: e,
219
266
  token: t
220
267
  });
@@ -228,57 +275,63 @@ function y(e, r) {
228
275
  case "CONFIRMATION_RESULT": n(), i.onResult(r.data.result);
229
276
  }
230
277
  }
231
- return window.addEventListener("message", d), {
278
+ return window.addEventListener("message", c), {
232
279
  update(t) {
233
- let n = "appearance" in t, r = "amount" in t, s = "merchantName" in t;
280
+ let n = "appearance" in t, r = "amount" in t, c = "merchantName" in t, l = "buttonstyle" in t || "type" in t || "locale" in t || "style" in t;
234
281
  i = {
235
282
  ...i,
236
283
  ...t
237
- }, n && c({
284
+ }, n && d({
238
285
  iframe: e,
239
286
  appearance: i.appearance
240
- }), r && a(), s && o();
287
+ }), r && a(), c && o(), l && s();
241
288
  },
242
289
  destroy() {
243
- window.removeEventListener("message", d), n();
290
+ window.removeEventListener("message", c), n();
244
291
  }
245
292
  };
246
293
  }
247
294
  //#endregion
248
295
  //#region src/google-pay.ts
249
- function b(e) {
296
+ function T(e) {
250
297
  return `${i(e)}/iframe/google-pay?token=${e}`;
251
298
  }
252
- function x() {
299
+ function E() {
253
300
  return "40px";
254
301
  }
255
- function S(e, t) {
302
+ function D(e, t) {
256
303
  let n = { ...t };
257
304
  function r() {
258
- l({
305
+ m({
259
306
  iframe: e,
260
307
  amount: n.amount
261
308
  });
262
309
  }
263
310
  function i() {
264
- u({
311
+ h({
265
312
  iframe: e,
266
313
  merchantName: n.merchantName
267
314
  });
268
315
  }
269
- function a(t) {
316
+ function a() {
317
+ p({
318
+ iframe: e,
319
+ props: n
320
+ });
321
+ }
322
+ function o(t) {
270
323
  if (t.source === e.contentWindow) switch (t.data.type) {
271
324
  case "IFRAME_READY":
272
- s(e), c({
325
+ u(e), d({
273
326
  iframe: e,
274
327
  appearance: n.appearance
275
- }), r(), i();
328
+ }), r(), i(), a();
276
329
  break;
277
330
  case "UPDATE_HEIGHT":
278
331
  n.onHeightChange?.(t.data.height);
279
332
  break;
280
333
  case "UPDATE_APPEARANCE":
281
- c({
334
+ d({
282
335
  iframe: e,
283
336
  appearance: t.data.appearance
284
337
  });
@@ -291,7 +344,7 @@ function S(e, t) {
291
344
  paymentIntentCreateAttributes: t.data.paymentIntentCreateAttributes,
292
345
  customerCreateAttributes: t.data.customerCreateAttributes
293
346
  }).then((t) => {
294
- p({
347
+ v({
295
348
  iframe: e,
296
349
  token: t
297
350
  });
@@ -305,23 +358,23 @@ function S(e, t) {
305
358
  case "CONFIRMATION_RESULT": n.onResult(t.data.result);
306
359
  }
307
360
  }
308
- return window.addEventListener("message", a), {
361
+ return window.addEventListener("message", o), {
309
362
  update(t) {
310
- let a = "appearance" in t, o = "amount" in t, s = "merchantName" in t;
363
+ let o = "appearance" in t, s = "amount" in t, c = "merchantName" in t, l = "buttonType" in t || "buttonColor" in t || "buttonRadius" in t || "buttonSizeMode" in t || "buttonLocale" in t || "buttonBorderType" in t || "style" in t;
311
364
  n = {
312
365
  ...n,
313
366
  ...t
314
- }, a && c({
367
+ }, o && d({
315
368
  iframe: e,
316
369
  appearance: n.appearance
317
- }), o && r(), s && i();
370
+ }), s && r(), c && i(), l && a();
318
371
  },
319
372
  destroy() {
320
- window.removeEventListener("message", a);
373
+ window.removeEventListener("message", o);
321
374
  }
322
375
  };
323
376
  }
324
- function C({ paymentData: e }) {
377
+ function O({ paymentData: e }) {
325
378
  return { paymentMethod: {
326
379
  type: "googlepay",
327
380
  billing_address_attributes: {
@@ -340,14 +393,14 @@ function C({ paymentData: e }) {
340
393
  }
341
394
  //#endregion
342
395
  //#region src/payment-method-form.ts
343
- var w = {
396
+ var k = {
344
397
  country: 212,
345
398
  full: 452
346
- }, T = 80, E = {
399
+ }, A = 80, j = {
347
400
  country: 400,
348
401
  full: 640
349
402
  };
350
- function D(e, t = { cardholderName: !1 }, n = "country") {
403
+ function M(e, t = { cardholderName: !1 }, n = "country") {
351
404
  let r = Object.entries(t).filter(([, e]) => e).map(([e]) => e).join(","), a = new URLSearchParams({
352
405
  token: e,
353
406
  additionalFields: r,
@@ -355,25 +408,25 @@ function D(e, t = { cardholderName: !1 }, n = "country") {
355
408
  });
356
409
  return `${i(e)}/iframe/card?${a}`;
357
410
  }
358
- function O(e, t = "country") {
411
+ function N(e, t = "country") {
359
412
  let n = new URLSearchParams({
360
413
  token: e,
361
414
  billingAddressRequirement: t
362
415
  });
363
416
  return `${i(e)}/iframe/bank?${n}`;
364
417
  }
365
- function k(e = { cardholderName: !1 }, t = "country") {
366
- return `${(w[t] ?? w.country) + (e.cardholderName ? T : 0)}px`;
418
+ function P(e = { cardholderName: !1 }, t = "country") {
419
+ return `${(k[t] ?? k.country) + (e.cardholderName ? A : 0)}px`;
367
420
  }
368
- function A(e = "country") {
369
- return `${E[e] ?? E.country}px`;
421
+ function F(e = "country") {
422
+ return `${j[e] ?? j.country}px`;
370
423
  }
371
- function j(e, t) {
424
+ function I(e, t) {
372
425
  let n = { ...t };
373
426
  function r(t) {
374
427
  if (t.source === e.contentWindow) switch (t.data.type) {
375
428
  case "IFRAME_READY":
376
- s(e), c({
429
+ u(e), d({
377
430
  iframe: e,
378
431
  appearance: n.appearance
379
432
  });
@@ -382,7 +435,7 @@ function j(e, t) {
382
435
  n.onHeightChange?.(t.data.height);
383
436
  break;
384
437
  case "UPDATE_APPEARANCE":
385
- c({
438
+ d({
386
439
  iframe: e,
387
440
  appearance: t.data.appearance
388
441
  });
@@ -390,6 +443,9 @@ function j(e, t) {
390
443
  case "UPDATED_APPEARANCE":
391
444
  n.onAppearanceReady?.();
392
445
  break;
446
+ case "FORM_VALIDITY_CHANGE":
447
+ n.onValidityChange?.({ isValid: t.data.isValid });
448
+ break;
393
449
  case "CONFIRMATION_RESULT": n.onResult(t.data.result);
394
450
  }
395
451
  }
@@ -399,7 +455,7 @@ function j(e, t) {
399
455
  n = {
400
456
  ...n,
401
457
  ...t
402
- }, r && c({
458
+ }, r && d({
403
459
  iframe: e,
404
460
  appearance: n.appearance
405
461
  });
@@ -411,7 +467,7 @@ function j(e, t) {
411
467
  }
412
468
  //#endregion
413
469
  //#region src/mount.ts
414
- function M(e) {
470
+ function L(e) {
415
471
  if (typeof e == "string") {
416
472
  let t = document.querySelector(e);
417
473
  if (!(t instanceof HTMLElement)) throw Error(`[amos-js] Container "${e}" did not match any HTMLElement.`);
@@ -419,26 +475,26 @@ function M(e) {
419
475
  }
420
476
  return e;
421
477
  }
422
- var N = {
478
+ var R = {
423
479
  width: "calc(100% + 8px)",
424
480
  transition: "opacity 150ms ease-in, height 200ms ease-in-out",
425
481
  margin: "0 -4px",
426
482
  opacity: "0",
427
483
  border: "0"
428
484
  };
429
- function P({ src: e, title: t, name: n, height: r, allow: i }) {
485
+ function z({ src: e, title: t, name: n, height: r, allow: i }) {
430
486
  let a = document.createElement("iframe");
431
- return a.src = e, a.title = t, a.name = n, a.setAttribute("role", "presentation"), a.scrolling = "no", i && (a.allow = i), Object.assign(a.style, N, { height: r }), a;
487
+ return a.src = e, a.title = t, a.name = n, a.setAttribute("role", "presentation"), a.scrolling = "no", i && (a.allow = i), Object.assign(a.style, R, { height: r }), a;
432
488
  }
433
- function F(e, t) {
434
- let n = M(e), { renderToken: r, additionalFields: i = { cardholderName: !1 }, billingAddressRequirement: a = "country", ...o } = t, s = P({
435
- src: D(r, i, a),
489
+ function B(e, t) {
490
+ let n = L(e), { renderToken: r, additionalFields: i = { cardholderName: !1 }, billingAddressRequirement: a = "country", ...o } = t, s = z({
491
+ src: M(r, i, a),
436
492
  title: "Secure credit card payment method form powered by Amos",
437
493
  name: "amos-credit-card-payment-method-form",
438
- height: k(i, a)
494
+ height: P(i, a)
439
495
  });
440
496
  n.appendChild(s);
441
- let c = j(s, {
497
+ let c = I(s, {
442
498
  ...o,
443
499
  onHeightChange: (e) => {
444
500
  s.style.height = e, o.onHeightChange?.(e);
@@ -455,15 +511,15 @@ function F(e, t) {
455
511
  }
456
512
  };
457
513
  }
458
- function I(e, t) {
459
- let n = M(e), { renderToken: r, billingAddressRequirement: i = "country", ...a } = t, o = P({
460
- src: O(r, i),
514
+ function V(e, t) {
515
+ let n = L(e), { renderToken: r, billingAddressRequirement: i = "country", ...a } = t, o = z({
516
+ src: N(r, i),
461
517
  title: "Secure bank account payment method form powered by Amos",
462
518
  name: "amos-bank-account-payment-method-form",
463
- height: A(i)
519
+ height: F(i)
464
520
  });
465
521
  n.appendChild(o);
466
- let s = j(o, {
522
+ let s = I(o, {
467
523
  ...a,
468
524
  onHeightChange: (e) => {
469
525
  o.style.height = e, a.onHeightChange?.(e);
@@ -480,16 +536,16 @@ function I(e, t) {
480
536
  }
481
537
  };
482
538
  }
483
- function L(e, t) {
484
- let n = M(e), { renderToken: r, ...i } = t, a = P({
485
- src: b(r),
539
+ function H(e, t) {
540
+ let n = L(e), { renderToken: r, ...i } = t, a = z({
541
+ src: T(r),
486
542
  title: "Secure Google Pay button powered by Amos",
487
543
  name: "amos-google-pay-button",
488
- height: x(),
544
+ height: E(),
489
545
  allow: "payment"
490
546
  });
491
547
  n.appendChild(a);
492
- let o = S(a, {
548
+ let o = D(a, {
493
549
  ...i,
494
550
  onHeightChange: (e) => {
495
551
  a.style.height = e, i.onHeightChange?.(e);
@@ -506,16 +562,16 @@ function L(e, t) {
506
562
  }
507
563
  };
508
564
  }
509
- function R(e, t) {
510
- let n = M(e), { renderToken: r, ...i } = t, a = P({
511
- src: g(r),
565
+ function U(e, t) {
566
+ let n = L(e), { renderToken: r, ...i } = t, a = z({
567
+ src: x(r),
512
568
  title: "Secure Apple Pay button powered by Amos",
513
569
  name: "amos-apple-pay-button",
514
- height: _(),
570
+ height: S(),
515
571
  allow: "payment"
516
572
  });
517
573
  n.appendChild(a);
518
- let o = y(a, {
574
+ let o = w(a, {
519
575
  ...i,
520
576
  onHeightChange: (e) => {
521
577
  a.style.height = e, i.onHeightChange?.(e);
@@ -533,4 +589,4 @@ function R(e, t) {
533
589
  };
534
590
  }
535
591
  //#endregion
536
- export { y as attachApplePayButtonListeners, S as attachGooglePayButtonListeners, j as attachPaymentMethodFormListeners, p as confirmPaymentIntent, m as confirmSetupIntent, a as createMessage, r as decodeJwt, C as formatGooglePayPaymentData, _ as getApplePayButtonInitialHeight, g as getApplePayButtonSrc, A as getBankAccountFormInitialHeight, O as getBankAccountFormSrc, k as getCreditCardFormInitialHeight, D as getCreditCardFormSrc, i as getEmbedOrigin, x as getGooglePayButtonInitialHeight, b as getGooglePayButtonSrc, R as mountAmosApplePayButton, I as mountAmosBankAccountPaymentMethodForm, F as mountAmosCreditCardPaymentMethodForm, L as mountAmosGooglePayButton, f as resetForm, h as sendConfirmationResult, s as sendParentReadyMessage, l as updateAmount, c as updateAppearance, u as updateMerchantName, d as validateForm };
592
+ export { w as attachApplePayButtonListeners, D as attachGooglePayButtonListeners, I as attachPaymentMethodFormListeners, v as confirmPaymentIntent, y as confirmSetupIntent, c as createMessage, r as decodeJwt, O as formatGooglePayPaymentData, S as getApplePayButtonInitialHeight, x as getApplePayButtonSrc, F as getBankAccountFormInitialHeight, N as getBankAccountFormSrc, P as getCreditCardFormInitialHeight, M as getCreditCardFormSrc, i as getEmbedOrigin, E as getGooglePayButtonInitialHeight, T as getGooglePayButtonSrc, U as mountAmosApplePayButton, V as mountAmosBankAccountPaymentMethodForm, B as mountAmosCreditCardPaymentMethodForm, H as mountAmosGooglePayButton, o as pickApplePayButtonElementProps, s as pickGooglePayButtonElementProps, _ as resetForm, b as sendConfirmationResult, u as sendParentReadyMessage, a as serializeWalletButtonStyle, m as updateAmount, d as updateAppearance, f as updateApplePayButton, p as updateGooglePayButton, h as updateMerchantName, g as validateForm };
@@ -1,5 +1,5 @@
1
1
  import { components } from '@amos.com/node';
2
- import { Appearance, Message } from './types';
2
+ import { Appearance, ApplePayButtonElementProps, GooglePayButtonElementProps, Message } from './types';
3
3
  type Iframe = HTMLIFrameElement | null | undefined;
4
4
  /**
5
5
  * Resolve the Amos embed origin from an iframe's configured `src`.
@@ -26,6 +26,20 @@ export declare function updateAppearance({ iframe, appearance, }: {
26
26
  iframe: Iframe;
27
27
  appearance?: Appearance;
28
28
  }): void;
29
+ /**
30
+ * Push Apple Pay button visual options into the embedded iframe.
31
+ */
32
+ export declare function updateApplePayButton({ iframe, props, }: {
33
+ iframe: Iframe;
34
+ props: ApplePayButtonElementProps;
35
+ }): void;
36
+ /**
37
+ * Push Google Pay button visual options into the embedded iframe.
38
+ */
39
+ export declare function updateGooglePayButton({ iframe, props, }: {
40
+ iframe: Iframe;
41
+ props: GooglePayButtonElementProps;
42
+ }): void;
29
43
  /**
30
44
  * Push the express-checkout amount into the embedded Google Pay iframe.
31
45
  */
@@ -1,4 +1,4 @@
1
- import { Appearance, ConfirmationResult } from './types';
1
+ import { Appearance, ConfirmationResult, PaymentMethodFormValidityChangeEvent } from './types';
2
2
  /**
3
3
  * The additional fields beyond the standard card number, expiration
4
4
  * date, CVV, and billing address fields that are required to be filled
@@ -59,6 +59,12 @@ export type PaymentMethodFormListenerOptions = {
59
59
  * iframe's opacity from `0` to `1` to fade it in.
60
60
  */
61
61
  onAppearanceReady?: () => void;
62
+ /**
63
+ * Called when card/bank form validity changes. `isValid` is true
64
+ * when all required fields are present and valid. Does not include
65
+ * PCI data. Use this to enable or disable a host checkout button.
66
+ */
67
+ onValidityChange?: (event: PaymentMethodFormValidityChangeEvent) => void;
62
68
  /**
63
69
  * Called when the interactive confirmation flow finishes (success or
64
70
  * terminal failure). Not settlement proof — verify via webhooks.