@funnelsgrove/payments 0.11.21 → 0.11.23

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.
@@ -1,7 +1,8 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useEffect, useMemo, useState } from 'react';
4
- import { apiService, buildPreviewManageSubscriptionsFallback, isPreviewFrameRuntime, runtimePublicConfig, useFunnel, } from '@funnelsgrove/runtime';
4
+ import { manageSubscriptionStyles } from './ManageSubscriptionScreen.styles.js';
5
+ import { apiService, buildPreviewManageSubscriptionsFallback, isPreviewFrameRuntime, runtimePublicConfig, useFunnel, useFunnelRuntimeConfig, } from '@funnelsgrove/runtime';
5
6
  import { getFallbackBillingPlans } from '../services/planCatalog.service.js';
6
7
  const pastSubscriptionsNote = 'Past subscriptions are already canceled or expired. Dates below are historical, not upcoming charges.';
7
8
  const cancelledSubscriptionsNote = 'These subscriptions are cancelled and remain active until the date shown below.';
@@ -81,6 +82,8 @@ const resolveSubscriptionStatusLabel = (subscription) => {
81
82
  export function ManageSubscriptionScreen({ stepId, content, homeStepId, nodeId, plans, }) {
82
83
  var _a, _b;
83
84
  const { attributes, goToStep, setAnswer, setUser, user } = useFunnel();
85
+ const { config: publishedRuntimeConfig } = useFunnelRuntimeConfig();
86
+ const paymentsApiVersion = publishedRuntimeConfig === null || publishedRuntimeConfig === void 0 ? void 0 : publishedRuntimeConfig.paymentsApiVersion;
84
87
  const supportEmail = runtimePublicConfig.supportEmail;
85
88
  const planList = useMemo(() => getFallbackBillingPlans(plans), [plans]);
86
89
  const [stage, setStage] = useState('subscriptions');
@@ -105,7 +108,7 @@ export function ManageSubscriptionScreen({ stepId, content, homeStepId, nodeId,
105
108
  return;
106
109
  }
107
110
  try {
108
- const payload = await apiService.getManageSubscriptions();
111
+ const payload = await apiService.getManageSubscriptions({ paymentsApiVersion });
109
112
  if (active) {
110
113
  setData(payload);
111
114
  }
@@ -125,7 +128,7 @@ export function ManageSubscriptionScreen({ stepId, content, homeStepId, nodeId,
125
128
  return () => {
126
129
  active = false;
127
130
  };
128
- }, [content.errorMessages.load]);
131
+ }, [content.errorMessages.load, paymentsApiVersion]);
129
132
  const subscriptions = useMemo(() => { var _a; return toManageSubscriptions((_a = data === null || data === void 0 ? void 0 : data.subscriptions) !== null && _a !== void 0 ? _a : []); }, [data]);
130
133
  const activeSubscriptions = useMemo(() => subscriptions.filter(isCancellableSubscription), [subscriptions]);
131
134
  const cancelledSubscriptions = useMemo(() => subscriptions.filter(isCancelledActiveSubscription), [subscriptions]);
@@ -179,7 +182,9 @@ export function ManageSubscriptionScreen({ stepId, content, homeStepId, nodeId,
179
182
  });
180
183
  const payload = await apiService.updateSubscription({
181
184
  subscriptionId: selectedSubscription.id,
185
+ subscriptionRef: selectedSubscription.subscriptionRef,
182
186
  action: 'cancel',
187
+ runtimeConfig: { paymentsApiVersion },
183
188
  });
184
189
  setData(payload);
185
190
  const refreshedSubscription = toManageSubscriptions(payload.subscriptions).find((subscription) => subscription.id === selectedSubscription.id);
@@ -222,313 +227,6 @@ function SubscriptionSection({ title, subscriptions, plans, onSelect, descriptio
222
227
  ? resolveBillingDateLabel(subscription, { cancelled })
223
228
  : resolveBillingDateLabel(subscription, { past }) }), _jsxs("span", { children: ["Created at: ", resolveCreatedDate(subscription)] })] })] }) }, subscription.id))) })] }));
224
229
  }
