Booking form

/**
* ============================================================
* INFINITELYCLEAR — BOOKING / SCHEDULING FORM (no plugin)
* ============================================================
* WHERE: WP Admin → Code Snippets → Add New (PHP snippet)
* Paste this WHOLE file → Save → Activate.
*
* WHAT IT GIVES YOU
* 1. A shortcode:

Book a Session

Choose your time with Kat

Pick the container, a preferred date, and a window that suits your day. Kat personally confirms the exact time within 24 hours — real back-and-forth, no apps, no accounts.

1 · Your container

2 · Preferred date

3 · Time window

4 · Your name

5 · Email

6 · Your time zone (e.g. Pacific — Los Angeles)

Anything Kat should know? (optional)

You'll choose payment on the next step. Kat confirms your exact time by email within 24 hours, and you can reschedule with 24 hours' notice.  ·  Prefer email? infinitelyclearshop@gmail.com


* Create a page “Book a Session” (slug: book-a-session),
* set Template = Default, add a “Shortcode” block with
*

Book a Session

Choose your time with Kat

Pick the container, a preferred date, and a window that suits your day. Kat personally confirms the exact time within 24 hours — real back-and-forth, no apps, no accounts.

1 · Your container

2 · Preferred date

3 · Time window

4 · Your name

5 · Email

6 · Your time zone (e.g. Pacific — Los Angeles)

Anything Kat should know? (optional)

You'll choose payment on the next step. Kat confirms your exact time by email within 24 hours, and you can reschedule with 24 hours' notice.  ·  Prefer email? infinitelyclearshop@gmail.com

→ Publish.
* 2. A branded scheduling form: package picker (pre-selected
* from the link, e.g. /book-a-session/?package=deep-dive),
* preferred date + time window, contact details, notes.
* 3. On submit it:
* • emails the request to Kat,
* • adds the chosen package to the WooCommerce cart,
* • sends the customer straight to Checkout to pay.
* (If WooCommerce is off, it just shows a thank-you.)
*
* BUTTON LINKS FOR THE MENTORING PAGE
* /book-a-session/?package=lets-chat (Let’s Chat · $33)
* /book-a-session/?package=deep-dive (Deep-Dive · $97)
* /book-a-session/?package=mastermind (Mastermind · $297)
*
* CHANGE WHERE REQUESTS ARE EMAILED: edit ICBK_NOTIFY_EMAIL below.
* ============================================================
*/

if ( ! defined( ‘ABSPATH’ ) ) { exit; }

/* —- SETTINGS ———————————————— */
define( ‘ICBK_NOTIFY_EMAIL’, ‘infinitelyclearshop@gmail.com’ ); // Kat’s inbox

/* —- PACKAGE MAP (slug → Woo product ID) ——————— */
function icbk_packages() {
return array(
‘lets-chat’ => array(
‘id’ => 652,
‘name’ => “Let’s Chat”,
‘meta’ => ’15 minutes · one focused question’,
‘price’ => 33,
),
‘deep-dive’ => array(
‘id’ => 656,
‘name’ => ‘Deep-Dive Session’,
‘meta’ => ’45 minutes · one stuck place, opened up’,
‘price’ => 97,
‘tag’ => ‘Most popular’,
),
‘mastermind’ => array(
‘id’ => 657,
‘name’ => ‘Monthly Mastermind’,
‘meta’ => ‘Ongoing monthly container with Kat’,
‘price’ => 297,
),
);
}

/* —- SHORTCODE ———————————————— */
add_shortcode( ‘ic_booking_form’, ‘icbk_render_form’ );
function icbk_render_form() {

$packages = icbk_packages();

/* pre-select from ?package=… (accepts slug or product ID) */
$pre = isset( $_GET[‘package’] ) ? sanitize_key( wp_unslash( $_GET[‘package’] ) ) : ”;
if ( $pre && ! isset( $packages[ $pre ] ) ) {
foreach ( $packages as $slug => $p ) {
if ( (string) $p[‘id’] === $pre ) { $pre = $slug; break; }
}
}
if ( ! isset( $packages[ $pre ] ) ) { $pre = ‘deep-dive’; }

$min_date = gmdate( ‘Y-m-d’, strtotime( ‘+1 day’ ) );
$booked = isset( $_GET[‘icbk’] ) && ‘thanks’ === $_GET[‘icbk’];

/* ———- confirmation state ———- */
if ( $booked ) {
return ‘

✓

Request received.

Kat has your session request and will reply within 24 hours to
confirm the exact time. If your checkout is still open, completing payment
locks your session in.

Go to Checkout

‘ . icbk_css();
}

/* ———- form ———- */
$out = ‘

‘;
$out .= ‘

Book a Session

‘;
$out .= ‘

Choose your time with Kat

‘;
$out .= ‘

Pick the container, a preferred date, and a window that suits
your day. Kat personally confirms the exact time within 24 hours — real
back-and-forth, no apps, no accounts.

‘;

$out .= ‘

‘;
$out .= ‘‘;
$out .= wp_nonce_field( ‘icbk_submit’, ‘icbk_nonce’, true, false );
$out .= ‘‘;

/* package tiles */
$out .= ‘

1 · Your container

‘;
foreach ( $packages as $slug => $p ) {
$checked = checked( $slug, $pre, false );
$tag = isset( $p[‘tag’] ) ? ‘‘ . esc_html( $p[‘tag’] ) . ‘‘ : ”;
$out .= ‘‘;
}
$out .= ‘

‘;

/* date + time window */
$out .= ‘

‘;
$out .= ‘

2 · Preferred date

‘;
$out .= ‘

3 · Time window

‘;
$out .= ‘

‘;

$out .= ‘

‘;
$out .= ‘

4 · Your name

‘;
$out .= ‘

5 · Email

‘;
$out .= ‘

‘;

$out .= ‘

6 · Your time zone (e.g. Pacific — Los Angeles)

‘;

$out .= ‘

Anything Kat should know? (optional)

‘;

$out .= ‘‘;
$out .= ‘

You’ll choose payment on the next step. Kat confirms your
exact time by email within 24 hours, and you can reschedule with 24 hours’ notice.

‘;
$out .= ‘

‘;

return $out . icbk_css();
}

