• 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 Block Patterns API

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

Securing ActiveCampaign API Credentials in WordPress

Integrating ActiveCampaign’s powerful automation capabilities into a WordPress site via custom plugins requires robust security for API credentials. Storing these sensitive keys directly within plugin files or the database in plain text is a critical vulnerability. A best practice is to leverage WordPress’s built-in mechanisms for handling sensitive data, specifically by using constants defined in wp-config.php. This file is intentionally excluded from version control (e.g., Git) and is not accessible via the web server, providing a secure environment for secrets.

We’ll define two constants: one for the ActiveCampaign API URL and another for the API key. These constants will be accessed within our custom plugin to authenticate API requests.

Defining API Credentials in wp-config.php

Locate your wp-config.php file in the root directory of your WordPress installation. Add the following lines before the /* That's all, stop editing! Happy publishing. */ line:

/**
 * ActiveCampaign API Configuration
 */
define( 'AC_API_URL', 'https://YOUR_ACCOUNT_NAME.api-us1.com' ); // Replace YOUR_ACCOUNT_NAME with your actual ActiveCampaign account name
define( 'AC_API_KEY', 'YOUR_API_KEY_HERE' ); // Replace YOUR_API_KEY_HERE with your actual ActiveCampaign API Key

Important: Replace YOUR_ACCOUNT_NAME and YOUR_API_KEY_HERE with your actual ActiveCampaign account details. Ensure these values are kept confidential.

Creating a Custom WordPress Plugin for API Integration

We’ll create a basic WordPress plugin structure to house our ActiveCampaign integration logic. This plugin will include a main PHP file and potentially other files for organization.

Plugin File Structure

Create a new folder within your wp-content/plugins/ directory, for example, activecampaign-integration. Inside this folder, create the main plugin file, e.g., activecampaign-integration.php.

Plugin Header

Add the standard WordPress plugin header to activecampaign-integration.php:

<?php
/**
 * Plugin Name: ActiveCampaign Integration
 * Plugin URI: https://example.com/plugins/activecampaign-integration/
 * Description: Integrates ActiveCampaign API endpoints with WordPress.
 * Version: 1.0
 * Author: Your Name
 * Author URI: https://example.com/
 * License: GPL2
 */

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

// Include other plugin files if necessary
// require_once plugin_dir_path( __FILE__ ) . 'includes/class-ac-api-client.php';
// require_once plugin_dir_path( __FILE__ ) . 'includes/class-ac-block-patterns.php';

Developing the ActiveCampaign API Client

To interact with the ActiveCampaign API, we’ll create a simple PHP class that handles making authenticated HTTP requests. This class will utilize the constants defined in wp-config.php.

AC_API_Client Class

Create a new file, for instance, includes/class-ac-api-client.php, and add the following code:

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

class AC_API_Client {

    private $api_url;
    private $api_key;

    public function __construct() {
        // Ensure constants are defined before using them
        if ( ! defined( 'AC_API_URL' ) || ! defined( 'AC_API_KEY' ) ) {
            error_log( 'ActiveCampaign API constants are not defined. Please check wp-config.php.' );
            return;
        }
        $this->api_url = AC_API_URL;
        $this->api_key = AC_API_KEY;
    }

    /**
     * Makes a GET request to the ActiveCampaign API.
     *
     * @param string $endpoint The API endpoint (e.g., '/contacts').
     * @param array  $params   Optional query parameters.
     * @return array|WP_Error The API response or a WP_Error object on failure.
     */
    public function get( $endpoint, $params = array() ) {
        return $this->request( 'GET', $endpoint, $params );
    }

    /**
     * Makes a POST request to the ActiveCampaign API.
     *
     * @param string $endpoint The API endpoint (e.g., '/contacts').
     * @param array  $data     The data to send in the request body.
     * @return array|WP_Error The API response or a WP_Error object on failure.
     */
    public function post( $endpoint, $data = array() ) {
        return $this->request( 'POST', $endpoint, $data );
    }

    /**
     * Makes a PUT request to the ActiveCampaign API.
     *
     * @param string $endpoint The API endpoint (e.g., '/contacts/1').
     * @param array  $data     The data to send in the request body.
     * @return array|WP_Error The API response or a WP_Error object on failure.
     */
    public function put( $endpoint, $data = array() ) {
        return $this->request( 'PUT', $endpoint, $data );
    }

    /**
     * Makes a DELETE request to the ActiveCampaign API.
     *
     * @param string $endpoint The API endpoint (e.g., '/contacts/1').
     * @return array|WP_Error The API response or a WP_Error object on failure.
     */
    public function delete( $endpoint ) {
        return $this->request( 'DELETE', $endpoint );
    }

    /**
     * Handles the actual HTTP request to the ActiveCampaign API.
     *
     * @param string $method   The HTTP method (GET, POST, PUT, DELETE).
     * @param string $endpoint The API endpoint.
     * @param array  $args     Arguments for the request (query params or body data).
     * @return array|WP_Error The API response or a WP_Error object on failure.
     */
    private function request( $method, $endpoint, $args = array() ) {
        if ( ! defined( 'AC_API_URL' ) || ! defined( 'AC_API_KEY' ) ) {
            return new WP_Error( 'ac_api_credentials_missing', __( 'ActiveCampaign API credentials are not configured.', 'activecampaign-integration' ) );
        }

        $url = trailingslashit( $this->api_url ) . ltrim( $endpoint, '/' );
        $headers = array(
            'Api-Token' => $this->api_key,
            'Accept'    => 'application/json',
        );

        $request_args = array(
            'method'  => strtoupper( $method ),
            'headers' => $headers,
            'timeout' => 30, // Adjust timeout as needed
        );

        if ( 'GET' === strtoupper( $method ) ) {
            if ( ! empty( $args ) ) {
                $url = add_query_arg( $args, $url );
            }
        } else {
            // For POST, PUT, DELETE, send data in the body
            $headers['Content-Type'] = 'application/json';
            $request_args['body'] = json_encode( $args );
        }

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

        if ( is_wp_error( $response ) ) {
            return $response;
        }

        $response_code = wp_remote_retrieve_response_code( $response );
        $response_body = wp_remote_retrieve_body( $response );
        $decoded_body = json_decode( $response_body, true );

        if ( $response_code >= 200 && $response_code < 300 ) {
            return $decoded_body;
        } else {
            $error_message = isset( $decoded_body['errors'] ) ? implode( ', ', $decoded_body['errors'] ) : $response_body;
            return new WP_Error( 'ac_api_error', sprintf( __( 'ActiveCampaign API Error (%d): %s', 'activecampaign-integration' ), $response_code, $error_message ) );
        }
    }
}

In the main plugin file (activecampaign-integration.php), include this class:

// ... (plugin header) ...

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

// Include the API client class
require_once plugin_dir_path( __FILE__ ) . 'includes/class-ac-api-client.php';

// Instantiate the client globally or within specific functions/classes
// For simplicity, we'll instantiate it when needed.

Leveraging the Block Patterns API for UI Integration

The Block Patterns API in WordPress allows developers to create pre-designed blocks of content that users can insert into their posts and pages. We can use this to create a user-friendly interface for triggering ActiveCampaign automations or displaying contact information.

Registering a Custom Block Pattern

We’ll create a block pattern that, when inserted, can trigger an action like adding a user to an ActiveCampaign list. This pattern will likely contain some HTML and potentially a shortcode or a custom block that our plugin registers.

AC_Block_Patterns Class

Create a new file, e.g., includes/class-ac-block-patterns.php, and add the following code:

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

class AC_Block_Patterns {

    private $ac_client;

    public function __construct() {
        // Ensure AC_API_Client is available
        if ( ! class_exists( 'AC_API_Client' ) ) {
            error_log( 'AC_API_Client class not found.' );
            return;
        }
        $this->ac_client = new AC_API_Client();

        add_action( 'init', array( $this, 'register_block_patterns' ) );
        add_action( 'wp_ajax_ac_add_contact_to_list', array( $this, 'ajax_add_contact_to_list' ) );
        add_action( 'wp_ajax_nopriv_ac_add_contact_to_list', array( $this, 'ajax_add_contact_to_list' ) ); // For logged-out users if needed
    }

    /**
     * Registers the ActiveCampaign block patterns.
     */
    public function register_block_patterns() {
        if ( function_exists( 'register_block_pattern' ) ) {
            register_block_pattern(
                'activecampaign/add-to-list-form', // Unique pattern name
                array(
                    'title'       => __( 'ActiveCampaign Add to List Form', 'activecampaign-integration' ),
                    'description' => __( 'A form to add a contact to an ActiveCampaign list.', 'activecampaign-integration' ),
                    'content'     => $this->get_pattern_content(),
                    'categories'  => array( 'activecampaign', 'forms' ),
                    'keywords'    => array( 'activecampaign', 'form', 'subscribe', 'list' ),
                )
            );
        }
    }

    /**
     * Generates the HTML content for the block pattern.
     * This will include a form that uses AJAX to submit data.
     *
     * @return string The HTML content for the pattern.
     */
    private function get_pattern_content() {
        // This HTML will be inserted into the editor.
        // It includes a form that will trigger our AJAX handler.
        ob_start();
        ?>
        <div class="wp-block-group ac-add-to-list-form">
            <h3><?php esc_html_e( 'Subscribe to Our Newsletter', 'activecampaign-integration' ); ?></h3>
            <p><?php esc_html_e( 'Enter your details below to join our mailing list.', 'activecampaign-integration' ); ?></p>
            <form id="ac-subscribe-form">
                <input type="email" name="email" placeholder="<?php esc_attr_e( 'Your Email', 'activecampaign-integration' ); ?>" required><br>
                <input type="text" name="first_name" placeholder="<?php esc_attr_e( 'Your First Name', 'activecampaign-integration' ); ?>"><br>
                <button type="submit"><?php esc_html_e( 'Subscribe', 'activecampaign-integration' ); ?></button>
                <div id="ac-form-message" style="margin-top: 10px;"></div>
                <?php wp_nonce_field( 'ac_add_contact_nonce', 'ac_nonce' ); ?>
            </form>
        </div>
        <script>
        jQuery(document).ready(function($) {
            $('#ac-subscribe-form').on('submit', function(e) {
                e.preventDefault();
                var form = $(this);
                var messageDiv = $('#ac-form-message');
                messageDiv.html('<?php esc_html_e( 'Submitting...', 'activecampaign-integration' ); ?>');

                $.ajax({
                    url: ajaxurl, // WordPress AJAX URL
                    type: 'POST',
                    dataType: 'json',
                    data: {
                        action: 'ac_add_contact_to_list',
                        email: form.find('input[name="email"]').val(),
                        first_name: form.find('input[name="first_name"]').val(),
                        ac_nonce: form.find('input[name="ac_nonce"]').val()
                    },
                    success: function(response) {
                        if (response.success) {
                            messageDiv.html('<p style="color: green;">' + response.data.message + '</p>');
                            form[0].reset(); // Reset form
                        } else {
                            messageDiv.html('<p style="color: red;">' + response.data.message + '</p>');
                        }
                    },
                    error: function(jqXHR, textStatus, errorThrown) {
                        messageDiv.html('<p style="color: red;">An error occurred: ' + textStatus + '</p>');
                        console.error('AJAX Error: ', textStatus, errorThrown, jqXHR.responseText);
                    }
                });
            });
        });
        </script>
        



Now, include this class in your main plugin file:

// ... (plugin header and AC_API_Client include) ...

// Include the Block Patterns class
require_once plugin_dir_path( __FILE__ ) . 'includes/class-ac-block-patterns.php';

// Instantiate the Block Patterns class
if ( class_exists( 'AC_Block_Patterns' ) ) {
    new AC_Block_Patterns();
}

Configuring and Using the Block Pattern

After activating your plugin, navigate to the WordPress editor for a post or page. In the block inserter, search for "ActiveCampaign" or "Add to List Form". You should see your registered pattern. Insert it, and you'll have a functional subscription form.

Crucially, remember to replace $list_id = 1; in ajax_add_contact_to_list with your actual ActiveCampaign List ID. You can find this ID within your ActiveCampaign account under "Lists" -> "Manage Lists", and then clicking on the list name to see its details in the URL or settings.

Advanced Considerations and Further Development

This setup provides a secure and functional integration. For more advanced use cases, consider:

  • Customization: Allow users to select the ActiveCampaign list ID via a plugin setting page (using the WordPress Settings API) instead of hardcoding it.
  • Error Handling: Implement more granular error reporting and user feedback for API failures.
  • Data Sync: Develop custom blocks or shortcodes to fetch and display contact data or automation status from ActiveCampaign.
  • Security Enhancements: For highly sensitive operations, consider implementing rate limiting on your AJAX endpoints and further input validation.
  • Enqueueing Scripts: Properly enqueue the JavaScript file containing the AJAX submission logic using wp_enqueue_script instead of embedding it directly in the pattern's HTML. This improves performance and maintainability.
  • Internationalization: Ensure all user-facing strings are translatable using WordPress's internationalization functions (__(), _e(), esc_html__(), etc.).

By following these steps, you can securely integrate ActiveCampaign's automation features into your WordPress site using custom plugins and the Block Patterns API, enhancing user engagement and marketing efforts.

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

  • Optimizing p99 database query response latency in multi-site Domain-driven architecture (DDD) blocks custom tables
  • How to design a modular Action-hook Event Mediator architecture for enterprise-level custom plugins
  • Step-by-Step Guide to building a custom database optimizer portal block for Gutenberg using Next.js headless configurations
  • Optimizing WooCommerce cart response times by lazy loading custom user transaction ledgers assets
  • Step-by-Step Guide: Offloading high-frequency custom subscription logs metadata writes to a Redis KV store

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 (41)
  • 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 (66)
  • WordPress Plugin Development (72)
  • WordPress Plugin Development (330)
  • WordPress Theme Development (357)

Recent Posts

  • Optimizing p99 database query response latency in multi-site Domain-driven architecture (DDD) blocks custom tables
  • How to design a modular Action-hook Event Mediator architecture for enterprise-level custom plugins
  • Step-by-Step Guide to building a custom database optimizer portal block for Gutenberg using Next.js headless configurations

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