createVaultManager(): HeadlessVaultManager
HeadlessVaultManager
, which can be used to:
customerId
attached to the client sessioncustomerId
attached to the client session// Headless Checkout initialisation
const headless = await Primer.createHeadless(clientToken, {
onAvailablePaymentMethodsLoad: () => {
// create your UI for displaying payment methods
},
container: "#checkout-container",
});
await headless.start();
// Headless Vault Manager initialisation
const vaultManager = headless.createVaultManager();
HeadlessVaultManager
.
Hide HeadlessVaultManager
VaultedPaymentMethod
for the customerId
attached to the client session.
Build your own UI to display, manage and perform payments with them.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.// Initialise Headless Checkout ...
const vaultManager = headless.createVaultManager();
const vaultedPaymentMethods = await vaultManager.fetchVaultedPaymentMethods();
Show VaultedPaymentMethod
{
"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
}
APPLE_PAY
CARD_OFF_SESSION_PAYMENT
GOOGLE_PAY
KLARNA_CUSTOMER_TOKEN
OFF_SESSION_PAYMENT
PAYMENT_CARD
PAYPAL_BILLING_AGREEMENT
PAYPAL_ORDER
customerId
attached to the client session.You can get the id from any instance of VaultedPaymentMethod returned by fetchVaultedPaymentMethods.// Initialise Headless Checkout ...
const vaultManager = headless.createVaultManager();
const vaultedPaymentMethods = await vaultManager.fetchVaultedPaymentMethods();
// Delete the first vaulted payment method
try {
await vaultManager.deleteVaultedPaymentMethod(vaultedPaymentMethods[0]?.id);
} catch (error) {
// handle errors
}
Show VaultedPaymentMethod
{
"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
}
APPLE_PAY
CARD_OFF_SESSION_PAYMENT
GOOGLE_PAY
KLARNA_CUSTOMER_TOKEN
OFF_SESSION_PAYMENT
PAYMENT_CARD
PAYPAL_BILLING_AGREEMENT
PAYPAL_ORDER
id
of a VaultedPaymentMethod previously retrieved with fetchVaultedPaymentMethods.Upon a successful invocation of this function, the SDK will automatically trigger the standard payment callbacks.// Initialise Headless Checkout ...
const vaultManager = headless.createVaultManager();
const vaultedPaymentMethods = await vaultManager.fetchVaultedPaymentMethods();
// Start the payment flow using the first vaulted payment method
try {
await vaultManager.startPaymentFlow(vaultedPaymentMethods[0]?.id);
} catch (error) {
// handle errors
}
paymentInstrumentType
in the vaulted payment method passed in is not recognised.Show VaultedPaymentMethod
{
"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
}
APPLE_PAY
CARD_OFF_SESSION_PAYMENT
GOOGLE_PAY
KLARNA_CUSTOMER_TOKEN
OFF_SESSION_PAYMENT
PAYMENT_CARD
PAYPAL_BILLING_AGREEMENT
PAYPAL_ORDER
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.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
}
};
Show CardSecurityCodeInputOptions
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.aria-label
attribute for the input element wrapped by CvvInput
.id
attribute that will be assigned to the HTMLIFrameElement
used by CvvInput
.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:<input name="cvv-custom" /* Other attributes */ />
placeholder
attribute for the input element wrapped by CvvInput
.append
or prepend
the CvvInput
to its container.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
optionsmaxLength
and minLength
will be inferred from the cardNetwork
tel
to provide a good UX when typing on a virtual keyboardonkeydown
, onkeyup
won’t be serialized and passed down to the inputdata-*
, aria-*
…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.Show CvvInput
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)
.// use `metadata` to check for validation errors
if (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
}
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 reasonsmetadata
: additional details on the state of the input field wrapped by the CvvInput.valueToken
and metadata
can be also accessed directly on an instance of CvvInput
(cvvInput.valueToken
, cvvInput.metadata
)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.HTMLInputElement
wrapped by CvvInput
.HTMLInputElement
wrapped by CvvInput
.CvvInput
field from the DOM and detaches all event listeners previously added with addListener
.HTMLIFrameElement
wrapping the input.CvvInput
.Show InputMetadata
null
if the input value has no validation errors.name
attribute of the underlying HTMLInputElement
field.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.CvvInput
in a React component using addListener('change', listener)
: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" />;
};
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>
);
};
customer.customerId
is not provided in the client session