stripe-testing-tool / index.html
offerpk3's picture
Update index.html
cf0c0d0 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Payment Testing Tool</title>
<!-- Tailwind CSS -->
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--primary-color: #635bff;
--primary-light: #7a73ff;
--primary-dark: #4b44d1;
--secondary-color: #0a2540;
--success-color: #3ecf8e;
--warning-color: #f7b500;
--danger-color: #e25950;
--neutral-light: #f6f9fc;
--neutral-medium: #e3e8ee;
--neutral-dark: #697386;
}
body {
font-family: 'Inter', sans-serif;
background-color: var(--neutral-light);
color: var(--secondary-color);
}
.navbar {
background-color: white;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.card {
background-color: white;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08);
transition: all 0.3s;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 7px 14px rgba(50, 50, 93, 0.1), 0 3px 6px rgba(0, 0, 0, 0.08);
}
.btn-primary {
background-color: var(--primary-color);
color: white;
border-radius: 6px;
padding: 10px 20px;
font-weight: 500;
transition: all 0.2s;
}
.btn-primary:hover {
background-color: var(--primary-light);
}
.btn-secondary {
background-color: white;
color: var(--secondary-color);
border: 1px solid var(--neutral-medium);
border-radius: 6px;
padding: 10px 20px;
font-weight: 500;
transition: all 0.2s;
}
.btn-secondary:hover {
background-color: var(--neutral-light);
}
.tab-active {
border-bottom: 2px solid var(--primary-color);
color: var(--primary-color);
font-weight: 500;
}
.tab {
padding: 10px 16px;
cursor: pointer;
transition: all 0.2s;
}
.tab:hover:not(.tab-active) {
color: var(--primary-light);
}
.test-card {
border: 1px solid var(--neutral-medium);
border-radius: 6px;
padding: 12px;
margin-bottom: 8px;
cursor: pointer;
transition: all 0.2s;
}
.test-card:hover {
border-color: var(--primary-color);
background-color: rgba(99, 91, 255, 0.05);
}
.copy-btn {
color: var(--neutral-dark);
transition: all 0.2s;
}
.copy-btn:hover {
color: var(--primary-color);
}
.badge {
font-size: 0.75rem;
padding: 2px 8px;
border-radius: 12px;
font-weight: 500;
}
.badge-success {
background-color: rgba(62, 207, 142, 0.2);
color: var(--success-color);
}
.badge-warning {
background-color: rgba(247, 181, 0, 0.2);
color: var(--warning-color);
}
.badge-danger {
background-color: rgba(226, 89, 80, 0.2);
color: var(--danger-color);
}
.badge-primary {
background-color: rgba(99, 91, 255, 0.2);
color: var(--primary-color);
}
.search-input {
border: 1px solid var(--neutral-medium);
border-radius: 6px;
padding: 10px 16px;
width: 100%;
transition: all 0.2s;
}
.search-input:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 1px var(--primary-color);
}
.sidebar {
background-color: white;
border-right: 1px solid var(--neutral-medium);
}
.sidebar-item {
padding: 10px 16px;
cursor: pointer;
transition: all 0.2s;
border-radius: 6px;
margin: 4px 0;
}
.sidebar-item:hover {
background-color: var(--neutral-light);
}
.sidebar-item.active {
background-color: rgba(99, 91, 255, 0.1);
color: var(--primary-color);
font-weight: 500;
}
.code-block {
background-color: var(--secondary-color);
color: white;
border-radius: 6px;
padding: 16px;
font-family: monospace;
overflow-x: auto;
}
.slider {
-webkit-appearance: none;
width: 100%;
height: 6px;
border-radius: 5px;
background: var(--neutral-medium);
outline: none;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--primary-color);
cursor: pointer;
transition: all 0.2s;
}
.slider::-webkit-slider-thumb:hover {
transform: scale(1.1);
box-shadow: 0 0 0 6px rgba(99, 91, 255, 0.2);
}
.slider::-moz-range-thumb {
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--primary-color);
cursor: pointer;
transition: all 0.2s;
}
.slider::-moz-range-thumb:hover {
transform: scale(1.1);
box-shadow: 0 0 0 6px rgba(99, 91, 255, 0.2);
}
/* Custom switch */
.switch {
position: relative;
display: inline-block;
width: 48px;
height: 24px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider-switch {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--neutral-medium);
transition: .4s;
border-radius: 24px;
}
.slider-switch:before {
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 3px;
bottom: 3px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider-switch {
background-color: var(--primary-color);
}
input:checked + .slider-switch:before {
transform: translateX(24px);
}
/* Tooltip */
.tooltip {
position: relative;
display: inline-block;
}
.tooltip .tooltip-text {
visibility: hidden;
width: 200px;
background-color: var(--secondary-color);
color: white;
text-align: center;
border-radius: 6px;
padding: 8px;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
transform: translateX(-50%);
opacity: 0;
transition: opacity 0.3s;
font-size: 0.75rem;
}
.tooltip:hover .tooltip-text {
visibility: visible;
opacity: 1;
}
/* Responsive table */
.responsive-table {
width: 100%;
overflow-x: auto;
}
.responsive-table table {
width: 100%;
border-collapse: collapse;
}
.responsive-table th {
background-color: var(--neutral-light);
padding: 12px;
text-align: left;
font-weight: 500;
color: var(--neutral-dark);
}
.responsive-table td {
padding: 12px;
border-bottom: 1px solid var(--neutral-medium);
}
/* Animations */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.fade-in {
animation: fadeIn 0.3s ease-in-out;
}
@keyframes slideIn {
from { transform: translateY(10px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
.slide-in {
animation: slideIn 0.3s ease-in-out;
}
</style>
</head>
<body>
<!-- Navbar -->
<nav class="navbar p-4 flex items-center justify-between">
<div class="flex items-center">
<div class="text-2xl font-bold text-primary-color flex items-center">
<i class="fas fa-credit-card mr-2 text-primary-color"></i>
<span>Payment Testing Tool</span>
</div>
</div>
<div class="flex items-center space-x-4">
<button class="btn-secondary">
<i class="fas fa-moon mr-2"></i>
Dark Mode
</button>
<button class="btn-primary">
<i class="fas fa-code mr-2"></i>
API Reference
</button>
</div>
</nav>
<!-- Main Content -->
<div class="flex">
<!-- Sidebar -->
<div class="sidebar w-64 h-screen sticky top-0 p-4 hidden md:block">
<div class="mb-6">
<div class="text-sm text-neutral-dark mb-2">TESTING</div>
<div class="sidebar-item active">
<i class="fas fa-credit-card mr-2"></i>
Card Testing
</div>
<div class="sidebar-item">
<i class="fas fa-globe mr-2"></i>
Payment Methods
</div>
<div class="sidebar-item">
<i class="fas fa-exclamation-triangle mr-2"></i>
Error Simulation
</div>
<div class="sidebar-item">
<i class="fas fa-shield-alt mr-2"></i>
3D Secure
</div>
<div class="sidebar-item">
<i class="fas fa-exchange-alt mr-2"></i>
Webhooks
</div>
</div>
<div class="mb-6">
<div class="text-sm text-neutral-dark mb-2">RESOURCES</div>
<div class="sidebar-item">
<i class="fas fa-book mr-2"></i>
Documentation
</div>
<div class="sidebar-item">
<i class="fas fa-code mr-2"></i>
API Reference
</div>
<div class="sidebar-item">
<i class="fas fa-question-circle mr-2"></i>
Help & Support
</div>
</div>
<div>
<div class="text-sm text-neutral-dark mb-2">SETTINGS</div>
<div class="sidebar-item">
<i class="fas fa-cog mr-2"></i>
Preferences
</div>
<div class="sidebar-item">
<i class="fas fa-key mr-2"></i>
API Keys
</div>
</div>
</div>
<!-- Content -->
<div class="flex-1 p-6">
<div class="mb-8">
<h1 class="text-3xl font-bold mb-2">Payment Testing Tool</h1>
<p class="text-neutral-dark">Simulate payments and test your integration without moving any money.</p>
</div>
<!-- Tabs -->
<div class="flex border-b border-neutral-medium mb-6">
<div class="tab tab-active" onclick="switchTab('card-testing')">Card Testing</div>
<div class="tab" onclick="switchTab('payment-methods')">Payment Methods</div>
<div class="tab" onclick="switchTab('error-simulation')">Error Simulation</div>
<div class="tab" onclick="switchTab('3d-secure')">3D Secure</div>
</div>
<!-- Card Testing Tab -->
<div id="card-testing" class="tab-content slide-in">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Left Column -->
<div class="lg:col-span-2">
<div class="card p-6 mb-6">
<h2 class="text-xl font-semibold mb-4">Test Card Numbers</h2>
<p class="mb-4">Use these card numbers to test different payment scenarios. Any future expiration date and any 3-digit CVC will work.</p>
<!-- Search and Filter -->
<div class="flex flex-col md:flex-row space-y-2 md:space-y-0 md:space-x-4 mb-4">
<div class="flex-1">
<input type="text" class="search-input" placeholder="Search cards..." id="card-search">
</div>
<div>
<select class="search-input" id="card-filter">
<option value="all">All Cards</option>
<option value="brand">By Brand</option>
<option value="country">By Country</option>
<option value="scenario">By Scenario</option>
</select>
</div>
</div>
<!-- Cards by Brand -->
<div class="mb-4">
<h3 class="text-lg font-medium mb-3">Cards by Brand</h3>
<div class="test-card flex justify-between items-center" onclick="copyToClipboard('4242424242424242')">
<div>
<div class="flex items-center">
<img src="https://www.pngitem.com/pimgs/m/6-62449_visa-logo-png-transparent-visa-card-logo-png.png" alt="Visa" class="h-6 mr-2">
<span class="font-medium">Visa</span>
</div>
<div class="text-neutral-dark mt-1">4242 4242 4242 4242</div>
</div>
<div class="flex items-center">
<span class="badge badge-success mr-2">Success</span>
<button class="copy-btn" onclick="event.stopPropagation(); copyToClipboard('4242424242424242')">
<i class="far fa-copy"></i>
</button>
</div>
</div>
<div class="test-card flex justify-between items-center" onclick="copyToClipboard('4000056655665556')">
<div>
<div class="flex items-center">
<img src="https://www.pngitem.com/pimgs/m/6-62449_visa-logo-png-transparent-visa-card-logo-png.png" alt="Visa" class="h-6 mr-2">
<span class="font-medium">Visa (debit)</span>
</div>
<div class="text-neutral-dark mt-1">4000 0566 5566 5556</div>
</div>
<div class="flex items-center">
<span class="badge badge-success mr-2">Success</span>
<button class="copy-btn" onclick="event.stopPropagation(); copyToClipboard('4000056655665556')">
<i class="far fa-copy"></i>
</button>
</div>
</div>
<div class="test-card flex justify-between items-center" onclick="copyToClipboard('5555555555554444')">
<div>
<div class="flex items-center">
<img src="https://www.mastercard.us/content/dam/public/mastercardcom/na/us/en/homepage/Home/mc-logo-52.svg" alt="Mastercard" class="h-6 mr-2">
<span class="font-medium">Mastercard</span>
</div>
<div class="text-neutral-dark mt-1">5555 5555 5555 4444</div>
</div>
<div class="flex items-center">
<span class="badge badge-success mr-2">Success</span>
<button class="copy-btn" onclick="event.stopPropagation(); copyToClipboard('5555555555554444')">
<i class="far fa-copy"></i>
</button>
</div>
</div>
<div class="test-card flex justify-between items-center" onclick="copyToClipboard('378282246310005')">
<div>
<div class="flex items-center">
<img src="https://www.pngitem.com/pimgs/m/217-2172284_transparent-amex-logo-american-express-black-logo-hd.png" alt="American Express" class="h-6 mr-2">
<span class="font-medium">American Express</span>
</div>
<div class="text-neutral-dark mt-1">3782 822463 10005</div>
</div>
<div class="flex items-center">
<span class="badge badge-success mr-2">Success</span>
<button class="copy-btn" onclick="event.stopPropagation(); copyToClipboard('378282246310005')">
<i class="far fa-copy"></i>
</button>
</div>
</div>
<div class="test-card flex justify-between items-center" onclick="copyToClipboard('6011111111111117')">
<div>
<div class="flex items-center">
<img src="https://www.pngitem.com/pimgs/m/292-2924859_discover-network-logo-png-transparent-png.png" alt="Discover" class="h-6 mr-2">
<span class="font-medium">Discover</span>
</div>
<div class="text-neutral-dark mt-1">6011 1111 1111 1117</div>
</div>
<div class="flex items-center">
<span class="badge badge-success mr-2">Success</span>
<button class="copy-btn" onclick="event.stopPropagation(); copyToClipboard('6011111111111117')">
<i class="far fa-copy"></i>
</button>
</div>
</div>
</div>
<!-- Declined Payments -->
<div class="mb-4">
<h3 class="text-lg font-medium mb-3">Declined Payments</h3>
<div class="test-card flex justify-between items-center" onclick="copyToClipboard('4000000000000002')">
<div>
<div class="flex items-center">
<img src="https://www.pngitem.com/pimgs/m/6-62449_visa-logo-png-transparent-visa-card-logo-png.png" alt="Visa" class="h-6 mr-2">
<span class="font-medium">Visa (Generic Decline)</span>
</div>
<div class="text-neutral-dark mt-1">4000 0000 0000 0002</div>
</div>
<div class="flex items-center">
<span class="badge badge-danger mr-2">Declined</span>
<button class="copy-btn" onclick="event.stopPropagation(); copyToClipboard('4000000000000002')">
<i class="far fa-copy"></i>
</button>
</div>
</div>
<div class="test-card flex justify-between items-center" onclick="copyToClipboard('4000000000009995')">
<div>
<div class="flex items-center">
<img src="https://www.pngitem.com/pimgs/m/6-62449_visa-logo-png-transparent-visa-card-logo-png.png" alt="Visa" class="h-6 mr-2">
<span class="font-medium">Visa (Insufficient Funds)</span>
</div>
<div class="text-neutral-dark mt-1">4000 0000 0000 9995</div>
</div>
<div class="flex items-center">
<span class="badge badge-danger mr-2">Declined</span>
<button class="copy-btn" onclick="event.stopPropagation(); copyToClipboard('4000000000009995')">
<i class="far fa-copy"></i>
</button>
</div>
</div>
<div class="test-card flex justify-between items-center" onclick="copyToClipboard('4000000000009987')">
<div>
<div class="flex items-center">
<img src="https://www.pngitem.com/pimgs/m/6-62449_visa-logo-png-transparent-visa-card-logo-png.png" alt="Visa" class="h-6 mr-2">
<span class="font-medium">Visa (Lost Card)</span>
</div>
<div class="text-neutral-dark mt-1">4000 0000 0000 9987</div>
</div>
<div class="flex items-center">
<span class="badge badge-danger mr-2">Declined</span>
<button class="copy-btn" onclick="event.stopPropagation(); copyToClipboard('4000000000009987')">
<i class="far fa-copy"></i>
</button>
</div>
</div>
</div>
<!-- 3D Secure Authentication -->
<div>
<h3 class="text-lg font-medium mb-3">3D Secure Authentication</h3>
<div class="test-card flex justify-between items-center" onclick="copyToClipboard('4000002500003155')">
<div>
<div class="flex items-center">
<img src="https://www.pngitem.com/pimgs/m/6-62449_visa-logo-png-transparent-visa-card-logo-png.png" alt="Visa" class="h-6 mr-2">
<span class="font-medium">Visa (3DS Required)</span>
</div>
<div class="text-neutral-dark mt-1">4000 0025 0000 3155</div>
</div>
<div class="flex items-center">
<span class="badge badge-primary mr-2">3D Secure</span>
<button class="copy-btn" onclick="event.stopPropagation(); copyToClipboard('4000002500003155')">
<i class="far fa-copy"></i>
</button>
</div>
</div>
<div class="test-card flex justify-between items-center" onclick="copyToClipboard('4000002760003184')">
<div>
<div class="flex items-center">
<img src="https://www.pngitem.com/pimgs/m/6-62449_visa-logo-png-transparent-visa-card-logo-png.png" alt="Visa" class="h-6 mr-2">
<span class="font-medium">Visa (3DS2 Frictionless)</span>
</div>
<div class="text-neutral-dark mt-1">4000 0027 6000 3184</div>
</div>
<div class="flex items-center">
<span class="badge badge-primary mr-2">3D Secure</span>
<button class="copy-btn" onclick="event.stopPropagation(); copyToClipboard('4000002760003184')">
<i class="far fa-copy"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Right Column -->
<div>
<!-- Test Card Form -->
<div class="card p-6 mb-6">
<h2 class="text-xl font-semibold mb-4">Test Payment Form</h2>
<p class="mb-4">Enter a test card number to simulate a payment.</p>
<div class="mb-4">
<label class="block text-sm font-medium mb-2">Card Number</label>
<input type="text" id="card-number" class="search-input" placeholder="4242 4242 4242 4242">
</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div>
<label class="block text-sm font-medium mb-2">Expiration Date</label>
<input type="text" class="search-input" placeholder="MM / YY">
</div>
<div>
<label class="block text-sm font-medium mb-2">CVC</label>
<input type="text" class="search-input" placeholder="123">
</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium mb-2">Amount</label>
<div class="relative">
<span class="absolute left-3 top-2.5 text-neutral-dark">$</span>
<input type="text" class="search-input pl-8" placeholder="100.00">
</div>
</div>
<div class="mb-6">
<label class="block text-sm font-medium mb-2">Currency</label>
<select class="search-input">
<option>USD - US Dollar</option>
<option>EUR - Euro</option>
<option>GBP - British Pound</option>
<option>JPY - Japanese Yen</option>
</select>
</div>
<button class="btn-primary w-full" onclick="processPayment()">
<i class="fas fa-credit-card mr-2"></i>
Process Payment
</button>
</div>
<!-- Test Result -->
<div class="card p-6" id="test-result" style="display: none;">
<h2 class="text-xl font-semibold mb-4">Test Result</h2>
<div id="result-content"></div>
</div>
</div>
</div>
</div>
<!-- Payment Methods Tab (Hidden by default) -->
<div id="payment-methods" class="tab-content hidden">
<div class="card p-6 mb-6">
<h2 class="text-xl font-semibold mb-4">Payment Methods</h2>
<p class="mb-4">Test different payment methods using these test values.</p>
<div class="mb-6">
<h3 class="text-lg font-medium mb-3">ACH Direct Debit</h3>
<div class="responsive-table">
<table>
<thead>
<tr>
<th>Account Number</th>
<th>Routing Number</th>
<th>Result</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>000123456789</td>
<td>110000000</td>
<td><span class="badge badge-success">Success</span></td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
<tr>
<td>000111111116</td>
<td>110000000</td>
<td><span class="badge badge-danger">Declined</span></td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="mb-6">
<h3 class="text-lg font-medium mb-3">SEPA Direct Debit</h3>
<div class="responsive-table">
<table>
<thead>
<tr>
<th>IBAN</th>
<th>Result</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>DE89370400440532013000</td>
<td><span class="badge badge-success">Success</span></td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
<tr>
<td>DE62370400440532013001</td>
<td><span class="badge badge-danger">Declined</span></td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
</tbody>
</table>
</div>
</div>
<div>
<h3 class="text-lg font-medium mb-3">BACS Direct Debit</h3>
<div class="responsive-table">
<table>
<thead>
<tr>
<th>Account Number</th>
<th>Sort Code</th>
<th>Result</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>00012345</td>
<td>108800</td>
<td><span class="badge badge-success">Success</span></td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
<tr>
<td>00012346</td>
<td>108800</td>
<td><span class="badge badge-danger">Declined</span></td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Error Simulation Tab (Hidden by default) -->
<div id="error-simulation" class="tab-content hidden">
<div class="card p-6 mb-6">
<h2 class="text-xl font-semibold mb-4">Error Simulation</h2>
<p class="mb-4">Simulate various error scenarios to test your error handling.</p>
<div class="mb-6">
<h3 class="text-lg font-medium mb-3">API Errors</h3>
<div class="responsive-table">
<table>
<thead>
<tr>
<th>Error Type</th>
<th>Test Value</th>
<th>Description</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>Card Declined</td>
<td>4000000000000002</td>
<td>Generic decline</td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
<tr>
<td>Insufficient Funds</td>
<td>4000000000009995</td>
<td>Insufficient funds error</td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
<tr>
<td>Processing Error</td>
<td>4000000000009987</td>
<td>Processing error</td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
<tr>
<td>Incorrect CVC</td>
<td>4000000000000127</td>
<td>Incorrect CVC code</td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
<tr>
<td>Expired Card</td>
<td>4000000000000069</td>
<td>Expired card error</td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
</tbody>
</table>
</div>
</div>
<div>
<h3 class="text-lg font-medium mb-3">Rate Limiting</h3>
<p class="mb-4">Simulate rate limiting errors by making multiple requests in quick succession.</p>
<div class="flex items-center mb-4">
<div class="mr-4">
<label class="switch">
<input type="checkbox" id="rate-limit-toggle">
<span class="slider-switch"></span>
</label>
</div>
<div>
<div class="font-medium">Enable Rate Limit Simulation</div>
<div class="text-sm text-neutral-dark">Simulates rate limiting after 3 consecutive requests</div>
</div>
</div>
<button class="btn-primary" id="test-rate-limit">
<i class="fas fa-bolt mr-2"></i>
Test Rate Limiting
</button>
</div>
</div>
</div>
<!-- 3D Secure Tab (Hidden by default) -->
<div id="3d-secure" class="tab-content hidden">
<div class="card p-6 mb-6">
<h2 class="text-xl font-semibold mb-4">3D Secure Authentication</h2>
<p class="mb-4">Test 3D Secure authentication flows with these test cards.</p>
<div class="mb-6">
<h3 class="text-lg font-medium mb-3">3D Secure 2 Test Cards</h3>
<div class="responsive-table">
<table>
<thead>
<tr>
<th>Card Number</th>
<th>Authentication</th>
<th>Description</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>4000002500003155</td>
<td><span class="badge badge-primary">Challenge</span></td>
<td>3DS authentication with challenge</td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
<tr>
<td>4000002760003184</td>
<td><span class="badge badge-success">Frictionless</span></td>
<td>3DS authentication without challenge</td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
<tr>
<td>4000008260003178</td>
<td><span class="badge badge-danger">Failed</span></td>
<td>3DS authentication fails</td>
<td><button class="copy-btn"><i class="far fa-copy"></i></button></td>
</tr>
</tbody>
</table>
</div>
</div>
<div>
<h3 class="text-lg font-medium mb-3">Test 3D Secure Authentication</h3>
<p class="mb-4">Enter a 3D Secure test card to simulate the authentication flow.</p>
<div class="mb-4">
<label class="block text-sm font-medium mb-2">Card Number</label>
<input type="text" id="3ds-card-number" class="search-input" placeholder="4000 0025 0000 3155">
</div>
<div class="grid grid-cols-2 gap-4 mb-6">
<div>
<label class="block text-sm font-medium mb-2">Expiration Date</label>
<input type="text" class="search-input" placeholder="MM / YY">
</div>
<div>
<label class="block text-sm font-medium mb-2">CVC</label>
<input type="text" class="search-input" placeholder="123">
</div>
</div>
<button class="btn-primary w-full" onclick="test3DSecure()">
<i class="fas fa-shield-alt mr-2"></i>
Test 3D Secure
</button>
</div>
</div>
</div>
</div>
</div>
<!-- 3D Secure Modal -->
<div id="3ds-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
<div class="bg-white rounded-lg p-6 max-w-md w-full">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-semibold">3D Secure Authentication</h3>
<button onclick="close3DSModal()" class="text-neutral-dark hover:text-secondary-color">
<i class="fas fa-times"></i>
</button>
</div>
<div class="mb-6">
<p class="mb-4">Please complete the authentication to proceed with your payment.</p>
<div class="bg-neutral-light p-4 rounded mb-4">
<div class="flex justify-between mb-2">
<span class="text-neutral-dark">Card:</span>
<span class="font-medium" id="3ds-card-display">**** **** **** 3155</span>
</div>
<div class="flex justify-between">
<span class="text-neutral-dark">Amount:</span>
<span class="font-medium">$100.00</span>
</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium mb-2">Authentication Code</label>
<input type="text" class="search-input" placeholder="Enter code: 123456">
</div>
</div>
<div class="flex space-x-4">
<button class="btn-secondary flex-1" onclick="close3DSModal()">Cancel</button>
<button class="btn-primary flex-1" onclick="complete3DSAuth()">Complete Authentication</button>
</div>
</div>
</div>
<script>
// Switch tabs
function switchTab(tabId) {
// Hide all tab contents
document.querySelectorAll('.tab-content').forEach(tab => {
tab.classList.add('hidden');
});
// Remove active class from all tabs
document.querySelectorAll('.tab').forEach(tab => {
tab.classList.remove('tab-active');
});
// Show selected tab content
document.getElementById(tabId).classList.remove('hidden');
document.getElementById(tabId).classList.add('slide-in');
// Add active class to selected tab
document.querySelector(`.tab[onclick="switchTab('${tabId}')"]`).classList.add('tab-active');
}
// Copy to clipboard
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
// Show a temporary tooltip or notification
alert('Copied to clipboard: ' + text);
});
}
// Process payment
function processPayment() {
const cardNumber = document.getElementById('card-number').value.replace(/\s/g, '');
let result = '';
// Show test result
document.getElementById('test-result').style.display = 'block';
// Simulate different results based on card number
if (cardNumber === '4242424242424242') {
result = `
<div class="bg-green-50 border border-green-200 rounded p-4 mb-4">
<div class="flex items-center text-green-800 font-medium mb-2">
<i class="fas fa-check-circle mr-2"></i>
Payment Successful
</div>
<p class="text-green-700">The payment was processed successfully.</p>
</div>
<div class="bg-neutral-light p-4 rounded">
<div class="grid grid-cols-2 gap-2">
<div class="text-neutral-dark">Transaction ID:</div>
<div class="font-medium">ch_1NjK9L2eZvKYlo2C0A2Uvl7g</div>
<div class="text-neutral-dark">Amount:</div>
<div class="font-medium">$100.00</div>
<div class="text-neutral-dark">Status:</div>
<div class="font-medium">Succeeded</div>
<div class="text-neutral-dark">Card:</div>
<div class="font-medium">Visa **** 4242</div>
</div>
</div>
`;
} else if (cardNumber === '4000000000000002') {
result = `
<div class="bg-red-50 border border-red-200 rounded p-4 mb-4">
<div class="flex items-center text-red-800 font-medium mb-2">
<i class="fas fa-exclamation-circle mr-2"></i>
Payment Failed
</div>
<p class="text-red-700">Your card was declined.</p>
</div>
<div class="bg-neutral-light p-4 rounded">
<div class="grid grid-cols-2 gap-2">
<div class="text-neutral-dark">Error Code:</div>
<div class="font-medium">card_declined</div>
<div class="text-neutral-dark">Error Message:</div>
<div class="font-medium">Your card was declined.</div>
<div class="text-neutral-dark">Card:</div>
<div class="font-medium">Visa **** 0002</div>
</div>
</div>
`;
} else if (cardNumber === '4000002500003155') {
// Show 3D Secure modal
show3DSModal('4000 0025 0000 3155');
return;
} else {
result = `
<div class="bg-yellow-50 border border-yellow-200 rounded p-4 mb-4">
<div class="flex items-center text-yellow-800 font-medium mb-2">
<i class="fas fa-exclamation-triangle mr-2"></i>
Invalid Card
</div>
<p class="text-yellow-700">Please enter a valid test card number.</p>
</div>
`;
}
document.getElementById('result-content').innerHTML = result;
}
// 3D Secure functions
function test3DSecure() {
const cardNumber = document.getElementById('3ds-card-number').value.replace(/\s/g, '');
if (cardNumber === '4000002500003155' || cardNumber === '4000002760003184') {
show3DSModal(cardNumber);
} else {
alert('Please enter a valid 3D Secure test card number.');
}
}
function show3DSModal(cardNumber) {
// Format card number for display
const formattedCard = cardNumber.replace(/(\d{4})/g, '$1 ').trim();
document.getElementById('3ds-card-display').textContent = formattedCard;
// Show modal
document.getElementById('3ds-modal').classList.remove('hidden');
}
function close3DSModal() {
document.getElementById('3ds-modal').classList.add('hidden');
}
function complete3DSAuth() {
close3DSModal();
// Show success result
document.getElementById('test-result').style.display = 'block';
document.getElementById('result-content').innerHTML = `
<div class="bg-green-50 border border-green-200 rounded p-4 mb-4">
<div class="flex items-center text-green-800 font-medium mb-2">
<i class="fas fa-check-circle mr-2"></i>
3D Secure Authentication Successful
</div>
<p class="text-green-700">The payment was authenticated and processed successfully.</p>
</div>
<div class="bg-neutral-light p-4 rounded">
<div class="grid grid-cols-2 gap-2">
<div class="text-neutral-dark">Transaction ID:</div>
<div class="font-medium">ch_1NjK9L2eZvKYlo2C0A2Uvl7g</div>
<div class="text-neutral-dark">Amount:</div>
<div class="font-medium">$100.00</div>
<div class="text-neutral-dark">Status:</div>
<div class="font-medium">Succeeded</div>
<div class="text-neutral-dark">Authentication:</div>
<div class="font-medium">3D Secure</div>
</div>
</div>
`;
}
// Rate limiting test
document.getElementById('test-rate-limit').addEventListener('click', function() {
const isEnabled = document.getElementById('rate-limit-toggle').checked;
if (isEnabled) {
let count = 0;
const interval = setInterval(() => {
count++;
if (count < 3) {
alert(`Request ${count} successful`);
} else {
clearInterval(interval);
alert('Rate limit exceeded. Too many requests in a short period.');
}
}, 500);
} else {
alert('Please enable rate limit simulation first.');
}
});
// Card search functionality
document.getElementById('card-search').addEventListener('input', function() {
const searchTerm = this.value.toLowerCase();
const cards = document.querySelectorAll('.test-card');
cards.forEach(card => {
const cardText = card.textContent.toLowerCase();
if (cardText.includes(searchTerm)) {
card.style.display = 'flex';
} else {
card.style.display = 'none';
}
});
});
// Initialize
document.addEventListener('DOMContentLoaded', function() {
// Start with card testing tab active
switchTab('card-testing');
});
</script>
</body>
</html>