100, 'sslverify' => false, 'headers' => $headers, ] ); if ( is_wp_error( $response ) ) { return new \WP_Error( 'http_request_failed', esc_html__( 'HTTP request failed', 'sellkit' ), [ 'status' => 500, 'details' => $response->get_error_message() ] ); } $body = wp_remote_retrieve_body( $response ); $data = json_decode( $body, true ); if ( json_last_error() !== JSON_ERROR_NONE ) { return new \WP_Error( 'json_error', esc_html__( 'Error parsing JSON response', 'sellkit' ), [ 'status' => 500, 'details' => json_last_error_msg() ] ); } return $data; } /** * Fetch ActiveCampaign lists, tags, and fields. * * @since 2.3.0 * @return WP_REST_Response|WP_Error */ public function fetch_active_campaign_data() { $key = sellkit_get_option( 'activecampaign_api_key', '' ); $url = sellkit_get_option( 'activecampaign_api_url', '' ); if ( ! $key || ! $url ) { return new \WP_Error( 'missing_params', esc_html__( 'API key or URL is missing', 'sellkit' ), [ 'status' => 400 ] ); } $headers = [ 'Api-Token' => $key, 'Accept' => 'application/json', 'Content-Type' => 'application/json', ]; $responses = [ 'lists' => $this->fetch_api_data( "$url/api/3/lists", $headers ), 'tags' => $this->fetch_api_data( "$url/api/3/tags", $headers ), 'fields' => $this->fetch_api_data( "$url/api/3/fields", $headers ), ]; if ( is_wp_error( $responses['lists'] ) || is_wp_error( $responses['tags'] ) || is_wp_error( $responses['fields'] ) ) { return new \WP_Error( 'api_request_failed', esc_html__( 'Failed to fetch data from ActiveCampaign API', 'sellkit' ), [ 'status' => 500 ] ); } $responses['fields']['fields'] = [ 'email' => esc_html__( 'Email', 'sellkit' ), 'firstName' => esc_html__( 'First Name', 'sellkit' ), 'lastName' => esc_html__( 'Last Name', 'sellkit' ), 'phone' => esc_html__( 'Phone', 'sellkit' ), ]; return rest_ensure_response( $responses ); } /** * Fetch ConvertKit data (forms, tags, and custom fields). * * @since 2.3.0 * @return WP_REST_Response|WP_Error */ public function fetch_convertkit_data() { $api_key = sellkit_get_option( 'convertkit_api_key', '' ); if ( ! $api_key ) { return new \WP_Error( 'missing_params', esc_html__( 'API key is missing', 'sellkit' ), [ 'status' => 400 ] ); } $url = 'https://api.convertkit.com/v3/'; $responses = [ 'forms' => $this->fetch_api_data( "$url/forms?api_key=$api_key" ), 'tags' => $this->fetch_api_data( "$url/tags?api_key=$api_key" ), 'fields' => $this->fetch_api_data( "$url/custom_fields?api_key=$api_key" ), ]; if ( is_wp_error( $responses['forms'] ) || is_wp_error( $responses['tags'] ) || is_wp_error( $responses['fields'] ) ) { return new \WP_Error( 'api_request_failed', esc_html__( 'Failed to fetch data from ConvertKit API', 'sellkit' ), [ 'status' => 500 ] ); } $custom_fields = [ 'email' => esc_html__( 'Email', 'sellkit' ), 'first_name' => esc_html__( 'First Name', 'sellkit' ), ]; if ( isset( $responses['fields']['custom_fields'] ) && is_array( $responses['fields']['custom_fields'] ) ) { $responses['fields']['custom_fields'] = array_merge( $responses['fields']['custom_fields'], $custom_fields ); } else { $responses['fields']['custom_fields'] = $custom_fields; } return rest_ensure_response( $responses ); } /** * Fetch Drip accounts. * * @since 2.3.0 * @return WP_REST_Response|WP_Error */ public function fetch_drip_accounts() { $api_key = sellkit_get_option( 'drip_api_key', '' ); if ( ! $api_key ) { return new \WP_Error( 'missing_params', esc_html__( 'API key is missing', 'sellkit' ), [ 'status' => 400 ] ); } $url = 'https://api.getdrip.com/v2/accounts'; $headers = [ 'Authorization' => 'Basic ' . base64_encode( $api_key ), 'Content-Type' => 'application/vnd.api+json', 'User-Agent' => 'sellkit', ]; $data = $this->fetch_api_data( $url, $headers ); if ( is_wp_error( $data ) ) { return $data; } $accounts = array_map( function( $account ) { return [ 'id' => $account['id'], 'name' => $account['name'], ]; }, $data['accounts'] ); return rest_ensure_response( $accounts ); } /** * Fetch Drip tags and custom fields for a specific account. * * @since 2.3.0 * @param WP_REST_Request $request The REST API request object. * @return WP_REST_Response|WP_Error */ public function fetch_drip_tags_fields( $request ) { $api_key = sellkit_get_option( 'drip_api_key', '' ); $account_id = $request->get_param( 'account_id' ); if ( ! $api_key ) { return new \WP_Error( 'missing_params', esc_html__( 'API key is missing', 'sellkit' ), [ 'status' => 400 ] ); } if ( ! $account_id ) { return new \WP_Error( 'missing_params', esc_html__( 'Account ID is missing', 'sellkit' ), [ 'status' => 400 ] ); } $url = "https://api.getdrip.com/v2/$account_id"; $headers = [ 'Authorization' => 'Basic ' . base64_encode( $api_key ), 'Content-Type' => 'application/vnd.api+json', 'User-Agent' => 'sellkit', ]; $tags = $this->fetch_api_data( "$url/tags", $headers ); $fields = $this->fetch_api_data( "$url/custom_field_identifiers", $headers ); if ( is_wp_error( $tags ) || is_wp_error( $fields ) ) { return new \WP_Error( 'api_request_failed', __( 'Failed to fetch data from Drip API', 'sellkit' ), [ 'status' => 500 ] ); } $custom_fields = [ 'email' => esc_html__( 'Email', 'sellkit' ), 'first_name' => esc_html__( 'First Name', 'sellkit' ), 'last_name' => esc_html__( 'Last Name', 'sellkit' ), 'address1' => esc_html__( 'Address 1', 'sellkit' ), 'address2' => esc_html__( 'Address 2', 'sellkit' ), 'city' => esc_html__( 'City', 'sellkit' ), 'state' => esc_html__( 'State', 'sellkit' ), 'country' => esc_html__( 'Country', 'sellkit' ), 'zip' => esc_html__( 'Zip', 'sellkit' ), 'phone' => esc_html__( 'Phone', 'sellkit' ), 'sms_number' => esc_html__( 'SMS Number', 'sellkit' ), 'sms_consent' => esc_html__( 'SMS Consent', 'sellkit' ), 'time_zone' => esc_html__( 'Timezone', 'sellkit' ), ]; if ( isset( $fields['custom_field_definitions'] ) && is_array( $fields['custom_field_definitions'] ) ) { $fields['custom_field_definitions'] = array_merge( $fields['custom_field_definitions'], $custom_fields ); } else { $fields['custom_field_definitions'] = $custom_fields; } return rest_ensure_response([ 'tags' => $tags['tags'] ?? [], 'fields' => $fields['custom_field_definitions'] ?? [], ]); } /** * Fetch GetResponse data (campaigns, tags, and custom fields). * * @since 2.3.0 * @return WP_REST_Response|WP_Error */ public function fetch_getresponse_data() { $api_key = sellkit_get_option( 'getresponse_api_key', '' ); if ( ! $api_key ) { return new \WP_Error( 'missing_params', esc_html__( 'API key is missing', 'sellkit' ), [ 'status' => 400 ] ); } $url = 'https://api.getresponse.com/v3'; $headers = [ 'X-Auth-Token' => 'api-key ' . $api_key, 'Content-Type' => 'application/json', 'User-Agent' => 'sellkit', ]; $responses = [ 'campaigns' => $this->fetch_api_data( "$url/campaigns", $headers ), 'tags' => $this->fetch_api_data( "$url/tags", $headers ), 'fields' => $this->fetch_api_data( "$url/custom-fields", $headers ), ]; if ( is_wp_error( $responses['campaigns'] ) || is_wp_error( $responses['tags'] ) || is_wp_error( $responses['fields'] ) ) { return new \WP_Error( 'api_request_failed', esc_html__( 'Failed to fetch data from GetResponse API', 'sellkit' ), [ 'status' => 500 ] ); } $custom_fields = [ 'email' => esc_html__( 'Email', 'sellkit' ), 'name' => esc_html__( 'Name', 'sellkit' ), ]; foreach ( $responses['fields'] as $field ) { if ( is_array( $field ) && isset( $field['customFieldId'] ) ) { $custom_fields[ $field['customFieldId'] ] = $field['name']; } } $responses['fields'] = $custom_fields; return rest_ensure_response( $responses ); } /** * Fetch Mailchimp audiences. * * @since 2.3.0 * @return WP_REST_Response|WP_Error */ public function fetch_mailchimp_audiences() { $api_key = sellkit_get_option( 'mailchimp_api_key', '' ); if ( ! $api_key ) { return new \WP_Error( 'missing_params', esc_html__( 'API key is missing', 'sellkit' ), [ 'status' => 400 ] ); } $parts = explode( '-', $api_key ); if ( 2 !== count( $parts ) ) { return new \WP_Error( 'invalid_api_key', esc_html__( 'Invalid API key format', 'sellkit' ), [ 'status' => 400 ] ); } $api = [ 'token' => $parts[0], 'server' => $parts[1], ]; $url = "https://{$api['server']}.api.mailchimp.com/3.0/lists?count=999"; $headers = [ 'Authorization' => 'Basic ' . base64_encode( 'user:' . $api['token'] ), 'Content-Type' => 'application/json', 'User-Agent' => 'sellkit', ]; $data = $this->fetch_api_data( $url, $headers ); if ( is_wp_error( $data ) ) { return $data; } $lists = []; if ( ! empty( $data['lists'] ) ) { foreach ( $data['lists'] as $list ) { $lists[ $list['id'] ] = [ 'name' => $list['name'], 'value' => $list['id'], ]; } } return rest_ensure_response( [ 'lists' => $lists ] ); } /** * Fetch Mailchimp data (tags, fields, groups, and double opt-in settings based on audience). * * @since 2.3.0 * @param WP_REST_Request $request The REST API request object. * @return WP_REST_Response|WP_Error * @SuppressWarnings(PHPMD.NPathComplexity) */ public function fetch_mailchimp_data( $request ) { $api_key = sellkit_get_option( 'mailchimp_api_key', '' ); $audience_id = $request->get_param( 'audience_id' ); if ( ! $api_key || ! $audience_id ) { return new \WP_Error( 'missing_params', esc_html__( 'API key or Audience ID is missing', 'sellkit' ), [ 'status' => 400 ] ); } $parts = explode( '-', $api_key ); if ( 2 !== count( $parts ) ) { return new \WP_Error( 'invalid_api_key', esc_html__( 'Invalid API key format', 'sellkit' ), [ 'status' => 400 ] ); } $api = [ 'token' => $parts[0], 'server' => $parts[1], ]; $url_base = "https://{$api['server']}.api.mailchimp.com/3.0/lists/$audience_id"; $headers = [ 'Authorization' => 'Basic ' . base64_encode( 'user:' . $api['token'] ), 'Content-Type' => 'application/json', 'User-Agent' => 'sellkit', ]; $tags = $this->fetch_api_data( "$url_base/tag-search", $headers ); $fields = $this->fetch_api_data( "$url_base/merge-fields", $headers ); $groups = $this->fetch_api_data( "$url_base/interest-categories?count=99", $headers ); if ( is_wp_error( $tags ) || is_wp_error( $fields ) || is_wp_error( $groups ) ) { return new \WP_Error( 'api_request_failed', esc_html__( 'Failed to fetch data from Mailchimp API', 'sellkit' ), [ 'status' => 500 ] ); } $custom_fields = [ 'email' => esc_html__( 'Email', 'sellkit' ), 'full_name' => esc_html__( 'Full Name', 'sellkit' ), ]; foreach ( $fields['merge_fields'] as $field ) { if ( is_array( $field ) ) { $custom_fields[ $field['tag'] ] = $field['name']; } } $responses = [ 'tags' => $tags['tags'] ?? [], 'fields' => $custom_fields, 'groups' => [], ]; if ( ! empty( $groups['categories'] ) ) { foreach ( $groups['categories'] as $category ) { $category_data = $this->fetch_api_data( "$url_base/interest-categories/{$category['id']}/interests?count=999", $headers ); if ( ! is_wp_error( $category_data ) && ! empty( $category_data['interests'] ) ) { foreach ( $category_data['interests'] as $interest ) { $responses['groups'][ $interest['id'] ] = "{$category['title']}: {$interest['name']}"; } } } } return rest_ensure_response( $responses ); } /** * Fetch MailerLite groups. * * @since 2.3.0 * @return WP_REST_Response|WP_Error */ public function fetch_mailerlite_data() { $key = sellkit_get_option( 'mailerlite_api_key', '' ); if ( ! $key ) { return new \WP_Error( 'missing_params', esc_html__( 'API key is missing', 'sellkit' ), [ 'status' => 400 ] ); } $url_base = 'https://api.mailerlite.com/api/v2'; $headers = [ 'X-MailerLite-ApiKey' => $key, 'Accept' => 'application/json', 'Content-Type' => 'application/json', ]; $groups = $this->fetch_api_data( "$url_base/groups", $headers ); $fields = $this->fetch_api_data( "$url_base/fields", $headers ); if ( is_wp_error( $groups ) || is_wp_error( $fields ) ) { return new \WP_Error( 'api_request_failed', esc_html__( 'Failed to fetch data from MailerLite API', 'sellkit' ), [ 'status' => 500 ] ); } $custom_fields = [ 'email' => esc_html__( 'Email', 'sellkit' ), 'name' => esc_html__( 'Name', 'sellkit' ), ]; foreach ( $fields as $field ) { if ( is_array( $field ) && ! array_key_exists( $field['key'], $custom_fields ) ) { $custom_fields[ $field['key'] ] = $field['title']; } } return rest_ensure_response( [ 'groups' => $groups, 'fields' => $custom_fields, ] ); } /** * Register CRM endpoint. * * @since 2.3.0 */ public function register_crm_endpoint() { $routes = [ [ 'namespace' => 'sellkit/v1', 'route' => '/activecampaign', 'method' => 'GET', 'callback' => [ $this, 'fetch_active_campaign_data' ], ], [ 'namespace' => 'sellkit/v1', 'route' => '/convertkit', 'method' => 'GET', 'callback' => [ $this, 'fetch_convertkit_data' ], ], [ 'namespace' => 'sellkit/v1', 'route' => '/getResponse', 'method' => 'GET', 'callback' => [ $this, 'fetch_getresponse_data' ], ], [ 'namespace' => 'sellkit/v1', 'route' => '/mailchimp/audiences', 'method' => 'GET', 'callback' => [ $this, 'fetch_mailchimp_audiences' ], ], [ 'namespace' => 'sellkit/v1', 'route' => '/mailchimp/data', 'method' => 'GET', 'callback' => [ $this, 'fetch_mailchimp_data' ], 'args' => [ 'audience_id' => [ 'required' => true, 'validate_callback' => function( $param ) { return is_string( $param ); } ] ] ], [ 'namespace' => 'sellkit/v1', 'route' => '/drip/accounts', 'method' => 'GET', 'callback' => [ $this, 'fetch_drip_accounts' ], ], [ 'namespace' => 'sellkit/v1', 'route' => '/drip/tags-fields', 'method' => 'GET', 'callback' => [ $this, 'fetch_drip_tags_fields' ], 'args' => [ 'account_id' => [ 'required' => true, 'validate_callback' => function( $param ) { return is_string( $param ); } ] ] ], [ 'namespace' => 'sellkit/v1', 'route' => '/mailerlite-data', 'method' => 'GET', 'callback' => [ $this, 'fetch_mailerlite_data' ], ], ]; foreach ( $routes as $route ) { register_rest_route( $route['namespace'], $route['route'], [ 'methods' => $route['method'], 'callback' => $route['callback'], 'permission_callback' => [ $this, 'admin_permission_callback' ], 'args' => isset( $route['args'] ) ? $route['args'] : [], ] ); } } } Sellkit_Blocks_Endpoint::get_instance();