@owlmeans/web-payment 0.1.18-rc.2 → 0.1.18-rc.21

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 (203) hide show
  1. package/README.md +30 -1
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/web-payment/SKILL.md +287 -20
  4. package/build/@/components/ui/card.d.ts +10 -0
  5. package/build/@/components/ui/card.d.ts.map +1 -0
  6. package/build/@/components/ui/card.js +25 -0
  7. package/build/@/components/ui/card.js.map +1 -0
  8. package/build/@/components/ui/checkbox.d.ts +5 -0
  9. package/build/@/components/ui/checkbox.d.ts.map +1 -0
  10. package/build/@/components/ui/checkbox.js +6 -0
  11. package/build/@/components/ui/checkbox.js.map +1 -0
  12. package/build/@/components/ui/progress.d.ts +5 -0
  13. package/build/@/components/ui/progress.d.ts.map +1 -0
  14. package/build/@/components/ui/progress.js +11 -0
  15. package/build/@/components/ui/progress.js.map +1 -0
  16. package/build/@/components/ui/select.d.ts +8 -0
  17. package/build/@/components/ui/select.d.ts.map +1 -0
  18. package/build/@/components/ui/select.js +9 -0
  19. package/build/@/components/ui/select.js.map +1 -0
  20. package/build/capability-list.d.ts +7 -0
  21. package/build/capability-list.d.ts.map +1 -0
  22. package/build/capability-list.js +24 -0
  23. package/build/capability-list.js.map +1 -0
  24. package/build/checkout-limit.d.ts +11 -0
  25. package/build/checkout-limit.d.ts.map +1 -0
  26. package/build/checkout-limit.js +34 -0
  27. package/build/checkout-limit.js.map +1 -0
  28. package/build/consumer/cancellation.d.ts +20 -0
  29. package/build/consumer/cancellation.d.ts.map +1 -0
  30. package/build/consumer/cancellation.js +115 -0
  31. package/build/consumer/cancellation.js.map +1 -0
  32. package/build/consumer/copy.d.ts +23 -0
  33. package/build/consumer/copy.d.ts.map +1 -0
  34. package/build/consumer/copy.js +75 -0
  35. package/build/consumer/copy.js.map +1 -0
  36. package/build/consumer/ensure.d.ts +56 -0
  37. package/build/consumer/ensure.d.ts.map +1 -0
  38. package/build/consumer/ensure.js +71 -0
  39. package/build/consumer/ensure.js.map +1 -0
  40. package/build/consumer/fields.d.ts +43 -0
  41. package/build/consumer/fields.d.ts.map +1 -0
  42. package/build/consumer/fields.js +19 -0
  43. package/build/consumer/fields.js.map +1 -0
  44. package/build/consumer/hooks.d.ts +113 -0
  45. package/build/consumer/hooks.d.ts.map +1 -0
  46. package/build/consumer/hooks.js +225 -0
  47. package/build/consumer/hooks.js.map +1 -0
  48. package/build/consumer/index.d.ts +14 -0
  49. package/build/consumer/index.d.ts.map +1 -0
  50. package/build/consumer/index.js +12 -0
  51. package/build/consumer/index.js.map +1 -0
  52. package/build/consumer/legal.d.ts +53 -0
  53. package/build/consumer/legal.d.ts.map +1 -0
  54. package/build/consumer/legal.js +77 -0
  55. package/build/consumer/legal.js.map +1 -0
  56. package/build/consumer/performance-consent-dialog.d.ts +18 -0
  57. package/build/consumer/performance-consent-dialog.d.ts.map +1 -0
  58. package/build/consumer/performance-consent-dialog.js +71 -0
  59. package/build/consumer/performance-consent-dialog.js.map +1 -0
  60. package/build/consumer/provider.d.ts +33 -0
  61. package/build/consumer/provider.d.ts.map +1 -0
  62. package/build/consumer/provider.js +26 -0
  63. package/build/consumer/provider.js.map +1 -0
  64. package/build/consumer/refusal.d.ts +35 -0
  65. package/build/consumer/refusal.d.ts.map +1 -0
  66. package/build/consumer/refusal.js +98 -0
  67. package/build/consumer/refusal.js.map +1 -0
  68. package/build/consumer/subscription-start-dialog.d.ts +16 -0
  69. package/build/consumer/subscription-start-dialog.d.ts.map +1 -0
  70. package/build/consumer/subscription-start-dialog.js +43 -0
  71. package/build/consumer/subscription-start-dialog.js.map +1 -0
  72. package/build/consumer/types.d.ts +114 -0
  73. package/build/consumer/types.d.ts.map +1 -0
  74. package/build/consumer/types.js +2 -0
  75. package/build/consumer/types.js.map +1 -0
  76. package/build/consumer/withdrawal.d.ts +29 -0
  77. package/build/consumer/withdrawal.d.ts.map +1 -0
  78. package/build/consumer/withdrawal.js +140 -0
  79. package/build/consumer/withdrawal.js.map +1 -0
  80. package/build/copy.d.ts +14 -0
  81. package/build/copy.d.ts.map +1 -0
  82. package/build/copy.js +51 -0
  83. package/build/copy.js.map +1 -0
  84. package/build/dialog.d.ts +1 -1
  85. package/build/dialog.d.ts.map +1 -1
  86. package/build/dialog.js +46 -17
  87. package/build/dialog.js.map +1 -1
  88. package/build/entitlement.d.ts +26 -0
  89. package/build/entitlement.d.ts.map +1 -0
  90. package/build/entitlement.js +42 -0
  91. package/build/entitlement.js.map +1 -0
  92. package/build/estimate-cache.d.ts +14 -0
  93. package/build/estimate-cache.d.ts.map +1 -0
  94. package/build/estimate-cache.js +39 -0
  95. package/build/estimate-cache.js.map +1 -0
  96. package/build/estimate-summary.d.ts +64 -0
  97. package/build/estimate-summary.d.ts.map +1 -0
  98. package/build/estimate-summary.js +94 -0
  99. package/build/estimate-summary.js.map +1 -0
  100. package/build/estimate.d.ts +34 -0
  101. package/build/estimate.d.ts.map +1 -0
  102. package/build/estimate.js +92 -0
  103. package/build/estimate.js.map +1 -0
  104. package/build/format.d.ts +15 -0
  105. package/build/format.d.ts.map +1 -0
  106. package/build/format.js +68 -0
  107. package/build/format.js.map +1 -0
  108. package/build/hooks.d.ts +0 -4
  109. package/build/hooks.d.ts.map +1 -1
  110. package/build/hooks.js +3 -30
  111. package/build/hooks.js.map +1 -1
  112. package/build/i18n/be.json +1 -1
  113. package/build/i18n/de.json +1 -1
  114. package/build/i18n/en.json +1 -1
  115. package/build/i18n/es.json +1 -1
  116. package/build/i18n/fr.json +145 -0
  117. package/build/i18n/pl.json +1 -1
  118. package/build/i18n/ru.json +1 -1
  119. package/build/i18n/uk.json +1 -1
  120. package/build/i18n.d.ts +2 -1
  121. package/build/i18n.d.ts.map +1 -1
  122. package/build/i18n.js +11 -7
  123. package/build/i18n.js.map +1 -1
  124. package/build/index.d.ts +9 -0
  125. package/build/index.d.ts.map +1 -1
  126. package/build/index.js +9 -0
  127. package/build/index.js.map +1 -1
  128. package/build/limit-meter.d.ts +7 -0
  129. package/build/limit-meter.d.ts.map +1 -0
  130. package/build/limit-meter.js +26 -0
  131. package/build/limit-meter.js.map +1 -0
  132. package/build/plan-card.d.ts +7 -0
  133. package/build/plan-card.d.ts.map +1 -0
  134. package/build/plan-card.js +29 -0
  135. package/build/plan-card.js.map +1 -0
  136. package/build/poll.d.ts +7 -0
  137. package/build/poll.d.ts.map +1 -0
  138. package/build/poll.js +28 -0
  139. package/build/poll.js.map +1 -0
  140. package/build/selectors.d.ts +18 -0
  141. package/build/selectors.d.ts.map +1 -0
  142. package/build/selectors.js +78 -0
  143. package/build/selectors.js.map +1 -0
  144. package/build/types.d.ts +120 -2
  145. package/build/types.d.ts.map +1 -1
  146. package/package.json +22 -7
  147. package/src/@/components/ui/card.tsx +93 -0
  148. package/src/@/components/ui/checkbox.tsx +23 -0
  149. package/src/@/components/ui/progress.tsx +44 -0
  150. package/src/@/components/ui/select.tsx +62 -0
  151. package/src/@/globals.css +10 -0
  152. package/src/capability-list.tsx +50 -0
  153. package/src/checkout-limit.tsx +48 -0
  154. package/src/consumer/cancellation.tsx +214 -0
  155. package/src/consumer/copy.ts +93 -0
  156. package/src/consumer/ensure.ts +124 -0
  157. package/src/consumer/fields.tsx +89 -0
  158. package/src/consumer/hooks.ts +358 -0
  159. package/src/consumer/index.ts +13 -0
  160. package/src/consumer/legal.tsx +129 -0
  161. package/src/consumer/performance-consent-dialog.tsx +132 -0
  162. package/src/consumer/provider.tsx +49 -0
  163. package/src/consumer/refusal.ts +110 -0
  164. package/src/consumer/subscription-start-dialog.tsx +87 -0
  165. package/src/consumer/types.ts +121 -0
  166. package/src/consumer/withdrawal.tsx +279 -0
  167. package/src/copy.tsx +62 -0
  168. package/src/dialog.tsx +58 -25
  169. package/src/entitlement.ts +56 -0
  170. package/src/estimate-cache.ts +40 -0
  171. package/src/estimate-summary.tsx +172 -0
  172. package/src/estimate.ts +119 -0
  173. package/src/format.ts +71 -0
  174. package/src/hooks.ts +3 -35
  175. package/src/i18n/be.json +1 -1
  176. package/src/i18n/de.json +1 -1
  177. package/src/i18n/en.json +1 -1
  178. package/src/i18n/es.json +1 -1
  179. package/src/i18n/fr.json +145 -0
  180. package/src/i18n/pl.json +1 -1
  181. package/src/i18n/ru.json +1 -1
  182. package/src/i18n/uk.json +1 -1
  183. package/src/i18n.ts +12 -7
  184. package/src/index.ts +9 -0
  185. package/src/limit-meter.tsx +55 -0
  186. package/src/plan-card.tsx +67 -0
  187. package/src/poll.ts +27 -0
  188. package/src/selectors.ts +93 -0
  189. package/src/types.ts +142 -2
  190. package/tests/consent-refusal.spec.ts +83 -0
  191. package/tests/consumer-hooks.spec.ts +205 -0
  192. package/tests/consumer.spec.ts +343 -0
  193. package/tests/context.ts +9 -0
  194. package/tests/dialog.spec.ts +49 -0
  195. package/tests/entitlement.spec.ts +117 -0
  196. package/tests/estimate-cache.spec.ts +46 -0
  197. package/tests/harness/consumer-fixtures.ts +105 -0
  198. package/tests/harness/consumer.tsx +197 -0
  199. package/tests/harness/entitlement.tsx +159 -0
  200. package/tests/harness/estimate-fixtures.ts +48 -0
  201. package/tests/harness/mount.tsx +19 -3
  202. package/tests/i18n.spec.ts +78 -8
  203. package/tests/pieces.spec.ts +134 -0
