Přeskočit na hlavní obsah

Přizpůsobení vzhledu

Výchozí vzhled SDK je navržen tak, aby jej bylo možné použít bez dalších úprav. Pokud však potřebujete vzhled SDK, zejména karetního formuláře, přizpůsobit vizuálnímu stylu vašeho e-shopu, SDK poskytuje několik možností konfigurace.

SDK pracuje se dvěma vizuálními vrstvami, které se upravují odlišným způsobem:

  1. Tlačítka Apple Pay a Google Pay — tlačítka jsou vytvářena knihovnami společností Apple a Google a umožňují pouze základní přizpůsobení. Pomocí konfiguračního objektu ui v konfiguračním parametru applepay nebo googlepay lze nastavit pouze barvu a typ tlačítka (text obsažený na tlačítku). Vlastní CSS nelze použít, protože tlačítka jsou renderována oficiální knihovnou a nejsou dostupná pro přímé stylování.
  2. Karetní formulář — pole pro číslo karty, expiraci a bezpečnostní kód jsou z bezpečnostních důvodů umístěna v izolovaném iframe. Obsah iframe není dostupný pro stylování pomocí CSS z nadřazené stránky. Vzhled karetního formuláře se proto nastavuje prostřednictvím konfiguračního objektu appearance. Všechny ostatní prvky zobrazené na stránce mimo izolovaný iframe je možné stylovat standardně pomocí vlastního CSS stránky.

Apple Pay

Tlačítka Apple Pay nelze stylovat vlastním CSS. Jeho vzhled lze ovlivnit pouze prostřednictvím konfigurace ui. Toto omezení vychází přímo z pravidel Apple.

applepay.ui

ParametrTypPovolené hodnotyDefaultPopis
typestringplain, add-money, book, buy, check-out, continue, contribute, donate, order, pay, reload, rent, set-up, subscribe, support, tip, top-up'pay'Text/logo zobrazené na tlačítku.
colorstringblack, white, white-with-outline'black'Barevná varianta tlačítka.
enableResizeListenerbooleantrue, falsetrueZapne automatické přizpůsobení tlačítka při změně rozměrů kontejneru.
styleobjectRozměry a zaoblení tlačítka — viz tabulka níže.

applepay.ui.style

Přes volitelný objekt style lze doplnit rozměry a zaoblení:

ParametrTypDefaultPopis
widthnumberŠířka v px; pokud není nastavena, tlačítko vyplní šířku kontejneru.
heightnumberVýška v px; pokud není nastavena, tlačítko vyplní výšku kontejneru.
borderRadiusnumber4Zaoblení rohů v px.
paddingXnumber0Vodorovný padding uvnitř tlačítka v px.
paddingYnumber2Svislý padding uvnitř tlačítka v px.
boxSizing'border-box' | 'content-box''border-box'Model rámečku.

applepay.payment

Informace

Tuto konfiguraci používejte pouze pokud přesně víte, že potřebujete změnit výchozího poskytovatele pro Apple Pay (výchozí je COMGATE). Pokud využíváte standardní nastavení, tento klíč vynechte a nechte SDK, aby si poskytovatele zvolilo samo.

ParametrTypPovinnýDefaultPopis
providerstringAno (pokud payment uvedete)'COMGATE'Poskytovatel zpracování Apple Pay. Povolené: 'COMGATE', 'CSOB'.
providerIdstringNeID poskytovatele (pokud se liší od výchozího).

applepay.actions

ParametrTypPopis
onButtonClick(moduleId: string) => Promise<void>Voláno po kliknutí na tlačítko Apple Pay, před zahájením platby. Lze využít pro validaci košíku. Platba se spustí až po vyřešení vráceného Promise.

Ukázka konfigurace

applepay: {
mountPoint: '#cg-applepay-box',
ui: {
type: 'pay',
color: 'black',
enableResizeListener: true,
style: {
width: 240,
height: 45,
borderRadius: 6,
paddingX: 12,
paddingY: 10,
boxSizing: 'border-box',
},
},
//payment: {
//provider: 'COMGATE',
//providerId: 'M0MIPS0001', // or '123456'
//},
actions: {
onButtonClick: async (moduleId) => {
console.log('Apple Pay button clicked', moduleId);
// platba se spustí až po dokončení funkce / vyřešení Promise
// lze například i zastavit zpracování
// více v dokumentaci k onButtonClick níže
},
},
}

Zdroje

Google Pay

Tlačítka Google Pay nelze stylovat vlastním CSS. Jeho vzhled lze ovlivnit pouze prostřednictvím konfigurace ui. Toto omezení vychází přímo z pravidel Google.

