fontdue-js 2.16.1 → 2.17.0

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 (113) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/__generated__/AddressFieldsRefetchQuery.graphql.d.ts +1 -1
  3. package/dist/__generated__/AddressFieldsRefetchQuery.graphql.js +25 -4
  4. package/dist/__generated__/AddressFields_viewer.graphql.d.ts +5 -1
  5. package/dist/__generated__/AddressFields_viewer.graphql.js +23 -2
  6. package/dist/__generated__/CartOrderCompleteOrderMutation.graphql.d.ts +1 -1
  7. package/dist/__generated__/CartOrderCompleteOrderMutation.graphql.js +10 -4
  8. package/dist/__generated__/CartOrderRemoveDiscountMutation.graphql.d.ts +1 -1
  9. package/dist/__generated__/CartOrderRemoveDiscountMutation.graphql.js +10 -4
  10. package/dist/__generated__/CartOrderUpdateMutation.graphql.d.ts +3 -2
  11. package/dist/__generated__/CartOrderUpdateMutation.graphql.js +10 -4
  12. package/dist/__generated__/CartQuery.graphql.d.ts +1 -1
  13. package/dist/__generated__/CartQuery.graphql.js +22 -4
  14. package/dist/__generated__/CartStateRemoveDiscountMutation.graphql.d.ts +1 -1
  15. package/dist/__generated__/CartStateRemoveDiscountMutation.graphql.js +43 -4
  16. package/dist/__generated__/CartStateUpdateMutation.graphql.d.ts +3 -2
  17. package/dist/__generated__/CartStateUpdateMutation.graphql.js +60 -53
  18. package/dist/__generated__/CartState_order.graphql.d.ts +2 -1
  19. package/dist/__generated__/CartState_order.graphql.js +8 -2
  20. package/dist/__generated__/CheckoutUpdateCustomerMutation.graphql.d.ts +1 -1
  21. package/dist/__generated__/CheckoutUpdateCustomerMutation.graphql.js +10 -4
  22. package/dist/__generated__/CheckoutUpdateOrderMutation.graphql.d.ts +5 -4
  23. package/dist/__generated__/CheckoutUpdateOrderMutation.graphql.js +10 -4
  24. package/dist/__generated__/Checkout_UpdateOrderErrors.graphql.d.ts +3 -3
  25. package/dist/__generated__/Checkout_UpdateOrderErrors.graphql.js +3 -3
  26. package/dist/__generated__/Checkout_identity.graphql.d.ts +2 -2
  27. package/dist/__generated__/Checkout_identity.graphql.js +3 -3
  28. package/dist/__generated__/Checkout_order.graphql.d.ts +3 -3
  29. package/dist/__generated__/Checkout_order.graphql.js +2 -2
  30. package/dist/__generated__/CouponCodeInputApplyCouponMutation.graphql.d.ts +1 -1
  31. package/dist/__generated__/CouponCodeInputApplyCouponMutation.graphql.js +43 -4
  32. package/dist/__generated__/CustomerLoginFormLoginMutation.graphql.d.ts +4 -1
  33. package/dist/__generated__/CustomerLoginFormLoginMutation.graphql.js +1 -1
  34. package/dist/__generated__/FontFamiliesQuery.graphql.d.ts +2 -1
  35. package/dist/__generated__/FontFamiliesQuery.graphql.js +1 -1
  36. package/dist/__generated__/OrderVariableSelectionRedux_viewer.graphql.d.ts +6 -1
  37. package/dist/__generated__/OrderVariableSelectionRedux_viewer.graphql.js +29 -2
  38. package/dist/__generated__/OrderVariableSelection_variables.graphql.d.ts +5 -1
  39. package/dist/__generated__/OrderVariableSelection_variables.graphql.js +31 -15
  40. package/dist/__generated__/PrecartAddToCartMutation.graphql.d.ts +2 -1
  41. package/dist/__generated__/PrecartAddToCartMutation.graphql.js +10 -4
  42. package/dist/__generated__/PriceBarSectionRefetchQuery.graphql.d.ts +2 -1
  43. package/dist/__generated__/PriceBarSectionRefetchQuery.graphql.js +1 -1
  44. package/dist/__generated__/StoreModalCartQuery.graphql.d.ts +8 -2
  45. package/dist/__generated__/StoreModalCartQuery.graphql.js +173 -126
  46. package/dist/__generated__/StoreModalIndexItem_fontCollection.graphql.d.ts +2 -1
  47. package/dist/__generated__/StoreModalIndexItem_fontCollection.graphql.js +8 -2
  48. package/dist/__generated__/StoreModalIndexQuery.graphql.d.ts +1 -1
  49. package/dist/__generated__/StoreModalIndexQuery.graphql.js +9 -3
  50. package/dist/__generated__/StoreModalOrderVariableSelection_order.graphql.d.ts +30 -0
  51. package/dist/__generated__/StoreModalOrderVariableSelection_order.graphql.js +98 -0
  52. package/dist/__generated__/StoreModalOrderVariableSelection_viewer.graphql.d.ts +1 -16
  53. package/dist/__generated__/StoreModalOrderVariableSelection_viewer.graphql.js +40 -104
  54. package/dist/__generated__/StoreModalProductQuery.graphql.d.ts +2 -1
  55. package/dist/__generated__/StoreModalProductQuery.graphql.js +24 -3
  56. package/dist/__generated__/StoreModalProductRefetchQuery.graphql.d.ts +2 -1
  57. package/dist/__generated__/StoreModalProductRefetchQuery.graphql.js +1 -1
  58. package/dist/__generated__/StoreModalProductSummaryAddToCartMutation.graphql.d.ts +2 -1
  59. package/dist/__generated__/StoreModalProductSummaryAddToCartMutation.graphql.js +1 -1
  60. package/dist/__generated__/StoreModalProductSummaryRefetchQuery.graphql.d.ts +2 -1
  61. package/dist/__generated__/StoreModalProductSummaryRefetchQuery.graphql.js +1 -1
  62. package/dist/__generated__/StoreModalUnifiedCheckoutCompleteOrderMutation.graphql.d.ts +1 -1
  63. package/dist/__generated__/StoreModalUnifiedCheckoutCompleteOrderMutation.graphql.js +43 -4
  64. package/dist/__generated__/StoreModalUnifiedCheckoutUpdateCustomerMutation.graphql.d.ts +1 -1
  65. package/dist/__generated__/StoreModalUnifiedCheckoutUpdateCustomerMutation.graphql.js +43 -4
  66. package/dist/__generated__/StoreModalUnifiedCheckoutUpdateOrderMutation.graphql.d.ts +5 -4
  67. package/dist/__generated__/StoreModalUnifiedCheckoutUpdateOrderMutation.graphql.js +43 -4
  68. package/dist/__generated__/StoreModalUnifiedCheckout_order.graphql.d.ts +13 -3
  69. package/dist/__generated__/StoreModalUnifiedCheckout_order.graphql.js +50 -4
  70. package/dist/__generated__/StoreModalUnifiedCheckout_viewer.graphql.d.ts +2 -1
  71. package/dist/__generated__/StoreModalUnifiedCheckout_viewer.graphql.js +8 -2
  72. package/dist/__generated__/TestFontsFormUpdateCustomerMutation.graphql.d.ts +1 -1
  73. package/dist/__generated__/TestFontsFormUpdateCustomerMutation.graphql.js +10 -4
  74. package/dist/__generated__/TypeTesterStandaloneChangedStylesQuery.graphql.d.ts +2 -1
  75. package/dist/__generated__/TypeTesterStandaloneChangedStylesQuery.graphql.js +9 -3
  76. package/dist/__generated__/TypeTesterStandaloneQuery.graphql.d.ts +1 -1
  77. package/dist/__generated__/TypeTesterStandaloneQuery.graphql.js +30 -14
  78. package/dist/__generated__/TypeTesterStyleSelectData_fontStyle.graphql.d.ts +2 -1
  79. package/dist/__generated__/TypeTesterStyleSelectData_fontStyle.graphql.js +8 -2
  80. package/dist/__generated__/TypeTesterStyleSelectData_viewer.graphql.d.ts +4 -1
  81. package/dist/__generated__/TypeTesterStyleSelectData_viewer.graphql.js +17 -2
  82. package/dist/__generated__/TypeTestersChangedStylesQuery.graphql.d.ts +2 -1
  83. package/dist/__generated__/TypeTestersChangedStylesQuery.graphql.js +9 -3
  84. package/dist/__generated__/TypeTestersIDQuery.graphql.d.ts +1 -1
  85. package/dist/__generated__/TypeTestersIDQuery.graphql.js +53 -37
  86. package/dist/__generated__/TypeTestersRefetchQuery.graphql.d.ts +2 -1
  87. package/dist/__generated__/TypeTestersRefetchQuery.graphql.js +9 -3
  88. package/dist/__generated__/TypeTestersSlugQuery.graphql.d.ts +1 -1
  89. package/dist/__generated__/TypeTestersSlugQuery.graphql.js +53 -37
  90. package/dist/components/Cart/AddressFields.d.ts +3 -2
  91. package/dist/components/Cart/AddressFields.js +45 -47
  92. package/dist/components/Cart/CartState.js +1 -1
  93. package/dist/components/Cart/CartTotals.d.ts +5 -2
  94. package/dist/components/Cart/CartTotals.js +24 -10
  95. package/dist/components/Cart/Checkout.js +33 -6
  96. package/dist/components/Cart/types.d.ts +1 -1
  97. package/dist/components/OrderVariableSelection/OrderVariableSelectionRedux.js +21 -1
  98. package/dist/components/OrderVariableSelection/index.d.ts +1 -0
  99. package/dist/components/OrderVariableSelection/index.js +23 -10
  100. package/dist/components/StoreModal/StoreModalCart.js +9 -6
  101. package/dist/components/StoreModal/StoreModalIndexItem.js +3 -3
  102. package/dist/components/StoreModal/StoreModalOrderVariableSelection.d.ts +3 -1
  103. package/dist/components/StoreModal/StoreModalOrderVariableSelection.js +9 -5
  104. package/dist/components/StoreModal/StoreModalStyleButton.js +1 -8
  105. package/dist/components/StripeProvider/index.js +5 -3
  106. package/dist/components/TypeTester/TypeTesterStyleSelectData.js +12 -3
  107. package/dist/components/elements/StoreModalUnifiedCheckout.d.ts +60 -1
  108. package/dist/components/elements/StoreModalUnifiedCheckout.js +409 -201
  109. package/dist/fontdue.css +36 -10
  110. package/dist/reducer.d.ts +1 -0
  111. package/dist/utils.d.ts +1 -0
  112. package/dist/utils.js +11 -2
  113. package/package.json +2 -1