@@ -0,0 +1,64 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { PriceEstimateControl } from './types.js';
3
+ export interface CountrySelectProps {
4
+ /** ISO 3166-1 alpha-2, or `''` for the placeholder. */
5
+ value: string;
6
+ onChange: (country: string) => void;
7
+ /** Defaults to the `estimate.country` string (also the field's own label). */
8
+ label?: string;
9
+ id?: string;
10
+ className?: string;
11
+ /** The country cannot be changed here — a billing country locked by the first purchase. */
12
+ disabled?: boolean;
13
+ /** A line under the picker — why it is disabled, typically. */
14
+ note?: ReactNode;
15
+ }
16
+ /**
17
+ * The billing-country picker alone — the piece `PriceEstimateSummary` composes for a single,
18
+ * self-contained estimate, and what a shared picker (several estimates, one country — a plan
19
+ * comparison table) renders once and drives every `usePriceEstimate({ country, onCountryChange })`
20
+ * with. Country names are the viewer's own language, alphabetically ordered.
21
+ *
22
+ * `[data-country-select]` carries `data-locked` (`"true"` while disabled) and the chosen
23
+ * `data-country`; the note is `[data-country-note]`.
24
+ */
25
+ export declare const CountrySelect: ({ value, onChange, label, id, className, disabled, note, }: CountrySelectProps) => import("react").JSX.Element;
26
+ export interface PriceEstimateAmountProps {
27
+ control: Pick<PriceEstimateControl, 'estimate' | 'loading' | 'failed'>;
28
+ /** The amount to show tax and a total for — may differ from the estimate's own reference amount. */
29
+ subtotalMinor: number;
30
+ currency: string;
31
+ /** Appended after the total row, e.g. `"/ month"`. */
32
+ suffix?: string;
33
+ className?: string;
34
+ }
35
+ /**
36
+ * What Stripe Tax says at the estimate's country, with NO country picker of its own: the rate(s),
37
+ * an estimated total, and one sentence for whichever status leaves no number to trust (reverse
38
+ * charge, no tax, "at checkout", "choose a country"). Several of these may share one
39
+ * `CountrySelect` (a plan comparison table).
40
+ *
41
+ * A country whose currency differs from `currency` (Adaptive Pricing found a rate) shows the tax
42
+ * and the total in THAT currency instead, marked `≈` throughout — never both currencies at once,
43
+ * which would read as two different prices for the same line. The rate percentage itself is
44
+ * currency-agnostic and always shows as Stripe stated it.
45
+ *
46
+ * `data-price-estimate` / `data-status` are stable test hooks.
47
+ */
48
+ export declare const PriceEstimateAmount: ({ control, subtotalMinor, currency, suffix, className }: PriceEstimateAmountProps) => import("react").JSX.Element;
49
+ export interface PriceEstimateSummaryProps {
50
+ control: PriceEstimateControl;
51
+ /** The amount the summary shows tax and a total for — may differ from the estimate's own reference amount. */
52
+ subtotalMinor: number;
53
+ currency: string;
54
+ /** Appended after the total row, e.g. `"/ month"`. */
55
+ suffix?: string;
56
+ className?: string;
57
+ }
58
+ /**
59
+ * A self-contained estimate: `CountrySelect` bound to the control's own `country`/`onCountryChange`,
60
+ * plus `PriceEstimateAmount` beneath it. What a single estimate (the credit dialog) wants; several
61
+ * estimates sharing one picker (a plan comparison table) compose the two pieces separately instead.
62
+ */
63
+ export declare const PriceEstimateSummary: ({ control, subtotalMinor, currency, suffix, className }: PriceEstimateSummaryProps) => import("react").JSX.Element;
64
+ //# sourceMappingURL=estimate-summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimate-summary.d.ts","sourceRoot":"","sources":["../src/estimate-summary.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAOzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAoBtD,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,+DAEvB,kBAAkB,gCAqBpB,CAAA;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC,CAAA;IACtE,oGAAoG;IACpG,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,4DAA6D,wBAAwB,gCA+CpH,CAAA;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,oBAAoB,CAAA;IAC7B,8GAA8G;IAC9G,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,4DAA6D,yBAAyB,gCAStH,CAAA"}
@@ -0,0 +1,94 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment, useMemo } from 'react';
3
+ import { useI18nLib, useLanguage } from '@owlmeans/client-i18n';
4
+ import { COUNTRY_CODES, TaxEstimateStatus, estimateOf } from '@owlmeans/payment';
5
+ import { cn } from '@/lib/utils';
6
+ import { Label } from '@/components/ui/label';
7
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
8
+ import { money } from './format.js';
9
+ const localMoney = (amount, currency, locale) => {
10
+ try {
11
+ return new Intl.NumberFormat(locale, { style: 'currency', currency: currency.toUpperCase() }).format(amount);
12
+ }
13
+ catch {
14
+ return `${amount.toFixed(2)} ${currency.toUpperCase()}`;
15
+ }
16
+ };
17
+ /** The country names a `<Select>` offers, in the viewer's own language and alphabetical order. */
18
+ const useCountryOptions = (locale) => useMemo(() => {
19
+ let names = null;
20
+ try {
21
+ names = new Intl.DisplayNames([locale], { type: 'region' });
22
+ }
23
+ catch {
24
+ names = null;
25
+ }
26
+ const collator = new Intl.Collator(locale);
27
+ return COUNTRY_CODES
28
+ .map(code => ({ code, name: names?.of(code) ?? code }))
29
+ .sort((a, b) => collator.compare(a.name, b.name));
30
+ }, [locale]);
31
+ /**
32
+ * The billing-country picker alone — the piece `PriceEstimateSummary` composes for a single,
33
+ * self-contained estimate, and what a shared picker (several estimates, one country — a plan
34
+ * comparison table) renders once and drives every `usePriceEstimate({ country, onCountryChange })`
35
+ * with. Country names are the viewer's own language, alphabetically ordered.
36
+ *
37
+ * `[data-country-select]` carries `data-locked` (`"true"` while disabled) and the chosen
38
+ * `data-country`; the note is `[data-country-note]`.
39
+ */
40
+ export const CountrySelect = ({ value, onChange, label, id = 'price-estimate-country', className, disabled = false, note, }) => {
41
+ const t = useI18nLib('web-payment', 'estimate');
42
+ const [locale] = useLanguage();
43
+ const countries = useCountryOptions(locale);
44
+ const text = label ?? t('country');
45
+ return _jsxs("div", { className: cn('grid gap-2', className), "data-country-select": "", "data-locked": disabled ? 'true' : 'false', "data-country": value, children: [_jsx(Label, { htmlFor: id, children: text }), _jsxs(Select, { value: value, onValueChange: next => { if (!disabled)
46
+ onChange(next); }, disabled: disabled, children: [_jsx(SelectTrigger, { id: id, "aria-label": text, "aria-describedby": note != null ? `${id}-note` : undefined, children: _jsx(SelectValue, { placeholder: t('country-placeholder') }) }), _jsx(SelectContent, { children: countries.map(({ code, name }) => _jsx(SelectItem, { value: code, children: name }, code)) })] }), note != null && _jsx("p", { id: `${id}-note`, className: "text-muted-foreground text-xs", "data-country-note": "", children: note })] });
47
+ };
48
+ /**
49
+ * What Stripe Tax says at the estimate's country, with NO country picker of its own: the rate(s),
50
+ * an estimated total, and one sentence for whichever status leaves no number to trust (reverse
51
+ * charge, no tax, "at checkout", "choose a country"). Several of these may share one
52
+ * `CountrySelect` (a plan comparison table).
53
+ *
54
+ * A country whose currency differs from `currency` (Adaptive Pricing found a rate) shows the tax
55
+ * and the total in THAT currency instead, marked `≈` throughout — never both currencies at once,
56
+ * which would read as two different prices for the same line. The rate percentage itself is
57
+ * currency-agnostic and always shows as Stripe stated it.
58
+ *
59
+ * `data-price-estimate` / `data-status` are stable test hooks.
60
+ */
61
+ export const PriceEstimateAmount = ({ control, subtotalMinor, currency, suffix, className }) => {
62
+ const t = useI18nLib('web-payment', 'estimate');
63
+ const [locale] = useLanguage();
64
+ const { estimate, loading, failed } = control;
65
+ const derived = estimate != null ? estimateOf(subtotalMinor, estimate) : null;
66
+ const status = estimate?.tax.status;
67
+ const numeric = status === TaxEstimateStatus.Taxed || status === TaxEstimateStatus.ReverseCharge
68
+ || status === TaxEstimateStatus.None;
69
+ const rateLabel = estimate != null && estimate.tax.rates.length > 0
70
+ ? estimate.tax.rates
71
+ .map(rate => t('rate', { type: t(`tax-type.${rate.type}`), percentage: rate.percentage }))
72
+ .join(' + ')
73
+ : null;
74
+ const local = derived?.local;
75
+ const taxText = local != null
76
+ ? (derived?.taxMinor != null ? localMoney(local.taxAmount, local.currency, locale) : null)
77
+ : (derived?.taxMinor != null ? money(derived.taxMinor, currency, locale) : null);
78
+ const totalText = local != null
79
+ ? (derived?.totalMinor != null ? localMoney(local.totalAmount, local.currency, locale) : null)
80
+ : (derived?.totalMinor != null ? money(derived.totalMinor, currency, locale) : null);
81
+ const approx = local != null ? '≈ ' : '';
82
+ return _jsxs("div", { "data-price-estimate": "", "data-status": status ?? 'pending', className: cn('grid gap-1.5', className), children: [estimate == null && loading && _jsx("p", { className: "text-muted-foreground text-xs", children: t('loading') }), estimate == null && !loading && failed && _jsx("p", { className: "text-destructive text-xs", children: t('failed') }), estimate != null && _jsxs(_Fragment, { children: [numeric && taxText != null && totalText != null && _jsxs("dl", { className: "grid grid-cols-[1fr_auto] gap-x-4 gap-y-1 text-sm", "data-estimate-rows": "", children: [status === TaxEstimateStatus.Taxed && rateLabel != null && _jsxs(Fragment, { children: [_jsx("dt", { className: "text-muted-foreground", "data-estimate-rate": "", children: rateLabel }), _jsxs("dd", { "data-estimate-tax": "", children: [approx, taxText] })] }), _jsx("dt", { className: "font-medium", children: t('total') }), _jsxs("dd", { className: "font-medium", "data-estimate-total": "", children: [approx, totalText, suffix != null ? ` ${suffix}` : ''] })] }), numeric && local != null && _jsx("p", { className: "text-muted-foreground text-xs", "data-estimate-converted": "", children: t('converted-note') }), _jsx("p", { className: "text-muted-foreground text-xs", "data-estimate-status": "", children: t(`status.${status}`) })] })] });
83
+ };
84
+ /**
85
+ * A self-contained estimate: `CountrySelect` bound to the control's own `country`/`onCountryChange`,
86
+ * plus `PriceEstimateAmount` beneath it. What a single estimate (the credit dialog) wants; several
87
+ * estimates sharing one picker (a plan comparison table) compose the two pieces separately instead.
88
+ */
89
+ export const PriceEstimateSummary = ({ control, subtotalMinor, currency, suffix, className }) => {
90
+ const t = useI18nLib('web-payment', 'estimate');
91
+ const { country, onCountryChange, locked = false } = control;
92
+ return _jsxs("div", { className: cn('grid gap-3', className), children: [_jsx(CountrySelect, { value: country, onChange: onCountryChange, disabled: locked, note: locked ? t('country-locked') : undefined }), _jsx(PriceEstimateAmount, { control: control, subtotalMinor: subtotalMinor, currency: currency, suffix: suffix })] });
93
+ };
94
+ //# sourceMappingURL=estimate-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimate-summary.js","sourceRoot":"","sources":["../src/estimate-summary.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { RegisteredEntrypoint } from '@owlmeans/entrypoint';
2
+ import type { PriceEstimate } from '@owlmeans/payment';
3
+ import type { PriceEstimateArguments, PriceEstimateControl, PriceEstimateRequest } from './types.js';
4
+ export interface UsePriceEstimateOptions {
5
+ /** Fetch (and refetch on a country change) only while `true` — a closed dialog costs nothing. */
6
+ enabled: boolean;
7
+ ttlMs?: number;
8
+ /**
9
+ * Controls the country from outside (several estimates sharing one picker — a plan comparison
10
+ * table). Given: the hook never owns `useState` for it, never preselects from `source:
11
+ * 'customer'` (the owner does, once, for whichever estimate answers first), and the returned
12
+ * control's `onCountryChange` calls this back instead of an internal setter. Absent (the
13
+ * default): the hook is self-contained, exactly as a standalone dialog needs.
14
+ */
15
+ country?: string;
16
+ onCountryChange?: (country: string) => void;
17
+ }
18
+ /**
19
+ * A live `PriceEstimate` for one protocol/request, with a country the caller may change.
20
+ *
21
+ * Fetches once `enabled` and again on every `onCountryChange`, from a client-side cache keyed by
22
+ * the entry's alias, the request body and the country — a TTL match answers instantly, an identical
23
+ * in-flight request is shared. Uncontrolled (no `opts.country`): the first answer whose `source` is
24
+ * `'customer'` preselects its `country`, once, so a returning buyer sees their own country without
25
+ * picking it. Controlled (`opts.country` given): the country and its preselection are the caller's.
26
+ *
27
+ * An answer for a LOCKED billing country (`locked`, or `source: 'profile'`) wins over any pick: the
28
+ * hook adopts its country (controlled: through `opts.onCountryChange`, once), returns `locked:
29
+ * true`, and ignores `onCountryChange` from then on — the picker renders disabled.
30
+ */
31
+ export declare const usePriceEstimate: <Request extends PriceEstimateRequest>(entry: RegisteredEntrypoint<Request, PriceEstimate>, opts: UsePriceEstimateOptions, ...request: PriceEstimateArguments<Request>) => PriceEstimateControl;
32
+ /** An answer computed for the entity's locked billing country, which no picker may change. */
33
+ export declare const isLockedAnswer: (estimate: PriceEstimate) => boolean;
34
+ //# sourceMappingURL=estimate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimate.d.ts","sourceRoot":"","sources":["../src/estimate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAOpG,MAAM,WAAW,uBAAuB;IACtC,iGAAiG;IACjG,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAC5C;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,SAAS,oBAAoB,SAC5D,oBAAoB,CAAC,OAAO,EAAE,aAAa,CAAC,QAAQ,uBAAuB,cACtE,sBAAsB,CAAC,OAAO,CAAC,KAC1C,oBAwEF,CAAA;AAED,8FAA8F;AAC9F,eAAO,MAAM,cAAc,aAAc,aAAa,KAAG,OACE,CAAA"}
@@ -0,0 +1,92 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { EstimateCache } from './estimate-cache.js';
3
+ const DEFAULT_TTL_MS = 5 * 60_000;
4
+ /** Shared across every mounted dialog/estimate card in the tab — the server already caches per TTL too. */
5
+ const cache = new EstimateCache();
6
+ /**
7
+ * A live `PriceEstimate` for one protocol/request, with a country the caller may change.
8
+ *
9
+ * Fetches once `enabled` and again on every `onCountryChange`, from a client-side cache keyed by
10
+ * the entry's alias, the request body and the country — a TTL match answers instantly, an identical
11
+ * in-flight request is shared. Uncontrolled (no `opts.country`): the first answer whose `source` is
12
+ * `'customer'` preselects its `country`, once, so a returning buyer sees their own country without
13
+ * picking it. Controlled (`opts.country` given): the country and its preselection are the caller's.
14
+ *
15
+ * An answer for a LOCKED billing country (`locked`, or `source: 'profile'`) wins over any pick: the
16
+ * hook adopts its country (controlled: through `opts.onCountryChange`, once), returns `locked:
17
+ * true`, and ignores `onCountryChange` from then on — the picker renders disabled.
18
+ */
19
+ export const usePriceEstimate = (entry, opts, ...request) => {
20
+ const entryRef = useRef(entry);
21
+ entryRef.current = entry;
22
+ const base = (request[0] ?? {});
23
+ const bodyKey = JSON.stringify(base.body ?? {});
24
+ const controlled = opts.country !== undefined;
25
+ const [internalCountry, setInternalCountry] = useState('');
26
+ const country = controlled ? opts.country : internalCountry;
27
+ const [estimate, setEstimate] = useState(null);
28
+ const [loading, setLoading] = useState(false);
29
+ const [failed, setFailed] = useState(false);
30
+ const preselectedRef = useRef(false);
31
+ const lockedRef = useRef(false);
32
+ const locked = estimate != null && isLockedAnswer(estimate);
33
+ lockedRef.current = locked;
34
+ const onCountryChangeRef = useRef(opts.onCountryChange);
35
+ onCountryChangeRef.current = opts.onCountryChange;
36
+ useEffect(() => {
37
+ if (!opts.enabled) {
38
+ return;
39
+ }
40
+ let active = true;
41
+ const key = `${entryRef.current.alias}:${bodyKey}:${country}`;
42
+ const ttlMs = opts.ttlMs ?? DEFAULT_TTL_MS;
43
+ setLoading(true);
44
+ setFailed(false);
45
+ cache.load(key, ttlMs, async () => await entryRef.current.call({
46
+ ...base, body: { ...(base.body ?? {}), ...(country !== '' ? { country } : {}) },
47
+ })).then(result => {
48
+ if (!active)
49
+ return;
50
+ setEstimate(result);
51
+ setLoading(false);
52
+ if (isLockedAnswer(result) && result.country != null && result.country !== country) {
53
+ // A locked billing country overrides whatever was picked: adopt it, once per country.
54
+ preselectedRef.current = true;
55
+ if (controlled) {
56
+ onCountryChangeRef.current?.(result.country);
57
+ }
58
+ else {
59
+ setInternalCountry(result.country);
60
+ }
61
+ return;
62
+ }
63
+ if (!controlled && !preselectedRef.current && country === '' && result.source === 'customer' && result.country != null) {
64
+ preselectedRef.current = true;
65
+ setInternalCountry(result.country);
66
+ }
67
+ }).catch(() => {
68
+ if (active) {
69
+ setFailed(true);
70
+ setLoading(false);
71
+ }
72
+ });
73
+ return () => { active = false; };
74
+ // eslint-disable-next-line react-hooks/exhaustive-deps
75
+ }, [opts.enabled, opts.ttlMs, bodyKey, country]);
76
+ const onCountryChange = useCallback((next) => {
77
+ if (lockedRef.current) {
78
+ return;
79
+ }
80
+ if (controlled) {
81
+ opts.onCountryChange?.(next);
82
+ return;
83
+ }
84
+ preselectedRef.current = true;
85
+ setInternalCountry(next);
86
+ // eslint-disable-next-line react-hooks/exhaustive-deps
87
+ }, [controlled, opts.onCountryChange]);
88
+ return { estimate, country, loading, failed, locked, onCountryChange };
89
+ };
90
+ /** An answer computed for the entity's locked billing country, which no picker may change. */
91
+ export const isLockedAnswer = (estimate) => estimate.locked === true || estimate.source === 'profile';
92
+ //# sourceMappingURL=estimate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimate.js","sourceRoot":"","sources":["../src/estimate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /** Minor units as a currency amount in a locale; an unknown locale or currency still reads. */
2
+ export declare const money: (minor: number, currency: string, locale: string) => string;
3
+ /** A calendar day in UTC (`dateStyle: 'long'`); `''` for no or an unparseable date. */
4
+ export declare const dayUtc: (date: Date | string | null | undefined, locale: string) => string;
5
+ /**
6
+ * The last day of a window whose deadline is EXCLUSIVE (the start of the next UTC day) — the day a
7
+ * consumer reads as "until". The rule is `@owlmeans/payment`'s `lastWithdrawalDayOf`, the one the
8
+ * server's e-mails and texts use, so the dialog and the mail never name different days.
9
+ */
10
+ export declare const lastDayUtc: (deadline: Date | string | null | undefined, locale: string) => string;
11
+ /** A date and time in UTC, to the second — the moment a declaration was received. */
12
+ export declare const momentUtc: (date: Date | string | null | undefined, locale: string) => string;
13
+ /** A date and time in UTC to the minute, with the zone named — when a limit rises again. */
14
+ export declare const shortMomentUtc: (date: Date | string | null | undefined, locale: string) => string;
15
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAEA,+FAA+F;AAC/F,eAAO,MAAM,KAAK,UAAW,MAAM,YAAY,MAAM,UAAU,MAAM,KAAG,MAQvE,CAAA;AAWD,uFAAuF;AACvF,eAAO,MAAM,MAAM,SAAU,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,UAAU,MAAM,KAAG,MAU/E,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,aAAc,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,UAAU,MAAM,KAAG,MAIvF,CAAA;AAED,qFAAqF;AACrF,eAAO,MAAM,SAAS,SAAU,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,UAAU,MAAM,KAAG,MAUlF,CAAA;AAED,4FAA4F;AAC5F,eAAO,MAAM,cAAc,SAAU,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,UAAU,MAAM,KAAG,MAUvF,CAAA"}
@@ -0,0 +1,68 @@
1
+ import { lastWithdrawalDayOf } from '@owlmeans/payment';
2
+ /** Minor units as a currency amount in a locale; an unknown locale or currency still reads. */
3
+ export const money = (minor, currency, locale) => {
4
+ try {
5
+ return new Intl.NumberFormat(locale, {
6
+ style: 'currency', currency: currency.toUpperCase(), minimumFractionDigits: 2,
7
+ }).format(minor / 100);
8
+ }
9
+ catch {
10
+ return `${(minor / 100).toFixed(2)} ${currency.toUpperCase()}`;
11
+ }
12
+ };
13
+ const dateOf = (date) => {
14
+ if (date == null) {
15
+ return null;
16
+ }
17
+ const value = date instanceof Date ? date : new Date(date);
18
+ return Number.isNaN(value.getTime()) ? null : value;
19
+ };
20
+ /** A calendar day in UTC (`dateStyle: 'long'`); `''` for no or an unparseable date. */
21
+ export const dayUtc = (date, locale) => {
22
+ const value = dateOf(date);
23
+ if (value == null) {
24
+ return '';
25
+ }
26
+ try {
27
+ return new Intl.DateTimeFormat(locale, { dateStyle: 'long', timeZone: 'UTC' }).format(value);
28
+ }
29
+ catch {
30
+ return value.toISOString().slice(0, 10);
31
+ }
32
+ };
33
+ /**
34
+ * The last day of a window whose deadline is EXCLUSIVE (the start of the next UTC day) — the day a
35
+ * consumer reads as "until". The rule is `@owlmeans/payment`'s `lastWithdrawalDayOf`, the one the
36
+ * server's e-mails and texts use, so the dialog and the mail never name different days.
37
+ */
38
+ export const lastDayUtc = (deadline, locale) => {
39
+ const value = dateOf(deadline);
40
+ return value == null ? '' : dayUtc(lastWithdrawalDayOf(value), locale);
41
+ };
42
+ /** A date and time in UTC, to the second — the moment a declaration was received. */
43
+ export const momentUtc = (date, locale) => {
44
+ const value = dateOf(date);
45
+ if (value == null) {
46
+ return '';
47
+ }
48
+ try {
49
+ return new Intl.DateTimeFormat(locale, { dateStyle: 'long', timeStyle: 'medium', timeZone: 'UTC' }).format(value);
50
+ }
51
+ catch {
52
+ return value.toISOString().replace('T', ' ').slice(0, 19);
53
+ }
54
+ };
55
+ /** A date and time in UTC to the minute, with the zone named — when a limit rises again. */
56
+ export const shortMomentUtc = (date, locale) => {
57
+ const value = dateOf(date);
58
+ if (value == null) {
59
+ return '';
60
+ }
61
+ try {
62
+ return `${new Intl.DateTimeFormat(locale, { dateStyle: 'medium', timeStyle: 'short', timeZone: 'UTC' }).format(value)} UTC`;
63
+ }
64
+ catch {
65
+ return `${value.toISOString().replace('T', ' ').slice(0, 16)} UTC`;
66
+ }
67
+ };
68
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
package/build/hooks.d.ts CHANGED
@@ -6,8 +6,4 @@ export declare const useCheckout: (target?: CheckoutTarget) => {
6
6
  pending: boolean;
7
7
  };
