Examples
3D Secure Integration 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
3D Secure Integration Example
Learn how to implement 3D Secure authentication with the PaySight Widget
3D Secure Integration Example
This example demonstrates how to implement 3D Secure (3DS) authentication with the PaySight Widget, including handling the complete 3DS flow and providing appropriate user feedback.
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 - 3DS Integration</title>
<style>
body {
font-family: system-ui, -apple-system, sans-serif;
line-height: 1.5;
margin: 0;
padding: 20px;
background-color: #f8fafc;
}
.container {
max-width: 600px;
margin: 40px auto;
background-color: white;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
padding: 24px;
}
.header {
text-align: center;
margin-bottom: 24px;
}
.header h1 {
margin: 0;
color: #0f172a;
font-size: 24px;
}
.header p {
margin: 8px 0 0;
color: #64748b;
}
.status-message {
padding: 12px 16px;
border-radius: 6px;
margin-bottom: 16px;
display: none;
font-size: 14px;
}
.error {
background-color: #fee2e2;
border: 1px solid #ef4444;
color: #b91c1c;
}
.success {
background-color: #dcfce7;
border: 1px solid #22c55e;
color: #15803d;
}
.info {
background-color: #e0f2fe;
border: 1px solid #0ea5e9;
color: #0369a1;
}
.widget-container {
border: 1px solid #e5e7eb;
border-radius: 6px;
padding: 20px;
}
.progress-steps {
display: flex;
justify-content: space-between;
margin-bottom: 24px;
position: relative;
}
.progress-steps::before {
content: '';
position: absolute;
top: 14px;
left: 0;
right: 0;
height: 2px;
background-color: #e5e7eb;
z-index: 0;
}
.step {
position: relative;
z-index: 1;
background-color: white;
padding: 0 12px;
text-align: center;
}
.step-number {
width: 30px;
height: 30px;
border-radius: 50%;
background-color: #e5e7eb;
color: #64748b;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 8px;
font-weight: 500;
transition: all 0.2s ease;
}
.step-label {
font-size: 14px;
color: #64748b;
transition: all 0.2s ease;
}
.step.active .step-number {
background-color: #3b82f6;
color: white;
}
.step.active .step-label {
color: #0f172a;
font-weight: 500;
}
.step.complete .step-number {
background-color: #22c55e;
color: white;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Secure Payment</h1>
<p>Complete your payment with 3D Secure authentication</p>
</div>
<div class="progress-steps">
<div class="step active" id="step-1">
<div class="step-number">1</div>
<div class="step-label">Card Details</div>
</div>
<div class="step" id="step-2">
<div class="step-number">2</div>
<div class="step-label">3D Secure</div>
</div>
<div class="step" id="step-3">
<div class="step-number">3</div>
<div class="step-label">Confirmation</div>
</div>
</div>
<div id="info-message" class="status-message info"></div>
<div id="error-message" class="status-message error"></div>
<div id="success-message" class="status-message success"></div>
<div id="widget-container" class="widget-container"></div>
</div>
<!-- Add the PaySight Widget SDK -->
<script src="https://payment.paysight.io/widget-sdk.js"></script>
<script>
// Widget configuration
const config = {
productId: YOUR_PRODUCT_ID,
sessionId: \`session_\${Date.now()}\`,
amount: 2999,
environment: 'production',
threeDSRequired: true, // Enable 3DS
ecom: true,
currency: 'USD',
locale: 'en-US'
};
// Initialize widget
const widget = PaySightSDK.createWidget({
targetId: 'widget-container',
config,
onReady: handleWidgetReady,
onError: handleError,
onMessage: handleMessage
});
// Widget ready handler
function handleWidgetReady() {
console.log('Widget is ready');
updateProgress('step-1');
}
// Error handler
function handleError(error) {
console.error('Widget error:', error);
showError(error.message);
updateProgress('step-1');
}
// Message handler
function handleMessage(message) {
console.log('Message received:', message);
switch (message.type) {
case 'PAYMENT_START':
hideMessages();
showInfo('Processing payment...');
break;
case 'PAYMENT_3DS_START':
hideMessages();
showInfo('Starting 3D Secure verification...');
updateProgress('step-2');
break;
case 'PAYMENT_3DS_SUCCESS':
hideMessages();
showInfo('3D Secure verification successful, completing payment...');
break;
case 'PAYMENT_3DS_ERROR':
handlePaymentError(message.payload);
updateProgress('step-1');
break;
case 'PAYMENT_3DS_FAILURE':
handlePaymentError({
message: '3D Secure verification failed. Please try again.'
});
updateProgress('step-1');
break;
case 'PAYMENT_SUCCESS':
handlePaymentSuccess(message.payload);
updateProgress('step-3');
break;
case 'PAYMENT_ERROR':
handlePaymentError(message.payload);
updateProgress('step-1');
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}`
);
// Optional: Redirect to success page after delay
setTimeout(() => {
// window.location.href = '/payment-success';
}, 3000);
}
// Payment error handler
function handlePaymentError(payload) {
showError(payload.message);
}
// Progress management
function updateProgress(stepId) {
const steps = ['step-1', 'step-2', 'step-3'];
const currentIndex = steps.indexOf(stepId);
steps.forEach((step, index) => {
const element = document.getElementById(step);
element.classList.remove('active', 'complete');
if (index === currentIndex) {
element.classList.add('active');
} else if (index < currentIndex) {
element.classList.add('complete');
}
});
}
// UI Helper functions
function showSuccess(message) {
const element = document.getElementById('success-message');
element.textContent = message;
element.style.display = 'block';
hideOtherMessages('success-message');
}
function showError(message) {
const element = document.getElementById('error-message');
element.textContent = message;
element.style.display = 'block';
hideOtherMessages('error-message');
}
function showInfo(message) {
const element = document.getElementById('info-message');
element.textContent = message;
element.style.display = 'block';
hideOtherMessages('info-message');
}
function hideMessages() {
document.getElementById('success-message').style.display = 'none';
document.getElementById('error-message').style.display = 'none';
document.getElementById('info-message').style.display = 'none';
}
function hideOtherMessages(currentId) {
const messageIds = ['success-message', 'error-message', 'info-message'];
messageIds
.filter(id => id !== currentId)
.forEach(id => {
document.getElementById(id).style.display = 'none';
});
}
</script>
</body>
</html>
Key Components
1. Enable 3DS
const config = {
productId: YOUR_PRODUCT_ID,
sessionId: 'unique-session-id',
amount: 2999,
environment: 'production',
threeDSRequired: true // Enable 3DS authentication
};
2. Handle 3DS Events
function handleMessage(message) {
switch (message.type) {
case 'PAYMENT_3DS_START':
// 3DS verification started
showLoadingUI();
break;
case 'PAYMENT_3DS_SUCCESS':
// 3DS verification successful
hideLoadingUI();
break;
case 'PAYMENT_3DS_ERROR':
// 3DS verification error
handleError(message.payload);
break;
case 'PAYMENT_3DS_FAILURE':
// 3DS verification failed
handleFailure(message.payload);
break;
}
}
3. Progress Tracking
function updateProgress(stepId) {
const steps = ['step-1', 'step-2', 'step-3'];
const currentIndex = steps.indexOf(stepId);
steps.forEach((step, index) => {
const element = document.getElementById(step);
element.classList.remove('active', 'complete');
if (index === currentIndex) {
element.classList.add('active');
} else if (index < currentIndex) {
element.classList.add('complete');
}
});
}
Implementation Steps
-
Enable 3DS
- Set
threeDSRequired: true
in configuration - Ensure proper environment setup
- Set
-
Handle 3DS Flow
- Implement all 3DS event handlers
- Show appropriate loading states
- Handle success and error cases
-
Add Progress Tracking
- Create progress indicator UI
- Update progress based on events
- Show current step to user
-
Implement Error Handling
- Handle 3DS-specific errors
- Show user-friendly error messages
- Provide recovery options
-
Add User Feedback
- Show loading indicators
- Display progress messages
- Confirm successful completion
Best Practices
- Clear User Communication
function showUserFeedback(step) {
const messages = {
'PAYMENT_3DS_START': 'Verifying your card with 3D Secure...',
'PAYMENT_3DS_SUCCESS': '3D Secure verification successful',
'PAYMENT_3DS_ERROR': 'Unable to complete 3D Secure verification'
};
showMessage(messages[step]);
}
- Handle Timeouts
const TIMEOUT_DURATION = 60000; // 60 seconds
let timeoutId = setTimeout(() => {
handleTimeout();
}, TIMEOUT_DURATION);
function handleTimeout() {
showError('3D Secure verification timed out. Please try again.');
updateProgress('step-1');
}
- Implement Recovery
function handleError(error) {
if (error.code === '3DS_UNAVAILABLE') {
// Fallback to non-3DS payment if allowed
retryWithout3DS();
} else {
// Show error and reset form
showError(error.message);
resetForm();
}
}
Next Steps
- Basic Integration Example - Simple implementation example
- Custom Styling Example - Customize widget appearance
- Error Handling Example - Advanced error handling
- Configuration Guide - Complete configuration options