Examples
Custom Styling Example
Widget SDK Reference
Examples
Paysight API
Email Services
Payment API
- Card
Customer Service API
- API Reference
Admin API
- MerchantAccounts
Mitigation API
- API for Chargeback Mitigation Providers
Examples
Custom Styling Example
Learn how to customize the appearance of the PaySight Widget with advanced styling options
Custom Styling Example
This example demonstrates how to create a beautifully styled payment form using the PaySight Widget’s theming capabilities.
Complete Implementation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PaySight Widget - Custom Styling</title>
<!-- Add Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<style>
:root {
--primary-color: #6366f1;
--primary-dark: #4f46e5;
--error-color: #ef4444;
--success-color: #22c55e;
--text-color: #0f172a;
--text-light: #64748b;
--border-color: #e2e8f0;
--background-color: #f8fafc;
--surface-color: #ffffff;
}
/* Dark mode support */
@media (prefers-color-scheme: dark) {
:root {
--primary-color: #818cf8;
--primary-dark: #6366f1;
--text-color: #f1f5f9;
--text-light: #94a3b8;
--border-color: #334155;
--background-color: #0f172a;
--surface-color: #1e293b;
}
}
body {
font-family: 'Inter', system-ui, -apple-system, sans-serif;
line-height: 1.5;
margin: 0;
padding: 20px;
background-color: var(--background-color);
color: var(--text-color);
}
.container {
max-width: 600px;
margin: 40px auto;
background-color: var(--surface-color);
border-radius: 16px;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
padding: 32px;
}
.header {
text-align: center;
margin-bottom: 32px;
}
.header h1 {
margin: 0;
font-size: 24px;
font-weight: 600;
color: var(--text-color);
}
.header p {
margin: 8px 0 0;
color: var(--text-light);
}
.widget-container {
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 24px;
background-color: var(--surface-color);
}
.status-message {
padding: 12px 16px;
border-radius: 8px;
margin-bottom: 20px;
display: none;
font-size: 14px;
font-weight: 500;
}
.error {
background-color: rgb(239 68 68 / 0.1);
border: 1px solid var(--error-color);
color: var(--error-color);
}
.success {
background-color: rgb(34 197 94 / 0.1);
border: 1px solid var(--success-color);
color: var(--success-color);
}
/* Theme toggle button */
.theme-toggle {
position: fixed;
bottom: 20px;
right: 20px;
background-color: var(--surface-color);
border: 1px solid var(--border-color);
color: var(--text-color);
padding: 8px 16px;
border-radius: 8px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.2s ease;
}
.theme-toggle:hover {
background-color: var(--border-color);
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Complete Your Payment</h1>
<p>Secure payment processing by PaySight</p>
</div>
<div id="success-message" class="status-message success"></div>
<div id="error-message" class="status-message error"></div>
<div id="widget-container" class="widget-container"></div>
</div>
<button id="theme-toggle" class="theme-toggle">
Toggle Theme
</button>
<!-- Add the PaySight Widget SDK -->
<script src="https://payment.paysight.io/widget-sdk.js"></script>
<script>
// Theme configuration
const lightTheme = {
font: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap',
css: {
":root": {
"--primary-color": "#6366f1",
"--primary-dark": "#4f46e5",
"--error-color": "#ef4444",
"--text-color": "#0f172a",
"--text-light": "#64748b",
"--border-color": "#e2e8f0",
"--background": "#ffffff",
"--input-height": "40px",
"--border-radius": "8px",
"--shadow-color": "rgb(0 0 0 / 0.1)"
},
// Input styles
input: {
height: "var(--input-height)",
padding: "0 16px",
fontSize: "15px",
fontWeight: "500",
borderRadius: "var(--border-radius)",
border: "1px solid var(--border-color)",
color: "var(--text-color)",
backgroundColor: "var(--background)",
transition: "all 0.2s ease",
"&::placeholder": {
color: "var(--text-light)",
fontWeight: "400"
},
"&:focus": {
outline: "none",
borderColor: "var(--primary-color)",
boxShadow: "0 0 0 3px rgb(99 102 241 / 0.1)"
}
},
// Button styles
button: {
backgroundColor: "var(--primary-color)",
color: "#ffffff",
padding: "0 24px",
height: "var(--input-height)",
borderRadius: "var(--border-radius)",
fontSize: "15px",
fontWeight: "500",
border: "none",
cursor: "pointer",
transition: "all 0.2s ease",
"&:hover": {
backgroundColor: "var(--primary-dark)"
},
"&:focus": {
outline: "none",
boxShadow: "0 0 0 3px rgb(99 102 241 / 0.1)"
}
},
// Label styles
label: {
fontSize: "14px",
fontWeight: "500",
color: "var(--text-color)",
marginBottom: "6px"
},
// Error message styles
".error": {
color: "var(--error-color)",
fontSize: "13px",
marginTop: "6px",
fontWeight: "500"
},
// Card field styles
"[ev-component=card]": {
gap: "16px",
".field[ev-name=number]": {
"& input": {
paddingLeft: "48px"
},
"& .icon": {
left: "16px",
width: "20px",
height: "20px"
}
}
}
}
};
const darkTheme = {
...lightTheme,
css: {
...lightTheme.css,
":root": {
"--primary-color": "#818cf8",
"--primary-dark": "#6366f1",
"--error-color": "#ef4444",
"--text-color": "#f1f5f9",
"--text-light": "#94a3b8",
"--border-color": "#334155",
"--background": "#1e293b",
"--input-height": "40px",
"--border-radius": "8px",
"--shadow-color": "rgb(0 0 0 / 0.3)"
}
}
};
// Widget configuration
const config = {
productId: YOUR_PRODUCT_ID,
sessionId: \`session_\${Date.now()}\`,
amount: 2999,
environment: 'production',
threeDSRequired: true,
theme: lightTheme
};
// Initialize widget
const widget = PaySightSDK.createWidget({
targetId: 'widget-container',
config,
onReady: () => console.log('Widget ready'),
onError: handleError,
onMessage: handleMessage
});
// Error handler
function handleError(error) {
console.error('Widget error:', error);
showError(error.message);
}
// Message handler
function handleMessage(message) {
switch (message.type) {
case 'PAYMENT_SUCCESS':
handlePaymentSuccess(message.payload);
break;
case 'PAYMENT_ERROR':
handlePaymentError(message.payload);
break;
}
}
// Payment success handler
function handlePaymentSuccess(payload) {
const { transactionId, amount, currency } = payload;
const formattedAmount = new Intl.NumberFormat('en-US', {
style: 'currency',
currency
}).format(amount / 100);
showSuccess(
`Payment successful! Amount: ${formattedAmount}, Transaction ID: ${transactionId}`
);
}
// Payment error handler
function handlePaymentError(payload) {
showError(payload.message);
}
// UI Helper functions
function showSuccess(message) {
const element = document.getElementById('success-message');
element.textContent = message;
element.style.display = 'block';
document.getElementById('error-message').style.display = 'none';
}
function showError(message) {
const element = document.getElementById('error-message');
element.textContent = message;
element.style.display = 'block';
document.getElementById('success-message').style.display = 'none';
}
// Theme toggle
let isDarkTheme = false;
document.getElementById('theme-toggle').addEventListener('click', () => {
isDarkTheme = !isDarkTheme;
widget.update({
theme: isDarkTheme ? darkTheme : lightTheme
});
});
</script>
</body>
</html>
Key Styling Features
1. Theme Configuration
const theme = {
// Google Font integration
font: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap',
// Custom CSS
css: {
// CSS variables
":root": {
"--primary-color": "#6366f1",
"--text-color": "#0f172a"
},
// Component styles
input: {
// Input field styles
},
button: {
// Button styles
}
}
};
2. Dark Mode Support
const darkTheme = {
css: {
":root": {
"--primary-color": "#818cf8",
"--text-color": "#f1f5f9",
"--background": "#1e293b"
}
}
};
// Update theme
widget.update({ theme: darkTheme });
3. Component-Specific Styles
const theme = {
css: {
// Card input styling
"[ev-component=card]": {
gap: "16px",
// Card number field
".field[ev-name=number]": {
"& input": {
paddingLeft: "48px"
}
}
}
}
};
4. State-Based Styling
const theme = {
css: {
// Focus states
"input:focus": {
outline: "none",
borderColor: "var(--primary-color)",
boxShadow: "0 0 0 3px rgb(99 102 241 / 0.1)"
},
// Error states
".error": {
color: "var(--error-color)",
fontSize: "13px",
fontWeight: "500"
}
}
};
Implementation Steps
-
Define Theme Variables
- Set up CSS variables for consistent styling
- Include both light and dark mode values
-
Create Base Styles
- Style container elements
- Set up typography
- Configure spacing and layout
-
Style Form Components
- Customize input fields
- Style buttons
- Add field labels and error messages
-
Add Interactive States
- Implement hover effects
- Add focus states
- Style error states
-
Implement Dark Mode
- Create dark theme variables
- Add theme toggle functionality
- Test both themes
-
Add Polish
- Include transitions
- Add subtle animations
- Ensure consistent spacing
Best Practices
-
Use CSS Variables
const theme = { css: { ":root": { "--primary": "#6366f1", "--text": "#0f172a" }, button: { backgroundColor: "var(--primary)", color: "var(--text)" } } };
-
Maintain Consistency
const spacing = { sm: "8px", md: "16px", lg: "24px" }; const theme = { css: { input: { padding: spacing.md, marginBottom: spacing.md } } };
-
Follow Accessibility Guidelines
const theme = { css: { // Ensure sufficient color contrast button: { backgroundColor: "#6366f1", color: "#ffffff", // Visible focus indicators "&:focus": { outline: "2px solid #818cf8", outlineOffset: "2px" } } } };
Next Steps
- Basic Integration Example - Simple implementation example
- 3DS Integration Example - 3D Secure implementation
- Error Handling Example - Advanced error handling
- Styling Guide - Complete styling documentation