Skip to main content

Customization

Customizing the Vault Payment Form

Purse Headless Checkout allows you to customize both the appearance and the translations of your payment form using the getPaymentElement method.

This enables full control over the branding, accessibility, and localization of the UI.

Theme object

The theme object enables you to customize the appearance of the Vault payment form. It has a global scope and several specific scopes for different parts of the UI, such as input, label, helperText, and tooltip.

Global styles apply to all elements, while specific styles can override global styles for particular elements.

In the global scope you can define the following CSS properties:

  • color
  • fontSize
  • fontFamily
  • fontWeight
  • gap
  • fontSrc (for custom fonts)

In the specific scopes, you can define the following CSS properties:

  • input:color,fontSize,fontFamily,borderRadius,backgroundColor,borderColor,borderStyle,borderWidth, fontWeight,fontStyle,padding,boxShadow,outlineColor,outlineStyle,outlineWidth,],
  • helperText: color, fontSize, fontFamily, fontWeight, margin,
  • tooltip: color,fontSize,fontFamily,fontWeight,borderRadius,backgroundColor,padding,boxShadow,,
  • label: color, fontSize, fontFamily, fontWeight, margin,

You can also define pseudo-classes and pseudo-elements for each scope, such as :focus, :hover, :valid, :invalid, ::placeholder, and :-webkit-autofill.

Pseudo-classes and pseudo-elements are applicable on the fields like this :

  • global: :valid, :invalid
  • input: :hover, :valid, :focus, :invalid, ::placeholder, ::placeholder:disabled, :-webkit-autofill
  • helperText: :disabled, :valid, :invalid
  • tooltip: :focus, :invalid
  • label: :valid, :invalid

Code example

// let's find a payment method
const allMethods = checkout.paymentMethods.value
const method = allMethods.find((method) => method.method === "creditcard");

if (!method) {
console.error("Payment method not found");
return;
}

const paymentElement = method.getPaymentElement({
hostedForm: {
//Define the translation for the credit card forms
panInputLabel: "Card number",
cvvInputLabel: "Security code"
},
theme: {
global: {
'::placeholder': {color: '#ccc'},
'::placeholder:disabled': {color: '#bbb'},
':invalid': {color: '#ba2525'},
':valid': {color: '#0f8613'},
color: '#1f2933',
fontFamily: 'Arial, sans-serif',
fontSize: '14px',
fontWeight: '14px',
gap: '8px',
margin: '0',
padding: '0'
},
input: {//input is what we call a scope
':focus': {//:focus is a scope variant
border: '1px solid #1f2933'
},
':invalid': {
color: '#ba2525',
border: '1px solid #ba2525'
},
':valid': {
color: '#0f8613',
border: '1px solid #0f8613'
},
padding: '8px',
border: '1px solid #616e7c'
},
helperText: {},
label: {},
tooltip: {}
}
})
paymentElement.appendTo("a-container");

The theme is designed to be pretty permissive, so that any missing value in a scope falls back to the global scope, and any missing value in a variant falls back to its parent scope.

Using the SDK through npm will give you the typescript definitions for the theme, which will help you understand what keys are available and how to use them.

Here's however a sample of a theme object you can use to customize the payment form:

Theme sample
const exampleTheme: PartnerUITheme = {
global: {
color: '#222',
fontSize: '16px',
fontFamily: 'Arial, sans-serif',
fontWeight: '400',
gap: '8px',
fontSrc: 'https://fonts.googleapis.com/css?family=Roboto',
':valid': {
color: '#0a0',
},
':invalid': {
color: '#a00',
},
},
input: {
color: '#333',
fontSize: '16px',
fontFamily: 'Arial, sans-serif',
borderRadius: '4px',
backgroundColor: '#fff',
borderColor: '#ccc',
borderStyle: 'solid',
borderWidth: '1px',
fontWeight: '400',
fontStyle: 'normal',
padding: '8px',
boxShadow: 'none',
outlineColor: '#007bff',
outlineStyle: 'solid',
outlineWidth: '2px',
':hover': {
borderColor: '#888',
},
':focus': {
borderColor: '#007bff',
boxShadow: '0 0 0 2px #cce4ff',
},
'::placeholder': {
color: '#aaa',
},
':-webkit-autofill': {
backgroundColor: '#eaffd0',
},
},
label: {
color: '#444',
fontSize: '14px',
fontFamily: 'Arial, sans-serif',
fontWeight: '500',
margin: '0 0 4px 0',
':valid': {
color: '#0a0',
},
':invalid': {
color: '#a00',
},
},
helperText: {
color: '#888',
fontSize: '12px',
fontFamily: 'Arial, sans-serif',
fontWeight: '400',
margin: '4px 0 0 0',
':disabled': {
color: '#ccc',
},
':valid': {
color: '#0a0',
},
':invalid': {
color: '#a00',
},
},
tooltip: {
color: '#fff',
fontSize: '12px',
fontFamily: 'Arial, sans-serif',
fontWeight: '400',
borderRadius: '4px',
backgroundColor: '#222',
padding: '8px',
boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
':focus': {
backgroundColor: '#333',
},
':invalid': {
backgroundColor: '#a00',
},
},
};

See Theme references to get the full list of available keys.

Providing your own fonts for the Vault secure fields

If you want to use your own fonts, you have to provide us with the file of your font. We will host it for you on your instance of the secure fields. You can then use the fontSrc property in the theme object. The fontSrcneeds to match the filename of the font you provided.

For instance: if you provided a font file named my-font.woff2, you can use the following code: The font name will match any variable you set first in the fontFamily property.

const paymentElement = method.getPaymentElement({
theme: {
global: {
fontSrc: 'my-font.woff2',
fontFamily: 'my-font, Arial, sans-serif',
},
}
})