/* —- STYLE —————————————————- */
function icbk_css() {
return “

“;
}

/* —- HANDLE SUBMIT ——————————————– */
add_action( ‘admin_post_ic_booking’, ‘icbk_handle’ );
add_action( ‘admin_post_nopriv_ic_booking’, ‘icbk_handle’ );
function icbk_handle() {

$back = home_url( ‘/book-a-session/’ );

/* honeypot: bots fill this */
if ( ! empty( $_POST[‘icbk_website’] ) ) {
wp_safe_redirect( add_query_arg( ‘icbk’, ‘thanks’, $back ) );
exit;
}
if ( ! isset( $_POST[‘icbk_nonce’] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[‘icbk_nonce’] ) ), ‘icbk_submit’ ) ) {
wp_safe_redirect( $back );
exit;
}

$packages = icbk_packages();
$slug = isset( $_POST[‘icbk_package’] ) ? sanitize_key( wp_unslash( $_POST[‘icbk_package’] ) ) : ”;
if ( ! isset( $packages[ $slug ] ) ) { $slug = ‘deep-dive’; }
$p = $packages[ $slug ];

$name = isset( $_POST[‘icbk_name’] ) ? sanitize_text_field( wp_unslash( $_POST[‘icbk_name’] ) ) : ”;
$email = isset( $_POST[‘icbk_email’] ) ? sanitize_email( wp_unslash( $_POST[‘icbk_email’] ) ) : ”;
$date = isset( $_POST[‘icbk_date’] ) ? sanitize_text_field( wp_unslash( $_POST[‘icbk_date’] ) ) : ”;
$win = isset( $_POST[‘icbk_window’] ) ? sanitize_text_field( wp_unslash( $_POST[‘icbk_window’] ) ) : ”;
$tz = isset( $_POST[‘icbk_tz’] ) ? sanitize_text_field( wp_unslash( $_POST[‘icbk_tz’] ) ) : ”;
$notes = isset( $_POST[‘icbk_notes’] ) ? sanitize_textarea_field( wp_unslash( $_POST[‘icbk_notes’] ) ) : ”;

if ( ! $name || ! is_email( $email ) || ! $date ) {
wp_safe_redirect( $back );
exit;
}

/* 1 · email the request to Kat */
$to = ICBK_NOTIFY_EMAIL;
$subject = ‘New session request — ‘ . $p[‘name’] . ‘ — ‘ . $name;
$body = “NEW SESSION REQUEST\n”
. str_repeat( ‘=’, 46 ) . “\n\n”
. ‘Container: ‘ . $p[‘name’] . ” ($” . number_format( $p[‘price’] ) . “)\n”
. ‘Preferred: ‘ . $date . ‘ · ‘ . $win . “\n”
. ‘Time zone: ‘ . ( $tz ? $tz : ‘not given’ ) . “\n\n”
. ‘Name: ‘ . $name . “\n”
. ‘Email: ‘ . $email . “\n\n”
. ‘Notes: ‘ . ( $notes ? $notes : ‘—’ ) . “\n\n”
. str_repeat( ‘-‘, 46 ) . “\n”
. ‘Reply directly to this email to confirm the time.’;
$headers = array( ‘Reply-To: ‘ . $name . ‘ <' . $email . '>‘ );
wp_mail( $to, $subject, $body, $headers );

/* 2 · gentle confirmation to the client */
$conf = “Hi ” . $name . “,\n\n”
. “Your request for a ” . $p[‘name’] . ” has landed with Kat.\n”
. “Preferred: ” . $date . ” · ” . $win . ( $tz ? ” (” . $tz . “)” : ” ) . “\n\n”
. “Kat will reply within 24 hours to confirm your exact time.\n”
. “Next step: complete checkout to lock your session in:\n”
. home_url( ‘/checkout/?add-to-cart=’ . $p[‘id’] ) . “\n\n”
. “— InfinitelyClear”;
wp_mail( $email, ‘Your session request — ‘ . $p[‘name’], $conf );

/* 3 · add to cart → checkout */
if ( function_exists( ‘WC’ ) && WC()->cart && wc_get_product( $p[‘id’] ) && wc_get_product( $p[‘id’] )->is_purchasable() ) {
WC()->cart->empty_cart();
WC()->cart->add_to_cart( $p[‘id’], 1 );
wp_safe_redirect( wc_get_checkout_url() );
exit;
}

/* Woo missing/unpurchasable → thank-you state */
wp_safe_redirect( add_query_arg( ‘icbk’, ‘thanks’, $back ) );
exit;
}