googlepay.ui

ParametrTypPovolené hodnotyDefaultPopis
typestringbook, buy, checkout, donate, order, pay, plain, subscribe, short'plain'Text/logo zobrazené na tlačítku.
colorstringblack, white'black'Barevná varianta tlačítka.
enableResizeListenerbooleantrue, falseZapne automatické přizpůsobení tlačítka při změně rozměrů kontejneru.
Tip

Hodnota short odpovídá tlačítku pouze s logem (bez textu), buy zobrazí text „Buy with Google Pay".

googlepay.payment

ParametrTypPovinnýDefaultPopis
googlePayMerchantIdstringNe (test) / Ano (prod)Merchant ID z Google Pay Business Console. Pro testování není vyžadováno, pro produkci je povinné.
providerstringNe'COMGATE'Poskytovatel zpracování Google Pay. Povolené: 'COMGATE', 'CSOB'.
providerIdstringNeID poskytovatele (pokud se liší od výchozího).

googlepay.actions

ParametrTypPopis
onButtonClick(moduleId: string) => Promise<void>Voláno po kliknutí na tlačítko Google Pay, před zahájením platby. Lze využít pro validaci košíku. Platba se spustí až po vyřešení vráceného Promise.

Ukázka konfigurace

googlepay: {
mountPoint: '#cg-googlepay-box',
ui: {
type: 'pay',
color: 'black',
enableResizeListener: true,
},
payment: {
googlePayMerchantId: 'BCR*******ZAV',
//provider: 'COMGATE',
},
actions: {
onButtonClick: async (moduleId) => {
console.log('Google Pay button clicked', moduleId);
// platba se spustí až po vyřešení tohoto Promise
},
},
}

Zdroje

  • Online simulátor — oficiální nástroj pro testování různých konfigurací Google Pay tlačítka
  • Brand Guidelines — marketingové pokyny, jak správně používat Google Pay tlačítka
  • UX best practices — pokyny pro návrh uživatelského rozhraní pro integraci Google Pay

Karetní formulář

SDK automaticky vkládá výchozí styly pro karetní kontejner při mountování modulu. Styly jsou vloženy na začátek <head> jako <style> tag — všechny selektory jsou omezeny (scoped) na ID kontejneru, díky tomu nedochází ke kolizím s ostatními styly stránky.

  • Styly jsou vloženy při volání mount() a odstraněny při destroy().
  • SDK nepoužívá !important — stačí definovat pravidla se stejnou nebo vyšší specificitou.
  • CSS proměnné (--cg-green, --cg-green-hover, --cg-ibox-h, --cg-btn-h) jsou scopované pod ID kontejneru a lze je přepsat vlastním selektorem.
Pořadí specificity

SDK styly jsou vloženy na začátek <head> (před všechny ostatní <style> a <link>). Vaše vlastní CSS se stejnou specificitou proto vždy vyhraje díky pozdějšímu pořadí v kaskádě (source order) — bez ohledu na to, kde na stránce se nachází.

Přizpůsobení výchozích stylů

Přepsat SDK styly můžete jednoduše vlastním CSS se stejnou nebo vyšší specificitou:

Upozornění

Podmínkou úpravy stylů je zachování plné funkčnosti všech prvků formuláře. Veškeré prvky musí zůstat viditelné, dostupné a použitelné.

Skrytí části formuláře, například pomocí pravidla display: none, je považováno za porušení integračních podmínek Comgate a může vést k ukončení poskytování služby Checkout SDK.

Příklad — úplné přepsání všech SDK stylů

Níže je uveden příklad CSS pokrývající všechny styly, které SDK vkládá. Můžete si vybrat jen ta pravidla, která chcete přepsat.

/* CSS proměnné a základní rámec kontejneru */
#cg-card-box {
/* --cg-green: #2abd4f; */
/* --cg-green-hover: #38c65d; */
/* --cg-ibox-h: 140px; */
/* --cg-btn-h: 44px; */
/* border: 1px solid #f0f0f0; */
/* background: #f2f2f2; */
/* border-radius: 5px; */
/* padding: 15px; */
/* max-width: 450px; */
}

/* Oblast formuláře pro zadání karty */
#cg-card-box-ibox {
/* min-height: var(--cg-ibox-h); */
}

#cg-card-box-ibox iframe {
/* display: block; */
/* width: 100%; */
/* height: var(--cg-ibox-h); */
/* border: none; */
}

