Custom Integrations for WPForms

For many online businesses, the contact form is one piece of a larger marketing and customer management system involving multiple services. You might be sending support requests into HelpScout, or adding interested readers to your MailChimp mailing list, or creating a new lead in your CRM.

WPForms may already have add-ons that integrate with your services, like MailChimp and Aweber. But what if you need to build your own integration? It is surprisingly easy.

Real World Examples

Here are some WPForms integrations I have built for clients. You can download and install these plugins yourself if you want to connect to these services:

Building a custom integration

You can use the wpforms_process_complete hook to run your own custom code after the successful submission of a WPForms entry. This hook runs at the end because there are reasons a form submission might not reach the complete hook (required fields weren’t filled out, message was determined to be spam…). 

This hook runs after submission of every form on your site. If you’d like to limit it to a specific form, you can use wpforms_process_complete_{form_id}.

For a simple one-off integration, this is all you need. In your theme’s functions.php file or a core functionality plugin, add the following code and customize it to your service’s API specifications:

/**
 * Integrate WPForms with CRM
 *
 * @author Bill Erickson
 * @link https://www.billerickson.net/contact-form-integration/
 * 
 * @param array $fields
 * @param array $entry
 * @param array $form_data
 * @param int $entry_id
 */
function be_crm_connector( $fields, $entry, $form_data, $entry_id ) {

	// Limit to Form ID = 123
	if( 123 != $form_data['id'] )
		return;

	$api_url = 'http://example.com';
	$body = array(
		'name'                => $fields['1']['value'],
		'email'               => $fields['2']['value'],
	);
	$request = wp_remote_post( $api_url, array( 'body' => $body ) );
	
}
add_action( 'wpforms_process_complete', 'be_crm_connector', 10, 4 );

If you plan to use this on multiple website or multiple forms, I recommend including a backend settings panel for managing the connection.

Backend Settings Panel

You can use internal WPForms filters and helper functions to add your own section to the form settings.

For my ConvertKit addon, I created a settings panel for managing an API key, selecting the ConvertKit Form ID, and selecting which fields to send.

We will first use the wpforms_builder_settings_sections filter to add a section to the settings panel. It’s a simple array with a unique slug and label.

/**
 * Add Settings Section
 *
 */
function be_wpforms_settings_section( $sections, $form_data ) {
    $sections['be_convertkit'] = __( 'ConvertKit', 'integrate_convertkit_wpforms' );
    return $sections;
}
add_filter( 'wpforms_builder_settings_sections', 'be_wpforms_settings_section', 20, 2 );

Then we use the wpforms_form_settings_panel_content filter to specify what content appears in that section.

/**
 * ConvertKit Settings Content
 *
 */
function be_wpforms_settings_section_content( $instance ) {
    echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-be_convertkit">';
    echo '<div class="wpforms-panel-content-section-title">' . __( 'ConvertKit', 'be_wpforms_convertkit' ) . '</div>';
    wpforms_panel_field(
        'text',
        'settings',
        'be_convertkit_api',
        $instance->form_data,
        __( 'ConvertKit API Key', 'be_wpforms_convertkit' )
    );
    wpforms_panel_field(
        'text',
        'settings',
        'be_convertkit_form_id',
        $instance->form_data,
        __( 'ConvertKit Form ID', 'be_wpforms_convertkit' )
    );
    wpforms_panel_field(
        'select',
        'settings',
        'be_convertkit_field_first_name',
        $instance->form_data,
        __( 'First Name', 'be_wpforms_convertkit' ),
        array(
            'field_map'   => array( 'text', 'name' ),
            'placeholder' => __( '-- Select Field --', 'be_wpforms_convertkit' ),
        )
    );
    wpforms_panel_field(
        'select',
        'settings',
        'be_convertkit_field_email',
        $instance->form_data,
        __( 'Email Address', 'be_wpforms_convertkit' ),
        array(
            'field_map'   => array( 'email' ),
            'placeholder' => __( '-- Select Field --', 'be_wpforms_convertkit' ),
        )
    );
    echo '</div>';
}
add_filter( 'wpforms_form_settings_panel_content', 'be_wpforms_settings_section_content', 20 );

I’m using the wpforms_panel_field() function to create the fields. WPForms does all the heavy lifting for rendering, sanitizing, and saving these fields. Here are the parameters of the function:

wpforms_panel_field( $option, $panel, $field, $form_data, $label, $args, $echo )

  • Option: What type of field it is (ex: text, select…). Look in wpforms/includes/admin/builder/functions.php for a list of all available options
  • Panel: What panel it is in. These are all in a section of the Settings panel so we’re setting them all to ‘settings’
  • Field: The field ID you’ll use to save/access this data.
  • Form Data: Pass all the form data, which has important information for building out the fields. Use $instance->form_data, which is provided by the filter we’re using.
  • Label: The label you want associated with this field.
  • Args: Any additional arguments you want to pass. For instance, 'field_map' => array( 'email' ) on a “select” field type will pre-populate the dropdown with every email field in the form
  • Echo: defaults to true

If WPForms rebuilds its form builder, you may need to update your backend settings to use its new helper functions, so you may want to include some method of updating your plugin in the future. You could release it on WordPress.org, or include a GitHub updater so you can push updates from your GitHub repo.

Using the backend settings

All of the backend settings you create will be accessible inside $form_data['settings'].

Rather than limiting my code by the Form ID, I’m limiting it to only those that have an API key and ConvertKit Form ID specified. We can use this same code on multiple forms across the site.

