1
createVaultManager(): HeadlessVaultManager
ts
copy

Get an instance of HeadlessVaultManager, which can be used to:

Example:

123456789101112
// Headless Checkout initialisationconst headless = await Primer.createHeadless(clientToken)await headless.configure({    onAvailablePaymentMethodsLoad: () => {        // create your UI for displaying payment methods    },    container: '#checkout-container',})await headless.start()
// Headless Vault Manager initialisationconst vaultManager = headless.createVaultManager()
ts
copy

Returns

An instance of HeadlessVaultManager.

HeadlessVaultManager
fetchVaultedPaymentMethods
() => Promise<VaultedPaymentMethod[]>

Get a list of VaultedPaymentMethod for the customerId attached to the client session. Build your own UI to display, manage and perform payments with them.

The list of vaulted payment methods is not affected by the checkout builder's conditions. For example, if you configured the checkout builder to not show Paypal with the current client session, but Paypal was vaulted previously, fetchVaultedPaymentMethods will still return it.

This issue will be addressed and resolved in an upcoming release.

1234
// Initialise Headless Checkout ...
const vaultManager = headless.createVaultManager()const vaultedPaymentMethods = await vaultManager.fetchVaultedPaymentMethods()
ts
copy

Throws an error if the call to retrieve the vaulted payment methods fails.

VaultedPaymentMethod
id
string

A temporary identifier for the vaulted payment method. You should use this id with deleteVaultedPaymentMethod, and startPaymentFlow.

ℹ️ This id changes with each call to fetchVaultedPaymentMethods.

An identifier for the vaulted payment method that doesn't change across calls to fetchVaultedPaymentMethods.

Data associated to the payment instrument. You can use this information to display the vaulted payment method in your UI.

As an example, for a vaulted card, you will receive:

123456789101112131415161718192021
{    "first6Digits": "411111",    "last4Digits": "1111",    "expirationMonth": "05",    "expirationYear": "2030",    "cardholderName": "Primer Test",    "network": "VISA",    "binData": {        "network": "VISA",        "issuerCountryCode": "US",        "issuerName": "TEST BANK, N.A.",        "regionalRestriction": "UNKNOWN",        "accountNumberType": "UNKNOWN",        "accountFundingType": "UNKNOWN",        "prepaidReloadableIndicator": "NOT_APPLICABLE",        "productUsageType": "UNKNOWN",        "productCode": "UNKNOWN",        "productName": "UNKNOWN"    },    "isNetworkTokenized": false}
ts
copy

The type of the payment instrument associated to the vaulted payment method.

Examples of possible values (new values could be added as we add new payment methods):

  • APPLE_PAY
  • CARD_OFF_SESSION_PAYMENT
  • GOOGLE_PAY
  • KLARNA_CUSTOMER_TOKEN
  • OFF_SESSION_PAYMENT
  • PAYMENT_CARD
  • PAYPAL_BILLING_AGREEMENT
  • PAYPAL_ORDER
threeDSecureAuthentication
Nullable<ThreeDSAuthenticationData>
userDescription
Optional<string>
deleteVaultedPaymentMethod
(vaultedPaymentMethodId: string) => Promise<void>

Delete a vaulted payment method by id for the customerId attached to the client session.

You can get the id from any instance of VaultedPaymentMethod returned by fetchVaultedPaymentMethods.

12345678910
// Initialise Headless Checkout ...
const vaultManager = headless.createVaultManager()const vaultedPaymentMethods = await vaultManager.fetchVaultedPaymentMethods()// Delete the first vaulted payment methodtry {    await vaultManager.deleteVaultedPaymentMethod(vaultedPaymentMethods[0]?.id)} catch (error) {    // handle errors}
ts
copy

Throws an error if the id passed does not match any payment method previously retrieved by fetchVaultedPaymentMethods.

Throws an error if the call to delete the vaulted payment method fails.

VaultedPaymentMethod
id
string

A temporary identifier for the vaulted payment method. You should use this id with deleteVaultedPaymentMethod, and startPaymentFlow.

ℹ️ This id changes with each call to fetchVaultedPaymentMethods.

An identifier for the vaulted payment method that doesn't change across calls to fetchVaultedPaymentMethods.

Data associated to the payment instrument. You can use this information to display the vaulted payment method in your UI.

As an example, for a vaulted card, you will receive:

123456789101112131415161718192021
{    "first6Digits": "411111",    "last4Digits": "1111",    "expirationMonth": "05",    "expirationYear": "2030",    "cardholderName": "Primer Test",    "network": "VISA",    "binData": {        "network": "VISA",        "issuerCountryCode": "US",        "issuerName": "TEST BANK, N.A.",        "regionalRestriction": "UNKNOWN",        "accountNumberType": "UNKNOWN",        "accountFundingType": "UNKNOWN",        "prepaidReloadableIndicator": "NOT_APPLICABLE",        "productUsageType": "UNKNOWN",        "productCode": "UNKNOWN",        "productName": "UNKNOWN"    },    "isNetworkTokenized": false}
ts
copy

