Skip to main content

<primer-vault-manager>

Displays saved payment methods for returning customers. Supports viewing, selecting, deleting, and paying with vaulted methods. Includes CVV recapture when required.

Quick Reference

Parent<primer-checkout>
Requiresoptions.vault.enabled: true
Slotsubmit-button
Emitsprimer:vault:methods-update, primer:vault:selection-change
Listens forprimer:vault-submit

Examples

Basic (auto-integrated)

When vault is enabled, appears automatically in the default layout:
const checkout = document.querySelector('primer-checkout');
checkout.options = {
  vault: { enabled: true }
};

Custom Layout

Include manually when using custom layouts:
<primer-checkout client-token="your-token">
  <primer-main slot="main">
    <div slot="payments">
      <primer-vault-manager></primer-vault-manager>
      
      <primer-show-other-payments>
        <div slot="other-payments">
          <primer-payment-method type="PAYMENT_CARD"></primer-payment-method>
        </div>
      </primer-show-other-payments>
    </div>
  </primer-main>
</primer-checkout>

Custom Submit Button

<primer-vault-manager>
  <button slot="submit-button" type="submit">Pay with Saved Card</button>
</primer-vault-manager>
Button requirements: type="submit" or data-submit attribute.

External Submit Button

document.getElementById('my-pay-button').addEventListener('click', () => {
  document.dispatchEvent(
    new CustomEvent('primer:vault-submit', {
      bubbles: true,
      composed: true
    })
  );
});
Note: bubbles: true and composed: true are required for shadow DOM traversal.

Configuration

checkout.options = {
  vault: {
    enabled: true,       // Required
    headless: false,     // Hide default UI for custom implementation
    showEmptyState: true
  }
};
Backend required: Your client session must be configured for vaulting. See Save Payment Methods.

Events

Emitted Events

EventWhenPayload
primer:vault:methods-updateMethods loaded/changed{ vaultedPayments, cvvRecapture }
primer:vault:selection-changeUser selects method{ paymentMethodId, timestamp }

Listened Events

EventPurpose
primer:vault-submitTriggers payment with selected method

Tracking Selection

checkout.addEventListener('primer:vault:selection-change', (event) => {
  const { paymentMethodId } = event.detail;
  submitButton.disabled = !paymentMethodId;
});

Slots

SlotDescriptionRequirements
submit-buttonCustom submit buttontype="submit" or data-submit

States

StateDescription
LoadingFetching saved methods
EmptyNo saved methods
ListShowing methods with submit button
EditManaging methods (delete)
Delete ConfirmationConfirming deletion
ProcessingPayment in progress

Headless Mode

Build completely custom vault UI while retaining full functionality:
checkout.options = {
  vault: {
    enabled: true,
    headless: true
  }
};

checkout.addEventListener('primer:ready', (event) => {
  const primer = event.detail;
  
  primer.onVaultedMethodsUpdate = async ({ vaultedPayments, cvvRecapture }) => {
    const methods = vaultedPayments.toArray();
    
    methods.forEach(method => {
      if (method.paymentInstrumentType === 'PAYMENT_CARD') {
        const { network, last4Digits } = method.paymentInstrumentData;
        // Render: Visa •••• 4242
      }
    });
    
    if (cvvRecapture) {
      const cvvInput = await primer.vault.createCvvInput({
        cardNetwork: methods[0].paymentInstrumentData.network,
        container: '#cvv-container'
      });
    }
  };
});

Headless Methods

MethodDescription
primer.vault.createCvvInput(options)Create CVV input for recapture
primer.vault.startPayment(id, options?)Start payment with vaulted method
primer.vault.delete(id)Delete a vaulted method

Payment Data by Type

TypeFields
PAYMENT_CARDnetwork, last4Digits, cardholderName, expirationMonth, expirationYear
PAYPAL_BILLING_AGREEMENTemail, firstName, lastName, externalPayerId
KLARNA_CUSTOMER_TOKENemail, firstName, lastName
ACHaccountNumberLastFourDigits, bankName, accountType

CSS Properties

Layout

PropertyDescriptionDefault
--primer-space-smallGap between saved payment methods8px
--primer-space-mediumInternal padding12px
--primer-space-xlargeSection spacing20px

Typography

PropertyDescriptionDefault
--primer-typography-title-large-sizeHeader text size16px
--primer-typography-title-large-weightHeader text weight550
--primer-typography-body-medium-sizeCard details text14px
--primer-typography-body-small-sizeSecondary info text12px

Colors

PropertyDescription
--primer-color-text-primaryPrimary text color
--primer-color-text-secondarySecondary text (card details)
--primer-color-text-disabledDisabled text
--primer-color-icon-primaryPayment method icons

Borders & Backgrounds

PropertyDescription
--primer-color-border-outlined-defaultCard item border
--primer-color-border-outlined-selectedSelected card border
--primer-color-background-outlined-defaultCard item background
--primer-color-background-outlined-hoverHover background
--primer-radius-mediumCard item border radius

Delete Confirmation

PropertyDescription
--primer-color-red-100Warning background
--primer-color-red-500Delete button color
--primer-color-text-negativeWarning text

Animation

PropertyDescriptionDefault
--primer-animation-durationTransition duration200ms
--primer-animation-easingTransition easingcubic-bezier(0.44, 0, 0.4, 1)

Dependencies

Works with:
ComponentPurpose
primer-show-other-paymentsCollapses other methods when vault has saved cards

Usage Guidelines

Do

  • Enable vault in SDK options: vault: { enabled: true }
  • Configure client session on backend for vaulting
  • Use with <primer-show-other-payments> in custom layouts
  • Track selection state for custom submit buttons

Don’t

  • Don’t use without backend vault configuration
  • Don’t mix default UI with headless mode
  • Don’t forget to handle empty state UX

Content Guidelines

Delete confirmation

DoDon’t
”Remove this card?""Delete?"
"Visa ending in 4242 will be removed""Are you sure?”

Empty state

DoDon’t
”No saved payment methods""Empty"
"Save a card for faster checkout next time""Nothing here”