@vtex/faststore 0.0.5 → 0.0.6
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.
- package/CHANGELOG.md +45 -0
- package/dist/actions.json +181 -0
- package/dist/catalog.json +1543 -495
- package/dist/client.d.ts +2 -1
- package/dist/client.js +2 -1
- package/dist/components.d.ts +28 -7
- package/dist/components.js +31 -12
- package/dist/docs/access-code-sign-in.md +1 -1
- package/dist/docs/address-summary.md +24 -3
- package/dist/docs/alert-dialog.md +204 -0
- package/dist/docs/billing-address.md +284 -0
- package/dist/docs/card-entry.md +250 -0
- package/dist/docs/cardholder-document.md +142 -0
- package/dist/docs/client-preferences-fieldset.md +148 -0
- package/dist/docs/client-preferences.md +2 -1
- package/dist/docs/client-profile-fieldset.md +184 -0
- package/dist/docs/client-profile.md +1 -1
- package/dist/docs/document-field.md +58 -4
- package/dist/docs/field.md +317 -0
- package/dist/docs/form.md +307 -0
- package/dist/docs/identity-edit.md +6 -6
- package/dist/docs/identity-summary.md +5 -5
- package/dist/docs/installments.md +248 -0
- package/dist/docs/my-account-profile.md +1 -0
- package/dist/docs/order-placed-payment-summary.md +138 -0
- package/dist/docs/payment-method-badges.md +232 -0
- package/dist/docs/payment-methods.md +1 -0
- package/dist/docs/payment.md +218 -0
- package/dist/docs/phone-field.md +58 -4
- package/dist/docs/place-order.md +157 -0
- package/dist/docs/save-card.md +186 -0
- package/dist/docs/saved-cards.md +218 -0
- package/dist/docs/select.md +465 -0
- package/dist/docs/shipping-address.md +110 -258
- package/dist/index.d.ts +4 -1
- package/dist/internal/client.d.ts +3 -1
- package/dist/internal/client.js +3 -1
- package/dist/matter/access-code-sign-in/access-code-sign-in.js +9 -8
- package/dist/matter/access-code-sign-in/access-code-sign-in.js.map +1 -1
- package/dist/matter/billing-address/billing-address.d.ts +165 -0
- package/dist/matter/billing-address/billing-address.js +408 -0
- package/dist/matter/billing-address/billing-address.js.map +1 -0
- package/dist/matter/card-entry/card-capture.d.ts +25 -0
- package/dist/matter/card-entry/card-capture.js +25 -0
- package/dist/matter/card-entry/card-capture.js.map +1 -0
- package/dist/matter/card-entry/card-entry.d.ts +120 -0
- package/dist/matter/card-entry/card-entry.js +832 -0
- package/dist/matter/card-entry/card-entry.js.map +1 -0
- package/dist/matter/cardholder-document/cardholder-document.d.ts +45 -0
- package/dist/matter/cardholder-document/cardholder-document.js +70 -0
- package/dist/matter/cardholder-document/cardholder-document.js.map +1 -0
- package/dist/matter/client-preferences/client-preferences-fieldset.d.ts +77 -0
- package/dist/matter/client-preferences/client-preferences-fieldset.js +299 -0
- package/dist/matter/client-preferences/client-preferences-fieldset.js.map +1 -0
- package/dist/matter/client-preferences/client-preferences.d.ts +3 -5
- package/dist/matter/client-preferences/client-preferences.js +6 -6
- package/dist/matter/client-preferences/client-preferences.js.map +1 -1
- package/dist/matter/client-profile/client-profile.d.ts +4 -6
- package/dist/matter/client-profile/client-profile.js +9 -6
- package/dist/matter/client-profile/client-profile.js.map +1 -1
- package/dist/matter/client-profile-form/client-profile-fieldset.d.ts +119 -0
- package/dist/matter/client-profile-form/client-profile-fieldset.js +488 -0
- package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -0
- package/dist/matter/identity-edit/identity-edit.js +2 -2
- package/dist/matter/identity-edit/identity-edit.js.map +1 -1
- package/dist/matter/identity-summary/identity-summary.js +2 -2
- package/dist/matter/identity-summary/identity-summary.js.map +1 -1
- package/dist/matter/installments/installments-select.d.ts +42 -0
- package/dist/matter/installments/installments-select.js +167 -0
- package/dist/matter/installments/installments-select.js.map +1 -0
- package/dist/matter/installments/installments.d.ts +58 -0
- package/dist/matter/installments/installments.js +176 -0
- package/dist/matter/installments/installments.js.map +1 -0
- package/dist/matter/installments/use-installments-selection.d.ts +29 -0
- package/dist/matter/installments/use-installments-selection.js +95 -0
- package/dist/matter/installments/use-installments-selection.js.map +1 -0
- package/dist/matter/my-account-profile/my-account-profile.js +4 -4
- package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +63 -0
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +305 -0
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -0
- package/dist/matter/payment/payment-card-capture.d.ts +19 -0
- package/dist/matter/payment/payment-card-capture.js +129 -0
- package/dist/matter/payment/payment-card-capture.js.map +1 -0
- package/dist/matter/payment/payment-controller.d.ts +24 -0
- package/dist/matter/payment/payment-controller.js +107 -0
- package/dist/matter/payment/payment-controller.js.map +1 -0
- package/dist/matter/payment/payment-method-badges.d.ts +57 -0
- package/dist/matter/payment/payment-method-badges.js +192 -0
- package/dist/matter/payment/payment-method-badges.js.map +1 -0
- package/dist/matter/payment/payment.d.ts +89 -0
- package/dist/matter/payment/payment.js +263 -0
- package/dist/matter/payment/payment.js.map +1 -0
- package/dist/matter/payment/use-payment-method-selection.d.ts +302 -0
- package/dist/matter/payment/use-payment-method-selection.js +458 -0
- package/dist/matter/payment/use-payment-method-selection.js.map +1 -0
- package/dist/matter/payment/use-payment-submit-gate.d.ts +111 -0
- package/dist/matter/payment/use-payment-submit-gate.js +144 -0
- package/dist/matter/payment/use-payment-submit-gate.js.map +1 -0
- package/dist/matter/place-order/place-order.d.ts +74 -0
- package/dist/matter/place-order/place-order.js +379 -0
- package/dist/matter/place-order/place-order.js.map +1 -0
- package/dist/matter/product-list/product-list.d.ts +1 -0
- package/dist/matter/product-list/product-list.js.map +1 -1
- package/dist/matter/product-shelf/product-shelf.d.ts +1 -0
- package/dist/matter/product-shelf/product-shelf.js +2 -0
- package/dist/matter/product-shelf/product-shelf.js.map +1 -1
- package/dist/matter/region/region.js +1 -1
- package/dist/matter/region/region.js.map +1 -1
- package/dist/matter/save-card/save-card.d.ts +49 -0
- package/dist/matter/save-card/save-card.js +188 -0
- package/dist/matter/save-card/save-card.js.map +1 -0
- package/dist/matter/saved-cards/saved-cards.d.ts +79 -0
- package/dist/matter/saved-cards/saved-cards.js +387 -0
- package/dist/matter/saved-cards/saved-cards.js.map +1 -0
- package/dist/matter/shipping-address/country-descriptors.js +20 -10
- package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
- package/dist/matter/shipping-address/shipping-address.d.ts +113 -174
- package/dist/matter/shipping-address/shipping-address.js +480 -791
- package/dist/matter/shipping-address/shipping-address.js.map +1 -1
- package/dist/matter/variant-selector/variant-selector.js +1 -1
- package/dist/particles/address-summary/address-summary.d.ts +24 -0
- package/dist/particles/address-summary/address-summary.js +83 -2
- package/dist/particles/address-summary/address-summary.js.map +1 -1
- package/dist/particles/alert-dialog/alert-dialog.d.ts +68 -0
- package/dist/particles/alert-dialog/alert-dialog.js +187 -0
- package/dist/particles/alert-dialog/alert-dialog.js.map +1 -0
- package/dist/particles/checkbox/checkbox.d.ts +7 -3
- package/dist/particles/checkbox/checkbox.js +4 -1
- package/dist/particles/checkbox/checkbox.js.map +1 -1
- package/dist/particles/document-field/document-field.d.ts +48 -5
- package/dist/particles/document-field/document-field.js +189 -32
- package/dist/particles/document-field/document-field.js.map +1 -1
- package/dist/particles/field/bound-field-registry.js +52 -0
- package/dist/particles/field/bound-field-registry.js.map +1 -0
- package/dist/particles/field/field.d.ts +116 -0
- package/dist/particles/field/field.js +497 -6
- package/dist/particles/field/field.js.map +1 -1
- package/dist/particles/fieldset/fieldset.js +2 -2
- package/dist/particles/fieldset/fieldset.js.map +1 -1
- package/dist/particles/form/form.d.ts +104 -0
- package/dist/particles/form/form.js +485 -0
- package/dist/particles/form/form.js.map +1 -0
- package/dist/particles/phone-field/phone-field.d.ts +38 -10
- package/dist/particles/phone-field/phone-field.js +183 -39
- package/dist/particles/phone-field/phone-field.js.map +1 -1
- package/dist/particles/postal-code-field/postal-code-field.js +2 -2
- package/dist/particles/postal-code-field/postal-code-field.js.map +1 -1
- package/dist/particles/select/field-select.d.ts +43 -0
- package/dist/particles/select/field-select.js +150 -0
- package/dist/particles/select/field-select.js.map +1 -0
- package/dist/particles/select/select.d.ts +2 -0
- package/dist/particles/select/select.js.map +1 -1
- package/dist/particles/shared/compose-refs.js +21 -0
- package/dist/particles/shared/compose-refs.js.map +1 -0
- package/dist/schema.graphql +701 -2
- package/dist/sdk/actions/analytics-action-provider.d.ts +15 -0
- package/dist/sdk/actions/analytics-action-provider.js +19 -0
- package/dist/sdk/actions/analytics-action-provider.js.map +1 -0
- package/dist/sdk/actions/index.d.ts +3 -1
- package/dist/sdk/actions/index.js +3 -1
- package/dist/sdk/actions/payment-action-provider.d.ts +22 -0
- package/dist/sdk/actions/payment-action-provider.js +26 -0
- package/dist/sdk/actions/payment-action-provider.js.map +1 -0
- package/dist/sdk/actions/types.d.ts +6 -2
- package/dist/sdk/analytics/analytics-destination.d.ts +43 -0
- package/dist/sdk/analytics/analytics-destination.js +90 -0
- package/dist/sdk/analytics/analytics-destination.js.map +1 -0
- package/dist/sdk/analytics/use-analytics-actions.d.ts +57 -0
- package/dist/sdk/analytics/use-analytics-actions.js +108 -0
- package/dist/sdk/analytics/use-analytics-actions.js.map +1 -0
- package/dist/sdk/cart/use-cart-actions.js +1 -1
- package/dist/sdk/data/entity-resolution-context.js +31 -0
- package/dist/sdk/data/entity-resolution-context.js.map +1 -0
- package/dist/sdk/data/entity-subscriber.js +18 -8
- package/dist/sdk/data/entity-subscriber.js.map +1 -1
- package/dist/sdk/data/index.js +1 -0
- package/dist/sdk/data/page-reactive-data-root.d.ts +36 -0
- package/dist/sdk/data/page-reactive-data-root.js +4 -2
- package/dist/sdk/data/page-reactive-data-root.js.map +1 -1
- package/dist/sdk/data/reactive-data-provider.js +7 -3
- package/dist/sdk/data/reactive-data-provider.js.map +1 -1
- package/dist/sdk/data/reactive-list-item-data-provider.js +12 -4
- package/dist/sdk/data/reactive-list-item-data-provider.js.map +1 -1
- package/dist/sdk/data/use-reactive-data-settled.js +39 -0
- package/dist/sdk/data/use-reactive-data-settled.js.map +1 -0
- package/dist/sdk/data/use-reactive-entity.js +5 -1
- package/dist/sdk/data/use-reactive-entity.js.map +1 -1
- package/dist/sdk/generated/fragment-types.js +2 -0
- package/dist/sdk/generated/fragment-types.js.map +1 -1
- package/dist/sdk/generated/graphql.js.map +1 -1
- package/dist/sdk/i18n/messages/en-US.js +3 -0
- package/dist/sdk/i18n/messages/en-US.json +3 -0
- package/dist/sdk/i18n/messages/en-US.json.d.ts +3 -0
- package/dist/sdk/i18n/messages/es-ES.js +3 -0
- package/dist/sdk/i18n/messages/es-ES.json +3 -0
- package/dist/sdk/i18n/messages/pt-BR.js +3 -0
- package/dist/sdk/i18n/messages/pt-BR.json +3 -0
- package/dist/sdk/identity/use-identity-actions.js +3 -2
- package/dist/sdk/identity/use-identity-actions.js.map +1 -1
- package/dist/sdk/payment/gateway-origin.js +35 -0
- package/dist/sdk/payment/gateway-origin.js.map +1 -0
- package/dist/sdk/payment/gateway.d.ts +85 -0
- package/dist/sdk/payment/gateway.js +183 -0
- package/dist/sdk/payment/gateway.js.map +1 -0
- package/dist/sdk/payment/operations.d.ts +52 -0
- package/dist/sdk/payment/operations.js +223 -0
- package/dist/sdk/payment/operations.js.map +1 -0
- package/dist/sdk/payment/security-code-mask.js +71 -0
- package/dist/sdk/payment/security-code-mask.js.map +1 -0
- package/dist/sdk/payment/submission-registry.d.ts +33 -0
- package/dist/sdk/payment/submission-registry.js +58 -0
- package/dist/sdk/payment/submission-registry.js.map +1 -0
- package/dist/sdk/payment/use-payment-actions.d.ts +78 -0
- package/dist/sdk/payment/use-payment-actions.js +276 -0
- package/dist/sdk/payment/use-payment-actions.js.map +1 -0
- package/dist/sdk/payment/use-place-order.d.ts +65 -0
- package/dist/sdk/payment/use-place-order.js +640 -0
- package/dist/sdk/payment/use-place-order.js.map +1 -0
- package/dist/sdk/shipping/use-shipping-actions.js +1 -1
- package/dist/utils/loggable-error-name.js +49 -0
- package/dist/utils/loggable-error-name.js.map +1 -0
- package/dist/utils/resolve-authored-copy.js +18 -0
- package/dist/utils/resolve-authored-copy.js.map +1 -0
- package/dist/utils/substitute-template.js +33 -0
- package/dist/utils/substitute-template.js.map +1 -0
- package/package.json +2 -1
- package/src/styles/tailwind.css +34 -0
- package/dist/docs/client-profile-form.md +0 -192
- package/dist/matter/client-profile-form/client-profile-form.d.ts +0 -126
- package/dist/matter/client-profile-form/client-profile-form.js +0 -662
- package/dist/matter/client-profile-form/client-profile-form.js.map +0 -1
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { PaymentUserError } from "../../sdk/payment/operations.js";
|
|
2
|
+
import "./use-payment-method-selection.js";
|
|
3
|
+
//#region src/matter/payment/use-payment-submit-gate.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The submit gate (specs/cardholder-document-submit-gate.md, T24 of the Credit Card epic;
|
|
6
|
+
* docs/features/credit-card/rfc.md § D3, D6). One pure resolver covering the two facts T11's own
|
|
7
|
+
* deferral asked to ship together: a required-but-missing-or-malformed cardholder document, and a
|
|
8
|
+
* declined "same as delivery" billing address with nothing persisted yet. `PlaceOrder` (T14) reads the
|
|
9
|
+
* verdict through `usePaymentSubmitGate()` below and forwards it into `usePlaceOrder`'s (T13)
|
|
10
|
+
* pre-flight, which refuses on it before `startTransaction` ever opens a transaction the client already
|
|
11
|
+
* knows it cannot complete.
|
|
12
|
+
*
|
|
13
|
+
* **Only the verdict crosses into `sdk/payment/`.** `usePlaceOrder` never learns *why* it refused —
|
|
14
|
+
* only this opaque `PaymentUserError` — because `sdk/payment/use-place-order.ts` may name no identifier
|
|
15
|
+
* matching `CARD_FIELD_PATTERN` (`sdk/payment/card-field-pattern.ts`), which includes `document`. Every
|
|
16
|
+
* fact the gate reads, and the four codes below, live here in `matter/payment/` instead.
|
|
17
|
+
*/
|
|
18
|
+
export declare const PAYMENT_MISSING_DOCUMENT_CODE = "MISSING_CARDHOLDER_DOCUMENT";
|
|
19
|
+
export declare const PAYMENT_INVALID_DOCUMENT_CODE = "INVALID_CARDHOLDER_DOCUMENT";
|
|
20
|
+
export declare const PAYMENT_UNSAVED_BILLING_ADDRESS_CODE = "UNSAVED_BILLING_ADDRESS";
|
|
21
|
+
/**
|
|
22
|
+
* T192 (issue 948): a document refusal while `CardholderDocument` renders nothing —
|
|
23
|
+
* a method the card form cannot pay with, or a selection outside the section's `group` — so the
|
|
24
|
+
* shopper is told to change the method, never to fill a field that is not on screen. The code and its
|
|
25
|
+
* copy are provisional until Product answers T191's OQ-4; `PlaceOrder` authors the copy
|
|
26
|
+
* (`unavailableMethodMessage`).
|
|
27
|
+
*/
|
|
28
|
+
export declare const PAYMENT_UNAVAILABLE_METHOD_CODE = "UNAVAILABLE_PAYMENT_METHOD";
|
|
29
|
+
export type PaymentSubmitGateInput = Readonly<{
|
|
30
|
+
/**
|
|
31
|
+
* The selected method's `validator.documentRequired`; `false` when no method is resolved yet.
|
|
32
|
+
* `usePaymentSubmitGate()` resolves the method by `selectedMethodId` against `allMethods` — the
|
|
33
|
+
* section's *unscoped* list — never the group-scoped `selectedMethod` (finding S1; see that hook's
|
|
34
|
+
* own doc comment).
|
|
35
|
+
*/
|
|
36
|
+
documentRequired: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The selected method's `validator.documentDisplayable`, resolved the same unscoped way; `false` when
|
|
39
|
+
* no method is resolved yet. Gates *both* document checks below (fix pass, findings R1/S4/S5 — one
|
|
40
|
+
* root cause, three symptoms): `draft.document` is a single fact with a single writer,
|
|
41
|
+
* `CardholderDocument.onValueChange` (`cardholder-document.tsx:111`). When the selected method's
|
|
42
|
+
* validator says the document is not displayable, `CardholderDocument` renders nothing for it
|
|
43
|
+
* (`cardholder-document.tsx:93`) — but nothing clears `draft.document` when that happens: not
|
|
44
|
+
* `CardholderDocument` unmounting, and not `selectMethod` (`use-payment-method-selection.ts`), which
|
|
45
|
+
* writes only `path`/`bin` from its input. So `draft.document` can still hold whatever the shopper
|
|
46
|
+
* typed for a *previously* selected, displayable method. Without this flag, a stale malformed value
|
|
47
|
+
* would refuse forever with no field left to fix it (R1: a mid-typing, not-yet-valid value survives a
|
|
48
|
+
* network-detection re-dispatch to a method that never shows the field; S5: any method whose validator
|
|
49
|
+
* pairs `documentRequired: true` with `documentDisplayable: false` is unconditionally unsatisfiable),
|
|
50
|
+
* and a stale *valid* value would silently vouch for a document the current method never collected
|
|
51
|
+
* (S4). Both are the same mistake: treating `draft.document` as meaningful when there is no field on
|
|
52
|
+
* screen for the shopper to read it from or correct it in. Neither check may run in that state —
|
|
53
|
+
* matching US-1's fourth criterion ("the gate contributes nothing regardless of what `draft.document`
|
|
54
|
+
* holds") generalized to every `documentRequired` value, not only `false`. This does not weaken the
|
|
55
|
+
* spec's own settled "no `CardholderDocument` composed" deadlock (its Risk R1, US-4 — a different R1
|
|
56
|
+
* than this fix pass's own): that case has `documentDisplayable: true` on the validator (the method
|
|
57
|
+
* genuinely calls for a document) with the leaf simply missing from the schema, so FR-1 still fires and
|
|
58
|
+
* still refuses with a console diagnostic.
|
|
59
|
+
*/
|
|
60
|
+
documentDisplayable: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Whether `CardholderDocument` renders for this selection: `isCardholderDocumentShown(...)` over the
|
|
63
|
+
* *scoped* `selectedMethod` and `cardPaymentCollapsed` (T192, Decision 3). Never a trigger: the two
|
|
64
|
+
* unscoped flags above still decide whether the document refuses (S1). It decides only what the
|
|
65
|
+
* refusal says — the document codes when the field is on screen, `UNAVAILABLE_PAYMENT_METHOD` when it
|
|
66
|
+
* is not, since a shopper cannot fill a field that is not there (issue 948).
|
|
67
|
+
*/
|
|
68
|
+
documentFieldShown: boolean;
|
|
69
|
+
/** `draft.document` — the masked value `CardholderDocument` publishes on change. */
|
|
70
|
+
document: string | null;
|
|
71
|
+
/** `draft.billingAddressUnsaved`. */
|
|
72
|
+
billingAddressUnsaved: boolean | null;
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* The whole gate: at most one refusal, resolved in a fixed order (FR-7) — the document slot
|
|
76
|
+
* (document-missing, then document-invalid), then billing-unsaved. Pure — no hooks, no context, no DOM —
|
|
77
|
+
* so the truth table is unit-testable without rendering, mirroring `card-entry.tsx`'s own exported
|
|
78
|
+
* `isValidLuhn` / `isExpirationInFuture` convention.
|
|
79
|
+
*
|
|
80
|
+
* T192 (Decision 2): the document slot refuses in exactly the states it always did, and `documentFieldShown`
|
|
81
|
+
* changes only its code — `UNAVAILABLE_PAYMENT_METHOD` instead of a document code while `CardholderDocument`
|
|
82
|
+
* renders nothing (INV-1, INV-2). The billing check is unchanged.
|
|
83
|
+
*/
|
|
84
|
+
export declare function resolvePaymentSubmitGate({ documentRequired, documentDisplayable, documentFieldShown, document, billingAddressUnsaved }: PaymentSubmitGateInput): PaymentUserError | null;
|
|
85
|
+
/**
|
|
86
|
+
* Reads `usePayment()` and resolves the gate, memoized on the primitives — never on the `draft` object
|
|
87
|
+
* itself (NFR-3): `draft`'s identity changes on every card-number keystroke (`setDraftBin`), and this
|
|
88
|
+
* must not re-run the CPF check-digit test on each one.
|
|
89
|
+
*
|
|
90
|
+
* Resolves the validator by looking `persistedMethodId` up against `allMethods` — the section's
|
|
91
|
+
* *unscoped* fact and *unscoped* method list — rather than the group-scoped `selectedMethod` /
|
|
92
|
+
* `selectedMethodId` `usePayment()` also exposes (T74, Decision 4/7: the ones `CardholderDocument`/
|
|
93
|
+
* `CardEntry` render from). Fix pass, finding S1, carried forward by T74's contract split:
|
|
94
|
+
* `usePlaceOrder`'s own pre-flight (`sdk/payment/use-place-order.ts`) resolves *its* `selectedMethod`
|
|
95
|
+
* the same unscoped way, off its own independent fragment slice (Decision 2 forbids either hook from
|
|
96
|
+
* reading the other's module). Resolving off the scoped `selectedMethodId` here would silently degrade
|
|
97
|
+
* `documentRequired` to `false` whenever the persisted selection's `groupName` sits outside this root's
|
|
98
|
+
* configured `group` set — no attacker needed, just a store whose real credit- or debit-card group name
|
|
99
|
+
* differs from the hardcoded defaults (`payment.tsx`'s `DEFAULT_METHOD_GROUP`, now two groups rather than
|
|
100
|
+
* one) — while `usePlaceOrder` still finds the method by id alone and opens a transaction. Matching
|
|
101
|
+
* `usePlaceOrder`'s own by-id lookup keeps the two
|
|
102
|
+
* in agreement for every method actually reachable through this root, which is the one thing
|
|
103
|
+
* `usePaymentSubmitGate` and `usePlaceOrder` can never be allowed to disagree about.
|
|
104
|
+
*
|
|
105
|
+
* T192 (issue 948): the scoped `selectedMethod` and `cardPaymentCollapsed` are read for one fact only,
|
|
106
|
+
* `documentFieldShown`, through the same `isCardholderDocumentShown` `CardholderDocument` renders by.
|
|
107
|
+
* It never decides whether the gate refuses — only whether a refusal may name the document.
|
|
108
|
+
*/
|
|
109
|
+
export declare function usePaymentSubmitGate(): PaymentUserError | null;
|
|
110
|
+
//#endregion
|
|
111
|
+
//# sourceMappingURL=use-payment-submit-gate.d.ts.map
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePayment } from "./payment.js";
|
|
3
|
+
import { isValidDocument } from "../../particles/document-field/document-field.js";
|
|
4
|
+
import { useMemo } from "react";
|
|
5
|
+
//#region src/matter/payment/use-payment-submit-gate.ts
|
|
6
|
+
/**
|
|
7
|
+
* The submit gate (specs/cardholder-document-submit-gate.md, T24 of the Credit Card epic;
|
|
8
|
+
* docs/features/credit-card/rfc.md § D3, D6). One pure resolver covering the two facts T11's own
|
|
9
|
+
* deferral asked to ship together: a required-but-missing-or-malformed cardholder document, and a
|
|
10
|
+
* declined "same as delivery" billing address with nothing persisted yet. `PlaceOrder` (T14) reads the
|
|
11
|
+
* verdict through `usePaymentSubmitGate()` below and forwards it into `usePlaceOrder`'s (T13)
|
|
12
|
+
* pre-flight, which refuses on it before `startTransaction` ever opens a transaction the client already
|
|
13
|
+
* knows it cannot complete.
|
|
14
|
+
*
|
|
15
|
+
* **Only the verdict crosses into `sdk/payment/`.** `usePlaceOrder` never learns *why* it refused —
|
|
16
|
+
* only this opaque `PaymentUserError` — because `sdk/payment/use-place-order.ts` may name no identifier
|
|
17
|
+
* matching `CARD_FIELD_PATTERN` (`sdk/payment/card-field-pattern.ts`), which includes `document`. Every
|
|
18
|
+
* fact the gate reads, and the four codes below, live here in `matter/payment/` instead.
|
|
19
|
+
*/
|
|
20
|
+
const PAYMENT_MISSING_DOCUMENT_CODE = "MISSING_CARDHOLDER_DOCUMENT";
|
|
21
|
+
const PAYMENT_INVALID_DOCUMENT_CODE = "INVALID_CARDHOLDER_DOCUMENT";
|
|
22
|
+
const PAYMENT_UNSAVED_BILLING_ADDRESS_CODE = "UNSAVED_BILLING_ADDRESS";
|
|
23
|
+
/**
|
|
24
|
+
* T192 (issue 948): a document refusal while `CardholderDocument` renders nothing —
|
|
25
|
+
* a method the card form cannot pay with, or a selection outside the section's `group` — so the
|
|
26
|
+
* shopper is told to change the method, never to fill a field that is not on screen. The code and its
|
|
27
|
+
* copy are provisional until Product answers T191's OQ-4; `PlaceOrder` authors the copy
|
|
28
|
+
* (`unavailableMethodMessage`).
|
|
29
|
+
*/
|
|
30
|
+
const PAYMENT_UNAVAILABLE_METHOD_CODE = "UNAVAILABLE_PAYMENT_METHOD";
|
|
31
|
+
const MISSING_DOCUMENT_ERROR = {
|
|
32
|
+
code: PAYMENT_MISSING_DOCUMENT_CODE,
|
|
33
|
+
message: "Enter your document before placing the order."
|
|
34
|
+
};
|
|
35
|
+
const INVALID_DOCUMENT_ERROR = {
|
|
36
|
+
code: PAYMENT_INVALID_DOCUMENT_CODE,
|
|
37
|
+
message: "Enter a valid document before placing the order."
|
|
38
|
+
};
|
|
39
|
+
const UNSAVED_BILLING_ADDRESS_ERROR = {
|
|
40
|
+
code: PAYMENT_UNSAVED_BILLING_ADDRESS_CODE,
|
|
41
|
+
message: "Save your billing address before placing the order."
|
|
42
|
+
};
|
|
43
|
+
const UNAVAILABLE_METHOD_ERROR = {
|
|
44
|
+
code: PAYMENT_UNAVAILABLE_METHOD_CODE,
|
|
45
|
+
message: "Choose another payment method before placing the order."
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Whether `CardholderDocument` renders for this selection (T192, Decision 3): the one definition, so
|
|
49
|
+
* the field and the gate can never disagree about it. `selectedMethod` is the *scoped* one
|
|
50
|
+
* `usePayment()` serves, so a selection outside `group` shows no field. Nothing shows while the card
|
|
51
|
+
* payment is collapsed either (T191, FR-7), whatever the method's validator says.
|
|
52
|
+
*/
|
|
53
|
+
function isCardholderDocumentShown({ cardPaymentCollapsed, selectedMethod }) {
|
|
54
|
+
return !cardPaymentCollapsed && (selectedMethod?.validator.documentDisplayable ?? false);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The document half of the gate: document-missing, then document-invalid, or `null`.
|
|
58
|
+
*
|
|
59
|
+
* FR-1/FR-3: emptiness is its own explicit check, never expressed through `isValidDocument` alone —
|
|
60
|
+
* `isValidDocument('')` returns `true` by design (the document is optional in the general case), which
|
|
61
|
+
* would otherwise silently let a required-but-blank document through. FR-2/Decision 6: validity is
|
|
62
|
+
* checked whenever a value is present, independent of `documentRequired` — a malformed *optional*
|
|
63
|
+
* document blocks too, matching the legacy's own unconditional `pattern`/`validate` rule. Decision 6's
|
|
64
|
+
* own premise is a *displayable* field (a shopper who can see and fix what they typed); `documentDisplayable`
|
|
65
|
+
* therefore gates FR-1 and FR-2 alike (findings R1/S4/S5).
|
|
66
|
+
*/
|
|
67
|
+
function resolveDocumentRefusal({ documentRequired, documentDisplayable, document }) {
|
|
68
|
+
if (!documentDisplayable) return null;
|
|
69
|
+
if (documentRequired && (document?.trim() ?? "") === "") return MISSING_DOCUMENT_ERROR;
|
|
70
|
+
if (!isValidDocument(document ?? "", "CPF")) return INVALID_DOCUMENT_ERROR;
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The whole gate: at most one refusal, resolved in a fixed order (FR-7) — the document slot
|
|
75
|
+
* (document-missing, then document-invalid), then billing-unsaved. Pure — no hooks, no context, no DOM —
|
|
76
|
+
* so the truth table is unit-testable without rendering, mirroring `card-entry.tsx`'s own exported
|
|
77
|
+
* `isValidLuhn` / `isExpirationInFuture` convention.
|
|
78
|
+
*
|
|
79
|
+
* T192 (Decision 2): the document slot refuses in exactly the states it always did, and `documentFieldShown`
|
|
80
|
+
* changes only its code — `UNAVAILABLE_PAYMENT_METHOD` instead of a document code while `CardholderDocument`
|
|
81
|
+
* renders nothing (INV-1, INV-2). The billing check is unchanged.
|
|
82
|
+
*/
|
|
83
|
+
function resolvePaymentSubmitGate({ documentRequired, documentDisplayable, documentFieldShown, document, billingAddressUnsaved }) {
|
|
84
|
+
const documentRefusal = resolveDocumentRefusal({
|
|
85
|
+
documentRequired,
|
|
86
|
+
documentDisplayable,
|
|
87
|
+
document
|
|
88
|
+
});
|
|
89
|
+
if (documentRefusal) return documentFieldShown ? documentRefusal : UNAVAILABLE_METHOD_ERROR;
|
|
90
|
+
if (billingAddressUnsaved) return UNSAVED_BILLING_ADDRESS_ERROR;
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Reads `usePayment()` and resolves the gate, memoized on the primitives — never on the `draft` object
|
|
95
|
+
* itself (NFR-3): `draft`'s identity changes on every card-number keystroke (`setDraftBin`), and this
|
|
96
|
+
* must not re-run the CPF check-digit test on each one.
|
|
97
|
+
*
|
|
98
|
+
* Resolves the validator by looking `persistedMethodId` up against `allMethods` — the section's
|
|
99
|
+
* *unscoped* fact and *unscoped* method list — rather than the group-scoped `selectedMethod` /
|
|
100
|
+
* `selectedMethodId` `usePayment()` also exposes (T74, Decision 4/7: the ones `CardholderDocument`/
|
|
101
|
+
* `CardEntry` render from). Fix pass, finding S1, carried forward by T74's contract split:
|
|
102
|
+
* `usePlaceOrder`'s own pre-flight (`sdk/payment/use-place-order.ts`) resolves *its* `selectedMethod`
|
|
103
|
+
* the same unscoped way, off its own independent fragment slice (Decision 2 forbids either hook from
|
|
104
|
+
* reading the other's module). Resolving off the scoped `selectedMethodId` here would silently degrade
|
|
105
|
+
* `documentRequired` to `false` whenever the persisted selection's `groupName` sits outside this root's
|
|
106
|
+
* configured `group` set — no attacker needed, just a store whose real credit- or debit-card group name
|
|
107
|
+
* differs from the hardcoded defaults (`payment.tsx`'s `DEFAULT_METHOD_GROUP`, now two groups rather than
|
|
108
|
+
* one) — while `usePlaceOrder` still finds the method by id alone and opens a transaction. Matching
|
|
109
|
+
* `usePlaceOrder`'s own by-id lookup keeps the two
|
|
110
|
+
* in agreement for every method actually reachable through this root, which is the one thing
|
|
111
|
+
* `usePaymentSubmitGate` and `usePlaceOrder` can never be allowed to disagree about.
|
|
112
|
+
*
|
|
113
|
+
* T192 (issue 948): the scoped `selectedMethod` and `cardPaymentCollapsed` are read for one fact only,
|
|
114
|
+
* `documentFieldShown`, through the same `isCardholderDocumentShown` `CardholderDocument` renders by.
|
|
115
|
+
* It never decides whether the gate refuses — only whether a refusal may name the document.
|
|
116
|
+
*/
|
|
117
|
+
function usePaymentSubmitGate() {
|
|
118
|
+
const { persistedMethodId, allMethods, selectedMethod, cardPaymentCollapsed, draft } = usePayment();
|
|
119
|
+
const resolvedMethod = useMemo(() => allMethods.find((method) => method.id === persistedMethodId) ?? null, [allMethods, persistedMethodId]);
|
|
120
|
+
const documentRequired = resolvedMethod?.validator.documentRequired ?? false;
|
|
121
|
+
const documentDisplayable = resolvedMethod?.validator.documentDisplayable ?? false;
|
|
122
|
+
const documentFieldShown = isCardholderDocumentShown({
|
|
123
|
+
cardPaymentCollapsed,
|
|
124
|
+
selectedMethod
|
|
125
|
+
});
|
|
126
|
+
const { document, billingAddressUnsaved } = draft;
|
|
127
|
+
return useMemo(() => resolvePaymentSubmitGate({
|
|
128
|
+
documentRequired,
|
|
129
|
+
documentDisplayable,
|
|
130
|
+
documentFieldShown,
|
|
131
|
+
document,
|
|
132
|
+
billingAddressUnsaved
|
|
133
|
+
}), [
|
|
134
|
+
documentRequired,
|
|
135
|
+
documentDisplayable,
|
|
136
|
+
documentFieldShown,
|
|
137
|
+
document,
|
|
138
|
+
billingAddressUnsaved
|
|
139
|
+
]);
|
|
140
|
+
}
|
|
141
|
+
//#endregion
|
|
142
|
+
export { PAYMENT_INVALID_DOCUMENT_CODE, PAYMENT_MISSING_DOCUMENT_CODE, PAYMENT_UNAVAILABLE_METHOD_CODE, PAYMENT_UNSAVED_BILLING_ADDRESS_CODE, isCardholderDocumentShown, resolvePaymentSubmitGate, usePaymentSubmitGate };
|
|
143
|
+
|
|
144
|
+
//# sourceMappingURL=use-payment-submit-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-payment-submit-gate.js","names":[],"sources":["../../../src/matter/payment/use-payment-submit-gate.ts"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\nimport { isValidDocument } from '../../particles/document-field/document-field.js';\nimport type { PaymentUserError } from '../../sdk/payment/operations.js';\nimport { usePayment } from './payment.js';\nimport type { PaymentSectionMethod } from './use-payment-method-selection.js';\n\n/**\n * The submit gate (specs/cardholder-document-submit-gate.md, T24 of the Credit Card epic;\n * docs/features/credit-card/rfc.md § D3, D6). One pure resolver covering the two facts T11's own\n * deferral asked to ship together: a required-but-missing-or-malformed cardholder document, and a\n * declined \"same as delivery\" billing address with nothing persisted yet. `PlaceOrder` (T14) reads the\n * verdict through `usePaymentSubmitGate()` below and forwards it into `usePlaceOrder`'s (T13)\n * pre-flight, which refuses on it before `startTransaction` ever opens a transaction the client already\n * knows it cannot complete.\n *\n * **Only the verdict crosses into `sdk/payment/`.** `usePlaceOrder` never learns *why* it refused —\n * only this opaque `PaymentUserError` — because `sdk/payment/use-place-order.ts` may name no identifier\n * matching `CARD_FIELD_PATTERN` (`sdk/payment/card-field-pattern.ts`), which includes `document`. Every\n * fact the gate reads, and the four codes below, live here in `matter/payment/` instead.\n */\n\n// ---------------------------------------------------------------------------\n// Client-synthesized codes. Distinct from T13's own three (`use-place-order.ts`) and from the\n// gateway's (`gateway.ts`) — these mean \"the client already knows this submission would be refused,\"\n// resolved before any request leaves the browser.\n// ---------------------------------------------------------------------------\n\nexport const PAYMENT_MISSING_DOCUMENT_CODE = 'MISSING_CARDHOLDER_DOCUMENT';\nexport const PAYMENT_INVALID_DOCUMENT_CODE = 'INVALID_CARDHOLDER_DOCUMENT';\nexport const PAYMENT_UNSAVED_BILLING_ADDRESS_CODE = 'UNSAVED_BILLING_ADDRESS';\n/**\n * T192 (issue 948): a document refusal while `CardholderDocument` renders nothing —\n * a method the card form cannot pay with, or a selection outside the section's `group` — so the\n * shopper is told to change the method, never to fill a field that is not on screen. The code and its\n * copy are provisional until Product answers T191's OQ-4; `PlaceOrder` authors the copy\n * (`unavailableMethodMessage`).\n */\nexport const PAYMENT_UNAVAILABLE_METHOD_CODE = 'UNAVAILABLE_PAYMENT_METHOD';\n\nconst MISSING_DOCUMENT_ERROR: PaymentUserError = {\n code: PAYMENT_MISSING_DOCUMENT_CODE,\n message: 'Enter your document before placing the order.',\n};\n\nconst INVALID_DOCUMENT_ERROR: PaymentUserError = {\n code: PAYMENT_INVALID_DOCUMENT_CODE,\n message: 'Enter a valid document before placing the order.',\n};\n\nconst UNSAVED_BILLING_ADDRESS_ERROR: PaymentUserError = {\n code: PAYMENT_UNSAVED_BILLING_ADDRESS_CODE,\n message: 'Save your billing address before placing the order.',\n};\n\nconst UNAVAILABLE_METHOD_ERROR: PaymentUserError = {\n code: PAYMENT_UNAVAILABLE_METHOD_CODE,\n message: 'Choose another payment method before placing the order.',\n};\n\n/**\n * Whether `CardholderDocument` renders for this selection (T192, Decision 3): the one definition, so\n * the field and the gate can never disagree about it. `selectedMethod` is the *scoped* one\n * `usePayment()` serves, so a selection outside `group` shows no field. Nothing shows while the card\n * payment is collapsed either (T191, FR-7), whatever the method's validator says.\n */\nexport function isCardholderDocumentShown({\n cardPaymentCollapsed,\n selectedMethod,\n}: Readonly<{ cardPaymentCollapsed: boolean; selectedMethod: PaymentSectionMethod | null }>): boolean {\n return !cardPaymentCollapsed && (selectedMethod?.validator.documentDisplayable ?? false);\n}\n\n// ---------------------------------------------------------------------------\n// The resolver\n// ---------------------------------------------------------------------------\n\nexport type PaymentSubmitGateInput = Readonly<{\n /**\n * The selected method's `validator.documentRequired`; `false` when no method is resolved yet.\n * `usePaymentSubmitGate()` resolves the method by `selectedMethodId` against `allMethods` — the\n * section's *unscoped* list — never the group-scoped `selectedMethod` (finding S1; see that hook's\n * own doc comment).\n */\n documentRequired: boolean;\n /**\n * The selected method's `validator.documentDisplayable`, resolved the same unscoped way; `false` when\n * no method is resolved yet. Gates *both* document checks below (fix pass, findings R1/S4/S5 — one\n * root cause, three symptoms): `draft.document` is a single fact with a single writer,\n * `CardholderDocument.onValueChange` (`cardholder-document.tsx:111`). When the selected method's\n * validator says the document is not displayable, `CardholderDocument` renders nothing for it\n * (`cardholder-document.tsx:93`) — but nothing clears `draft.document` when that happens: not\n * `CardholderDocument` unmounting, and not `selectMethod` (`use-payment-method-selection.ts`), which\n * writes only `path`/`bin` from its input. So `draft.document` can still hold whatever the shopper\n * typed for a *previously* selected, displayable method. Without this flag, a stale malformed value\n * would refuse forever with no field left to fix it (R1: a mid-typing, not-yet-valid value survives a\n * network-detection re-dispatch to a method that never shows the field; S5: any method whose validator\n * pairs `documentRequired: true` with `documentDisplayable: false` is unconditionally unsatisfiable),\n * and a stale *valid* value would silently vouch for a document the current method never collected\n * (S4). Both are the same mistake: treating `draft.document` as meaningful when there is no field on\n * screen for the shopper to read it from or correct it in. Neither check may run in that state —\n * matching US-1's fourth criterion (\"the gate contributes nothing regardless of what `draft.document`\n * holds\") generalized to every `documentRequired` value, not only `false`. This does not weaken the\n * spec's own settled \"no `CardholderDocument` composed\" deadlock (its Risk R1, US-4 — a different R1\n * than this fix pass's own): that case has `documentDisplayable: true` on the validator (the method\n * genuinely calls for a document) with the leaf simply missing from the schema, so FR-1 still fires and\n * still refuses with a console diagnostic.\n */\n documentDisplayable: boolean;\n /**\n * Whether `CardholderDocument` renders for this selection: `isCardholderDocumentShown(...)` over the\n * *scoped* `selectedMethod` and `cardPaymentCollapsed` (T192, Decision 3). Never a trigger: the two\n * unscoped flags above still decide whether the document refuses (S1). It decides only what the\n * refusal says — the document codes when the field is on screen, `UNAVAILABLE_PAYMENT_METHOD` when it\n * is not, since a shopper cannot fill a field that is not there (issue 948).\n */\n documentFieldShown: boolean;\n /** `draft.document` — the masked value `CardholderDocument` publishes on change. */\n document: string | null;\n /** `draft.billingAddressUnsaved`. */\n billingAddressUnsaved: boolean | null;\n}>;\n\n/**\n * The document half of the gate: document-missing, then document-invalid, or `null`.\n *\n * FR-1/FR-3: emptiness is its own explicit check, never expressed through `isValidDocument` alone —\n * `isValidDocument('')` returns `true` by design (the document is optional in the general case), which\n * would otherwise silently let a required-but-blank document through. FR-2/Decision 6: validity is\n * checked whenever a value is present, independent of `documentRequired` — a malformed *optional*\n * document blocks too, matching the legacy's own unconditional `pattern`/`validate` rule. Decision 6's\n * own premise is a *displayable* field (a shopper who can see and fix what they typed); `documentDisplayable`\n * therefore gates FR-1 and FR-2 alike (findings R1/S4/S5).\n */\nfunction resolveDocumentRefusal({\n documentRequired,\n documentDisplayable,\n document,\n}: Pick<PaymentSubmitGateInput, 'documentRequired' | 'documentDisplayable' | 'document'>): PaymentUserError | null {\n if (!documentDisplayable) return null;\n if (documentRequired && (document?.trim() ?? '') === '') return MISSING_DOCUMENT_ERROR;\n if (!isValidDocument(document ?? '', 'CPF')) return INVALID_DOCUMENT_ERROR;\n return null;\n}\n\n/**\n * The whole gate: at most one refusal, resolved in a fixed order (FR-7) — the document slot\n * (document-missing, then document-invalid), then billing-unsaved. Pure — no hooks, no context, no DOM —\n * so the truth table is unit-testable without rendering, mirroring `card-entry.tsx`'s own exported\n * `isValidLuhn` / `isExpirationInFuture` convention.\n *\n * T192 (Decision 2): the document slot refuses in exactly the states it always did, and `documentFieldShown`\n * changes only its code — `UNAVAILABLE_PAYMENT_METHOD` instead of a document code while `CardholderDocument`\n * renders nothing (INV-1, INV-2). The billing check is unchanged.\n */\nexport function resolvePaymentSubmitGate({\n documentRequired,\n documentDisplayable,\n documentFieldShown,\n document,\n billingAddressUnsaved,\n}: PaymentSubmitGateInput): PaymentUserError | null {\n const documentRefusal = resolveDocumentRefusal({ documentRequired, documentDisplayable, document });\n if (documentRefusal) {\n return documentFieldShown ? documentRefusal : UNAVAILABLE_METHOD_ERROR;\n }\n\n if (billingAddressUnsaved) {\n return UNSAVED_BILLING_ADDRESS_ERROR;\n }\n\n return null;\n}\n\n/**\n * Reads `usePayment()` and resolves the gate, memoized on the primitives — never on the `draft` object\n * itself (NFR-3): `draft`'s identity changes on every card-number keystroke (`setDraftBin`), and this\n * must not re-run the CPF check-digit test on each one.\n *\n * Resolves the validator by looking `persistedMethodId` up against `allMethods` — the section's\n * *unscoped* fact and *unscoped* method list — rather than the group-scoped `selectedMethod` /\n * `selectedMethodId` `usePayment()` also exposes (T74, Decision 4/7: the ones `CardholderDocument`/\n * `CardEntry` render from). Fix pass, finding S1, carried forward by T74's contract split:\n * `usePlaceOrder`'s own pre-flight (`sdk/payment/use-place-order.ts`) resolves *its* `selectedMethod`\n * the same unscoped way, off its own independent fragment slice (Decision 2 forbids either hook from\n * reading the other's module). Resolving off the scoped `selectedMethodId` here would silently degrade\n * `documentRequired` to `false` whenever the persisted selection's `groupName` sits outside this root's\n * configured `group` set — no attacker needed, just a store whose real credit- or debit-card group name\n * differs from the hardcoded defaults (`payment.tsx`'s `DEFAULT_METHOD_GROUP`, now two groups rather than\n * one) — while `usePlaceOrder` still finds the method by id alone and opens a transaction. Matching\n * `usePlaceOrder`'s own by-id lookup keeps the two\n * in agreement for every method actually reachable through this root, which is the one thing\n * `usePaymentSubmitGate` and `usePlaceOrder` can never be allowed to disagree about.\n *\n * T192 (issue 948): the scoped `selectedMethod` and `cardPaymentCollapsed` are read for one fact only,\n * `documentFieldShown`, through the same `isCardholderDocumentShown` `CardholderDocument` renders by.\n * It never decides whether the gate refuses — only whether a refusal may name the document.\n */\nexport function usePaymentSubmitGate(): PaymentUserError | null {\n const { persistedMethodId, allMethods, selectedMethod, cardPaymentCollapsed, draft } = usePayment();\n const resolvedMethod = useMemo(\n () => allMethods.find((method) => method.id === persistedMethodId) ?? null,\n [allMethods, persistedMethodId],\n );\n const documentRequired = resolvedMethod?.validator.documentRequired ?? false;\n const documentDisplayable = resolvedMethod?.validator.documentDisplayable ?? false;\n const documentFieldShown = isCardholderDocumentShown({ cardPaymentCollapsed, selectedMethod });\n const { document, billingAddressUnsaved } = draft;\n\n return useMemo(\n () =>\n resolvePaymentSubmitGate({\n documentRequired,\n documentDisplayable,\n documentFieldShown,\n document,\n billingAddressUnsaved,\n }),\n [documentRequired, documentDisplayable, documentFieldShown, document, billingAddressUnsaved],\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA6BA,MAAa,gCAAgC;AAC7C,MAAa,gCAAgC;AAC7C,MAAa,uCAAuC;;;;;;;;AAQpD,MAAa,kCAAkC;AAE/C,MAAM,yBAA2C;CAC/C,MAAM;CACN,SAAS;AACX;AAEA,MAAM,yBAA2C;CAC/C,MAAM;CACN,SAAS;AACX;AAEA,MAAM,gCAAkD;CACtD,MAAM;CACN,SAAS;AACX;AAEA,MAAM,2BAA6C;CACjD,MAAM;CACN,SAAS;AACX;;;;;;;AAQA,SAAgB,0BAA0B,EACxC,sBACA,kBACoG;CACpG,OAAO,CAAC,yBAAyB,gBAAgB,UAAU,uBAAuB;AACpF;;;;;;;;;;;;AA+DA,SAAS,uBAAuB,EAC9B,kBACA,qBACA,YACiH;CACjH,IAAI,CAAC,qBAAqB,OAAO;CACjC,IAAI,qBAAqB,UAAU,KAAK,KAAK,QAAQ,IAAI,OAAO;CAChE,IAAI,CAAC,gBAAgB,YAAY,IAAI,KAAK,GAAG,OAAO;CACpD,OAAO;AACT;;;;;;;;;;;AAYA,SAAgB,yBAAyB,EACvC,kBACA,qBACA,oBACA,UACA,yBACkD;CAClD,MAAM,kBAAkB,uBAAuB;EAAE;EAAkB;EAAqB;CAAS,CAAC;CAClG,IAAI,iBACF,OAAO,qBAAqB,kBAAkB;CAGhD,IAAI,uBACF,OAAO;CAGT,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,uBAAgD;CAC9D,MAAM,EAAE,mBAAmB,YAAY,gBAAgB,sBAAsB,UAAU,WAAW;CAClG,MAAM,iBAAiB,cACf,WAAW,MAAM,WAAW,OAAO,OAAO,iBAAiB,KAAK,MACtE,CAAC,YAAY,iBAAiB,CAChC;CACA,MAAM,mBAAmB,gBAAgB,UAAU,oBAAoB;CACvE,MAAM,sBAAsB,gBAAgB,UAAU,uBAAuB;CAC7E,MAAM,qBAAqB,0BAA0B;EAAE;EAAsB;CAAe,CAAC;CAC7F,MAAM,EAAE,UAAU,0BAA0B;CAE5C,OAAO,cAEH,yBAAyB;EACvB;EACA;EACA;EACA;EACA;CACF,CAAC,GACH;EAAC;EAAkB;EAAqB;EAAoB;EAAU;CAAqB,CAC7F;AACF"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ComponentDefinition } from "../../core/dist/define-component.js";
|
|
2
|
+
import "../../core/dist/index.js";
|
|
3
|
+
import "../../sdk/payment/operations.js";
|
|
4
|
+
import { ComponentActions } from "../../sdk/actions/types.js";
|
|
5
|
+
import { PlaceOrderData } from "../../sdk/payment/use-place-order.js";
|
|
6
|
+
import { ComponentPropsWithRef } from "react";
|
|
7
|
+
//#region src/matter/place-order/place-order.d.ts
|
|
8
|
+
export type PlaceOrderProps = ComponentPropsWithRef<'div'> & {
|
|
9
|
+
/** CTA label while idle. */
|
|
10
|
+
label?: string;
|
|
11
|
+
/** CTA label while the three-call sequence is in flight. */
|
|
12
|
+
placingLabel?: string;
|
|
13
|
+
/**
|
|
14
|
+
* CTA label while a surviving attempt (T29) offers a resume — the card already left the browser
|
|
15
|
+
* (`sent`) or its fate is unknown (`unresolved`), and the next click finalizes it rather than running
|
|
16
|
+
* the full sequence again. Shown instead of `label`, never alongside `placingLabel` (mutually
|
|
17
|
+
* exclusive — `placing` takes priority whenever both could apply).
|
|
18
|
+
*/
|
|
19
|
+
resumeLabel?: string;
|
|
20
|
+
/** Inline message shown once the sequence has settled with no `userErrors`. */
|
|
21
|
+
successMessage?: string;
|
|
22
|
+
/** Shown when `placeOrder()` is invoked with no registered submission for the current path. */
|
|
23
|
+
missingSubmissionMessage?: string;
|
|
24
|
+
/** Shown when no payment method is selected yet. */
|
|
25
|
+
missingMethodMessage?: string;
|
|
26
|
+
/** Shown when `startTransaction` resolves incomplete transaction data. */
|
|
27
|
+
invalidTransactionMessage?: string;
|
|
28
|
+
/** Shown for an infrastructure-level failure reaching the payment gateway action. */
|
|
29
|
+
networkErrorMessage?: string;
|
|
30
|
+
/** Shown when the selected method requires a cardholder document and none is set. */
|
|
31
|
+
missingDocumentMessage?: string;
|
|
32
|
+
/** Shown when the typed cardholder document fails validation. */
|
|
33
|
+
invalidDocumentMessage?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Shown instead of the two document messages above when the selected method calls for a cardholder
|
|
36
|
+
* document the page is not showing — a method the card form cannot pay with, or one outside the
|
|
37
|
+
* section's `group` — so the shopper has to choose another payment method (T192).
|
|
38
|
+
*/
|
|
39
|
+
unavailableMethodMessage?: string;
|
|
40
|
+
/** Shown when the shopper declined "same as delivery" but never saved a billing address. */
|
|
41
|
+
unsavedBillingAddressMessage?: string;
|
|
42
|
+
/** Shown when the new-card draft itself fails validation before ever reaching the gateway. */
|
|
43
|
+
invalidCardDataMessage?: string;
|
|
44
|
+
/** Shown when a saved-card submission is refused for a missing or invalid CVV. */
|
|
45
|
+
invalidSecurityCodeMessage?: string;
|
|
46
|
+
/** Shown when the payment gateway itself refuses the submitted card. */
|
|
47
|
+
gatewayErrorMessage?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Shown when a click lands on an order-placement attempt whose own sequence is still running — a
|
|
50
|
+
* transaction this instance did not open, and which nothing here may finalize or re-run (T170).
|
|
51
|
+
*/
|
|
52
|
+
inFlightMessage?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Shown when the payment was handed to the gateway but the order could not be confirmed, so it may still be
|
|
55
|
+
* processing (T176). Rendered as a status, never as the error alert.
|
|
56
|
+
*/
|
|
57
|
+
unconfirmedMessage?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Route template navigated to after a successful placement. The literal `{orderGroup}` is
|
|
60
|
+
* replaced by the placed order's group, percent-encoded. Absent ⇒ no navigation. Must resolve to
|
|
61
|
+
* the current page's origin — an absolute, protocol-relative, or non-http(s) template is refused
|
|
62
|
+
* rather than navigated to (fail closed, dev-only warn; fix pass, finding S1).
|
|
63
|
+
* e.g. "/reserva/checkout/order-placed/{orderGroup}"
|
|
64
|
+
*/
|
|
65
|
+
successHref?: string;
|
|
66
|
+
/** `Payment` slice forwarded by the reactive runtime (arity-1, ADR-0015) — `null` until it resolves. */
|
|
67
|
+
$data?: PlaceOrderData;
|
|
68
|
+
/** Compiler-injected action surface; carries `payment.startTransaction`, `payment.gatewayCallback`, `analytics.track`. */
|
|
69
|
+
$actions?: ComponentActions;
|
|
70
|
+
};
|
|
71
|
+
export declare const PlaceOrderDefinition: ComponentDefinition<PlaceOrderProps>;
|
|
72
|
+
export declare function PlaceOrder({ label, placingLabel, resumeLabel, successMessage, missingSubmissionMessage, missingMethodMessage, invalidTransactionMessage, networkErrorMessage, missingDocumentMessage, invalidDocumentMessage, unavailableMethodMessage, unsavedBillingAddressMessage, invalidCardDataMessage, invalidSecurityCodeMessage, gatewayErrorMessage, inFlightMessage, unconfirmedMessage, successHref, $data: $dataProp, $actions: $actionsProp, className, ...props }: PlaceOrderProps): import("react/jsx-runtime").JSX.Element;
|
|
73
|
+
//#endregion
|
|
74
|
+
//# sourceMappingURL=place-order.d.ts.map
|