@vtex/faststore 0.0.4 → 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.
Files changed (306) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/actions.json +181 -0
  3. package/dist/catalog.json +1595 -481
  4. package/dist/client.d.ts +2 -1
  5. package/dist/client.js +2 -1
  6. package/dist/components.d.ts +31 -7
  7. package/dist/components.js +35 -13
  8. package/dist/content-types.json +73 -0
  9. package/dist/docs/access-code-sign-in.md +1 -1
  10. package/dist/docs/account-access-gate.md +153 -0
  11. package/dist/docs/account-entry-point.md +1 -2
  12. package/dist/docs/account-menu.md +164 -0
  13. package/dist/docs/address-summary.md +24 -3
  14. package/dist/docs/alert-dialog.md +204 -0
  15. package/dist/docs/billing-address.md +284 -0
  16. package/dist/docs/buy-button.md +1 -1
  17. package/dist/docs/card-entry.md +250 -0
  18. package/dist/docs/cardholder-document.md +142 -0
  19. package/dist/docs/cart.md +1 -1
  20. package/dist/docs/client-preferences-fieldset.md +148 -0
  21. package/dist/docs/client-preferences.md +2 -1
  22. package/dist/docs/client-profile-fieldset.md +184 -0
  23. package/dist/docs/client-profile.md +1 -1
  24. package/dist/docs/document-field.md +58 -4
  25. package/dist/docs/field.md +317 -0
  26. package/dist/docs/form.md +307 -0
  27. package/dist/docs/identity-edit.md +6 -6
  28. package/dist/docs/identity-summary.md +5 -5
  29. package/dist/docs/installments.md +248 -0
  30. package/dist/docs/my-account-profile.md +1 -0
  31. package/dist/docs/order-placed-payment-summary.md +138 -0
  32. package/dist/docs/payment-method-badges.md +232 -0
  33. package/dist/docs/payment-methods.md +1 -0
  34. package/dist/docs/payment.md +218 -0
  35. package/dist/docs/phone-field.md +58 -4
  36. package/dist/docs/place-order.md +157 -0
  37. package/dist/docs/save-card.md +186 -0
  38. package/dist/docs/saved-cards.md +218 -0
  39. package/dist/docs/select.md +465 -0
  40. package/dist/docs/session.md +1 -1
  41. package/dist/docs/shipping-address.md +110 -258
  42. package/dist/docs/sign-in-redirect.md +1 -1
  43. package/dist/index.d.ts +4 -1
  44. package/dist/internal/client.d.ts +3 -1
  45. package/dist/internal/client.js +3 -1
  46. package/dist/matter/access-code-sign-in/access-code-sign-in.js +9 -8
  47. package/dist/matter/access-code-sign-in/access-code-sign-in.js.map +1 -1
  48. package/dist/matter/account-access-gate/account-access-gate.d.ts +86 -0
  49. package/dist/matter/account-access-gate/account-access-gate.js +283 -0
  50. package/dist/matter/account-access-gate/account-access-gate.js.map +1 -0
  51. package/dist/matter/account-access-gate/sign-out-intent.d.ts +17 -0
  52. package/dist/matter/account-access-gate/sign-out-intent.js +62 -0
  53. package/dist/matter/account-access-gate/sign-out-intent.js.map +1 -0
  54. package/dist/matter/account-entry-point/account-entry-point.js +2 -2
  55. package/dist/matter/account-entry-point/account-entry-point.js.map +1 -1
  56. package/dist/matter/account-menu/account-menu.d.ts +88 -0
  57. package/dist/matter/account-menu/account-menu.js +246 -0
  58. package/dist/matter/account-menu/account-menu.js.map +1 -0
  59. package/dist/matter/billing-address/billing-address.d.ts +165 -0
  60. package/dist/matter/billing-address/billing-address.js +408 -0
  61. package/dist/matter/billing-address/billing-address.js.map +1 -0
  62. package/dist/matter/card-entry/card-capture.d.ts +25 -0
  63. package/dist/matter/card-entry/card-capture.js +25 -0
  64. package/dist/matter/card-entry/card-capture.js.map +1 -0
  65. package/dist/matter/card-entry/card-entry.d.ts +120 -0
  66. package/dist/matter/card-entry/card-entry.js +832 -0
  67. package/dist/matter/card-entry/card-entry.js.map +1 -0
  68. package/dist/matter/cardholder-document/cardholder-document.d.ts +45 -0
  69. package/dist/matter/cardholder-document/cardholder-document.js +70 -0
  70. package/dist/matter/cardholder-document/cardholder-document.js.map +1 -0
  71. package/dist/matter/cart/cart.d.ts +1 -1
  72. package/dist/matter/cart/cart.js +2 -2
  73. package/dist/matter/cart/cart.js.map +1 -1
  74. package/dist/matter/client-preferences/client-preferences-fieldset.d.ts +77 -0
  75. package/dist/matter/client-preferences/client-preferences-fieldset.js +299 -0
  76. package/dist/matter/client-preferences/client-preferences-fieldset.js.map +1 -0
  77. package/dist/matter/client-preferences/client-preferences.d.ts +3 -5
  78. package/dist/matter/client-preferences/client-preferences.js +6 -6
  79. package/dist/matter/client-preferences/client-preferences.js.map +1 -1
  80. package/dist/matter/client-profile/client-profile.d.ts +4 -6
  81. package/dist/matter/client-profile/client-profile.js +9 -6
  82. package/dist/matter/client-profile/client-profile.js.map +1 -1
  83. package/dist/matter/client-profile-form/client-profile-fieldset.d.ts +119 -0
  84. package/dist/matter/client-profile-form/client-profile-fieldset.js +488 -0
  85. package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -0
  86. package/dist/matter/delivery-options/delivery-options.js.map +1 -1
  87. package/dist/matter/identity-edit/identity-edit.js +2 -2
  88. package/dist/matter/identity-edit/identity-edit.js.map +1 -1
  89. package/dist/matter/identity-summary/identity-summary.js +2 -2
  90. package/dist/matter/identity-summary/identity-summary.js.map +1 -1
  91. package/dist/matter/installments/installments-select.d.ts +42 -0
  92. package/dist/matter/installments/installments-select.js +167 -0
  93. package/dist/matter/installments/installments-select.js.map +1 -0
  94. package/dist/matter/installments/installments.d.ts +58 -0
  95. package/dist/matter/installments/installments.js +176 -0
  96. package/dist/matter/installments/installments.js.map +1 -0
  97. package/dist/matter/installments/use-installments-selection.d.ts +29 -0
  98. package/dist/matter/installments/use-installments-selection.js +95 -0
  99. package/dist/matter/installments/use-installments-selection.js.map +1 -0
  100. package/dist/matter/my-account-profile/my-account-profile.js +5 -5
  101. package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
  102. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +63 -0
  103. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +305 -0
  104. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -0
  105. package/dist/matter/payment/payment-card-capture.d.ts +19 -0
  106. package/dist/matter/payment/payment-card-capture.js +129 -0
  107. package/dist/matter/payment/payment-card-capture.js.map +1 -0
  108. package/dist/matter/payment/payment-controller.d.ts +24 -0
  109. package/dist/matter/payment/payment-controller.js +107 -0
  110. package/dist/matter/payment/payment-controller.js.map +1 -0
  111. package/dist/matter/payment/payment-method-badges.d.ts +57 -0
  112. package/dist/matter/payment/payment-method-badges.js +192 -0
  113. package/dist/matter/payment/payment-method-badges.js.map +1 -0
  114. package/dist/matter/payment/payment.d.ts +89 -0
  115. package/dist/matter/payment/payment.js +263 -0
  116. package/dist/matter/payment/payment.js.map +1 -0
  117. package/dist/matter/payment/use-payment-method-selection.d.ts +302 -0
  118. package/dist/matter/payment/use-payment-method-selection.js +458 -0
  119. package/dist/matter/payment/use-payment-method-selection.js.map +1 -0
  120. package/dist/matter/payment/use-payment-submit-gate.d.ts +111 -0
  121. package/dist/matter/payment/use-payment-submit-gate.js +144 -0
  122. package/dist/matter/payment/use-payment-submit-gate.js.map +1 -0
  123. package/dist/matter/place-order/place-order.d.ts +74 -0
  124. package/dist/matter/place-order/place-order.js +379 -0
  125. package/dist/matter/place-order/place-order.js.map +1 -0
  126. package/dist/matter/product-list/product-list.d.ts +1 -0
  127. package/dist/matter/product-list/product-list.js.map +1 -1
  128. package/dist/matter/product-shelf/product-shelf.d.ts +1 -0
  129. package/dist/matter/product-shelf/product-shelf.js +2 -0
  130. package/dist/matter/product-shelf/product-shelf.js.map +1 -1
  131. package/dist/matter/region/region.js +1 -1
  132. package/dist/matter/region/region.js.map +1 -1
  133. package/dist/matter/save-card/save-card.d.ts +49 -0
  134. package/dist/matter/save-card/save-card.js +188 -0
  135. package/dist/matter/save-card/save-card.js.map +1 -0
  136. package/dist/matter/saved-cards/saved-cards.d.ts +79 -0
  137. package/dist/matter/saved-cards/saved-cards.js +387 -0
  138. package/dist/matter/saved-cards/saved-cards.js.map +1 -0
  139. package/dist/matter/shipping-address/country-descriptors.js +20 -10
  140. package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
  141. package/dist/matter/shipping-address/shipping-address.d.ts +113 -174
  142. package/dist/matter/shipping-address/shipping-address.js +481 -792
  143. package/dist/matter/shipping-address/shipping-address.js.map +1 -1
  144. package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
  145. package/dist/matter/variant-selector/variant-selector.js +1 -1
  146. package/dist/particles/address-summary/address-summary.d.ts +24 -0
  147. package/dist/particles/address-summary/address-summary.js +83 -2
  148. package/dist/particles/address-summary/address-summary.js.map +1 -1
  149. package/dist/particles/alert-dialog/alert-dialog.d.ts +68 -0
  150. package/dist/particles/alert-dialog/alert-dialog.js +187 -0
  151. package/dist/particles/alert-dialog/alert-dialog.js.map +1 -0
  152. package/dist/particles/checkbox/checkbox.d.ts +7 -3
  153. package/dist/particles/checkbox/checkbox.js +4 -1
  154. package/dist/particles/checkbox/checkbox.js.map +1 -1
  155. package/dist/particles/document-field/document-field.d.ts +48 -5
  156. package/dist/particles/document-field/document-field.js +189 -32
  157. package/dist/particles/document-field/document-field.js.map +1 -1
  158. package/dist/particles/field/bound-field-registry.js +52 -0
  159. package/dist/particles/field/bound-field-registry.js.map +1 -0
  160. package/dist/particles/field/field.d.ts +116 -0
  161. package/dist/particles/field/field.js +497 -6
  162. package/dist/particles/field/field.js.map +1 -1
  163. package/dist/particles/fieldset/fieldset.js +2 -2
  164. package/dist/particles/fieldset/fieldset.js.map +1 -1
  165. package/dist/particles/footer-social/footer-social.js +1 -1
  166. package/dist/particles/form/form.d.ts +104 -0
  167. package/dist/particles/form/form.js +485 -0
  168. package/dist/particles/form/form.js.map +1 -0
  169. package/dist/particles/incentives/incentives.js +1 -1
  170. package/dist/particles/phone-field/phone-field.d.ts +38 -10
  171. package/dist/particles/phone-field/phone-field.js +183 -39
  172. package/dist/particles/phone-field/phone-field.js.map +1 -1
  173. package/dist/particles/postal-code-field/postal-code-field.js +2 -2
  174. package/dist/particles/postal-code-field/postal-code-field.js.map +1 -1
  175. package/dist/particles/select/field-select.d.ts +43 -0
  176. package/dist/particles/select/field-select.js +150 -0
  177. package/dist/particles/select/field-select.js.map +1 -0
  178. package/dist/particles/select/select.d.ts +2 -0
  179. package/dist/particles/select/select.js.map +1 -1
  180. package/dist/particles/shared/compose-refs.js +21 -0
  181. package/dist/particles/shared/compose-refs.js.map +1 -0
  182. package/dist/schema.graphql +701 -2
  183. package/dist/sdk/actions/analytics-action-provider.d.ts +15 -0
  184. package/dist/sdk/actions/analytics-action-provider.js +19 -0
  185. package/dist/sdk/actions/analytics-action-provider.js.map +1 -0
  186. package/dist/sdk/actions/cart-action-provider.d.ts +1 -1
  187. package/dist/sdk/actions/cart-action-provider.js +1 -1
  188. package/dist/sdk/actions/cart-action-provider.js.map +1 -1
  189. package/dist/sdk/actions/index.d.ts +3 -1
  190. package/dist/sdk/actions/index.js +3 -1
  191. package/dist/sdk/actions/payment-action-provider.d.ts +22 -0
  192. package/dist/sdk/actions/payment-action-provider.js +26 -0
  193. package/dist/sdk/actions/payment-action-provider.js.map +1 -0
  194. package/dist/sdk/actions/session-action-provider.d.ts +1 -1
  195. package/dist/sdk/actions/session-action-provider.js +1 -1
  196. package/dist/sdk/actions/session-action-provider.js.map +1 -1
  197. package/dist/sdk/actions/shipping-action-provider.d.ts +1 -1
  198. package/dist/sdk/actions/shipping-action-provider.js +1 -1
  199. package/dist/sdk/actions/shipping-action-provider.js.map +1 -1
  200. package/dist/sdk/actions/types.d.ts +6 -2
  201. package/dist/sdk/analytics/analytics-destination.d.ts +43 -0
  202. package/dist/sdk/analytics/analytics-destination.js +90 -0
  203. package/dist/sdk/analytics/analytics-destination.js.map +1 -0
  204. package/dist/sdk/analytics/use-analytics-actions.d.ts +57 -0
  205. package/dist/sdk/analytics/use-analytics-actions.js +108 -0
  206. package/dist/sdk/analytics/use-analytics-actions.js.map +1 -0
  207. package/dist/sdk/cache/storefront-cache.js +1 -1
  208. package/dist/sdk/cache/storefront-cache.js.map +1 -1
  209. package/dist/sdk/cart/operations.d.ts +4 -4
  210. package/dist/sdk/cart/operations.js +1 -1
  211. package/dist/sdk/cart/operations.js.map +1 -1
  212. package/dist/sdk/cart/optimistic.js +1 -1
  213. package/dist/sdk/cart/optimistic.js.map +1 -1
  214. package/dist/sdk/cart/use-cart-actions.d.ts +1 -1
  215. package/dist/sdk/cart/use-cart-actions.js +4 -4
  216. package/dist/sdk/cart/use-cart-actions.js.map +1 -1
  217. package/dist/sdk/cart/use-cart-validate-on-open.js +1 -1
  218. package/dist/sdk/cart/use-cart-validate-on-open.js.map +1 -1
  219. package/dist/sdk/cart/write-gate.js +1 -1
  220. package/dist/sdk/cart/write-gate.js.map +1 -1
  221. package/dist/sdk/data/entity-resolution-context.js +31 -0
  222. package/dist/sdk/data/entity-resolution-context.js.map +1 -0
  223. package/dist/sdk/data/entity-subscriber.js +18 -8
  224. package/dist/sdk/data/entity-subscriber.js.map +1 -1
  225. package/dist/sdk/data/index.js +1 -0
  226. package/dist/sdk/data/page-reactive-data-root.d.ts +38 -2
  227. package/dist/sdk/data/page-reactive-data-root.js +4 -2
  228. package/dist/sdk/data/page-reactive-data-root.js.map +1 -1
  229. package/dist/sdk/data/reactive-data-provider.d.ts +1 -1
  230. package/dist/sdk/data/reactive-data-provider.js +8 -4
  231. package/dist/sdk/data/reactive-data-provider.js.map +1 -1
  232. package/dist/sdk/data/reactive-list-item-data-provider.d.ts +1 -1
  233. package/dist/sdk/data/reactive-list-item-data-provider.js +13 -5
  234. package/dist/sdk/data/reactive-list-item-data-provider.js.map +1 -1
  235. package/dist/sdk/data/use-reactive-data-settled.js +39 -0
  236. package/dist/sdk/data/use-reactive-data-settled.js.map +1 -0
  237. package/dist/sdk/data/use-reactive-entity.js +6 -2
  238. package/dist/sdk/data/use-reactive-entity.js.map +1 -1
  239. package/dist/sdk/generated/fragment-types.js +2 -0
  240. package/dist/sdk/generated/fragment-types.js.map +1 -1
  241. package/dist/sdk/generated/gql.js +2 -1
  242. package/dist/sdk/generated/gql.js.map +1 -1
  243. package/dist/sdk/generated/graphql.js +85 -1
  244. package/dist/sdk/generated/graphql.js.map +1 -1
  245. package/dist/sdk/i18n/messages/en-US.js +3 -0
  246. package/dist/sdk/i18n/messages/en-US.json +3 -0
  247. package/dist/sdk/i18n/messages/en-US.json.d.ts +3 -0
  248. package/dist/sdk/i18n/messages/es-ES.js +3 -0
  249. package/dist/sdk/i18n/messages/es-ES.json +3 -0
  250. package/dist/sdk/i18n/messages/pt-BR.js +3 -0
  251. package/dist/sdk/i18n/messages/pt-BR.json +3 -0
  252. package/dist/sdk/identity/operations.js.map +1 -1
  253. package/dist/sdk/identity/use-identity-actions.d.ts +1 -1
  254. package/dist/sdk/identity/use-identity-actions.js +3 -2
  255. package/dist/sdk/identity/use-identity-actions.js.map +1 -1
  256. package/dist/sdk/payment/gateway-origin.js +35 -0
  257. package/dist/sdk/payment/gateway-origin.js.map +1 -0
  258. package/dist/sdk/payment/gateway.d.ts +85 -0
  259. package/dist/sdk/payment/gateway.js +183 -0
  260. package/dist/sdk/payment/gateway.js.map +1 -0
  261. package/dist/sdk/payment/operations.d.ts +52 -0
  262. package/dist/sdk/payment/operations.js +223 -0
  263. package/dist/sdk/payment/operations.js.map +1 -0
  264. package/dist/sdk/payment/security-code-mask.js +71 -0
  265. package/dist/sdk/payment/security-code-mask.js.map +1 -0
  266. package/dist/sdk/payment/submission-registry.d.ts +33 -0
  267. package/dist/sdk/payment/submission-registry.js +58 -0
  268. package/dist/sdk/payment/submission-registry.js.map +1 -0
  269. package/dist/sdk/payment/use-payment-actions.d.ts +78 -0
  270. package/dist/sdk/payment/use-payment-actions.js +276 -0
  271. package/dist/sdk/payment/use-payment-actions.js.map +1 -0
  272. package/dist/sdk/payment/use-place-order.d.ts +65 -0
  273. package/dist/sdk/payment/use-place-order.js +640 -0
  274. package/dist/sdk/payment/use-place-order.js.map +1 -0
  275. package/dist/sdk/session/auth-operations.d.ts +1 -1
  276. package/dist/sdk/session/auth-operations.js.map +1 -1
  277. package/dist/sdk/session/use-session-actions.d.ts +1 -1
  278. package/dist/sdk/session/use-session-actions.js.map +1 -1
  279. package/dist/sdk/session/use-session-revalidation.js +65 -0
  280. package/dist/sdk/session/use-session-revalidation.js.map +1 -0
  281. package/dist/sdk/shipping/option-select-operations.d.ts +1 -1
  282. package/dist/sdk/shipping/option-select-operations.js.map +1 -1
  283. package/dist/sdk/shipping/request-timeout.js +1 -1
  284. package/dist/sdk/shipping/request-timeout.js.map +1 -1
  285. package/dist/sdk/shipping/shipping-operations.d.ts +1 -1
  286. package/dist/sdk/shipping/shipping-operations.js.map +1 -1
  287. package/dist/sdk/shipping/use-shipping-actions.d.ts +2 -2
  288. package/dist/sdk/shipping/use-shipping-actions.js +1 -1
  289. package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
  290. package/dist/sdk/state/cart.d.ts +3 -4
  291. package/dist/sdk/state/cart.js +6 -7
  292. package/dist/sdk/state/cart.js.map +1 -1
  293. package/dist/utils/loggable-error-name.js +49 -0
  294. package/dist/utils/loggable-error-name.js.map +1 -0
  295. package/dist/utils/resolve-authored-copy.js +18 -0
  296. package/dist/utils/resolve-authored-copy.js.map +1 -0
  297. package/dist/utils/safe-href.js +3 -3
  298. package/dist/utils/safe-href.js.map +1 -1
  299. package/dist/utils/substitute-template.js +33 -0
  300. package/dist/utils/substitute-template.js.map +1 -0
  301. package/package.json +2 -1
  302. package/src/styles/tailwind.css +34 -0
  303. package/dist/docs/client-profile-form.md +0 -192
  304. package/dist/matter/client-profile-form/client-profile-form.d.ts +0 -126
  305. package/dist/matter/client-profile-form/client-profile-form.js +0 -662
  306. package/dist/matter/client-profile-form/client-profile-form.js.map +0 -1
