Files
old-riskletpy/backend/core/templates/payment.html
2025-10-20 19:52:11 +02:00

196 lines
6.8 KiB
HTML

{% extends 'base.html' %}
{% block content %}
<section class="py-24 bg-gradient-to-br from-teal-100 to-primary flex items-center justify-center">
<div class="max-w-md w-full mx-auto shadow-2xl border border-accent rounded-2xl p-4 bg-white/90 backdrop-blur">
<h2 class="text-3xl font-extrabold mb-6 text-accent text-center">Payment</h2>
<!-- Tabs -->
<div class="flex justify-center mb-6 border-b border-accent">
<button id="tab-demo" class="px-4 py-2 text-accent font-semibold border-b-2 border-accent">Demo Code</button>
<button id="tab-paddle" class="px-4 py-2 text-gray-500 hover:text-accent font-semibold">Paddle</button>
</div>
<!-- Demo Code Tab -->
<div id="demo-tab-content">
<p class="text-lg text-gray-700 mb-4">Enter your demo code to access the document:</p>
<form method="post" class="space-y-6">
{% csrf_token %}
<div class="relative flex items-center">
<input
type="text"
id="code-input"
name="code"
maxlength="10"
class="w-full px-4 py-3 border-2 border-accent rounded-lg focus:outline-none focus:ring-2 focus:ring-accent text-lg tracking-widest text-center font-mono mb-2"
placeholder="Enter your code"
required
autocomplete="off"
>
<span id="code-status" class="absolute right-3 top-1/2 -translate-y-1/2 text-2xl"></span>
</div>
<button
type="submit"
class="w-full bg-accent text-primary hover:bg-yellow-400 font-bold py-3 px-8 rounded-lg shadow-lg text-lg transition-all duration-200 ease-in-out transform hover:scale-105"
id="submit-btn"
disabled
>
Enter Code
</button>
<p id="code-error" class="mt-2 font-semibold text-lg"></p>
{% if error %}
<p id="backend-error" class="text-red-600 mt-2 font-semibold text-lg">{{ error }}</p>
{% endif %}
</form>
</div>
<!-- Paddle Tab -->
<div id="paddle-tab-content" class="hidden text-center">
<p class="text-lg text-gray-700 mb-4">Pay with Paddle to access the document:</p>
<button
id="paddle-button"
class="mt-4 bg-green-600 text-white font-bold py-3 px-8 rounded-lg shadow-lg text-lg transition-all duration-200 ease-in-out transform hover:scale-105"
data-client="{{ pdl_client }}"
data-price="{{ pdl_price }}"
>
Buy Now
</button>
</div>
</div>
</section>
<script>
document.addEventListener('DOMContentLoaded', function() {
const input = document.getElementById('code-input');
const status = document.getElementById('code-status');
const codeError = document.getElementById('code-error');
const backendError = document.getElementById('backend-error');
const submitBtn = document.getElementById('submit-btn');
function disableBtn() {
submitBtn.disabled = true;
submitBtn.classList.add('opacity-50', 'cursor-not-allowed');
}
function enableBtn() {
submitBtn.disabled = false;
submitBtn.classList.remove('opacity-50', 'cursor-not-allowed');
}
disableBtn();
input.addEventListener('input', function() {
status.innerHTML = '';
codeError.innerHTML = '';
if (backendError) backendError.style.display = 'none';
const code = input.value.trim();
if (code.length === 0) {
disableBtn();
return;
};
disableBtn();
status.innerHTML = `<svg class="animate-spin h-6 w-6 text-accent" xmlns="http://www.w3.org/2000/svg" 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-8v8z"></path>
</svg>`;
fetch("{% url 'core:validate_code' %}", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRFToken": "{{ csrf_token }}",
},
body: JSON.stringify({ code: code })
})
.then(response => response.json())
.then(data => {
status.innerHTML = '';
if (data.valid) {
codeError.innerHTML = '<span class="text-green-600">✅ Valid code</span>';
enableBtn();
} else {
codeError.innerHTML = '<span class="text-red-600">❌ Invalid code</span>';
disableBtn();
}
})
.catch(() => {
status.innerHTML = '';
codeError.innerHTML = '<span class="text-red-600">❌ Error checking code</span>';
disableBtn();
});
});
});
</script>
<script>
const demoTabBtn = document.getElementById('tab-demo');
const paddleTabBtn = document.getElementById('tab-paddle');
const demoContent = document.getElementById('demo-tab-content');
const paddleContent = document.getElementById('paddle-tab-content');
demoTabBtn.addEventListener('click', () => {
demoContent.classList.remove('hidden');
paddleContent.classList.add('hidden');
demoTabBtn.classList.add('border-b-2', 'border-accent', 'text-accent');
paddleTabBtn.classList.remove('border-b-2', 'border-accent', 'text-accent');
paddleTabBtn.classList.add('text-gray-500');
});
paddleTabBtn.addEventListener('click', () => {
paddleContent.classList.remove('hidden');
demoContent.classList.add('hidden');
paddleTabBtn.classList.add('border-b-2', 'border-accent', 'text-accent');
demoTabBtn.classList.remove('border-b-2', 'border-accent', 'text-accent');
demoTabBtn.classList.add('text-gray-500');
});
</script>
<script src="https://cdn.paddle.com/paddle/v2/paddle.js"></script>
<script>
const paddleBtn = document.getElementById('paddle-button');
const email = "{{ email|escapejs }}";
const client = paddleBtn.dataset.client;
const price = paddleBtn.dataset.price;
Paddle.Environment.set('sandbox');
Paddle.Initialize({
token: client,
eventCallback: function(event) {
if (event.name === 'checkout.completed') {
handlePaymentSuccess(event.data);
}
}
});
paddleBtn.addEventListener('click', function() {
Paddle.Checkout.open({
customer: { email: email },
items: [{ priceId: price, quantity: 1 }]
});
});
function handlePaymentSuccess(data) {
const payload = {
transaction_id: data.transaction_id,
customer_email: data.customer.email,
amount: data.totals.total,
currency: data.currency_code
};
fetch("{% url 'core:payment_page' %}", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': '{{ csrf_token }}',
},
body: JSON.stringify(payload)
})
.then(response => {
if (!response.ok) throw new Error('Network response was not ok');
return response.json();
})
.then(result => {
if (result.redirect_url) window.location.href = result.redirect_url;
})
.catch(error => console.error('Fetch error:', error));
}
</script>
{% endblock %}