JezK
Edit File: elements-create-intent.php
<?php ini_set('display_errors', 0); ini_set('log_errors', 1); error_reporting(E_ALL); /* -------------------- Session (for CSRF) -------------------- */ if (!session_id() && !headers_sent()) { ini_set('session.cookie_httponly', 1); if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') { ini_set('session.cookie_secure', 1); } ini_set('session.use_only_cookies', 1); ini_set('session.cookie_samesite', 'Strict'); session_start(); } /* -------------------- WordPress bootstrap -------------------- */ if (!defined('ABSPATH')) { define('ABSPATH', '/home/authentica.com/public_html/'); } require_once ABSPATH . 'wp-load.php'; // loads wp-config.php so STRIPE_* constants are available /* -------------------- Config (keys from wp-config.php) -------------------- */ /** * Pull STRIPE_SECRET_KEY from wp-config.php (at /home/authentica.com/public_html/wp-config.php). * If not present, fail fast to avoid charging with the wrong key. */ if (defined('STRIPE_SECRET_KEY') && STRIPE_SECRET_KEY) { $stripe_secret_key = STRIPE_SECRET_KEY; } else { // Fail explicitly if the key is missing http_response_code(500); header('Content-Type: application/json; charset=utf-8'); echo json_encode([ 'status' => 'error', 'error' => 'Stripe secret key missing. Please define STRIPE_SECRET_KEY in wp-config.php.' ]); exit; } $allowed_origins = ['https://authentica.com', 'https://www.authentica.com']; /* -------------------- CORS -------------------- */ $origin = $_SERVER['HTTP_ORIGIN'] ?? ''; if ($origin && in_array($origin, $allowed_origins, true)) { header("Access-Control-Allow-Origin: $origin"); } header('Vary: Origin'); header('Access-Control-Allow-Methods: POST, OPTIONS'); header('Access-Control-Allow-Headers: Content-Type'); if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; } /* -------------------- Helpers -------------------- */ function json_out($status, $payload = [], $code = 200) { http_response_code($code); header('Content-Type: application/json; charset=utf-8'); echo json_encode(array_merge(['status' => $status], $payload)); exit; } function sanitize_scalar($v) { return is_string($v) ? trim($v) : $v; } /* -------------------- Read JSON body -------------------- */ $raw = file_get_contents('php://input'); $data = json_decode($raw, true); if (!is_array($data)) { json_out('error', ['error' => 'Invalid JSON body'], 400); } /* -------------------- CSRF validation -------------------- */ if ( empty($data['csrf_token']) || empty($_SESSION['csrf_token']) || empty($_SESSION['csrf_token_hash']) || $data['csrf_token'] !== $_SESSION['csrf_token'] || $_SESSION['csrf_token_hash'] !== hash('sha256', $_SESSION['csrf_token'] . ($_SERVER['HTTP_USER_AGENT'] ?? '') . ($_SERVER['REMOTE_ADDR'] ?? '')) || (time() - (int)($_SESSION['csrf_token_time'] ?? 0) > 1800) ) { json_out('error', ['error' => 'Invalid or expired CSRF token'], 403); } /* -------------------- Validate inputs -------------------- */ /** * We do NOT accept lead_id (per your request). * We use the Step 1 email only. */ $amount_usd = 25; // final application fee $currency = 'usd'; $email = filter_var($data['email'] ?? '', FILTER_VALIDATE_EMAIL); $billing = $data['billing'] ?? []; // optional fields for AVS checks $billing_name = sanitize_scalar($billing['name'] ?? ''); $address = $billing['address'] ?? []; $addr_line1 = sanitize_scalar($address['line1'] ?? ''); $addr_line2 = sanitize_scalar($address['line2'] ?? ''); $addr_city = sanitize_scalar($address['city'] ?? ''); $addr_state = sanitize_scalar($address['state'] ?? ''); $addr_zip = sanitize_scalar($address['postal_code'] ?? ''); $addr_ctry = strtoupper(sanitize_scalar($address['country'] ?? '')); // ISO-2 if (!$email) { json_out('error', ['error' => 'Valid email is required'], 422); } /* -------------------- Load Stripe SDK -------------------- */ /** Using your confirmed on-disk SDK path */ require_once __DIR__ . '/../authentica-prgrm-r2r/stripe-lib/stripe-php-master/init.php'; \Stripe\Stripe::setApiKey($stripe_secret_key); \Stripe\Stripe::setAppInfo('authentica-elements', '1.0'); /* -------------------- Create PaymentIntent -------------------- */ /** * IMPORTANT: Do not pass payment_method_data on creation when using automatic_payment_methods. * We only create the PI with amount/currency/metadata/receipt_email and confirm on client. */ try { $intent_params = [ 'amount' => $amount_usd * 100, 'currency' => $currency, 'description' => 'Standard Program Application Fee', 'metadata' => [ 'payment_type' => 'Standard Program Application Fee', 'customer_email' => $email, ], 'receipt_email' => $email, 'automatic_payment_methods' => ['enabled' => true], // If you ever want to send billing details at creation time (optional), you can pass: // 'shipping' => [ // 'name' => $billing_name, // 'address' => [ // 'line1' => $addr_line1, // 'line2' => $addr_line2, // 'city' => $addr_city, // 'state' => $addr_state, // 'postal_code' => $addr_zip, // 'country' => $addr_ctry, // ], // ], ]; $intent = \Stripe\PaymentIntent::create($intent_params); json_out('ok', [ 'client_secret' => $intent->client_secret, 'intent_id' => $intent->id, 'amount' => $amount_usd, 'currency' => $currency, ], 200); } catch (\Stripe\Exception\ApiErrorException $e) { error_log('Stripe PI error: ' . $e->getMessage()); json_out('error', ['error' => 'Payment setup error', 'stripe_error' => $e->getMessage()], 500); } catch (\Throwable $t) { error_log('Stripe PI general error: ' . $t->getMessage()); json_out('error', ['error' => 'Server error'], 500); }