Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Payment API Tester</title> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| min-height: 100vh; | |
| padding: 20px; | |
| } | |
| .container { | |
| max-width: 900px; | |
| margin: 0 auto; | |
| background: white; | |
| border-radius: 12px; | |
| box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2); | |
| padding: 40px; | |
| } | |
| h1 { | |
| color: #333; | |
| margin-bottom: 10px; | |
| text-align: center; | |
| } | |
| .subtitle { | |
| text-align: center; | |
| color: #666; | |
| margin-bottom: 30px; | |
| } | |
| .form-group { | |
| margin-bottom: 20px; | |
| } | |
| label { | |
| display: block; | |
| margin-bottom: 8px; | |
| color: #333; | |
| font-weight: 600; | |
| } | |
| input[type="text"], | |
| input[type="number"] { | |
| width: 100%; | |
| padding: 12px; | |
| border: 2px solid #ddd; | |
| border-radius: 6px; | |
| font-size: 16px; | |
| transition: border-color 0.3s; | |
| } | |
| input[type="text"]:focus, | |
| input[type="number"]:focus { | |
| outline: none; | |
| border-color: #667eea; | |
| } | |
| .btn { | |
| width: 100%; | |
| padding: 14px; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| border: none; | |
| border-radius: 6px; | |
| font-size: 16px; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: transform 0.3s; | |
| } | |
| .btn:hover { | |
| transform: translateY(-2px); | |
| } | |
| .btn:disabled { | |
| opacity: 0.6; | |
| cursor: not-allowed; | |
| } | |
| .response-section { | |
| margin-top: 30px; | |
| display: none; | |
| } | |
| .response-section.show { | |
| display: block; | |
| } | |
| .response-box { | |
| background: #f8f9fa; | |
| border-radius: 8px; | |
| padding: 20px; | |
| margin-top: 15px; | |
| } | |
| .response-box h3 { | |
| margin-bottom: 15px; | |
| color: #333; | |
| } | |
| .response-box pre { | |
| background: #2d2d2d; | |
| color: #f8f8f2; | |
| padding: 15px; | |
| border-radius: 6px; | |
| overflow-x: auto; | |
| font-size: 14px; | |
| line-height: 1.5; | |
| } | |
| .status-badge { | |
| display: inline-block; | |
| padding: 6px 12px; | |
| border-radius: 4px; | |
| font-weight: 600; | |
| margin-bottom: 10px; | |
| } | |
| .status-success { | |
| background: #28a745; | |
| color: white; | |
| } | |
| .status-error { | |
| background: #dc3545; | |
| color: white; | |
| } | |
| .info-box { | |
| background: #e7f3ff; | |
| border-left: 4px solid #2196F3; | |
| padding: 15px; | |
| margin-bottom: 20px; | |
| border-radius: 4px; | |
| } | |
| .info-box p { | |
| margin: 5px 0; | |
| color: #333; | |
| } | |
| .checkbox-group { | |
| margin-bottom: 20px; | |
| } | |
| .checkbox-group label { | |
| display: flex; | |
| align-items: center; | |
| font-weight: normal; | |
| } | |
| .checkbox-group input[type="checkbox"] { | |
| margin-right: 10px; | |
| width: 18px; | |
| height: 18px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>Payment API Tester</h1> | |
| <p class="subtitle">Test the Payment Processing API endpoint</p> | |
| <div class="info-box"> | |
| <p><strong>API Endpoint:</strong> <code id="apiEndpoint"></code></p> | |
| <p><strong>Method:</strong> POST</p> | |
| <p><strong>Content-Type:</strong> application/json</p> | |
| </div> | |
| <form id="paymentForm"> | |
| <div class="form-group"> | |
| <label for="studentId">Student ID *</label> | |
| <input type="text" id="studentId" name="student_id" required placeholder="e.g., 000001234567890123"> | |
| </div> | |
| <div class="form-group"> | |
| <label for="tellerNo">Teller Number *</label> | |
| <input type="text" id="tellerNo" name="teller_no" required placeholder="e.g., 1234567890"> | |
| </div> | |
| <div class="form-group"> | |
| <label for="amount">Amount *</label> | |
| <input type="number" id="amount" name="amount" step="0.01" min="0.01" required | |
| placeholder="e.g., 50000"> | |
| </div> | |
| <div class="checkbox-group"> | |
| <label> | |
| <input type="checkbox" id="useAuth" name="use_auth"> | |
| Use API Key Authentication | |
| </label> | |
| </div> | |
| <div class="form-group" id="apiKeyGroup" style="display: none;"> | |
| <label for="apiKey">API Key</label> | |
| <input type="text" id="apiKey" name="api_key" placeholder="Enter your API key"> | |
| </div> | |
| <button type="submit" class="btn" id="submitBtn">Send Request</button> | |
| </form> | |
| <div class="response-section" id="responseSection"> | |
| <div class="response-box"> | |
| <h3>Response</h3> | |
| <div id="statusBadge"></div> | |
| <pre id="responseBody"></pre> | |
| </div> | |
| <div class="response-box"> | |
| <h3>Request Details</h3> | |
| <pre id="requestDetails"></pre> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Set API endpoint | |
| const apiEndpoint = window.location.origin + '/easypay/api/payments/process'; | |
| document.getElementById('apiEndpoint').textContent = apiEndpoint; | |
| // Toggle API key field | |
| document.getElementById('useAuth').addEventListener('change', function () { | |
| document.getElementById('apiKeyGroup').style.display = this.checked ? 'block' : 'none'; | |
| }); | |
| // Handle form submission | |
| document.getElementById('paymentForm').addEventListener('submit', async function (e) { | |
| e.preventDefault(); | |
| const submitBtn = document.getElementById('submitBtn'); | |
| submitBtn.disabled = true; | |
| submitBtn.textContent = 'Sending...'; | |
| // Prepare request data | |
| const requestData = { | |
| student_id: document.getElementById('studentId').value, | |
| teller_no: document.getElementById('tellerNo').value, | |
| amount: parseFloat(document.getElementById('amount').value) | |
| }; | |
| // Prepare headers | |
| const headers = { | |
| 'Content-Type': 'application/json' | |
| }; | |
| if (document.getElementById('useAuth').checked) { | |
| const apiKey = document.getElementById('apiKey').value; | |
| if (apiKey) { | |
| headers['Authorization'] = 'Bearer ' + apiKey; | |
| } | |
| } | |
| try { | |
| // Send request | |
| const response = await fetch(apiEndpoint, { | |
| method: 'POST', | |
| headers: headers, | |
| body: JSON.stringify(requestData) | |
| }); | |
| const responseData = await response.json(); | |
| // Display response | |
| displayResponse(response.status, responseData, requestData, headers); | |
| } catch (error) { | |
| displayError(error.message, requestData, headers); | |
| } finally { | |
| submitBtn.disabled = false; | |
| submitBtn.textContent = 'Send Request'; | |
| } | |
| }); | |
| function displayResponse(status, data, request, headers) { | |
| const responseSection = document.getElementById('responseSection'); | |
| const statusBadge = document.getElementById('statusBadge'); | |
| const responseBody = document.getElementById('responseBody'); | |
| const requestDetails = document.getElementById('requestDetails'); | |
| // Show response section | |
| responseSection.classList.add('show'); | |
| // Set status badge | |
| const isSuccess = status >= 200 && status < 300; | |
| statusBadge.className = 'status-badge ' + (isSuccess ? 'status-success' : 'status-error'); | |
| statusBadge.textContent = 'HTTP ' + status + ' - ' + (isSuccess ? 'Success' : 'Error'); | |
| // Display response body | |
| responseBody.textContent = JSON.stringify(data, null, 2); | |
| // Display request details | |
| const requestInfo = { | |
| url: apiEndpoint, | |
| method: 'POST', | |
| headers: headers, | |
| body: request | |
| }; | |
| requestDetails.textContent = JSON.stringify(requestInfo, null, 2); | |
| // Scroll to response | |
| responseSection.scrollIntoView({ behavior: 'smooth' }); | |
| } | |
| function displayError(message, request, headers) { | |
| const responseSection = document.getElementById('responseSection'); | |
| const statusBadge = document.getElementById('statusBadge'); | |
| const responseBody = document.getElementById('responseBody'); | |
| const requestDetails = document.getElementById('requestDetails'); | |
| // Show response section | |
| responseSection.classList.add('show'); | |
| // Set status badge | |
| statusBadge.className = 'status-badge status-error'; | |
| statusBadge.textContent = 'Request Failed'; | |
| // Display error | |
| responseBody.textContent = JSON.stringify({ | |
| error: message | |
| }, null, 2); | |
| // Display request details | |
| const requestInfo = { | |
| url: apiEndpoint, | |
| method: 'POST', | |
| headers: headers, | |
| body: request | |
| }; | |
| requestDetails.textContent = JSON.stringify(requestInfo, null, 2); | |
| // Scroll to response | |
| responseSection.scrollIntoView({ behavior: 'smooth' }); | |
| } | |
| </script> | |
| </body> | |
| </html> |