225
- const manageSubscriptionStyles = `
226
- .funnel-shell[data-preview-frame='true'] {
227
- min-width: 0;
228
- }
229
-
230
- .manage-subscription {
231
- position: absolute;
232
- inset: 0;
233
- max-width: 100%;
234
- overflow-y: auto;
235
- box-sizing: border-box;
236
- background: color-mix(in srgb, var(--color-primary, #4db53f) 8%, var(--color-surface, #fff) 92%);
237
- color: var(--color-text, #262729);
238
- font-family: var(--font-family-base, Inter, sans-serif);
239
- }
240
-
241
- .manage-subscription-inner,
242
- .manage-subscription-section,
243
- .manage-subscription-list,
244
- .manage-subscription-row,
245
- .manage-subscription-row-heading,
246
- .manage-subscription-row-meta,
247
- .manage-subscription-support {
248
- min-width: 0;
249
- max-width: 100%;
250
- }
251
-
252
- .manage-subscription-inner {
253
- box-sizing: border-box;
254
- min-height: 100%;
255
- padding: 22px 12px 32px;
256
- }
257
-
258
- .manage-subscription-inner.is-short {
259
- padding-top: 22px;
260
- }
261
-
262
- .manage-subscription-title {
263
- margin: 0;
264
- color: var(--color-text, #262729);
265
- font-size: 20px;
266
- line-height: 1.3;
267
- font-weight: 800;
268
- text-align: center;
269
- }
270
-
271
- .manage-subscription-title.is-reason {
272
- max-width: 620px;
273
- margin-inline: auto;
274
- }
275
-
276
- .manage-subscription-section {
277
- margin-top: 22px;
278
- }
279
-
280
- .manage-subscription-section h2 {
281
- margin: 0 0 10px;
282
- color: var(--color-text, #262729);
283
- font-size: 15px;
284
- line-height: 1.25;
285
- font-weight: 800;
286
- text-align: center;
287
- }
288
-
289
- .manage-subscription-section-note {
290
- margin: 0 0 12px;
291
- color: color-mix(in srgb, var(--color-text, #262729) 72%, transparent);
292
- font-size: 13px;
293
- line-height: 1.35;
294
- text-align: center;
295
- }
296
-
297
- .manage-subscription-list {
298
- margin: 0;
299
- padding: 0;
300
- display: grid;
301
- gap: 8px;
302
- list-style: none;
303
- }
304
-
305
- .manage-subscription-row {
306
- width: 100%;
307
- min-height: 118px;
308
- border: 0;
309
- border-left: 4px solid var(--color-primary, #4db53f);
310
- border-radius: 6px;
311
- box-sizing: border-box;
312
- background: var(--color-surface, #fff);
313
- color: var(--color-text, #262729);
314
- display: grid;
315
- grid-template-columns: 1fr;
316
- justify-items: start;
317
- gap: 7px;
318
- padding: 10px 12px;
319
- text-align: left;
320
- cursor: pointer;
321
- }
322
-
323
- .manage-subscription-row.is-past {
324
- border-left-color: color-mix(in srgb, var(--color-text, #262729) 25%, var(--color-surface, #fff) 75%);
325
- color: color-mix(in srgb, var(--color-text, #262729) 68%, transparent);
326
- cursor: default;
327
- opacity: 0.82;
328
- }
329
-
330
- .manage-subscription-row.is-cancelled {
331
- border-left-color: var(--color-warning, #f28100);
332
- cursor: default;
333
- }
334
-
335
- .manage-subscription-radio {
336
- width: 14px;
337
- height: 14px;
338
- border: 2px solid color-mix(in srgb, var(--color-text, #262729) 45%, var(--color-surface, #fff) 55%);
339
- border-radius: 999px;
340
- display: block;
341
- }
342
-
343
- .manage-subscription-row-heading {
344
- width: 100%;
345
- display: flex;
346
- align-items: center;
347
- justify-content: space-between;
348
- gap: 8px;
349
- }
350
-
351
- .manage-subscription-row-title {
352
- font-size: 15px;
353
- line-height: 1.25;
354
- font-weight: 800;
355
- overflow-wrap: anywhere;
356
- }
357
-
358
- .manage-subscription-row-status {
359
- flex-shrink: 0;
360
- border-radius: 999px;
361
- background: color-mix(in srgb, var(--color-warning, #f28100) 16%, var(--color-surface, #fff) 84%);
362
- color: var(--color-warning, #f28100);
363
- padding: 3px 8px;
364
- font-size: 10px;
365
- line-height: 1.2;
366
- font-weight: 800;
367
- text-transform: uppercase;
368
- }
369
-
370
- .manage-subscription-row-plan {
371
- font-size: 13px;
372
- line-height: 1.2;
373
- font-weight: 800;
374
- overflow-wrap: anywhere;
375
- }
376
-
377
- .manage-subscription-row-meta {
378
- width: 100%;
379
- display: grid;
380
- grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
381
- gap: 8px;
382
- color: color-mix(in srgb, var(--color-text, #262729) 68%, transparent);
383
- font-size: 11px;
384
- font-style: italic;
385
- line-height: 1.3;
386
- }
387
-
388
- .manage-subscription-row-meta span {
389
- overflow-wrap: anywhere;
390
- }
391
-
392
- .manage-subscription-row-meta .is-active-until {
393
- color: var(--color-text, #262729);
394
- font-weight: 800;
395
- }
396
-
397
- .manage-subscription-support {
398
- margin: 30px 0 0;
399
- color: var(--color-text, #262729);
400
- font-size: 15px;
401
- line-height: 1.35;
402
- text-align: center;
403
- overflow-wrap: anywhere;
404
- }
405
-
406
- .manage-subscription-support a {
407
- color: var(--color-secondary, var(--color-primary, #4db53f));
408
- text-decoration: underline;
409
- text-underline-offset: 3px;
410
- overflow-wrap: anywhere;
411
- }
412
-
413
- .manage-subscription-muted,
414
- .manage-subscription-empty,
415
- .manage-subscription-error {
416
- margin: 18px 0 0;
417
- border-radius: 6px;
418
- background: var(--color-surface, #fff);
419
- padding: 12px;
420
- color: color-mix(in srgb, var(--color-text, #262729) 72%, transparent);
421
- font-size: 12px;
422
- line-height: 1.4;
423
- text-align: center;
424
- }
425
-
426
- .manage-subscription-error {
427
- color: var(--color-danger, #c74b43);
428
- }
429
-
430
- .manage-subscription-done-copy {
431
- margin: 15px 0 0;
432
- color: color-mix(in srgb, var(--color-text, #262729) 76%, transparent);
433
- font-size: 13px;
434
- line-height: 1.4;
435
- text-align: center;
436
- }
437
-
438
- .manage-subscription-done-copy.is-active-until {
439
- margin-top: 8px;
440
- color: var(--color-text, #262729);
441
- font-weight: 800;
442
- }
443
-
444
- .manage-subscription-done-status {
445
- width: fit-content;
446
- margin: 14px auto 0;
447
- border-radius: 999px;
448
- background: color-mix(in srgb, var(--color-warning, #f28100) 16%, var(--color-surface, #fff) 84%);
449
- color: var(--color-warning, #f28100);
450
- padding: 4px 10px;
451
- font-size: 11px;
452
- line-height: 1.2;
453
- font-weight: 800;
454
- text-transform: uppercase;
455
- }
456
-
457
- .manage-subscription-reasons {
458
- margin: 18px 0 0;
459
- padding: 0;
460
- display: grid;
461
- gap: 12px;
462
- list-style: none;
463
- }
464
-
465
- .manage-subscription-reason {
466
- width: 100%;
467
- min-height: 68px;
468
- border: 0;
469
- border-radius: 10px;
470
- box-sizing: border-box;
471
- background: var(--color-surface, #fff);
472
- color: var(--color-text, #262729);
473
- display: grid;
474
- grid-template-columns: 36px 1fr auto;
475
- align-items: center;
476
- gap: 8px;
477
- padding: 14px 16px;
478
- font-size: 15px;
479
- line-height: 1.25;
480
- font-weight: 800;
481
- text-align: left;
482
- cursor: pointer;
483
- }
484
-
485
- .manage-subscription-reason-icon {
486
- font-size: 20px;
487
- line-height: 1;
488
- }
489
-
490
- .manage-subscription-reason-arrow {
491
- color: var(--color-secondary, var(--color-primary, #4db53f));
492
- font-size: 28px;
493
- line-height: 0.8;
494
- }
495
-
496
- .manage-subscription-primary {
497
- margin-top: 18px;
498
- width: 100%;
499
- min-height: 56px;
500
- border: 0;
501
- border-radius: 5px;
502
- box-sizing: border-box;
503
- background: var(--color-primary, #4db53f);
504
- color: var(--color-primary-text, #fff);
505
- font-size: 19px;
506
- line-height: 1.2;
507
- font-weight: 800;
508
- cursor: pointer;
509
- }
510
-
511
- .manage-subscription-primary:disabled {
512
- opacity: 0.58;
513
- cursor: default;
514
- }
515
-
516
- @media (max-width: 420px) {
517
- .manage-subscription-title {
518
- font-size: 19px;
519
- }
520
-
521
- .manage-subscription-row-meta {
522
- grid-template-columns: 1fr;
523
- }
524
-
525
- .manage-subscription-reason {
526
- grid-template-columns: 32px 1fr auto;
527
- padding-inline: 14px;
528
- font-size: 14px;
529
- }
530
- }
531
- `;
532
230
  export const __manageSubscriptionScreenTestables = {
533
231
  resolveBillingDateLabel,
534
232
  resolveSubscriptionStatusLabel,
@@ -0,0 +1 @@
1
+ export declare const manageSubscriptionStyles = "\n.funnel-shell[data-preview-frame='true'] {\n min-width: 0;\n}\n\n.manage-subscription {\n position: absolute;\n inset: 0;\n max-width: 100%;\n overflow-y: auto;\n box-sizing: border-box;\n background: color-mix(in srgb, var(--color-primary, #4db53f) 8%, var(--color-surface, #fff) 92%);\n color: var(--color-text, #262729);\n font-family: var(--font-family-base, Inter, sans-serif);\n}\n\n.manage-subscription-inner,\n.manage-subscription-section,\n.manage-subscription-list,\n.manage-subscription-row,\n.manage-subscription-row-heading,\n.manage-subscription-row-meta,\n.manage-subscription-support {\n min-width: 0;\n max-width: 100%;\n}\n\n.manage-subscription-inner {\n box-sizing: border-box;\n min-height: 100%;\n padding: 22px 12px 32px;\n}\n\n.manage-subscription-inner.is-short {\n padding-top: 22px;\n}\n\n.manage-subscription-title {\n margin: 0;\n color: var(--color-text, #262729);\n font-size: 20px;\n line-height: 1.3;\n font-weight: 800;\n text-align: center;\n}\n\n.manage-subscription-title.is-reason {\n max-width: 620px;\n margin-inline: auto;\n}\n\n.manage-subscription-section {\n margin-top: 22px;\n}\n\n.manage-subscription-section h2 {\n margin: 0 0 10px;\n color: var(--color-text, #262729);\n font-size: 15px;\n line-height: 1.25;\n font-weight: 800;\n text-align: center;\n}\n\n.manage-subscription-section-note {\n margin: 0 0 12px;\n color: color-mix(in srgb, var(--color-text, #262729) 72%, transparent);\n font-size: 13px;\n line-height: 1.35;\n text-align: center;\n}\n\n.manage-subscription-list {\n margin: 0;\n padding: 0;\n display: grid;\n gap: 8px;\n list-style: none;\n}\n\n.manage-subscription-row {\n width: 100%;\n min-height: 118px;\n border: 0;\n border-left: 4px solid var(--color-primary, #4db53f);\n border-radius: 6px;\n box-sizing: border-box;\n background: var(--color-surface, #fff);\n color: var(--color-text, #262729);\n display: grid;\n grid-template-columns: 1fr;\n justify-items: start;\n gap: 7px;\n padding: 10px 12px;\n text-align: left;\n cursor: pointer;\n}\n\n.manage-subscription-row.is-past {\n border-left-color: color-mix(in srgb, var(--color-text, #262729) 25%, var(--color-surface, #fff) 75%);\n color: color-mix(in srgb, var(--color-text, #262729) 68%, transparent);\n cursor: default;\n opacity: 0.82;\n}\n\n.manage-subscription-row.is-cancelled {\n border-left-color: var(--color-warning, #f28100);\n cursor: default;\n}\n\n.manage-subscription-radio {\n width: 14px;\n height: 14px;\n border: 2px solid color-mix(in srgb, var(--color-text, #262729) 45%, var(--color-surface, #fff) 55%);\n border-radius: 999px;\n display: block;\n}\n\n.manage-subscription-row-heading {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.manage-subscription-row-title {\n font-size: 15px;\n line-height: 1.25;\n font-weight: 800;\n overflow-wrap: anywhere;\n}\n\n.manage-subscription-row-status {\n flex-shrink: 0;\n border-radius: 999px;\n background: color-mix(in srgb, var(--color-warning, #f28100) 16%, var(--color-surface, #fff) 84%);\n color: var(--color-warning, #f28100);\n padding: 3px 8px;\n font-size: 10px;\n line-height: 1.2;\n font-weight: 800;\n text-transform: uppercase;\n}\n\n.manage-subscription-row-plan {\n font-size: 13px;\n line-height: 1.2;\n font-weight: 800;\n overflow-wrap: anywhere;\n}\n\n.manage-subscription-row-meta {\n width: 100%;\n display: grid;\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n gap: 8px;\n color: color-mix(in srgb, var(--color-text, #262729) 68%, transparent);\n font-size: 11px;\n font-style: italic;\n line-height: 1.3;\n}\n\n.manage-subscription-row-meta span {\n overflow-wrap: anywhere;\n}\n\n.manage-subscription-row-meta .is-active-until {\n color: var(--color-text, #262729);\n font-weight: 800;\n}\n\n.manage-subscription-support {\n margin: 30px 0 0;\n color: var(--color-text, #262729);\n font-size: 15px;\n line-height: 1.35;\n text-align: center;\n overflow-wrap: anywhere;\n}\n\n.manage-subscription-support a {\n color: var(--color-secondary, var(--color-primary, #4db53f));\n text-decoration: underline;\n text-underline-offset: 3px;\n overflow-wrap: anywhere;\n}\n\n.manage-subscription-muted,\n.manage-subscription-empty,\n.manage-subscription-error {\n margin: 18px 0 0;\n border-radius: 6px;\n background: var(--color-surface, #fff);\n padding: 12px;\n color: color-mix(in srgb, var(--color-text, #262729) 72%, transparent);\n font-size: 12px;\n line-height: 1.4;\n text-align: center;\n}\n\n.manage-subscription-error {\n color: var(--color-danger, #c74b43);\n}\n\n.manage-subscription-done-copy {\n margin: 15px 0 0;\n color: color-mix(in srgb, var(--color-text, #262729) 76%, transparent);\n font-size: 13px;\n line-height: 1.4;\n text-align: center;\n}\n\n.manage-subscription-done-copy.is-active-until {\n margin-top: 8px;\n color: var(--color-text, #262729);\n font-weight: 800;\n}\n\n.manage-subscription-done-status {\n width: fit-content;\n margin: 14px auto 0;\n border-radius: 999px;\n background: color-mix(in srgb, var(--color-warning, #f28100) 16%, var(--color-surface, #fff) 84%);\n color: var(--color-warning, #f28100);\n padding: 4px 10px;\n font-size: 11px;\n line-height: 1.2;\n font-weight: 800;\n text-transform: uppercase;\n}\n\n.manage-subscription-reasons {\n margin: 18px 0 0;\n padding: 0;\n display: grid;\n gap: 12px;\n list-style: none;\n}\n\n.manage-subscription-reason {\n width: 100%;\n min-height: 68px;\n border: 0;\n border-radius: 10px;\n box-sizing: border-box;\n background: var(--color-surface, #fff);\n color: var(--color-text, #262729);\n display: grid;\n grid-template-columns: 36px 1fr auto;\n align-items: center;\n gap: 8px;\n padding: 14px 16px;\n font-size: 15px;\n line-height: 1.25;\n font-weight: 800;\n text-align: left;\n cursor: pointer;\n}\n\n.manage-subscription-reason-icon {\n font-size: 20px;\n line-height: 1;\n}\n\n.manage-subscription-reason-arrow {\n color: var(--color-secondary, var(--color-primary, #4db53f));\n font-size: 28px;\n line-height: 0.8;\n}\n\n.manage-subscription-primary {\n margin-top: 18px;\n width: 100%;\n min-height: 56px;\n border: 0;\n border-radius: 5px;\n box-sizing: border-box;\n background: var(--color-primary, #4db53f);\n color: var(--color-primary-text, #fff);\n font-size: 19px;\n line-height: 1.2;\n font-weight: 800;\n cursor: pointer;\n}\n\n.manage-subscription-primary:disabled {\n opacity: 0.58;\n cursor: default;\n}\n\n@media (max-width: 420px) {\n .manage-subscription-title {\n font-size: 19px;\n }\n\n .manage-subscription-row-meta {\n grid-template-columns: 1fr;\n }\n\n .manage-subscription-reason {\n grid-template-columns: 32px 1fr auto;\n padding-inline: 14px;\n font-size: 14px;\n }\n}\n";
@@ -0,0 +1,307 @@
1
+ export const manageSubscriptionStyles = `
2
+ .funnel-shell[data-preview-frame='true'] {
3
+ min-width: 0;
4
+ }
5
+
6
+ .manage-subscription {
7
+ position: absolute;
8
+ inset: 0;
9
+ max-width: 100%;
10
+ overflow-y: auto;
11
+ box-sizing: border-box;
12
+ background: color-mix(in srgb, var(--color-primary, #4db53f) 8%, var(--color-surface, #fff) 92%);
13
+ color: var(--color-text, #262729);
14
+ font-family: var(--font-family-base, Inter, sans-serif);
15
+ }
16
+
17
+ .manage-subscription-inner,
18
+ .manage-subscription-section,
19
+ .manage-subscription-list,
20
+ .manage-subscription-row,
21
+ .manage-subscription-row-heading,
22
+ .manage-subscription-row-meta,
23
+ .manage-subscription-support {
24
+ min-width: 0;
25
+ max-width: 100%;
26
+ }
27
+
28
+ .manage-subscription-inner {
29
+ box-sizing: border-box;
30
+ min-height: 100%;
31
+ padding: 22px 12px 32px;
32
+ }
33
+
34
+ .manage-subscription-inner.is-short {
35
+ padding-top: 22px;
36
+ }
37
+
38
+ .manage-subscription-title {
39
+ margin: 0;
40
+ color: var(--color-text, #262729);
41
+ font-size: 20px;
42
+ line-height: 1.3;
43
+ font-weight: 800;
44
+ text-align: center;
45
+ }
46
+
47
+ .manage-subscription-title.is-reason {
48
+ max-width: 620px;
49
+ margin-inline: auto;
50
+ }
51
+
52
+ .manage-subscription-section {
53
+ margin-top: 22px;
54
+ }
55
+
56
+ .manage-subscription-section h2 {
57
+ margin: 0 0 10px;
58
+ color: var(--color-text, #262729);
59
+ font-size: 15px;
60
+ line-height: 1.25;
61
+ font-weight: 800;
62
+ text-align: center;
63
+ }
64
+
65
+ .manage-subscription-section-note {
66
+ margin: 0 0 12px;
67
+ color: color-mix(in srgb, var(--color-text, #262729) 72%, transparent);
68
+ font-size: 13px;
69
+ line-height: 1.35;
70
+ text-align: center;
71
+ }
72
+
73
+ .manage-subscription-list {
74
+ margin: 0;
75
+ padding: 0;
76
+ display: grid;
77
+ gap: 8px;
78
+ list-style: none;
79
+ }
80
+
81
+ .manage-subscription-row {
82
+ width: 100%;
83
+ min-height: 118px;
84
+ border: 0;
85
+ border-left: 4px solid var(--color-primary, #4db53f);
86
+ border-radius: 6px;
87
+ box-sizing: border-box;
88
+ background: var(--color-surface, #fff);
89
+ color: var(--color-text, #262729);
90
+ display: grid;
91
+ grid-template-columns: 1fr;
92
+ justify-items: start;
93
+ gap: 7px;
94
+ padding: 10px 12px;
95
+ text-align: left;
96
+ cursor: pointer;
97
+ }
98
+
99
+ .manage-subscription-row.is-past {
100
+ border-left-color: color-mix(in srgb, var(--color-text, #262729) 25%, var(--color-surface, #fff) 75%);
101
+ color: color-mix(in srgb, var(--color-text, #262729) 68%, transparent);
102
+ cursor: default;
103
+ opacity: 0.82;
104
+ }
105
+
106
+ .manage-subscription-row.is-cancelled {
107
+ border-left-color: var(--color-warning, #f28100);
108
+ cursor: default;
109
+ }
110
+
111
+ .manage-subscription-radio {
112
+ width: 14px;
113
+ height: 14px;
114
+ border: 2px solid color-mix(in srgb, var(--color-text, #262729) 45%, var(--color-surface, #fff) 55%);
115
+ border-radius: 999px;
116
+ display: block;
117
+ }
118
+
119
+ .manage-subscription-row-heading {
120
+ width: 100%;
121
+ display: flex;
122
+ align-items: center;
123
+ justify-content: space-between;
124
+ gap: 8px;
125
+ }
126
+
127
+ .manage-subscription-row-title {
128
+ font-size: 15px;
129
+ line-height: 1.25;
130
+ font-weight: 800;
131
+ overflow-wrap: anywhere;
132
+ }
133
+
134
+ .manage-subscription-row-status {
135
+ flex-shrink: 0;
136
+ border-radius: 999px;
137
+ background: color-mix(in srgb, var(--color-warning, #f28100) 16%, var(--color-surface, #fff) 84%);
138
+ color: var(--color-warning, #f28100);
139
+ padding: 3px 8px;
140
+ font-size: 10px;
141
+ line-height: 1.2;
142
+ font-weight: 800;
143
+ text-transform: uppercase;
144
+ }
145
+
146
+ .manage-subscription-row-plan {
147
+ font-size: 13px;
148
+ line-height: 1.2;
149
+ font-weight: 800;
150
+ overflow-wrap: anywhere;
151
+ }
152
+
153
+ .manage-subscription-row-meta {
154
+ width: 100%;
155
+ display: grid;
156
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
157
+ gap: 8px;
158
+ color: color-mix(in srgb, var(--color-text, #262729) 68%, transparent);
159
+ font-size: 11px;
160
+ font-style: italic;
161
+ line-height: 1.3;
162
+ }
163
+
164
+ .manage-subscription-row-meta span {
165
+ overflow-wrap: anywhere;
166
+ }
167
+
168
+ .manage-subscription-row-meta .is-active-until {
169
+ color: var(--color-text, #262729);
170
+ font-weight: 800;
171
+ }
172
+
173
+ .manage-subscription-support {
174
+ margin: 30px 0 0;
175
+ color: var(--color-text, #262729);
176
+ font-size: 15px;
177
+ line-height: 1.35;
178
+ text-align: center;
179
+ overflow-wrap: anywhere;
180
+ }
181
+
182
+ .manage-subscription-support a {
183
+ color: var(--color-secondary, var(--color-primary, #4db53f));
184
+ text-decoration: underline;
185
+ text-underline-offset: 3px;
186
+ overflow-wrap: anywhere;
187
+ }
188
+
189
+ .manage-subscription-muted,
190
+ .manage-subscription-empty,
191
+ .manage-subscription-error {
192
+ margin: 18px 0 0;
193
+ border-radius: 6px;
194
+ background: var(--color-surface, #fff);
195
+ padding: 12px;
196
+ color: color-mix(in srgb, var(--color-text, #262729) 72%, transparent);
197
+ font-size: 12px;
198
+ line-height: 1.4;
199
+ text-align: center;
200
+ }
201
+
202
+ .manage-subscription-error {
203
+ color: var(--color-danger, #c74b43);
204
+ }
205
+
206
+ .manage-subscription-done-copy {
207
+ margin: 15px 0 0;
208
+ color: color-mix(in srgb, var(--color-text, #262729) 76%, transparent);
209
+ font-size: 13px;
210
+ line-height: 1.4;
211
+ text-align: center;
212
+ }
213
+
214
+ .manage-subscription-done-copy.is-active-until {
215
+ margin-top: 8px;
216
+ color: var(--color-text, #262729);
217
+ font-weight: 800;
218
+ }
219
+
220
+ .manage-subscription-done-status {
221
+ width: fit-content;
222
+ margin: 14px auto 0;
223
+ border-radius: 999px;
224
+ background: color-mix(in srgb, var(--color-warning, #f28100) 16%, var(--color-surface, #fff) 84%);
225
+ color: var(--color-warning, #f28100);
226
+ padding: 4px 10px;
227
+ font-size: 11px;
228
+ line-height: 1.2;
229
+ font-weight: 800;
230
+ text-transform: uppercase;
231
+ }
232
+
233
+ .manage-subscription-reasons {
234
+ margin: 18px 0 0;
235
+ padding: 0;
236
+ display: grid;
237
+ gap: 12px;
238
+ list-style: none;
239
+ }
240
+
241
+ .manage-subscription-reason {
242
+ width: 100%;
243
+ min-height: 68px;
244
+ border: 0;
245
+ border-radius: 10px;
246
+ box-sizing: border-box;
247
+ background: var(--color-surface, #fff);
248
+ color: var(--color-text, #262729);
249
+ display: grid;
250
+ grid-template-columns: 36px 1fr auto;
251
+ align-items: center;
252
+ gap: 8px;
253
+ padding: 14px 16px;
254
+ font-size: 15px;
255
+ line-height: 1.25;
256
+ font-weight: 800;
257
+ text-align: left;
258
+ cursor: pointer;
259
+ }
260
+
261
+ .manage-subscription-reason-icon {
262
+ font-size: 20px;
263
+ line-height: 1;
264
+ }
265
+
266
+ .manage-subscription-reason-arrow {
267
+ color: var(--color-secondary, var(--color-primary, #4db53f));
268
+ font-size: 28px;
269
+ line-height: 0.8;
270
+ }
271
+
272
+ .manage-subscription-primary {
273
+ margin-top: 18px;
274
+ width: 100%;
275
+ min-height: 56px;
276
+ border: 0;
277
+ border-radius: 5px;
278
+ box-sizing: border-box;
279
+ background: var(--color-primary, #4db53f);
280
+ color: var(--color-primary-text, #fff);
281
+ font-size: 19px;
282
+ line-height: 1.2;
283
+ font-weight: 800;
284
+ cursor: pointer;
285
+ }
286
+
287
+ .manage-subscription-primary:disabled {
288
+ opacity: 0.58;
289
+ cursor: default;
290
+ }
291
+
292
+ @media (max-width: 420px) {
293
+ .manage-subscription-title {
294
+ font-size: 19px;
295
+ }
296
+
297
+ .manage-subscription-row-meta {
298
+ grid-template-columns: 1fr;
299
+ }
300
+
301
+ .manage-subscription-reason {
302
+ grid-template-columns: 32px 1fr auto;
303
+ padding-inline: 14px;
304
+ font-size: 14px;
305
+ }
306
+ }
307
+ `;
@@ -303,14 +303,15 @@ export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAna
303
303
  }