@@ -10,14 +10,13 @@ var _StoreModalUnifiedCheckoutUpdateCustomerMutation2 = _interopRequireDefault(r
10
10
  var _StoreModalUnifiedCheckout_order2 = _interopRequireDefault(require("../../__generated__/StoreModalUnifiedCheckout_order.graphql"));
11
11
  var _StoreModalUnifiedCheckout_viewer2 = _interopRequireDefault(require("../../__generated__/StoreModalUnifiedCheckout_viewer.graphql"));
12
12
  var _react = _interopRequireWildcard(require("react"));
13
+ var Sentry = _interopRequireWildcard(require("@sentry/react"));
13
14
  var _reactRelay = require("react-relay");
14
15
  var _AddressFields = _interopRequireDefault(require("../Cart/AddressFields"));
15
16
  var _CustomerFields = _interopRequireDefault(require("../Cart/CustomerFields"));
16
- var _StoreModalReviewIdentity = _interopRequireDefault(require("../StoreModal/StoreModalReviewIdentity"));
17
17
  var _reactStripeJs = require("@stripe/react-stripe-js");
18
18
  var _StoreModalLicenseeIsBillingIdentityElement = _interopRequireDefault(require("./StoreModalLicenseeIsBillingIdentityElement"));
19
19
  var _reactRedux = require("react-redux");
20
- var _reactErrorBoundary = require("react-error-boundary");
21
20
  var _StripeLogo = _interopRequireDefault(require("../StripeLogo"));
22
21
  var _Icons = require("../Icons");
23
22
  var _ConfigContext = _interopRequireDefault(require("../ConfigContext"));
@@ -25,9 +24,68 @@ var _Price = require("../Price");
25
24
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
26
25
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
27
26
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
27
+ /**
28
+ * StoreModalUnifiedCheckout
29
+ *
30
+ * This component handles the checkout flow for orders, collecting customer information,
31
+ * billing/licensee details, and processing payment through Stripe.
32
+ *
33
+ * Key implementation details:
34
+ *
35
+ * 1. Auto-save billing identity (fontdue tax system only):
36
+ * - When using fontdue's tax system (not Stripe Tax), we need the billing address
37
+ * to calculate taxes before showing the final amount
38
+ * - The billing identity is auto-saved (with 500ms debounce) once the Stripe Address
39
+ * Element reports complete (name + address fields)
40
+ * - Email is a separate field (not part of Address Element), so auto-save may trigger
41
+ * before email is filled, which will cause backend validation errors to display
42
+ * - This ensures taxes are calculated and displayed before the user clicks Pay
43
+ * - On page reload, if billing identity already exists, billingAddressComplete starts
44
+ * as true to prevent re-triggering auto-save
45
+ *
46
+ * 2. Billing identity diff tracking:
47
+ * - We track differences between local state and saved backend data (billingIdentityDiff)
48
+ * - This determines isBillingIdentitySaved, which controls when payment can proceed
49
+ * - If the user edits any field after auto-save, it triggers another save cycle
50
+ * - All fields are normalized (null/undefined/empty string treated as equivalent)
51
+ *
52
+ * 3. Pay button validation:
53
+ * - The Pay button is always enabled (as long as EULA is checked) even if billing
54
+ * info isn't fully saved yet
55
+ * - This is intentional: we need to allow the user to click Pay so we can call
56
+ * elements.submit(), which triggers Stripe's validation and shows any validation
57
+ * errors inline in the Stripe UI elements
58
+ * - After Stripe validation passes, we check if billing identity is saved
59
+ * - If not saved, we show an error message above the Pay button asking them to
60
+ * complete billing information (validation errors should now be visible above)
61
+ *
62
+ * 4. Customer info pre-fill:
63
+ * - When customer submits their contact info, if billing name/email are empty,
64
+ * we pre-fill them from customer data as a convenience
65
+ *
66
+ * 5. Country mismatch handling (order snapshots):
67
+ * - When loading a hydrated order (e.g., from quote/snapshot), the order may have
68
+ * a country variable that differs from the user's detected country
69
+ * - In this case, we force licenseeIsBillingIdentity to false and always collect
70
+ * separate licensee information to ensure the licensee country matches the quote
71
+ * - This preserves pricing/availability from the original quote
72
+ *
73
+ * 6. Licensee country syncing:
74
+ * - When licensee country changes, it automatically updates any country-type order
75
+ * variables to maintain consistent pricing based on the selected country
76
+ *
77
+ * 7. Zero-order/coupon flow:
78
+ * - Orders with $0 total (due to coupons) bypass Stripe payment entirely
79
+ * - These use the completeOrder mutation instead of confirmPayment
80
+ *
81
+ * 8. Tax system variations:
82
+ * - Stripe Tax system: Uses embedded checkout, billing handled by Stripe
83
+ * - Fontdue tax system: Collects billing info directly, auto-saves for tax calculation
84
+ */
85
+
28
86
  /* const LICENSEE_REQUIRED_FIELDS = ['organization', 'country'] as (keyof Identity)[]; */
29
87
 
30
- const IDENTITY_REQUIRED_FIELDS = ['name', 'email', 'phone', 'country'];
88
+ const IDENTITY_REQUIRED_FIELDS = ['name', 'email', 'country'];
31
89
  const defaultIdentity = {
32
90
  name: '',
33
91
  organization: '',
@@ -43,17 +101,18 @@ const defaultIdentity = {
43
101
  };
44
102
  function getIdentityFields(object) {
45
103
  if (!object) return;
46
- const identityKeys = Object.keys(defaultIdentity);
47
- const result = {};
48
- for (const key of identityKeys) {
49
- if (key in object) {
50
- const value = object[key];
51
- if (value) result[key] = value;
52
- }
53
- }
54
104
  return {
55
- ...defaultIdentity,
56
- ...result
105
+ name: object.name ?? '',
106
+ organization: object.organization ?? null,
107
+ email: object.email ?? '',
108
+ phone: object.phoneNullable ?? '',
109
+ country: object.country ?? '',
110
+ administrativeArea: object.administrativeArea ?? null,
111
+ street: object.street ?? null,
112
+ locality: object.locality ?? null,
113
+ sublocality: object.sublocality ?? null,
114
+ zip: object.zip ?? null,
115
+ vatNumber: object.vatNumber ?? null
57
116
  };
58
117
  }
59
118
  function EditableSection(_ref) {
@@ -67,7 +126,8 @@ function EditableSection(_ref) {
67
126
  editing,
68
127
  children: {
69
128
  show,
70
- edit
129
+ edit,
130
+ save
71
131
  }
72
132
  } = _ref;
73
133
  const [submitting, setSubmitting] = (0, _react.useState)(false);
@@ -101,24 +161,54 @@ function EditableSection(_ref) {
101
161
  className: "store-modal__cart__button",
102
162
  type: "submit",
103
163
  disabled: submitting || disableSubmit
104
- }, submitting ? 'Submitting...' : 'Save'))) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, show, /*#__PURE__*/_react.default.createElement("button", {
164
+ }, submitting ? 'Submitting...' : save))) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, show, /*#__PURE__*/_react.default.createElement("button", {
105
165
  type: "button",
106
166
  className: "store-modal__cart__edit-button",
107
167
  onClick: onEdit
108
168
  }, "Change")));