I then access my backend settings for email and first name to get the field IDs for those respective fields, then include their field values in the $args I’m sending to ConvertKit.

/**
 * Integrate WPForms with ConvertKit
 *
 * @author Bill Erickson
 * @link https://www.billerickson.net/contact-form-integration/
 * 
 * @param array $fields
 * @param array $entry
 * @param array $form_data
 * @param int $entry_id
 */
function be_send_data_to_convertkit( $fields, $entry, $form_data, $entry_id ) {

	// Get API key and CK Form ID
	 $api_key = $ck_form_id = false;
	if( !empty( $form_data['settings']['be_convertkit_api'] ) )
		$api_key = esc_html( $form_data['settings']['be_convertkit_api'] );
	if( !empty( $form_data['settings']['be_convertkit_form_id'] ) )
		$ck_form_id = intval( $form_data['settings']['be_convertkit_form_id'] );
	if( ! ( $api_key && $ck_form_id ) )
		return;

	// Get email and first name
	$email_field_id = $form_data['settings']['be_convertkit_field_email'];
	$first_name_field_id = $form_data['settings']['be_convertkit_field_first_name'];

	$args = array(
		'api_key'    => $api_key,
		'email'      => $fields[$email_field_id]['value'],
		'first_name' => $fields[$first_name_field_id]['value']
 	);

	if( empty( $args['email'] ) || empty( $args['first_name'] ) )
		return;

	// Submit to ConvertKit
	$request = wp_remote_post( add_query_arg( $args, 'https://api.convertkit.com/v3/forms/' . $ck_form_id . '/subscribe' ) );
}
add_action( 'wpforms_process_complete', 'be_send_data_to_convertkit', 10, 4 );

Bill Erickson

Bill Erickson is the co-founder and lead developer at CultivateWP, a WordPress agency focusing on high performance sites for web publishers.

About Me
Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments are closed. Continue the conversation with me on Twitter: @billerickson

Comments

  1. Puneet says

    Hi Bill,

    I am using Wpforms, this is a great plugin. I have a query regarding confirmation page in wpform. I want to make a customize confirmation “page”, where I want to integrate some “fields” of my “registration form” of every “new entry”. So please help to make me this possible, how can I integrate every new registration’s, specific field or entry form my registration form after successfully submission of form and then it redirect to other confirmation page with these details in “Wpforms”.

  2. Vasili says

    Hi Bill,

    Can i ask you regarding building a custom integration with WPForms and ACF acf_form()?

    I am building a niche site for writers who can create small landing pages for their books. The fucntionality of creating the landing pages is built with ACF front-end form.

    I am looking for an option to let each writer to add a mail subscription on their landing pages. The scenario i thought about is to create a form in WPForms, then add two ACF fields, one for the API key and the other for form id, and then pass the fields into the wpforms_panel_field() function – so that both API key and form id will be added by each writer in the acf_form() fields.

    For example:

    Instead of:

    wpforms_panel_field(
    ‘text’,
    ‘settings’,
    ‘be_convertkit_api’,
    );

    I’ll be using:

    wpforms_panel_field(
    ‘text’,
    ‘settings’,
    get_field( ‘lp_convertkit_api’ ),
    );

    Theoretically it looks like an easy thing to do, from your point of view do you think it is achievable?

    Thank you.

    • Vasili says

      I missed one step: Adding two WPForms custom smart tags for API key {writer_ck_api_key} and form id {writer_ck_from_id} fields which will include a condition of author meta.

    • Bill Erickson says

      I would drop the settings panel altogether and use usermeta for that data storage instead. You could have an ACF front-end form that sets user meta for those two fields, then in your ConvertKit code use `get_field()` to retrieve the data.

  3. Neil A. says

    Hi Bill,

    Can this solution (or some other?) be used to send an SMS/text message to the users who completes and submits the WPforms form? Use case: User fills out name, email and mobile phone number. *The system* sends a text message from an existing Twilio account/service.

    I have this working with Ninja Forms as they have the text messaging capability as part of their product. However, WPforms does not allow this.

    Any ideas?

    Many thanks in advance!

    • Bill Erickson says

      I haven’t tried to send SMS from a form, but the simple solution would be to connect your form to Zapier and use one of those services to send the SMS.

  4. Zeb says

    Thanks for this! It was super helpful and did exactly what I needed even better and easier than I was thinking of doing it, ha.

  5. Christi says

    Hi Bill, Thank you for the great information. I was wondering if you could take this a step further. What I need to do is execute an external program (PHP) that is triggered by the value in on of my form fields. That program then queries a separate database and passes values back to the form. In other words, I am wanting to prefill the form but the values vary. I am currently doing it pretty successfully with another plugin but it is no longer supported. Any ideas? I appreciate any insights.

  6. Jamie Glasspool says

    Hi Bill

    This is quite a general question. Do you have any tips for troubleshooting why this might not be working. I have a simple landing page up and running and am trying to get it to connect to a client’s API to send the form data. First time I’ve done it.

    I’ve tried adding your code above via a Code Snippets plugin and also I tried upgrading to WPForms elite level to be able to use their Webhooks option, but neither solution seems to be doing anything and I can’t see why.

    Kind regards,
    Jamie

    • Bill Erickson says

      I recommend using WPForms’ logging feature to diagnose the issue. Go to WPForms > Tools > Logs and enable logs.

      In your custom code, you can use the wpforms_log() function to trigger a log with any data you want. It’s a good idea to log the API responses you receive, and anywhere you might be exiting early due to an error / missing content. Here’s an example.