/* Ikony karetních sítí */
#cg-card-box .cg-card-icons {
/* display: flex; */
/* align-items: center; */
/* gap: 6px; */
/* padding: 5px 0; */
}

#cg-card-box .cg-card-icons .cg-card-icon {
/* display: inline-flex; */
/* align-items: center; */
/* justify-content: center; */
/* width: 30px; */
/* height: 19px; */
}

#cg-card-box .cg-card-icons .cg-card-icon img {
/* width: 30px; */
/* height: 19px; */
/* object-fit: contain; */
}

/* Tlačítko pro odeslání platby */
#cg-card-box-button button {
/* transition: background-color 0.1s ease-in-out; */
/* display: inline-flex; */
/* align-items: center; */
/* justify-content: center; */
/* width: 100%; */
/* height: var(--cg-btn-h); */
/* padding: 14px 10px; */
/* margin-top: 10px; */
/* border: none; */
/* border-radius: 5px; */
/* background: var(--cg-green); */
/* color: #fff; */
/* font-size: 14px; */
/* font-weight: 700; */
/* cursor: pointer; */
}

#cg-card-box-button button:hover {
/* background: var(--cg-green-hover); */
}

/* Ikona zámku uvnitř tlačítka */
#cg-card-box-button button .cg-button-lock {
/* width: 17px; */
/* flex-shrink: 0; */
/* margin-right: 6px; */
}

/* Ikona fajfky uvnitř tlačítka (stav zaplaceno) */
#cg-card-box-button button .cg-button-tick {
/* width: 14px; */
/* height: 14px; */
/* flex-shrink: 0; */
/* margin-right: 6px; */
}

/* Spinner uvnitř tlačítka (během zpracování platby) */
#cg-card-box-button button .cg-button-spinner {
/* display: inline-block; */
/* width: 16px; */
/* height: 16px; */
/* margin-right: 8px; */
/* border: 2px solid rgba(255,255,255,0.35); */
/* border-top-color: #fff; */
/* border-radius: 50%; */
/* animation: cg-card-spin .6s linear infinite; */
/* vertical-align: middle; */
}

/* Tlačítko — disabled stav */
#cg-card-box-button button.disabled-btn,
#cg-card-box-button button.disabled-btn:hover,
#cg-card-box-button button.disabled-btn:active,
#cg-card-box-button button.disabled-btn:focus {
/* opacity: 0.65; */
/* cursor: default; */
/* background: var(--cg-green); */
}

/* Loader v oblasti tlačítka */
#cg-card-box-button .cg-card-button-loader {
/* display: flex; */
/* align-items: center; */
/* justify-content: center; */
/* min-height: var(--cg-btn-h); */
/* padding: 12px 0; */
}

#cg-card-box-button .cg-card-button-loader-spinner {
/* display: inline-block; */
/* width: 24px; */
/* height: 24px; */
/* border: 3px solid rgba(0,0,0,0.15); */
/* border-top-color: var(--cg-green); */
/* border-radius: 50%; */
/* animation: cg-card-spin .6s linear infinite; */
}

/* Chybový stav formuláře */
#cg-card-box .cg-card-error {
/* display: flex; */
/* flex-direction: column; */
/* align-items: center; */
/* justify-content: center; */
/* gap: 10px; */
/* min-height: var(--cg-ibox-h); */
/* padding: 20px 16px; */
/* text-align: center; */
/* color: #555; */
/* font-size: 13px; */
/* line-height: 1.55; */
}

/* Ikona chybového stavu (SVG přes background-image) */
#cg-card-box .cg-card-error::before {
/* content: ''; */
/* display: block; */
/* width: 40px; */
/* height: 40px; */
/* flex-shrink: 0; */
/* background: url("...") center / contain no-repeat; */
}

#cg-card-box .cg-card-error-retry {
/* display: inline-block; */
/* margin-top: 2px; */
/* color: var(--cg-green); */
/* font-size: 13px; */
/* font-weight: 600; */
/* text-decoration: none; */
/* cursor: pointer; */
}

#cg-card-box .cg-card-error-retry:hover {
/* text-decoration: underline; */
}

/* Příplatek za platební metodu */
#cg-card-box .cg-surcharge {
/* margin-top: 8px; */
/* font-size: 14px; */
/* line-height: 1.4; */
}

#cg-card-box .cg-surcharge-info {
/* display: flex; */
/* justify-content: space-between; */
/* align-items: center; */
}

#cg-card-box .cg-surcharge-amount {
/* font-weight: 600; */
/* color: #dc291e; */
}

