Sure, there is a way to solve this.
You need to save the submitted data into a transient and access it from the redirected page where you can confirm the visitor has actually filled in the form. No need for a private page, but rather use a custom page template to view your restricted page and check if the user has access rights at the top of the page template, else redirect them.
You can do this by,
Step 1: identify the current submission (this works even for non-logged in users.) using a WP nonce as a hidden field in your form, as well as place a js script to redirect to your page once a successful submission event is fired using an anonymous function hooked on the cf7 do_shortcode_tag
display filter,
add_filter('wpcf7_form_hidden_fields','add_hidden_nonce');
function add_hidden_nonce($fields){
$nonce = wp_create_nonce('cf7-redirect-id');
$fields['redirect_nonce'] = $nonce;
/*
hook the shortcode tag filter using an anonymous function
in order to use the same nonce and place a redirect js event
script at the end of the form.
*/
add_filter('do_shortcode_tag', function($output, $tag, $attrs) use ($nonce){
//check this is your form, assuming form id = 1, replace it with your id.
if($tag != "contact-form-7" || $attrs['id']!= 1) return $output;
$script = '<script>'.PHP_EOL;
$script .= 'document.addEventListener( "wpcf7mailsent", function( event ){'.PHP_EOL;
//add your redirect page url with the nonce as an attribute.
$script .= ' location = "http://example.com/submitted/?cf7="'.$nonce.';'.PHP_EOL;
$script .= ' }'.PHP_EOL;
$script .= '</script>'.PHP_EOL;
return $output.PHP_EOL.$script;
},10,3);
return $fields;
}
Step 2: hook the cf7 action 'wpcf7_mail_sent' once the submission has passed the validation/and email is sent.
add_action('wpcf7_mail_sent', 'save_posted_data_into_transient');
function save_posted_data_into_transient(){
if(isset($_POST['redirect_nonce'])){ //save the data.
//save the posted data from the form. Note if you have submitted file fields you will also need to store the $_FILES array.
set_transient('_cf7_data_'.$_POST['redirect_nonce'], $_POST, 5*60); //5 min expiration.
}
}
Step 3: on your redirect custom page, you can now access your stored transient data, place this at the top of your custom page template,
<?php
if( isset($_GET['cf7']) ){
$transient = '_cf7_data_'.$_GET['cf7'];
$data = get_transient($transient);
//$data['my-text-field']....
}
?>
if the transient is missing, invalid, or the cf7 nonce attribute is missing, then simply redirect to a page informing the user they have to fill in the form to access the page.