109
169
  }
110
170
  function StoreModalUnifiedCheckout(_ref2) {
111
- var _viewer$settings, _viewer$settings2, _viewer$settings3, _order$stripePaymentI, _order$stripePaymentI2;
171
+ var _order$orderVariableS, _viewer$settings, _viewer$settings2, _viewer$settings3, _order$stripePaymentI, _order$stripePaymentI2;
112
172
  let {
113
173
  order: orderKey,
114
174
  viewer: viewerKey,
115
- onScrollToTop
175
+ onScrollToTop,
176
+ onUpdateOrderVariableSelections
116
177
  } = _ref2;
117
- const viewer = (0, _reactRelay.useFragment)((_StoreModalUnifiedCheckout_viewer2.default.hash && _StoreModalUnifiedCheckout_viewer2.default.hash !== "568763fc3756be6256c132ebf0fcacb7" && console.error("The definition of 'StoreModalUnifiedCheckout_viewer' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _StoreModalUnifiedCheckout_viewer2.default), viewerKey);
118
- const order = (0, _reactRelay.useFragment)((_StoreModalUnifiedCheckout_order2.default.hash && _StoreModalUnifiedCheckout_order2.default.hash !== "94683a80ba2c7104fd80f9e508cd6d70" && console.error("The definition of 'StoreModalUnifiedCheckout_order' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _StoreModalUnifiedCheckout_order2.default), orderKey);
178
+ const viewer = (0, _reactRelay.useFragment)((_StoreModalUnifiedCheckout_viewer2.default.hash && _StoreModalUnifiedCheckout_viewer2.default.hash !== "83cc5e6f8d508fb1c2356a72b040f9b0" && console.error("The definition of 'StoreModalUnifiedCheckout_viewer' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _StoreModalUnifiedCheckout_viewer2.default), viewerKey);
179
+ const order = (0, _reactRelay.useFragment)((_StoreModalUnifiedCheckout_order2.default.hash && _StoreModalUnifiedCheckout_order2.default.hash !== "ea43fb766c4dd1183b46ddf449aa85bd" && console.error("The definition of 'StoreModalUnifiedCheckout_order' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _StoreModalUnifiedCheckout_order2.default), orderKey);
180
+
181
+ // Check if order has a country-type order variable with a different country than detected
182
+ // This is important for order snapshot/quote functionality where a quote was created for
183
+ // a different country than the user's detected country. In this case, we must collect
184
+ // licensee information to ensure the country variable matches the licensee's country.
185
+ // If the countries match (or no country variable exists), allow the normal checkout flow.
186
+ const countryVariableSelection = (_order$orderVariableS = order.orderVariableSelections) === null || _order$orderVariableS === void 0 ? void 0 : _order$orderVariableS.find(selection => selection.orderVariable.variableType === 'country');
187
+ const hasCountryMismatch = countryVariableSelection && countryVariableSelection.countryCode && countryVariableSelection.countryCode !== viewer.detectedCountry;
188
+
189
+ // When loading a hydrated order (e.g., from order snapshot/quote), initialize the
190
+ // licensee country from the order variable country if no licensee country exists yet.
191
+ // This is useful for the "order snapshot" functionality where we want to preserve
192
+ // the original country selection from the quote.
193
+ const getInitialCountry = () => {
194
+ var _order$licenseeIdenti, _order$orderVariableS2;
195
+ // If order already has a licensee identity with country, use that
196
+ if (order !== null && order !== void 0 && (_order$licenseeIdenti = order.licenseeIdentity) !== null && _order$licenseeIdenti !== void 0 && _order$licenseeIdenti.country) {
197
+ return order.licenseeIdentity.country;
198
+ }
199
+
200
+ // Otherwise, check if there's a country-type order variable selection
201
+ const countryVariableSelection = order === null || order === void 0 ? void 0 : (_order$orderVariableS2 = order.orderVariableSelections) === null || _order$orderVariableS2 === void 0 ? void 0 : _order$orderVariableS2.find(selection => selection.orderVariable.variableType === 'country');
202
+ if (countryVariableSelection !== null && countryVariableSelection !== void 0 && countryVariableSelection.countryCode) {
203
+ return countryVariableSelection.countryCode;
204
+ }
205
+
206
+ // Fall back to detected country or viewer country
207
+ return viewer.detectedCountry ?? viewer.country;
208
+ };
119
209
  const initialIdentity = {
120
210
  ...defaultIdentity,
121
- country: viewer.country
211
+ country: getInitialCountry()
122
212
  };
123
213
  const [customer, setCustomer] = (0, _react.useState)((order === null || order === void 0 ? void 0 : order.customer) ?? {
124
214
  name: null,
@@ -127,22 +217,69 @@ function StoreModalUnifiedCheckout(_ref2) {
127
217
  });
128
218
  const [licenseeIdentity, setLicenseeIdentity] = (0, _react.useState)(getIdentityFields(order === null || order === void 0 ? void 0 : order.licenseeIdentity) ?? initialIdentity);
129
219
  const [billingIdentity, setBillingIdentity] = (0, _react.useState)(getIdentityFields(order === null || order === void 0 ? void 0 : order.billingIdentity) ?? initialIdentity);
220
+
221
+ // Track if the Stripe Address Element reports as complete
222
+ // Start as true if order already has billing identity (page reload case)
223
+ const [billingAddressComplete, setBillingAddressComplete] = (0, _react.useState)(!!(order !== null && order !== void 0 && order.billingIdentity));
224
+
225
+ // Track differences between local state and saved backend data
226
+ const billingIdentityDiff = (0, _react.useMemo)(() => {
227
+ const savedIdentity = order === null || order === void 0 ? void 0 : order.billingIdentity;
228
+ if (!savedIdentity) return null;
229
+
230
+ // Helper to normalize values (treat null, undefined, and empty string as equivalent)
231
+ const normalize = val => val || '';
232
+ const differences = {};
233
+ const checkField = (field, localValue, savedValue) => {
234
+ const normalizedLocal = normalize(localValue);
235
+ const normalizedSaved = normalize(savedValue);
236
+ if (normalizedLocal !== normalizedSaved) {
237
+ differences[field] = {
238
+ local: normalizedLocal,
239
+ saved: normalizedSaved
240
+ };
241
+ }
242
+ };
243
+ checkField('name', billingIdentity.name, savedIdentity.name);
244
+ checkField('email', billingIdentity.email, savedIdentity.email);
245
+ checkField('phone', billingIdentity.phone, savedIdentity.phoneNullable);
246
+ checkField('country', billingIdentity.country, savedIdentity.country);
247
+ checkField('street', billingIdentity.street, savedIdentity.street);
248
+ checkField('locality', billingIdentity.locality, savedIdentity.locality);
249
+ checkField('sublocality', billingIdentity.sublocality, savedIdentity.sublocality);
250
+ checkField('administrativeArea', billingIdentity.administrativeArea, savedIdentity.administrativeArea);
251
+ checkField('zip', billingIdentity.zip, savedIdentity.zip);
252
+ checkField('organization', billingIdentity.organization, savedIdentity.organization);
253
+ checkField('vatNumber', billingIdentity.vatNumber, savedIdentity.vatNumber);
254
+ return Object.keys(differences).length > 0 ? differences : null;
255
+ }, [billingIdentity, order === null || order === void 0 ? void 0 : order.billingIdentity]);
256
+ const isBillingIdentitySaved = billingIdentityDiff === null && !!(order !== null && order !== void 0 && order.billingIdentity);
130
257
  const handleCustomerChange = (0, _react.useCallback)(value => setCustomer(currentValue => ({
131
258
  ...currentValue,
132
259
  ...value
133
260
  })), [setCustomer]);
134
261
  const handleLicenseeChange = (0, _react.useCallback)(value => {
262
+ setErrorsObject(currentValue => {
263
+ if (currentValue !== null && currentValue !== void 0 && currentValue.licenseeIdentity) {
264
+ const keys = Object.keys(value);
265
+ return {
266
+ ...currentValue,
267
+ licenseeIdentity: {
268
+ ...currentValue.licenseeIdentity,
269
+ ...keys.reduce((acc, field) => {
270
+ acc[field] = null;
271
+ return acc;
272
+ }, {})
273
+ }
274
+ };
275
+ }
276
+ return currentValue;
277
+ });
135
278
  setLicenseeIdentity(currentValue => ({
136
279
  ...currentValue,
137
280
  ...value
138
281
  }));
139
282
  }, [setLicenseeIdentity]);
140
- const handleBillingChange = (0, _react.useCallback)(value => {
141
- setBillingIdentity(currentValue => ({
142
- ...currentValue,
143
- ...value
144
- }));
145
- }, [setBillingIdentity]);
146
283
  const environment = (0, _reactRelay.useRelayEnvironment)();
147
284
  const [error, setError] = (0, _react.useState)(null);
148
285
  const [errorsObject, setErrorsObject] = (0, _react.useState)(null);
@@ -173,7 +310,6 @@ function StoreModalUnifiedCheckout(_ref2) {
173
310
  const onError = error => {
174
311
  setError(error.message);
175
312
  setSubmitting(false);
176
- onScrollToTop();
177
313
  };
178
314
  const updateCustomer = (0, _react.useCallback)((variables, onSuccess) => {
179
315
  (0, _reactRelay.commitMutation)(environment, {
@@ -187,16 +323,76 @@ function StoreModalUnifiedCheckout(_ref2) {
187
323
  (0, _reactRelay.commitMutation)(environment, {
188
324
  mutation: (_StoreModalUnifiedCheckoutUpdateOrderMutation2.default.hash && _StoreModalUnifiedCheckoutUpdateOrderMutation2.default.hash !== "189cd7ac579c6898dca2f4b6e07861d1" && console.error("The definition of 'StoreModalUnifiedCheckoutUpdateOrderMutation' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _StoreModalUnifiedCheckoutUpdateOrderMutation2.default),
189
325
  variables,
190
- onCompleted: (res, errors) => onCompleted(res, errors, onSuccess),
326
+ onCompleted: (res, errors) => onCompleted(res, errors, onSuccess, onError),
191
327
  onError
192
328
  });
193
329
  }, [environment]);
330
+
331
+ // Update country order variable when licensee address country changes
332
+ (0, _react.useEffect)(() => {
333
+ if (!licenseeIdentity.country || !order.orderVariableSelections) return;
334
+
335
+ // Find country-type order variable
336
+ const countryVariableSelection = order.orderVariableSelections.find(selection => selection.orderVariable.variableType === 'country');
337
+ if (!countryVariableSelection) return;
338
+
339
+ // Only update if the country has actually changed
340
+ if (countryVariableSelection.countryCode === licenseeIdentity.country) return;
341
+
342
+ // Build updated selections array
343
+ const updatedSelections = order.orderVariableSelections.map(selection => {
344
+ var _selection$orderVaria;
345
+ return {
346
+ orderVariableId: selection.orderVariable.id,
347
+ orderVariableOptionId: ((_selection$orderVaria = selection.orderVariableOption) === null || _selection$orderVaria === void 0 ? void 0 : _selection$orderVaria.id) ?? null,
348
+ countryCode: selection.orderVariable.variableType === 'country' ? licenseeIdentity.country : selection.countryCode ?? null
349
+ };
350
+ });
351
+
352
+ // Update the order with new country via callback
353
+ onUpdateOrderVariableSelections(updatedSelections);
354
+ }, [licenseeIdentity.country, order.orderVariableSelections, onUpdateOrderVariableSelections]);
355
+
356
+ // When a country mismatch exists, force licenseeIsBillingIdentity to false
357
+ // This ensures we always collect licensee information for orders with mismatched country
358
+ (0, _react.useEffect)(() => {
359
+ if (hasCountryMismatch && (order.licenseeIsBillingIdentity ?? true)) {
360
+ // Update order to force separate licensee collection
361
+ updateOrder({
362
+ input: {
363
+ licenseeIsBillingIdentity: false
364
+ }
365
+ });
366
+ }
367
+ }, [hasCountryMismatch, order.licenseeIsBillingIdentity, updateOrder]);
368
+
369
+ // Auto-save billing identity when complete (for fontdue tax system only)
370
+ // This ensures taxes are calculated before showing the payment element
371
+ (0, _react.useEffect)(() => {
372
+ const taxSystem = viewer.settings.taxSystem;
373
+ const canUseEmbeddedCheckout = taxSystem === 'stripe';
374
+
375
+ // Only for fontdue tax system (not Stripe Tax/embedded checkout)
376
+ if (!canUseEmbeddedCheckout && order.customer && !isBillingIdentitySaved) {
377
+ // Check if the Stripe Address Element reports as complete AND email is filled
378
+ const isComplete = billingAddressComplete;
379
+ if (isComplete) {
380
+ // Debounce the update to avoid sending on every character change
381
+ const timeoutId = setTimeout(() => {
382
+ // Save billing identity to backend for tax calculation
383
+ updateOrder({
384
+ input: {
385
+ billingIdentity
386
+ }
387
+ });
388
+ }, 500); // 500ms debounce
389
+
390
+ return () => clearTimeout(timeoutId);
391
+ }
392
+ }
393
+ }, [billingIdentity, isBillingIdentitySaved, billingAddressComplete, order.customer, updateOrder, viewer.settings]);
194
394
  let initialEditingState = null;
195
395
  // set initial state depending on if checkout is already in progress
196
- if (!order.billingIdentity) initialEditingState = 'billing';
197
- if (order.licenseeIsBillingIdentity === false && !order.licenseeIdentity) {
198
- initialEditingState = 'licensee';
199
- }
200
396
  if (!order.customer) initialEditingState = 'customer';
201
397
  const [editing, setEditing] = (0, _react.useState)(initialEditingState);
202
398
  const handleCustomerSubmit = _ref3 => {
@@ -215,11 +411,6 @@ function StoreModalUnifiedCheckout(_ref2) {
215
411
  }, () => {
216
412
  onSuccess();
217
413
  setEditing(null);
218
- if (order.licenseeIsBillingIdentity) {
219
- if (!order.billingIdentity) setEditing('billing');
220
- } else {
221
- if (!order.licenseeIdentity) setEditing('licensee');
222
- }
223
414
  });
224
415
  };
225
416
  const handleLicenseeIsBillingIdentityChange = (0, _react.useCallback)(value => {
@@ -227,128 +418,185 @@ function StoreModalUnifiedCheckout(_ref2) {
227
418
  input: {
228
419
  licenseeIsBillingIdentity: value
229
420
  }
230
- }, () => {
231
- if (!value && !order.licenseeIdentity) {
232
- setEditing('licensee');
233
- }
234
- if (value && !order.billingIdentity) {
235
- setEditing('billing');
236
- }
237
421
  });
238
- }, [updateOrder, order.licenseeIdentity]);
239
- const handleLicenseeSubmit = _ref4 => {
240
- let {
241
- onSuccess,
242
- onError
243
- } = _ref4;
244
- updateOrder({
245
- input: {
246
- licenseeIdentity
422
+ }, [updateOrder]);
423
+ const handleBillingChange = (0, _react.useCallback)((value, complete) => {
424
+ setError(null);
425
+ setErrorsObject(currentValue => {
426
+ if (currentValue !== null && currentValue !== void 0 && currentValue.billingIdentity) {
427
+ const keys = Object.keys(value);
428
+ return {
429
+ ...currentValue,
430
+ billingIdentity: {
431
+ ...currentValue.billingIdentity,
432
+ ...keys.reduce((acc, field) => {
433
+ acc[field] = null;
434
+ return acc;
435
+ }, {})
436
+ }
437
+ };
247
438
  }
248
- }, () => {
249
- onSuccess();
250
- setEditing(null);
251
- if (!order.billingIdentity) setEditing('billing');
252
- }, onError);
253
- };
254
- const handleBillingSubmit = _ref5 => {
255
- let {
256
- onSuccess
257
- } = _ref5;
258
- updateOrder({
259
- input: {
260
- billingIdentity
439
+ return currentValue;
440
+ });
441
+ setBillingIdentity(currentValue => {
442
+ const newValue = {
443
+ ...currentValue,
444
+ ...value
445
+ };
446
+ if (typeof complete === 'boolean') {
447
+ setBillingAddressComplete(complete);
261
448
  }
262
- }, () => {
263
- onSuccess();
264
- setEditing(null);
449
+ return newValue;
265
450
  });
266
- };
451
+ }, [order === null || order === void 0 ? void 0 : order.billingIdentity]);
267
452
  const stripe = (0, _reactStripeJs.useStripe)();
268
453
  const elements = (0, _reactStripeJs.useElements)();
269
454
  const [completing, setCompleting] = (0, _react.useState)(false);
455
+ const [checkingOut, setCheckingOut] = (0, _react.useState)(false);
270
456
  const dispatch = (0, _reactRedux.useDispatch)();
271
- const handleCheckout = (0, _react.useCallback)(() => {
272
- dispatch({
273
- type: 'STORE_MODAL_NAVIGATE',
274
- route: 'checkout'
275
- });
276
- }, []);
277
- const handleComplete = e => {
278
- var _billingIdentity$stre, _billingIdentity$stre2;
457
+
458
+ // When a country mismatch exists, always show licensee section (force collection)
459
+ // Otherwise, only show when user has selected "Your client" option
460
+ const showLicenseeSection = order.customer && (hasCountryMismatch || !(order.licenseeIsBillingIdentity ?? false));
461
+ const handleCheckout = (0, _react.useCallback)(async () => {
462
+ // Validate Stripe elements first
463
+ if (elements) {
464
+ const result = await elements.submit();
465
+ if (result.error) {
466
+ // Stripe will show validation errors in the UI
467
+ return;
468
+ }
469
+ }
470
+
471
+ // If licensee section is shown, save licensee data before navigating to checkout
472
+ if (showLicenseeSection) {
473
+ setCheckingOut(true);
474
+ updateOrder({
475
+ input: {
476
+ licenseeIdentity
477
+ }
478
+ }, () => {
479
+ setCheckingOut(false);
480
+ dispatch({
481
+ type: 'STORE_MODAL_NAVIGATE',
482
+ route: 'checkout'
483
+ });
484
+ }, () => {
485
+ setCheckingOut(false);
486
+ });
487
+ } else {
488
+ dispatch({
489
+ type: 'STORE_MODAL_NAVIGATE',
490
+ route: 'checkout'
491
+ });
492
+ }
493
+ }, [showLicenseeSection, licenseeIdentity, updateOrder, dispatch, elements]);
494
+ const handleComplete = async e => {
279
495
  e.preventDefault();
280
496
  if (!order) return;
281
497
  if (!billingIdentity) {
282
498
  console.error('No billing identity, required for payment');
283
499
  return;
284
500
  }
501
+
502
+ // Validate Stripe elements first
503
+ if (elements) {
504
+ const result = await elements.submit();
505
+ if (result.error) {
506
+ // Stripe will show validation errors in the UI
507
+ return;
508
+ }
509
+ }
510
+
511
+ // If billing identity is not saved yet, don't proceed with payment
512
+ // The validation above will show errors for incomplete fields
513
+ if (!isBillingIdentitySaved) {
514
+ setError('Please complete all billing information above');
515
+ return;
516
+ }
285
517
  setCompleting(true);
286
518
  setError(null);
287
- if (order.canCompleteWithCoupon) {
288
- (0, _reactRelay.commitMutation)(environment, {
289
- mutation: (_StoreModalUnifiedCheckoutCompleteOrderMutation2.default.hash && _StoreModalUnifiedCheckoutCompleteOrderMutation2.default.hash !== "ea880419670573334e55529f454f8026" && console.error("The definition of 'StoreModalUnifiedCheckoutCompleteOrderMutation' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _StoreModalUnifiedCheckoutCompleteOrderMutation2.default),
290
- variables: {},
291
- onCompleted: (_response, errors) => {
292
- if (errors && errors.length > 0) {
293
- setCompleting(false);
294
- setError(errors[0].message);
295
- return;
519
+ const processPayment = () => {
520
+ var _billingIdentity$stre, _billingIdentity$stre2;
521
+ if (order.canCompleteWithCoupon) {
522
+ (0, _reactRelay.commitMutation)(environment, {
523
+ mutation: (_StoreModalUnifiedCheckoutCompleteOrderMutation2.default.hash && _StoreModalUnifiedCheckoutCompleteOrderMutation2.default.hash !== "ea880419670573334e55529f454f8026" && console.error("The definition of 'StoreModalUnifiedCheckoutCompleteOrderMutation' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _StoreModalUnifiedCheckoutCompleteOrderMutation2.default),
524
+ variables: {},
525
+ onCompleted: (_response, errors) => {
526
+ if (errors && errors.length > 0) {
527
+ setCompleting(false);
528
+ setError(errors[0].message);
529
+ return;
530
+ }
531
+ window.location.href = order.completeUrl;
296
532
  }
297
- window.location.href = order.completeUrl;
298
- }
299
- });
300
- return;
301
- }
302
- if (!stripe || !elements) return;
303
- stripe === null || stripe === void 0 ? void 0 : stripe.confirmPayment({
304
- elements,
305
- confirmParams: {
306
- return_url: order.completeUrl,
307
- payment_method_data: {
308
- billing_details: {
309
- email: billingIdentity.email,
310
- name: billingIdentity.name,
311
- phone: billingIdentity.phone,
312
- address: {
313
- line1: (_billingIdentity$stre = billingIdentity.street) === null || _billingIdentity$stre === void 0 ? void 0 : _billingIdentity$stre.split(/\n/)[0],
314
- line2: ((_billingIdentity$stre2 = billingIdentity.street) === null || _billingIdentity$stre2 === void 0 ? void 0 : _billingIdentity$stre2.split(/\n/)[1]) ?? '',
315
- city: billingIdentity.locality ?? '',
316
- state: billingIdentity.administrativeArea ?? '',
317
- country: billingIdentity.country,
318
- postal_code: billingIdentity.zip ?? ''
533
+ });
534
+ return;
535
+ }
536
+ if (!stripe || !elements) return;
537
+ stripe === null || stripe === void 0 ? void 0 : stripe.confirmPayment({
538
+ elements,
539
+ confirmParams: {
540
+ return_url: order.completeUrl,
541
+ payment_method_data: {
542
+ billing_details: {
543
+ email: billingIdentity.email,
544
+ name: billingIdentity.name,
545
+ phone: billingIdentity.phone,
546
+ address: {
547
+ line1: (_billingIdentity$stre = billingIdentity.street) === null || _billingIdentity$stre === void 0 ? void 0 : _billingIdentity$stre.split(/\n/)[0],
548
+ line2: ((_billingIdentity$stre2 = billingIdentity.street) === null || _billingIdentity$stre2 === void 0 ? void 0 : _billingIdentity$stre2.split(/\n/)[1]) ?? '',
549
+ city: billingIdentity.locality ?? '',
550
+ state: billingIdentity.administrativeArea ?? '',
551
+ country: billingIdentity.country,
552
+ postal_code: billingIdentity.zip ?? ''
553
+ }
319
554
  }
320
555
  }
321
556
  }
322
- }
323
- }).then(result => {
324
- if ('error' in result) {
557
+ }).then(result => {
558
+ if ('error' in result) {
559
+ setCompleting(false);
560
+ setError(result.error.message ?? 'Payment failed. Please try another payment method.');
561
+ }
562
+ }).catch(error => {
563
+ console.log(error);
325
564
  setCompleting(false);
326
- setError(result.error.message ?? 'Payment failed. Please try another payment method.');
327
- }
328
- }).catch(error => {
329
- console.log(error);
565
+ });
566
+ };
567
+
568
+ // Save both licensee (if shown) and billing info before processing payment
569
+ const orderInput = {
570
+ billingIdentity
571
+ };
572
+ if (showLicenseeSection) {
573
+ orderInput.licenseeIdentity = licenseeIdentity;
574
+ }
575
+ updateOrder({
576
+ input: orderInput
577
+ }, () => {
578
+ processPayment();
579
+ }, () => {
330
580
  setCompleting(false);
331
581
  });
332
582
  };
333
583
  const taxSystem = viewer.settings.taxSystem;
334
584
  const canUseEmbeddedCheckout = taxSystem === 'stripe';
335
- const showLicenseeSection = order.customer && !order.licenseeIsBillingIdentity;
336
- const hasLicensee = order.licenseeIsBillingIdentity ? true : Boolean(order.licenseeIdentity);
337
- const showBillingSection = !canUseEmbeddedCheckout && (order.customer && hasLicensee || order.billingIdentity);
585
+ const showBillingSection = !canUseEmbeddedCheckout && order.customer;
338
586
 
339
587
  // billing info will be handled by embedded checkout
340
588
  const showCheckoutButton = canUseEmbeddedCheckout && order.customer;
341
589
  const zeroOrder = order.canCompleteWithCoupon;
342
- const showPaymentSection = !canUseEmbeddedCheckout && order.customer && order.billingIdentity && hasLicensee;
343
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, error && /*#__PURE__*/_react.default.createElement("div", {
344
- className: "store-modal__cart__error"
345
- }, error), /*#__PURE__*/_react.default.createElement(EditableSection, {
590
+ const showPaymentSection = !canUseEmbeddedCheckout && order.customer;
591
+ const billingComplete = IDENTITY_REQUIRED_FIELDS.every(key => Boolean(billingIdentity[key]));
592
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(EditableSection, {
346
593
  editing: editing === 'customer',
347
594
  disabled: false,
348
595
  onEdit: () => setEditing('customer'),
349
596
  onSubmit: handleCustomerSubmit,
350
- disableSubmit: !customer.name || !customer.email
597
+ disableSubmit: false
351
598
  }, {
599
+ save: canUseEmbeddedCheckout ? order.customer ? 'Save' : 'Continue' : 'Checkout',
352
600
  show: /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("h3", {
353
601
  className: "store-modal__cart__checkout-section-title"
354
602
  }, "Contact information"), order.customer ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, order.customer.name, /*#__PURE__*/_react.default.createElement("br", null), order.customer.email) : 'Loading...'),
@@ -359,9 +607,9 @@ function StoreModalUnifiedCheckout(_ref2) {
359
607
  onChange: handleCustomerChange,
360
608
  optInLabel: (_viewer$settings = viewer.settings) === null || _viewer$settings === void 0 ? void 0 : _viewer$settings.newsletterOptInLabel
361
609
  }))
362
- }), order.customer ? /*#__PURE__*/_react.default.createElement(_StoreModalLicenseeIsBillingIdentityElement.default, {
610
+ }), order.customer && !hasCountryMismatch ? /*#__PURE__*/_react.default.createElement(_StoreModalLicenseeIsBillingIdentityElement.default, {
363
611
  disabled: false,
364
- value: order.licenseeIsBillingIdentity,
612
+ value: order.licenseeIsBillingIdentity ?? false,
365
613
  onChange: handleLicenseeIsBillingIdentityChange
366
614
  }, {
367
615
  label: /*#__PURE__*/_react.default.createElement("div", {
@@ -369,72 +617,42 @@ function StoreModalUnifiedCheckout(_ref2) {
369
617
  __html: ((_viewer$settings2 = viewer.settings) === null || _viewer$settings2 === void 0 ? void 0 : _viewer$settings2.storeModalSelectLicenseeLabel) ?? ''
370
618
  }
371
619
  })
372
- }) : null, showLicenseeSection ? /*#__PURE__*/_react.default.createElement(EditableSection, {
373
- disabled: false,
374
- editing: editing === 'licensee',
375
- onEdit: () => setEditing('licensee'),
376
- disableSubmit: Object.keys(licenseeIdentity).some(key => {
377
- if (IDENTITY_REQUIRED_FIELDS.includes(key)) return Boolean(licenseeIdentity[key]) === false;
378
- return false;
379
- }),
380
- onSubmit: handleLicenseeSubmit
381
- }, {
382
- edit: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("h3", {
383
- className: "store-modal__cart__checkout-section-title"
384
- }, "Licensee information (your client)"), /*#__PURE__*/_react.default.createElement("div", {
385
- className: "store-modal__cart__identity-fields"
386
- }, /*#__PURE__*/_react.default.createElement(_AddressFields.default, {
387
- viewer: viewer,
388
- value: licenseeIdentity,
389
- onChange: handleLicenseeChange,
390
- errorsObject: errorsObject === null || errorsObject === void 0 ? void 0 : errorsObject.licenseeIdentity,
391
- identityType: "licensee"
392
- }))),
393
- show: /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("h3", {
394
- className: "store-modal__cart__checkout-section-title"
395
- }, "Licensee information (your client)"), order.licenseeIdentity ? /*#__PURE__*/_react.default.createElement("div", {
396
- className: "store-modal__cart__identity"
397
- }, /*#__PURE__*/_react.default.createElement(_StoreModalReviewIdentity.default, {
398
- identity: order.licenseeIdentity
399
- })) : 'Loading...')
400
- }) : null, showBillingSection ? /*#__PURE__*/_react.default.createElement(EditableSection, {
401
- disabled: false,
402
- editing: editing === 'billing',
403
- onEdit: () => setEditing('billing'),
404
- disableSubmit: Object.keys(billingIdentity).some(key => {
405
- if (IDENTITY_REQUIRED_FIELDS.includes(key)) return Boolean(billingIdentity[key]) === false;
406
- return false;
407
- }),
408
- onSubmit: handleBillingSubmit
409
- }, {
410
- edit: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("h3", {
411
- className: "store-modal__cart__checkout-section-title"
412
- }, "Billing information"), /*#__PURE__*/_react.default.createElement("div", {
413
- className: "store-modal__cart__identity-fields"
414
- }, /*#__PURE__*/_react.default.createElement(_AddressFields.default, {
415
- viewer: viewer,
416
- value: billingIdentity,
417
- onChange: handleBillingChange,
418
- errorsObject: errorsObject === null || errorsObject === void 0 ? void 0 : errorsObject.billingIdentity,
419
- identityType: "billing"
420
- }))),
421
- show: /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("h3", {
422
- className: "store-modal__cart__checkout-section-title"
423
- }, "Billing information"), order.billingIdentity ? /*#__PURE__*/_react.default.createElement("div", {
424
- className: "store-modal__cart__identity"
425
- }, /*#__PURE__*/_react.default.createElement(_StoreModalReviewIdentity.default, {
426
- identity: order.billingIdentity
427
- })) : 'Loading...')
428
- }) : null, showCheckoutButton ? /*#__PURE__*/_react.default.createElement("div", {
620
+ }) : null, showLicenseeSection ? /*#__PURE__*/_react.default.createElement("div", {
621
+ className: "store-modal__cart__checkout-section"
622
+ }, /*#__PURE__*/_react.default.createElement("h3", {
623
+ className: "store-modal__cart__checkout-section-title"
624
+ }, hasCountryMismatch ? 'Licensee information' : 'Licensee information (your client)'), /*#__PURE__*/_react.default.createElement("div", {
625
+ className: "store-modal__cart__identity-fields"
626
+ }, /*#__PURE__*/_react.default.createElement(_AddressFields.default, {
627
+ viewer: viewer,
628
+ value: licenseeIdentity,
629
+ onChange: handleLicenseeChange,
630
+ errorsObject: errorsObject === null || errorsObject === void 0 ? void 0 : errorsObject.licenseeIdentity,
631
+ identityType: "licensee"
632
+ }))) : null, showBillingSection ? /*#__PURE__*/_react.default.createElement("div", {
429
633
  className: "store-modal__cart__checkout-section",
430
- "data-disabled": showLicenseeSection ? editing === 'licensee' : false
634
+ "data-disabled": !order.customer
635
+ }, /*#__PURE__*/_react.default.createElement("h3", {
636
+ className: "store-modal__cart__checkout-section-title"
637
+ }, "Billing information"), /*#__PURE__*/_react.default.createElement("div", {
638
+ className: "store-modal__cart__identity-fields"
639
+ }, /*#__PURE__*/_react.default.createElement(_AddressFields.default, {
640
+ viewer: viewer,
641
+ value: billingIdentity,
642
+ onChange: handleBillingChange,
643
+ errorsObject: errorsObject === null || errorsObject === void 0 ? void 0 : errorsObject.billingIdentity,
644
+ identityType: "billing"
645
+ }))) : null, showCheckoutButton ? /*#__PURE__*/_react.default.createElement("div", {
646
+ className: "store-modal__cart__checkout-section",
647
+ "data-disabled": false
431
648
  }, /*#__PURE__*/_react.default.createElement("button", {
432
649
  type: "button",
433
650
  className: "store-modal__cart__button",
434
- onClick: handleCheckout
435
- }, "Checkout")) : null, showPaymentSection ? /*#__PURE__*/_react.default.createElement("div", {
651
+ onClick: handleCheckout,
652
+ disabled: checkingOut
653
+ }, checkingOut ? 'Submitting...' : 'Checkout')) : null, showPaymentSection ? /*#__PURE__*/_react.default.createElement("div", {
436
654
  className: "store-modal__cart__checkout-section",
437
- "data-disabled": editing !== null
655
+ "data-disabled": false
438
656
  }, /*#__PURE__*/_react.default.createElement("form", {
439
657
  onSubmit: handleComplete
440
658
  }, !zeroOrder && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("h3", {
@@ -447,7 +665,7 @@ function StoreModalUnifiedCheckout(_ref2) {
447
665
  rel: "noopener"
448
666
  }, "Powered by ", /*#__PURE__*/_react.default.createElement(_StripeLogo.default, null)))), /*#__PURE__*/_react.default.createElement("div", {
449
667
  className: "store-modal__cart__payment"
450
- }, /*#__PURE__*/_react.default.createElement(_reactErrorBoundary.ErrorBoundary, {
668
+ }, /*#__PURE__*/_react.default.createElement(Sentry.ErrorBoundary, {
451
669
  fallback: /*#__PURE__*/_react.default.createElement("div", null, "Something went wrong")
452
670
  }, /*#__PURE__*/_react.default.createElement(_reactStripeJs.PaymentElement, {
453
671
  options: {
@@ -456,21 +674,11 @@ function StoreModalUnifiedCheckout(_ref2) {
456
674
  defaultCollapsed: false,
457
675
  radios: true,
458
676
  spacedAccordionItems: true
459
- },
460
- defaultValues: {
461
- billingDetails: {
462
- name: order.customer.name ?? undefined,
463
- email: order.customer.email ?? undefined,
464
- phone: order.billingIdentity.phone ?? undefined
465
- }
466
- },
467
- fields: {
468
- billingDetails: {
469
- address: 'never'
470
- }
471
677
  }
472
678
  }
473
- })))), /*#__PURE__*/_react.default.createElement("div", {
679
+ })))), error && /*#__PURE__*/_react.default.createElement("div", {
680
+ className: "store-modal__cart__error"
681
+ }, error), /*#__PURE__*/_react.default.createElement("div", {
474
682
  className: "store-modal__cart__agreement"
475
683
  }, /*#__PURE__*/_react.default.createElement("div", {
476
684
  className: "checkbox"