Файловый менеджер - Редактировать - /home/gqdcvggs/vertchasseur.com/payment.php
Назад
<?php session_start(); include 'db.php'; require_once 'vendor/autoload.php'; if (!isset($_SESSION['resident_id'])) { header('Location: login.php'); exit; } if (!isset($_GET['plan']) || !in_array($_GET['plan'], ['member', 'premium'])) { header('Location: resident-dashboard.php'); exit; } $plan = $_GET['plan']; $resident_id = $_SESSION['resident_id']; $stmt = $conn->prepare("SELECT * FROM residents WHERE id = ?"); $stmt->bind_param("i", $resident_id); $stmt->execute(); $resident = $stmt->get_result()->fetch_assoc(); if (($plan === 'member' && $resident['member_'] == 1) || ($plan === 'premium' && $resident['premium_'] == 1)) { header('Location: resident-dashboard.php?error=already_subscribed'); exit; } $plan_info = [ 'member' => [ 'title' => 'Membre Vert Chasseur', 'price' => '1,99€', 'features' => [ 'Carte membre Vert Chasseur', '10% de réduction chez les partenaires', 'Avantages du quartier' ] ], 'premium' => [ 'title' => 'Membre Vert+ Chasseur', 'price' => '9,99€', 'features' => [ 'Tout de l\'abonnement membre', 'Magazine trimestriel du quartier', 'Accès au service privé de livraison', ] ] ]; $current_plan = $plan_info[$plan]; ?> <!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Abonnement <?= $current_plan['title'] ?> - Vert Chasseur</title> <link rel="icon" type="image/png" href="logo_new.png"> <script src="https://cdn.tailwindcss.com"></script> <script src="https://js.stripe.com/v3/"></script> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet"> <style> body { font-family: 'Poppins', sans-serif; } .payment-form { background: white; border-radius: 16px; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); border: 1px solid #f3f4f6; } .feature-check { width: 20px; height: 20px; background: #16a34a; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; } #card-element { padding: 16px; border: 2px solid #e5e7eb; border-radius: 12px; background: #fafafa; transition: border-color 0.2s ease; } #card-element:focus-within { border-color: #16a34a; background: white; } .payment-button { background: linear-gradient(135deg, #16a34a 0%, #15803d 100%); border: none; border-radius: 12px; color: white; font-weight: 600; padding: 16px; width: 100%; font-size: 16px; cursor: pointer; transition: all 0.2s ease; margin-bottom: 12px; } .payment-button:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); } .payment-button:disabled { opacity: 0.6; cursor: not-allowed; } .app-store-button { background: linear-gradient(135deg, #007AFF 0%, #0051D5 100%); border: none; border-radius: 12px; color: white; font-weight: 600; padding: 20px; width: 100%; font-size: 16px; cursor: pointer; transition: all 0.2s ease; margin-bottom: 12px; display: flex; align-items: center; justify-content: center; gap: 12px; } .app-store-button:hover { background: linear-gradient(135deg, #0051D5 0%, #003D9F 100%); transform: translateY(-1px); box-shadow: 0 15px 25px -5px rgba(0, 122, 255, 0.3); } .security-badge { display: flex; align-items: center; gap: 8px; padding: 12px 16px; background: #f0fdf4; border: 1px solid #bbf7d0; border-radius: 8px; font-size: 14px; color: #166534; margin-top: 16px; } .ios-security-badge { display: flex; align-items: center; gap: 8px; padding: 12px 16px; background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 8px; font-size: 14px; color: #1e40af; margin-top: 16px; } .back-button { display: inline-flex; align-items: center; gap: 8px; color: #6b7280; text-decoration: none; font-size: 14px; margin-bottom: 24px; transition: color 0.2s ease; } .back-button:hover { color: #374151; } .ios-payment-form { background: white; border-radius: 16px; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); border: 1px solid #f3f4f6; padding: 32px; } .app-store-icon { width: 28px; height: 28px; fill: white; } .hidden { display: none !important; } .ios-steps { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 12px; padding: 20px; margin: 20px 0; } .step-item { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; font-size: 14px; color: #475569; } .step-item:last-child { margin-bottom: 0; } .step-number { background: #007AFF; color: white; width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600; flex-shrink: 0; } </style> </head> <body class="bg-gradient-to-br from-white to-emerald-50 min-h-screen py-8 px-4"> <div class="max-w-4xl mx-auto"> <a href="resident-dashboard.php" class="back-button"> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/> </svg> Annuler l'opération </a> <div class="grid lg:grid-cols-2 gap-8"> <div class="space-y-6"> <div> <h1 class="text-3xl font-bold text-gray-900 mb-4"> <?= $current_plan['title'] ?> </h1> <div class="text-4xl font-bold text-green-600 mb-2"> <?= $current_plan['price'] ?><span class="text-lg font-normal text-gray-600">/mois</span> </div> <p class="text-gray-600">Abonnement sans engagement, résiliable à tout moment</p> </div> <div class="bg-white rounded-2xl p-6 border border-gray-200"> <h3 class="text-lg font-semibold text-gray-900 mb-4">Ce qui est inclus :</h3> <div class="space-y-3"> <?php foreach ($current_plan['features'] as $feature): ?> <div class="flex items-center gap-3"> <div class="feature-check"> <svg class="w-3 h-3 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"/> </svg> </div> <span class="text-gray-700"><?= $feature ?></span> </div> <?php endforeach; ?> </div> </div> <div class="bg-blue-50 border border-blue-200 rounded-xl p-4"> <div class="flex items-start gap-3"> <svg class="w-5 h-5 text-blue-600 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/> </svg> <div> <h4 class="font-medium text-blue-900 mb-1">Information importante</h4> <p class="text-sm text-blue-800"> Tu peux annuler ton abonnement à tout moment depuis tes paramètres. L'abonnement reste actif jusqu'à la fin de la période payée. </p> </div> </div> </div> </div> <div id="ios-payment" class="ios-payment-form hidden"> <h2 class="text-xl font-semibold text-gray-900 mb-6">Abonnement via App Store</h2> <div class="text-center mb-6"> <p class="text-gray-600 mb-4">Pour respecter les règles Apple, l'abonnement se fait directement via l'App Store</p> </div> <div class="ios-steps"> <h3 class="text-sm font-semibold text-gray-900 mb-3">Comment ça marche :</h3> <div class="step-item"> <div class="step-number">1</div> <span>Tu vas être redirigé vers l'App Store</span> </div> <div class="step-item"> <div class="step-number">2</div> <span>Choisis ton abonnement et confirme avec Face ID/Touch ID</span> </div> <div class="step-item"> <div class="step-number">3</div> <span>Reviens dans l'app, ton abonnement sera automatiquement activé</span> </div> </div> <button id="app-store-button" class="app-store-button"> <svg class="app-store-icon" viewBox="0 0 24 24"> <path d="M18.71 19.5C17.88 20.74 17 21.95 15.66 21.97C14.32 21.99 13.89 21.18 12.37 21.18C10.84 21.18 10.37 21.95 9.1 21.99C7.79 22.03 6.8 20.68 5.96 19.47C4.25 17 2.94 12.45 4.7 9.39C5.57 7.87 7.13 6.91 8.82 6.88C10.1 6.86 11.32 7.75 12.11 7.75C12.89 7.75 14.37 6.68 15.92 6.84C16.57 6.87 18.39 7.1 19.56 8.82C19.47 8.88 17.39 10.19 17.41 12.63C17.44 15.65 20.06 16.66 20.09 16.67C20.06 16.74 19.67 18.11 18.71 19.5ZM13 3.5C13.73 2.67 14.94 2.04 15.94 2C16.07 3.17 15.6 4.35 14.9 5.19C14.21 6.04 13.07 6.7 11.95 6.61C11.8 5.46 12.36 4.26 13 3.5Z"/> </svg> <span>Continuer sur l'App Store</span> </button> <div class="ios-security-badge"> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/> </svg> <span>Paiement 100% sécurisé par Apple • Géré par l'App Store</span> </div> <p class="text-xs text-gray-500 mt-4 text-center"> En continuant, tu acceptes nos conditions d'utilisation. Ton abonnement sera géré par Apple et facturable sur ton compte Apple ID. </p> </div> <div id="web-payment" class="payment-form p-8"> <h2 class="text-xl font-semibold text-gray-900 mb-6">Informations de paiement</h2> <form id="payment-form"> <div class="mb-6"> <label class="block text-sm font-medium text-gray-700 mb-3"> Informations de la carte </label> <div id="card-element"></div> <div id="card-errors" class="text-red-600 text-sm mt-2 hidden"></div> </div> <div class="mb-6"> <div class="flex items-center gap-3 p-4 bg-gray-50 rounded-lg"> <svg class="w-8 h-6" viewBox="0 0 40 24" fill="none"> <rect width="40" height="24" rx="4" fill="#1A1F71"/> <text x="20" y="15" text-anchor="middle" fill="white" font-size="8" font-weight="bold">VISA</text> </svg> <svg class="w-8 h-6" viewBox="0 0 40 24" fill="none"> <rect width="40" height="24" rx="4" fill="#EB001B"/> <circle cx="15" cy="12" r="7" fill="#FF5F00"/> <circle cx="25" cy="12" r="7" fill="#F79E1B"/> </svg> <svg class="w-8 h-6" viewBox="0 0 40 24" fill="none"> <rect width="40" height="24" rx="4" fill="#006FCF"/> <text x="20" y="15" text-anchor="middle" fill="white" font-size="6" font-weight="bold">AMEX</text> </svg> <span class="text-xs text-gray-600 ml-auto">Cartes acceptées</span> </div> </div> <button type="submit" id="submit-button" class="payment-button"> <span id="button-text">Confirmer l'abonnement • <?= $current_plan['price'] ?></span> <span id="spinner" class="hidden"> <svg class="animate-spin h-5 w-5 mx-auto" fill="none" viewBox="0 0 24 24"> <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle> <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> </svg> </span> </button> </form> <div class="security-badge"> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/> </svg> <span>Paiement sécurisé par Stripe • Vos données sont protégées</span> </div> <p class="text-xs text-gray-500 mt-4 text-center"> En confirmant votre abonnement, vous acceptez nos conditions d'utilisation. Vous recevrez un email de confirmation après le paiement. Le payement est opérer par Stripe au nom de Imators, une société aktascorp </p> </div> </div> </div> <script> let stripe; let elements; let cardElement; let isIOS = false; function detectPlatform() { const userAgent = navigator.userAgent; const isMedianApp = userAgent.includes('median'); const isIOSDevice = /iPad|iPhone|iPod/.test(userAgent) && !window.MSStream; isIOS = isMedianApp && isIOSDevice; if (isIOS) { document.getElementById('ios-payment').classList.remove('hidden'); document.getElementById('web-payment').classList.add('hidden'); setupAppStoreHandler(); } else { document.getElementById('web-payment').classList.remove('hidden'); document.getElementById('ios-payment').classList.add('hidden'); initializeStripe(); } } function setupAppStoreHandler() { const appStoreButton = document.getElementById('app-store-button'); appStoreButton.addEventListener('click', function() { appStoreButton.disabled = true; appStoreButton.innerHTML = ` <svg class="animate-spin h-5 w-5 mx-auto" fill="none" viewBox="0 0 24 24"> <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle> <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> </svg> <span>Redirection vers l'App Store...</span> `; setTimeout(() => { window.location.href = 'https://apps.apple.com/app/id6749919223'; }, 1500); }); } function initializeStripe() { try { stripe = Stripe('pk_live_51LmhGsHQanXHoJn0qgKjMAisGwy6TzfZyUnzSq2Yc9qDmAQv8Syu9wuFDZVjgpg8kWUxm9bQ8MMi8E3WwNayGXus00Oe5tyNIP'); elements = stripe.elements(); cardElement = elements.create('card', { style: { base: { fontSize: '16px', color: '#424770', '::placeholder': { color: '#aab7c4', }, }, invalid: { color: '#9e2146', }, }, }); cardElement.mount('#card-element'); cardElement.on('change', function(event) { const displayError = document.getElementById('card-errors'); if (event.error) { displayError.textContent = event.error.message; displayError.classList.remove('hidden'); } else { displayError.textContent = ''; displayError.classList.add('hidden'); } }); setupFormHandler(); } catch (error) { console.error('Erreur initialisation Stripe:', error); setTimeout(initializeStripe, 1000); } } function setupFormHandler() { const form = document.getElementById('payment-form'); form.addEventListener('submit', async function(event) { event.preventDefault(); const submitButton = document.getElementById('submit-button'); const buttonText = document.getElementById('button-text'); const spinner = document.getElementById('spinner'); submitButton.disabled = true; buttonText.classList.add('hidden'); spinner.classList.remove('hidden'); try { const response = await fetch('create-payment-subscription.php', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ plan: '<?= $plan ?>' }) }); const data = await response.json(); if (data.error) { throw new Error(data.error); } const {error, paymentIntent} = await stripe.confirmCardPayment( data.client_secret, { payment_method: { card: cardElement, billing_details: { name: '<?= htmlspecialchars($resident['first_name'] . ' ' . $resident['last_name']) ?>', email: '<?= htmlspecialchars($resident['email']) ?>', }, } } ); if (error) { throw new Error(error.message); } else { const confirmResponse = await fetch('confirm-payment-subscription.php', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ subscription_id: data.subscription_id }) }); const confirmResult = await confirmResponse.json(); if (confirmResult.success) { window.location.href = 'payment-success.php?plan=<?= $plan ?>'; } else { throw new Error(confirmResult.error); } } } catch (error) { const displayError = document.getElementById('card-errors'); displayError.textContent = error.message; displayError.classList.remove('hidden'); submitButton.disabled = false; buttonText.classList.remove('hidden'); spinner.classList.add('hidden'); } }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', detectPlatform); } else { detectPlatform(); } </script> </body> </html>
| ver. 1.6 |
Github
|
.
| PHP 8.1.33 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка