2 Update using the admin_post_(action) hook
source | link

---- UPDATE ----

If you prefer use $_POST without AJAX, you can use the hook admin_post_(action)

HTML example:

<form action="<?php echo admin_url('admin-post.php'); ?>" method="post">
  <input type="hidden" name="action" value="my_process_form">
  <input type="text" name="name">
  <input type="email" name="email">
  <input type="submit" value="Submit">
</form>

PHP Example:

add_action( 'admin_post_my_process_form', 'my_process_form' );

function my_process_form() {
    // The process_form.php code here
}

---- UPDATE ----

If you prefer use $_POST without AJAX, you can use the hook admin_post_(action)

HTML example:

<form action="<?php echo admin_url('admin-post.php'); ?>" method="post">
  <input type="hidden" name="action" value="my_process_form">
  <input type="text" name="name">
  <input type="email" name="email">
  <input type="submit" value="Submit">
</form>

PHP Example:

add_action( 'admin_post_my_process_form', 'my_process_form' );

function my_process_form() {
    // The process_form.php code here
}
1
source | link

I believe you're using ajax refering the process_form.php. However the right way to access any ajax is through the wp-admin/admin-ajax.php.

Pull all your code from process_form.php to a function (can be added on your main plugin file):

function my_process_form() {
    //...code from process_form.php
    if ( ! $error ) { //your error boolean
        return wp_json_success(); //recommend for return an success as JSON
    } else {
        return wp_json_error(); //recommend for return an error as JSON
    }
}

Than, add a hook to the ajax action, like so:

//You can choose one of those or leave both:
add_action( 'wp_ajax_my_process_form', 'my_process_form' ); //Only logged users
add_action( 'wp_ajax_nopriv_my_process_form', 'my_process_form' ); //Not logged users

In Javascript, you must call the url wp-admin/admin-ajax.php with the parameter you hooked, in this case my_proccess_form:

PHP calling JS and send the admin-ajax.php URL:

wp_enqueue_script( 'my-custom-script', plugins_url( '/js/my_custom.js', __FILE__ ), array('jquery') );

wp_localize_script(
    'my-custom-script', //JS referenced above
    'ajax_object', //Javascript Object
    array(
        'ajax_url' => admin_url( 'admin-ajax.php' ) //Same as wp-admin/admin.ajax.php
    )
);

I'll send you an example using jQuery for the AJAX request:

jQuery.ajax({
     type : "post",
     dataType : "json", //Example only
     url : ajax_object.ajax_url, //From wp_localize_script
     data : { //can use jQuery.serialize() as well
         action: "my_process_form", //used on wp_ajax_(action) and wp_ajax_nopriv_(action)
         post_id : 1, //Dummy id, more parameters, use comma
         nonce: nonce //Read https://codex.wordpress.org/Function_Reference/wp_create_nonce
     },
     success: function( response ) {
         if( response.success ) {
             //Success JS Process
         } else {
             alert("Error");
             console.log( response );
         }
     }
});

Referencies

https://codex.wordpress.org/AJAX_in_Plugins https://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_(action) https://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_nopriv_(action) https://codex.wordpress.org/Function_Reference/wp_localize_script