diff --git a/assets/css/custom.css b/assets/css/custom.css
new file mode 100644
index 0000000..4532c60
--- /dev/null
+++ b/assets/css/custom.css
@@ -0,0 +1,34 @@
+body {
+ background-color: #ECE5DD;
+ font-family: 'Helvetica', 'Arial', sans-serif;
+}
+
+.card {
+ border-radius: 0.75rem;
+ border: none;
+}
+
+.btn-primary {
+ background-color: #25D366;
+ border-color: #25D366;
+ background-image: linear-gradient(to right, #25D366, #128C7E);
+}
+
+.btn-primary:hover {
+ background-color: #128C7E;
+ border-color: #128C7E;
+ background-image: none;
+}
+
+.form-control:focus {
+ border-color: #25D366;
+ box-shadow: 0 0 0 0.25rem rgba(37, 211, 102, 0.25);
+}
+
+#status.online {
+ color: #25D366;
+}
+
+#status.offline {
+ color: #dc3545;
+}
diff --git a/assets/js/main.js b/assets/js/main.js
new file mode 100644
index 0000000..b54ab37
--- /dev/null
+++ b/assets/js/main.js
@@ -0,0 +1,63 @@
+document.addEventListener('DOMContentLoaded', function () {
+ const checkStatusForm = document.getElementById('checkStatusForm');
+ const submitButton = document.getElementById('submitButton');
+ const loadingDiv = document.getElementById('loading');
+ const resultDiv = document.getElementById('result');
+ const statusText = document.getElementById('statusText');
+ const lastSeen = document.getElementById('lastSeen');
+
+ if (checkStatusForm) {
+ checkStatusForm.addEventListener('submit', function (e) {
+ e.preventDefault();
+
+ // Hide previous result and show loading
+ resultDiv.style.display = 'none';
+ loadingDiv.style.display = 'block';
+ submitButton.disabled = true;
+ submitButton.innerHTML = ' Buscando...';
+
+ const isPremium = checkStatusForm.dataset.premium === 'true';
+
+ // Simulate a 3-second delay
+ setTimeout(() => {
+ let status = '';
+ let lastSeenText = '';
+ let statusColor = '';
+
+ if (isPremium) {
+ // Premium user experience
+ status = 'En Línea';
+ lastSeenText = 'escribiendo...';
+ statusColor = '#25D366'; // WhatsApp Green
+ } else {
+ // Standard user experience
+ const isOnline = Math.random() < 0.5;
+ status = isOnline ? 'En Línea' : 'Desconectado';
+ statusColor = isOnline ? '#25D366' : '#dc3545'; // Red for offline
+
+ if (isOnline) {
+ lastSeenText = 'últ. vez hoy a las ' + new Date().toLocaleTimeString('es-ES', { hour: '2-digit', minute: '2-digit' });
+ } else {
+ const hoursAgo = Math.floor(Math.random() * 23) + 1;
+ const minutesAgo = Math.floor(Math.random() * 59);
+ lastSeenText = `últ. vez hace ${hoursAgo}h ${minutesAgo}m`;
+ }
+ }
+
+ // Update status text and color
+ statusText.innerText = status;
+ statusText.style.color = statusColor;
+ lastSeen.innerText = lastSeenText;
+
+ // Hide loading and show result
+ loadingDiv.style.display = 'none';
+ resultDiv.style.display = 'block';
+
+ // Re-enable button
+ submitButton.disabled = false;
+ submitButton.innerHTML = 'Ver Estado';
+
+ }, 3000);
+ });
+ }
+});
\ No newline at end of file
diff --git a/assets/js/payment.js b/assets/js/payment.js
new file mode 100644
index 0000000..52b3c87
--- /dev/null
+++ b/assets/js/payment.js
@@ -0,0 +1,42 @@
+document.addEventListener('DOMContentLoaded', async () => {
+ const stripe = Stripe('pk_live_51SJvpVAgq1ywLQy0IPutpWNtY9AmGKijmeu0MgxOxsNQEXW1nsdrLuUS0o7aU2Cnki6OwkZ1YhV10nCVcBgRuWjO00jh0pFCLY');
+
+ const { clientSecret } = await fetch('create-payment-intent.php', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({})
+ }).then(r => r.json());
+
+ const elements = stripe.elements({ clientSecret });
+ const cardElement = elements.create('card');
+ cardElement.mount('#card-element');
+
+ const form = document.getElementById('payment-form');
+ const errorContainer = document.getElementById('card-errors');
+
+ form.addEventListener('submit', async (event) => {
+ event.preventDefault();
+
+ const { error } = await stripe.confirmPayment({
+ elements,
+ confirmParams: {
+ return_url: window.location.href.split('?')[0] + '?payment=success'
+ }
+ });
+
+ if (error) {
+ errorContainer.textContent = error.message;
+ } else {
+ errorContainer.textContent = '';
+ }
+ });
+
+ const urlParams = new URLSearchParams(window.location.search);
+ if (urlParams.get('payment') === 'success') {
+ document.getElementById('card-payment-form').classList.add('d-none');
+ document.getElementById('spei-info').classList.add('d-none');
+ document.getElementById('payment-success').classList.remove('d-none');
+ }
+});
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..dcf8a9e
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,5 @@
+{
+ "require": {
+ "stripe/stripe-php": "^1.8"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..28063ef
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,71 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "7ddc6309b099a518705cc62a6091e848",
+ "packages": [
+ {
+ "name": "stripe/stripe-php",
+ "version": "v1.18.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/stripe/stripe-php.git",
+ "reference": "022c3f21ec1e4141b46738bd5e7ab730d04f78cc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/stripe/stripe-php/zipball/022c3f21ec1e4141b46738bd5e7ab730d04f78cc",
+ "reference": "022c3f21ec1e4141b46738bd5e7ab730d04f78cc",
+ "shasum": ""
+ },
+ "require": {
+ "ext-curl": "*",
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "php": ">=5.2"
+ },
+ "require-dev": {
+ "simpletest/simpletest": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "lib/Stripe/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Stripe and contributors",
+ "homepage": "https://github.com/stripe/stripe-php/contributors"
+ }
+ ],
+ "description": "Stripe PHP Library",
+ "homepage": "https://stripe.com/",
+ "keywords": [
+ "api",
+ "payment processing",
+ "stripe"
+ ],
+ "support": {
+ "issues": "https://github.com/stripe/stripe-php/issues",
+ "source": "https://github.com/stripe/stripe-php/tree/v1.18.0"
+ },
+ "time": "2015-01-22T05:01:46+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": {},
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {},
+ "platform-dev": {},
+ "plugin-api-version": "2.6.0"
+}
diff --git a/composer.phar b/composer.phar
new file mode 100755
index 0000000..7f8a37d
Binary files /dev/null and b/composer.phar differ
diff --git a/create-payment-intent.php b/create-payment-intent.php
new file mode 100644
index 0000000..2ff8b32
--- /dev/null
+++ b/create-payment-intent.php
@@ -0,0 +1,46 @@
+ 'User not logged in']);
+ exit;
+}
+
+// It is not recommended to store the secret key directly in the code.
+// It should be stored in an environment variable or a secure configuration file.
+$stripeSecretKey = 'sk_live_51SJvpVAgq1ywLQy0jBRZsARLf9VGKH8LOW2l9GVHRXJ2KiG5dqYYRMFOw1DT';
+
+\Stripe\Stripe::setApiKey($stripeSecretKey);
+
+header('Content-Type: application/json');
+
+try {
+ $pdo = db();
+ $userId = $_SESSION['user_id'];
+
+ // Create a PaymentIntent with amount and currency
+ $paymentIntent = \Stripe\PaymentIntent::create([
+ 'amount' => 18000, // 180.00 MXN
+ 'currency' => 'mxn',
+ 'metadata' => [
+ 'user_id' => $userId
+ ]
+ ]);
+
+ // Save the payment intent to the database
+ $stmt = $pdo->prepare("INSERT INTO payments (user_id, stripe_payment_intent_id, amount, currency, status) VALUES (?, ?, ?, ?, ?)");
+ $stmt->execute([$userId, $paymentIntent->id, $paymentIntent->amount, $paymentIntent->currency, 'requires_payment_method']);
+
+ $output = [
+ 'clientSecret' => $paymentIntent->client_secret,
+ ];
+
+ echo json_encode($output);
+} catch (Exception $e) {
+ http_response_code(500);
+ echo json_encode(['error' => $e->getMessage()]);
+}
diff --git a/db/migrations/001_create_users_and_payments_tables.sql b/db/migrations/001_create_users_and_payments_tables.sql
new file mode 100644
index 0000000..955c793
--- /dev/null
+++ b/db/migrations/001_create_users_and_payments_tables.sql
@@ -0,0 +1,17 @@
+CREATE TABLE IF NOT EXISTS `users` (
+ `id` INT AUTO_INCREMENT PRIMARY KEY,
+ `email` VARCHAR(255) UNIQUE NOT NULL,
+ `is_premium` BOOLEAN NOT NULL DEFAULT FALSE,
+ `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
+
+CREATE TABLE IF NOT EXISTS `payments` (
+ `id` INT AUTO_INCREMENT PRIMARY KEY,
+ `user_id` INT,
+ `stripe_payment_intent_id` VARCHAR(255) UNIQUE NOT NULL,
+ `amount` INT NOT NULL,
+ `currency` VARCHAR(10) NOT NULL,
+ `status` VARCHAR(50) NOT NULL,
+ `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (user_id) REFERENCES users(id)
+);
diff --git a/includes/footer.php b/includes/footer.php
new file mode 100644
index 0000000..0fa24d1
--- /dev/null
+++ b/includes/footer.php
@@ -0,0 +1,3 @@
+
+