Styling & Customization
Customize the Inflow card payment form with two recommended APIs:
appearance— theme tokens (colors, radii, fonts)options— layout, width, card / wallet button labels, placeholders, and success UI
Legacy style and top-level copy props still work, but prefer appearance and options for new integrations.
Quick example
appearance: {
// fonts is optional. When set, cssSrc must be a Google Fonts URL
// (fonts.googleapis.com / fonts.google.com). Built-in fonts like Inter
// load from fontFamily alone — no fonts entry needed.
fonts: [
{
cssSrc:
'https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap',
},
],
variables: {
fontFamily: 'Lato, system-ui, sans-serif',
primaryColor: '#0070F3',
buttonBackgroundColor: '#0070F3',
buttonTextColor: '#FFFFFF',
buttonBorderRadius: '8px',
},
},
options: {
paymentMethodLayout: 'horizontalSelector',
paymentMethodOrder: ['apple_pay', 'google_pay', 'card'],
cardFieldLayout: 'compact',
fillParent: true,
buttonText: 'Pay €49.99',
wallets: {
buttonText: {
applePay: 'Pay with Apple Pay',
googlePay: 'Pay with Google Pay',
},
},
cardForm: {
placeholders: {
cardNumber: 'Card number',
expiry: 'MM / YY',
cvc: 'CVC',
},
},
showDefaultSuccessUI: true,
}Precedence
- Theme: if
appearanceis set, it is used; otherwise legacystyleis applied. - Width:
options.fillParentif set; otherwisestyle.fillParent. - Copy / success UI: values under
optionswin over deprecated top-level fields.
Appearance
Use appearance to theme the checkout form. Variables map to CSS custom properties inside the iframe.
appearance: {
// fonts is optional. When set, cssSrc must be a Google Fonts URL
// (fonts.googleapis.com / fonts.google.com). Built-in fonts like Inter
// load from fontFamily alone — no fonts entry needed.
fonts: [
{
cssSrc:
'https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap',
},
],
variables: {
fontFamily: 'Lato, system-ui, sans-serif',
formBackgroundColor: 'transparent',
backgroundColor: '#ffffff',
textColor: '#111111',
textSecondaryColor: '#6b7280',
placeholderColor: '#9ca3af',
primaryColor: '#111111',
primaryTextColor: '#ffffff',
layoutBorderColor: '#d8d8d8',
inputBorderColor: '#e5e5e5',
inputFocusBorderColor: '#111111',
layoutBorderRadius: '12px',
inputBorderRadius: '8px',
buttonBorderRadius: '8px',
dangerColor: '#ef4444',
dangerBackgroundColor: '#fee2e2',
successColor: '#ffffff',
successBackgroundColor: '#22c55e',
buttonBackgroundColor: '#111111',
buttonTextColor: '#ffffff',
// Special-case only — see table below:
// iframeBackgroundColor: '#ffffff',
},
}appearance.variables
appearance.variables| Variable | Purpose |
|---|---|
fontFamily | CSS font stack for the form, including wallet button labels. Known Google Fonts in the primary slot are auto-loaded |
formBackgroundColor | Checkout form box background. Default is transparent so the parent page shows through |
iframeBackgroundColor | Special case. Overrides the iframe document (html / body) background. Omit by default; use only when the iframe background does not match the page and formBackgroundColor alone is not enough |
backgroundColor | Input / panel surface background |
textColor | Primary text |
textSecondaryColor | Secondary / muted text (labels, disclaimer, helpers) |
placeholderColor | Input placeholders |
primaryColor | Brand / selection accent |
primaryTextColor | Text and icons on primary-filled surfaces |
layoutBorderColor | Payment-method layout and divider borders |
inputBorderColor | Card input borders |
inputFocusBorderColor | Focused input borders |
layoutBorderRadius | Layout chrome radius |
inputBorderRadius | Input radius |
buttonBorderRadius | Pay / wallet button radius (shared; see Wallet buttons) |
dangerColor | Error text / field errors |
dangerBackgroundColor | Error banner background |
successColor | Success accent |
successBackgroundColor | Success fill surfaces |
buttonBackgroundColor | Card pay button background (falls back to primaryColor when omitted). Does not apply to wallet buttons |
buttonTextColor | Card pay button label color. Does not apply to wallet buttons |
appearance.fonts
appearance.fontsOptional Google Fonts stylesheets for fonts outside the SDK auto-load list.
These are auto-loaded from fontFamily alone (no fonts entry needed):
DM Sans, Inter, Poppins, Nunito, Work Sans, Manrope, Rubik, Karla, Figtree, Outfit, Space Grotesk, Urbanist.
For any other Google Font, pass a stylesheet URL. Only https://fonts.googleapis.com and https://fonts.google.com HTTPS URLs are accepted.
appearance: {
fonts: [
{
cssSrc:
'https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap',
},
],
variables: {
fontFamily: 'Lato, system-ui, sans-serif',
},
}Dark mode
appearance has no built-in dark block (unlike legacy style.dark).
To support dark mode, detect it in your app however you prefer (system preference, class toggle, theme provider, etc.), then pass the matching appearance.variables (and remount or update the element when the theme changes).
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
appearance: {
variables: isDark
? {
backgroundColor: '#1A1A1A',
textColor: '#FFFFFF',
placeholderColor: '#959499',
primaryColor: '#0066CC',
buttonBackgroundColor: '#0066CC',
buttonTextColor: '#FFFFFF',
layoutBorderColor: '#333333',
inputBorderColor: '#333333',
}
: {
backgroundColor: '#FFFFFF',
textColor: '#1A1A1A',
primaryColor: '#0070F3',
buttonBackgroundColor: '#0070F3',
buttonTextColor: '#FFFFFF',
},
}Options
Use options for layout and non-theme configuration.
options: {
paymentMethodLayout: 'stacked', // 'stacked' | 'verticalSelector' | 'horizontalSelector'
paymentMethodOrder: ['apple_pay', 'google_pay', 'card'],
cardFieldLayout: 'compact', // 'compact' | 'split'
fillParent: true,
buttonText: 'Pay now',
wallets: {
buttonText: {
applePay: 'Pay with Apple Pay',
googlePay: 'Pay with Google Pay',
},
},
cardForm: {
placeholders: {
cardNumber: 'Card number',
expiry: 'MM / YY',
cvc: 'CVC',
},
},
showDefaultSuccessUI: true,
}| Option | Default | Description |
|---|---|---|
paymentMethodLayout | stacked | stacked (wallets on top, card always visible), verticalSelector (vertical selectable list), or horizontalSelector (horizontal selectable tabs) |
paymentMethodOrder | card, then wallets | Display order and default selection for verticalSelector and horizontalSelector only. Values: card, apple_pay, google_pay. First available method is shown first and selected; unavailable entries are skipped. Does not change stacked layout behavior |
cardFieldLayout | compact | compact (grouped fields) or split (number alone; expiry + CVC on a second row) |
fillParent | false | When true, host iframe and form use 100% width |
buttonText | "Complete Payment" | Card pay button label (does not apply to wallet buttons) |
wallets.buttonText.applePay | locale "Pay" | Apple Pay button label (translated when omitted; overrides are used as-is) |
wallets.buttonText.googlePay | locale "Pay" | Google Pay button label (translated when omitted; overrides are used as-is) |
wallets.buttonTheme | "auto" | Rare override — leave unset / "auto" unless you must lock wallets to a single color; see Wallet buttons |
cardForm.placeholders | — | Card number / expiry / CVC placeholders |
showDefaultSuccessUI | true | Show the built-in success screen after payment |
Wallet buttons
Apple Pay and Google Pay are configured mainly under options.wallets. Appearance does not fully theme wallet buttons.
What appearance applies to wallet buttons
Only these Appearance variables affect wallet buttons:
appearance.variables.fontFamily— wallet button label font (shared with the rest of the form)appearance.variables.buttonBorderRadius— corner radius (shared with the card pay button)
Every other Appearance property — including colors such as buttonBackgroundColor, buttonTextColor, primaryColor, borders, and the rest of the variables table — does not apply to wallet buttons.
What you configure under options.wallets
| Field | Purpose |
|---|---|
buttonText.applePay / buttonText.googlePay | Wallet button labels. If omitted, the iframe uses the localized default for "Pay". Merchant-provided strings are not translated. |
buttonTheme | Rare override only. Leave unset (default "auto") so wallets follow the system light/dark theme. Set "black" or "white" only if you must keep one fixed wallet color (for example, always black even in dark mode). Most integrations should not set this. |
Wallet buttons use black or white only; you cannot set custom brand colors on them via Appearance.
options: {
buttonText: 'Start Trial', // card CTA only
wallets: {
buttonText: {
applePay: 'Pay $0.50 & Start Trial',
googlePay: 'Pay with Google Pay',
},
// buttonTheme: omit — keep default "auto"
},
},
appearance: {
variables: {
fontFamily: 'Lato, system-ui, sans-serif', // applies to wallet labels
buttonBorderRadius: '8px', // applies to card + wallet buttons
buttonBackgroundColor: '#adffd2', // card pay button only — not wallets
buttonTextColor: '#000000', // card pay button only — not wallets
},
},Payment method order
Applies to selector layouts (verticalSelector / horizontalSelector):
options: {
paymentMethodLayout: 'horizontalSelector',
paymentMethodOrder: ['apple_pay', 'google_pay', 'card'],
}If Apple Pay is unavailable, Google Pay is selected when available; otherwise Card. Remaining enabled methods that were not listed are appended after your order.
Legacy styling (style)
style)The style object is deprecated but still fully supported when appearance is not provided.
style: {
fontFamily: 'Inter',
fillParent: true,
formBackgroundColor: '#211e19',
inputContainer: {
backgroundColor: '#F5F5F5',
borderRadius: '8px',
borderEnabled: true,
borderColor: '#E0E0E0',
},
input: {
textColor: '#1A1A1A',
placeholderColor: '#999999',
backgroundColor: 'transparent',
},
button: {
backgroundColor: '#0070F3',
textColor: '#FFFFFF',
borderRadius: '8px',
fontSize: '16px',
fontWeight: 600,
hover: {
backgroundColor: '#0051CC',
},
disabled: {
opacity: 0.5,
},
},
successUI: {
backgroundColor: '#F5F5F5',
primaryTextColor: '#1A1A1A',
secondaryTextColor: '#999999',
},
dark: {
inputContainer: {
backgroundColor: '#1A1A1A',
borderColor: '#333333',
},
input: {
textColor: '#FFFFFF',
placeholderColor: '#959499',
},
button: {
backgroundColor: '#0066CC',
},
successUI: {
backgroundColor: '#1A1A1A',
primaryTextColor: '#FFFFFF',
secondaryTextColor: '#959499',
},
},
}Supported legacy style fields: fontFamily, fillParent, formBackgroundColor, inputContainer, input, button (including hover / disabled / loaderColor), successUI, generalError, disclaimerColor, fieldErrorColor, dark.
Legacy → recommended
| Legacy field | Recommended replacement |
|---|---|
style | appearance.variables |
style.fillParent | options.fillParent |
style.fontFamily | appearance.variables.fontFamily (+ optional appearance.fonts) |
style.dark | No appearance.dark — detect dark mode in your app and pass matching appearance.variables |
top-level buttonText | options.buttonText |
top-level placeholders | options.cardForm.placeholders |
top-level showDefaultSuccessUI | options.showDefaultSuccessUI |
Top-level buttonText, placeholders, and showDefaultSuccessUI remain supported for compatibility:
buttonText: 'Pay €49.99',
placeholders: {
cardNumber: '1234 5678 9012 3456',
expiry: 'MM/YY',
cvc: 'CVC',
},Prefer
options.buttonTextandoptions.cardForm.placeholdersfor new integrations.
The styling API may evolve. Refer to the npm package for the full TypeScript types and all available properties.
Updated 25 minutes ago