The type of the payment instrument associated to the vaulted payment method.

Examples of possible values (new values could be added as we add new payment methods):

  • APPLE_PAY
  • CARD_OFF_SESSION_PAYMENT
  • GOOGLE_PAY
  • KLARNA_CUSTOMER_TOKEN
  • OFF_SESSION_PAYMENT
  • PAYMENT_CARD
  • PAYPAL_BILLING_AGREEMENT
  • PAYPAL_ORDER
threeDSecureAuthentication
Nullable<ThreeDSAuthenticationData>
userDescription
Optional<string>
startPaymentFlow
(vaultedPaymentMethodId: string) => Promise<void>

Starts the payment flow. You should pass as a parameter the id of a VaultedPaymentMethod previously retrieved with fetchVaultedPaymentMethods.

Upon a successful invocation of this function, the SDK will automatically trigger the standard payment callbacks.

1234567891011
// Initialise Headless Checkout ...
const vaultManager = headless.createVaultManager()
const vaultedPaymentMethods = await vaultManager.fetchVaultedPaymentMethods()// Start the payment flow using the first vaulted payment methodtry {    await vaultManager.startPaymentFlow(vaultedPaymentMethods[0]?.id)} catch (error) {    // handle errors}
ts
copy

Throws an error if the id passed does not match any payment method previously retrieved by fetchVaultedPaymentMethods.

Throws an error if the paymentInstrumentType in the vaulted payment method passed in is not recognised.

VaultedPaymentMethod
id
string

A temporary identifier for the vaulted payment method. You should use this id with deleteVaultedPaymentMethod, and startPaymentFlow.

ℹ️ This id changes with each call to fetchVaultedPaymentMethods.

An identifier for the vaulted payment method that doesn't change across calls to fetchVaultedPaymentMethods.

Data associated to the payment instrument. You can use this information to display the vaulted payment method in your UI.

As an example, for a vaulted card, you will receive:

123456789101112131415161718192021
{    "first6Digits": "411111",    "last4Digits": "1111",    "expirationMonth": "05",    "expirationYear": "2030",    "cardholderName": "Primer Test",    "network": "VISA",    "binData": {        "network": "VISA",        "issuerCountryCode": "US",        "issuerName": "TEST BANK, N.A.",        "regionalRestriction": "UNKNOWN",        "accountNumberType": "UNKNOWN",        "accountFundingType": "UNKNOWN",        "prepaidReloadableIndicator": "NOT_APPLICABLE",        "productUsageType": "UNKNOWN",        "productCode": "UNKNOWN",        "productName": "UNKNOWN"    },    "isNetworkTokenized": false}
ts
copy

The type of the payment instrument associated to the vaulted payment method.

Examples of possible values (new values could be added as we add new payment methods):

  • APPLE_PAY
  • CARD_OFF_SESSION_PAYMENT
  • GOOGLE_PAY
  • KLARNA_CUSTOMER_TOKEN
  • OFF_SESSION_PAYMENT
  • PAYMENT_CARD
  • PAYPAL_BILLING_AGREEMENT
  • PAYPAL_ORDER
threeDSecureAuthentication
Nullable<ThreeDSAuthenticationData>
userDescription
Optional<string>
createCvvInput
(options: CardSecurityCodeInputOptions) => Promise<CvvInput | null>

Create a CvvInput that can be used to safely pass the secure code associated to a vaulted card to Primer's backend.

For security reasons, the input is rendered in an iframe on Primer's domain and you won't be able to access programmatically the value stored in the input.