8
8
  export declare const usePaymentBalance: <T>(entry: RegisteredEntrypoint<{}, T>, intervalMs?: number, deps?: unknown[]) => T | null;
9
- export declare const useEntitlements: <T extends {
10
- entitlements?: string[];
11
- }>(entry: RegisteredEntrypoint<{}, T>, intervalMs?: number, deps?: unknown[]) => string[] | null;
12
- export declare const useEntitlement: (list: string[] | null, param: string) => boolean;
13
9
  //# sourceMappingURL=hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAE7F,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,eAAO,MAAM,WAAW,YAAY,cAAc;eAEZ,OAAO,SAAS,YAAY,SACvD,oBAAoB,CAAC,OAAO,EAAE,cAAc,CAAC,cAAc,aAAa,CAAC,OAAO,CAAC,KACvF,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;;CASlC,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAC1B,oBAAoB,CAAC,EAAE,EAAE,CAAC,CAAC,eAAc,MAAM,SAAiB,OAAO,EAAE,KAC/E,CAAC,GAAG,IAkBN,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS;IAAE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,SAC5D,oBAAoB,CAAC,EAAE,EAAE,CAAC,CAAC,eAAc,MAAM,SAAiB,OAAO,EAAE,KAC/E,MAAM,EAAE,GAAG,IAAwE,CAAA;AAEtF,eAAO,MAAM,cAAc,SAAU,MAAM,EAAE,GAAG,IAAI,SAAS,MAAM,KAAG,OAQrE,CAAA"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAE7F,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,eAAO,MAAM,WAAW,YAAY,cAAc;eAEZ,OAAO,SAAS,YAAY,SACvD,oBAAoB,CAAC,OAAO,EAAE,cAAc,CAAC,cAAc,aAAa,CAAC,OAAO,CAAC,KACvF,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;;CASlC,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAC1B,oBAAoB,CAAC,EAAE,EAAE,CAAC,CAAC,eAAc,MAAM,SAAiB,OAAO,EAAE,KAC/E,CAAC,GAAG,IAAuD,CAAA"}
