'workspace-plan'])); if (!self::valid_billing_url($status['billingUrl'] ?? null) || !is_string($status['planName'] ?? null) || !is_array($status['messages'] ?? null)) { throw new RuntimeException(esc_html__('Invalid billing status.', 'refref')); } $billing = $status['billingUrl']; echo '
' . esc_html__('RefRef plan: ', 'refref') . '' . esc_html($status['planName']) . '
'; foreach ($status['messages'] as $message) { if (is_string($message)) { echo '' . esc_html($message) . '
' . esc_html__('Current plan status is unavailable. Open RefRef Billing to check your plan and limits.', 'refref') . '
'; } if (self::valid_billing_url($billing)) { echo '' . esc_html__('Open RefRef Billing', 'refref') . '
'; } echo '' . esc_html__('Manage your Workspace plan and payments in RefRef Console. Connecting a store does not change your subscription.', 'refref') . '
'; } public static function mode(): string { return wp_get_environment_type() === 'production' ? 'live' : 'test'; } public static function identity(): array { $identity = get_option('refref_identity'); if (!$identity) { add_option('refref_identity', ['id' => wp_generate_uuid4(), 'url' => untrailingslashit(home_url()), 'mode' => self::mode()], '', false); $identity = get_option('refref_identity'); } return $identity; } public static function valid_site(): bool { $identity = self::identity(); return $identity['url'] === untrailingslashit(home_url()) && $identity['mode'] === self::mode(); } public static function connection(): array { if (!self::valid_site()) { return []; } return get_option('refref_connection', []); } public static function register(): void { add_action('admin_menu', static function () { add_submenu_page('woocommerce', 'RefRef', 'RefRef', 'manage_woocommerce', 'refref', [self::class, 'page']); }); add_action('admin_post_refref_sandbox', [self::class, 'sandbox']); add_action('admin_post_refref_connect', [self::class, 'connect']); } public static function sandbox(): void { if (!current_user_can('manage_woocommerce')) { wp_die(esc_html__('Store management permission is required.', 'refref'), '', ['response' => 403]); } check_admin_referer('refref_sandbox'); if (self::mode() !== 'test' || self::valid_site()) { wp_die(esc_html__('Only a changed Sandbox copy can create an independent identity.', 'refref')); } foreach (['refref_identity', 'refref_secret', 'refref_connection', 'refref_pair', 'refref_sync_status'] as $key) { delete_option($key); } self::identity(); wp_safe_redirect(admin_url('admin.php?page=refref')); exit; } public static function connect(): void { if (!current_user_can('manage_woocommerce')) { wp_die(esc_html__('Store management permission is required.', 'refref'), '', ['response' => 403]); } check_admin_referer('refref_connect'); if (!self::valid_site() || !is_ssl()) { wp_die(esc_html__('Confirm the store environment and HTTPS before connecting.', 'refref')); } $token = bin2hex(random_bytes(32)); update_option('refref_pair', ['hash' => hash('sha256', $token), 'expires' => time() + 600], false); if (!get_option('refref_secret')) { add_option('refref_secret', bin2hex(random_bytes(32)), '', false); } $fragment = http_build_query(['provider' => 'woocommerce', 'url' => untrailingslashit(home_url()), 'token' => $token]); // External redirect is intentional: this trusted server-side URL opens Console approval. // phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect -- Destination is not supplied by the request. wp_redirect(self::console_url() . '/connect#' . $fragment, 302, 'RefRef'); exit; } public static function page(): void { if (!current_user_can('manage_woocommerce')) { return; } $connection = self::connection(); echo '' . esc_html__('Connect your store, then configure and publish your referral Program in RefRef.', 'refref') . '
'; echo '' . esc_html__('Environment: ', 'refref') . '' . esc_html(self::mode() === 'test' ? __('Sandbox', 'refref') : __('Live', 'refref')) . '
'; if (!self::valid_site()) { echo '' . esc_html__('This copy has a different store URL or environment. It cannot use the original connection. Create a separate Sandbox installation before reconnecting.', 'refref') . '
' . esc_html__('Connection: ', 'refref') . esc_html(empty($connection['id']) ? __('Not connected', 'refref') : __('Connected', 'refref')) . '
'; echo '' . esc_html__('Order sync: ', 'refref') . esc_html(get_option('refref_sync_status', __('No orders sent yet', 'refref'))) . '
'; if (!empty($connection['id'])) { self::billing($connection); } echo '' . esc_html__('Reward delivery is managed in RefRef. A connection alone does not mean Rewards have been delivered.', 'refref') . '
'; echo ''; $console = $connection['consoleUrl'] ?? self::console_url(); echo ''; } }