304
304
  onCancel === null || onCancel === void 0 ? void 0 : onCancel();
305
305
  };
306
- return (_jsxs(_Fragment, { children: [_jsx("div", { "aria-busy": serverUpdatePending || undefined, "aria-disabled": serverUpdatePending || undefined, className: [
306
+ const inertWhileUpdating = (serverUpdatePending ? { inert: true } : {});
307
+ return (_jsxs(_Fragment, { children: [_jsx("div", Object.assign({}, inertWhileUpdating, { "aria-busy": serverUpdatePending || undefined, "aria-disabled": serverUpdatePending || undefined, className: [
307
308
  'stripe-express-checkout-button',
308
309
  className !== null && className !== void 0 ? className : '',
309
310
  effectiveWalletAvailable === false ? 'is-hidden' : '',
310
311
  serverUpdatePending ? 'is-server-update-pending' : '',
311
312
  ]
312
313
  .filter(Boolean)
313
- .join(' '), inert: serverUpdatePending, children: _jsx(ExpressCheckoutElementWithCancel, { options: resolvedOptions, onCancel: handleCancel, onClick: handleClick, onConfirm: (event) => void handleConfirm(event), onLoadError: ({ error }) => {
314
+ .join(' '), children: _jsx(ExpressCheckoutElementWithCancel, { options: resolvedOptions, onCancel: handleCancel, onClick: handleClick, onConfirm: (event) => void handleConfirm(event), onLoadError: ({ error }) => {
314
315
  setWalletAvailable(false);
315
316
  onAvailabilityChange === null || onAvailabilityChange === void 0 ? void 0 : onAvailabilityChange(false);
316
317
  reportFailure(error.message || 'Unable to load wallet checkout.', 'wallet_load');
@@ -322,7 +323,7 @@ export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAna
322
323
  if (resolvedAvailable) {
323
324
  onError === null || onError === void 0 ? void 0 : onError(null);
324
325
  }
325
- } }) }), _jsx("style", { children: stripeExpressCheckoutButtonStyles })] }));
326
+ } }) })), _jsx("style", { children: stripeExpressCheckoutButtonStyles })] }));
326
327
  }