12345678910111213141516171819202122232425262728
const vaultManager = headless.createVaultManager()
// ... retrieve payment methods with fetchVaultedPaymentMethods
const cvvInput = await vaultManager.createCvvInput({    cardNetwork: vaultedPaymentMethod.paymentInstrumentData.network,    container: '#foo',    name: 'cvv',    style,    placeholder: '123',})
// Somewhere else in your code, create a `submitButton` to start the payment// and a `cvvError` container to show validation errors
submitButton.onclick = () => {    // use metadata to show error messages    cvvError.innerText = cvvInput.metadata.error ?? ''    // don't start the payment flow if the `CVVInput` is in an invalid state    if (cvvInput.metadata.error) return    try {        vaultManager.startPaymentFlow(vaultedPaymentMethod.id, {            cvv: cvvInput.valueToken,        })    } catch (error) {        // handle errors    }}
ts
copy
Parameters:
CardSecurityCodeInputOptions
container
string

A CSS selector that identifies the container where the CvvInput will be appended. If the container is not found and the CVVInput cannot be mounted, the Promise returned by createCVVInput is resolved with null and an error message is logged to the developer's console.

ariaLabel
Optional<string>

The aria-label attribute for the input element wrapped by CvvInput.

id
Optional<string>

The id attribute that will be assigned to the HTMLIFrameElement used by CvvInput.

name
Optional<string>

An optional name attribute for the input element wrapped by CvvInput.

The name you provide will always be prefixed with cvv-, so if for example you pass name: 'custom' the CVVInput will wrap an HTMLInputElement that looks like this:

1
<input name='cvv-custom' /* Other attributes */ />
ts
copy
placeholder
Optional<string>

The placeholder attribute for the input element wrapped by CvvInput.

placement
Optional<'append' | 'prepend'>

Whether to append or prepend the CvvInput to its container.

properties
Optional<Object>

Additional attributes that can be applied to the HTMLInputElement wrapped by CvvInput.

Any attribute that would be valid on an <input> can be used here, however:

  • name is taken directly from the CardSecurityCodeInputOptions options
  • maxLength and minLength will be inferred from the cardNetwork
  • type is always set to tel to provide a good UX when typing on a virtual keyboard
  • for security reasons event handlers such as onkeydown, onkeyup won't be serialized and passed down to the input

You can pass other attributes such as data-*, aria-*...

style
Optional<CheckoutStyle>

A CheckoutStyle object that will be applied to the input element.

cardNetwork
Optional<string>

The card network to determine the length of the field for CVV validation.

You should pass the paymentInstrumentData.network attribute on any of the VaultedPaymentMethods returned by fetchVaultedPaymentMethods.

If you don't pass a cardNetwork or the SDK cannot recognize the card network passed in, it will raise a warning and will default the validation of the CVV to a minimum length of 3 and a maximum length of 4.

Returns:
CvvInput

The valueToken representing the actual CVV value not accessible for security reasons.

You can forward the token to HeadlessVaultManager.startPaymentFlow as the cvv parameter and under the hood it will be replaced with the value entered by the user.

You can also access the valueToken and be informed of when it changes using addListener('change', listener).

123456789101112
// use `metadata` to check for validation errorsif (cvvInput.metadata.error) {    // display errors, don't start the payment flow    return}try {    vaultManager.startPaymentFlow(vaultedPaymentMethod.id, {        cvv: cvvInput.valueToken,    })} catch (error) {    // Handle startPaymentFlow errors}
ts
copy
addListener
(event: 'change' | 'focus' | 'blur', listener: Function) => Function

Add a listener for one of the supported events (change, focus and blur) and return a function that can be called without arguments to remove the listener.

focus and blur listeners do not receive any arguments.

change listeners receive the following arguments:

  • valueToken: a string representing the actual CVV value not accessible for security reasons
  • metadata: additional details on the state of the input field wrapped by the CvvInput.

Both valueToken and metadata can be also accessed directly on an instance of CvvInput (cvvInput.valueToken, cvvInput.metadata)

addEventListener
(event: 'change' | 'focus' | 'blur', listener: Function) => Function

Alias of addListener

removeListener
(event: 'change' | 'focus' | 'blur', listener: Function) => void

Removes a listener previously added with addListener. You should pass as parameters the exact same parameters passed to addListener.

Alternatively, you can just use the function returned by addListener.

Note: if you try to add a listener for an event that can't be handled, addListener will not add it and it will return undefined instead of a function to remove it.

focus
() => void

Give focus to the HTMLInputElement wrapped by CvvInput.

blur
() => void

Remove focus from the HTMLInputElement wrapped by CvvInput.

remove
() => {}

Removes the CvvInput field from the DOM and detaches all event listeners previously added with addListener.

frame
HTMLIFrameElement

A reference to the HTMLIFrameElement wrapping the input.

metadata
InputMetadata

Additional details on the state of the input field wrapped by the CvvInput.

InputMetadata
error
"cvvRequired" | "cvvIncomplete" | null
A label describing validation errors, `null` if the input value has no validation errors.
valid
boolean
True if the input value has no validation errors.
active
boolean
True if the input is focused.
dirty
boolean
True if the input value is different from the initial.
touched
boolean
True if the input has been touched once.
name
string

The name attribute of the underlying HTMLInputElement field.

Errors:

If the container passed in the parameters is not found and the CVVInput cannot be mounted, the promise is resolved with null and an error message is logged to the developer's console.

Example:

Wrap a CvvInput in a React component using addListener('change', listener):

1234567891011121314
const CvvInput = ({ onChange }) => {    useEffect(() => {        const cvvInput = headless.createCvvInput({            cardNetwork: vaultedPaymentMethod.paymentInstrumentData.network,            container: '#foo',            name: 'cvv',            style,            placeholder: '123',        })        cvvInput.addListener('change', onChange)    }, [])
    return <div id='foo' />}
ts
copy
12345678910111213
const CardForm = () => {    const vaultManager = useVaultManager()    const selectedVaultedPaymentMethod = useSelectedVaultedPaymentMethod()
    const [cvv, setCvv] = useState('')
    return (        <div>            <CvvInput onChange={value => setCvv(value)} />            <SubmitButton onClick={() => vaultManager.startPaymentFlow(vaultedPaymentMethod.id, { cvv })} />        </div>    )}
ts
copy

Throws

  • Throws an error if a customer.customerId is not provided in the client session
  • Throws an error if the Headless Instance was not started