on a school's own external website by * embed.js. It resolves the school from its public embed key, renders the * existing Web Payments widget, and auto-reports its height to the parent page * so the iframe can size itself with no scrollbars. * * Query params: * key (required) the school's public merchant_key (sqpk_…) * amount (required) major-units amount, e.g. 25.00 * currency (optional) ISO-4217, default the school's onboarding currency/CAD * email (optional) buyer email for the receipt * success (optional) URL to redirect to after a successful charge * * Because this is meant to be framed, it deliberately does NOT send * X-Frame-Options. When enforce_embed_origins is on and the school has * registered origins, we additionally restrict framing via CSP frame-ancestors. */ require_once __DIR__ . '/lib/SquareClient.php'; require_once __DIR__ . '/lib/MerchantStore.php'; $config = require __DIR__ . '/config.php'; $store = new MerchantStore($config); $key = isset($_GET['key']) ? trim((string)$_GET['key']) : ''; $amount = isset($_GET['amount']) && is_numeric($_GET['amount']) ? number_format((float)$_GET['amount'], 2, '.', '') : ''; $currency = isset($_GET['currency']) ? strtoupper(preg_replace('/[^A-Za-z]/', '', (string)$_GET['currency'])) : ''; $email = isset($_GET['email']) ? trim((string)$_GET['email']) : ''; $success = isset($_GET['success']) ? trim((string)$_GET['success']) : ''; if (!preg_match('#^(https?://|/)#i', $success)) { $success = ''; // only real web URLs (blocks javascript:/data: redirects) } $school = $store->findSchoolByKey($key); // Restrict who may frame us when origin enforcement is enabled. if (!empty($config['enforce_embed_origins']) && $school !== null) { $allowed = $store->allowedOrigins($school); if (!empty($allowed)) { header("Content-Security-Policy: frame-ancestors 'self' " . implode(' ', $allowed)); } } ?>