@solvapay/core 1.6.0 → 1.7.0-preview-3f68079d7097167693fa7cdc76752dcf23fd1ab6

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.
@@ -47,23 +47,72 @@ export declare function getTaxIdExample(country: SupportedBusinessCountry): stri
47
47
 
48
48
  export declare function getTaxIdHelperText(country: SupportedBusinessCountry): string
49
49
 
50
+ export declare const POSTAL_CODE_REQUIRED_COUNTRIES: readonly ['US', 'CA', 'GB']
51
+
52
+ export declare const STATE_REQUIRED_COUNTRIES: readonly ['US', 'CA', 'IN']
53
+
54
+ export declare function isPostalCodeRequired(country: string): boolean
55
+
56
+ export declare function isStateRequired(country: string): boolean
57
+
58
+ export declare function getStateFieldLabel(country: string): string
59
+
60
+ export declare function getPostalCodeFieldLabel(country: string): string
61
+
62
+ export declare function getPostalCodePlaceholder(country: string): string
63
+
64
+ export declare function resolveBuyerCountry(input: {
65
+ isBusiness: boolean
66
+ country?: string
67
+ customerCountry?: string
68
+ }): string | undefined
69
+
70
+ export declare function isCustomerAddressComplete(input: {
71
+ isBusiness: boolean
72
+ country?: string
73
+ customerCountry?: string
74
+ customerState?: string
75
+ customerPostalCode?: string
76
+ }): boolean
77
+
78
+ export declare function getCustomerAddressFieldErrors(input: {
79
+ isBusiness: boolean
80
+ country?: string
81
+ customerCountry?: string
82
+ customerState?: string
83
+ customerPostalCode?: string
84
+ }): Partial<Record<'country' | 'customerCountry' | 'customerState' | 'customerPostalCode', string>>
85
+
50
86
  export type BusinessDetailsInput = {
51
87
  isBusiness: boolean
52
88
  businessName?: string
53
89
  country?: string
54
90
  customerCountry?: string
91
+ customerName?: string
92
+ customerState?: string
93
+ customerPostalCode?: string
55
94
  taxId?: string
56
95
  taxIdType?: TaxIdType
57
96
  }
58
97
 
59
98
  export type BusinessDetails =
60
- | { isBusiness: false; customerCountry?: SupportedBusinessCountry }
99
+ | {
100
+ isBusiness: false
101
+ customerCountry?: SupportedBusinessCountry
102
+ customerName?: string
103
+ customerState?: string
104
+ customerPostalCode?: string
105
+ }
61
106
  | {
62
107
  isBusiness: true
63
- businessName: string
108
+ businessName?: string
64
109
  country: SupportedBusinessCountry
65
- taxId: string
66
- taxIdType: TaxIdType
110
+ customerCountry: SupportedBusinessCountry
111
+ taxId?: string
112
+ taxIdType?: TaxIdType
113
+ customerName?: string
114
+ customerState?: string
115
+ customerPostalCode?: string
67
116
  }
68
117
 
69
118
  export type BusinessDetailsValidationIssue = {
@@ -144,12 +144,50 @@ type BusinessCountryOption = {
144
144
  label: string;
145
145
  };
146
146
  declare const BUSINESS_COUNTRY_OPTIONS: BusinessCountryOption[];
147
+ /**
148
+ * Countries that require a postal/ZIP code for Stripe Tax and confirm.
149
+ * Keep in sync with `POSTAL_CODE_REQUIRED_COUNTRIES` in
150
+ * `platform/apps/customer-app/src/components/customer/checkout/PaymentForm.tsx`.
151
+ */
152
+ declare const POSTAL_CODE_REQUIRED_COUNTRIES: readonly ["US", "CA", "GB"];
153
+ /**
154
+ * Countries that require a state/province for Stripe Tax and confirm.
155
+ * Keep in sync with `STATE_REQUIRED_COUNTRIES` in
156
+ * `platform/apps/customer-app/src/components/customer/checkout/PaymentForm.tsx`.
157
+ */
158
+ declare const STATE_REQUIRED_COUNTRIES: readonly ["US", "CA", "IN"];
159
+ declare function isPostalCodeRequired(country: string): boolean;
160
+ declare function isStateRequired(country: string): boolean;
161
+ declare function getStateFieldLabel(country: string): string;
162
+ declare function getPostalCodeFieldLabel(country: string): string;
163
+ declare function getPostalCodePlaceholder(country: string): string;
164
+ declare function resolveBuyerCountry(input: {
165
+ isBusiness: boolean;
166
+ country?: string;
167
+ customerCountry?: string;
168
+ }): string | undefined;
169
+ declare function isCustomerAddressComplete(input: {
170
+ isBusiness: boolean;
171
+ country?: string;
172
+ customerCountry?: string;
173
+ customerState?: string;
174
+ customerPostalCode?: string;
175
+ }): boolean;
176
+ declare function getCustomerAddressFieldErrors(input: {
177
+ isBusiness: boolean;
178
+ country?: string;
179
+ customerCountry?: string;
180
+ customerState?: string;
181
+ customerPostalCode?: string;
182
+ }): Partial<Record<'country' | 'customerCountry' | 'customerState' | 'customerPostalCode', string>>;
147
183
  declare const BusinessDetailsSchema: z.ZodPipe<z.ZodObject<{
148
184
  isBusiness: z.ZodBoolean;
149
185
  businessName: z.ZodOptional<z.ZodString>;
150
186
  country: z.ZodOptional<z.ZodString>;
151
187
  customerCountry: z.ZodOptional<z.ZodString>;
152
188
  customerName: z.ZodOptional<z.ZodString>;
189
+ customerState: z.ZodOptional<z.ZodString>;
190
+ customerPostalCode: z.ZodOptional<z.ZodString>;
153
191
  taxId: z.ZodOptional<z.ZodString>;
154
192
  taxIdType: z.ZodOptional<z.ZodEnum<{
155
193
  ae_trn: "ae_trn";
@@ -231,6 +269,8 @@ declare const BusinessDetailsSchema: z.ZodPipe<z.ZodObject<{
231
269
  zw_tin: "zw_tin";
232
270
  }>>;
233
271
  }, z.core.$strip>, z.ZodTransform<{
272
+ customerState?: string;
273
+ customerPostalCode?: string;
234
274
  customerName?: string | undefined;
235
275
  isBusiness: false;
236
276
  customerCountry: "AT" | "BE" | "BG" | "HR" | "CY" | "CZ" | "DK" | "EE" | "FI" | "FR" | "DE" | "GR" | "HU" | "IE" | "IT" | "LV" | "LT" | "LU" | "MT" | "NL" | "PL" | "PT" | "RO" | "SK" | "SI" | "ES" | "SE" | "AE" | "AL" | "AM" | "AO" | "AU" | "AW" | "AZ" | "BA" | "BB" | "BD" | "BF" | "BH" | "BJ" | "BS" | "BY" | "CA" | "CD" | "CH" | "CL" | "CM" | "CO" | "CR" | "CV" | "EC" | "EG" | "ET" | "GB" | "GE" | "GN" | "HK" | "ID" | "IN" | "IS" | "JP" | "KE" | "KG" | "KH" | "KR" | "KZ" | "LA" | "LI" | "LK" | "MA" | "MD" | "ME" | "MK" | "MR" | "MX" | "MY" | "NG" | "NO" | "NP" | "NZ" | "OM" | "PE" | "PH" | "PR" | "RS" | "RU" | "SA" | "SG" | "SN" | "SR" | "TH" | "TJ" | "TR" | "TW" | "TZ" | "UA" | "UG" | "US" | "UY" | "UZ" | "VN" | "ZA" | "ZM" | "ZW";
@@ -238,18 +278,23 @@ declare const BusinessDetailsSchema: z.ZodPipe<z.ZodObject<{
238
278
  customerName?: string | undefined;
239
279
  isBusiness: false;
240
280
  } | {
281
+ customerState?: string;
282
+ customerPostalCode?: string;
241
283
  customerName?: string | undefined;
242
284
  taxIdType?: "ae_trn" | "al_tin" | "am_tin" | "ao_tin" | "au_abn" | "aw_tin" | "az_tin" | "ba_tin" | "bb_tin" | "bd_bin" | "bf_ifu" | "bh_vat" | "bj_ifu" | "bs_tin" | "by_tin" | "ca_gst_hst" | "cd_nif" | "ch_vat" | "cl_tin" | "cm_niu" | "co_nit" | "cr_tin" | "cv_nif" | "ec_ruc" | "eg_tin" | "et_tin" | "eu_vat" | "gb_vat" | "ge_vat" | "gn_nif" | "hk_br" | "id_npwp" | "in_gst" | "is_vat" | "jp_trn" | "ke_pin" | "kg_tin" | "kh_tin" | "kr_brn" | "kz_bin" | "la_tin" | "li_vat" | "lk_vat" | "ma_vat" | "md_vat" | "me_pib" | "mk_vat" | "mr_nif" | "mx_rfc" | "my_sst" | "ng_tin" | "no_vat" | "np_pan" | "nz_gst" | "om_vat" | "pe_ruc" | "ph_tin" | "rs_pib" | "ru_inn" | "sa_vat" | "sg_gst" | "sn_ninea" | "sr_fin" | "th_vat" | "tj_tin" | "tr_tin" | "tw_vat" | "tz_vat" | "ua_vat" | "ug_tin" | "us_ein" | "uy_ruc" | "uz_vat" | "vn_tin" | "za_vat" | "zm_tin" | "zw_tin" | undefined;
243
285
  taxId?: string | undefined;
244
286
  businessName?: string | undefined;
245
287
  isBusiness: true;
246
288
  country: "AT" | "BE" | "BG" | "HR" | "CY" | "CZ" | "DK" | "EE" | "FI" | "FR" | "DE" | "GR" | "HU" | "IE" | "IT" | "LV" | "LT" | "LU" | "MT" | "NL" | "PL" | "PT" | "RO" | "SK" | "SI" | "ES" | "SE" | "AE" | "AL" | "AM" | "AO" | "AU" | "AW" | "AZ" | "BA" | "BB" | "BD" | "BF" | "BH" | "BJ" | "BS" | "BY" | "CA" | "CD" | "CH" | "CL" | "CM" | "CO" | "CR" | "CV" | "EC" | "EG" | "ET" | "GB" | "GE" | "GN" | "HK" | "ID" | "IN" | "IS" | "JP" | "KE" | "KG" | "KH" | "KR" | "KZ" | "LA" | "LI" | "LK" | "MA" | "MD" | "ME" | "MK" | "MR" | "MX" | "MY" | "NG" | "NO" | "NP" | "NZ" | "OM" | "PE" | "PH" | "PR" | "RS" | "RU" | "SA" | "SG" | "SN" | "SR" | "TH" | "TJ" | "TR" | "TW" | "TZ" | "UA" | "UG" | "US" | "UY" | "UZ" | "VN" | "ZA" | "ZM" | "ZW";
289
+ customerCountry: "AT" | "BE" | "BG" | "HR" | "CY" | "CZ" | "DK" | "EE" | "FI" | "FR" | "DE" | "GR" | "HU" | "IE" | "IT" | "LV" | "LT" | "LU" | "MT" | "NL" | "PL" | "PT" | "RO" | "SK" | "SI" | "ES" | "SE" | "AE" | "AL" | "AM" | "AO" | "AU" | "AW" | "AZ" | "BA" | "BB" | "BD" | "BF" | "BH" | "BJ" | "BS" | "BY" | "CA" | "CD" | "CH" | "CL" | "CM" | "CO" | "CR" | "CV" | "EC" | "EG" | "ET" | "GB" | "GE" | "GN" | "HK" | "ID" | "IN" | "IS" | "JP" | "KE" | "KG" | "KH" | "KR" | "KZ" | "LA" | "LI" | "LK" | "MA" | "MD" | "ME" | "MK" | "MR" | "MX" | "MY" | "NG" | "NO" | "NP" | "NZ" | "OM" | "PE" | "PH" | "PR" | "RS" | "RU" | "SA" | "SG" | "SN" | "SR" | "TH" | "TJ" | "TR" | "TW" | "TZ" | "UA" | "UG" | "US" | "UY" | "UZ" | "VN" | "ZA" | "ZM" | "ZW";
247
290
  }, {
248
291
  isBusiness: boolean;
249
292
  businessName?: string | undefined;
250
293
  country?: string | undefined;
251
294
  customerCountry?: string | undefined;
252
295
  customerName?: string | undefined;
296
+ customerState?: string | undefined;
297
+ customerPostalCode?: string | undefined;
253
298
  taxId?: string | undefined;
254
299
  taxIdType?: "ae_trn" | "al_tin" | "am_tin" | "ao_tin" | "au_abn" | "aw_tin" | "az_tin" | "ba_tin" | "bb_tin" | "bd_bin" | "bf_ifu" | "bh_vat" | "bj_ifu" | "bs_tin" | "by_tin" | "ca_gst_hst" | "cd_nif" | "ch_vat" | "cl_tin" | "cm_niu" | "co_nit" | "cr_tin" | "cv_nif" | "ec_ruc" | "eg_tin" | "et_tin" | "eu_vat" | "gb_vat" | "ge_vat" | "gn_nif" | "hk_br" | "id_npwp" | "in_gst" | "is_vat" | "jp_trn" | "ke_pin" | "kg_tin" | "kh_tin" | "kr_brn" | "kz_bin" | "la_tin" | "li_vat" | "lk_vat" | "ma_vat" | "md_vat" | "me_pib" | "mk_vat" | "mr_nif" | "mx_rfc" | "my_sst" | "ng_tin" | "no_vat" | "np_pan" | "nz_gst" | "om_vat" | "pe_ruc" | "ph_tin" | "rs_pib" | "ru_inn" | "sa_vat" | "sg_gst" | "sn_ninea" | "sr_fin" | "th_vat" | "tj_tin" | "tr_tin" | "tw_vat" | "tz_vat" | "ua_vat" | "ug_tin" | "us_ein" | "uy_ruc" | "uz_vat" | "vn_tin" | "za_vat" | "zm_tin" | "zw_tin" | undefined;
255
300
  }>>;
@@ -259,6 +304,8 @@ type BusinessDetailsInput = {
259
304
  country?: string;
260
305
  customerCountry?: string;
261
306
  customerName?: string;
307
+ customerState?: string;
308
+ customerPostalCode?: string;
262
309
  taxId?: string;
263
310
  taxIdType?: TaxIdType;
264
311
  };
@@ -266,13 +313,18 @@ type BusinessDetails = {
266
313
  isBusiness: false;
267
314
  customerCountry?: SupportedBusinessCountry;
268
315
  customerName?: string;
316
+ customerState?: string;
317
+ customerPostalCode?: string;
269
318
  } | {
270
319
  isBusiness: true;
271
320
  country: SupportedBusinessCountry;
321
+ customerCountry: SupportedBusinessCountry;
272
322
  businessName?: string;
273
323
  taxId?: string;
274
324
  taxIdType?: TaxIdType;
275
325
  customerName?: string;
326
+ customerState?: string;
327
+ customerPostalCode?: string;
276
328
  };
277
329
  type BusinessDetailsValidationIssue = {
278
330
  path: PropertyKey[];
@@ -324,4 +376,4 @@ declare function resolveSellerIdentityDisplay(input: {
324
376
  companyNumber?: string | null;
325
377
  }): SellerIdentityDisplay;
326
378
 
327
- export { BUSINESS_COUNTRY_DISPLAY_NAMES as B, COUNTRY_TO_TAX_ID_TYPE as C, type EuMemberCountry as E, SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE as S, TAX_BEHAVIORS as T, type ValidateBusinessDetailsResult as V, BUSINESS_COUNTRY_OPTIONS as a, type BusinessCountryOption as b, type BusinessDetails as c, type BusinessDetailsInput as d, BusinessDetailsSchema as e, type BusinessDetailsValidationError as f, type BusinessDetailsValidationIssue as g, SUPPORTED_BUSINESS_COUNTRIES as h, type SellerIdentityDisplay as i, type SellerIdentityRow as j, type SupportedBusinessCountry as k, TAX_EXCLUSIVE_CURRENCIES as l, TAX_ID_EXAMPLE_BY_COUNTRY as m, TAX_ID_TYPES as n, type TaxBehavior as o, type TaxBreakdown as p, type TaxIdType as q, deriveTaxIdType as r, getSellerTaxIdentifierDisplayLabel as s, getTaxIdExample as t, getTaxIdFieldLabel as u, getTaxIdHelperText as v, resolveSellerIdentityDisplay as w, resolveTaxBehavior as x, validateBusinessDetails as y };
379
+ export { getTaxIdHelperText as A, BUSINESS_COUNTRY_DISPLAY_NAMES as B, COUNTRY_TO_TAX_ID_TYPE as C, isCustomerAddressComplete as D, type EuMemberCountry as E, isPostalCodeRequired as F, isStateRequired as G, resolveBuyerCountry as H, resolveSellerIdentityDisplay as I, resolveTaxBehavior as J, validateBusinessDetails as K, POSTAL_CODE_REQUIRED_COUNTRIES as P, SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE as S, TAX_BEHAVIORS as T, type ValidateBusinessDetailsResult as V, BUSINESS_COUNTRY_OPTIONS as a, type BusinessCountryOption as b, type BusinessDetails as c, type BusinessDetailsInput as d, BusinessDetailsSchema as e, type BusinessDetailsValidationError as f, type BusinessDetailsValidationIssue as g, STATE_REQUIRED_COUNTRIES as h, SUPPORTED_BUSINESS_COUNTRIES as i, type SellerIdentityDisplay as j, type SellerIdentityRow as k, type SupportedBusinessCountry as l, TAX_EXCLUSIVE_CURRENCIES as m, TAX_ID_EXAMPLE_BY_COUNTRY as n, TAX_ID_TYPES as o, type TaxBehavior as p, type TaxBreakdown as q, type TaxIdType as r, deriveTaxIdType as s, getCustomerAddressFieldErrors as t, getPostalCodeFieldLabel as u, getPostalCodePlaceholder as v, getSellerTaxIdentifierDisplayLabel as w, getStateFieldLabel as x, getTaxIdExample as y, getTaxIdFieldLabel as z };
@@ -144,12 +144,50 @@ type BusinessCountryOption = {
144
144
  label: string;
145
145
  };
146
146
  declare const BUSINESS_COUNTRY_OPTIONS: BusinessCountryOption[];
147
+ /**
148
+ * Countries that require a postal/ZIP code for Stripe Tax and confirm.
149
+ * Keep in sync with `POSTAL_CODE_REQUIRED_COUNTRIES` in
150
+ * `platform/apps/customer-app/src/components/customer/checkout/PaymentForm.tsx`.
151
+ */
152
+ declare const POSTAL_CODE_REQUIRED_COUNTRIES: readonly ["US", "CA", "GB"];
153
+ /**
154
+ * Countries that require a state/province for Stripe Tax and confirm.
155
+ * Keep in sync with `STATE_REQUIRED_COUNTRIES` in
156
+ * `platform/apps/customer-app/src/components/customer/checkout/PaymentForm.tsx`.
157
+ */
158
+ declare const STATE_REQUIRED_COUNTRIES: readonly ["US", "CA", "IN"];
159
+ declare function isPostalCodeRequired(country: string): boolean;
160
+ declare function isStateRequired(country: string): boolean;
161
+ declare function getStateFieldLabel(country: string): string;
162
+ declare function getPostalCodeFieldLabel(country: string): string;
163
+ declare function getPostalCodePlaceholder(country: string): string;
164
+ declare function resolveBuyerCountry(input: {
165
+ isBusiness: boolean;
166
+ country?: string;
167
+ customerCountry?: string;
168
+ }): string | undefined;
169
+ declare function isCustomerAddressComplete(input: {
170
+ isBusiness: boolean;
171
+ country?: string;
172
+ customerCountry?: string;
173
+ customerState?: string;
174
+ customerPostalCode?: string;
175
+ }): boolean;
176
+ declare function getCustomerAddressFieldErrors(input: {
177
+ isBusiness: boolean;
178
+ country?: string;
179
+ customerCountry?: string;
180
+ customerState?: string;
181
+ customerPostalCode?: string;
182
+ }): Partial<Record<'country' | 'customerCountry' | 'customerState' | 'customerPostalCode', string>>;
147
183
  declare const BusinessDetailsSchema: z.ZodPipe<z.ZodObject<{
148
184
  isBusiness: z.ZodBoolean;
149
185
  businessName: z.ZodOptional<z.ZodString>;
150
186
  country: z.ZodOptional<z.ZodString>;
151
187
  customerCountry: z.ZodOptional<z.ZodString>;
152
188
  customerName: z.ZodOptional<z.ZodString>;
189
+ customerState: z.ZodOptional<z.ZodString>;
190
+ customerPostalCode: z.ZodOptional<z.ZodString>;
153
191
  taxId: z.ZodOptional<z.ZodString>;
154
192
  taxIdType: z.ZodOptional<z.ZodEnum<{
155
193
  ae_trn: "ae_trn";
@@ -231,6 +269,8 @@ declare const BusinessDetailsSchema: z.ZodPipe<z.ZodObject<{
231
269
  zw_tin: "zw_tin";
232
270
  }>>;
233
271
  }, z.core.$strip>, z.ZodTransform<{
272
+ customerState?: string;
273
+ customerPostalCode?: string;
234
274
  customerName?: string | undefined;
235
275
  isBusiness: false;
236
276
  customerCountry: "AT" | "BE" | "BG" | "HR" | "CY" | "CZ" | "DK" | "EE" | "FI" | "FR" | "DE" | "GR" | "HU" | "IE" | "IT" | "LV" | "LT" | "LU" | "MT" | "NL" | "PL" | "PT" | "RO" | "SK" | "SI" | "ES" | "SE" | "AE" | "AL" | "AM" | "AO" | "AU" | "AW" | "AZ" | "BA" | "BB" | "BD" | "BF" | "BH" | "BJ" | "BS" | "BY" | "CA" | "CD" | "CH" | "CL" | "CM" | "CO" | "CR" | "CV" | "EC" | "EG" | "ET" | "GB" | "GE" | "GN" | "HK" | "ID" | "IN" | "IS" | "JP" | "KE" | "KG" | "KH" | "KR" | "KZ" | "LA" | "LI" | "LK" | "MA" | "MD" | "ME" | "MK" | "MR" | "MX" | "MY" | "NG" | "NO" | "NP" | "NZ" | "OM" | "PE" | "PH" | "PR" | "RS" | "RU" | "SA" | "SG" | "SN" | "SR" | "TH" | "TJ" | "TR" | "TW" | "TZ" | "UA" | "UG" | "US" | "UY" | "UZ" | "VN" | "ZA" | "ZM" | "ZW";
@@ -238,18 +278,23 @@ declare const BusinessDetailsSchema: z.ZodPipe<z.ZodObject<{
238
278
  customerName?: string | undefined;
239
279
  isBusiness: false;
240
280
  } | {
281
+ customerState?: string;
282
+ customerPostalCode?: string;
241
283
  customerName?: string | undefined;
242
284
  taxIdType?: "ae_trn" | "al_tin" | "am_tin" | "ao_tin" | "au_abn" | "aw_tin" | "az_tin" | "ba_tin" | "bb_tin" | "bd_bin" | "bf_ifu" | "bh_vat" | "bj_ifu" | "bs_tin" | "by_tin" | "ca_gst_hst" | "cd_nif" | "ch_vat" | "cl_tin" | "cm_niu" | "co_nit" | "cr_tin" | "cv_nif" | "ec_ruc" | "eg_tin" | "et_tin" | "eu_vat" | "gb_vat" | "ge_vat" | "gn_nif" | "hk_br" | "id_npwp" | "in_gst" | "is_vat" | "jp_trn" | "ke_pin" | "kg_tin" | "kh_tin" | "kr_brn" | "kz_bin" | "la_tin" | "li_vat" | "lk_vat" | "ma_vat" | "md_vat" | "me_pib" | "mk_vat" | "mr_nif" | "mx_rfc" | "my_sst" | "ng_tin" | "no_vat" | "np_pan" | "nz_gst" | "om_vat" | "pe_ruc" | "ph_tin" | "rs_pib" | "ru_inn" | "sa_vat" | "sg_gst" | "sn_ninea" | "sr_fin" | "th_vat" | "tj_tin" | "tr_tin" | "tw_vat" | "tz_vat" | "ua_vat" | "ug_tin" | "us_ein" | "uy_ruc" | "uz_vat" | "vn_tin" | "za_vat" | "zm_tin" | "zw_tin" | undefined;
243
285
  taxId?: string | undefined;
244
286
  businessName?: string | undefined;
245
287
  isBusiness: true;
246
288
  country: "AT" | "BE" | "BG" | "HR" | "CY" | "CZ" | "DK" | "EE" | "FI" | "FR" | "DE" | "GR" | "HU" | "IE" | "IT" | "LV" | "LT" | "LU" | "MT" | "NL" | "PL" | "PT" | "RO" | "SK" | "SI" | "ES" | "SE" | "AE" | "AL" | "AM" | "AO" | "AU" | "AW" | "AZ" | "BA" | "BB" | "BD" | "BF" | "BH" | "BJ" | "BS" | "BY" | "CA" | "CD" | "CH" | "CL" | "CM" | "CO" | "CR" | "CV" | "EC" | "EG" | "ET" | "GB" | "GE" | "GN" | "HK" | "ID" | "IN" | "IS" | "JP" | "KE" | "KG" | "KH" | "KR" | "KZ" | "LA" | "LI" | "LK" | "MA" | "MD" | "ME" | "MK" | "MR" | "MX" | "MY" | "NG" | "NO" | "NP" | "NZ" | "OM" | "PE" | "PH" | "PR" | "RS" | "RU" | "SA" | "SG" | "SN" | "SR" | "TH" | "TJ" | "TR" | "TW" | "TZ" | "UA" | "UG" | "US" | "UY" | "UZ" | "VN" | "ZA" | "ZM" | "ZW";
289
+ customerCountry: "AT" | "BE" | "BG" | "HR" | "CY" | "CZ" | "DK" | "EE" | "FI" | "FR" | "DE" | "GR" | "HU" | "IE" | "IT" | "LV" | "LT" | "LU" | "MT" | "NL" | "PL" | "PT" | "RO" | "SK" | "SI" | "ES" | "SE" | "AE" | "AL" | "AM" | "AO" | "AU" | "AW" | "AZ" | "BA" | "BB" | "BD" | "BF" | "BH" | "BJ" | "BS" | "BY" | "CA" | "CD" | "CH" | "CL" | "CM" | "CO" | "CR" | "CV" | "EC" | "EG" | "ET" | "GB" | "GE" | "GN" | "HK" | "ID" | "IN" | "IS" | "JP" | "KE" | "KG" | "KH" | "KR" | "KZ" | "LA" | "LI" | "LK" | "MA" | "MD" | "ME" | "MK" | "MR" | "MX" | "MY" | "NG" | "NO" | "NP" | "NZ" | "OM" | "PE" | "PH" | "PR" | "RS" | "RU" | "SA" | "SG" | "SN" | "SR" | "TH" | "TJ" | "TR" | "TW" | "TZ" | "UA" | "UG" | "US" | "UY" | "UZ" | "VN" | "ZA" | "ZM" | "ZW";
247
290
  }, {
248
291
  isBusiness: boolean;
249
292
  businessName?: string | undefined;
250
293
  country?: string | undefined;
251
294
  customerCountry?: string | undefined;
252
295
  customerName?: string | undefined;
296
+ customerState?: string | undefined;
297
+ customerPostalCode?: string | undefined;
253
298
  taxId?: string | undefined;
254
299
  taxIdType?: "ae_trn" | "al_tin" | "am_tin" | "ao_tin" | "au_abn" | "aw_tin" | "az_tin" | "ba_tin" | "bb_tin" | "bd_bin" | "bf_ifu" | "bh_vat" | "bj_ifu" | "bs_tin" | "by_tin" | "ca_gst_hst" | "cd_nif" | "ch_vat" | "cl_tin" | "cm_niu" | "co_nit" | "cr_tin" | "cv_nif" | "ec_ruc" | "eg_tin" | "et_tin" | "eu_vat" | "gb_vat" | "ge_vat" | "gn_nif" | "hk_br" | "id_npwp" | "in_gst" | "is_vat" | "jp_trn" | "ke_pin" | "kg_tin" | "kh_tin" | "kr_brn" | "kz_bin" | "la_tin" | "li_vat" | "lk_vat" | "ma_vat" | "md_vat" | "me_pib" | "mk_vat" | "mr_nif" | "mx_rfc" | "my_sst" | "ng_tin" | "no_vat" | "np_pan" | "nz_gst" | "om_vat" | "pe_ruc" | "ph_tin" | "rs_pib" | "ru_inn" | "sa_vat" | "sg_gst" | "sn_ninea" | "sr_fin" | "th_vat" | "tj_tin" | "tr_tin" | "tw_vat" | "tz_vat" | "ua_vat" | "ug_tin" | "us_ein" | "uy_ruc" | "uz_vat" | "vn_tin" | "za_vat" | "zm_tin" | "zw_tin" | undefined;
255
300
  }>>;
@@ -259,6 +304,8 @@ type BusinessDetailsInput = {
259
304
  country?: string;
260
305
  customerCountry?: string;
261
306
  customerName?: string;
307
+ customerState?: string;
308
+ customerPostalCode?: string;
262
309
  taxId?: string;
263
310
  taxIdType?: TaxIdType;
264
311
  };
@@ -266,13 +313,18 @@ type BusinessDetails = {
266
313
  isBusiness: false;
267
314
  customerCountry?: SupportedBusinessCountry;
268
315
  customerName?: string;
316
+ customerState?: string;
317
+ customerPostalCode?: string;
269
318
  } | {
270
319
  isBusiness: true;
271
320
  country: SupportedBusinessCountry;
321
+ customerCountry: SupportedBusinessCountry;
272
322
  businessName?: string;
273
323
  taxId?: string;
274
324
  taxIdType?: TaxIdType;
275
325
  customerName?: string;
326
+ customerState?: string;
327
+ customerPostalCode?: string;
276
328
  };
277
329
  type BusinessDetailsValidationIssue = {
278
330
  path: PropertyKey[];
@@ -324,4 +376,4 @@ declare function resolveSellerIdentityDisplay(input: {
324
376
  companyNumber?: string | null;
325
377
  }): SellerIdentityDisplay;
326
378
 
327
- export { BUSINESS_COUNTRY_DISPLAY_NAMES as B, COUNTRY_TO_TAX_ID_TYPE as C, type EuMemberCountry as E, SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE as S, TAX_BEHAVIORS as T, type ValidateBusinessDetailsResult as V, BUSINESS_COUNTRY_OPTIONS as a, type BusinessCountryOption as b, type BusinessDetails as c, type BusinessDetailsInput as d, BusinessDetailsSchema as e, type BusinessDetailsValidationError as f, type BusinessDetailsValidationIssue as g, SUPPORTED_BUSINESS_COUNTRIES as h, type SellerIdentityDisplay as i, type SellerIdentityRow as j, type SupportedBusinessCountry as k, TAX_EXCLUSIVE_CURRENCIES as l, TAX_ID_EXAMPLE_BY_COUNTRY as m, TAX_ID_TYPES as n, type TaxBehavior as o, type TaxBreakdown as p, type TaxIdType as q, deriveTaxIdType as r, getSellerTaxIdentifierDisplayLabel as s, getTaxIdExample as t, getTaxIdFieldLabel as u, getTaxIdHelperText as v, resolveSellerIdentityDisplay as w, resolveTaxBehavior as x, validateBusinessDetails as y };
379
+ export { getTaxIdHelperText as A, BUSINESS_COUNTRY_DISPLAY_NAMES as B, COUNTRY_TO_TAX_ID_TYPE as C, isCustomerAddressComplete as D, type EuMemberCountry as E, isPostalCodeRequired as F, isStateRequired as G, resolveBuyerCountry as H, resolveSellerIdentityDisplay as I, resolveTaxBehavior as J, validateBusinessDetails as K, POSTAL_CODE_REQUIRED_COUNTRIES as P, SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE as S, TAX_BEHAVIORS as T, type ValidateBusinessDetailsResult as V, BUSINESS_COUNTRY_OPTIONS as a, type BusinessCountryOption as b, type BusinessDetails as c, type BusinessDetailsInput as d, BusinessDetailsSchema as e, type BusinessDetailsValidationError as f, type BusinessDetailsValidationIssue as g, STATE_REQUIRED_COUNTRIES as h, SUPPORTED_BUSINESS_COUNTRIES as i, type SellerIdentityDisplay as j, type SellerIdentityRow as k, type SupportedBusinessCountry as l, TAX_EXCLUSIVE_CURRENCIES as m, TAX_ID_EXAMPLE_BY_COUNTRY as n, TAX_ID_TYPES as o, type TaxBehavior as p, type TaxBreakdown as q, type TaxIdType as r, deriveTaxIdType as s, getCustomerAddressFieldErrors as t, getPostalCodeFieldLabel as u, getPostalCodePlaceholder as v, getSellerTaxIdentifierDisplayLabel as w, getStateFieldLabel as x, getTaxIdExample as y, getTaxIdFieldLabel as z };
@@ -23,17 +23,27 @@ __export(business_details_public_exports, {
23
23
  BUSINESS_COUNTRY_DISPLAY_NAMES: () => BUSINESS_COUNTRY_DISPLAY_NAMES,
24
24
  BUSINESS_COUNTRY_OPTIONS: () => BUSINESS_COUNTRY_OPTIONS,
25
25
  COUNTRY_TO_TAX_ID_TYPE: () => COUNTRY_TO_TAX_ID_TYPE,
26
+ POSTAL_CODE_REQUIRED_COUNTRIES: () => POSTAL_CODE_REQUIRED_COUNTRIES,
26
27
  SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE: () => SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE,
28
+ STATE_REQUIRED_COUNTRIES: () => STATE_REQUIRED_COUNTRIES,
27
29
  SUPPORTED_BUSINESS_COUNTRIES: () => SUPPORTED_BUSINESS_COUNTRIES,
28
30
  TAX_BEHAVIORS: () => TAX_BEHAVIORS,
29
31
  TAX_EXCLUSIVE_CURRENCIES: () => TAX_EXCLUSIVE_CURRENCIES,
30
32
  TAX_ID_EXAMPLE_BY_COUNTRY: () => TAX_ID_EXAMPLE_BY_COUNTRY,
31
33
  TAX_ID_TYPES: () => TAX_ID_TYPES,
32
34
  deriveTaxIdType: () => deriveTaxIdType,
35
+ getCustomerAddressFieldErrors: () => getCustomerAddressFieldErrors,
36
+ getPostalCodeFieldLabel: () => getPostalCodeFieldLabel,
37
+ getPostalCodePlaceholder: () => getPostalCodePlaceholder,
33
38
  getSellerTaxIdentifierDisplayLabel: () => getSellerTaxIdentifierDisplayLabel,
39
+ getStateFieldLabel: () => getStateFieldLabel,
34
40
  getTaxIdExample: () => getTaxIdExample,
35
41
  getTaxIdFieldLabel: () => getTaxIdFieldLabel,
36
42
  getTaxIdHelperText: () => getTaxIdHelperText,
43
+ isCustomerAddressComplete: () => isCustomerAddressComplete,
44
+ isPostalCodeRequired: () => isPostalCodeRequired,
45
+ isStateRequired: () => isStateRequired,
46
+ resolveBuyerCountry: () => resolveBuyerCountry,
37
47
  resolveSellerIdentityDisplay: () => resolveSellerIdentityDisplay,
38
48
  resolveTaxBehavior: () => resolveTaxBehavior,
39
49
  validateBusinessDetails: () => validateBusinessDetails
@@ -660,12 +670,67 @@ var BUSINESS_COUNTRY_OPTIONS = STRIPE_TAX_BUYER_COUNTRIES.map(
660
670
  label: country.name
661
671
  })
662
672
  ).sort((a, b) => a.label.localeCompare(b.label));
673
+ var POSTAL_CODE_REQUIRED_COUNTRIES = ["US", "CA", "GB"];
674
+ var STATE_REQUIRED_COUNTRIES = ["US", "CA", "IN"];
675
+ var POSTAL_CODE_REQUIRED_COUNTRY_SET = new Set(POSTAL_CODE_REQUIRED_COUNTRIES);
676
+ var STATE_REQUIRED_COUNTRY_SET = new Set(STATE_REQUIRED_COUNTRIES);
677
+ function isPostalCodeRequired(country) {
678
+ return POSTAL_CODE_REQUIRED_COUNTRY_SET.has(country.trim().toUpperCase());
679
+ }
680
+ function isStateRequired(country) {
681
+ return STATE_REQUIRED_COUNTRY_SET.has(country.trim().toUpperCase());
682
+ }
683
+ function getStateFieldLabel(country) {
684
+ return country.trim().toUpperCase() === "US" ? "State" : "Province";
685
+ }
686
+ function getPostalCodeFieldLabel(country) {
687
+ return country.trim().toUpperCase() === "US" ? "ZIP code" : "Postal code";
688
+ }
689
+ function getPostalCodePlaceholder(country) {
690
+ return country.trim().toUpperCase() === "US" ? "94103" : "Required";
691
+ }
692
+ function resolveBuyerCountry(input) {
693
+ const customerCountry = input.customerCountry?.trim().toUpperCase();
694
+ if (customerCountry) return customerCountry;
695
+ if (input.isBusiness) {
696
+ const country = input.country?.trim().toUpperCase();
697
+ if (country) return country;
698
+ }
699
+ return void 0;
700
+ }
701
+ function isCustomerAddressComplete(input) {
702
+ return Object.keys(getCustomerAddressFieldErrors(input)).length === 0;
703
+ }
704
+ function getCustomerAddressFieldErrors(input) {
705
+ const country = resolveBuyerCountry(input);
706
+ if (!country) {
707
+ return input.isBusiness ? { country: "Country is required" } : { customerCountry: "Country is required" };
708
+ }
709
+ const errors = {};
710
+ if (isPostalCodeRequired(country) && !input.customerPostalCode?.trim()) {
711
+ errors.customerPostalCode = country === "US" ? "ZIP code is required" : "Postal code is required";
712
+ }
713
+ if (isStateRequired(country) && !input.customerState?.trim()) {
714
+ errors.customerState = country === "US" ? "State is required" : "Province is required";
715
+ }
716
+ return errors;
717
+ }
718
+ function pickAddressFields(data) {
719
+ const customerState = data.customerState?.trim();
720
+ const customerPostalCode = data.customerPostalCode?.trim();
721
+ return {
722
+ ...customerState && { customerState },
723
+ ...customerPostalCode && { customerPostalCode }
724
+ };
725
+ }
663
726
  var BusinessDetailsSchema = import_zod.z.object({
664
727
  isBusiness: import_zod.z.boolean(),
665
728
  businessName: import_zod.z.string().optional(),
666
729
  country: import_zod.z.string().optional(),
667
730
  customerCountry: import_zod.z.string().optional(),
668
731
  customerName: import_zod.z.string().max(100).optional(),
732
+ customerState: import_zod.z.string().optional(),
733
+ customerPostalCode: import_zod.z.string().optional(),
669
734
  taxId: import_zod.z.string().optional(),
670
735
  taxIdType: import_zod.z.enum(TAX_ID_TYPES).optional()
671
736
  }).superRefine((data, ctx) => {
@@ -708,13 +773,15 @@ var BusinessDetailsSchema = import_zod.z.object({
708
773
  }
709
774
  }).transform((data) => {
710
775
  const customerName = data.customerName?.trim();
776
+ const address = pickAddressFields(data);
711
777
  if (!data.isBusiness) {
712
- const customerCountry = data.customerCountry?.trim().toUpperCase();
713
- if (customerCountry && isStripeTaxBuyerCountry(customerCountry)) {
778
+ const customerCountry2 = data.customerCountry?.trim().toUpperCase();
779
+ if (customerCountry2 && isStripeTaxBuyerCountry(customerCountry2)) {
714
780
  return {
715
781
  isBusiness: false,
716
- customerCountry,
717
- ...customerName && { customerName }
782
+ customerCountry: customerCountry2,
783
+ ...customerName && { customerName },
784
+ ...address
718
785
  };
719
786
  }
720
787
  return {
@@ -723,15 +790,19 @@ var BusinessDetailsSchema = import_zod.z.object({
723
790
  };
724
791
  }
725
792
  const country = data.country.trim().toUpperCase();
793
+ const customerCountryRaw = data.customerCountry?.trim().toUpperCase();
794
+ const customerCountry = customerCountryRaw && isStripeTaxBuyerCountry(customerCountryRaw) ? customerCountryRaw : country;
726
795
  const businessName = data.businessName?.trim();
727
796
  const taxId = data.taxId?.trim() ? normalizeTaxId(data.taxId) : void 0;
728
797
  const taxIdType = taxId ? deriveTaxIdType(country) : void 0;
729
798
  return {
730
799
  isBusiness: true,
731
800
  country,
801
+ customerCountry,
732
802
  ...businessName && { businessName },
733
803
  ...taxId && { taxId, ...taxIdType && { taxIdType } },
734
- ...customerName && { customerName }
804
+ ...customerName && { customerName },
805
+ ...address
735
806
  };
736
807
  });
737
808
  function validateBusinessDetails(input) {
@@ -805,17 +876,27 @@ function resolveSellerIdentityDisplay(input) {
805
876
  BUSINESS_COUNTRY_DISPLAY_NAMES,
806
877
  BUSINESS_COUNTRY_OPTIONS,
807
878
  COUNTRY_TO_TAX_ID_TYPE,
879
+ POSTAL_CODE_REQUIRED_COUNTRIES,
808
880
  SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE,
881
+ STATE_REQUIRED_COUNTRIES,
809
882
  SUPPORTED_BUSINESS_COUNTRIES,
810
883
  TAX_BEHAVIORS,
811
884
  TAX_EXCLUSIVE_CURRENCIES,
812
885
  TAX_ID_EXAMPLE_BY_COUNTRY,
813
886
  TAX_ID_TYPES,
814
887
  deriveTaxIdType,
888
+ getCustomerAddressFieldErrors,
889
+ getPostalCodeFieldLabel,
890
+ getPostalCodePlaceholder,
815
891
  getSellerTaxIdentifierDisplayLabel,
892
+ getStateFieldLabel,
816
893
  getTaxIdExample,
817
894
  getTaxIdFieldLabel,
818
895
  getTaxIdHelperText,
896
+ isCustomerAddressComplete,
897
+ isPostalCodeRequired,
898
+ isStateRequired,
899
+ resolveBuyerCountry,
819
900
  resolveSellerIdentityDisplay,
820
901
  resolveTaxBehavior,
821
902
  validateBusinessDetails
@@ -1,2 +1,2 @@
1
- export { B as BUSINESS_COUNTRY_DISPLAY_NAMES, a as BUSINESS_COUNTRY_OPTIONS, b as BusinessCountryOption, c as BusinessDetails, d as BusinessDetailsInput, f as BusinessDetailsValidationError, g as BusinessDetailsValidationIssue, C as COUNTRY_TO_TAX_ID_TYPE, E as EuMemberCountry, S as SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE, h as SUPPORTED_BUSINESS_COUNTRIES, i as SellerIdentityDisplay, j as SellerIdentityRow, k as SupportedBusinessCountry, T as TAX_BEHAVIORS, l as TAX_EXCLUSIVE_CURRENCIES, m as TAX_ID_EXAMPLE_BY_COUNTRY, n as TAX_ID_TYPES, o as TaxBehavior, p as TaxBreakdown, q as TaxIdType, V as ValidateBusinessDetailsResult, r as deriveTaxIdType, s as getSellerTaxIdentifierDisplayLabel, t as getTaxIdExample, u as getTaxIdFieldLabel, v as getTaxIdHelperText, w as resolveSellerIdentityDisplay, x as resolveTaxBehavior, y as validateBusinessDetails } from './business-details-public-7S0Hs-TZ.cjs';
1
+ export { B as BUSINESS_COUNTRY_DISPLAY_NAMES, a as BUSINESS_COUNTRY_OPTIONS, b as BusinessCountryOption, c as BusinessDetails, d as BusinessDetailsInput, f as BusinessDetailsValidationError, g as BusinessDetailsValidationIssue, C as COUNTRY_TO_TAX_ID_TYPE, E as EuMemberCountry, P as POSTAL_CODE_REQUIRED_COUNTRIES, S as SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE, h as STATE_REQUIRED_COUNTRIES, i as SUPPORTED_BUSINESS_COUNTRIES, j as SellerIdentityDisplay, k as SellerIdentityRow, l as SupportedBusinessCountry, T as TAX_BEHAVIORS, m as TAX_EXCLUSIVE_CURRENCIES, n as TAX_ID_EXAMPLE_BY_COUNTRY, o as TAX_ID_TYPES, p as TaxBehavior, q as TaxBreakdown, r as TaxIdType, V as ValidateBusinessDetailsResult, s as deriveTaxIdType, t as getCustomerAddressFieldErrors, u as getPostalCodeFieldLabel, v as getPostalCodePlaceholder, w as getSellerTaxIdentifierDisplayLabel, x as getStateFieldLabel, y as getTaxIdExample, z as getTaxIdFieldLabel, A as getTaxIdHelperText, D as isCustomerAddressComplete, F as isPostalCodeRequired, G as isStateRequired, H as resolveBuyerCountry, I as resolveSellerIdentityDisplay, J as resolveTaxBehavior, K as validateBusinessDetails } from './business-details-public-DSBkp-BK.cjs';
2
2
  import 'zod';
@@ -47,23 +47,72 @@ export declare function getTaxIdExample(country: SupportedBusinessCountry): stri
47
47
 
48
48
  export declare function getTaxIdHelperText(country: SupportedBusinessCountry): string
49
49
 
50
+ export declare const POSTAL_CODE_REQUIRED_COUNTRIES: readonly ['US', 'CA', 'GB']
51
+
52
+ export declare const STATE_REQUIRED_COUNTRIES: readonly ['US', 'CA', 'IN']
53
+
54
+ export declare function isPostalCodeRequired(country: string): boolean
55
+
56
+ export declare function isStateRequired(country: string): boolean
57
+
58
+ export declare function getStateFieldLabel(country: string): string
59
+
60
+ export declare function getPostalCodeFieldLabel(country: string): string
61
+
62
+ export declare function getPostalCodePlaceholder(country: string): string
63
+
64
+ export declare function resolveBuyerCountry(input: {
65
+ isBusiness: boolean
66
+ country?: string
67
+ customerCountry?: string
68
+ }): string | undefined
69
+
70
+ export declare function isCustomerAddressComplete(input: {
71
+ isBusiness: boolean
72
+ country?: string
73
+ customerCountry?: string
74
+ customerState?: string
75
+ customerPostalCode?: string
76
+ }): boolean
77
+
78
+ export declare function getCustomerAddressFieldErrors(input: {
79
+ isBusiness: boolean
80
+ country?: string
81
+ customerCountry?: string
82
+ customerState?: string
83
+ customerPostalCode?: string
84
+ }): Partial<Record<'country' | 'customerCountry' | 'customerState' | 'customerPostalCode', string>>
85
+
50
86
  export type BusinessDetailsInput = {
51
87
  isBusiness: boolean
52
88
  businessName?: string
53
89
  country?: string
54
90
  customerCountry?: string
91
+ customerName?: string
92
+ customerState?: string
93
+ customerPostalCode?: string
55
94
  taxId?: string
56
95
  taxIdType?: TaxIdType
57
96
  }
58
97
 
59
98
  export type BusinessDetails =
60
- | { isBusiness: false; customerCountry?: SupportedBusinessCountry }
99
+ | {
100
+ isBusiness: false
101
+ customerCountry?: SupportedBusinessCountry
102
+ customerName?: string
103
+ customerState?: string
104
+ customerPostalCode?: string
105
+ }
61
106
  | {
62
107
  isBusiness: true
63
- businessName: string
108
+ businessName?: string
64
109
  country: SupportedBusinessCountry
65
- taxId: string
66
- taxIdType: TaxIdType
110
+ customerCountry: SupportedBusinessCountry
111
+ taxId?: string
112
+ taxIdType?: TaxIdType
113
+ customerName?: string
114
+ customerState?: string
115
+ customerPostalCode?: string
67
116
  }
68
117
 
69
118
  export type BusinessDetailsValidationIssue = {
@@ -2,36 +2,56 @@ import {
2
2
  BUSINESS_COUNTRY_DISPLAY_NAMES,
3
3
  BUSINESS_COUNTRY_OPTIONS,
4
4
  COUNTRY_TO_TAX_ID_TYPE,
5
+ POSTAL_CODE_REQUIRED_COUNTRIES,
5
6
  SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE,
7
+ STATE_REQUIRED_COUNTRIES,
6
8
  SUPPORTED_BUSINESS_COUNTRIES,
7
9
  TAX_BEHAVIORS,
8
10
  TAX_EXCLUSIVE_CURRENCIES,
9
11
  TAX_ID_EXAMPLE_BY_COUNTRY,
10
12
  TAX_ID_TYPES,
11
13
  deriveTaxIdType,
14
+ getCustomerAddressFieldErrors,
15
+ getPostalCodeFieldLabel,
16
+ getPostalCodePlaceholder,
12
17
  getSellerTaxIdentifierDisplayLabel,
18
+ getStateFieldLabel,
13
19
  getTaxIdExample,
14
20
  getTaxIdFieldLabel,
15
21
  getTaxIdHelperText,
22
+ isCustomerAddressComplete,
23
+ isPostalCodeRequired,
24
+ isStateRequired,
25
+ resolveBuyerCountry,
16
26
  resolveSellerIdentityDisplay,
17
27
  resolveTaxBehavior,
18
28
  validateBusinessDetails
19
- } from "./chunk-3RBWU5OY.js";
29
+ } from "./chunk-M5X43XFK.js";
20
30
  export {
21
31
  BUSINESS_COUNTRY_DISPLAY_NAMES,
22
32
  BUSINESS_COUNTRY_OPTIONS,
23
33
  COUNTRY_TO_TAX_ID_TYPE,
34
+ POSTAL_CODE_REQUIRED_COUNTRIES,
24
35
  SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE,
36
+ STATE_REQUIRED_COUNTRIES,
25
37
  SUPPORTED_BUSINESS_COUNTRIES,
26
38
  TAX_BEHAVIORS,
27
39
  TAX_EXCLUSIVE_CURRENCIES,
28
40
  TAX_ID_EXAMPLE_BY_COUNTRY,
29
41
  TAX_ID_TYPES,
30
42
  deriveTaxIdType,
43
+ getCustomerAddressFieldErrors,
44
+ getPostalCodeFieldLabel,
45
+ getPostalCodePlaceholder,
31
46
  getSellerTaxIdentifierDisplayLabel,
47
+ getStateFieldLabel,
32
48
  getTaxIdExample,
33
49
  getTaxIdFieldLabel,
34
50
  getTaxIdHelperText,
51
+ isCustomerAddressComplete,
52
+ isPostalCodeRequired,
53
+ isStateRequired,
54
+ resolveBuyerCountry,
35
55
  resolveSellerIdentityDisplay,
36
56
  resolveTaxBehavior,
37
57
  validateBusinessDetails
@@ -616,12 +616,67 @@ var BUSINESS_COUNTRY_OPTIONS = STRIPE_TAX_BUYER_COUNTRIES.map(
616
616
  label: country.name
617
617
  })
618
618
  ).sort((a, b) => a.label.localeCompare(b.label));
619
+ var POSTAL_CODE_REQUIRED_COUNTRIES = ["US", "CA", "GB"];
620
+ var STATE_REQUIRED_COUNTRIES = ["US", "CA", "IN"];
621
+ var POSTAL_CODE_REQUIRED_COUNTRY_SET = new Set(POSTAL_CODE_REQUIRED_COUNTRIES);
622
+ var STATE_REQUIRED_COUNTRY_SET = new Set(STATE_REQUIRED_COUNTRIES);
623
+ function isPostalCodeRequired(country) {
624
+ return POSTAL_CODE_REQUIRED_COUNTRY_SET.has(country.trim().toUpperCase());
625
+ }
626
+ function isStateRequired(country) {
627
+ return STATE_REQUIRED_COUNTRY_SET.has(country.trim().toUpperCase());
628
+ }
629
+ function getStateFieldLabel(country) {
630
+ return country.trim().toUpperCase() === "US" ? "State" : "Province";
631
+ }
632
+ function getPostalCodeFieldLabel(country) {
633
+ return country.trim().toUpperCase() === "US" ? "ZIP code" : "Postal code";
634
+ }
635
+ function getPostalCodePlaceholder(country) {
636
+ return country.trim().toUpperCase() === "US" ? "94103" : "Required";
637
+ }
638
+ function resolveBuyerCountry(input) {
639
+ const customerCountry = input.customerCountry?.trim().toUpperCase();
640
+ if (customerCountry) return customerCountry;
641
+ if (input.isBusiness) {
642
+ const country = input.country?.trim().toUpperCase();
643
+ if (country) return country;
644
+ }
645
+ return void 0;
646
+ }
647
+ function isCustomerAddressComplete(input) {
648
+ return Object.keys(getCustomerAddressFieldErrors(input)).length === 0;
649
+ }
650
+ function getCustomerAddressFieldErrors(input) {
651
+ const country = resolveBuyerCountry(input);
652
+ if (!country) {
653
+ return input.isBusiness ? { country: "Country is required" } : { customerCountry: "Country is required" };
654
+ }
655
+ const errors = {};
656
+ if (isPostalCodeRequired(country) && !input.customerPostalCode?.trim()) {
657
+ errors.customerPostalCode = country === "US" ? "ZIP code is required" : "Postal code is required";
658
+ }
659
+ if (isStateRequired(country) && !input.customerState?.trim()) {
660
+ errors.customerState = country === "US" ? "State is required" : "Province is required";
661
+ }
662
+ return errors;
663
+ }
664
+ function pickAddressFields(data) {
665
+ const customerState = data.customerState?.trim();
666
+ const customerPostalCode = data.customerPostalCode?.trim();
667
+ return {
668
+ ...customerState && { customerState },
669
+ ...customerPostalCode && { customerPostalCode }
670
+ };
671
+ }
619
672
  var BusinessDetailsSchema = z.object({
620
673
  isBusiness: z.boolean(),
621
674
  businessName: z.string().optional(),
622
675
  country: z.string().optional(),
623
676
  customerCountry: z.string().optional(),
624
677
  customerName: z.string().max(100).optional(),
678
+ customerState: z.string().optional(),
679
+ customerPostalCode: z.string().optional(),
625
680
  taxId: z.string().optional(),
626
681
  taxIdType: z.enum(TAX_ID_TYPES).optional()
627
682
  }).superRefine((data, ctx) => {
@@ -664,13 +719,15 @@ var BusinessDetailsSchema = z.object({
664
719
  }
665
720
  }).transform((data) => {
666
721
  const customerName = data.customerName?.trim();
722
+ const address = pickAddressFields(data);
667
723
  if (!data.isBusiness) {
668
- const customerCountry = data.customerCountry?.trim().toUpperCase();
669
- if (customerCountry && isStripeTaxBuyerCountry(customerCountry)) {
724
+ const customerCountry2 = data.customerCountry?.trim().toUpperCase();
725
+ if (customerCountry2 && isStripeTaxBuyerCountry(customerCountry2)) {
670
726
  return {
671
727
  isBusiness: false,
672
- customerCountry,
673
- ...customerName && { customerName }
728
+ customerCountry: customerCountry2,
729
+ ...customerName && { customerName },
730
+ ...address
674
731
  };
675
732
  }
676
733
  return {
@@ -679,15 +736,19 @@ var BusinessDetailsSchema = z.object({
679
736
  };
680
737
  }
681
738
  const country = data.country.trim().toUpperCase();
739
+ const customerCountryRaw = data.customerCountry?.trim().toUpperCase();
740
+ const customerCountry = customerCountryRaw && isStripeTaxBuyerCountry(customerCountryRaw) ? customerCountryRaw : country;
682
741
  const businessName = data.businessName?.trim();
683
742
  const taxId = data.taxId?.trim() ? normalizeTaxId(data.taxId) : void 0;
684
743
  const taxIdType = taxId ? deriveTaxIdType(country) : void 0;
685
744
  return {
686
745
  isBusiness: true,
687
746
  country,
747
+ customerCountry,
688
748
  ...businessName && { businessName },
689
749
  ...taxId && { taxId, ...taxIdType && { taxIdType } },
690
- ...customerName && { customerName }
750
+ ...customerName && { customerName },
751
+ ...address
691
752
  };
692
753
  });
693
754
  function validateBusinessDetails(input) {
@@ -769,6 +830,16 @@ export {
769
830
  getTaxIdExample,
770
831
  getTaxIdHelperText,
771
832
  BUSINESS_COUNTRY_OPTIONS,
833
+ POSTAL_CODE_REQUIRED_COUNTRIES,
834
+ STATE_REQUIRED_COUNTRIES,
835
+ isPostalCodeRequired,
836
+ isStateRequired,
837
+ getStateFieldLabel,
838
+ getPostalCodeFieldLabel,
839
+ getPostalCodePlaceholder,
840
+ resolveBuyerCountry,
841
+ isCustomerAddressComplete,
842
+ getCustomerAddressFieldErrors,
772
843
  BusinessDetailsSchema,
773
844
  validateBusinessDetails,
774
845
  TAX_BEHAVIORS,
package/dist/index.cjs CHANGED
@@ -25,8 +25,10 @@ __export(index_exports, {
25
25
  BusinessDetailsSchema: () => BusinessDetailsSchema,
26
26
  COUNTRY_TO_TAX_ID_TYPE: () => COUNTRY_TO_TAX_ID_TYPE,
27
27
  Env: () => Env,
28
+ POSTAL_CODE_REQUIRED_COUNTRIES: () => POSTAL_CODE_REQUIRED_COUNTRIES,
28
29
  SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE: () => SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE,
29
30
  SOLVAPAY_PRODUCT_REF_PLACEHOLDER: () => SOLVAPAY_PRODUCT_REF_PLACEHOLDER,
31
+ STATE_REQUIRED_COUNTRIES: () => STATE_REQUIRED_COUNTRIES,
30
32
  SUPPORTED_BUSINESS_COUNTRIES: () => SUPPORTED_BUSINESS_COUNTRIES,
31
33
  SolvaPayError: () => SolvaPayError,
32
34
  TAX_BEHAVIORS: () => TAX_BEHAVIORS,
@@ -41,18 +43,27 @@ __export(index_exports, {
41
43
  creditsToDisplayMinorUnits: () => creditsToDisplayMinorUnits,
42
44
  deriveTaxIdType: () => deriveTaxIdType,
43
45
  evaluateProductReadiness: () => evaluateProductReadiness,
46
+ getCustomerAddressFieldErrors: () => getCustomerAddressFieldErrors,
47
+ getPostalCodeFieldLabel: () => getPostalCodeFieldLabel,
48
+ getPostalCodePlaceholder: () => getPostalCodePlaceholder,
44
49
  getSellerTaxIdentifierDisplayLabel: () => getSellerTaxIdentifierDisplayLabel,
45
50
  getSolvaPayConfig: () => getSolvaPayConfig,
51
+ getStateFieldLabel: () => getStateFieldLabel,
46
52
  getTaxIdExample: () => getTaxIdExample,
47
53
  getTaxIdFieldLabel: () => getTaxIdFieldLabel,
48
54
  getTaxIdHelperText: () => getTaxIdHelperText,
49
55
  headlineCharges: () => headlineCharges,
50
56
  includedUnits: () => includedUnits,
57
+ isCustomerAddressComplete: () => isCustomerAddressComplete,
58
+ isPostalCodeRequired: () => isPostalCodeRequired,
59
+ isStateRequired: () => isStateRequired,
51
60
  isZeroDecimalCurrency: () => isZeroDecimalCurrency,
52
61
  meterName: () => meterName,
53
62
  minorUnitsPerMajor: () => minorUnitsPerMajor,
54
63
  peggedCreditsPerUnit: () => peggedCreditsPerUnit,
55
64
  perUnitCharge: () => perUnitCharge,
65
+ planPricingShape: () => planPricingShape,
66
+ resolveBuyerCountry: () => resolveBuyerCountry,
56
67
  resolveSellerIdentityDisplay: () => resolveSellerIdentityDisplay,
57
68
  resolveTaxBehavior: () => resolveTaxBehavior,
58
69
  tierBands: () => tierBands,
@@ -224,6 +235,59 @@ function peggedCreditsPerUnit(chargeMinor, creditsPerMinorUnit, usdToChargeRate
224
235
  const rate = usdToChargeRate > 0 ? usdToChargeRate : 1;
225
236
  return Math.round(chargeMinor / rate * creditsPerMinorUnit);
226
237
  }
238
+ function isMetered(priced) {
239
+ return perUnitCharge(priced) != null || tierBands(priced).length > 0;
240
+ }
241
+ function isBillableMetered(priced) {
242
+ const rate = usageRate(priced);
243
+ if (rate != null && rate.amountMinor > 0) return true;
244
+ return tierBands(priced).some((band) => band.charge.amountMinor > 0);
245
+ }
246
+ function baseRecurringChargeMinor(priced) {
247
+ if (!billingCycle(priced)) return void 0;
248
+ const flat = charges(priced).find((charge) => charge.per === "flat" && !charge.oneTime);
249
+ return flat?.amountMinor;
250
+ }
251
+ function oneTimeChargeMinor(priced) {
252
+ if (billingCycle(priced)) return void 0;
253
+ const flat = charges(priced).find((charge) => charge.per === "flat");
254
+ return flat?.amountMinor;
255
+ }
256
+ function headlinePriceMinor(priced) {
257
+ return baseRecurringChargeMinor(priced) ?? oneTimeChargeMinor(priced) ?? 0;
258
+ }
259
+ function derivePricingShape(recurring, metered, billableMetered) {
260
+ if (recurring && billableMetered) return "hybrid";
261
+ if (recurring) return "recurring";
262
+ if (metered) return "usage";
263
+ return "oneTime";
264
+ }
265
+ function planPricingShape(priced) {
266
+ const currencyFallback = (priced?.currency ?? "USD").toUpperCase();
267
+ if (!priced) {
268
+ return { shape: "oneTime", headlineMinor: 0, currency: currencyFallback, cycle: null, rate: null };
269
+ }
270
+ if (priced.requiresPayment === false) {
271
+ return {
272
+ shape: "free",
273
+ headlineMinor: 0,
274
+ currency: currencyFallback,
275
+ cycle: billingCycle(priced),
276
+ rate: usageRate(priced)
277
+ };
278
+ }
279
+ const recurring = billingCycle(priced) != null;
280
+ const metered = isMetered(priced);
281
+ const billableMetered = isBillableMetered(priced);
282
+ const headline = headlineCharges(priced)[0];
283
+ return {
284
+ shape: derivePricingShape(recurring, metered, billableMetered),
285
+ headlineMinor: headlinePriceMinor(priced),
286
+ currency: (headline?.currency ?? priced.currency ?? "USD").toUpperCase(),
287
+ cycle: recurring ? billingCycle(priced) : null,
288
+ rate: metered ? usageRate(priced) : null
289
+ };
290
+ }
227
291
  function creditsPerUnitFromBalance(priced, balance, meter) {
228
292
  const charge = usageRate(priced, meter);
229
293
  if (!charge || !(charge.amountMinor > 0)) return null;
@@ -859,12 +923,67 @@ var BUSINESS_COUNTRY_OPTIONS = STRIPE_TAX_BUYER_COUNTRIES.map(
859
923
  label: country.name
860
924
  })
861
925
  ).sort((a, b) => a.label.localeCompare(b.label));
926
+ var POSTAL_CODE_REQUIRED_COUNTRIES = ["US", "CA", "GB"];
927
+ var STATE_REQUIRED_COUNTRIES = ["US", "CA", "IN"];
928
+ var POSTAL_CODE_REQUIRED_COUNTRY_SET = new Set(POSTAL_CODE_REQUIRED_COUNTRIES);
929
+ var STATE_REQUIRED_COUNTRY_SET = new Set(STATE_REQUIRED_COUNTRIES);
930
+ function isPostalCodeRequired(country) {
931
+ return POSTAL_CODE_REQUIRED_COUNTRY_SET.has(country.trim().toUpperCase());
932
+ }
933
+ function isStateRequired(country) {
934
+ return STATE_REQUIRED_COUNTRY_SET.has(country.trim().toUpperCase());
935
+ }
936
+ function getStateFieldLabel(country) {
937
+ return country.trim().toUpperCase() === "US" ? "State" : "Province";
938
+ }
939
+ function getPostalCodeFieldLabel(country) {
940
+ return country.trim().toUpperCase() === "US" ? "ZIP code" : "Postal code";
941
+ }
942
+ function getPostalCodePlaceholder(country) {
943
+ return country.trim().toUpperCase() === "US" ? "94103" : "Required";
944
+ }
945
+ function resolveBuyerCountry(input) {
946
+ const customerCountry = input.customerCountry?.trim().toUpperCase();
947
+ if (customerCountry) return customerCountry;
948
+ if (input.isBusiness) {
949
+ const country = input.country?.trim().toUpperCase();
950
+ if (country) return country;
951
+ }
952
+ return void 0;
953
+ }
954
+ function isCustomerAddressComplete(input) {
955
+ return Object.keys(getCustomerAddressFieldErrors(input)).length === 0;
956
+ }
957
+ function getCustomerAddressFieldErrors(input) {
958
+ const country = resolveBuyerCountry(input);
959
+ if (!country) {
960
+ return input.isBusiness ? { country: "Country is required" } : { customerCountry: "Country is required" };
961
+ }
962
+ const errors = {};
963
+ if (isPostalCodeRequired(country) && !input.customerPostalCode?.trim()) {
964
+ errors.customerPostalCode = country === "US" ? "ZIP code is required" : "Postal code is required";
965
+ }
966
+ if (isStateRequired(country) && !input.customerState?.trim()) {
967
+ errors.customerState = country === "US" ? "State is required" : "Province is required";
968
+ }
969
+ return errors;
970
+ }
971
+ function pickAddressFields(data) {
972
+ const customerState = data.customerState?.trim();
973
+ const customerPostalCode = data.customerPostalCode?.trim();
974
+ return {
975
+ ...customerState && { customerState },
976
+ ...customerPostalCode && { customerPostalCode }
977
+ };
978
+ }
862
979
  var BusinessDetailsSchema = import_zod.z.object({
863
980
  isBusiness: import_zod.z.boolean(),
864
981
  businessName: import_zod.z.string().optional(),
865
982
  country: import_zod.z.string().optional(),
866
983
  customerCountry: import_zod.z.string().optional(),
867
984
  customerName: import_zod.z.string().max(100).optional(),
985
+ customerState: import_zod.z.string().optional(),
986
+ customerPostalCode: import_zod.z.string().optional(),
868
987
  taxId: import_zod.z.string().optional(),
869
988
  taxIdType: import_zod.z.enum(TAX_ID_TYPES).optional()
870
989
  }).superRefine((data, ctx) => {
@@ -907,13 +1026,15 @@ var BusinessDetailsSchema = import_zod.z.object({
907
1026
  }
908
1027
  }).transform((data) => {
909
1028
  const customerName = data.customerName?.trim();
1029
+ const address = pickAddressFields(data);
910
1030
  if (!data.isBusiness) {
911
- const customerCountry = data.customerCountry?.trim().toUpperCase();
912
- if (customerCountry && isStripeTaxBuyerCountry(customerCountry)) {
1031
+ const customerCountry2 = data.customerCountry?.trim().toUpperCase();
1032
+ if (customerCountry2 && isStripeTaxBuyerCountry(customerCountry2)) {
913
1033
  return {
914
1034
  isBusiness: false,
915
- customerCountry,
916
- ...customerName && { customerName }
1035
+ customerCountry: customerCountry2,
1036
+ ...customerName && { customerName },
1037
+ ...address
917
1038
  };
918
1039
  }
919
1040
  return {
@@ -922,15 +1043,19 @@ var BusinessDetailsSchema = import_zod.z.object({
922
1043
  };
923
1044
  }
924
1045
  const country = data.country.trim().toUpperCase();
1046
+ const customerCountryRaw = data.customerCountry?.trim().toUpperCase();
1047
+ const customerCountry = customerCountryRaw && isStripeTaxBuyerCountry(customerCountryRaw) ? customerCountryRaw : country;
925
1048
  const businessName = data.businessName?.trim();
926
1049
  const taxId = data.taxId?.trim() ? normalizeTaxId(data.taxId) : void 0;
927
1050
  const taxIdType = taxId ? deriveTaxIdType(country) : void 0;
928
1051
  return {
929
1052
  isBusiness: true,
930
1053
  country,
1054
+ customerCountry,
931
1055
  ...businessName && { businessName },
932
1056
  ...taxId && { taxId, ...taxIdType && { taxIdType } },
933
- ...customerName && { customerName }
1057
+ ...customerName && { customerName },
1058
+ ...address
934
1059
  };
935
1060
  });
936
1061
  function validateBusinessDetails(input) {
@@ -1094,8 +1219,10 @@ var version = "0.1.0";
1094
1219
  BusinessDetailsSchema,
1095
1220
  COUNTRY_TO_TAX_ID_TYPE,
1096
1221
  Env,
1222
+ POSTAL_CODE_REQUIRED_COUNTRIES,
1097
1223
  SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE,
1098
1224
  SOLVAPAY_PRODUCT_REF_PLACEHOLDER,
1225
+ STATE_REQUIRED_COUNTRIES,
1099
1226
  SUPPORTED_BUSINESS_COUNTRIES,
1100
1227
  SolvaPayError,
1101
1228
  TAX_BEHAVIORS,
@@ -1110,18 +1237,27 @@ var version = "0.1.0";
1110
1237
  creditsToDisplayMinorUnits,
1111
1238
  deriveTaxIdType,
1112
1239
  evaluateProductReadiness,
1240
+ getCustomerAddressFieldErrors,
1241
+ getPostalCodeFieldLabel,
1242
+ getPostalCodePlaceholder,
1113
1243
  getSellerTaxIdentifierDisplayLabel,
1114
1244
  getSolvaPayConfig,
1245
+ getStateFieldLabel,
1115
1246
  getTaxIdExample,
1116
1247
  getTaxIdFieldLabel,
1117
1248
  getTaxIdHelperText,
1118
1249
  headlineCharges,
1119
1250
  includedUnits,
1251
+ isCustomerAddressComplete,
1252
+ isPostalCodeRequired,
1253
+ isStateRequired,
1120
1254
  isZeroDecimalCurrency,
1121
1255
  meterName,
1122
1256
  minorUnitsPerMajor,
1123
1257
  peggedCreditsPerUnit,
1124
1258
  perUnitCharge,
1259
+ planPricingShape,
1260
+ resolveBuyerCountry,
1125
1261
  resolveSellerIdentityDisplay,
1126
1262
  resolveTaxBehavior,
1127
1263
  tierBands,
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- export { B as BUSINESS_COUNTRY_DISPLAY_NAMES, a as BUSINESS_COUNTRY_OPTIONS, b as BusinessCountryOption, c as BusinessDetails, d as BusinessDetailsInput, e as BusinessDetailsSchema, f as BusinessDetailsValidationError, g as BusinessDetailsValidationIssue, C as COUNTRY_TO_TAX_ID_TYPE, E as EuMemberCountry, S as SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE, h as SUPPORTED_BUSINESS_COUNTRIES, i as SellerIdentityDisplay, j as SellerIdentityRow, k as SupportedBusinessCountry, T as TAX_BEHAVIORS, l as TAX_EXCLUSIVE_CURRENCIES, m as TAX_ID_EXAMPLE_BY_COUNTRY, n as TAX_ID_TYPES, o as TaxBehavior, p as TaxBreakdown, q as TaxIdType, V as ValidateBusinessDetailsResult, r as deriveTaxIdType, s as getSellerTaxIdentifierDisplayLabel, t as getTaxIdExample, u as getTaxIdFieldLabel, v as getTaxIdHelperText, w as resolveSellerIdentityDisplay, x as resolveTaxBehavior, y as validateBusinessDetails } from './business-details-public-7S0Hs-TZ.cjs';
2
+ export { B as BUSINESS_COUNTRY_DISPLAY_NAMES, a as BUSINESS_COUNTRY_OPTIONS, b as BusinessCountryOption, c as BusinessDetails, d as BusinessDetailsInput, e as BusinessDetailsSchema, f as BusinessDetailsValidationError, g as BusinessDetailsValidationIssue, C as COUNTRY_TO_TAX_ID_TYPE, E as EuMemberCountry, P as POSTAL_CODE_REQUIRED_COUNTRIES, S as SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE, h as STATE_REQUIRED_COUNTRIES, i as SUPPORTED_BUSINESS_COUNTRIES, j as SellerIdentityDisplay, k as SellerIdentityRow, l as SupportedBusinessCountry, T as TAX_BEHAVIORS, m as TAX_EXCLUSIVE_CURRENCIES, n as TAX_ID_EXAMPLE_BY_COUNTRY, o as TAX_ID_TYPES, p as TaxBehavior, q as TaxBreakdown, r as TaxIdType, V as ValidateBusinessDetailsResult, s as deriveTaxIdType, t as getCustomerAddressFieldErrors, u as getPostalCodeFieldLabel, v as getPostalCodePlaceholder, w as getSellerTaxIdentifierDisplayLabel, x as getStateFieldLabel, y as getTaxIdExample, z as getTaxIdFieldLabel, A as getTaxIdHelperText, D as isCustomerAddressComplete, F as isPostalCodeRequired, G as isStateRequired, H as resolveBuyerCountry, I as resolveSellerIdentityDisplay, J as resolveTaxBehavior, K as validateBusinessDetails } from './business-details-public-DSBkp-BK.cjs';
3
3
 
4
4
  /**
5
5
  * Shared credit → fiat conversion for MCP bootstrap narration and React
@@ -167,18 +167,31 @@ interface BalancePegLike {
167
167
  displayExchangeRate?: number | null;
168
168
  creditsPerMinorUnit?: number | null;
169
169
  }
170
+ type PricingShape = 'free' | 'usage' | 'recurring' | 'hybrid' | 'oneTime';
170
171
  /**
171
- * Credits per metered call for `priced`, priced against a customer's
172
- * balance peg. `null` when it cannot be established honestly.
173
- *
174
- * The backend converts a per-unit charge to credits with
175
- * `resolveDisplayFx(chargeCurrency)`. A balance carries
176
- * `resolveDisplayFx(provider.defaultCurrency)` as `displayExchangeRate`,
177
- * so the two agree only when the charge is denominated in the balance's
178
- * `displayCurrency`. When they differ the SDK does not hold the right
179
- * rate and returns `null` rather than publishing a number that would be
180
- * wrong by the FX ratio.
172
+ * Derived scalars accept `null` because the wire sends them that way on
173
+ * frozen plan snapshots — an absent value and an explicit `null` mean the
174
+ * same thing here, and every read below treats them alike.
175
+ */
176
+ interface PlanPricingShapeInput extends PricedLike {
177
+ requiresPayment?: boolean | null;
178
+ type?: string | null;
179
+ currency?: string | null;
180
+ price?: number | null;
181
+ }
182
+ interface PlanPricingShape {
183
+ shape: PricingShape;
184
+ headlineMinor: number;
185
+ currency: string;
186
+ cycle: BillingCycleLike | null;
187
+ rate: UsageRate | null;
188
+ }
189
+ /**
190
+ * Derives the pricing shape a plan-row or narration surface should branch on.
191
+ * Mirrors the backend's `derivePlanLabelFromFlags` rule in
192
+ * `packages/domain/src/contracts/pricing/derive.ts`.
181
193
  */
194
+ declare function planPricingShape(priced: PlanPricingShapeInput | null | undefined): PlanPricingShape;
182
195
  declare function creditsPerUnitFromBalance(priced: PricedLike | null | undefined, balance: BalancePegLike | null | undefined, meter?: string): number | null;
183
196
 
184
197
  /**
@@ -303,4 +316,4 @@ declare function getSolvaPayConfig(): SolvaPayConfig;
303
316
 
304
317
  declare const version = "0.1.0";
305
318
 
306
- export { type BalancePegLike, type BillingCycleLike, type ChargeLike, Env, type PricedLike, type PricingOptionLike, type ProductReadinessInput, type ProductReadinessResult, SOLVAPAY_PRODUCT_REF_PLACEHOLDER, type SolvaPayConfig, SolvaPayError, type TierLike, type UsageRate, assertValidProductRef, billingCycle, charges, countsUsage, creditsPerUnitFromBalance, creditsToDisplayMinorUnits, evaluateProductReadiness, getSolvaPayConfig, headlineCharges, includedUnits, isZeroDecimalCurrency, meterName, minorUnitsPerMajor, peggedCreditsPerUnit, perUnitCharge, tierBands, tierMeters, trialDays, usageRate, version };
319
+ export { type BalancePegLike, type BillingCycleLike, type ChargeLike, Env, type PlanPricingShape, type PlanPricingShapeInput, type PricedLike, type PricingOptionLike, type PricingShape, type ProductReadinessInput, type ProductReadinessResult, SOLVAPAY_PRODUCT_REF_PLACEHOLDER, type SolvaPayConfig, SolvaPayError, type TierLike, type UsageRate, assertValidProductRef, billingCycle, charges, countsUsage, creditsPerUnitFromBalance, creditsToDisplayMinorUnits, evaluateProductReadiness, getSolvaPayConfig, headlineCharges, includedUnits, isZeroDecimalCurrency, meterName, minorUnitsPerMajor, peggedCreditsPerUnit, perUnitCharge, planPricingShape, tierBands, tierMeters, trialDays, usageRate, version };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- export { B as BUSINESS_COUNTRY_DISPLAY_NAMES, a as BUSINESS_COUNTRY_OPTIONS, b as BusinessCountryOption, c as BusinessDetails, d as BusinessDetailsInput, e as BusinessDetailsSchema, f as BusinessDetailsValidationError, g as BusinessDetailsValidationIssue, C as COUNTRY_TO_TAX_ID_TYPE, E as EuMemberCountry, S as SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE, h as SUPPORTED_BUSINESS_COUNTRIES, i as SellerIdentityDisplay, j as SellerIdentityRow, k as SupportedBusinessCountry, T as TAX_BEHAVIORS, l as TAX_EXCLUSIVE_CURRENCIES, m as TAX_ID_EXAMPLE_BY_COUNTRY, n as TAX_ID_TYPES, o as TaxBehavior, p as TaxBreakdown, q as TaxIdType, V as ValidateBusinessDetailsResult, r as deriveTaxIdType, s as getSellerTaxIdentifierDisplayLabel, t as getTaxIdExample, u as getTaxIdFieldLabel, v as getTaxIdHelperText, w as resolveSellerIdentityDisplay, x as resolveTaxBehavior, y as validateBusinessDetails } from './business-details-public-7S0Hs-TZ.js';
2
+ export { B as BUSINESS_COUNTRY_DISPLAY_NAMES, a as BUSINESS_COUNTRY_OPTIONS, b as BusinessCountryOption, c as BusinessDetails, d as BusinessDetailsInput, e as BusinessDetailsSchema, f as BusinessDetailsValidationError, g as BusinessDetailsValidationIssue, C as COUNTRY_TO_TAX_ID_TYPE, E as EuMemberCountry, P as POSTAL_CODE_REQUIRED_COUNTRIES, S as SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE, h as STATE_REQUIRED_COUNTRIES, i as SUPPORTED_BUSINESS_COUNTRIES, j as SellerIdentityDisplay, k as SellerIdentityRow, l as SupportedBusinessCountry, T as TAX_BEHAVIORS, m as TAX_EXCLUSIVE_CURRENCIES, n as TAX_ID_EXAMPLE_BY_COUNTRY, o as TAX_ID_TYPES, p as TaxBehavior, q as TaxBreakdown, r as TaxIdType, V as ValidateBusinessDetailsResult, s as deriveTaxIdType, t as getCustomerAddressFieldErrors, u as getPostalCodeFieldLabel, v as getPostalCodePlaceholder, w as getSellerTaxIdentifierDisplayLabel, x as getStateFieldLabel, y as getTaxIdExample, z as getTaxIdFieldLabel, A as getTaxIdHelperText, D as isCustomerAddressComplete, F as isPostalCodeRequired, G as isStateRequired, H as resolveBuyerCountry, I as resolveSellerIdentityDisplay, J as resolveTaxBehavior, K as validateBusinessDetails } from './business-details-public-DSBkp-BK.js';
3
3
 
4
4
  /**
5
5
  * Shared credit → fiat conversion for MCP bootstrap narration and React
@@ -167,18 +167,31 @@ interface BalancePegLike {
167
167
  displayExchangeRate?: number | null;
168
168
  creditsPerMinorUnit?: number | null;
169
169
  }
170
+ type PricingShape = 'free' | 'usage' | 'recurring' | 'hybrid' | 'oneTime';
170
171
  /**
171
- * Credits per metered call for `priced`, priced against a customer's
172
- * balance peg. `null` when it cannot be established honestly.
173
- *
174
- * The backend converts a per-unit charge to credits with
175
- * `resolveDisplayFx(chargeCurrency)`. A balance carries
176
- * `resolveDisplayFx(provider.defaultCurrency)` as `displayExchangeRate`,
177
- * so the two agree only when the charge is denominated in the balance's
178
- * `displayCurrency`. When they differ the SDK does not hold the right
179
- * rate and returns `null` rather than publishing a number that would be
180
- * wrong by the FX ratio.
172
+ * Derived scalars accept `null` because the wire sends them that way on
173
+ * frozen plan snapshots — an absent value and an explicit `null` mean the
174
+ * same thing here, and every read below treats them alike.
175
+ */
176
+ interface PlanPricingShapeInput extends PricedLike {
177
+ requiresPayment?: boolean | null;
178
+ type?: string | null;
179
+ currency?: string | null;
180
+ price?: number | null;
181
+ }
182
+ interface PlanPricingShape {
183
+ shape: PricingShape;
184
+ headlineMinor: number;
185
+ currency: string;
186
+ cycle: BillingCycleLike | null;
187
+ rate: UsageRate | null;
188
+ }
189
+ /**
190
+ * Derives the pricing shape a plan-row or narration surface should branch on.
191
+ * Mirrors the backend's `derivePlanLabelFromFlags` rule in
192
+ * `packages/domain/src/contracts/pricing/derive.ts`.
181
193
  */
194
+ declare function planPricingShape(priced: PlanPricingShapeInput | null | undefined): PlanPricingShape;
182
195
  declare function creditsPerUnitFromBalance(priced: PricedLike | null | undefined, balance: BalancePegLike | null | undefined, meter?: string): number | null;
183
196
 
184
197
  /**
@@ -303,4 +316,4 @@ declare function getSolvaPayConfig(): SolvaPayConfig;
303
316
 
304
317
  declare const version = "0.1.0";
305
318
 
306
- export { type BalancePegLike, type BillingCycleLike, type ChargeLike, Env, type PricedLike, type PricingOptionLike, type ProductReadinessInput, type ProductReadinessResult, SOLVAPAY_PRODUCT_REF_PLACEHOLDER, type SolvaPayConfig, SolvaPayError, type TierLike, type UsageRate, assertValidProductRef, billingCycle, charges, countsUsage, creditsPerUnitFromBalance, creditsToDisplayMinorUnits, evaluateProductReadiness, getSolvaPayConfig, headlineCharges, includedUnits, isZeroDecimalCurrency, meterName, minorUnitsPerMajor, peggedCreditsPerUnit, perUnitCharge, tierBands, tierMeters, trialDays, usageRate, version };
319
+ export { type BalancePegLike, type BillingCycleLike, type ChargeLike, Env, type PlanPricingShape, type PlanPricingShapeInput, type PricedLike, type PricingOptionLike, type PricingShape, type ProductReadinessInput, type ProductReadinessResult, SOLVAPAY_PRODUCT_REF_PLACEHOLDER, type SolvaPayConfig, SolvaPayError, type TierLike, type UsageRate, assertValidProductRef, billingCycle, charges, countsUsage, creditsPerUnitFromBalance, creditsToDisplayMinorUnits, evaluateProductReadiness, getSolvaPayConfig, headlineCharges, includedUnits, isZeroDecimalCurrency, meterName, minorUnitsPerMajor, peggedCreditsPerUnit, perUnitCharge, planPricingShape, tierBands, tierMeters, trialDays, usageRate, version };
package/dist/index.js CHANGED
@@ -3,21 +3,31 @@ import {
3
3
  BUSINESS_COUNTRY_OPTIONS,
4
4
  BusinessDetailsSchema,
5
5
  COUNTRY_TO_TAX_ID_TYPE,
6
+ POSTAL_CODE_REQUIRED_COUNTRIES,
6
7
  SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE,
8
+ STATE_REQUIRED_COUNTRIES,
7
9
  SUPPORTED_BUSINESS_COUNTRIES,
8
10
  TAX_BEHAVIORS,
9
11
  TAX_EXCLUSIVE_CURRENCIES,
10
12
  TAX_ID_EXAMPLE_BY_COUNTRY,
11
13
  TAX_ID_TYPES,
12
14
  deriveTaxIdType,
15
+ getCustomerAddressFieldErrors,
16
+ getPostalCodeFieldLabel,
17
+ getPostalCodePlaceholder,
13
18
  getSellerTaxIdentifierDisplayLabel,
19
+ getStateFieldLabel,
14
20
  getTaxIdExample,
15
21
  getTaxIdFieldLabel,
16
22
  getTaxIdHelperText,
23
+ isCustomerAddressComplete,
24
+ isPostalCodeRequired,
25
+ isStateRequired,
26
+ resolveBuyerCountry,
17
27
  resolveSellerIdentityDisplay,
18
28
  resolveTaxBehavior,
19
29
  validateBusinessDetails
20
- } from "./chunk-3RBWU5OY.js";
30
+ } from "./chunk-M5X43XFK.js";
21
31
 
22
32
  // src/index.ts
23
33
  import { z } from "zod";
@@ -181,6 +191,59 @@ function peggedCreditsPerUnit(chargeMinor, creditsPerMinorUnit, usdToChargeRate
181
191
  const rate = usdToChargeRate > 0 ? usdToChargeRate : 1;
182
192
  return Math.round(chargeMinor / rate * creditsPerMinorUnit);
183
193
  }
194
+ function isMetered(priced) {
195
+ return perUnitCharge(priced) != null || tierBands(priced).length > 0;
196
+ }
197
+ function isBillableMetered(priced) {
198
+ const rate = usageRate(priced);
199
+ if (rate != null && rate.amountMinor > 0) return true;
200
+ return tierBands(priced).some((band) => band.charge.amountMinor > 0);
201
+ }
202
+ function baseRecurringChargeMinor(priced) {
203
+ if (!billingCycle(priced)) return void 0;
204
+ const flat = charges(priced).find((charge) => charge.per === "flat" && !charge.oneTime);
205
+ return flat?.amountMinor;
206
+ }
207
+ function oneTimeChargeMinor(priced) {
208
+ if (billingCycle(priced)) return void 0;
209
+ const flat = charges(priced).find((charge) => charge.per === "flat");
210
+ return flat?.amountMinor;
211
+ }
212
+ function headlinePriceMinor(priced) {
213
+ return baseRecurringChargeMinor(priced) ?? oneTimeChargeMinor(priced) ?? 0;
214
+ }
215
+ function derivePricingShape(recurring, metered, billableMetered) {
216
+ if (recurring && billableMetered) return "hybrid";
217
+ if (recurring) return "recurring";
218
+ if (metered) return "usage";
219
+ return "oneTime";
220
+ }
221
+ function planPricingShape(priced) {
222
+ const currencyFallback = (priced?.currency ?? "USD").toUpperCase();
223
+ if (!priced) {
224
+ return { shape: "oneTime", headlineMinor: 0, currency: currencyFallback, cycle: null, rate: null };
225
+ }
226
+ if (priced.requiresPayment === false) {
227
+ return {
228
+ shape: "free",
229
+ headlineMinor: 0,
230
+ currency: currencyFallback,
231
+ cycle: billingCycle(priced),
232
+ rate: usageRate(priced)
233
+ };
234
+ }
235
+ const recurring = billingCycle(priced) != null;
236
+ const metered = isMetered(priced);
237
+ const billableMetered = isBillableMetered(priced);
238
+ const headline = headlineCharges(priced)[0];
239
+ return {
240
+ shape: derivePricingShape(recurring, metered, billableMetered),
241
+ headlineMinor: headlinePriceMinor(priced),
242
+ currency: (headline?.currency ?? priced.currency ?? "USD").toUpperCase(),
243
+ cycle: recurring ? billingCycle(priced) : null,
244
+ rate: metered ? usageRate(priced) : null
245
+ };
246
+ }
184
247
  function creditsPerUnitFromBalance(priced, balance, meter) {
185
248
  const charge = usageRate(priced, meter);
186
249
  if (!charge || !(charge.amountMinor > 0)) return null;
@@ -289,8 +352,10 @@ export {
289
352
  BusinessDetailsSchema,
290
353
  COUNTRY_TO_TAX_ID_TYPE,
291
354
  Env,
355
+ POSTAL_CODE_REQUIRED_COUNTRIES,
292
356
  SELLER_TAX_IDENTIFIER_DISPLAY_LABEL_BY_TYPE,
293
357
  SOLVAPAY_PRODUCT_REF_PLACEHOLDER,
358
+ STATE_REQUIRED_COUNTRIES,
294
359
  SUPPORTED_BUSINESS_COUNTRIES,
295
360
  SolvaPayError,
296
361
  TAX_BEHAVIORS,
@@ -305,18 +370,27 @@ export {
305
370
  creditsToDisplayMinorUnits,
306
371
  deriveTaxIdType,
307
372
  evaluateProductReadiness,
373
+ getCustomerAddressFieldErrors,
374
+ getPostalCodeFieldLabel,
375
+ getPostalCodePlaceholder,
308
376
  getSellerTaxIdentifierDisplayLabel,
309
377
  getSolvaPayConfig,
378
+ getStateFieldLabel,
310
379
  getTaxIdExample,
311
380
  getTaxIdFieldLabel,
312
381
  getTaxIdHelperText,
313
382
  headlineCharges,
314
383
  includedUnits,
384
+ isCustomerAddressComplete,
385
+ isPostalCodeRequired,
386
+ isStateRequired,
315
387
  isZeroDecimalCurrency,
316
388
  meterName,
317
389
  minorUnitsPerMajor,
318
390
  peggedCreditsPerUnit,
319
391
  perUnitCharge,
392
+ planPricingShape,
393
+ resolveBuyerCountry,
320
394
  resolveSellerIdentityDisplay,
321
395
  resolveTaxBehavior,
322
396
  tierBands,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solvapay/core",
3
- "version": "1.6.0",
3
+ "version": "1.7.0-preview-3f68079d7097167693fa7cdc76752dcf23fd1ab6",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",