diff --git a/_dropin-enrichments/payment-services/containers.json b/_dropin-enrichments/payment-services/containers.json
index 6b84d059d..36acb305d 100644
--- a/_dropin-enrichments/payment-services/containers.json
+++ b/_dropin-enrichments/payment-services/containers.json
@@ -3,6 +3,10 @@
"description": "Displays apple pay for the Payment Services drop-in."
},
"CreditCard": {
- "description": "... See '`CardType`' from @`adobe-commerce/payment-services-sdk/payment`."
+ "description": "Renders the credit or debit card form and an optional “save this card” for signed-in shoppers. See `CardType` in `@adobe-commerce/payment-services-sdk/payment`."
+ },
+ "StoredCards": {
+ "description": "Lists vaulted (saved) cards and an optional “pay with a new card” row for checkout.",
+ "override_template": true
}
-}
+}
\ No newline at end of file
diff --git a/_dropin-enrichments/payment-services/initialization.json b/_dropin-enrichments/payment-services/initialization.json
index a8a7d30b1..48a1c2de2 100644
--- a/_dropin-enrichments/payment-services/initialization.json
+++ b/_dropin-enrichments/payment-services/initialization.json
@@ -5,10 +5,10 @@
"description": "URL for the payment or Commerce API endpoint. Required for payment processing and backend communication."
},
"getCustomerToken": {
- "description": "Function that returns the current customer auth token, or null if not authenticated. Used for authenticated API requests."
+ "description": "Function that returns the current customer auth token, or `null` if the shopper is not authenticated. It’s used for authenticated GraphQL calls (such as vault token queries and vault payment orders) and to control whether the **Save this card** option appears on the CreditCard form."
},
"storeViewCode": {
"description": "Store view code for the Commerce backend. Determines locale, currency, and catalog scope for API requests."
}
}
-}
+}
\ No newline at end of file
diff --git a/astro.config.mjs b/astro.config.mjs
index c636ac4e6..ac77fe279 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -253,49 +253,6 @@ async function config() {
],
vite: {
- plugins: [
- {
- // Patch the Vite logger after config is resolved so the filter applies
- // to all logging paths, including environment-level loggers in Vite 6+.
- name: 'suppress-known-build-warnings',
- configResolved(resolvedConfig) {
- const isKnownSafe = (msg) =>
- typeof msg === 'string' && (
- // Public SVG assets used in CSS url() — resolved correctly by the browser
- // at runtime even though Vite can't resolve them at build time.
- (msg.includes("didn't resolve at build time") && (
- msg.includes('hero-bg-light.svg') ||
- msg.includes('hero-bg-dark.svg')
- )) ||
- // Empty chunk from starlight-heading-badges — deduplication artifact.
- (msg.includes('empty chunk') && msg.includes('HeadingBadgesTableOfContents')) ||
- // Unused import noise from expressive-code packages.
- (msg.includes('@expressive-code/plugin-text-markers') && msg.includes('never used'))
- );
-
- const patchLogger = (logger) => {
- if (!logger) return;
- for (const method of ['warn', 'warnOnce']) {
- const original = logger[method]?.bind(logger);
- if (original) {
- logger[method] = (msg, opts) => { if (!isKnownSafe(msg)) original(msg, opts); };
- }
- }
- };
-
- // Patch the root logger.
- patchLogger(resolvedConfig.logger);
- // Patch each environment logger (Vite 6+). Environment-level loggers are
- // separate instances; the CSS url() resolution warning is emitted via
- // environment.logger, so the root logger patch alone may not catch it.
- if (resolvedConfig.environments) {
- for (const env of Object.values(resolvedConfig.environments)) {
- patchLogger(env.logger);
- }
- }
- },
- },
- ],
build: {
chunkSizeWarningLimit: 1000, // Increase limit to 1MB to reduce noise
rollupOptions: {
@@ -307,17 +264,21 @@ async function config() {
warning.source.includes('expressive-code'))) {
return;
}
- // Suppress empty chunk warning from starlight-heading-badges plugin — the
- // starlight-toc custom element it re-registers is deduplicated by Rollup.
- if (warning.code === 'EMPTY_BUNDLE' &&
- warning.names?.some((n) => n.includes('HeadingBadgesTableOfContents'))) {
- return;
- }
warn(warning);
}
}
},
logLevel: 'warn',
+ customLogger: {
+ warn(msg, options) {
+ // Suppress specific expressive-code warnings
+ if (msg.includes('@expressive-code/plugin-text-markers') &&
+ msg.includes('never used')) {
+ return;
+ }
+ console.warn(msg, options);
+ }
+ }
}
});
}
diff --git a/astro.sidebar.mjs b/astro.sidebar.mjs
index 83165f918..559cca12c 100644
--- a/astro.sidebar.mjs
+++ b/astro.sidebar.mjs
@@ -145,6 +145,13 @@ export function generateSidebar() {
{ label: 'Validate address', link: '/dropins/user-account/tutorials/validate-address/' },
],
},
+ {
+ label: 'Payment Services',
+ collapsed: true,
+ items: [
+ { label: 'Vaulted cards at checkout', link: '/dropins/payment-services/tutorials/vaulted-cards-checkout/' },
+ ],
+ },
],
},
// ---------- DROP-INS Overview ----------
@@ -296,7 +303,8 @@ export function generateSidebar() {
items: [
{ label: 'Overview', link: '/dropins/payment-services/containers/' },
{ label: 'ApplePay', link: '/dropins/payment-services/containers/apple-pay/' },
- { label: 'CreditCard', link: '/dropins/payment-services/containers/credit-card/' }
+ { label: 'CreditCard', link: '/dropins/payment-services/containers/credit-card/' },
+ { label: 'StoredCards', link: '/dropins/payment-services/containers/stored-cards/' }
],
},
],
diff --git a/package.json b/package.json
index 6867c3615..a83d8e451 100644
--- a/package.json
+++ b/package.json
@@ -118,7 +118,7 @@
"hast-util-from-html": "^2.0.3",
"hast-util-to-string": "^3.0.1",
"hastscript": "^9.0.1",
- "lodash": "^4.18.1",
+ "lodash": "^4.17.23",
"lodash.escaperegexp": "^4.1.2",
"mermaid": "^11.12.2",
"node-html-parser": "^7.0.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0bad24dee..57a2da211 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -152,7 +152,7 @@ importers:
specifier: ^9.0.1
version: 9.0.1
lodash:
- specifier: ^4.18.1
+ specifier: ^4.17.23
version: 4.18.1
lodash.escaperegexp:
specifier: ^4.1.2
@@ -501,8 +501,8 @@ packages:
'@emmetio/stream-reader@2.2.0':
resolution: {integrity: sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==}
- '@emnapi/runtime@1.9.2':
- resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==}
+ '@emnapi/runtime@1.10.0':
+ resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
'@emotion/is-prop-valid@0.8.8':
resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==}
@@ -2779,8 +2779,8 @@ packages:
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
- electron-to-chromium@1.5.337:
- resolution: {integrity: sha512-15gKW9mRUNP9RdzhedJNypFUxtYWSXohFz2nTLzM272xbRXHws68kNDzyATG3qej+vUj/7Sn9hf5XTDh0XK6/w==}
+ electron-to-chromium@1.5.339:
+ resolution: {integrity: sha512-Is+0BBHJ4NrdpAYiperrmp53pLywG/yV/6lIMTAnhxvzj/Cmn5Q/ogSHC6AKe7X+8kPLxxFk0cs5oc/3j/fxIg==}
emmet@2.4.11:
resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==}
@@ -5603,7 +5603,7 @@ snapshots:
'@emmetio/stream-reader@2.2.0': {}
- '@emnapi/runtime@1.9.2':
+ '@emnapi/runtime@1.10.0':
dependencies:
tslib: 2.8.1
optional: true
@@ -6007,7 +6007,7 @@ snapshots:
'@img/sharp-wasm32@0.34.5':
dependencies:
- '@emnapi/runtime': 1.9.2
+ '@emnapi/runtime': 1.10.0
optional: true
'@img/sharp-win32-arm64@0.34.5':
@@ -7426,7 +7426,7 @@ snapshots:
dependencies:
baseline-browser-mapping: 2.10.19
caniuse-lite: 1.0.30001788
- electron-to-chromium: 1.5.337
+ electron-to-chromium: 1.5.339
node-releases: 2.0.37
update-browserslist-db: 1.2.3(browserslist@4.28.2)
@@ -7935,7 +7935,7 @@ snapshots:
eastasianwidth@0.2.0: {}
- electron-to-chromium@1.5.337: {}
+ electron-to-chromium@1.5.339: {}
emmet@2.4.11:
dependencies:
diff --git a/public/images/payment-services-checkout-pay-with-new-card.png b/public/images/payment-services-checkout-pay-with-new-card.png
new file mode 100644
index 000000000..2827b832f
Binary files /dev/null and b/public/images/payment-services-checkout-pay-with-new-card.png differ
diff --git a/public/images/payment-services-checkout-stored-card-selected.png b/public/images/payment-services-checkout-stored-card-selected.png
new file mode 100644
index 000000000..b1be82389
Binary files /dev/null and b/public/images/payment-services-checkout-stored-card-selected.png differ
diff --git a/src/components/List.astro b/src/components/List.astro
index 60c221240..e732a43a2 100644
--- a/src/components/List.astro
+++ b/src/components/List.astro
@@ -1,4 +1,5 @@
---
+
---
@@ -35,11 +36,7 @@
border-color: var(--sl-color-black);
text-align: center;
vertical-align: sub;
- /* Inline data URI of src/components/images/adobe.svg — keeps the icon
- self-contained so it renders in both dev and production builds without
- any path or base-path dependency. If the source SVG changes, re-encode
- it and update the identical copy in Vocabulary.astro as well. */
- content: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjIwIiB2aWV3Qm94PSIwIDAgMjEgMjAiIHdpZHRoPSIyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMTAuNDA0My4wMDc2MDk2NmMyLjE1MDQgMCA0LjMwMDgtLjAyMTMwMDg2IDYuNDUwNC4wMDczNzMzNCAxLjQ5NTIuMDE5NjYyNCAyLjU4Ljc1ODYzOCAzLjIzMiAyLjE0MDczNy4yMTYuNDU3MTUuMzA2NC45NDk1My4zMDY0IDEuNDU5MTEtLjAwMDggNC4yNTE5OC4wMDI0IDguNTAzOTctLjAwMTYgMTIuNzU1OTctLjAwMjQgMi4wMDE0LTEuNTQyNCAzLjYxMDUtMy41MDI0IDMuNjE3OC00LjMyNjQuMDE1Ni04LjY1MjgzLjAxNDgtMTIuOTc5MjMgMC0xLjk2NTYxLS4wMDY1LTMuNTA4MDExLTEuNjE0Ny0zLjUxMTIxMS0zLjYzMjYtLjAwNjQtNC4yMzg5LS4wMDcyLTguNDc3NzIgMC0xMi43MTU3OC4wMDQtMi4wMzE3NyAxLjU3NDQwMS0zLjYyODUxNCAzLjU1NTIxMS0zLjYzMTc5MTA4IDIuMTUwNC0uMDAzMjc3MDUgNC4zLS4wMDA4MTkyNiA2LjQ1MDQzLS4wMDA4MTkyNnoiIGZpbGw9IiNlYjEwMDAiLz48cGF0aCBkPSJtNy44NjQ3IDE1LjM5OGMtMS4xMjY2OSAwLTIuMjUzMzggMC0zLjM4MDA3IDAtLjQyNjc2IDAtLjU0OTgyLS4xOTM5LS4zODMxMy0uNjAwNiAxLjQ1MjIyLTMuNTQzNyAyLjkwNDQ0LTcuMDg2NDQgNC4zNTY2Ni0xMC42MjkyMy4xNzM2Ny0uNDIzNjMuMzI5ODktLjUyOTA5Ljc4MzctLjUyOTA5Ljc2OTc0IDAgMS41NDAzNC4wMDUzNiAyLjMxMDE0LS4wMDI2OC4zNjY1LS4wMDM1OC41OTYuMTU2NC43MzkyLjUwNDk2IDEuNDYxOCAzLjU1NTMgMi45Mjk3IDcuMTA3MDQgNC4zOTU5IDEwLjY2MDU0LjE2NjcuNDA0LjA0MTkuNTk2MS0uMzg4NC41OTctLjc4NDUuMDAwOS0xLjU2OTEtLjAwNzEtMi4zNTI4LjAwMzYtLjM0NDguMDA0NS0uNTU1MS0uMTQyMS0uNjkwNC0uNDY2NS0uODk4OS0yLjE2ODMtMS44MDU2LTQuMzMyLTIuNzE0MS02LjQ5NTc1LS4wMzMyLS4wNzg2NS0uMTA0OC0uMTQxMjEtLjE1OC0uMjEwOTItLjA1NTkuMDY2MTQtLjEzMzUuMTI0MjMtLjE2NS4yMDEwOS0uNTUyMzkgMS4zMzYxNC0xLjA5ODcyIDIuNjc0OTgtMS42NDU5MiA0LjAxMzc4LS4xMTUyLjI4MDYtLjA3OTQyLjMzNy4yMTQ2OS4zMzc4LjU2Mzc5LjAwMDkgMS4xMjY2OS4wMDYzIDEuNjg5NjMtLjAwMjYuMjA1OS0uMDAyNy4zMzI1LjA3NDEuNDE1NC4yNjgxLjI1MDUuNTg4MS41MTQgMS4xNzA4Ljc2NzEgMS43NTcxLjE1NDUuMzU3NS4wMDc5LjU5MzQtLjM3MDkuNTk0My0xLjE0MDYuMDAyNy0yLjI4MjE3LjAwMDktMy40MjI4My4wMDA5eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==");
+ content: url(/src/components/images/adobe.svg);
margin-top: 0;
margin-bottom: 0;
margin-right: 1rem;
diff --git a/src/components/Vocabulary.astro b/src/components/Vocabulary.astro
index 711773023..5bbf13337 100644
--- a/src/components/Vocabulary.astro
+++ b/src/components/Vocabulary.astro
@@ -56,11 +56,7 @@ const { columns = 1 } = Astro.props;
border-color: var(--sl-color-black);
text-align: center;
vertical-align: sub;
- /* Inline data URI of src/components/images/adobe.svg — keeps the icon
- self-contained so it renders in both dev and production builds without
- any path or base-path dependency. If the source SVG changes, re-encode
- it and update the identical copy in List.astro as well. */
- content: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjIwIiB2aWV3Qm94PSIwIDAgMjEgMjAiIHdpZHRoPSIyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMTAuNDA0My4wMDc2MDk2NmMyLjE1MDQgMCA0LjMwMDgtLjAyMTMwMDg2IDYuNDUwNC4wMDczNzMzNCAxLjQ5NTIuMDE5NjYyNCAyLjU4Ljc1ODYzOCAzLjIzMiAyLjE0MDczNy4yMTYuNDU3MTUuMzA2NC45NDk1My4zMDY0IDEuNDU5MTEtLjAwMDggNC4yNTE5OC4wMDI0IDguNTAzOTctLjAwMTYgMTIuNzU1OTctLjAwMjQgMi4wMDE0LTEuNTQyNCAzLjYxMDUtMy41MDI0IDMuNjE3OC00LjMyNjQuMDE1Ni04LjY1MjgzLjAxNDgtMTIuOTc5MjMgMC0xLjk2NTYxLS4wMDY1LTMuNTA4MDExLTEuNjE0Ny0zLjUxMTIxMS0zLjYzMjYtLjAwNjQtNC4yMzg5LS4wMDcyLTguNDc3NzIgMC0xMi43MTU3OC4wMDQtMi4wMzE3NyAxLjU3NDQwMS0zLjYyODUxNCAzLjU1NTIxMS0zLjYzMTc5MTA4IDIuMTUwNC0uMDAzMjc3MDUgNC4zLS4wMDA4MTkyNiA2LjQ1MDQzLS4wMDA4MTkyNnoiIGZpbGw9IiNlYjEwMDAiLz48cGF0aCBkPSJtNy44NjQ3IDE1LjM5OGMtMS4xMjY2OSAwLTIuMjUzMzggMC0zLjM4MDA3IDAtLjQyNjc2IDAtLjU0OTgyLS4xOTM5LS4zODMxMy0uNjAwNiAxLjQ1MjIyLTMuNTQzNyAyLjkwNDQ0LTcuMDg2NDQgNC4zNTY2Ni0xMC42MjkyMy4xNzM2Ny0uNDIzNjMuMzI5ODktLjUyOTA5Ljc4MzctLjUyOTA5Ljc2OTc0IDAgMS41NDAzNC4wMDUzNiAyLjMxMDE0LS4wMDI2OC4zNjY1LS4wMDM1OC41OTYuMTU2NC43MzkyLjUwNDk2IDEuNDYxOCAzLjU1NTMgMi45Mjk3IDcuMTA3MDQgNC4zOTU5IDEwLjY2MDU0LjE2NjcuNDA0LjA0MTkuNTk2MS0uMzg4NC41OTctLjc4NDUuMDAwOS0xLjU2OTEtLjAwNzEtMi4zNTI4LjAwMzYtLjM0NDguMDA0NS0uNTU1MS0uMTQyMS0uNjkwNC0uNDY2NS0uODk4OS0yLjE2ODMtMS44MDU2LTQuMzMyLTIuNzE0MS02LjQ5NTc1LS4wMzMyLS4wNzg2NS0uMTA0OC0uMTQxMjEtLjE1OC0uMjEwOTItLjA1NTkuMDY2MTQtLjEzMzUuMTI0MjMtLjE2NS4yMDEwOS0uNTUyMzkgMS4zMzYxNC0xLjA5ODcyIDIuNjc0OTgtMS42NDU5MiA0LjAxMzc4LS4xMTUyLjI4MDYtLjA3OTQyLjMzNy4yMTQ2OS4zMzc4LjU2Mzc5LjAwMDkgMS4xMjY2OS4wMDYzIDEuNjg5NjMtLjAwMjYuMjA1OS0uMDAyNy4zMzI1LjA3NDEuNDE1NC4yNjgxLjI1MDUuNTg4MS41MTQgMS4xNzA4Ljc2NzEgMS43NTcxLjE1NDUuMzU3NS4wMDc5LjU5MzQtLjM3MDkuNTk0My0xLjE0MDYuMDAyNy0yLjI4MjE3LjAwMDktMy40MjI4My4wMDA5eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==");
+ content: url(/src/components/images/adobe.svg);
margin-top: 0;
margin-bottom: 0;
margin-right: 1rem;
diff --git a/src/content/docs/dropins-b2b/requisition-list/containers/requisition-list-selector.mdx b/src/content/docs/dropins-b2b/requisition-list/containers/requisition-list-selector.mdx
index 94fc9ec6c..f0c8441f2 100644
--- a/src/content/docs/dropins-b2b/requisition-list/containers/requisition-list-selector.mdx
+++ b/src/content/docs/dropins-b2b/requisition-list/containers/requisition-list-selector.mdx
@@ -26,7 +26,8 @@ The `RequisitionListSelector` container provides the following configuration opt
| `sku` | `string` | Yes | Specifies the product SKU to add to the selected requisition list. Required to identify the exact product variant being added. Must match a valid product SKU in your catalog. |
| `selectedOptions` | `string[]` | No | Provides an array of selected product option IDs for configurable products. Captures variant selections such as size, color, or other configurable attributes. Required for configurable products to identify the specific variant being added. |
| `quantity` | `number` | No | Sets the quantity of the product to add to the requisition list. Defaults to 1 if not specified. Use to allow bulk additions or pre-populate quantities from previous orders or saved preferences. |
-| `beforeAddProdToReqList` | `function` | No | Callback function to handle validation before the Add to Requisition List dropdown opens when the button is clicked. Use to validate if the product can be added directly (for example, check if a configurable product needs options selected) and redirect to the product detail page if needed. If the callback throws an error or rejects, the dropdown will not open, enabling patterns like redirecting complex products to their detail pages. |
+| `matchBySKU` | `boolean` | No | Controls how the active state is determined. When set to `true`, it checks only the product SKU. When set to `false`, it checks both the SKU and selected configurable option UIDs. The default is `true` (SKU-only). Use `false` on product detail pages (PDP) for configurable products so the button is active only for the exact variant (matching SKU and selected options). Use `true` on product listing pages (PLP), where specific variants aren’t selected. |
+| `beforeAddProdToReqList` | `function` | No | Callback function that runs before the **Add to Requisition List** dropdown opens. Use it to validate whether the product can be added directly (for example, ensuring required options are selected). If validation fails—by throwing or rejecting—the dropdown will not open, allowing you to handle cases like redirecting configurable products to the product detail page. |
| `initialData` | `object` | No | Preloaded data for the model before backend data is fetched. Use for testing, SSR, or improving initial load. |
diff --git a/src/content/docs/dropins-b2b/requisition-list/functions.mdx b/src/content/docs/dropins-b2b/requisition-list/functions.mdx
index fc66f0e6f..8d6bd9a81 100644
--- a/src/content/docs/dropins-b2b/requisition-list/functions.mdx
+++ b/src/content/docs/dropins-b2b/requisition-list/functions.mdx
@@ -232,7 +232,8 @@ Returns the requisition lists for the logged-in user.
```ts
const getRequisitionLists = async (
currentPage?: number,
- pageSize?: number
+ pageSize?: number,
+ listItemsPageSize?: number
): Promise
```
@@ -242,6 +243,7 @@ const getRequisitionLists = async (
|---|---|---|---|
| `currentPage` | `number` | No | The page number for pagination (1-indexed). Used to navigate through multiple pages of requisition lists. |
| `pageSize` | `number` | No | The number of requisition lists to return per page. Controls how many lists appear on each page. |
+| `listItemsPageSize` | `number` | No | Sets the number of items loaded per GraphQL request (default: 100). If a list exceeds this, additional requests are made automatically so all items are available to the user. |
diff --git a/src/content/docs/dropins/all/introduction.mdx b/src/content/docs/dropins/all/introduction.mdx
index ce46c8d26..11ca93a01 100644
--- a/src/content/docs/dropins/all/introduction.mdx
+++ b/src/content/docs/dropins/all/introduction.mdx
@@ -23,7 +23,7 @@ Drop-in components are full-featured shopping components (not primitives like Ca
| [Cart](/dropins/cart/) | Summary of items in the cart; view and manage cart contents, update quantities, and proceed to checkout. |
| [Checkout](/dropins/checkout/) | Streamlined process for completing a purchase: shipping and payment information, order review, and confirmation. |
| [Order](/dropins/order/) | Tools and containers to manage and display order-related data across pages; supports customer accounts and guest workflows. |
-| [Payment Services](/dropins/payment-services/) | Renders the credit card form and Apple Pay button for payment details; supports credit/debit cards and Apple Pay. |
+| [Payment Services](/dropins/payment-services/) | Renders the credit card form and Apple Pay button for payment details; supports credit/debit cards and Apple Pay. Vaulted (saved) cards are available for signed-in shoppers when the integration enables vaulting. |
| [Personalization](/dropins/personalization/) | Displays content conditionally based on Adobe Commerce customer groups, segments, and cart price rules. |
| [Product Details](/dropins/product-details/) | Detailed product information: SKUs, pricing, descriptions, options; supports internationalization and accessibility. |
| [Product Discovery](/dropins/product-discovery/) | Search results, category listings, and faceted navigation so customers can find and explore products. |
diff --git a/src/content/docs/dropins/index.mdx b/src/content/docs/dropins/index.mdx
index 3be77758c..bb6445142 100644
--- a/src/content/docs/dropins/index.mdx
+++ b/src/content/docs/dropins/index.mdx
@@ -17,7 +17,7 @@ Drop-ins are pre-built, customizable UI components that provide complete commerc
| [Cart overview](/dropins/cart/) | Provides editable controls to help you view, update, and merge the products in your cart and mini-cart, including image thumbnails, pricing. |
| [Checkout overview](/dropins/checkout/) | Provides customizable controls to help complete a purchase. |
| [Order overview](/dropins/order/) | Provides tools to manage and display order-related data across various pages and scenarios. |
-| [Payment Services overview](/dropins/payment-services/) | Renders the credit card form and the Apple Pay button. |
+| [Payment Services overview](/dropins/payment-services/) | Renders the credit card form and the Apple Pay button. Vaulted (saved) cards are available for signed-in shoppers when the integration enables them. |
| [Personalization overview](/dropins/personalization/) | Provides tools to display content conditionally, based on Adobe Commerce customer groups, segments, and cart price rules. |
| [Product details page overview](/dropins/product-details/) | Renders detailed information about your products, including descriptions, specifications, options, pricing, and images. |
| [Product Discovery overview](/dropins/product-discovery/) | Enables you to display and customize product search results, category listings, and faceted navigation. |
diff --git a/src/content/docs/dropins/payment-services/containers/apple-pay.mdx b/src/content/docs/dropins/payment-services/containers/apple-pay.mdx
index bdde3f203..305347398 100644
--- a/src/content/docs/dropins/payment-services/containers/apple-pay.mdx
+++ b/src/content/docs/dropins/payment-services/containers/apple-pay.mdx
@@ -9,11 +9,6 @@ import { Aside } from '@astrojs/starlight/components';
import TableWrapper from '@components/TableWrapper.astro';
-
-
-Version: 3.1.0
-
-
## Configuration
The `ApplePay` container provides the following configuration options:
diff --git a/src/content/docs/dropins/payment-services/containers/credit-card.mdx b/src/content/docs/dropins/payment-services/containers/credit-card.mdx
index 85b099f87..e53262897 100644
--- a/src/content/docs/dropins/payment-services/containers/credit-card.mdx
+++ b/src/content/docs/dropins/payment-services/containers/credit-card.mdx
@@ -10,10 +10,6 @@ import TableWrapper from '@components/TableWrapper.astro';
See the `CardType` type and related payment types in the `@adobe-commerce/payment-services-sdk/payment` module.
-
-Version: 3.1.0
-
-
## Configuration
The `CreditCard` container provides the following configuration options:
@@ -26,9 +22,19 @@ The `CreditCard` container provides the following configuration options:
| `creditCardFormRef` | `RefObject` | Yes | References the credit card form. Pass \{ current: null \} initially. After rendering, the container sets `current` to a \{ validate: () => boolean; submit: () => Promise<void> \} object for programmatic validation and submission. |
| `onSuccess` | `function` | Yes | Executes when the payment flow completes successfully. |
| `onError` | `function` | Yes | Executes when the payment flow aborts due to an error. Receives an object with two properties, \{ name: string, message: string \}, containing the localized error name and message. Both properties are user-facing and translatable through the "PaymentServices.CreditCard.errors" language definitions. **Note:** When omitted, the promise rejects properly so the calling code can catch errors directly. |
+| `getCustomerToken` | `(() => string \| null) \| null` | No | Optional override for retrieving the customer auth token. If it returns a non-null string, the Save this card checkbox is shown and vaulting can be requested on submit. If not provided, the container uses [`getCustomerToken` from initialization](/dropins/payment-services/initialization/). |
+## Card vaulting
+
+The CreditCard container shows a **Save this card for future purchases** checkbox when both of the following are true:
+
+- The shopper is **logged in** — the host application must emit the [`authenticated`](/dropins/all/common-events/#authenticated) event through the event bus.
+- Card vaulting is **enabled** in the Adobe Commerce Admin at **Stores > Configuration > Sales > Payment Methods > Adobe Payment Services > Credit Card Fields > Vault Enabled**.
+
+If the shopper selects the checkbox and submits, the card is saved for future purchases. The checkbox is automatically hidden when either the shopper is a guest or vaulting is disabled.
+
## Slots
This container exposes no customizable slots.
diff --git a/src/content/docs/dropins/payment-services/containers/index.mdx b/src/content/docs/dropins/payment-services/containers/index.mdx
index 2522d0b96..d46eda84b 100644
--- a/src/content/docs/dropins/payment-services/containers/index.mdx
+++ b/src/content/docs/dropins/payment-services/containers/index.mdx
@@ -11,10 +11,6 @@ import TableWrapper from '@components/TableWrapper.astro';
The **Payment Services** drop-in provides pre-built container components for integrating into your storefront.
-
-Version: 3.1.0
-
-
## What are Containers?
Containers are pre-built UI components that combine functionality, state management, and presentation. They provide a complete solution for specific features and can be customized through props, slots, and CSS.
@@ -25,8 +21,9 @@ Containers are pre-built UI components that combine functionality, state managem
| Container | Description |
| --------- | ----------- |
-| [ApplePay](/dropins/payment-services/containers/apple-pay/) | *Enrichment needed - add description to `_dropin-enrichments/payment-services/containers.json`* |
-| [CreditCard](/dropins/payment-services/containers/credit-card/) | *Enrichment needed - add description to `_dropin-enrichments/payment-services/containers.json`* |
+| [ApplePay](/dropins/payment-services/containers/apple-pay/) | Displays Apple Pay for the Payment Services drop-in. |
+| [CreditCard](/dropins/payment-services/containers/credit-card/) | Renders the credit or debit card form, including an optional **Save this card** option for signed-in shoppers. |
+| [StoredCards](/dropins/payment-services/containers/stored-cards/) | Lists vaulted (saved) cards and an optional “pay with a new card” row for checkout. |
diff --git a/src/content/docs/dropins/payment-services/containers/stored-cards.mdx b/src/content/docs/dropins/payment-services/containers/stored-cards.mdx
new file mode 100644
index 000000000..1e34c6ad9
--- /dev/null
+++ b/src/content/docs/dropins/payment-services/containers/stored-cards.mdx
@@ -0,0 +1,72 @@
+---
+title: StoredCards Container
+description: Learn about the StoredCards container for vaulted saved cards at checkout.
+sidebar:
+ label: StoredCards
+---
+
+import Diagram from '@components/Diagram.astro';
+import { Aside } from '@astrojs/starlight/components';
+import TableWrapper from '@components/TableWrapper.astro';
+
+The `StoredCards` container renders a Stored payment methods section with one radio row per vaulted card (brand, masked number, expiry) and an optional Pay with a new card option. The host checkout block handles loading tokens, syncing the cart when a card is selected, and mounting the [CreditCard](/dropins/payment-services/containers/credit-card/) form when the shopper chooses a new card. See [Vaulted cards at checkout](/dropins/payment-services/tutorials/vaulted-cards-checkout/).
+
+## Checkout appearance
+
+The screenshots below show the Payment section when **Credit card** is selected and vaulted cards are available—showing the same flows described in the [Vaulted cards at checkout](/dropins/payment-services/tutorials/vaulted-cards-checkout/) tutorial.
+
+### Saved card selected
+
+The shopper selects a vaulted card. The host typically syncs the selected token to the cart and does not mount the hosted card form.
+
+
+ 
+
+
+### Pay with a new card
+
+The shopper selects **Pay with a new card**. The host mounts the [CreditCard](/dropins/payment-services/containers/credit-card/) form in the same checkout section.
+
+
+ 
+
+
+## Configuration
+
+The `StoredCards` container accepts standard `fieldset` HTML attributes plus:
+
+
+
+| Parameter | Type | Req? | Description |
+|---|---|---|---|
+| `cards` | `StoredCard[]` | Yes | Vault rows to display. Each `StoredCard` includes `publicHash` and optional `brand`, `maskedNumber`, `expiry`, `holderName`. |
+| `onPaymentChoice` | `function` | No | Called when the shopper selects a saved card or **Pay with a new card**. Payload is `{ kind: 'vault', card }` or `{ kind: 'new' }`. |
+| `payWithNewCardLabel` | `string` | No | When set, renders an extra radio row after stored cards (for example, `Pay with a new card`). |
+| `selectedChoice` | `object \| null` | No | Controlled selection: `{ kind: 'new' }` or `{ kind: 'vault', publicHash: string }`. |
+
+
+
+## Slots
+
+This container does not expose any customizable slots.
+
+
+
+## Usage
+
+```js
+import { StoredCards } from '@dropins/storefront-payment-services/containers/StoredCards.js';
+import { render as provider } from '@dropins/storefront-payment-services/render.js';
+
+await provider.render(StoredCards, {
+ cards: [/* mapped from vault tokens */],
+ payWithNewCardLabel: 'Pay with a new card',
+ onPaymentChoice: (choice) => {
+ /* sync cart, mount or hide CreditCard */
+ },
+})(document.getElementById('stored-cards'));
+```
+
+For end-to-end wiring (tokens, `syncVaultToCart`, place order), use the [vault helpers](/dropins/payment-services/functions/) and the [Vaulted cards at checkout](/dropins/payment-services/tutorials/vaulted-cards-checkout/) tutorial.
diff --git a/src/content/docs/dropins/payment-services/dictionary.mdx b/src/content/docs/dropins/payment-services/dictionary.mdx
index 0582bca73..f0ff78759 100644
--- a/src/content/docs/dropins/payment-services/dictionary.mdx
+++ b/src/content/docs/dropins/payment-services/dictionary.mdx
@@ -16,10 +16,6 @@ The **Payment Services dictionary** contains all user-facing text, labels, and m
Dictionaries use the **i18n (internationalization)** pattern, where each text string is identified by a unique key path.
-
-Version: 3.1.0
-
-
## How to customize
Override dictionary values during drop-in initialization. The drop-in deep-merges your custom values with the defaults.
@@ -69,6 +65,9 @@ Below are the default English (`en_US`) strings provided by the **Payment Servic
"message": "An unexpected error occurred. Please try again or contact support."
}
},
+ "saveCard": {
+ "label": "Save this card for future purchases"
+ },
"formFields": {
"cvv": {
"invalidError": "Enter valid cvv.",
@@ -94,6 +93,10 @@ Below are the default English (`en_US`) strings provided by the **Payment Servic
"methodNotAvailable": "Payment method not available. Please contact support.",
"methodNotLoaded": "Failed to load payment method. Please try again later.",
"methodLoading": "Loading payment method..."
+ },
+ "StoredCards": {
+ "groupLegend": "Stored payment methods",
+ "selectSavedCard": "Select saved card"
}
}
}
diff --git a/src/content/docs/dropins/payment-services/events.mdx b/src/content/docs/dropins/payment-services/events.mdx
index 3b57f98d0..699fea784 100644
--- a/src/content/docs/dropins/payment-services/events.mdx
+++ b/src/content/docs/dropins/payment-services/events.mdx
@@ -7,9 +7,24 @@ sidebar:
---
import { Aside } from '@astrojs/starlight/components';
+import TableWrapper from '@components/TableWrapper.astro';
-This drop-in does not emit or listen to any drop-in-specific events.
+The Payment Services drop-in does not define its own namespaced events (for example, payment-services/...) for vault or payment UI. Instead, checkout integrations typically use the [Checkout](/dropins/checkout/) drop-in’s values and events. See the [Vaulted cards at checkout](/dropins/payment-services/tutorials/vaulted-cards-checkout/) tutorial for how the Commerce boilerplate combines `StoredCards` and `CreditCard`.
-
-Version: 3.1.0
-
+## Network errors and the `error` event
+
+GraphQL requests used in vault flows (for example, loading customer payment tokens) can share a common fetch error handler. If a request fails—and the error is not due to an abort—the handler can emit the global error event on the Adobe Commerce event bus with a payload such as:
+
+```json
+{
+ "source": "payment-services",
+ "type": "network",
+ "error": { }
+}
+```
+
+Subscribe to **`error`** if you need to correlate network failures with Payment Services. For broader patterns, see [Common events](/dropins/all/common-events/).
+
+
diff --git a/src/content/docs/dropins/payment-services/functions.mdx b/src/content/docs/dropins/payment-services/functions.mdx
index 0e0776fe4..80f7872a0 100644
--- a/src/content/docs/dropins/payment-services/functions.mdx
+++ b/src/content/docs/dropins/payment-services/functions.mdx
@@ -36,14 +36,106 @@ tableOfContents:
*/}
import TableWrapper from '@components/TableWrapper.astro';
-import Link from '@components/Link.astro';
-import { Aside } from '@astrojs/starlight/components';
-This drop-in currently has no functions defined.
+The Payment Services drop-in provides GraphQL helpers for vaulted (saved) card checkout. Additional functions may appear in the generated section below when sourced from the drop-in repository.
-
-Version: 3.1.0
-
+
+
+| Function | Description |
+| --- | --- |
+| [`getCustomerPaymentTokens`](#getcustomerpaymenttokens) | Loads vaulted Payment Services card tokens for the signed-in customer via the `customerPaymentTokens` query. |
+| [`createPaymentOrderForVault`](#createpaymentorderforvault) | Creates a PayPal / MP payment order for vault checkout using `createPaymentOrder`. |
+| [`syncVaultToCart`](#syncvaulttocart) | Runs vault `createPaymentOrder` then `setPaymentMethod` using your checkout `fetchGraphQl` and cart APIs. |
+| [`normalizedVaultTokenToStoredCardProps`](#normalizedvaulttokentostoredcardprops) | Maps a `NormalizedVaultToken` to props for the [StoredCards](/dropins/payment-services/containers/stored-cards/) container. |
+
+
+
+## getCustomerPaymentTokens
+
+The `getCustomerPaymentTokens` function retrieves customer payment tokens using this package’s GraphQL client (GET). The initializer must configure the endpoint and headers (see [Initialization](/dropins/payment-services/initialization/)). Results are filtered to Payment Services vaulted card tokens and returned as **`NormalizedVaultToken[]`**.
+
+```ts
+export async function getCustomerPaymentTokens(): Promise
+```
+
+### Returns
+
+Returns **`NormalizedVaultToken[]`**. See the [StoredCards container](/dropins/payment-services/containers/stored-cards/) and [`normalizedVaultTokenToStoredCardProps`](#normalizedvaulttokentostoredcardprops) (including **Related types**).
+
+## createPaymentOrderForVault
+
+The `createPaymentOrderForVault` function calls the vault `createPaymentOrder` mutation and returns the PayPal and MP order IDs used to build the payment method payload.
+
+```ts
+export async function createPaymentOrderForVault(
+ cartId: string
+): Promise
+```
+
+
+
+| Parameter | Type | Req? | Description |
+| --- | --- | --- | --- |
+| `cartId` | `string` | Yes | Active cart id for the checkout session. |
+
+
+
+### Returns
+
+Returns **`{ paypalOrderId, paymentsOrderId }`**. Throws if the mutation returns no order ids.
+
+## syncVaultToCart
+
+The `syncVaultToCart` function manages the vault checkout flow for storefronts that provide checkout (or mesh) `fetchGraphQl` and cart `setPaymentMethod`. It follows the same `createPaymentOrder` flow as `createPaymentOrderForVault`, builds the vault-specific additional data using the token’s `public_hash`, and then calls `setPaymentMethod` with `PaymentMethodCode.VAULT`.
+
+```ts
+export async function syncVaultToCart(
+ token: { publicHash?: string },
+ cartId: string | undefined,
+ deps: VaultCheckoutSyncDeps
+): Promise | null>
+```
+
+
+
+| Parameter | Type | Req? | Description |
+| --- | --- | --- | --- |
+| `token` | `{ publicHash?: string }` | Yes | Vault token; must include **`publicHash`** for vault additional data. |
+| `cartId` | `string \| undefined` | Yes | Active cart id; if missing, the function returns `null`. |
+| `deps` | `VaultCheckoutSyncDeps` | Yes | **`fetchGraphQl`** and **`setPaymentMethod`** implementations from your checkout integration. |
+
+
+
+### Returns
+
+Returns the payment method payload passed to **`setPaymentMethod`**, or **`null`** on failure.
+
+## normalizedVaultTokenToStoredCardProps
+
+Maps a **`NormalizedVaultToken`** to the **`VaultStoredCardProps`** shape (aligned with **StoredCards** **`cards`** rows).
+
+```ts
+export function normalizedVaultTokenToStoredCardProps(
+ token: NormalizedVaultToken
+): VaultStoredCardProps
+```
+
+### Related types
+
+Use these types from `@dropins/storefront-payment-services/api.js` for advanced integrations:
+
+```ts
+/** Normalized vault token used in checkout / StoredCards wiring. */
+type NormalizedVaultToken = {
+ publicHash?: string;
+ methodCode: string;
+ type: string;
+ brand: string;
+ masked: string;
+ expiry: string;
+ holder: string;
+};
+```
{/* AUTO-GENERATED CONTENT - Do not edit below this line */}
diff --git a/src/content/docs/dropins/payment-services/index.mdx b/src/content/docs/dropins/payment-services/index.mdx
index 75ab21d7e..6ecfc3c00 100644
--- a/src/content/docs/dropins/payment-services/index.mdx
+++ b/src/content/docs/dropins/payment-services/index.mdx
@@ -5,7 +5,7 @@ description: Learn about the features of the Payment Services drop-in component.
import { Badge } from '@astrojs/starlight/components';
-The Payment Services drop-in component renders the credit card form and the Apple Pay button.
+The Payment Services drop-in component renders the credit card form, optional vaulted (saved) cards for signed-in shoppers, and the Apple Pay button.
## Supported payment methods
@@ -27,11 +27,13 @@ import { PaymentMethodCode } from '@dropins/storefront-payment-services/api.js';
## Available containers
-The Payment Services drop-in component provides two containers:
+The Payment Services drop-in component provides these containers:
- **Apple Pay container:** The `ApplePay` container renders an Apple Pay button that shoppers on Apple devices can use to place an order.
-- **Credit card container:** The `CreditCard` container renders a form where shoppers enter their card details to place an order with a credit or debit card.
+- **Credit card container:** The `CreditCard` container renders a form where shoppers enter their card details to place an order with a credit or debit card. When the shopper is authenticated (via `getCustomerToken` on the initializer or container), the form can show a **Save this card** option for vaulting.
+
+- **Stored cards container:** The `StoredCards` container displays vaulted cards and can include a **pay with a new card** row. Use it with the vault APIs on `@dropins/storefront-payment-services/api.js` to load tokens and sync the cart when a saved card is selected. See the [StoredCards container](/dropins/payment-services/containers/stored-cards/) page and the [Vaulted cards at checkout](/dropins/payment-services/tutorials/vaulted-cards-checkout/) tutorial.
## Additional resources
diff --git a/src/content/docs/dropins/payment-services/initialization.mdx b/src/content/docs/dropins/payment-services/initialization.mdx
index a74cc1a96..a8d3b3d6d 100644
--- a/src/content/docs/dropins/payment-services/initialization.mdx
+++ b/src/content/docs/dropins/payment-services/initialization.mdx
@@ -11,10 +11,6 @@ import { Aside } from '@astrojs/starlight/components';
The **Payment Services initializer** configures payment processing features including payment methods, payment providers, and transaction handling. Use initialization to integrate payment gateways and customize payment data models.
-
-Version: 3.1.0
-
-
## Configuration options
@@ -27,11 +23,15 @@ The following table describes the configuration options available for the **Paym
|---|---|---|---|
| `langDefinitions` | [`LangDefinitions`](#langdefinitions) | No | Language definitions for internationalization (i18n). Override dictionary keys for localization or branding. |
| `apiUrl` | `string` | No | |
-| `getCustomerToken` | `(() => string \| null) \| null` | No | |
+| `getCustomerToken` | `(() => string \| null) \| null` | No | Returns the customer's authentication token for API requests. For UI behavior like the save-card checkbox, see the [`authenticated`](/dropins/all/common-events/#authenticated) event. |
| `storeViewCode` | `string` | No | |
+
+
## Default configuration
The initializer runs with these defaults when no configuration is provided:
diff --git a/src/content/docs/dropins/payment-services/slots.mdx b/src/content/docs/dropins/payment-services/slots.mdx
index f09a44500..33b50c1ba 100644
--- a/src/content/docs/dropins/payment-services/slots.mdx
+++ b/src/content/docs/dropins/payment-services/slots.mdx
@@ -10,17 +10,25 @@ tableOfContents:
---
import TableWrapper from '@components/TableWrapper.astro';
-import { Aside } from '@astrojs/starlight/components';
The Payment Services drop-in does not expose any slots for customization.
+
+
+| Container | Slots |
+| --- | --- |
+| ApplePay | None (SDK-rendered) |
+| CreditCard | None (SDK-rendered) |
+| StoredCards | None (optional vaulted-card UI; use props, dictionary, and styles) |
+
+
+
## Why no slots?
This drop-in wraps the Adobe Payment Services SDK (`@adobe-commerce/payment-services-sdk`), which renders secure payment forms directly into specified DOM elements. The SDK controls all UI rendering to maintain PCI (Payment Card Industry) compliance and security standards. You customize the payment forms through SDK configuration options (field placeholders, card type settings, callback handlers) passed to `sdk.Payment.CreditCard.render()`, not through the slot-based pattern other drop-ins use.
-
-Version: 3.1.0
-
+`StoredCards` (optional, for vaulted cards at checkout) is separate from the SDK card form and does not provide slots. When used, customize the layout and copy through [container props](/dropins/payment-services/containers/stored-cards/#configuration), the [dictionary](/dropins/payment-services/dictionary/), and [styles](/dropins/payment-services/styles/).
+
diff --git a/src/content/docs/dropins/payment-services/styles.mdx b/src/content/docs/dropins/payment-services/styles.mdx
index a861cf04d..8fc101485 100644
--- a/src/content/docs/dropins/payment-services/styles.mdx
+++ b/src/content/docs/dropins/payment-services/styles.mdx
@@ -52,6 +52,18 @@ The Payment Services drop-in uses BEM-style class naming. Use the browser DevToo
.payment-services-credit-card-form__eligible-cards-selected {}
.payment-services-credit-card-form__eligible-cards-unselected {}
.payment-services-credit-card-form__loading {}
+.payment-services-credit-card-form__save-card {}
+
+/* PaymentCard (vault rows and “pay with a new card”) */
+.payment-services-payment-card {}
+.payment-services-payment-card--selected {}
+.payment-services-payment-card__content {}
+.payment-services-payment-card__line {}
+.payment-services-payment-card__holder {}
+
+/* StoredCards fieldset */
+.payment-services-stored-cards {}
+.payment-services-stored-cards__legend {}
```
diff --git a/src/content/docs/dropins/payment-services/tutorials/vaulted-cards-checkout.mdx b/src/content/docs/dropins/payment-services/tutorials/vaulted-cards-checkout.mdx
new file mode 100644
index 000000000..f4da8d36d
--- /dev/null
+++ b/src/content/docs/dropins/payment-services/tutorials/vaulted-cards-checkout.mdx
@@ -0,0 +1,62 @@
+---
+title: Vaulted cards at checkout
+description: How the Payment Services drop-in shows saved cards and paying with a new card during checkout, including how the Commerce boilerplate wires the checkout block.
+---
+
+import Link from '@components/Link.astro';
+import Diagram from '@components/Diagram.astro';
+import { Aside } from '@astrojs/starlight/components';
+
+This page is checkout-focused: it describes the Credit card experience when vaulted tokens are available (stored rows plus Pay with a new card), the Payment Services containers and APIs used to build it, and where the Commerce boilerplate integrates this flow. Saved payment methods in **My Account** are handled by the [User Account](/dropins/user-account/) drop-in (for example, the `PaymentMethods` container, depending on your storefront version).
+
+When **Credit card** is selected and the shopper is signed in with vaulted cards, checkout displays **Stored payment methods**: each saved card as a selectable row, along with **Pay with a new card** to open the card form. The [CreditCard](/dropins/payment-services/containers/credit-card/) and [StoredCards](/dropins/payment-services/containers/stored-cards/) containers work together with helpers from [`@dropins/storefront-payment-services/api.js`](/dropins/payment-services/functions/) and [initialization](/dropins/payment-services/initialization/) (for example, `getCustomerToken`).
+
+
+
+## Prerequisites
+
+- **Payment Services** is and the meets the version your storefront uses for vault checkout.
+- Vaulted card creation and token behavior follow Adobe’s .
+- Checkout loads the Payment Services initializer (for example, the boilerplate ).
+- Use a storefront or boilerplate version that includes vaulted checkout support if you’re following the reference implementation below.
+
+## Pay with a saved card
+
+The shopper can select a vaulted card to charge that payment method without re-entering full card details.
+
+
+ 
+
+
+## Pay with a new card
+
+Choosing **Pay with a new card** displays the secure card form (card number, expiration, CVV), along with card brand icons and, when vaulting is enabled for the session, an option to **Save this card for future purchases**.
+
+
+ 
+
+
+## Reference implementation (Commerce boilerplate)
+
+The [Commerce boilerplate](https://github.com/hlxsites/aem-boilerplate-commerce) checkout block shows how to compose the Checkout `PaymentMethods` slot with Payment Services `StoredCards` and `CreditCard`. You can reference the same files you would customize in your own project:
+
+- **`blocks/commerce-checkout/containers.js`** — For **Credit card**, the block loads eligible vault tokens for signed-in shoppers, renders `StoredCards` using mapped vault data (`getVaultEligibleTokensFromCustomerPaymentTokensData`, `normalizedVaultTokenToStoredCardProps`), calls `syncVaultToCart` when a saved card is selected, and mounts `CreditCard` when Pay with a new card is chosen. It also adjusts payment method sync and `autoSync` when vault tokens are present to keep the cart aligned with the UI.
+- **`blocks/commerce-checkout/commerce-checkout.js`** — **Place order** uses the selected payment method (including the vault flow), allowing a stored card to complete the order without submitting the hosted card form.
+- **`blocks/commerce-checkout/commerce-checkout.css`** — Controls the layout and stacking of the credit card section when vault is enabled (for example, the wrapper around stored cards and the new card form).
+
+Use the repository history or your integration branch to find the revision that includes this wiring; file names typically remain stable on `main` over time.
+
+
+
+## Related documentation
+
+- [StoredCards container](/dropins/payment-services/containers/stored-cards/) — props and behavior for the stored-card list at checkout.
+- [CreditCard container](/dropins/payment-services/containers/credit-card/) — hosted form, **Save this card**, and refs.
+- [Functions (API)](/dropins/payment-services/functions/) — vault helpers, tokens, and GraphQL entry points exported from the drop-in.
+- [Initialization](/dropins/payment-services/initialization/) — Payment Services configuration and customer token.
+- [Add payment method](/dropins/checkout/tutorials/add-payment-method/) — Checkout **PaymentMethods** slot patterns for other providers.
+- [User Account](/dropins/user-account/) — account experiences, including saved payment methods when your docs version includes them.
diff --git a/src/content/docs/dropins/user-account/containers/addresses.mdx b/src/content/docs/dropins/user-account/containers/addresses.mdx
index 1336a9728..0986e5aeb 100644
--- a/src/content/docs/dropins/user-account/containers/addresses.mdx
+++ b/src/content/docs/dropins/user-account/containers/addresses.mdx
@@ -75,6 +75,7 @@ compact
options={[
['Options', 'Type', 'Req?', 'Description'],
['hideActionFormButtons', 'boolean', 'No', 'Controls the visibility of action buttons at the form\'s bottom. Useful for custom integrations where form submission is managed externally.'],
+ ['fieldIdPrefix', 'string', 'No', 'Prefixes every form field HTML `id` rendered inside the container. For example, `shipping` produces ids such as `shipping_firstname`. Use different values when you render two `Addresses` containers on the same page (such as shipping and billing forms in checkout) to prevent duplicate HTML element ids.'],
['formName', 'string', 'No', 'Sets the "name" attribute for the form. Defaults to "addressesForm" if not provided. Useful for custom integrations.'],
['slots.AddressCard', 'slot', 'No', 'Allows overriding address card content, such as rendering additional data or changing layout.'],
['slots.AddressFormActions', 'AddressFormActionsContext', 'No', 'Provides an option to override the call-to-action buttons for the address form.'],