bool, 'message' => string] */ public static function subscribe( $lead_id, $email, $full_name ) { if ( ! self::is_enabled() ) { return array( 'success' => false, 'message' => 'Brevo integration disabled.' ); } // Adding an address to a mailing list is marketing: an unsubscribed address is never re-added. if ( ! apply_filters( 'acquis_marketing_allowed', true, $email ) ) { return array( 'success' => false, 'message' => 'Skipped: this address unsubscribed from marketing.' ); } $api_key =get_option( 'acquis_brevo_api_key', '' ); $list_id = (int) get_option( 'acquis_brevo_list_id', 0 ); $dbl_optin = (bool) get_option( 'acquis_brevo_double_optin', false ); if ( empty( $api_key ) ) { return array( 'success' => false, 'message' => 'Brevo API key not configured.' ); } // Parse name $name_parts = explode( ' ', trim( $full_name ), 2 ); $fname = $name_parts[0]; $lname = isset( $name_parts[1] ) ? $name_parts[1] : ''; if ( $dbl_optin && $list_id ) { // Use Brevo double opt-in endpoint return self::double_optin_subscribe( $lead_id, $email, $fname, $lname, $list_id, $api_key ); } // Standard create/update contact $payload = array( 'email' => $email, 'attributes' => array( 'FIRSTNAME' => $fname, 'LASTNAME' => $lname, ), 'updateEnabled' => true, // update if exists ); if ( $list_id ) { $payload['listIds'] = array( $list_id ); } $response = self::api_request( 'POST', self::API_BASE . '/contacts', $payload, $api_key ); $success = in_array( $response['http_code'] ?? 0, array( 200, 201, 204 ), true ); if ( ! $success && ( $response['http_code'] ?? 0 ) === 400 ) { // Contact may already exist attempt PATCH update $encoded = rawurlencode( $email ); $response = self::api_request( 'PUT', self::API_BASE . '/contacts/' . $encoded, $payload, $api_key ); $success = in_array( $response['http_code'] ?? 0, array( 200, 201, 204 ), true ); } $message = $success ? "Subscribed to Brevo list {$list_id}." : ( $response['body']['message'] ?? 'Unknown Brevo API error.' ); ACQUIS_Database::log_integration( $lead_id, 'brevo', $success ? 'success' : 'failed', wp_json_encode( $response['body'] ?? array() ) ); return array( 'success' => $success, 'message' => $message ); } /** * Trigger Brevo's native double opt-in flow. */ private static function double_optin_subscribe( $lead_id, $email, $fname, $lname, $list_id, $api_key ) { // Brevo requires a DOI template configured in your account $doi_template_id = (int) get_option( 'acquis_brevo_doi_template_id', 0 ); $redirect_url = esc_url_raw( get_option( 'acquis_brevo_doi_redirect', home_url( '/' ) ) ); if ( ! $doi_template_id ) { // Fallback to regular subscribe return self::subscribe( $lead_id, $email, "{$fname} {$lname}" ); } $payload = array( 'email' => $email, 'attributes' => array( 'FIRSTNAME' => $fname, 'LASTNAME' => $lname ), 'includeListIds' => array( $list_id ), 'templateId' => $doi_template_id, 'redirectionUrl' => $redirect_url, ); $response = self::api_request( 'POST', self::API_BASE . '/contacts/doubleOptinConfirmation', $payload, $api_key ); $success = in_array( $response['http_code'] ?? 0, array( 200, 201, 204 ), true ); ACQUIS_Database::log_integration( $lead_id, 'brevo', $success ? 'success' : 'failed', wp_json_encode( $response['body'] ?? array() ) ); return array( 'success' => $success, 'message' => $success ? 'Brevo double opt-in confirmation sent.' : ( $response['body']['message'] ?? 'Brevo DOI failed.' ), ); } /** * Test API key validity. * * @param string $api_key * @return array ['success' => bool, 'message' => string] */ public static function test_connection( $api_key ) { $response = self::api_request( 'GET', self::API_BASE . '/account', array(), $api_key ); $success = ( $response['http_code'] ?? 0 ) === 200; return array( 'success' => $success, 'message' => $success ? ( 'Connected as: ' . ( $response['body']['email'] ?? 'unknown' ) ) : ( $response['body']['message'] ?? 'Invalid Brevo API key.' ), ); } /** * Fetch available contact lists for the admin dropdown. * * @param string $api_key * @return array [['id' => ..., 'name' => ...], ...] */ public static function get_lists( $api_key ) { $response = self::api_request( 'GET', self::API_BASE . '/contacts/lists?limit=50', array(), $api_key ); if ( empty( $response['body']['lists'] ) ) return array(); return array_map( function( $list ) { return array( 'id' => $list['id'], 'name' => $list['name'] ); }, $response['body']['lists'] ); } public static function is_enabled() { return (bool) get_option( 'acquis_brevo_enabled', false ); } /** * Shared HTTP helper. */ private static function api_request( $method, $url, $body, $api_key ) { $args = array( 'method' => strtoupper( $method ), 'headers' => array( 'api-key' => $api_key, 'Content-Type' => 'application/json', 'Accept' => 'application/json', ), 'timeout' => 15, ); if ( ! empty( $body ) ) { $args['body'] = wp_json_encode( $body ); } $response = wp_remote_request( $url, $args ); $http_code = wp_remote_retrieve_response_code( $response ); $raw_body = wp_remote_retrieve_body( $response ); $decoded = json_decode( $raw_body, true ); return array( 'http_code' => $http_code, 'body' => $decoded, 'raw' => $raw_body ); } }