is_compatible() ) { new Database_Updater(); // register hooks $this->register_hooks(); } } public function is_compatible() { if ( !function_exists( 'is_plugin_active' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } if ( !is_plugin_active( 'contact-form-7/wp-contact-form-7.php' ) ) { add_action( 'admin_notices', [$this, 'admin_notice_missing_main_plugin'] ); return false; } return true; } /** * Admin notice * * Warning when the site doesn't have Elementor installed or activated. * * @since 1.0.0 * @access public */ public function admin_notice_missing_main_plugin() { $message = sprintf( /* translators: 1: Plugin name 2: Elementor */ esc_html__( '"%1$s" requires "%2$s" to be installed and activated.', 'cf7-pay-addons' ), '' . CF7PA_PLUGIN_NAME . '', '' . esc_html__( 'Contact Form 7', 'cf7-pay-addons' ) . '' ); // printf( '

%1$s

', $message ); printf( esc_html__( $message ) ); } protected function register_hooks() { add_filter( 'plugin_action_links_' . plugin_basename( CF7PA_ADDONS_FILE ), [$this, 'add_plugin_action_link'], 10, 5 ); // rest api add_action( 'rest_api_init', array($this, 'register_apis') ); // admin section if ( is_admin() ) { // Admin add_action( 'admin_menu', array($this, 'admin_menu') ); add_action( 'admin_enqueue_scripts', array($this, 'admin_enqueue_scripts') ); // cf7 setting $this->init_contact_form_checkout_setting(); } // Frontend CSS // make sure before contact form 7 add_action( 'wp_enqueue_scripts', [$this, 'enqueue_scripts'], 9, 0 ); // Skip the spam check for the final CF7 mail submission when payment was already // verified in the plugin's REST API (Turnstile token is single-use and gets // consumed during the REST API call, so the second CF7 submit would fail without this). // Uses the same wpcf7_skip_spam_check hook that CF7's own Stripe module uses. add_filter( 'wpcf7_skip_spam_check', [$this, 'skip_spam_check_for_payment_verified'], 10, 2 ); } /** * After payment intent creation the REST handler stores a short-lived transient. * On the subsequent wpcf7.submit() call for mail delivery we skip spam re-checking * entirely, mirroring the pattern used by CF7's built-in Stripe module. */ public function skip_spam_check_for_payment_verified( $skip_spam_check, $submission ) { if ( $skip_spam_check ) { return $skip_spam_check; } $unit_tag = ( isset( $_POST['_wpcf7_unit_tag'] ) ? wpcf7_sanitize_unit_tag( sanitize_text_field( wp_unslash( $_POST['_wpcf7_unit_tag'] ) ) ) : '' ); $form_id = ( isset( $_POST['_wpcf7'] ) ? (int) $_POST['_wpcf7'] : 0 ); if ( $unit_tag && $form_id ) { $transient_key = 'cf7pa_pay_verified_' . md5( $form_id . '_' . $unit_tag ); if ( get_transient( $transient_key ) ) { delete_transient( $transient_key ); return true; // skip spam check — payment already verified } } return $skip_spam_check; } public function add_plugin_action_link( $actions ) { $mylinks = array('Settings', 'Documentation'); $actions = array_merge( $mylinks, $actions ); return $actions; } public function register_apis() { $settings_api = new Rest_API_Settings_Controller(); $email_api = new Rest_API_Emails_Controller(); $stripe_api = new Rest_API_Stripe_Checkout_Controller(); $webhooks_api = new Rest_API_Stripe_Webhooks_Controller(); $txn_api = new Rest_API_Transaction_Controller(); $settings_api->register_routes(); $email_api->register_routes(); $webhooks_api->register_routes(); $stripe_api->register_routes(); $txn_api->register_routes(); } public function enqueue_scripts() { wp_register_script( 'stripe', 'https://js.stripe.com/v3/', [], '3.0' ); wp_register_script( 'cf7-pay-addons', CF7PA_ADDONS_ASSET_URL . 'frontend/js/pay-addons.js', ['jquery'], CF7PA_PLUGIN_VERSION ); wp_register_style( 'cf7-pay-addons', CF7PA_ADDONS_ASSET_URL . 'frontend/css/pay-addons.css', [], CF7PA_PLUGIN_VERSION ); wp_enqueue_script( 'stripe' ); wp_enqueue_script( 'cf7-pay-addons' ); wp_enqueue_style( 'cf7-pay-addons' ); wp_localize_script( 'cf7-pay-addons', 'cf7paSettings', array( 'root' => esc_url_raw( rest_url() . CF7PA_ADDONS_REST_API ), 'nonce' => wp_create_nonce( 'wp_rest' ), 'apiKey' => Stripe_Settings::get_publishable_key(), ) ); } }