clavitor/clavitor.ai/admin/static/checkout.html

171 lines
7.2 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<title>Subscribe to Clavitor</title>
<script src="https://cdn.paddle.com/paddle/paddle.js"></script>
<style>
body { font-family: system-ui; max-width: 600px; margin: 50px auto; padding: 20px; }
.plan { border: 2px solid #ddd; padding: 20px; margin: 15px 0; border-radius: 8px; cursor: pointer; }
.plan:hover { border-color: #0066cc; }
.plan.selected { border-color: #0066cc; background: #f0f7ff; }
.plan h3 { margin: 0 0 10px 0; }
.price { font-size: 24px; font-weight: bold; color: #0066cc; }
button { width: 100%; padding: 15px; font-size: 18px; background: #0066cc; color: white; border: none; border-radius: 8px; cursor: pointer; }
button:disabled { background: #ccc; }
#error { color: red; margin: 15px 0; }
#success { color: green; margin: 15px 0; }
input { width: 100%; padding: 12px; font-size: 16px; margin: 10px 0; box-sizing: border-box; }
</style>
</head>
<body>
<h1>Choose Your Plan</h1>
<div id="plans">
<div class="plan" data-price-id="pri_01knejm7ft2ska5r4qff2gm9r4" onclick="selectPlan(this)">
<h3>Personal</h3>
<div class="price">$12/year</div>
<p>1 person, 1 vault, 5 agents</p>
</div>
<div class="plan" data-price-id="pri_01knejm7xs9kqt0vn61dx6q808" onclick="selectPlan(this)">
<h3>Family</h3>
<div class="price">$24/year</div>
<p>1 vault, 15 agents, ~6 people</p>
</div>
<div class="plan" data-price-id="pri_01knejm8djq4p63rmsxze7by58" onclick="selectPlan(this)">
<h3>Pro</h3>
<div class="price">$49/year</div>
<p>1 person, 1 vault, 50 agents</p>
</div>
<div class="plan" data-price-id="pri_01knejm8twprj5ca4zem1g4g56" onclick="selectPlan(this)">
<h3>Team 10</h3>
<div class="price">$249/year (annual only)</div>
<p>10 people, 11 vaults (10+1 company), 100 agents</p>
</div>
</div>
<div id="checkout-form" style="display:none;">
<h2>Complete Your Subscription</h2>
<input type="email" id="email" placeholder="Your email address" required>
<input type="text" id="vault-l0" placeholder="Vault ID (if you have one)" style="display:none;">
<div id="error"></div>
<div id="success"></div>
<button id="checkout-btn" onclick="openCheckout()">Subscribe Now</button>
</div>
<script>
// SANDBOX MODE - for local development
// Get your sandbox client token from: https://sandbox-vendors.paddle.com/authentication
// Create one at: Developer Tools > Authentication
const PADDLE_CLIENT_TOKEN = 'YOUR_SANDBOX_CLIENT_TOKEN_HERE';
let selectedPlan = null;
// Initialize Paddle.js in SANDBOX mode
if (PADDLE_CLIENT_TOKEN && PADDLE_CLIENT_TOKEN !== 'YOUR_SANDBOX_CLIENT_TOKEN_HERE') {
Paddle.Setup({
token: PADDLE_CLIENT_TOKEN,
environment: 'sandbox' // Use 'production' for live
});
console.log('Paddle.js initialized in SANDBOX mode');
} else {
console.error('Please set your Paddle SANDBOX client token');
document.getElementById('error').textContent =
'Developer: Set PADDLE_CLIENT_TOKEN in checkout.html (get from sandbox-vendors.paddle.com)';
}
function selectPlan(element) {
// Remove selected from all
document.querySelectorAll('.plan').forEach(p => p.classList.remove('selected'));
// Add to clicked
element.classList.add('selected');
selectedPlan = element.dataset.priceId;
// Show checkout form
document.getElementById('checkout-form').style.display = 'block';
document.getElementById('error').textContent = '';
}
async function openCheckout() {
const email = document.getElementById('email').value;
const errorDiv = document.getElementById('error');
const successDiv = document.getElementById('success');
const btn = document.getElementById('checkout-btn');
if (!email) {
errorDiv.textContent = 'Please enter your email';
return;
}
if (!selectedPlan) {
errorDiv.textContent = 'Please select a plan';
return;
}
btn.disabled = true;
btn.textContent = 'Opening checkout...';
try {
// Call our backend to create the checkout
const response = await fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
price_id: selectedPlan,
email: email,
vault_l0: document.getElementById('vault-l0').value || null
})
});
const result = await response.json();
if (!result.success) {
errorDiv.textContent = result.error || 'Failed to create checkout';
btn.disabled = false;
btn.textContent = 'Subscribe Now';
return;
}
// Option 1: Redirect to Paddle hosted checkout
// window.location.href = result.checkout_url;
// Option 2: Open Paddle.js inline checkout (better UX)
if (typeof Paddle !== 'undefined' && Paddle.Checkout) {
Paddle.Checkout.open({
transactionId: result.transaction_id,
successCallback: function(data) {
successDiv.textContent = 'Payment successful! Redirecting to your vault...';
// Redirect to vault
setTimeout(() => {
window.location.href = '/app/?subscription=active';
}, 2000);
},
closeCallback: function() {
btn.disabled = false;
btn.textContent = 'Subscribe Now';
}
});
} else {
// Fallback: redirect to hosted checkout
window.location.href = result.checkout_url;
}
} catch (err) {
errorDiv.textContent = 'Error: ' + err.message;
btn.disabled = false;
btn.textContent = 'Subscribe Now';
}
}
// Check for success parameter (returning from Paddle)
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('subscription') === 'active') {
document.getElementById('success').textContent =
'Your subscription is active! You can now use your vault.';
}
</script>
</body>
</html>