@shipengine/elements 2.27.0 → 2.29.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 (199) hide show
  1. package/dist/cjs/components/field/rate-select/rate-card/rate-card.cjs +1 -0
  2. package/dist/cjs/components/forms/edit-billing-form/edit-billing-form.cjs +87 -12
  3. package/dist/cjs/components/forms/edit-billing-form/edit-billing-form.styles.cjs +15 -0
  4. package/dist/cjs/components/forms/wallet-form/index.cjs +0 -2
  5. package/dist/cjs/components/forms/wallet-form/wallet-form.cjs +153 -23
  6. package/dist/cjs/components/forms/wallet-form/wallet-form.styles.cjs +15 -0
  7. package/dist/cjs/components/forms/wallet-form/wallet-schema.cjs +8 -43
  8. package/dist/cjs/components/forms/warehouse-form/warehouse-form.cjs +10 -1
  9. package/dist/cjs/components/payment/payment-method-selector/index.cjs +7 -0
  10. package/dist/cjs/components/payment/payment-method-selector/payment-method-selector.cjs +55 -0
  11. package/dist/cjs/components/payment/payment-method-selector/payment-method-selector.styles.cjs +58 -0
  12. package/dist/cjs/components/service-card/service-card.cjs +3 -2
  13. package/dist/cjs/components/service-card/service-card.styles.cjs +4 -2
  14. package/dist/cjs/contexts/auctane-pay-session-context.cjs +158 -0
  15. package/dist/cjs/contexts/index.cjs +8 -0
  16. package/dist/cjs/elements/labels-grid/hooks/use-labels-grid.cjs +2 -2
  17. package/dist/cjs/elements/labels-grid/labels-grid.cjs +29 -9
  18. package/dist/cjs/elements/labels-grid/labels-grid.styles.cjs +5 -0
  19. package/dist/cjs/elements/purchase-label/components/rate-form/rate-view.cjs +3 -5
  20. package/dist/cjs/elements/purchase-label/components/shipment-form/shipment-form.cjs +3 -1
  21. package/dist/cjs/elements/purchase-label/hooks/use-filter-visible-rate-options/use-filter-visible-rate-options.cjs +5 -5
  22. package/dist/cjs/elements/shipments-grid/hooks/use-shipments-grid.cjs +2 -2
  23. package/dist/cjs/elements/shipments-grid/shipments-grid.cjs +20 -6
  24. package/dist/cjs/elements/shipments-grid/shipments-grid.styles.cjs +5 -0
  25. package/dist/cjs/features/manage-warehouses/manage-warehouses.cjs +9 -5
  26. package/dist/cjs/features/payment-method-settings/payment-method-settings.cjs +4 -3
  27. package/dist/cjs/hooks/financial-services/financial-service.cjs +464 -0
  28. package/dist/cjs/hooks/financial-services/index.cjs +9 -0
  29. package/dist/cjs/hooks/financial-services/use-financial-service.cjs +188 -0
  30. package/dist/cjs/hooks/use-configure-shipment.cjs +8 -0
  31. package/dist/cjs/hooks/use-get-service-data.cjs +60 -0
  32. package/dist/cjs/locales/en/list-labels.json.cjs +2 -1
  33. package/dist/cjs/locales/en/list-shipments.json.cjs +1 -1
  34. package/dist/cjs/locales/en/manage-warehouses.json.cjs +2 -0
  35. package/dist/cjs/locales/en/register-wallet.json.cjs +5 -0
  36. package/dist/cjs/package.json.cjs +1 -1
  37. package/dist/cjs/utilities/feature-flags/feature-flags.cjs +2 -1
  38. package/dist/cjs/workflows/onboarding/components/confirmation-and-submission-step/confirmation-and-submission-step.cjs +16 -5
  39. package/dist/cjs/workflows/onboarding/components/confirmation-and-submission-step/use-confirmation-and-submission-step.cjs +6 -6
  40. package/dist/cjs/workflows/onboarding/components/funding-step/funding-step.cjs +7 -3
  41. package/dist/cjs/workflows/onboarding/components/ship-from-address-step/ship-from-address-step.cjs +1 -1
  42. package/dist/cjs/workflows/onboarding/onboarding.cjs +8 -5
  43. package/dist/esm/components/field/rate-select/rate-card/rate-card.js +1 -0
  44. package/dist/esm/components/forms/edit-billing-form/edit-billing-form.js +88 -13
  45. package/dist/esm/components/forms/edit-billing-form/edit-billing-form.styles.js +15 -0
  46. package/dist/esm/components/forms/wallet-form/index.js +0 -1
  47. package/dist/esm/components/forms/wallet-form/wallet-form.js +155 -25
  48. package/dist/esm/components/forms/wallet-form/wallet-form.styles.js +15 -0
  49. package/dist/esm/components/forms/wallet-form/wallet-schema.js +1 -36
  50. package/dist/esm/components/forms/warehouse-form/warehouse-form.js +10 -1
  51. package/dist/esm/components/payment/payment-method-selector/index.js +1 -0
  52. package/dist/esm/components/payment/payment-method-selector/payment-method-selector.js +53 -0
  53. package/dist/esm/components/payment/payment-method-selector/payment-method-selector.styles.js +56 -0
  54. package/dist/esm/components/service-card/service-card.js +3 -2
  55. package/dist/esm/components/service-card/service-card.styles.js +4 -2
  56. package/dist/esm/contexts/auctane-pay-session-context.js +155 -0
  57. package/dist/esm/contexts/index.js +1 -0
  58. package/dist/esm/elements/labels-grid/hooks/use-labels-grid.js +2 -2
  59. package/dist/esm/elements/labels-grid/labels-grid.js +30 -10
  60. package/dist/esm/elements/labels-grid/labels-grid.styles.js +5 -0
  61. package/dist/esm/elements/purchase-label/components/rate-form/rate-view.js +3 -5
  62. package/dist/esm/elements/purchase-label/components/shipment-form/shipment-form.js +3 -1
  63. package/dist/esm/elements/purchase-label/hooks/use-filter-visible-rate-options/use-filter-visible-rate-options.js +5 -5
  64. package/dist/esm/elements/shipments-grid/hooks/use-shipments-grid.js +2 -2
  65. package/dist/esm/elements/shipments-grid/shipments-grid.js +21 -7
  66. package/dist/esm/elements/shipments-grid/shipments-grid.styles.js +5 -0
  67. package/dist/esm/features/manage-warehouses/manage-warehouses.js +9 -5
  68. package/dist/esm/features/payment-method-settings/payment-method-settings.js +5 -4
  69. package/dist/esm/hooks/financial-services/financial-service.js +462 -0
  70. package/dist/esm/hooks/financial-services/index.js +2 -0
  71. package/dist/esm/hooks/financial-services/use-financial-service.js +186 -0
  72. package/dist/esm/hooks/use-configure-shipment.js +8 -0
  73. package/dist/esm/hooks/use-get-service-data.js +58 -0
  74. package/dist/esm/locales/en/list-labels.json.js +2 -1
  75. package/dist/esm/locales/en/list-shipments.json.js +1 -1
  76. package/dist/esm/locales/en/manage-warehouses.json.js +2 -0
  77. package/dist/esm/locales/en/register-wallet.json.js +5 -0
  78. package/dist/esm/package.json.js +1 -1
  79. package/dist/esm/utilities/feature-flags/feature-flags.js +2 -1
  80. package/dist/esm/workflows/onboarding/components/confirmation-and-submission-step/confirmation-and-submission-step.js +16 -5
  81. package/dist/esm/workflows/onboarding/components/confirmation-and-submission-step/use-confirmation-and-submission-step.js +6 -6
  82. package/dist/esm/workflows/onboarding/components/funding-step/funding-step.js +7 -3
  83. package/dist/esm/workflows/onboarding/components/ship-from-address-step/ship-from-address-step.js +1 -1
  84. package/dist/esm/workflows/onboarding/onboarding.js +8 -5
  85. package/dist/types/components/address-preference-context/address-preference-context.d.ts +0 -1
  86. package/dist/types/components/address-preference-context/address-preference-context.d.ts.map +1 -1
  87. package/dist/types/components/field/rate-select/rate-card/rate-card.d.ts.map +1 -1
  88. package/dist/types/components/forms/edit-billing-form/edit-billing-form.d.ts +2 -2
  89. package/dist/types/components/forms/edit-billing-form/edit-billing-form.d.ts.map +1 -1
  90. package/dist/types/components/forms/edit-billing-form/edit-billing-form.styles.d.ts +14 -0
  91. package/dist/types/components/forms/edit-billing-form/edit-billing-form.styles.d.ts.map +1 -1
  92. package/dist/types/components/forms/wallet-form/index.d.ts +0 -1
  93. package/dist/types/components/forms/wallet-form/index.d.ts.map +1 -1
  94. package/dist/types/components/forms/wallet-form/wallet-form.d.ts +4 -1
  95. package/dist/types/components/forms/wallet-form/wallet-form.d.ts.map +1 -1
  96. package/dist/types/components/forms/wallet-form/wallet-form.styles.d.ts +14 -0
  97. package/dist/types/components/forms/wallet-form/wallet-form.styles.d.ts.map +1 -1
  98. package/dist/types/components/forms/wallet-form/wallet-schema.d.ts +3 -43
  99. package/dist/types/components/forms/wallet-form/wallet-schema.d.ts.map +1 -1
  100. package/dist/types/components/forms/warehouse-form/warehouse-form.d.ts.map +1 -1
  101. package/dist/types/components/payment/payment-method-selector/index.d.ts +2 -0
  102. package/dist/types/components/payment/payment-method-selector/index.d.ts.map +1 -0
  103. package/dist/types/components/payment/payment-method-selector/payment-method-selector.d.ts +11 -0
  104. package/dist/types/components/payment/payment-method-selector/payment-method-selector.d.ts.map +1 -0
  105. package/dist/types/components/payment/payment-method-selector/payment-method-selector.styles.d.ts +52 -0
  106. package/dist/types/components/payment/payment-method-selector/payment-method-selector.styles.d.ts.map +1 -0
  107. package/dist/types/components/service-card/service-card.d.ts +2 -1
  108. package/dist/types/components/service-card/service-card.d.ts.map +1 -1
  109. package/dist/types/components/service-card/service-card.styles.d.ts +2 -1
  110. package/dist/types/components/service-card/service-card.styles.d.ts.map +1 -1
  111. package/dist/types/contexts/auctane-pay-session-context.d.ts +54 -0
  112. package/dist/types/contexts/auctane-pay-session-context.d.ts.map +1 -0
  113. package/dist/types/contexts/index.d.ts +3 -0
  114. package/dist/types/contexts/index.d.ts.map +1 -0
  115. package/dist/types/elements/customs-form/customs-form-element.d.ts +10 -2
  116. package/dist/types/elements/customs-form/customs-form-element.d.ts.map +1 -1
  117. package/dist/types/elements/labels-grid/labels-grid.d.ts +10 -2
  118. package/dist/types/elements/labels-grid/labels-grid.d.ts.map +1 -1
  119. package/dist/types/elements/labels-grid/labels-grid.styles.d.ts +5 -0
  120. package/dist/types/elements/labels-grid/labels-grid.styles.d.ts.map +1 -1
  121. package/dist/types/elements/manage-carriers/manage-carriers.d.ts +10 -2
  122. package/dist/types/elements/manage-carriers/manage-carriers.d.ts.map +1 -1
  123. package/dist/types/elements/manage-external-carriers/manage-external-carriers.d.ts +10 -2
  124. package/dist/types/elements/manage-external-carriers/manage-external-carriers.d.ts.map +1 -1
  125. package/dist/types/elements/manage-funding/manage-funding-element.d.ts +10 -2
  126. package/dist/types/elements/manage-funding/manage-funding-element.d.ts.map +1 -1
  127. package/dist/types/elements/manage-warehouses/manage-warehouses.d.ts +10 -2
  128. package/dist/types/elements/manage-warehouses/manage-warehouses.d.ts.map +1 -1
  129. package/dist/types/elements/payment-method-settings/payment-method-settings-element.d.ts +10 -2
  130. package/dist/types/elements/payment-method-settings/payment-method-settings-element.d.ts.map +1 -1
  131. package/dist/types/elements/purchase-label/components/rate-form/rate-view.d.ts +1 -1
  132. package/dist/types/elements/purchase-label/components/rate-form/rate-view.d.ts.map +1 -1
  133. package/dist/types/elements/purchase-label/components/shipment-form/shipment-form.d.ts.map +1 -1
  134. package/dist/types/elements/purchase-label/hooks/use-filter-visible-rate-options/use-filter-visible-rate-options.d.ts +2 -1
  135. package/dist/types/elements/purchase-label/hooks/use-filter-visible-rate-options/use-filter-visible-rate-options.d.ts.map +1 -1
  136. package/dist/types/elements/purchase-label/purchase-label.d.ts +10 -2
  137. package/dist/types/elements/purchase-label/purchase-label.d.ts.map +1 -1
  138. package/dist/types/elements/select-label-layout/select-label-layout-element.d.ts +10 -2
  139. package/dist/types/elements/select-label-layout/select-label-layout-element.d.ts.map +1 -1
  140. package/dist/types/elements/shipment-summary/shipment-summary.d.ts +10 -2
  141. package/dist/types/elements/shipment-summary/shipment-summary.d.ts.map +1 -1
  142. package/dist/types/elements/shipments-grid/shipments-grid.d.ts +10 -2
  143. package/dist/types/elements/shipments-grid/shipments-grid.d.ts.map +1 -1
  144. package/dist/types/elements/shipments-grid/shipments-grid.styles.d.ts +5 -0
  145. package/dist/types/elements/shipments-grid/shipments-grid.styles.d.ts.map +1 -1
  146. package/dist/types/elements/theme-creator/theme-creator.d.ts +10 -2
  147. package/dist/types/elements/theme-creator/theme-creator.d.ts.map +1 -1
  148. package/dist/types/elements/transaction-history/transaction-history-element.d.ts +10 -2
  149. package/dist/types/elements/transaction-history/transaction-history-element.d.ts.map +1 -1
  150. package/dist/types/elements/unit-settings/unit-settings-element.d.ts +10 -2
  151. package/dist/types/elements/unit-settings/unit-settings-element.d.ts.map +1 -1
  152. package/dist/types/elements/vat-settings/vat-settings-element.d.ts +10 -2
  153. package/dist/types/elements/vat-settings/vat-settings-element.d.ts.map +1 -1
  154. package/dist/types/elements/void-label/void-label.d.ts +10 -2
  155. package/dist/types/elements/void-label/void-label.d.ts.map +1 -1
  156. package/dist/types/elements-provider/elements-provider.d.ts.map +1 -1
  157. package/dist/types/features/manage-warehouses/manage-warehouses.d.ts.map +1 -1
  158. package/dist/types/features/payment-method-settings/payment-method-settings.d.ts.map +1 -1
  159. package/dist/types/hooks/financial-services/financial-service.d.ts +279 -0
  160. package/dist/types/hooks/financial-services/financial-service.d.ts.map +1 -0
  161. package/dist/types/hooks/financial-services/index.d.ts +5 -0
  162. package/dist/types/hooks/financial-services/index.d.ts.map +1 -0
  163. package/dist/types/hooks/financial-services/use-financial-service.d.ts +40 -0
  164. package/dist/types/hooks/financial-services/use-financial-service.d.ts.map +1 -0
  165. package/dist/types/hooks/use-configure-shipment.d.ts.map +1 -1
  166. package/dist/types/hooks/use-get-service-data.d.ts +14 -0
  167. package/dist/types/hooks/use-get-service-data.d.ts.map +1 -0
  168. package/dist/types/locales/en/index.d.ts +10 -2
  169. package/dist/types/locales/en/index.d.ts.map +1 -1
  170. package/dist/types/types/financial-services.d.ts +34 -0
  171. package/dist/types/types/financial-services.d.ts.map +1 -0
  172. package/dist/types/types/index.d.ts +1 -1
  173. package/dist/types/types/index.d.ts.map +1 -1
  174. package/dist/types/utilities/feature-flags/feature-flags.d.ts.map +1 -1
  175. package/dist/types/utilities/feature-flags/types.d.ts +4 -0
  176. package/dist/types/utilities/feature-flags/types.d.ts.map +1 -1
  177. package/dist/types/workflows/account-settings/account-settings.d.ts +10 -2
  178. package/dist/types/workflows/account-settings/account-settings.d.ts.map +1 -1
  179. package/dist/types/workflows/carrier-services/carrier-services.d.ts +10 -2
  180. package/dist/types/workflows/carrier-services/carrier-services.d.ts.map +1 -1
  181. package/dist/types/workflows/connect-external-carrier/connect-external-carrier.d.ts +10 -2
  182. package/dist/types/workflows/connect-external-carrier/connect-external-carrier.d.ts.map +1 -1
  183. package/dist/types/workflows/label-workflow/label-workflow.d.ts +10 -2
  184. package/dist/types/workflows/label-workflow/label-workflow.d.ts.map +1 -1
  185. package/dist/types/workflows/onboarding/components/confirmation-and-submission-step/confirmation-and-submission-step.d.ts.map +1 -1
  186. package/dist/types/workflows/onboarding/components/confirmation-and-submission-step/use-confirmation-and-submission-step.d.ts.map +1 -1
  187. package/dist/types/workflows/onboarding/components/funding-step/funding-step.d.ts.map +1 -1
  188. package/dist/types/workflows/onboarding/components/ship-from-address-step/ship-from-address-step.d.ts.map +1 -1
  189. package/dist/types/workflows/onboarding/onboarding.d.ts +10 -2
  190. package/dist/types/workflows/onboarding/onboarding.d.ts.map +1 -1
  191. package/package.json +5 -5
  192. package/dist/cjs/components/forms/wallet-form/billing-fields.cjs +0 -71
  193. package/dist/cjs/hooks/use-get-service-name.cjs +0 -22
  194. package/dist/esm/components/forms/wallet-form/billing-fields.js +0 -69
  195. package/dist/esm/hooks/use-get-service-name.js +0 -20
  196. package/dist/types/components/forms/wallet-form/billing-fields.d.ts +0 -7
  197. package/dist/types/components/forms/wallet-form/billing-fields.d.ts.map +0 -1
  198. package/dist/types/hooks/use-get-service-name.d.ts +0 -5
  199. package/dist/types/hooks/use-get-service-name.d.ts.map +0 -1
@@ -1,20 +1,23 @@
1
1
  import { __awaiter } from '../../../_virtual/_tslib.js';
2
2
  import { jsxs, jsx, Fragment } from '@emotion/react/jsx-runtime';
3
+ import { useAuctanePaySession } from '../../../contexts/auctane-pay-session-context.js';
3
4
  import { useBlackboxDetection } from '../../../hooks/use-black-box-detection.js';
4
5
  import { useNestedForm } from '../../../hooks/use-nested-form.js';
5
- import { Grid, GridChild, InlineNotification, NotificationType, Typography, ButtonVariant } from '@shipengine/giger';
6
+ import { Grid, GridChild, InlineNotification, NotificationType, Typography, Spinner, SpinnerSize, ButtonVariant } from '@shipengine/giger';
6
7
  import { formLogger } from '../../../utilities/form-logger.js';
7
8
  import { isPoBoxAddress } from '../../../utilities/shipengine/address.js';
8
9
  import { validationResolver } from '../../../utilities/validation.js';
9
- import { useState, useCallback } from 'react';
10
+ import { useState, useCallback, useMemo, useEffect } from 'react';
10
11
  import { useForm } from 'react-hook-form';
11
12
  import { useTranslation } from 'react-i18next';
12
13
  import { EditWalletAddressForm } from '../edit-wallet-address-form/edit-wallet-address-form.js';
