• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » How to securely integrate ActiveCampaign automation API endpoints into WordPress custom plugins using WordPress Settings API

How to securely integrate ActiveCampaign automation API endpoints into WordPress custom plugins using WordPress Settings API

Leveraging the WordPress Settings API for Secure ActiveCampaign API Key Management

Integrating third-party services like ActiveCampaign into WordPress often requires storing sensitive API credentials. The WordPress Settings API provides a robust and secure mechanism for managing these settings directly within the WordPress admin area. This approach avoids hardcoding keys in your plugin files, which is a critical security best practice. We’ll walk through creating a custom settings page to store your ActiveCampaign API key and account ID.

Registering Settings and Fields

The core of the Settings API lies in its registration functions. We need to register a settings group, a settings section, and individual fields for our API key and account ID. This is typically done within your plugin’s main PHP file or an included settings administration file, hooked into the admin_init action.

Plugin Setup and Hooking

Assume you have a basic plugin structure. We’ll create a function that handles all the settings registration.

`my-activecampaign-plugin.php` (Main Plugin File Snippet)

<?php
/*
Plugin Name: My ActiveCampaign Integration
Description: Integrates with ActiveCampaign using API keys stored securely.
Version: 1.0
Author: Your Name
*/

// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

// Include the settings API handler
require_once plugin_dir_path( __FILE__ ) . 'includes/settings-api.php';

// Add settings page to the admin menu
function my_ac_add_admin_menu() {
    add_options_page(
        'ActiveCampaign Integration Settings',
        'ActiveCampaign',
        'manage_options',
        'my-activecampaign-settings',
        'my_ac_options_page_html'
    );
}
add_action( 'admin_menu', 'my_ac_add_admin_menu' );

// Function to render the settings page HTML
function my_ac_options_page_html() {
    // Check user capabilities
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }
    ?>
    <div class="wrap">
        <h1></h1>
        <form action="options.php" method="post">
            
        </form>
    </div>
    


`includes/settings-api.php` - The Core Settings Logic

This file will contain the registration of our settings, sections, and fields. We'll use register_setting, add_settings_section, and add_settings_field.

<?php
// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

// Register settings, sections, and fields
function my_ac_settings_init() {
    // Register a setting group
    register_setting( 'my_ac_settings_group', 'my_ac_options', 'my_ac_options_sanitize' );

    // Add a settings section
    add_settings_section(
        'my_ac_main_section', // ID
        'ActiveCampaign API Credentials', // Title
        'my_ac_main_section_callback', // Callback for section description
        'my-activecampaign-settings' // Page slug
    );

    // Add API Key field
    add_settings_field(
        'my_ac_api_key', // ID
        'API Key', // Title
        'my_ac_api_key_callback', // Callback to render the field
        'my-activecampaign-settings', // Page slug
        'my_ac_main_section', // Section ID
        array( 'label_for' => 'my_ac_api_key' ) // Arguments for the callback
    );

    // Add Account ID field
    add_settings_field(
        'my_ac_account_id', // ID
        'Account ID', // Title
        'my_ac_account_id_callback', // Callback to render the field
        'my-activecampaign-settings', // Page slug
        'my_ac_main_section', // Section ID
        array( 'label_for' => 'my_ac_account_id' ) // Arguments for the callback
    );
}
add_action( 'admin_init', 'my_ac_settings_init' );

// Callback for the main section description
function my_ac_main_section_callback() {
    echo '<p>Enter your ActiveCampaign API Key and Account ID below. You can find these in your ActiveCampaign account settings under "Developer".</p>';
}

// Callback to render the API Key input field
function my_ac_api_key_callback() {
    $options = get_option( 'my_ac_options' );
    $api_key = isset( $options['api_key'] ) ? $options['api_key'] : '';
    ?>
    <input type="text" id="my_ac_api_key" name="my_ac_options[api_key]" value="" class="regular-text" />
    <p class="description">Your ActiveCampaign API Key.</p>
    <?php
}