327
328
  const stripeExpressCheckoutButtonStyles = `
328
329
  .stripe-express-checkout-button {
@@ -12,6 +12,7 @@ export type WalletCheckoutSmokeProfile = {
12
12
  };
13
13
  export type WalletCheckoutSmokeSnapshot = {
14
14
  blockingOverlayVisible: boolean;
15
+ cardDialogVisible: boolean;
15
16
  cardFallbackVisible: boolean;
16
17
  subscriptionRequestSucceeded: boolean;
17
18
  walletSlotState: 'ready' | 'unavailable' | 'unknown';
@@ -22,6 +23,7 @@ export type WalletCheckoutSmokeEvaluation = {
22
23
  };
23
24
  export type WalletCheckoutSmokeSelectors = {
24
25
  blockingOverlay?: string;
26
+ cardDialog: string;
25
27
  cardFallback: string;
26
28
  walletSlot: string;
27
29
  };
@@ -57,6 +57,9 @@ export function evaluateWalletCheckoutSmokeSnapshot(snapshot) {
57
57
  if (!snapshot.cardFallbackVisible) {
58
58
  failures.push('card fallback checkout is not visible');
59
59
  }
60
+ if (!snapshot.cardDialogVisible) {
61
+ failures.push('card checkout dialog did not open');
62
+ }
60
63
  if (snapshot.blockingOverlayVisible) {
61
64
  failures.push('a blocking loader or modal is still visible');
62
65
  }
@@ -69,7 +72,7 @@ export async function runWalletCheckoutSmokeTest(chromium, options) {
69
72
  var _a, _b, _c;
70
73
  const profiles = (_a = options.profiles) !== null && _a !== void 0 ? _a : buildWalletCheckoutSmokeProfiles();
71
74
  const timeoutMs = (_b = options.timeoutMs) !== null && _b !== void 0 ? _b : 15000;
72
- const subscriptionRequestPath = (_c = options.subscriptionRequestPath) !== null && _c !== void 0 ? _c : '/sdk/public/payments/subscriptions';
75
+ const subscriptionRequestPath = (_c = options.subscriptionRequestPath) !== null && _c !== void 0 ? _c : '/sdk/public/v2/payments/checkout-sessions';
73
76
  const browser = await chromium.launch({ headless: true });
74
77
  try {
75
78
  const results = [];
@@ -102,20 +105,32 @@ export async function runWalletCheckoutSmokeTest(chromium, options) {
102
105
  timeout: timeoutMs,
103
106
  }).then(() => 'unavailable'),
104
107
  ]).catch(() => 'unknown');
108
+ const cardFallbackVisible = await page
109
+ .isVisible(options.selectors.cardFallback, { timeout: timeoutMs })
110
+ .catch(() => false);
111
+ if (cardFallbackVisible) {
112
+ await page.click(options.selectors.cardFallback, { timeout: timeoutMs }).catch(() => undefined);
113
+ }
114
+ const cardDialogVisible = cardFallbackVisible
115
+ ? await page.waitForSelector(options.selectors.cardDialog, {
116
+ state: 'visible',
117
+ timeout: timeoutMs,
118
+ }).then(() => true).catch(() => false)
119
+ : false;
120
+ const blockingOverlayVisible = options.selectors.blockingOverlay
121
+ ? await page.waitForSelector(options.selectors.blockingOverlay, {
122
+ state: 'hidden',
123
+ timeout: timeoutMs,
124
+ }).then(() => false).catch(() => true)
125
+ : false;
105
126
  const snapshot = {
106
- blockingOverlayVisible: options.selectors.blockingOverlay
107
- ? await page.isVisible(options.selectors.blockingOverlay, { timeout: 500 }).catch(() => false)
108
- : false,
109
- cardFallbackVisible: await page
110
- .isVisible(options.selectors.cardFallback, { timeout: timeoutMs })
111
- .catch(() => false),
127
+ blockingOverlayVisible,
128
+ cardDialogVisible,
129
+ cardFallbackVisible,
112
130
  subscriptionRequestSucceeded: await subscriptionResponse,
113
131
  walletSlotState: walletSlotResolved,
114
132
  };
115
133
  const evaluation = evaluateWalletCheckoutSmokeSnapshot(snapshot);
116
- if (snapshot.cardFallbackVisible) {
117
- await page.click(options.selectors.cardFallback, { timeout: timeoutMs }).catch(() => undefined);
118
- }
119
134
  results.push(Object.assign(Object.assign({}, evaluation), { profileId: profile.id, snapshot }));
120
135
  }
121
136
  finally {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funnelsgrove/payments",
3
- "version": "0.11.21",
3
+ "version": "0.11.23",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/The-Solid-Grove/funnelsgrove.git",