13
- import { BillingFields } from './billing-fields.js';
14
14
  import { styles } from './wallet-form.styles.js';
15
15
  import { getWalletSchema } from './wallet-schema.js';
16
+ import { useFinancialService } from '../../../hooks/financial-services/use-financial-service.js';
17
+ import { PaymentMethodSelector } from '../../payment/payment-method-selector/payment-method-selector.js';
16
18
  import { AddressFields } from '../address-form/address-fields.js';
17
19
  import { VatSettings } from '../../../features/vat-settings/vat-settings.js';
20
+ import { useElements } from '../../../elements-provider/elements-context-provider.js';
18
21
  import { useAddressPreference } from '../../address-preference-context/address-preference-context.js';
19
22
  import { Spacer } from '../../spacer/spacer.js';
20
23
  import { AddressDisplay } from '../../address-display/address-display.js';
@@ -27,27 +30,38 @@ const WalletForm = ({
27
30
  onSubmit,
28
31
  showVatSettings
29
32
  }) => {
33
+ var _a, _b;
30
34
  const {
31
35
  t
32
36
  } = useTranslation(["register-wallet", "common"]);
37
+ const {
38
+ locale
39
+ } = useElements();
33
40
  const defaultWarehouseIsPoBox = isPoBoxAddress(address);
34
41
  const {
35
42
  validateAddress
36
43
  } = useAddressPreference();
37
44
  const [codedErrors, setCodedErrors] = useState(errors);
45
+ const [isSubmitting, setIsSubmitting] = useState(false);
46
+ const [paymentError, setPaymentError] = useState(null);
47
+ const [isAdyenReady, setIsAdyenReady] = useState(false);
48
+ const [cardBrand, setCardBrand] = useState();
49
+ const sessionContext = useAuctanePaySession();
38
50
  const form = useForm({
39
51
  defaultValues:
40
52
  // If the warehouse address is a PO Box they cannot use it as their billing address
41
53
  defaultWarehouseIsPoBox ? {
42
54
  address: {
43
55
  countryCode: "US"
44
- }
56
+ },
57
+ paymentMethod: "credit_card"
45
58
  } : {
46
59
  address: Object.assign(Object.assign({}, address), {
47
60
  countryCode: address.countryCode
48
- })
61
+ }),
62
+ paymentMethod: "credit_card"
49
63
  },