// Callback to render the Account ID input field
function my_ac_account_id_callback() {
    $options = get_option( 'my_ac_options' );
    $account_id = isset( $options['account_id'] ) ? $options['account_id'] : '';
    ?>
    <input type="text" id="my_ac_account_id" name="my_ac_options[account_id]" value="" class="regular-text" />
    <p class="description">Your ActiveCampaign Account ID.</p>
    <?php
}

// Sanitize and validate input data
function my_ac_options_sanitize( $input ) {
    $sanitized_input = array();

    if ( isset( $input['api_key'] ) ) {
        $sanitized_input['api_key'] = sanitize_text_field( $input['api_key'] );
        // Basic validation: Ensure it's not empty and has a typical format (e.g., alphanumeric)
        if ( ! empty( $sanitized_input['api_key'] ) && ! preg_match( '/^[a-zA-Z0-9]+$/', $sanitized_input['api_key'] ) ) {
            add_settings_error( 'my_ac_messages', 'my_ac_api_key_invalid', 'API Key appears to be invalid. Please check the format.', 'error' );
            // Optionally, unset the invalid value or keep it for user to correct
            // unset( $sanitized_input['api_key'] );
        }
    }

    if ( isset( $input['account_id'] ) ) {
        $sanitized_input['account_id'] = absint( $input['account_id'] ); // Ensure it's a positive integer
        if ( $sanitized_input['account_id'] === 0 && isset( $input['account_id'] ) && $input['account_id'] !== '' ) {
             add_settings_error( 'my_ac_messages', 'my_ac_account_id_invalid', 'Account ID must be a valid number.', 'error' );
             // unset( $sanitized_input['account_id'] );
        }
    }

    // Retrieve existing options to preserve other settings if any
    $existing_options = get_option( 'my_ac_options' );
    // Merge sanitized input with existing options, prioritizing sanitized values
    return array_merge( $existing_options ?: array(), $sanitized_input );
}
?>

In this code:

  • register_setting() registers the option group my_ac_settings_group and the option name my_ac_options. It also specifies a sanitization callback my_ac_options_sanitize.
  • add_settings_section() creates a visual grouping for our fields on the settings page.
  • add_settings_field() defines each input field, linking it to a callback function that renders the HTML for the input.
  • The callback functions (e.g., my_ac_api_key_callback) retrieve existing options using get_option() and display them in the input fields. esc_attr() is used for security.
  • The my_ac_options_sanitize() function is crucial. It receives the raw input from the form, cleans it using WordPress sanitization functions (sanitize_text_field, absint), and performs basic validation. It also uses add_settings_error() to display user-friendly error messages if validation fails.

Retrieving Stored API Credentials

Once the settings are saved, you can retrieve them anywhere in your plugin using get_option(). It's best practice to retrieve them once and store them in a constant or a class property to avoid repeated database queries.

<?php
// In your plugin's main file or a dedicated API handler file

// Retrieve ActiveCampaign options
$ac_options = get_option( 'my_ac_options' );

$activecampaign_api_key = isset( $ac_options['api_key'] ) ? $ac_options['api_key'] : '';
$activecampaign_account_id = isset( $ac_options['account_id'] ) ? $ac_options['account_id'] : '';

// Define constants for easy access and security (optional but recommended)
if ( ! defined( 'ACTIVECAMPAIGN_API_KEY' ) && ! empty( $activecampaign_api_key ) ) {
    define( 'ACTIVECAMPAIGN_API_KEY', $activecampaign_api_key );
}

if ( ! defined( 'ACTIVECAMPAIGN_ACCOUNT_ID' ) && ! empty( $activecampaign_account_id ) ) {
    define( 'ACTIVECAMPAIGN_ACCOUNT_ID', $activecampaign_account_id );
}