package/build/hooks.js CHANGED
@@ -1,5 +1,5 @@
1
- import { useCallback, useEffect, useRef, useState } from 'react';
2
- import { hasEntitlement } from '@owlmeans/payment';
1
+ import { useCallback, useState } from 'react';
2
+ import { usePolled } from './poll.js';
3
3
  import { openCheckout } from './service.js';
4
4
  export const useCheckout = (target = '_self') => {
5
5
  const [pending, setPending] = useState(false);
@@ -17,32 +17,5 @@ export const useCheckout = (target = '_self') => {
17
17
  }, [target]);
18
18
  return { checkout, pending };
19
19
  };
20
- export const usePaymentBalance = (entry, intervalMs = 60_000, deps = []) => {
21
- const [balance, setBalance] = useState(null);
22
- const entryRef = useRef(entry);
23
- entryRef.current = entry;
24
- useEffect(() => {
25
- let active = true;
26
- const load = async () => {
27
- try {
28
- const value = await entryRef.current.call();
29
- if (active)
30
- setBalance(value);
31
- }
32
- catch { /* explicit actions own their errors */ }
33
- };
34
- void load();
35
- const ticker = setInterval(load, intervalMs);
36
- return () => { active = false; clearInterval(ticker); };
37
- // eslint-disable-next-line react-hooks/exhaustive-deps
38
- }, [intervalMs, ...deps]);
39
- return balance;
40
- };
41
- export const useEntitlements = (entry, intervalMs = 60_000, deps = []) => usePaymentBalance(entry, intervalMs, deps)?.entitlements ?? null;
42
- export const useEntitlement = (list, param) => list != null && hasEntitlement(list.map(item => {
43
- const colon = item.indexOf(':');
44
- return colon >= 0
45
- ? { scope: item.slice(0, colon), permissions: { [item.slice(colon + 1)]: true } }
46
- : { scope: '', permissions: { [item]: true } };
47
- }), param);
20
+ export const usePaymentBalance = (entry, intervalMs = 60_000, deps = []) => usePolled(() => entry.call(), intervalMs, deps);
48
21
  //# sourceMappingURL=hooks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,YAAY,EAAuB,MAAM,cAAc,CAAA;AAGhE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,GAAmB,OAAO,EAAE,EAAE;IAC9D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,EAChC,KAAoD,EAAE,GAAG,OAA+B,EACxD,EAAE;QAClC,UAAU,CAAC,IAAI,CAAC,CAAA;QAChB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAA;YAC3C,IAAI,MAAM,EAAE,GAAG,IAAI,IAAI;gBAAE,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;YACzD,OAAO,MAAM,IAAI,IAAI,CAAA;QACvB,CAAC;gBAAS,CAAC;YAAC,UAAU,CAAC,KAAK,CAAC,CAAA;QAAC,CAAC;IACjC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IACZ,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;AAC9B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,KAAkC,EAAE,UAAU,GAAW,MAAM,EAAE,IAAI,GAAc,EAAE,EAC3E,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,CAAA"}