50
- resolver: validationResolver(getWalletSchema("emailOptional", "blackboxRequired"), ["creditCard"])
64
+ resolver: validationResolver(getWalletSchema("emailOptional", "blackboxRequired"))
51
65
  });
52
66
  const formSetValue = form.setValue;
53
67
  useBlackboxDetection({
@@ -65,24 +79,104 @@ const WalletForm = ({
65
79
  onSuccess: useCallback(bb => formSetValue("iovationBlackbox", bb), [formSetValue])
66
80
  });
67
81
  const watchAddress = form.watch("address");
82
+ const watchPaymentMethod = form.watch("paymentMethod");
83
+ const adyenOptions = useMemo(() => ({
84
+ showPayButton: false,
85
+ locale: locale || "en-US",
86
+ onChange: () => {
87
+ setPaymentError(null);
88
+ },
89
+ creditCardOptions: {
90
+ onLoad: event => {
91
+ if (event.iframesLoaded) {
92
+ setIsAdyenReady(true);
93
+ }
94
+ },
95
+ onBinLookup: event => {
96
+ var _a, _b;
97
+ // Some cards return multiple brands (e.g., ['star', 'visa']), so prioritize major brands
98
+ const majorBrands = ["visa", "mc", "amex", "discover"];
99
+ const brand = ((_a = event.detectedBrands) === null || _a === void 0 ? void 0 : _a.find(b => majorBrands.includes(b.toLowerCase()))) || ((_b = event.detectedBrands) === null || _b === void 0 ? void 0 : _b[0]);
100
+ setCardBrand(brand);
101
+ }
102
+ }
103
+ }), [locale]);
104
+ const {
105
+ adyenRef,
106
+ submit: adyenSubmit,
107
+ getSessionData
108
+ } = useFinancialService({
109
+ getAdyenSessionData: sessionContext.getSessionData,
110
+ paymentMethod: watchPaymentMethod || "credit_card",
111
+ options: adyenOptions
112
+ });
113
+ // Reset Adyen ready state when payment method changes
114
+ useEffect(() => {
115
+ setIsAdyenReady(false);
116
+ }, [watchPaymentMethod]);
68
117
  const handleSubmit = form.handleSubmit(values => __awaiter(void 0, void 0, void 0, function* () {
69
118
  const payload = values;
70
- yield validateAddress({
71
- addresses: {
72
- originAddress: payload.address
73
- },
74
- data: {
75
- creditCard: payload.creditCard,
76
- iovationBlackbox: payload.iovationBlackbox
77
- },
78
- onValid: validatedAddressesPayload => {
79
- onSubmit({
80
- address: validatedAddressesPayload.originAddress,
81
- creditCard: payload.creditCard,
119
+ setIsSubmitting(true);
120
+ try {
121
+ yield validateAddress({
122
+ addresses: {
123
+ originAddress: payload.address
124
+ },
125
+ data: {
82
126
  iovationBlackbox: payload.iovationBlackbox
83
- });
84
- }
85
- });
127
+ },
128
+ onValid: validatedAddressesPayload => {
129
+ const processPayment = () => __awaiter(void 0, void 0, void 0, function* () {
130
+ try {
131
+ const walletPayload = {
132
+ address: validatedAddressesPayload.originAddress,
133
+ iovationBlackbox: payload.iovationBlackbox,
134
+ paymentMethod: payload.paymentMethod
135
+ };
136
+ if (payload.paymentMethod === "credit_card") {
137
+ // For credit card, await Adyen payment completion
138
+ const paymentResult = yield adyenSubmit();
139
+ if (!paymentResult.success) {
140
+ // Payment failed - show error and allow retry
141
+ setPaymentError(paymentResult.error || "Payment failed");
142
+ form.reset(undefined, {
143
+ keepValues: true
144
+ });
145
+ return;
146
+ }
147
+ // Payment succeeded - get session data and add to payload
148
+ const sessionData = getSessionData();
149
+ if (sessionData) {
150
+ walletPayload.auctanePaySessionId = sessionData.id;
151
+ }
152
+ if (cardBrand) {
153
+ walletPayload.cardBrand = cardBrand;
154
+ }
155
+ }
156
+ // Payment successful or non-credit-card method - proceed to next step
157
+ onSubmit(walletPayload);
158
+ } catch (error) {
159
+ // Payment processing error
160
+ const errorMessage = error instanceof Error ? error.message : "Payment processing failed";
161
+ setPaymentError(errorMessage);
162
+ } finally {
163
+ setIsSubmitting(false);
164
+ }
165
+ });
166
+ void processPayment();
167
+ }
168
+ });
169
+ } catch (error) {
170
+ // Address validation error
171
+ const errorMessage = error instanceof Error ? error.message : "An error occurred";
172
+ setCodedErrors([{
173
+ errorCode: "unspecified",
174
+ errorSource: "client",
175
+ errorType: "validation",
176
+ message: errorMessage
177
+ }]);
178
+ setIsSubmitting(false);
179
+ }
86
180
  }));
87
181
  const [editWalletAddressForm, isEditWalletAddressFormOpen, toggleIsEditWalletAddressFormOpen] = useNestedForm(EditWalletAddressForm, {
88
182
  address: watchAddress,
@@ -97,9 +191,9 @@ const WalletForm = ({
97
191
  children: jsxs("form", {
98
192
  id: "wallet-form",
99
193
  onSubmit: formLogger.capture(handleSubmit),
100
- children: [jsx(GridChild, {
194
+ children: [jsxs(GridChild, {
101
195
  colSpan: 12,
102
- children: !!(codedErrors === null || codedErrors === void 0 ? void 0 : codedErrors.length) && jsxs(Fragment, {
196
+ children: [!!(codedErrors === null || codedErrors === void 0 ? void 0 : codedErrors.length) && jsxs(Fragment, {
103
197
  children: [jsx(InlineNotification, {
104
198
  title: t("register-wallet:sections.notifications.error.title"),
105
199
  type: NotificationType.ERROR,
@@ -109,12 +203,47 @@ const WalletForm = ({
109
203
  }), jsx(Spacer, {
110
204
  multiplier: 2
111
205
  })]
206
+ }), paymentError && jsxs(Fragment, {
207
+ children: [jsx(InlineNotification, {
208
+ title: t("register-wallet:sections.notifications.error.title"),
209
+ type: NotificationType.ERROR,
210
+ children: paymentError
211
+ }), jsx(Spacer, {
212
+ multiplier: 2
213
+ })]
214
+ })]
215
+ }), jsx(GridChild, {
216
+ colSpan: 12,
217
+ children: jsx(Typography, {
218
+ variant: "subtitle1",
219
+ children: t("register-wallet:sections.paymentMethod.title")
112
220
  })
221
+ }), jsx(Spacer, {
222
+ multiplier: 1
113
223
  }), jsx(GridChild, {
114
224
  colSpan: 12,
115
- children: jsx(BillingFields, {
116
- form: form
225
+ children: jsx(PaymentMethodSelector, {
226
+ onChange: method => form.setValue("paymentMethod", method),
227
+ payByBankEnabled: (_b = (_a = getSessionData()) === null || _a === void 0 ? void 0 : _a.eligiblePaymentMethodTypes) === null || _b === void 0 ? void 0 : _b.includes("pay_by_bank_us"),
228
+ value: watchPaymentMethod || "credit_card"
117
229
  })
230
+ }), jsx(Spacer, {
231
+ multiplier: 2
232
+ }), jsxs(GridChild, {
233
+ colSpan: 12,
234
+ children: [!isAdyenReady && jsx("div", {
235
+ css: styles.loadingContainer,
236
+ children: jsx(Spinner, {
237
+ size: SpinnerSize.SIZE_LARGE
238
+ })
239
+ }), jsx("div", {
240
+ css: styles.adyenContainer,
241
+ "data-ready": isAdyenReady,
242
+ "data-testid": "adyen-div",
243
+ ref: adyenRef
244
+ })]
245
+ }), jsx(Spacer, {
246
+ multiplier: 2
118
247
  }), jsx(GridChild, {
119
248
  colSpan: 12,
120
249
  children: jsx(Typography, {
@@ -165,6 +294,7 @@ const WalletForm = ({
165
294
  children: jsx(SubmitButton, {
166
295
  control: form.control,
167
296
  form: "wallet-form",
297
+ isLoading: isSubmitting,
168
298
  variant: ButtonVariant.FILLED,
169
299
  children: t("actions.continue")
170
300
  })
@@ -6,6 +6,21 @@ const styles = createStyles({
6
6
  }),
7
7
  grid: theme => ({
8
8
  margin: scopeTheme(theme).spacing(1)
9
+ }),
10
+ loadingContainer: theme => ({
11
+ display: "flex",
12
+ justifyContent: "center",
13
+ paddingTop: scopeTheme(theme).spacing(2),
14
+ paddingBottom: scopeTheme(theme).spacing(2)
15
+ }),
16
+ adyenContainer: () => ({
17
+ "&:not([data-ready='true'])": {
18
+ display: "none"
19
+ },
20
+ // Hide Adyen's "All fields are required" instruction text
21
+ "& .adyen-checkout-form-instruction": {
22
+ display: "none"
23
+ }
9
24
  })
10
25
  });
11
26
 
@@ -1,15 +1,9 @@
1
- import { __rest } from '../../../_virtual/_tslib.js';
2
- import { getExpirationYears } from '../../../utilities/date.js';
3
1
  import { isPoBox } from '../../../utilities/shipengine/address.js';
4
- import cardValidator from 'card-validator';
5
2
  import { isValidPhoneNumber } from 'libphonenumber-js/min';
6
3
  import { z } from 'zod';
7
4
  import { addressSchema, addressLine2Schema, addressLine1Schema } from '../address-form/address-schema.js';
8
5
  import { addressNameRegex, usStateCodes, postalCodeRegex } from '../../../constants/shipengine/address.js';
9
6
 
10
- const expirationYears = getExpirationYears(15);
11
- const creditCardTypes = ["visa", "mastercard", "american-express", "discover"];
12
- const expirationMonths = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"];
13
7
  const walletEmailSchemas = {
14
8
  emailOptional: addressSchema.shape.email,
15
9
  emailRequired: z.string().trim().email().min(1)
@@ -49,40 +43,11 @@ const getBillingAddressSchema = emailRequirement => {
49
43
  path: ["postalCode"]
50
44
  });
51
45
  };
52
- const creditCardSchema = z.object({
53
- cvv: z.string().trim().refine(cvv => cardValidator.cvv(cvv, [3, 4]).isValid, "Invalid CVV"),
54
- expiration: z.string().trim().refine(expiration => {
55
- const [expirationMonth, expirationYear] = expiration.split("/");
56
- return expirationMonths.includes(expirationMonth) && expirationYears.includes(expirationYear);
57
- }, "schemaErrors.invalidExpirationDate"),
58
- name: addressSchema.shape.name.refine(name => name.match(addressNameRegex), "schemaErrors.invalidAddressNameOnboarding"),
59
- number: z.string().trim().refine(number => cardValidator.number(number).isValid, "Invalid card number").refine(number => {
60
- var _a, _b;
61
- return !((_a = cardValidator.number(number).card) === null || _a === void 0 ? void 0 : _a.type) || creditCardTypes.includes((_b = cardValidator.number(number).card) === null || _b === void 0 ? void 0 : _b.type);
62
- }, "schemaErrors.invalidCreditCardType")
63
- }).transform(schema => {
64
- var _a;
65
- const {
66
- cvv,
67
- expiration
68
- } = schema,
69
- creditCard = __rest(schema, ["cvv", "expiration"]);
70
- const creditCardVendor = (_a = cardValidator.number(creditCard.number).card) === null || _a === void 0 ? void 0 : _a.type;
71
- const [expirationMonth, expirationYear] = expiration.split("/").map(v => parseInt(v, 10));
72
- return {
73
- cardNumber: creditCard.number,
74
- cvv: cvv,
75
- expirationMonth: expirationMonth,
76
- expirationYear: expirationYear,
77
- name: creditCard.name,
78
- provider: creditCardVendor === "american-express" ? "american_express" : creditCardVendor
79
- };
80
- });
81
46
  const getWalletSchema = (emailRequirement, blackboxRequirement) => {
82
47
  const billingAddressSchema = getBillingAddressSchema(emailRequirement);
83
48
  return z.object({
84
49
  address: billingAddressSchema,
85
- creditCard: creditCardSchema,
50
+ paymentMethod: z.enum(["credit_card", "pay_by_bank_us"]).default("credit_card"),
86
51
  iovationBlackbox: walletBlackboxSchemas[blackboxRequirement]
87
52
  });
88
53
  };
@@ -97,13 +97,22 @@ const WarehouseForm = ({
97
97
  form: form,
98
98
  formatFieldName: fieldName => `originAddress.${fieldName}`,
99
99
  optionalFields: ["addressLine2", ...(requireEmail ? [] : ["email"])]
100
- }), !shouldForceDefault && jsx(CheckboxInput, {
100
+ }), !shouldForceDefault ? jsx(CheckboxInput, {
101
101
  ariaLabel: "Is Default Warehouse",
102
102
  checkboxLabel: t("manage-warehouses:isDefault"),
103
103
  control: form.control,
104
104
  form: formId,
105
105
  label: "isDefault",
106
106
  name: "isDefault"
107
+ }) : jsx(CheckboxInput, {
108
+ ariaLabel: "Is Default Warehouse",
109
+ checkboxLabel: warehouse ? t("manage-warehouses:forcedDefault") : t("manage-warehouses:forcedDefaultNew"),
110
+ control: form.control,
111
+ defaultValue: true,
112
+ disabled: true,
113
+ form: formId,
114
+ label: "isDefault",
115
+ name: "isDefault"
107
116
  }), jsx(CheckboxInput, {
108
117
  ariaLabel: "Return To Address Is Different",
109
118
  checkboxLabel: t("manage-warehouses:returnToAddressIsDifferent"),
@@ -0,0 +1 @@
1
+ export { PaymentMethodSelector } from './payment-method-selector.js';
@@ -0,0 +1,53 @@
1
+ import { jsx, jsxs } from '@emotion/react/jsx-runtime';
2
+ import { RadioGroup, Radio, Icon, IconSize } from '@shipengine/giger';
3
+ import { IconNames } from '@shipengine/giger-theme';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { styles } from './payment-method-selector.styles.js';
6
+
7
+ const PaymentMethodSelector = ({
8
+ name = "paymentMethod",
9
+ onChange,
10
+ payByBankEnabled = false,
11
+ value
12
+ }) => {
13
+ const {
14
+ t
15
+ } = useTranslation("register-wallet");
16
+ const paymentMethods = [{
17
+ value: "credit_card",
18
+ icon: IconNames.CREDIT_CARD,
19
+ label: t("sections.paymentMethod.creditCard")
20
+ }, payByBankEnabled ? {
21
+ value: "pay_by_bank_us",
22
+ icon: IconNames.BANK,
23
+ label: t("sections.paymentMethod.payByBank")
24
+ } : undefined];
25
+ return jsx("div", {
26
+ css: styles.paymentMethodSelector,
27
+ children: jsx(RadioGroup, {
28
+ name: name,
29
+ onChange: e => onChange(e.target.value),
30
+ value: value,
31
+ children: paymentMethods.map(method => {
32
+ return method !== undefined ? jsx("div", {
33
+ css: [styles.paymentMethodOption, value === method.value && styles.paymentMethodOptionSelected],
34
+ onClick: () => onChange(method.value),
35
+ children: jsx(Radio, {
36
+ checked: value === method.value,
37
+ readOnly: true,
38
+ value: method.value,
39
+ children: jsxs("div", {
40
+ css: styles.paymentMethodOptionContent,
41
+ children: [jsx(Icon, {
42
+ name: method.icon,
43
+ size: IconSize.SIZE_SMALL
44
+ }), method.label]
45
+ })
46
+ })
47
+ }, method.value) : null;
48
+ })
49
+ })
50
+ });
51
+ };
52
+
53
+ export { PaymentMethodSelector };
@@ -0,0 +1,56 @@
1
+ import { createStyles, scopeTheme } from '../../../utilities/styles.js';
2
+
3
+ const styles = createStyles({
4
+ paymentMethodSelector: () => ({
5
+ display: "flex",
6
+ flexDirection: "column",
7
+ gap: "12px",
8
+ "& .giger-radio-group": {
9
+ display: "flex",
10
+ flexDirection: "column",
11
+ gap: "12px"
12
+ }
13
+ }),
14
+ paymentMethodOption: theme => ({
15
+ padding: scopeTheme(theme).spacing(2),
16
+ border: `1px solid ${scopeTheme(theme).palette.gray.light}`,
17
+ borderRadius: scopeTheme(theme).spacing(),
18
+ background: scopeTheme(theme).palette.white,
19
+ marginBottom: scopeTheme(theme).spacing(1),
20
+ transition: "all 0.2s ease",
21
+ cursor: "pointer",
22
+ "&:hover": {
23
+ borderColor: scopeTheme(theme).palette.primary.main
24
+ },
25
+ "& .giger-radio": {
26
+ margin: 0,
27
+ width: "100%",
28
+ pointerEvents: "none",
29
+ // Disable pointer events on radio to let div handle clicks
30
+ "& .giger-radio__container": {
31
+ width: "100%",
32
+ justifyContent: "flex-start"
33
+ },
34
+ "& .giger-radio__label": {
35
+ fontWeight: 500,
36
+ marginLeft: scopeTheme(theme).spacing(1),
37
+ flex: 1,
38
+ cursor: "pointer"
39
+ },
40
+ "& .giger-radio__input": {
41
+ pointerEvents: "auto" // Re-enable pointer events on the actual input
42
+ }
43
+ }
44
+ }),
45
+ paymentMethodOptionSelected: theme => ({
46
+ borderColor: scopeTheme(theme).palette.primary.main,
47
+ backgroundColor: scopeTheme(theme).palette.gray.megaLight
48
+ }),
49
+ paymentMethodOptionContent: () => ({
50
+ display: "flex",
51
+ alignItems: "center",
52
+ gap: "8px"
53
+ })
54
+ });
55
+
56
+ export { styles };
@@ -35,7 +35,8 @@ const ServiceCardHeader = ({
35
35
  rateDetailsProps,
36
36
  costBreakdownProps,
37
37
  rightContentCss,
38
- voided
38
+ voided,
39
+ hasRateAttributes
39
40
  }) => {
40
41
  const {
41
42
  type,
@@ -46,7 +47,7 @@ const ServiceCardHeader = ({
46
47
  return jsxs("div", {
47
48
  "data-testid": "service-card-header",
48
49
  children: [jsxs("section", {
49
- css: styles.section,
50
+ css: styles.getSectionStyles(hasRateAttributes),
50
51
  children: [carrierCode && jsx("div", {
51
52
  css: styles.carrierImage,
52
53
  children: jsx(CarrierIcon, {
@@ -45,12 +45,14 @@ const styles = createStyles({
45
45
  headerChildren: theme => ({
46
46
  padding: `${scopeTheme(theme).spacing(0)}px ${scopeTheme(theme).spacing(2)}px ${scopeTheme(theme).spacing(2)}px ${scopeTheme(theme).spacing(2)}px`
47
47
  }),
48
- section: theme => ({
48
+ getSectionStyles: hasRateAttributes => theme => Object.assign({
49
49
  alignItems: "flex-start",
50
50
  display: "flex",
51
51
  flexDirection: "row",
52
52
  flexWrap: "nowrap",
53
- padding: scopeTheme(theme).spacing(2)
53
+ padding: scopeTheme(theme).spacing(1.5)
54
+ }, hasRateAttributes && {
55
+ paddingTop: scopeTheme(theme).spacing(0.75)
54
56
  }),
55
57
  serviceInfo: theme => ({
56
58
  display: "flex",
@@ -0,0 +1,155 @@
1
+ import { __awaiter } from '../_virtual/_tslib.js';
2
+ import { jsx } from '@emotion/react/jsx-runtime';
3
+ import { useCreateAuctanePaySession } from '@shipengine/react-api';
4
+ import { useState, useRef, useCallback, useMemo, createContext, useContext } from 'react';
5
+
6
+ const SESSION_STORAGE_KEY = "auctane_pay_session";
7
+ const storeSession = (session, expiresAt) => {
8
+ try {
9
+ const data = {
10
+ session,
11
+ expiresAt
12
+ };
13
+ sessionStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(data));
14
+ } catch (error) {
15
+ console.warn("Failed to store session in sessionStorage:", error);
16
+ }
17
+ };
18
+ const retrieveStoredSession = () => {
19
+ try {
20
+ const stored = sessionStorage.getItem(SESSION_STORAGE_KEY);
21
+ if (!stored) return null;
22
+ const data = JSON.parse(stored);
23
+ return data;
24
+ } catch (error) {
25
+ console.warn("Failed to retrieve session from sessionStorage:", error);
26
+ return null;
27
+ }
28
+ };
29
+ const clearStoredSession = () => {
30
+ try {
31
+ sessionStorage.removeItem(SESSION_STORAGE_KEY);
32
+ } catch (error) {
33
+ console.warn("Failed to clear session from sessionStorage:", error);
34
+ }
35
+ };
36
+ const AuctanePaySessionContext = /*#__PURE__*/createContext(undefined);
37
+ /**
38
+ * Provider that manages Adyen payment session creation and redirect handling.
39
+ * Each call to getSessionData() creates a fresh session - sessions are not cached
40
+ * to avoid reusing sessions after authorization.
41
+ *
42
+ * @example
43
+ * ```tsx
44
+ * <AuctanePaySessionProvider paymentPreferences={["add_funds", "subscription"]}>
45
+ * <OnboardingWizard>
46
+ * <FundingStep />
47
+ * </OnboardingWizard>
48
+ * </AuctanePaySessionProvider>
49
+ * ```
50
+ */
51
+ const AuctanePaySessionProvider = ({
52
+ children,
53
+ paymentPreferences = ["add_funds", "subscription"],
54
+ returnUrl
55
+ }) => {
56
+ const [sessionError, setSessionError] = useState(null);
57
+ // Track the last created session for saveSessionForRedirect
58
+ const lastSessionRef = useRef(null);
59
+ const {
60
+ mutateAsync: createAdyenSession,
61
+ isLoading: isCreating
62
+ } = useCreateAuctanePaySession();
63
+ const createSession = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
64
+ try {
65
+ setSessionError(null);
66
+ const cleanUrl = returnUrl || `${window.location.origin}${window.location.pathname}`;
67
+ const session = yield createAdyenSession({
68
+ paymentPreferences,
69
+ returnUrl: cleanUrl
70
+ });
71
+ if (session) {
72
+ const expiresAt = new Date(session.metadata.adyenExpiration).getTime();
73
+ lastSessionRef.current = {
74
+ session,
75
+ expiresAt
76
+ };
77
+ }
78
+ return session;
79
+ } catch (err) {
80
+ const error = err instanceof Error ? err : new Error("Failed to create Adyen session");
81
+ setSessionError(error);
82
+ throw error;
83
+ }
84
+ }), [createAdyenSession, paymentPreferences, returnUrl]);
85
+ const getSessionData = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
86
+ // Always create a fresh session to avoid reusing sessions after authorization
87
+ return createSession();
88
+ }), [createSession]);
89
+ const clearSession = useCallback(() => {
90
+ lastSessionRef.current = null;
91
+ setSessionError(null);
92
+ clearStoredSession();
93
+ }, []);
94
+ const saveSessionForRedirect = useCallback(() => {
95
+ if (lastSessionRef.current) {
96
+ storeSession(lastSessionRef.current.session, lastSessionRef.current.expiresAt);
97
+ }
98
+ }, []);
99
+ const restoreSessionAfterRedirect = useCallback(() => {
100
+ const storedData = retrieveStoredSession();
101
+ if (!storedData) {
102
+ return null;
103
+ }
104
+ // Check if session is still valid
105
+ if (Date.now() >= storedData.expiresAt) {
106
+ clearStoredSession();
107
+ return null;
108
+ }
109
+ // Update lastSessionRef so saveSessionForRedirect can work if needed
110
+ lastSessionRef.current = storedData;
111
+ // Clear from storage after restoring (single-use)
112
+ clearStoredSession();
113
+ return storedData.session;
114
+ }, []);
115
+ const value = useMemo(() => ({
116
+ isCreating,
117
+ sessionError,
118
+ getSessionData,
119
+ clearSession,
120
+ saveSessionForRedirect,
121
+ restoreSessionAfterRedirect
122
+ }), [isCreating, sessionError, getSessionData, clearSession, saveSessionForRedirect, restoreSessionAfterRedirect]);
123
+ return jsx(AuctanePaySessionContext.Provider, {
124
+ value: value,
125
+ children: children
126
+ });
127
+ };
128
+ /**
129
+ * Hook to access the Adyen payment session context
130
+ *
131
+ * @throws Error if used outside of AuctanePaySessionProvider
132
+ *
133
+ * @example
134
+ * ```tsx
135
+ * const WalletForm = () => {
136
+ * const { getSessionData, sessionData } = useAuctanePaySession();
137
+ *
138
+ * const { adyenRef, submit } = useFinancialService({
139
+ * getAdyenSessionData: getSessionData, // Uses cached session!
140
+ * paymentMethod: "credit_card",
141
+ * });
142
+ *
143
+ * return <div ref={adyenRef} />;
144
+ * };
145
+ * ```
146
+ */
147
+ const useAuctanePaySession = () => {
148
+ const context = useContext(AuctanePaySessionContext);
149
+ if (!context) {
150
+ throw new Error("useAuctanePaySession must be used within AuctanePaySessionProvider");
151
+ }
152
+ return context;
153
+ };
154
+
155
+ export { AuctanePaySessionProvider, useAuctanePaySession };
@@ -0,0 +1 @@
1
+ export { AuctanePaySessionProvider, useAuctanePaySession } from './auctane-pay-session-context.js';