// Example usage in an API call function
function call_activecampaign_api( $endpoint, $method = 'GET', $data = array() ) {
    if ( ! defined( 'ACTIVECAMPAIGN_API_KEY' ) || ! defined( 'ACTIVECAMPAIGN_ACCOUNT_ID' ) ) {
        error_log( 'ActiveCampaign API credentials not configured.' );
        return false; // Or throw an exception
    }

    $url = "https://{ACTIVECAMPAIGN_ACCOUNT_ID}.api-us1.com/api/3/{$endpoint}"; // Adjust base URL if needed

    $headers = array(
        'Api-Token' => ACTIVECAMPAIGN_API_KEY,
        'Content-Type' => 'application/json',
    );

    $args = array(
        'method' => $method,
        'headers' => $headers,
        'body' => json_encode( $data ),
    );

    // Handle GET requests differently for parameters
    if ( $method === 'GET' && ! empty( $data ) ) {
        $url = add_query_arg( $data, $url );
        unset( $args['body'] ); // GET requests don't have a body
    }

    $response = wp_remote_request( $url, $args );

    if ( is_wp_error( $response ) ) {
        error_log( 'ActiveCampaign API Error: ' . $response->get_error_message() );
        return false;
    }

    $body = wp_remote_retrieve_body( $response );
    $status_code = wp_remote_retrieve_response_code( $response );

    if ( $status_code >= 400 ) {
        error_log( "ActiveCampaign API Error ({$status_code}): " . $body );
        return false;
    }

    return json_decode( $body, true );
}

// Example of calling the function
// $contacts = call_activecampaign_api( 'contacts', 'GET', array( 'limit' => 10 ) );
// if ( $contacts ) {
//     print_r( $contacts );
// }
?>

The call_activecampaign_api function demonstrates how to use the retrieved credentials. It constructs the API URL, sets the necessary headers (including the Api-Token), and uses wp_remote_request for making the HTTP call. Error handling and response processing are included.

Security Considerations and Best Practices

  • Never hardcode API keys: The Settings API approach prevents this.
  • Sanitize and Validate all input: The my_ac_options_sanitize function is critical. Always clean user-provided data before saving it to the database.
  • Use esc_attr() and esc_html(): When displaying data back to the user (in forms or elsewhere), always escape it to prevent XSS attacks.
  • Restrict Access: The manage_options capability check in my_ac_add_admin_menu and my_ac_options_page_html ensures only administrators can access and modify these settings.
  • Use HTTPS: Ensure your WordPress site uses HTTPS to protect data in transit.
  • Environment Variables (Advanced): For even greater security, especially in development or staging environments, consider using environment variables to store API keys and loading them into WordPress configuration. This is beyond the scope of the basic Settings API but is a valuable next step for production systems.
  • Database Encryption: For highly sensitive data, consider database-level encryption, though this adds significant complexity.

By following these steps, you can securely integrate ActiveCampaign API endpoints into your WordPress custom plugins, providing a user-friendly interface for managing credentials while adhering to security best practices.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Reducing database query bloat in Sage Roots modern environments layouts using custom lazy loaders
  • Performance Optimization: Tuning PHP-FPM and opcache pools for high-concurrency Firebase Realtime DB handlers
  • Reducing Largest Contentful Paint (LCP) by optimizing custom script enqueuing structures in legacy plugins
  • How to implement native Redis caching layers for high-volume custom taxonomy queries in Carbon Fields custom wrappers
  • Building secure B2B pricing grids with custom REST API Controllers endpoints and role overrides

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (658)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (872)
  • PHP (5)
  • PHP Development (48)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (639)
  • SEO & Growth (492)
  • Server (23)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (182)
  • WordPress Plugin Development (197)
  • WordPress Plugin Development (330)
  • WordPress Theme Development (357)

Recent Posts

  • Reducing database query bloat in Sage Roots modern environments layouts using custom lazy loaders
  • Performance Optimization: Tuning PHP-FPM and opcache pools for high-concurrency Firebase Realtime DB handlers
  • Reducing Largest Contentful Paint (LCP) by optimizing custom script enqueuing structures in legacy plugins

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (872)
  • Debugging & Troubleshooting (658)
  • Security & Compliance (639)
  • SEO & Growth (492)
  • Business & Monetization (390)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala