Use WordPress’ generic POST/GET handler wp-admin/admin-post.php
Don’t let the name confuse you – it accepts both GET/POST, and just like admin-ajax.php
it accepts both authorised (admin) and non-authorised (public) requests.
function wpse_406199_custom_action() {
// Do something!
// Maybe redirect back to where they came from?
wp_redirect( wp_get_referer() );
exit;
}
// Non-logged-in requests
add_action( 'admin_post_nopriv_wpse_406199_custom_action', 'wpse_406199_custom_action' );
// Logged-in requests
add_action( 'admin_post_wpse_406199_custom_action', 'wpse_406199_custom_action' );
And to get the URL:
$action_url = admin_url( 'admin-post.php?action=wpse_406199_custom_action' );