Changeset 3337863
- Timestamp:
- 08/01/2025 02:19:22 PM (8 months ago)
- Location:
- lapinopay/trunk
- Files:
-
- 2 edited
-
checkout.html (modified) (4 diffs)
-
lapinopay.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
lapinopay/trunk/checkout.html
r3324348 r3337863 13 13 body { 14 14 overflow: hidden; 15 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; 15 16 } 16 17 #lapinopay-checkout { … … 22 23 border: none; 23 24 } 25 .error-message { 26 display: flex; 27 align-items: center; 28 justify-content: center; 29 height: 100vh; 30 background: #f8f9fa; 31 color: #dc3545; 32 font-size: 16px; 33 text-align: center; 34 padding: 20px; 35 } 36 .loading { 37 display: flex; 38 align-items: center; 39 justify-content: center; 40 height: 100vh; 41 background: #f8f9fa; 42 color: #6c757d; 43 font-size: 16px; 44 } 45 .spinner { 46 border: 2px solid #f3f3f3; 47 border-top: 2px solid #007cba; 48 border-radius: 50%; 49 width: 20px; 50 height: 20px; 51 animation: spin 1s linear infinite; 52 margin-right: 10px; 53 } 54 @keyframes spin { 55 0% { transform: rotate(0deg); } 56 100% { transform: rotate(360deg); } 57 } 24 58 </style> 25 59 </head> 26 60 <body> 27 <iframe id="lapinopay-checkout" allow="camera; microphone"></iframe> 61 <div id="loading" class="loading"> 62 <div class="spinner"></div> 63 Loading checkout... 64 </div> 65 <iframe id="lapinopay-checkout" allow="camera; microphone; payment"></iframe> 28 66 29 67 <script> … … 31 69 let lastUrl = window.location.href; 32 70 const iframe = document.getElementById("lapinopay-checkout"); 71 const loading = document.getElementById("loading"); 33 72 const STORAGE_KEY = "lapinopay_checkout_hash"; 34 73 const EXPIRATION_TIME = 10 * 60 * 1000; // 10 minutes in milliseconds 35 74 36 // Get the full URL from the hash 75 // Allowed domains for security 76 const ALLOWED_DOMAINS = [ 77 'localhost', 78 '127.0.0.1', 79 'lapinopay.com', 80 'www.lapinopay.com', 81 'api.lapinopay.com' 82 ]; 83 84 function showError(message) { 85 document.body.innerHTML = `<div class="error-message">${message}</div>`; 86 } 87 88 function showLoading() { 89 loading.style.display = 'flex'; 90 iframe.style.display = 'none'; 91 } 92 93 function hideLoading() { 94 loading.style.display = 'none'; 95 iframe.style.display = 'block'; 96 } 97 98 function isValidUrl(url) { 99 try { 100 const urlObj = new URL(url); 101 return ALLOWED_DOMAINS.some(domain => 102 urlObj.hostname === domain || urlObj.hostname.endsWith('.' + domain) 103 ); 104 } catch (e) { 105 return false; 106 } 107 } 108 109 function processUrl(url) { 110 if (!url) { 111 showError('No checkout URL provided'); 112 return false; 113 } 114 115 try { 116 const decodedUrl = decodeURIComponent(url); 117 118 if (!isValidUrl(decodedUrl)) { 119 showError('Invalid checkout URL: Domain not allowed'); 120 return false; 121 } 122 123 iframe.src = decodedUrl; 124 hideLoading(); 125 return true; 126 } catch (e) { 127 console.error("Error processing URL:", e); 128 showError('Error: Invalid checkout URL format'); 129 return false; 130 } 131 } 132 37 133 let fullUrl = window.location.hash.substring(1); 38 134 39 // Check if we have the lapinopay_checkout parameter in the URL40 135 const urlParams = new URLSearchParams(window.location.search); 41 136 const hasCheckoutParam = urlParams.has('lapinopay_checkout'); 42 137 43 138 if (fullUrl || hasCheckoutParam) { 44 try { 45 const decodedUrl = decodeURIComponent(fullUrl); 46 iframe.src = decodedUrl; 47 } catch (e) { 48 console.error("Error processing URL:", e); 49 document.body.innerHTML = "<p>Error: Invalid checkout URL</p>"; 50 } 139 processUrl(fullUrl); 51 140 } else { 52 console.error("No URL provided in hash ");53 document.body.innerHTML = "<p>Error: No checkout URL provided</p>";141 console.error("No URL provided in hash or query params"); 142 showError('Error: No checkout URL provided'); 54 143 } 144 145 // Handle iframe load events 146 iframe.addEventListener('load', () => { 147 hideLoading(); 148 }); 149 150 iframe.addEventListener('error', () => { 151 showError('Error: Failed to load checkout page'); 152 }); 55 153 56 154 const checkUrlChange = () => { … … 62 160 63 161 if (newFullUrl && hasCheckoutParam) { 64 try { 65 const decodedUrl = decodeURIComponent(newFullUrl); 66 if (decodedUrl.includes("localhost") || decodedUrl.includes("lapinopay.com")) { 67 iframe.src = decodedUrl; 68 lastUrl = currentUrl; 69 window.history.replaceState(null, "", window.location.pathname); 70 } 71 } catch (e) { 72 console.error("Error processing new URL:", e); 73 } 162 showLoading(); 163 processUrl(newFullUrl); 164 lastUrl = currentUrl; 165 window.history.replaceState(null, "", window.location.pathname); 74 166 } 75 167 } 76 168 }; 77 169 170 // Check for URL changes every second 78 171 setInterval(checkUrlChange, 1000); 172 173 // Handle iframe messages for communication with parent 174 window.addEventListener('message', (event) => { 175 // Validate message origin for security 176 if (!isValidUrl(event.origin)) { 177 console.warn('Message from unauthorized origin:', event.origin); 178 return; 179 } 180 181 182 // Handle different message types 183 if (event.data && event.data.type) { 184 switch (event.data.type) { 185 case 'checkout_complete': 186 break; 187 case 'checkout_error': 188 break; 189 case 'checkout_cancelled': 190 break; 191 } 192 } 193 }); 79 194 }); 80 195 </script> -
lapinopay/trunk/lapinopay.php
r3324348 r3337863 187 187 188 188 if (file_exists($file)) { 189 // Initialize WP_Filesystem 190 global $wp_filesystem; 191 if (!function_exists('WP_Filesystem')) { 192 require_once(ABSPATH . 'wp-admin/includes/file.php'); 189 // Clear any output buffers 190 while (ob_get_level()) { 191 ob_end_clean(); 193 192 } 194 193 195 if (!WP_Filesystem()) {196 wp_die('Failed to initialize filesystem.');197 }198 199 194 // Set proper headers 200 195 header('Content-Type: text/html; charset=UTF-8'); 201 196 header('X-Content-Type-Options: nosniff'); 197 header('Cache-Control: no-cache, no-store, must-revalidate'); 198 header('Pragma: no-cache'); 199 header('Expires: 0'); 202 200 203 // Use WP_Filesystem to read and output the file 204 echo wp_kses_post($wp_filesystem->get_contents($file)); 201 // Disable WordPress filters that might interfere 202 remove_all_filters('the_content'); 203 remove_all_filters('the_title'); 204 205 // Read and output the file directly 206 $content = file_get_contents($file); 207 if ($content !== false) { 208 echo $content; 209 } else { 210 wp_die('Failed to read checkout page.'); 211 } 205 212 exit; 206 213 } else {
Note: See TracChangeset
for help on using the changeset viewer.