@@ -1 +1 @@
1
- { "amount-checkout": { "title": "Папоўніць крэдыты", "description": "Выберыце чысты кошт крэдытаў для арганізацыі.", "presets": "Гатовыя сумы", "custom": "Свая сума", "invalid": "Увядзіце карэктную суму, не больш за два знакі пасля коскі.", "below": "Мінімальная сума — {{amount}}.", "above": "Максімальная сума — {{amount}}.", "bounds": "Выберыце суму ад {{minimum}} да {{maximum}}.", "credits": "Кошт крэдытаў", "adjustment": "Карэкціроўка апрацоўкі", "subtotal": "Сума да падатку", "tax-note": "Stripe разлічыць падатак падчас аплаты.", "cancel": "Скасаваць", "continue": "Перайсці ў Stripe", "pending": "Адкрываем аплату…", "close": "Закрыць" } }
1
+ { "amount-checkout": { "title": "Папоўніць крэдыты", "description": "Выберыце чысты кошт крэдытаў для арганізацыі.", "presets": "Гатовыя сумы", "custom": "Свая сума", "invalid": "Увядзіце карэктную суму, не больш за два знакі пасля коскі.", "below": "Мінімальная сума — {{amount}}.", "above": "Максімальная сума — {{amount}}.", "bounds": "Выберыце суму ад {{minimum}} да {{maximum}}.", "credits": "Кошт крэдытаў", "adjustment": "Карэкціроўка апрацоўкі", "subtotal": "Сума да падатку", "tax-note": "Stripe разлічыць падатак падчас аплаты.", "cancel": "Скасаваць", "continue": "Перайсці ў Stripe", "pending": "Адкрываем аплату…", "close": "Закрыць", "above-limit": "Зараз можна дадаць не больш за {{amount}}." }, "entitlement": { "plan": { "current": "Бягучы план" }, "status": { "trial": "Пробны перыяд", "trial-on": "Пробны перыяд да {{date}}", "past-due": "Плацёж пратэрмінаваны", "cancel-scheduled": "Адмена запланавана", "cancel-scheduled-on": "Адмяняецца {{date}}", "paused": "На паўзе", "paused-on": "На паўзе з {{date}}", "suspended": "Прыпынены", "free": "Бясплатны план", "renews-on": "Падаўжаецца {{date}}", "active": "Актыўны", "created": "Чакае актывацыі", "canceled": "Адменены", "expired": "Тэрмін скончыўся", "ended": "Завершаны", "blocked": "Заблакаваны" }, "limit": { "usage": "{{used}} з {{limit}}", "usage-unit": "{{used}} з {{limit}} {{unit}}", "not-included": "Не ўваходзіць у план", "exhausted": "Ліміт вычарпаны", "resets-on": "Абновіцца {{date}}" }, "promo": { "free-until": "Бясплатна да {{date}}", "grandfathered": "Захавана для вашага плана", "ended": "Акцыя завершана" }, "capability": { "included": "Уваходзіць у план", "not-included": "Не ўваходзіць у план" } }, "estimate": { "country": "Краіна плацельшчыка", "country-placeholder": "Выберыце краіну", "tax-type": { "vat": "ПДВ", "gst": "GST", "sales-tax": "Падатак з продажаў", "tax": "Падатак" }, "rate": "{{type}} ({{percentage}}%)", "total": "Прыблізная сума", "converted-note": "Пералічана па бягучым курсе Stripe; дакладная сума і магчымая камісія за канвертацыю будуць пацверджаны падчас аплаты.", "status": { "taxed": "Падатак ужо ўключаны ў прыблізную суму ніжэй.", "reverse-charge": "Адваротнае налічэнне — пры ўказаным нумары ПДВ вы ўлічваеце падатак самастойна, таму мы нічога не дадаём.", "none": "Для гэтай краіны падатак не прымяняецца.", "at-checkout": "Дакладны падатак будзе разлічаны падчас аплаты.", "location-required": "Выберыце краіну плацельшчыка, каб убачыць разлік." }, "loading": "Правяраем падатак…", "failed": "Зараз не ўдалося праверыць падатак.", "country-locked": "Краіна плацельшчыка ўстаноўлена пры першай пакупцы, змяніць яе тут нельга." }, "checkout-limit": { "note": "Зараз можна дадаць да {{amount}}.", "blocked": "Зараз дадаць крэдыты нельга.", "resets": "Больш стане даступна {{date}}.", "reason": { "per-purchase": "Разавыя папаўненні для вашай арганізацыі пакуль абмежаваныя; ліміт расце па меры выкарыстання крэдытаў.", "window": "Нядаўнія папаўненні ўлічваюцца ў ліміце за апошнія некалькі дзён.", "hold": "Папаўненні для вашай арганізацыі прыпыненыя. Звярніцеся ў падтрымку.", "other": "Для вашай арганізацыі дзейнічае ліміт папаўненняў." } }, "consumer": { "show-in": "Паказаць на мове: {{language}}", "purchases": "Пакупкі ў перыядзе адмовы", "continue": "Далей", "back": "Назад", "close": "Закрыць", "print": "Надрукаваць або захаваць", "pending": "Адпраўка…", "required": "Запоўніце гэта поле.", "email-invalid": "Увядзіце карэктны адрас электроннай пошты.", "date-invalid": "Выберыце дату не раней за сённяшнюю.", "failed": "Не атрымалася. Паспрабуйце яшчэ раз.", "review": "Праверце даныя", "receipt": "Пацвярджэнне атрымання", "received-at": "Дата атрымання", "reference": "Нумар звароту", "status": "Статус", "not-mailed": "Захавайце гэту старонку: ліст з пацвярджэннем яшчэ не адпраўлены.", "website": "Вэб-сайт" }, "withdrawal": { "none": "Зараз няма дагавораў, ад якіх можна адмовіцца.", "purchased": "Куплена {{date}}", "paid": "Аплачана {{amount}}", "until": "Адмовіцца можна да канца дня {{date}} уключна", "estimate": "Арыентыровачная сума вяртання: {{amount}}", "estimate-unknown": "Сума вяртання будзе разлічана пры апрацоўцы адмовы.", "refund": "Вяртанне", "subscription-canceled": "Падпіска спынена.", "kind": { "top-up": "Крэдыты", "subscription": "Падпіска" }, "status": { "received": "Атрымана", "processing": "Апрацоўваецца", "refunded": "Вернута", "review": "На праверцы", "failed": "Вяртанне затрымліваецца — паўтараем спробу", "expired": "Атрымана пасля заканчэння тэрміну адмовы" } }, "cancellation": { "effective-at": "Ваш дагавор заканчваецца {{date}}.", "status": { "received": "Атрымана", "scheduled": "Растаргненне запланавана", "already-scheduled": "Растаргненне ўжо запланавана", "review": "Атрымана — мы разгледзім яго і пацвердзім па электроннай пошце" } } }
@@ -1 +1 @@
1
- { "amount-checkout": { "title": "Guthaben aufladen", "description": "Wähle den Nettowert des Guthabens für deine Organisation.", "presets": "Vorgegebene Beträge", "custom": "Eigener Betrag", "invalid": "Gib einen gültigen Betrag mit höchstens zwei Dezimalstellen ein.", "below": "Der Mindestbetrag ist {{amount}}.", "above": "Der Höchstbetrag ist {{amount}}.", "bounds": "Wähle zwischen {{minimum}} und {{maximum}}.", "credits": "Guthabenwert", "adjustment": "Verarbeitungsaufschlag", "subtotal": "Zwischensumme vor Steuern", "tax-note": "Stripe berechnet anwendbare Steuern beim Bezahlen.", "cancel": "Abbrechen", "continue": "Weiter zu Stripe", "pending": "Zahlung wird geöffnet…", "close": "Schließen" } }
1
+ { "amount-checkout": { "title": "Guthaben aufladen", "description": "Wähle den Nettowert des Guthabens für deine Organisation.", "presets": "Vorgegebene Beträge", "custom": "Eigener Betrag", "invalid": "Gib einen gültigen Betrag mit höchstens zwei Dezimalstellen ein.", "below": "Der Mindestbetrag ist {{amount}}.", "above": "Der Höchstbetrag ist {{amount}}.", "bounds": "Wähle zwischen {{minimum}} und {{maximum}}.", "credits": "Guthabenwert", "adjustment": "Verarbeitungsaufschlag", "subtotal": "Zwischensumme vor Steuern", "tax-note": "Stripe berechnet anwendbare Steuern beim Bezahlen.", "cancel": "Abbrechen", "continue": "Weiter zu Stripe", "pending": "Zahlung wird geöffnet…", "close": "Schließen", "above-limit": "Du kannst gerade höchstens {{amount}} aufladen." }, "entitlement": { "plan": { "current": "Aktueller Tarif" }, "status": { "trial": "Testphase", "trial-on": "Testphase endet am {{date}}", "past-due": "Zahlung überfällig", "cancel-scheduled": "Kündigung vorgemerkt", "cancel-scheduled-on": "Endet am {{date}}", "paused": "Pausiert", "paused-on": "Pausiert seit {{date}}", "suspended": "Ausgesetzt", "free": "Kostenloser Tarif", "renews-on": "Verlängert sich am {{date}}", "active": "Aktiv", "created": "Wartet auf Aktivierung", "canceled": "Gekündigt", "expired": "Abgelaufen", "ended": "Beendet", "blocked": "Gesperrt" }, "limit": { "usage": "{{used}} von {{limit}}", "usage-unit": "{{used}} von {{limit}} {{unit}}", "not-included": "Nicht enthalten", "exhausted": "Limit erreicht", "resets-on": "Wird am {{date}} zurückgesetzt" }, "promo": { "free-until": "Kostenlos bis {{date}}", "grandfathered": "In deinem Tarif enthalten", "ended": "Aktion beendet" }, "capability": { "included": "Enthalten", "not-included": "Nicht enthalten" } }, "estimate": { "country": "Rechnungsland", "country-placeholder": "Land wählen", "tax-type": { "vat": "USt.", "gst": "GST", "sales-tax": "Umsatzsteuer", "tax": "Steuer" }, "rate": "{{type}} ({{percentage}}%)", "total": "Geschätzter Gesamtbetrag", "converted-note": "Umgerechnet zum aktuellen Stripe-Wechselkurs; der genaue Betrag und eine mögliche Umrechnungsgebühr werden beim Bezahlen bestätigt.", "status": { "taxed": "Die Steuer ist bereits im geschätzten Gesamtbetrag unten enthalten.", "reverse-charge": "Reverse-Charge-Verfahren — mit deiner USt-IdNr. rechnest du diese Steuer selbst ab, daher berechnen wir nichts.", "none": "Für dieses Land fällt keine Steuer an.", "at-checkout": "Die genaue Steuer wird beim Bezahlen berechnet.", "location-required": "Wähle dein Rechnungsland, um eine Schätzung zu sehen." }, "loading": "Steuer wird geprüft…", "failed": "Die Steuer konnte gerade nicht geprüft werden.", "country-locked": "Dein Rechnungsland wurde mit deinem ersten Kauf festgelegt und kann hier nicht geändert werden." }, "checkout-limit": { "note": "Du kannst gerade bis zu {{amount}} aufladen.", "blocked": "Du kannst gerade kein Guthaben aufladen.", "resets": "Mehr ist ab {{date}} verfügbar.", "reason": { "per-purchase": "Einzelne Aufladungen deiner Organisation sind vorerst begrenzt; die Grenze steigt, wenn du dein Guthaben nutzt.", "window": "Deine letzten Aufladungen zählen zu einer Grenze über die letzten Tage.", "hold": "Aufladungen sind für deine Organisation pausiert. Bitte wende dich an den Support.", "other": "Für deine Organisation gilt eine Aufladegrenze." } }, "consumer": { "show-in": "Auf {{language}} anzeigen", "purchases": "Käufe innerhalb der Widerrufsfrist", "continue": "Weiter", "back": "Zurück", "close": "Schließen", "print": "Drucken oder speichern", "pending": "Wird gesendet…", "required": "Bitte füllen Sie dieses Feld aus.", "email-invalid": "Geben Sie eine gültige E-Mail-Adresse ein.", "date-invalid": "Wählen Sie ein Datum ab heute.", "failed": "Das hat nicht geklappt. Bitte versuchen Sie es noch einmal.", "review": "Prüfen Sie Ihre Angaben", "receipt": "Eingangsbestätigung", "received-at": "Eingegangen am", "reference": "Referenz", "status": "Status", "not-mailed": "Bitte bewahren Sie diese Seite auf: Die Bestätigungs-E-Mail wurde noch nicht versandt.", "website": "Webseite" }, "withdrawal": { "none": "Derzeit kann kein Vertrag widerrufen werden.", "purchased": "Gekauft am {{date}}", "paid": "Bezahlt: {{amount}}", "until": "Widerruf möglich bis einschließlich {{date}}", "estimate": "Voraussichtliche Erstattung: {{amount}}", "estimate-unknown": "Die Erstattung wird bei der Bearbeitung Ihres Widerrufs berechnet.", "refund": "Erstattung", "subscription-canceled": "Das Abonnement wurde beendet.", "kind": { "top-up": "Guthaben", "subscription": "Abonnement" }, "status": { "received": "Eingegangen", "processing": "In Bearbeitung", "refunded": "Erstattet", "review": "In Prüfung", "failed": "Erstattung verzögert — wir versuchen es erneut", "expired": "Nach Ablauf der Widerrufsfrist eingegangen" } }, "cancellation": { "effective-at": "Ihr Vertrag endet am {{date}}.", "status": { "received": "Eingegangen", "scheduled": "Kündigung vorgemerkt", "already-scheduled": "Kündigung war bereits vorgemerkt", "review": "Eingegangen — wir prüfen sie und bestätigen sie per E-Mail" } } }
@@ -1 +1 @@
1
- { "amount-checkout": { "title": "Add credits", "description": "Choose the net credit value to add to your organization.", "presets": "Preset amounts", "custom": "Custom amount", "invalid": "Enter a valid amount with no more than two decimal places.", "below": "The minimum amount is {{amount}}.", "above": "The maximum amount is {{amount}}.", "bounds": "Choose between {{minimum}} and {{maximum}}.", "credits": "Credit value", "adjustment": "Processing adjustment", "subtotal": "Pre-tax subtotal", "tax-note": "Stripe calculates any applicable tax at checkout.", "cancel": "Cancel", "continue": "Continue to Stripe", "pending": "Opening checkout…", "close": "Close" } }
1
+ { "amount-checkout": { "title": "Add credits", "description": "Choose the net credit value to add to your organization.", "presets": "Preset amounts", "custom": "Custom amount", "invalid": "Enter a valid amount with no more than two decimal places.", "below": "The minimum amount is {{amount}}.", "above": "The maximum amount is {{amount}}.", "bounds": "Choose between {{minimum}} and {{maximum}}.", "credits": "Credit value", "adjustment": "Processing adjustment", "subtotal": "Pre-tax subtotal", "tax-note": "Stripe calculates any applicable tax at checkout.", "cancel": "Cancel", "continue": "Continue to Stripe", "pending": "Opening checkout…", "close": "Close", "above-limit": "The most you can add right now is {{amount}}." }, "entitlement": { "plan": { "current": "Current plan" }, "status": { "trial": "Trial", "trial-on": "Trial ends on {{date}}", "past-due": "Payment past due", "cancel-scheduled": "Cancellation scheduled", "cancel-scheduled-on": "Cancels on {{date}}", "paused": "Paused", "paused-on": "Paused since {{date}}", "suspended": "Suspended", "free": "Free plan", "renews-on": "Renews on {{date}}", "active": "Active", "created": "Awaiting activation", "canceled": "Canceled", "expired": "Expired", "ended": "Ended", "blocked": "Blocked" }, "limit": { "usage": "{{used}} of {{limit}}", "usage-unit": "{{used}} of {{limit}} {{unit}}", "not-included": "Not included", "exhausted": "Limit reached", "resets-on": "Resets on {{date}}" }, "promo": { "free-until": "Free until {{date}}", "grandfathered": "Included for your plan", "ended": "Promotion ended" }, "capability": { "included": "Included", "not-included": "Not included" } }, "estimate": { "country": "Billing country", "country-placeholder": "Choose a country", "tax-type": { "vat": "VAT", "gst": "GST", "sales-tax": "Sales tax", "tax": "Tax" }, "rate": "{{type}} ({{percentage}}%)", "total": "Estimated total", "converted-note": "Converted at Stripe's current exchange rate; the exact amount and any conversion fee are confirmed at checkout.", "status": { "taxed": "Tax is included in the estimated total below.", "reverse-charge": "Reverse charge — your VAT ID means you account for this tax yourself, so nothing is added.", "none": "No tax applies for this country.", "at-checkout": "The exact tax is calculated at checkout.", "location-required": "Choose your billing country to see an estimate." }, "loading": "Checking tax…", "failed": "Tax could not be checked right now.", "country-locked": "Your billing country was set by your first purchase and cannot be changed here." }, "checkout-limit": { "note": "You can add up to {{amount}} right now.", "blocked": "You cannot add credits right now.", "resets": "More becomes available on {{date}}.", "reason": { "per-purchase": "Single top-ups are limited for your organization for now; the limit grows as you use your credits.", "window": "Your recent top-ups count toward a limit over the last few days.", "hold": "Top-ups are paused for your organization. Please contact support.", "other": "A top-up limit applies to your organization." } }, "consumer": { "show-in": "Show in {{language}}", "purchases": "Purchases within their withdrawal period", "continue": "Continue", "back": "Back", "close": "Close", "print": "Print or save", "pending": "Sending…", "required": "Please fill in this field.", "email-invalid": "Enter a valid e-mail address.", "date-invalid": "Choose a date from today on.", "failed": "That did not go through. Please try again.", "review": "Check your details", "receipt": "Acknowledgement of receipt", "received-at": "Received on", "reference": "Reference", "status": "Status", "not-mailed": "Please keep this page: the confirmation e-mail has not been sent yet.", "website": "Website" }, "withdrawal": { "none": "No contract can be withdrawn from right now.", "purchased": "Bought on {{date}}", "paid": "Paid {{amount}}", "until": "Withdraw until the end of {{date}}", "estimate": "Estimated refund: {{amount}}", "estimate-unknown": "The refund is calculated when your withdrawal is processed.", "refund": "Refund", "subscription-canceled": "The subscription has been ended.", "kind": { "top-up": "Credits", "subscription": "Subscription" }, "status": { "received": "Received", "processing": "Being processed", "refunded": "Refunded", "review": "Being reviewed", "failed": "Refund delayed — we are retrying it", "expired": "Received after the withdrawal period" } }, "cancellation": { "effective-at": "Your contract ends on {{date}}.", "status": { "received": "Received", "scheduled": "Termination scheduled", "already-scheduled": "Termination already scheduled", "review": "Received — we will review it and confirm by e-mail" } } }
@@ -1 +1 @@
1
- { "amount-checkout": { "title": "Añadir créditos", "description": "Elige el valor neto de créditos para tu organización.", "presets": "Importes predefinidos", "custom": "Importe personalizado", "invalid": "Introduce un importe válido con un máximo de dos decimales.", "below": "El importe mínimo es {{amount}}.", "above": "El importe máximo es {{amount}}.", "bounds": "Elige entre {{minimum}} y {{maximum}}.", "credits": "Valor de los créditos", "adjustment": "Ajuste de procesamiento", "subtotal": "Subtotal antes de impuestos", "tax-note": "Stripe calcula los impuestos aplicables al pagar.", "cancel": "Cancelar", "continue": "Continuar a Stripe", "pending": "Abriendo el pago…", "close": "Cerrar" } }
1
+ { "amount-checkout": { "title": "Añadir créditos", "description": "Elige el valor neto de créditos para tu organización.", "presets": "Importes predefinidos", "custom": "Importe personalizado", "invalid": "Introduce un importe válido con un máximo de dos decimales.", "below": "El importe mínimo es {{amount}}.", "above": "El importe máximo es {{amount}}.", "bounds": "Elige entre {{minimum}} y {{maximum}}.", "credits": "Valor de los créditos", "adjustment": "Ajuste de procesamiento", "subtotal": "Subtotal antes de impuestos", "tax-note": "Stripe calcula los impuestos aplicables al pagar.", "cancel": "Cancelar", "continue": "Continuar a Stripe", "pending": "Abriendo el pago…", "close": "Cerrar", "above-limit": "Lo máximo que puedes añadir ahora es {{amount}}." }, "entitlement": { "plan": { "current": "Plan actual" }, "status": { "trial": "Prueba", "trial-on": "La prueba termina el {{date}}", "past-due": "Pago vencido", "cancel-scheduled": "Cancelación programada", "cancel-scheduled-on": "Se cancela el {{date}}", "paused": "En pausa", "paused-on": "En pausa desde el {{date}}", "suspended": "Suspendido", "free": "Plan gratuito", "renews-on": "Se renueva el {{date}}", "active": "Activo", "created": "Pendiente de activación", "canceled": "Cancelado", "expired": "Vencido", "ended": "Finalizado", "blocked": "Bloqueado" }, "limit": { "usage": "{{used}} de {{limit}}", "usage-unit": "{{used}} de {{limit}} {{unit}}", "not-included": "No incluido", "exhausted": "Límite alcanzado", "resets-on": "Se restablece el {{date}}" }, "promo": { "free-until": "Gratis hasta el {{date}}", "grandfathered": "Incluido en tu plan", "ended": "Promoción finalizada" }, "capability": { "included": "Incluido", "not-included": "No incluido" } }, "estimate": { "country": "País de facturación", "country-placeholder": "Elige un país", "tax-type": { "vat": "IVA", "gst": "GST", "sales-tax": "Impuesto sobre ventas", "tax": "Impuesto" }, "rate": "{{type}} ({{percentage}}%)", "total": "Total estimado", "converted-note": "Convertido al tipo de cambio actual de Stripe; el importe exacto y cualquier comisión de conversión se confirman al pagar.", "status": { "taxed": "El impuesto ya está incluido en el total estimado de abajo.", "reverse-charge": "Inversión del sujeto pasivo — con tu NIF-IVA, tú mismo declaras este impuesto, así que no añadimos nada.", "none": "No se aplica ningún impuesto para este país.", "at-checkout": "El impuesto exacto se calcula al pagar.", "location-required": "Elige tu país de facturación para ver una estimación." }, "loading": "Comprobando el impuesto…", "failed": "No se ha podido comprobar el impuesto ahora.", "country-locked": "Tu país de facturación se fijó con tu primera compra y no se puede cambiar aquí." }, "checkout-limit": { "note": "Ahora puedes añadir hasta {{amount}}.", "blocked": "Ahora no puedes añadir créditos.", "resets": "Habrá más disponible el {{date}}.", "reason": { "per-purchase": "Las recargas individuales de tu organización están limitadas por ahora; el límite crece a medida que usas tus créditos.", "window": "Tus recargas recientes cuentan para un límite de los últimos días.", "hold": "Las recargas de tu organización están en pausa. Contacta con soporte.", "other": "Tu organización tiene un límite de recargas." } }, "consumer": { "show-in": "Mostrar en {{language}}", "purchases": "Compras dentro de su plazo de desistimiento", "continue": "Continuar", "back": "Atrás", "close": "Cerrar", "print": "Imprimir o guardar", "pending": "Enviando…", "required": "Rellene este campo.", "email-invalid": "Introduzca una dirección de correo electrónico válida.", "date-invalid": "Elija una fecha a partir de hoy.", "failed": "No se ha podido completar. Inténtelo de nuevo.", "review": "Revise sus datos", "receipt": "Acuse de recibo", "received-at": "Fecha de recepción", "reference": "Referencia", "status": "Estado", "not-mailed": "Guarde esta página: el correo de confirmación aún no se ha enviado.", "website": "Sitio web" }, "withdrawal": { "none": "Ahora no hay ningún contrato del que pueda desistir.", "purchased": "Comprado el {{date}}", "paid": "Pagado: {{amount}}", "until": "Desistimiento posible hasta el final del día {{date}}", "estimate": "Reembolso estimado: {{amount}}", "estimate-unknown": "El reembolso se calcula al tramitar su desistimiento.", "refund": "Reembolso", "subscription-canceled": "La suscripción ha finalizado.", "kind": { "top-up": "Créditos", "subscription": "Suscripción" }, "status": { "received": "Recibido", "processing": "En tramitación", "refunded": "Reembolsado", "review": "En revisión", "failed": "Reembolso retrasado: lo estamos reintentando", "expired": "Recibido tras el plazo de desistimiento" } }, "cancellation": { "effective-at": "Su contrato termina el {{date}}.", "status": { "received": "Recibida", "scheduled": "Baja programada", "already-scheduled": "La baja ya estaba programada", "review": "Recibida — la revisaremos y la confirmaremos por correo electrónico" } } }