@@ -0,0 +1,223 @@
1
+ import { gql } from "../graphql-tag.js";
2
+ import { CartFragment } from "../cart/operations.js";
3
+ //#region src/sdk/payment/operations.ts
4
+ /**
5
+ * The one client-synthesized error code, carried by the userError every mutation-backed method
6
+ * *resolves* (never throws) when its mutation fails at the transport or top-level-GraphQL layer.
7
+ * `gateway.ts` owns the separate code for a failed gateway leg (Decision 7).
8
+ */
9
+ const PAYMENT_NETWORK_ERROR_CODE = "NETWORK_ERROR";
10
+ /**
11
+ * The canonical `Payment` selection set, spread by every selection mutation so one response
12
+ * re-normalizes the whole entity and every reactive subscriber re-renders with no refetch — the
13
+ * payload-completeness invariant writes must honor (ADR-0010). Selecting the entire entity mirrors
14
+ * `CartFragment` and `SHIPPING_ADDRESS_UPDATE`'s full-`Shipping` selection: the method list (T5), the
15
+ * validator config (T7), `installmentOptions` (T9), and the summary's selection fields (T6) are all
16
+ * subscribed independently, and a partial selection would leave one of them incomplete.
17
+ */
18
+ const PaymentFragment = gql`
19
+ fragment PaymentFragment on Payment {
20
+ __typename
21
+ id
22
+ selectedMethodId
23
+ selectedAccountId
24
+ selectedBin
25
+ selectedInstallment {
26
+ __typename
27
+ count
28
+ value {
29
+ amount
30
+ currencyCode
31
+ }
32
+ total {
33
+ amount
34
+ currencyCode
35
+ }
36
+ interestRate
37
+ }
38
+ installmentOptions {
39
+ __typename
40
+ methodId
41
+ bin
42
+ baseValue {
43
+ amount
44
+ currencyCode
45
+ }
46
+ installments {
47
+ __typename
48
+ count
49
+ value {
50
+ amount
51
+ currencyCode
52
+ }
53
+ total {
54
+ amount
55
+ currencyCode
56
+ }
57
+ interestRate
58
+ }
59
+ }
60
+ methods {
61
+ __typename
62
+ id
63
+ name
64
+ groupName
65
+ validator {
66
+ __typename
67
+ numberMask
68
+ numberRegex
69
+ cvvMask
70
+ cvvRegex
71
+ cvvRequired
72
+ expirationRequired
73
+ holderNameRequired
74
+ billingAddressRequired
75
+ documentDisplayable
76
+ documentRequired
77
+ }
78
+ }
79
+ savedCards {
80
+ __typename
81
+ id
82
+ accountId
83
+ methodId
84
+ network
85
+ lastFourDigits
86
+ bin
87
+ label
88
+ expired
89
+ cvvRequired
90
+ }
91
+ }
92
+ `;
93
+ /** The billing-address echo, spread by the three selection mutations that return one. */
94
+ const PaymentBillingAddressFragment = gql`
95
+ fragment PaymentBillingAddressFragment on Address {
96
+ __typename
97
+ id
98
+ recipientName
99
+ postalCode
100
+ country
101
+ street
102
+ number
103
+ complement
104
+ neighborhood
105
+ city
106
+ state
107
+ }
108
+ `;
109
+ const PAYMENT_METHOD_SELECT = gql`
110
+ mutation PaymentMethodSelect($input: PaymentMethodSelectInput!) {
111
+ paymentMethodSelect(input: $input) {
112
+ __typename
113
+ payment {
114
+ ...PaymentFragment
115
+ }
116
+ billingAddress {
117
+ ...PaymentBillingAddressFragment
118
+ }
119
+ userErrors {
120
+ code
121
+ message
122
+ }
123
+ }
124
+ }
125
+ ${PaymentFragment}
126
+ ${PaymentBillingAddressFragment}
127
+ `;
128
+ /**
129
+ * Selects `cart { ...CartFragment }` alongside `payment` so the interest-inclusive order total lands
130
+ * in the normalized cache in the same round trip (REQ-03) — the same reason `shippingOptionSelect`
131
+ * selects the cart.
132
+ */
133
+ const PAYMENT_INSTALLMENT_SELECT = gql`
134
+ mutation PaymentInstallmentSelect($input: PaymentInstallmentSelectInput!) {
135
+ paymentInstallmentSelect(input: $input) {
136
+ __typename
137
+ payment {
138
+ ...PaymentFragment
139
+ }
140
+ cart {
141
+ ...CartFragment
142
+ }
143
+ billingAddress {
144
+ ...PaymentBillingAddressFragment
145
+ }
146
+ userErrors {
147
+ code
148
+ message
149
+ }
150
+ }
151
+ }
152
+ ${PaymentFragment}
153
+ ${PaymentBillingAddressFragment}
154
+ ${CartFragment}
155
+ `;
156
+ const PAYMENT_BILLING_ADDRESS_UPDATE = gql`
157
+ mutation PaymentBillingAddressUpdate($input: PaymentBillingAddressUpdateInput!) {
158
+ paymentBillingAddressUpdate(input: $input) {
159
+ __typename
160
+ billingAddress {
161
+ ...PaymentBillingAddressFragment
162
+ }
163
+ payment {
164
+ ...PaymentFragment
165
+ }
166
+ userErrors {
167
+ code
168
+ message
169
+ }
170
+ }
171
+ }
172
+ ${PaymentFragment}
173
+ ${PaymentBillingAddressFragment}
174
+ `;
175
+ /**
176
+ * Takes no input: every field VTEX's transaction endpoint needs is derived server-side from the
177
+ * already-persisted selection (T3 Decision 9). The transaction cookies it mints ride on the HTTP
178
+ * response, not on the payload.
179
+ *
180
+ * `merchantName`, `gatewayUrl`, `valueInCents`, and `referenceValueInCents` are T18's additions
181
+ * (specs/payment-transaction-payload-gaps.md), selected here by T13: `PaymentGatewayTransaction`
182
+ * requires all four, so the descriptor cannot be assembled without them. `value` stays selected
183
+ * beside the minor-unit pair — it is the display decimal, and the `purchase` analytics event reports
184
+ * it rather than a client-side division.
185
+ */
186
+ const PAYMENT_START_TRANSACTION = gql`
187
+ mutation PaymentStartTransaction {
188
+ paymentStartTransaction {
189
+ __typename
190
+ transactionId
191
+ merchantName
192
+ gatewayUrl
193
+ orderGroup
194
+ userProfileId
195
+ value {
196
+ amount
197
+ currencyCode
198
+ }
199
+ valueInCents
200
+ referenceValueInCents
201
+ userErrors {
202
+ code
203
+ message
204
+ }
205
+ }
206
+ }
207
+ `;
208
+ const PAYMENT_GATEWAY_CALLBACK = gql`
209
+ mutation PaymentGatewayCallback($input: PaymentGatewayCallbackInput!) {
210
+ paymentGatewayCallback(input: $input) {
211
+ __typename
212
+ orderId
213
+ userErrors {
214
+ code
215
+ message
216
+ }
217
+ }
218
+ }
219
+ `;
220
+ //#endregion
221
+ export { PAYMENT_BILLING_ADDRESS_UPDATE, PAYMENT_GATEWAY_CALLBACK, PAYMENT_INSTALLMENT_SELECT, PAYMENT_METHOD_SELECT, PAYMENT_NETWORK_ERROR_CODE, PAYMENT_START_TRANSACTION, PaymentBillingAddressFragment, PaymentFragment };
222
+
223
+ //# sourceMappingURL=operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations.js","names":[],"sources":["../../../src/sdk/payment/operations.ts"],"sourcesContent":["import type { TypedDocumentNode } from '@apollo/client';\nimport { type CartEntity, CartFragment } from '../cart/operations.js';\nimport { gql } from '../graphql-tag.js';\n\n/**\n * Payment write-model GraphQL operations (specs/payment-action-namespace.md, T4) — the five mutations\n * `api-module:PaymentWriteModel` shipped (T3, `checkout/schema.graphql` § 11). Nothing here is\n * invented: every mutation, input field, and payload field is pinned to that schema.\n *\n * Authored with the hand `gql` tag — the codegen `graphql()` factory is reserved for the reactive read\n * path — and excluded from the codegen `documents` glob (see `codegen.ts`): the `gql` tag alone is\n * still plucked by `graphql-codegen`, which would duplicate these hand-written types in\n * `sdk/generated/`. Mirrors `shipping/option-select-operations.ts` and `identity/operations.ts`.\n *\n * No field at any nesting depth carries a card number or CVV — the read model guarantees it (RFC D13),\n * and the one call that does carry them never touches GraphQL at all (see `gateway.ts`).\n *\n * Failures follow ADR-00007's two-path contract: domain outcomes arrive as payload `userErrors`;\n * transport and top-level GraphQL failures are infrastructure, collapsed by the handlers in\n * `use-payment-actions.ts` to the one client-synthesized code, `PAYMENT_NETWORK_ERROR_CODE`.\n */\n\n// ---------------------------------------------------------------------------\n// Domain types — mirror the shipped checkout schema\n// ---------------------------------------------------------------------------\n\n/** A payment domain error. Every mutation's error type is `{ code, message }`; codes stay strings. */\nexport type PaymentUserError = Readonly<{ code: string; message: string }>;\n\n/**\n * The one client-synthesized error code, carried by the userError every mutation-backed method\n * *resolves* (never throws) when its mutation fails at the transport or top-level-GraphQL layer.\n * `gateway.ts` owns the separate code for a failed gateway leg (Decision 7).\n */\nexport const PAYMENT_NETWORK_ERROR_CODE = 'NETWORK_ERROR';\n\nexport type PaymentMoney = Readonly<{ __typename?: 'Money'; amount: number; currencyCode: string }>;\n\ntype PaymentInstallmentEntity = Readonly<{\n __typename?: 'PaymentInstallment';\n count: number;\n value: PaymentMoney;\n total: PaymentMoney;\n interestRate: number;\n}>;\n\ntype PaymentMethodValidatorEntity = Readonly<{\n __typename?: 'PaymentMethodValidator';\n numberMask: string | null;\n numberRegex: string | null;\n cvvMask: string | null;\n cvvRegex: string | null;\n cvvRequired: boolean;\n expirationRequired: boolean;\n holderNameRequired: boolean;\n billingAddressRequired: boolean;\n documentDisplayable: boolean;\n documentRequired: boolean;\n}>;\n\ntype PaymentMethodEntity = Readonly<{\n __typename?: 'PaymentMethod';\n id: string;\n name: string;\n groupName: string;\n validator: PaymentMethodValidatorEntity;\n}>;\n\ntype PaymentInstallmentOptionEntity = Readonly<{\n __typename?: 'PaymentInstallmentOption';\n methodId: string;\n bin: string | null;\n baseValue: PaymentMoney;\n installments: readonly PaymentInstallmentEntity[];\n}>;\n\ntype SavedCardEntity = Readonly<{\n __typename?: 'SavedCard';\n id: string;\n accountId: string;\n methodId: string;\n network: string;\n lastFourDigits: string;\n bin: string;\n label: string | null;\n expired: boolean;\n cvvRequired: boolean;\n}>;\n\n/** The full `Payment` entity every selection mutation echoes back. Never carries a PAN or CVV. */\nexport type PaymentEntity = Readonly<{\n __typename?: 'Payment';\n id: string;\n methods: readonly PaymentMethodEntity[];\n selectedMethodId: string | null;\n selectedAccountId: string | null;\n selectedBin: string | null;\n selectedInstallment: PaymentInstallmentEntity | null;\n installmentOptions: readonly PaymentInstallmentOptionEntity[];\n savedCards: readonly SavedCardEntity[];\n}>;\n\n/** The billing-address echo on the selection payloads — the schema's shared `Address` type. */\nexport type PaymentBillingAddressEntity = Readonly<{\n __typename?: 'Address';\n id: string | null;\n recipientName: string | null;\n postalCode: string | null;\n country: string;\n street: string | null;\n number: string | null;\n complement: string | null;\n neighborhood: string | null;\n city: string | null;\n state: string | null;\n}>;\n\n// ---------------------------------------------------------------------------\n// Mutation inputs — mirror the schema's input types verbatim\n// ---------------------------------------------------------------------------\n\n/** A `bin` with an `accountId` is validated against the saved card's own BIN (MISMATCHED_BIN_FOR_SAVED_CARD). */\nexport type PaymentMethodSelectInput = Readonly<{ methodId: string; bin?: string; accountId?: string }>;\n\nexport type PaymentInstallmentSelectInput = Readonly<{ count: number }>;\n\n/** With `sameAsDelivery: true` every other field is ignored and the server performs no upstream write. */\nexport type PaymentBillingAddressUpdateInput = Readonly<{\n sameAsDelivery: boolean;\n addressType?: string;\n postalCode?: string;\n country?: string;\n street?: string;\n number?: string;\n complement?: string;\n neighborhood?: string;\n city?: string;\n state?: string;\n reference?: string;\n}>;\n\nexport type PaymentGatewayCallbackInput = Readonly<{ orderGroup: string }>;\n\n// ---------------------------------------------------------------------------\n// Shared fragment\n// ---------------------------------------------------------------------------\n\n/**\n * The canonical `Payment` selection set, spread by every selection mutation so one response\n * re-normalizes the whole entity and every reactive subscriber re-renders with no refetch — the\n * payload-completeness invariant writes must honor (ADR-0010). Selecting the entire entity mirrors\n * `CartFragment` and `SHIPPING_ADDRESS_UPDATE`'s full-`Shipping` selection: the method list (T5), the\n * validator config (T7), `installmentOptions` (T9), and the summary's selection fields (T6) are all\n * subscribed independently, and a partial selection would leave one of them incomplete.\n */\nexport const PaymentFragment = gql`\n fragment PaymentFragment on Payment {\n __typename\n id\n selectedMethodId\n selectedAccountId\n selectedBin\n selectedInstallment {\n __typename\n count\n value {\n amount\n currencyCode\n }\n total {\n amount\n currencyCode\n }\n interestRate\n }\n installmentOptions {\n __typename\n methodId\n bin\n baseValue {\n amount\n currencyCode\n }\n installments {\n __typename\n count\n value {\n amount\n currencyCode\n }\n total {\n amount\n currencyCode\n }\n interestRate\n }\n }\n methods {\n __typename\n id\n name\n groupName\n validator {\n __typename\n numberMask\n numberRegex\n cvvMask\n cvvRegex\n cvvRequired\n expirationRequired\n holderNameRequired\n billingAddressRequired\n documentDisplayable\n documentRequired\n }\n }\n savedCards {\n __typename\n id\n accountId\n methodId\n network\n lastFourDigits\n bin\n label\n expired\n cvvRequired\n }\n }\n`;\n\n/** The billing-address echo, spread by the three selection mutations that return one. */\nexport const PaymentBillingAddressFragment = gql`\n fragment PaymentBillingAddressFragment on Address {\n __typename\n id\n recipientName\n postalCode\n country\n street\n number\n complement\n neighborhood\n city\n state\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Mutation operations\n// ---------------------------------------------------------------------------\n\ntype PaymentMethodSelectMutation = Readonly<{\n paymentMethodSelect: Readonly<{\n __typename?: 'PaymentMethodSelectPayload';\n payment: PaymentEntity | null;\n billingAddress: PaymentBillingAddressEntity | null;\n userErrors: readonly PaymentUserError[];\n }>;\n}>;\n\nexport const PAYMENT_METHOD_SELECT: TypedDocumentNode<\n PaymentMethodSelectMutation,\n Readonly<{ input: PaymentMethodSelectInput }>\n> = gql`\n mutation PaymentMethodSelect($input: PaymentMethodSelectInput!) {\n paymentMethodSelect(input: $input) {\n __typename\n payment {\n ...PaymentFragment\n }\n billingAddress {\n ...PaymentBillingAddressFragment\n }\n userErrors {\n code\n message\n }\n }\n }\n ${PaymentFragment}\n ${PaymentBillingAddressFragment}\n`;\n\ntype PaymentInstallmentSelectMutation = Readonly<{\n paymentInstallmentSelect: Readonly<{\n __typename?: 'PaymentInstallmentSelectPayload';\n payment: PaymentEntity | null;\n cart: CartEntity | null;\n billingAddress: PaymentBillingAddressEntity | null;\n userErrors: readonly PaymentUserError[];\n }>;\n}>;\n\n/**\n * Selects `cart { ...CartFragment }` alongside `payment` so the interest-inclusive order total lands\n * in the normalized cache in the same round trip (REQ-03) — the same reason `shippingOptionSelect`\n * selects the cart.\n */\nexport const PAYMENT_INSTALLMENT_SELECT: TypedDocumentNode<\n PaymentInstallmentSelectMutation,\n Readonly<{ input: PaymentInstallmentSelectInput }>\n> = gql`\n mutation PaymentInstallmentSelect($input: PaymentInstallmentSelectInput!) {\n paymentInstallmentSelect(input: $input) {\n __typename\n payment {\n ...PaymentFragment\n }\n cart {\n ...CartFragment\n }\n billingAddress {\n ...PaymentBillingAddressFragment\n }\n userErrors {\n code\n message\n }\n }\n }\n ${PaymentFragment}\n ${PaymentBillingAddressFragment}\n ${CartFragment}\n`;\n\ntype PaymentBillingAddressUpdateMutation = Readonly<{\n paymentBillingAddressUpdate: Readonly<{\n __typename?: 'PaymentBillingAddressUpdatePayload';\n billingAddress: PaymentBillingAddressEntity | null;\n payment: PaymentEntity | null;\n userErrors: readonly PaymentUserError[];\n }>;\n}>;\n\nexport const PAYMENT_BILLING_ADDRESS_UPDATE: TypedDocumentNode<\n PaymentBillingAddressUpdateMutation,\n Readonly<{ input: PaymentBillingAddressUpdateInput }>\n> = gql`\n mutation PaymentBillingAddressUpdate($input: PaymentBillingAddressUpdateInput!) {\n paymentBillingAddressUpdate(input: $input) {\n __typename\n billingAddress {\n ...PaymentBillingAddressFragment\n }\n payment {\n ...PaymentFragment\n }\n userErrors {\n code\n message\n }\n }\n }\n ${PaymentFragment}\n ${PaymentBillingAddressFragment}\n`;\n\ntype PaymentStartTransactionMutation = Readonly<{\n paymentStartTransaction: Readonly<{\n __typename?: 'PaymentStartTransactionPayload';\n transactionId: string | null;\n merchantName: string | null;\n gatewayUrl: string | null;\n orderGroup: string | null;\n userProfileId: string | null;\n value: PaymentMoney | null;\n valueInCents: number | null;\n referenceValueInCents: number | null;\n userErrors: readonly PaymentUserError[];\n }>;\n}>;\n\n/**\n * Takes no input: every field VTEX's transaction endpoint needs is derived server-side from the\n * already-persisted selection (T3 Decision 9). The transaction cookies it mints ride on the HTTP\n * response, not on the payload.\n *\n * `merchantName`, `gatewayUrl`, `valueInCents`, and `referenceValueInCents` are T18's additions\n * (specs/payment-transaction-payload-gaps.md), selected here by T13: `PaymentGatewayTransaction`\n * requires all four, so the descriptor cannot be assembled without them. `value` stays selected\n * beside the minor-unit pair — it is the display decimal, and the `purchase` analytics event reports\n * it rather than a client-side division.\n */\nexport const PAYMENT_START_TRANSACTION: TypedDocumentNode<PaymentStartTransactionMutation, Record<string, never>> = gql`\n mutation PaymentStartTransaction {\n paymentStartTransaction {\n __typename\n transactionId\n merchantName\n gatewayUrl\n orderGroup\n userProfileId\n value {\n amount\n currencyCode\n }\n valueInCents\n referenceValueInCents\n userErrors {\n code\n message\n }\n }\n }\n`;\n\ntype PaymentGatewayCallbackMutation = Readonly<{\n paymentGatewayCallback: Readonly<{\n __typename?: 'PaymentGatewayCallbackPayload';\n orderId: string | null;\n userErrors: readonly PaymentUserError[];\n }>;\n}>;\n\nexport const PAYMENT_GATEWAY_CALLBACK: TypedDocumentNode<\n PaymentGatewayCallbackMutation,\n Readonly<{ input: PaymentGatewayCallbackInput }>\n> = gql`\n mutation PaymentGatewayCallback($input: PaymentGatewayCallbackInput!) {\n paymentGatewayCallback(input: $input) {\n __typename\n orderId\n userErrors {\n code\n message\n }\n }\n }\n`;\n"],"mappings":";;;;;;;;AAkCA,MAAa,6BAA6B;;;;;;;;;AAyH1C,MAAa,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6ElC,MAAa,gCAAgC,GAAG;;;;;;;;;;;;;;;AA6BhD,MAAa,wBAGT,GAAG;;;;;;;;;;;;;;;;IAgBH,gBAAgB;IAChB,8BAA8B;;;;;;;AAkBlC,MAAa,6BAGT,GAAG;;;;;;;;;;;;;;;;;;;IAmBH,gBAAgB;IAChB,8BAA8B;IAC9B,aAAa;;AAYjB,MAAa,iCAGT,GAAG;;;;;;;;;;;;;;;;IAgBH,gBAAgB;IAChB,8BAA8B;;;;;;;;;;;;;AA6BlC,MAAa,4BAAuG,GAAG;;;;;;;;;;;;;;;;;;;;;;AA+BvH,MAAa,2BAGT,GAAG"}
@@ -0,0 +1,71 @@
1
+ //#region src/sdk/payment/security-code-mask.ts
2
+ /**
3
+ * The security-code masking mechanism (specs/choose-a-security-code-masking-mechanism.md, T101 of
4
+ * the Credit Card epic; docs/features/credit-card/rfc.md § D13). One shared constant for the two
5
+ * inputs that hold a security code — `CardEntry`'s `cvv` field and `SavedCardCvvField`'s CVV
6
+ * re-entry field — so the two call sites cannot drift on the mechanism.
7
+ *
8
+ * Why this and not `type="password"`: T70 shipped `type="password"` on both fields and it made real
9
+ * Chrome offer a "Save password?" prompt on the new-card form — pairing the expiration date as a
10
+ * fake *Username* and the security code as *Password*, and offering to store it in Google Password
11
+ * Manager, synced to the signed-in account. PCI-DSS forbids retaining the security code past
12
+ * authorization, and a cloud-synced credential vault is a strictly worse posture than the field's
13
+ * pre-T70 baseline. `type="password"` was reverted; both fields ship `type="text"`.
14
+ *
15
+ * `-webkit-text-security: disc` obscures the digits on screen without touching `type`, so the
16
+ * heuristic that triggered the prompt (keyed off `type="password"` fields in the form) never fires —
17
+ * settled by the 2026-08-24 unblock ruling through measurement in real Chrome, not documentation.
18
+ * Applied as an **element inline style**, never a stylesheet the package ships (forbidden by
19
+ * ADR-0007's Consequences, `:104`) and never a class a store authors (defeatable by any compound
20
+ * swatch) — an inline declaration is the one CSS route that is both within the architecture rule and
21
+ * outside the store's reach, and it outranks every class-based rule at normal importance.
22
+ *
23
+ * This closes the password-manager capture surface structurally — it does not mean the code never
24
+ * leaves the browser by any path. `CardEntry`'s CVV keeps `autoComplete="cc-csc"` (FR-5, unchanged by
25
+ * this task): the exact token Chrome's own Autofill uses to classify the field as
26
+ * `CREDIT_CARD_VERIFICATION_CODE`, and Chrome ships CVC storage (`AutofillEnableCvcStorageAndFilling`)
27
+ * that retains the CVC beside a saved server card and syncs it to the signed-in Google account. This
28
+ * mechanism does not close that path and is not trying to — it is the separate *card* vault the field
29
+ * honestly declares itself to via `autoComplete`, not the credential vault this change removes (spec
30
+ * § Verification, G1(d)).
31
+ *
32
+ * `WebkitTextSecurity` is asserted `as CSSProperties` because csstype 3.2.3 declares no such key —
33
+ * mirrors the existing assertion in `variant-selector.tsx`. The property is standardized nowhere;
34
+ * supported in Chromium and WebKit (and Firefox 114+, per T70's spec). An engine without it renders
35
+ * exactly what ships today — not a regression.
36
+ *
37
+ * Defined once at module scope so the object is referentially stable and React's style diffing never
38
+ * has work to do on re-render.
39
+ */
40
+ const SECURITY_CODE_MASK_STYLE = Object.freeze({ WebkitTextSecurity: "disc" });
41
+ /**
42
+ * Whether the security code is fully typed — the moment `SECURITY_CODE_MASK_STYLE` above starts
43
+ * applying (specs/mask-the-cvv-only-once-it.md, T173). Until then the field renders its digits in
44
+ * the clear, so a shopper can read back what they just typed and catch a typo; from then on it
45
+ * renders exactly as it did when the mask was unconditional. The mechanism is untouched; only its
46
+ * timing moves. Never on blur, never after a delay: the mask engages on the keystroke that completes
47
+ * the code.
48
+ *
49
+ * `expectedLength` is passed in because the two fields resolve it from different places and neither
50
+ * belongs in this module: `CardEntry` takes the detected network's `cvvMask` (three digits for most
51
+ * networks, four for Amex), while `SavedCardCvvField` has no per-network length at all and uses its
52
+ * own three-or-four-digit floor. Resolving it here would mean knowing about payment-method validators
53
+ * and saved-card rows, and would still leave the comparison itself free to drift between the two.
54
+ *
55
+ * Both callers resolve a *floor*, and a ceiling would be a defect rather than a variation: whatever
56
+ * length arrives here is the length at which digits stop being legible, so the widest of several
57
+ * possible lengths leaves a code that is already complete for a shorter one readable for the rest of
58
+ * the flow.
59
+ *
60
+ * Derived from the value on every render, with no state and no timer. That is what makes the render
61
+ * which first holds a complete code already the masked one — so a paste delivering every digit in one
62
+ * event opens no legible frame — lets a cleared field unmask with nothing to reset, and leaves a code
63
+ * the shopper backspaces into legible again while they correct it.
64
+ */
65
+ function isSecurityCodeComplete(value, expectedLength) {
66
+ return value.length > 0 && value.length >= expectedLength;
67
+ }
68
+ //#endregion
69
+ export { SECURITY_CODE_MASK_STYLE, isSecurityCodeComplete };
70
+
71
+ //# sourceMappingURL=security-code-mask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-code-mask.js","names":[],"sources":["../../../src/sdk/payment/security-code-mask.ts"],"sourcesContent":["import type { CSSProperties } from 'react';\n\n/**\n * The security-code masking mechanism (specs/choose-a-security-code-masking-mechanism.md, T101 of\n * the Credit Card epic; docs/features/credit-card/rfc.md § D13). One shared constant for the two\n * inputs that hold a security code — `CardEntry`'s `cvv` field and `SavedCardCvvField`'s CVV\n * re-entry field — so the two call sites cannot drift on the mechanism.\n *\n * Why this and not `type=\"password\"`: T70 shipped `type=\"password\"` on both fields and it made real\n * Chrome offer a \"Save password?\" prompt on the new-card form — pairing the expiration date as a\n * fake *Username* and the security code as *Password*, and offering to store it in Google Password\n * Manager, synced to the signed-in account. PCI-DSS forbids retaining the security code past\n * authorization, and a cloud-synced credential vault is a strictly worse posture than the field's\n * pre-T70 baseline. `type=\"password\"` was reverted; both fields ship `type=\"text\"`.\n *\n * `-webkit-text-security: disc` obscures the digits on screen without touching `type`, so the\n * heuristic that triggered the prompt (keyed off `type=\"password\"` fields in the form) never fires —\n * settled by the 2026-08-24 unblock ruling through measurement in real Chrome, not documentation.\n * Applied as an **element inline style**, never a stylesheet the package ships (forbidden by\n * ADR-0007's Consequences, `:104`) and never a class a store authors (defeatable by any compound\n * swatch) — an inline declaration is the one CSS route that is both within the architecture rule and\n * outside the store's reach, and it outranks every class-based rule at normal importance.\n *\n * This closes the password-manager capture surface structurally — it does not mean the code never\n * leaves the browser by any path. `CardEntry`'s CVV keeps `autoComplete=\"cc-csc\"` (FR-5, unchanged by\n * this task): the exact token Chrome's own Autofill uses to classify the field as\n * `CREDIT_CARD_VERIFICATION_CODE`, and Chrome ships CVC storage (`AutofillEnableCvcStorageAndFilling`)\n * that retains the CVC beside a saved server card and syncs it to the signed-in Google account. This\n * mechanism does not close that path and is not trying to — it is the separate *card* vault the field\n * honestly declares itself to via `autoComplete`, not the credential vault this change removes (spec\n * § Verification, G1(d)).\n *\n * `WebkitTextSecurity` is asserted `as CSSProperties` because csstype 3.2.3 declares no such key —\n * mirrors the existing assertion in `variant-selector.tsx`. The property is standardized nowhere;\n * supported in Chromium and WebKit (and Firefox 114+, per T70's spec). An engine without it renders\n * exactly what ships today — not a regression.\n *\n * Defined once at module scope so the object is referentially stable and React's style diffing never\n * has work to do on re-render.\n */\nexport const SECURITY_CODE_MASK_STYLE: CSSProperties = Object.freeze({ WebkitTextSecurity: 'disc' }) as CSSProperties;\n\n/**\n * Whether the security code is fully typed — the moment `SECURITY_CODE_MASK_STYLE` above starts\n * applying (specs/mask-the-cvv-only-once-it.md, T173). Until then the field renders its digits in\n * the clear, so a shopper can read back what they just typed and catch a typo; from then on it\n * renders exactly as it did when the mask was unconditional. The mechanism is untouched; only its\n * timing moves. Never on blur, never after a delay: the mask engages on the keystroke that completes\n * the code.\n *\n * `expectedLength` is passed in because the two fields resolve it from different places and neither\n * belongs in this module: `CardEntry` takes the detected network's `cvvMask` (three digits for most\n * networks, four for Amex), while `SavedCardCvvField` has no per-network length at all and uses its\n * own three-or-four-digit floor. Resolving it here would mean knowing about payment-method validators\n * and saved-card rows, and would still leave the comparison itself free to drift between the two.\n *\n * Both callers resolve a *floor*, and a ceiling would be a defect rather than a variation: whatever\n * length arrives here is the length at which digits stop being legible, so the widest of several\n * possible lengths leaves a code that is already complete for a shorter one readable for the rest of\n * the flow.\n *\n * Derived from the value on every render, with no state and no timer. That is what makes the render\n * which first holds a complete code already the masked one — so a paste delivering every digit in one\n * event opens no legible frame — lets a cleared field unmask with nothing to reset, and leaves a code\n * the shopper backspaces into legible again while they correct it.\n */\nexport function isSecurityCodeComplete(value: string, expectedLength: number): boolean {\n // The length guard is not redundant with `>=`: a store-configured empty `cvvMask` resolves to a\n // zero expected length, which on its own would read an untouched field as fully typed.\n return value.length > 0 && value.length >= expectedLength;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,MAAa,2BAA0C,OAAO,OAAO,EAAE,oBAAoB,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;AA0BnG,SAAgB,uBAAuB,OAAe,gBAAiC;CAGrF,OAAO,MAAM,SAAS,KAAK,MAAM,UAAU;AAC7C"}
@@ -0,0 +1,33 @@
1
+ import "./operations.js";
2
+ import "./gateway.js";
3
+ import { ReactNode } from "react";
4
+ //#region src/sdk/payment/submission-registry.d.ts
5
+ /**
6
+ * The card-data submission channel (specs/use-place-order.md, Decision 1; specs/epics/credit-card.md
7
+ * § "The card-data submission channel"). **The holder submits; the orchestrator never holds.**
8
+ *
9
+ * T7 (new card) and T12 (saved card) each register a submit-time continuation here. Each closes over
10
+ * its own card fields, builds the gateway card object inside that closure, calls
11
+ * `$actions.payment.sendPayments` itself, and returns only the gateway leg's `userErrors`. T13's
12
+ * `usePlaceOrder` resolves one by `path` and invokes it between start-transaction and
13
+ * gateway-callback, so no card-shaped field appears anywhere in this channel's type signature.
14
+ *
15
+ * It is a *second*, narrow context beside T5's `payment` context rather than a field on it, because
16
+ * the two have different shapes and different readers: `draft` is render state every leaf reads, this
17
+ * is an imperative registry exactly two components write and one hook reads. Registration is a
18
+ * ref-held `Map`, not state — T7 re-registers a fresh closure on every keystroke, and making that a
19
+ * render would re-render the whole payment section per character.
20
+ *
21
+ * Values that are **not** sensitive travel on T5's `draft`, never here: the save-card flag and label
22
+ * (T10), the cardholder document (T8), and the billing-address-differs flag (T11). The holder folds
23
+ * them into the card object inside its own closure.
24
+ *
25
+ * This module lives in the SDK rather than beside T5's roots so the layering stays `matter → sdk`:
26
+ * `usePlaceOrder` is an SDK hook and cannot import from `matter/`. "Provided by T5's root" means the
27
+ * root renders `PaymentSubmissionProvider`, which it does — both of them, for the same ADR-0009
28
+ * reason the `payment` context has two providers.
29
+ */
30
+ /** Which entry path a submission serves. The canonical key type; T5's `PaymentPath` aliases it. */
31
+ export type PaymentSubmissionPath = 'new-card' | 'saved-card';
32
+ //#endregion
33
+ //# sourceMappingURL=submission-registry.d.ts.map
@@ -0,0 +1,58 @@
1
+ "use client";
2
+ import { createContext, useContext, useEffect, useMemo, useRef } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/sdk/payment/submission-registry.tsx
5
+ const SUBMISSION_CONTEXT_UNSET = Symbol("PaymentSubmissionContextUnset");
6
+ const PaymentSubmissionContext = createContext(SUBMISSION_CONTEXT_UNSET);
7
+ /** Rendered by `PaymentSectionRoot` and `PaymentSectionController` around the section composition. */
8
+ function PaymentSubmissionProvider({ path, children }) {
9
+ const submissions = useRef(/* @__PURE__ */ new Map());
10
+ const channel = useMemo(() => ({
11
+ path,
12
+ register: (registeredPath, submit, preflight) => {
13
+ submissions.current.set(registeredPath, {
14
+ submit,
15
+ preflight: preflight ?? null
16
+ });
17
+ return () => {
18
+ if (submissions.current.get(registeredPath)?.submit === submit) submissions.current.delete(registeredPath);
19
+ };
20
+ },
21
+ resolve: (registeredPath) => submissions.current.get(registeredPath)?.submit ?? null,
22
+ resolvePreflight: (registeredPath) => submissions.current.get(registeredPath)?.preflight ?? null
23
+ }), [path]);
24
+ return /* @__PURE__ */ jsx(PaymentSubmissionContext, {
25
+ value: channel,
26
+ children
27
+ });
28
+ }
29
+ /**
30
+ * Read the submission channel from the nearest `PaymentSectionRoot` or `PaymentSectionController`.
31
+ * Throws outside either subtree, mirroring `usePayment()`: a misplaced holder or CTA is a composition
32
+ * bug the author should see immediately. Distinct from the two *runtime* states — no path chosen, no
33
+ * continuation registered — which `usePlaceOrder` resolves as a userError.
34
+ */
35
+ function usePaymentSubmission() {
36
+ const channel = useContext(PaymentSubmissionContext);
37
+ if (channel === SUBMISSION_CONTEXT_UNSET) throw new Error("usePaymentSubmission() must be used inside a <PaymentSectionRoot> or <PaymentSectionController> subtree.");
38
+ return channel;
39
+ }
40
+ /**
41
+ * The holder-facing signature (T7, T12; `preflight` added by T27). Registers `submit` — and,
42
+ * optionally, its pre-flight check — for `path`, and unregisters on unmount or on any argument
43
+ * changing, so the map always holds the latest closures over the holder's card fields — a stale one
44
+ * would pay with the previous keystroke's CVV.
45
+ */
46
+ function useRegisterPaymentSubmission(path, submit, preflight) {
47
+ const { register } = usePaymentSubmission();
48
+ useEffect(() => register(path, submit, preflight), [
49
+ register,
50
+ path,
51
+ submit,
52
+ preflight
53
+ ]);
54
+ }
55
+ //#endregion
56
+ export { PaymentSubmissionProvider, usePaymentSubmission, useRegisterPaymentSubmission };
57
+
58
+ //# sourceMappingURL=submission-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submission-registry.js","names":[],"sources":["../../../src/sdk/payment/submission-registry.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, type ReactNode, useContext, useEffect, useMemo, useRef } from 'react';\nimport type { PaymentGatewayTransaction } from './gateway.js';\nimport type { PaymentUserError } from './operations.js';\n\n/**\n * The card-data submission channel (specs/use-place-order.md, Decision 1; specs/epics/credit-card.md\n * § \"The card-data submission channel\"). **The holder submits; the orchestrator never holds.**\n *\n * T7 (new card) and T12 (saved card) each register a submit-time continuation here. Each closes over\n * its own card fields, builds the gateway card object inside that closure, calls\n * `$actions.payment.sendPayments` itself, and returns only the gateway leg's `userErrors`. T13's\n * `usePlaceOrder` resolves one by `path` and invokes it between start-transaction and\n * gateway-callback, so no card-shaped field appears anywhere in this channel's type signature.\n *\n * It is a *second*, narrow context beside T5's `payment` context rather than a field on it, because\n * the two have different shapes and different readers: `draft` is render state every leaf reads, this\n * is an imperative registry exactly two components write and one hook reads. Registration is a\n * ref-held `Map`, not state — T7 re-registers a fresh closure on every keystroke, and making that a\n * render would re-render the whole payment section per character.\n *\n * Values that are **not** sensitive travel on T5's `draft`, never here: the save-card flag and label\n * (T10), the cardholder document (T8), and the billing-address-differs flag (T11). The holder folds\n * them into the card object inside its own closure.\n *\n * This module lives in the SDK rather than beside T5's roots so the layering stays `matter → sdk`:\n * `usePlaceOrder` is an SDK hook and cannot import from `matter/`. \"Provided by T5's root\" means the\n * root renders `PaymentSubmissionProvider`, which it does — both of them, for the same ADR-0009\n * reason the `payment` context has two providers.\n */\n\n/** Which entry path a submission serves. The canonical key type; T5's `PaymentPath` aliases it. */\nexport type PaymentSubmissionPath = 'new-card' | 'saved-card';\n\n/**\n * A holder's submit-time continuation — the whole channel. It takes the non-sensitive transaction\n * descriptor and resolves the gateway leg's `userErrors` (empty on success). It must not log,\n * serialize, or return the card.\n */\nexport type PaymentSubmission = (transaction: PaymentGatewayTransaction) => Promise<readonly PaymentUserError[]>;\n\n/**\n * A holder's pre-flight verdict on its own draft, resolved before any transaction opens (T27,\n * specs/place-order-preflight-card-validation.md). Returns the refusals that would make this\n * submission pointless, or an empty array to proceed. Synchronous by contract (Decision 6): a holder\n * validates what it already holds and performs no I/O.\n *\n * Card-free by the same rule the submission itself follows — it returns `PaymentUserError`s and never\n * the fields it inspected. It may have side effects inside its own component (rendering field errors,\n * moving focus); that is the half a value-shaped gate cannot carry.\n */\nexport type PaymentPreflightCheck = () => readonly PaymentUserError[];\n\n/** One path's registration. `preflight` is `null` when its holder registered none (FR-6). */\ntype PaymentSubmissionEntry = Readonly<{\n submit: PaymentSubmission;\n preflight: PaymentPreflightCheck | null;\n}>;\n\nexport type PaymentSubmissionChannel = Readonly<{\n /**\n * The entry path the shopper is on — T5's `draft.path`, mirrored here so the place-order sequence\n * resolves it without reading the matter context. One-way and derived: the root passes it through\n * on every render.\n */\n path: PaymentSubmissionPath | null;\n /** Registers (or replaces) the continuation, and optionally its pre-flight check, for a path. Returns its unregister function. */\n register: (path: PaymentSubmissionPath, submit: PaymentSubmission, preflight?: PaymentPreflightCheck) => () => void;\n /** Unchanged: the continuation registered for a path, or `null` when its holder is not composed or unmounted. */\n resolve: (path: PaymentSubmissionPath) => PaymentSubmission | null;\n /** The pre-flight check registered for a path, or `null` when its holder registered none. */\n resolvePreflight: (path: PaymentSubmissionPath) => PaymentPreflightCheck | null;\n}>;\n\nconst SUBMISSION_CONTEXT_UNSET = Symbol('PaymentSubmissionContextUnset');\n\nconst PaymentSubmissionContext = createContext<PaymentSubmissionChannel | typeof SUBMISSION_CONTEXT_UNSET>(\n SUBMISSION_CONTEXT_UNSET,\n);\n\nexport type PaymentSubmissionProviderProps = Readonly<{\n /** T5's `draft.path`. */\n path: PaymentSubmissionPath | null;\n children: ReactNode;\n}>;\n\n/** Rendered by `PaymentSectionRoot` and `PaymentSectionController` around the section composition. */\nexport function PaymentSubmissionProvider({ path, children }: PaymentSubmissionProviderProps) {\n const submissions = useRef(new Map<PaymentSubmissionPath, PaymentSubmissionEntry>());\n\n const channel = useMemo<PaymentSubmissionChannel>(\n () => ({\n path,\n register: (registeredPath, submit, preflight) => {\n submissions.current.set(registeredPath, { submit, preflight: preflight ?? null });\n return () => {\n // Delete only if this registration is still the one on file: a Map holds one entry per\n // path, so an unmounting holder whose registration was already superseded by a still-mounted\n // sibling under the same path must not wipe that sibling's live continuation (or its check).\n if (submissions.current.get(registeredPath)?.submit === submit) {\n submissions.current.delete(registeredPath);\n }\n };\n },\n resolve: (registeredPath) => submissions.current.get(registeredPath)?.submit ?? null,\n resolvePreflight: (registeredPath) => submissions.current.get(registeredPath)?.preflight ?? null,\n }),\n [path],\n );\n\n return <PaymentSubmissionContext value={channel}>{children}</PaymentSubmissionContext>;\n}\n\n/**\n * Read the submission channel from the nearest `PaymentSectionRoot` or `PaymentSectionController`.\n * Throws outside either subtree, mirroring `usePayment()`: a misplaced holder or CTA is a composition\n * bug the author should see immediately. Distinct from the two *runtime* states — no path chosen, no\n * continuation registered — which `usePlaceOrder` resolves as a userError.\n */\nexport function usePaymentSubmission(): PaymentSubmissionChannel {\n const channel = useContext(PaymentSubmissionContext);\n if (channel === SUBMISSION_CONTEXT_UNSET) {\n throw new Error(\n 'usePaymentSubmission() must be used inside a <PaymentSectionRoot> or <PaymentSectionController> subtree.',\n );\n }\n return channel;\n}\n\n/**\n * The holder-facing signature (T7, T12; `preflight` added by T27). Registers `submit` — and,\n * optionally, its pre-flight check — for `path`, and unregisters on unmount or on any argument\n * changing, so the map always holds the latest closures over the holder's card fields — a stale one\n * would pay with the previous keystroke's CVV.\n */\nexport function useRegisterPaymentSubmission(\n path: PaymentSubmissionPath,\n submit: PaymentSubmission,\n preflight?: PaymentPreflightCheck,\n): void {\n const { register } = usePaymentSubmission();\n\n useEffect(() => register(path, submit, preflight), [register, path, submit, preflight]);\n}\n"],"mappings":";;;;AA2EA,MAAM,2BAA2B,OAAO,+BAA+B;AAEvE,MAAM,2BAA2B,cAC/B,wBACF;;AASA,SAAgB,0BAA0B,EAAE,MAAM,YAA4C;CAC5F,MAAM,cAAc,uBAAO,IAAI,IAAmD,CAAC;CAEnF,MAAM,UAAU,eACP;EACL;EACA,WAAW,gBAAgB,QAAQ,cAAc;GAC/C,YAAY,QAAQ,IAAI,gBAAgB;IAAE;IAAQ,WAAW,aAAa;GAAK,CAAC;GAChF,aAAa;IAIX,IAAI,YAAY,QAAQ,IAAI,cAAc,CAAC,EAAE,WAAW,QACtD,YAAY,QAAQ,OAAO,cAAc;GAE7C;EACF;EACA,UAAU,mBAAmB,YAAY,QAAQ,IAAI,cAAc,CAAC,EAAE,UAAU;EAChF,mBAAmB,mBAAmB,YAAY,QAAQ,IAAI,cAAc,CAAC,EAAE,aAAa;CAC9F,IACA,CAAC,IAAI,CACP;CAEA,OAAO,oBAAC,0BAAD;EAA0B,OAAO;EAAU;CAAmC,CAAA;AACvF;;;;;;;AAQA,SAAgB,uBAAiD;CAC/D,MAAM,UAAU,WAAW,wBAAwB;CACnD,IAAI,YAAY,0BACd,MAAM,IAAI,MACR,0GACF;CAEF,OAAO;AACT;;;;;;;AAQA,SAAgB,6BACd,MACA,QACA,WACM;CACN,MAAM,EAAE,aAAa,qBAAqB;CAE1C,gBAAgB,SAAS,MAAM,QAAQ,SAAS,GAAG;EAAC;EAAU;EAAM;EAAQ;CAAS,CAAC;AACxF"}
@@ -0,0 +1,78 @@
1
+ import "../../core/dist/index.js";
2
+ import { PaymentBillingAddressUpdateInput, PaymentMethodSelectInput, PaymentMoney, PaymentUserError } from "./operations.js";
3
+ import { SendPaymentsRequest } from "./gateway.js";
4
+ //#region src/sdk/payment/use-payment-actions.d.ts
5
+ /**
6
+ * The `payment` action namespace — the sanctioned client write surface for credit-card payment
7
+ * (specs/payment-action-namespace.md; docs/features/credit-card/rfc.md § D12;
8
+ * docs/storefront-core/adr-0010-actions-own-the-write-side.md).
9
+ *
10
+ * Six mutation-backed methods run the write model T3 shipped (`checkout/schema.graphql` § 11), except
11
+ * `saveCard`, which reuses the already-shipped `clientPreferencesUpdate` document this package owns —
12
+ * there is no `paymentSaveCard` mutation and T3 decided there must not be one. All six are
13
+ * async/pessimistic: the handler awaits the mutation and only the server-confirmed payload changes the
14
+ * cache. Each is stateless (no reactive vars, no module state), resolves its payload `userErrors` (empty
15
+ * on success), and never throws for an expected outcome; an infrastructure failure (transport or an
16
+ * upstream GraphQLError) is caught and collapsed to one synthetic `NETWORK_ERROR` userError with no
17
+ * per-code branching, mirroring `useShippingActions`.
18
+ *
19
+ * `sendPayments` is the seventh method and the odd one: a **façade** (ADR-0010's sanctioned flavor,
20
+ * alongside `notifications`) that posts card data from the browser straight to the payment gateway,
21
+ * touching neither our GraphQL layer nor the normalized cache. It is catalogued like any other method —
22
+ * per D12, hiding a write route with no read-back would cost discoverability without protecting
23
+ * anything, and the compiler wants to *see* which components reference it. What is deliberately absent
24
+ * from the catalog is the card data itself: no `payload` entry below names a card number, CVV, expiry,
25
+ * or holder name, so there is no schema-bindable name for the editor or the agent to map a value onto
26
+ * (RFC D13). The card reaches the handler as a runtime argument from the card-entry component's local
27
+ * state (T7), and `gateway.ts` — which has no Apollo import — is the only module that touches it.
28
+ */
29
+ /**
30
+ * Everything `usePlaceOrder` (T13) needs to assemble `PaymentGatewayTransaction`, minus the five
31
+ * fields that come from the `Payment` read model. Every field is nullable because a payload carrying
32
+ * `userErrors` nulls all of them (T18 Decision 4), so a complete descriptor is only guaranteed once
33
+ * `userErrors` is empty *and* the payload passes the caller's completeness check.
34
+ */
35
+ export type PaymentStartTransactionResult = Readonly<{
36
+ transactionId: string | null;
37
+ merchantName: string | null;
38
+ /** Gateway origin. Nullable, and never interpolated into a URL before `isTrustedGatewayOrigin`. */
39
+ gatewayUrl: string | null;
40
+ orderGroup: string | null;
41
+ userProfileId: string | null;
42
+ /** Display decimal. The gateway body's unit is `valueInCents`. */
43
+ value: PaymentMoney | null;
44
+ valueInCents: number | null;
45
+ referenceValueInCents: number | null;
46
+ userErrors: readonly PaymentUserError[];
47
+ }>;
48
+ export type PaymentGatewayCallbackResult = Readonly<{
49
+ orderId: string | null;
50
+ userErrors: readonly PaymentUserError[];
51
+ }>;
52
+ export type PaymentActions = Readonly<{
53
+ /** Select a payment method, optionally identifying a new card's BIN or a saved card's account. */
54
+ setMethod: (input: PaymentMethodSelectInput) => Promise<readonly PaymentUserError[]>;
55
+ /** Select an installment count for the current method. The response carries the recomputed cart total. */
56
+ setInstallments: (count: number) => Promise<readonly PaymentUserError[]>;
57
+ /** Persist the billing address, or fall back to the delivery address (`sameAsDelivery: true`). */
58
+ setBillingAddress: (input: PaymentBillingAddressUpdateInput) => Promise<readonly PaymentUserError[]>;
59
+ /**
60
+ * Record the data-storage consent a saved card requires, over the existing `clientPreferencesUpdate`.
61
+ * This does not by itself save the card: the save flag and label travel on `sendPayments`'s card
62
+ * argument (RFC D5's two halves). The boolean passes through unchanged — whether unchecking should
63
+ * revoke a consent an unrelated opt-in component may have granted is T10's decision, and its spec must
64
+ * state one (Gap 4 in specs/payment-action-namespace.md).
65
+ */
66
+ saveCard: (enabled: boolean) => Promise<readonly PaymentUserError[]>;
67
+ /** Open a VTEX transaction from the persisted selection. Resolves the payload the gateway call needs. */
68
+ startTransaction: () => Promise<PaymentStartTransactionResult>;
69
+ /** Finalize the transaction after the gateway accepted the card. */
70
+ gatewayCallback: (orderGroup: string) => Promise<PaymentGatewayCallbackResult>;
71
+ /**
72
+ * Façade: post the card straight to the payment gateway. Issues no GraphQL operation and writes
73
+ * nothing to the cache. Resolves one `GATEWAY_ERROR` userError when the gateway rejects the call.
74
+ */
75
+ sendPayments: (request: SendPaymentsRequest) => Promise<readonly PaymentUserError[]>;
76
+ }>;
77
+ //#endregion
78
+ //# sourceMappingURL=use-payment-actions.d.ts.map