#cg-card-box .cg-surcharge-toggle {
/* font-size: 14px; */
/* margin-top: 0; */
/* display: inline-block; */
/* color: inherit; */
/* text-decoration: underline; */
/* outline: none; */
}

#cg-card-box .cg-surcharge-detail {
/* font-size: 14px; */
/* color: rgba(0, 0, 0, 0.5); */
/* transition: opacity 0.25s ease, max-height 0.25s ease 0.25s, margin-top 0.25s ease 0.25s; */
/* opacity: 0; */
/* overflow: hidden; */
/* max-height: 0; */
/* margin: 0; */
}

#cg-card-box .cg-surcharge-detail.cg-surcharge-detail--expanded {
/* transition: max-height 0.25s ease, margin-top 0.25s ease, opacity 0.25s ease; */
/* margin-top: 10px; */
/* max-height: 200px; */
/* opacity: 1; */
}

#cg-card-box .cg-surcharge-blocked {
/* color: #c0392b; */
}

#cg-card-box .cg-surcharge-blocked p {
/* margin: 0; */
}

/* Utility — skrytí prvku */
#cg-card-box .cg-hidden {
/* display: none !important; */
}

Loading stav karetního formuláře

SDK styly se vloží až po stažení a spuštění JavaScriptu. Pokud chcete uživateli zobrazit loading spinner okamžitě po vykreslení stránky (ještě před tím, než se SDK stihne načíst), přidejte hlavnímu kontejneru karty třídu is-loading — SDK ji po namountování automaticky odstraní.

Tip

Loading styly jsou volitelné — bez nich se kontejner zobrazí jako prázdný prostor do doby, než SDK načte formulář. Pokud vám to nevadí, tuto sekci můžete přeskočit.

<div id="cg-card-box" class="is-loading">
<div id="cg-card-box-ibox"></div>
<div id="cg-card-box-button">
<button type="button">Zaplatit</button>
</div>
</div>
CSS pro loading spinner

Vložte do svého CSS následující pravidla:

/* Loading state — spinner zobrazený okamžitě z HTML, než se SDK naloaduje */
#cg-card-box.is-loading #cg-card-box-ibox {
position: relative;
min-height: 140px;
}

#cg-card-box.is-loading #cg-card-box-ibox::before {
content: '';
position: absolute;
inset: 0;
margin: auto;
width: 25px;
height: 25px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%23888888' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='18' height='11' x='3' y='11' rx='2' ry='2'/%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'/%3E%3Cg transform='translate(0 -.38)'%3E%3Ccircle cx='12.1' cy='16.067' r='.472' style='fill:%23888888;stroke-width:1.25646;'/%3E%3Cpath d='M12.079 16.62h.042v1.342h-.042z' style='fill:%23888888;stroke-width:1.65753;'/%3E%3C/g%3E%3C/svg%3E");
background-size: contain;
background-repeat: no-repeat;
background-position: center;
z-index: 1;
}

#cg-card-box.is-loading #cg-card-box-ibox::after {
content: '';
position: absolute;
inset: 0;
margin: auto;
width: 63px;
height: 63px;
border: 3px solid #e4e4e4;
border-top-color: #999;
border-radius: 50%;
animation: cg-card-spin 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}

#cg-card-box.is-loading #cg-card-box-button {
display: none;
}

/* Varianta: tlačítko mimo kontejner */
#cg-card-box-button.is-loading {
display: none;
}

@keyframes cg-card-spin { to { transform: rotate(360deg); } }

Vstupní pole

Formulář pro zadávání karetních dat běží v zabezpečeném iframe, a proto je jeho přizpůsobení možné výhradně prostřednictvím konfigurace appearance v parametru card. Objekt appearance umožňuje nastavit barvy, fonty, zaoblení, odsazení — viz přehled níže.

Informace

Hierarchie aplikace stylů: výchozí CSS → variablesrules (každá vrstva přepisuje předchozí).

Hlavní objekt appearance

ParametrTypPovinnýPopis
versionnumberAnoVerze appearance konfigurace — zvedněte 1 při každé změně.
variablesobjectNeDesignové atributy (CSS custom properties) — viz tabulka níže.
rulesobjectNePer-element CSS přepisy — viz tabulka níže.

appearance.variables — designové atributy

Atributy nastavují CSS custom properties na :root uvnitř iframe. Ovlivní všechny prvky formuláře najednou.

