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:
- 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
uiv konfiguračním parametruapplepaynebogooglepaylze 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í. - 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ýiframeje 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
| Parametr | Typ | Povolené hodnoty | Default | Popis |
|---|---|---|---|---|
type | string | plain, 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. |
color | string | black, white, white-with-outline | 'black' | Barevná varianta tlačítka. |
enableResizeListener | boolean | true, false | true | Zapne automatické přizpůsobení tlačítka při změně rozměrů kontejneru. |
style | object | – | – | Rozměry a zaoblení tlačítka — viz tabulka níže. |
applepay.ui.style
Přes volitelný objekt style lze doplnit rozměry a zaoblení:
| Parametr | Typ | Default | Popis |
|---|---|---|---|
width | number | – | Šířka v px; pokud není nastavena, tlačítko vyplní šířku kontejneru. |
height | number | – | Výška v px; pokud není nastavena, tlačítko vyplní výšku kontejneru. |
borderRadius | number | 4 | Zaoblení rohů v px. |
paddingX | number | 0 | Vodorovný padding uvnitř tlačítka v px. |
paddingY | number | 2 | Svislý padding uvnitř tlačítka v px. |
boxSizing | 'border-box' | 'content-box' | 'border-box' | Model rámečku. |
applepay.payment
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.
| Parametr | Typ | Povinný | Default | Popis |
|---|---|---|---|---|
provider | string | Ano (pokud payment uvedete) | 'COMGATE' | Poskytovatel zpracování Apple Pay. Povolené: 'COMGATE', 'CSOB'. |
providerId | string | Ne | – | ID poskytovatele (pokud se liší od výchozího). |
applepay.actions
| Parametr | Typ | Popis |
|---|---|---|
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
- Online simulátor — oficiální nástroj pro testování různých konfigurací Apple Pay tlačítka
- Marketing Guidelines — marketingové pokyny, jak správně používat Apple Pay tlačítka
- Human Interface Guidelines — pokyny pro návrh uživatelského rozhraní pro integraci Apple Pay
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
| Parametr | Typ | Povolené hodnoty | Default | Popis |
|---|---|---|---|---|
type | string | book, buy, checkout, donate, order, pay, plain, subscribe, short | 'plain' | Text/logo zobrazené na tlačítku. |
color | string | black, white | 'black' | Barevná varianta tlačítka. |
enableResizeListener | boolean | true, false | – | Zapne automatické přizpůsobení tlačítka při změně rozměrů kontejneru. |
Hodnota short odpovídá tlačítku pouze s logem (bez textu), buy zobrazí text „Buy with Google Pay".
googlepay.payment
| Parametr | Typ | Povinný | Default | Popis |
|---|---|---|---|---|
googlePayMerchantId | string | Ne (test) / Ano (prod) | – | Merchant ID z Google Pay Business Console. Pro testování není vyžadováno, pro produkci je povinné. |
provider | string | Ne | 'COMGATE' | Poskytovatel zpracování Google Pay. Povolené: 'COMGATE', 'CSOB'. |
providerId | string | Ne | – | ID poskytovatele (pokud se liší od výchozího). |
googlepay.actions
| Parametr | Typ | Popis |
|---|---|---|
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řidestroy(). - 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.
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:
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í.
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.
- V kontejneru
- Mimo kontejner
<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>
<div id="cg-card-box" class="is-loading">
<div id="cg-card-box-ibox"></div>
</div>
<!-- tlačítko kdekoliv jinde na stránce -->
<div id="cg-card-box-button" class="is-loading">
<button type="button">Zaplatit</button>
</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.
Hierarchie aplikace stylů: výchozí CSS → variables → rules (každá vrstva přepisuje předchozí).
Hlavní objekt appearance
| Parametr | Typ | Povinný | Popis |
|---|---|---|---|
version | number | Ano | Verze appearance konfigurace — zvedněte 1 při každé změně. |
variables | object | Ne | Designové atributy (CSS custom properties) — viz tabulka níže. |
rules | object | Ne | Per-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.
| Parametr | Popis |
|---|---|
colorText | Barva textu (inputy, popisky). |
colorBackground | Barva pozadí inputů. |
colorPrimary | Primární barva — rámeček při focusu, aktivní prvky. |
colorDanger | Barva nebezpečí — rámeček nevalidního pole, text chybové hlášky. |
colorPlaceholder | Barva placeholder textu. |
borderColor | Výchozí barva rámečku inputu. |
borderRadius | Zaoblení rohů inputu. |
fontFamily | Font formuláře (omezeno na povolený allowlist). |
fontSize | Velikost písma inputu. |
spacing | Padding 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 |
|---|---|
container | Kořenový kontejner formuláře ([data-slot="container"]) |
label | Popisek nad inputem ([data-slot="label"]) |
input | Input ve výchozím stavu ([data-slot="input"]) |
inputFocus | Input ve stavu focus ([data-slot="input"][data-state="focus"]) |
inputInvalid | Input s nevalidní hodnotou ([data-slot="input"][data-invalid]) |
error | Chybová zpráva pod inputem ([data-slot="error"]) |
Každý klíč přijímá objekt s povolenými CSS vlastnostmi (SafeStyle):
| CSS vlastnost | Typ | Příklad |
|---|---|---|
color | string | '#111827' |
backgroundColor | string | '#ffffff' |
borderColor | string | '#e5e7eb' |
borderRadius | string | '6px' |
fontFamily | string | 'Arial, sans-serif' |
fontSize | string | '14px' |
fontWeight | string | '500' |
lineHeight | string | '1.5' |
letterSpacing | string | '0.5px' |
paddingBlock | string | '10px' |
paddingInline | string | '12px' |
boxShadow | string | '0 0 0 2px rgba(0, 102, 204, 0.25)' |
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');