ParametrPopis
colorTextBarva textu (inputy, popisky).
colorBackgroundBarva pozadí inputů.
colorPrimaryPrimární barva — rámeček při focusu, aktivní prvky.
colorDangerBarva nebezpečí — rámeček nevalidního pole, text chybové hlášky.
colorPlaceholderBarva placeholder textu.
borderColorVýchozí barva rámečku inputu.
borderRadiusZaoblení rohů inputu.
fontFamilyFont formuláře (omezeno na povolený allowlist).
fontSizeVelikost písma inputu.
spacingPadding inputů a mezery mezi poli.
appearance.rules — per-element CSS přepisy

Každý klíč v objektu rules cílí na konkrétní vizuální element formuláře:

KlíčCo styluje
containerKořenový kontejner formuláře ([data-slot="container"])
labelPopisek nad inputem ([data-slot="label"])
inputInput ve výchozím stavu ([data-slot="input"])
inputFocusInput ve stavu focus ([data-slot="input"][data-state="focus"])
inputInvalidInput s nevalidní hodnotou ([data-slot="input"][data-invalid])
errorChybová zpráva pod inputem ([data-slot="error"])

Každý klíč přijímá objekt s povolenými CSS vlastnostmi (SafeStyle):

CSS vlastnostTypPříklad
colorstring'#111827'
backgroundColorstring'#ffffff'
borderColorstring'#e5e7eb'
borderRadiusstring'6px'
fontFamilystring'Arial, sans-serif'
fontSizestring'14px'
fontWeightstring'500'
lineHeightstring'1.5'
letterSpacingstring'0.5px'
paddingBlockstring'10px'
paddingInlinestring'12px'
boxShadowstring'0 0 0 2px rgba(0, 102, 204, 0.25)'
Upozornění

SDK interně validuje styly a odmítá nebezpečné hodnoty. Neplatný styl je ignorován a SDK vypíše varování do konzole.

Fonty lze nastavit takové, které jsou obsaženy v rámci operačního systému (např. Arial, Helvetica, sans-serif). Nelze načítat externí fonty pomocí @font-face nebo z CDN.

Ukázka konfigurace

card: {
mountPoint: '#cg-card-box',
appearance: {
version: 1, // zvedněte o 1 při každé změně
variables: {
colorText: '#111827',
colorBackground: '#ffffff',
colorPrimary: '#0891b2',
colorDanger: '#dc2626',
colorPlaceholder: '#9ca3af',
borderColor: '#e5e7eb',
borderRadius: '4px',
fontFamily: 'Arial, sans-serif',
fontSize: '14px',
spacing: '8px',
},
rules: {
container: { backgroundColor: '#f9fafb' },
label: { color: '#374151', fontWeight: 'bold', fontSize: '12px' },
input: { backgroundColor: '#ffffff', borderColor: '#e5e7eb', color: '#111827', paddingBlock: '6px', paddingInline: '8px' },
inputFocus: { borderColor: '#0891b2' },
inputInvalid: { borderColor: '#dc2626' },
error: { color: '#dc2626', fontSize: '11px' },
},
},
}

Dynamická změna vzhledu za běhu

Vzhled karetního formuláře lze měnit i po inicializaci — například při přepnutí mezi světlým a tmavým režimem. Použijte metodu setAppearance() na instanci Card modulu:

const result = await useCheckout({ /* ... */ });
const instanceCard = result.card?.instance;

// Přepnutí do dark mode
instanceCard.setAppearance({
version: 1, // zvedněte o 1 při každé změně
variables: {
colorText: '#e5e7eb',
colorBackground: '#2c2c2e',
colorPrimary: '#a1a1aa',
colorDanger: '#f87171',
colorPlaceholder: '#52525b',
borderColor: '#3f3f46',
borderRadius: '4px',
},
rules: {
container: {
backgroundColor: '#0f0f0f',
},
label: {
color: '#71717a',
fontWeight: '500',
},
input: {
backgroundColor: '#2c2c2e',
color: '#e5e7eb',
borderColor: '#3f3f46',
},
inputFocus: {
borderColor: '#a1a1aa',
boxShadow: '0 0 0 2px rgba(161, 161, 170, 0.15)',
},
inputInvalid: {
borderColor: '#f87171',
boxShadow: '0 0 0 2px rgba(248, 113, 113, 0.15)',
},
error: {
color: '#f87171',
},
},
});

Metoda přijímá stejný formát jako appearance v konfiguraci card. Změna se projeví okamžitě.

Změna jazyka

Jazyk celého SDK — včetně textů tlačítek a chybových hlášek — lze změnit za běhu voláním changeLocale() na instanci Core modulu:

const result = await useCheckout({ /* ... */ });
const instanceCore = result.core?.instance;

// Přepnutí jazyka na angličtinu
instanceCore.changeLocale('en');