// Postpone Order Completed Email Hook
add_action( 'woocommerce_init', function() {
$email_class = WC()->mailer();
$removed = remove_action( 'woocommerce_order_status_completed_notification',
array( $email_class->emails['WC_Email_Customer_Completed_Order'], 'trigger' ) );
if( $removed ) {
add_action( 'woocommerce_order_status_completed_notification',
array( $email_class->emails['WC_Email_Customer_Completed_Order'], 'trigger' ), 20 );
}
} );
// Order Completed Hook
add_action( 'woocommerce_order_status_completed', function( $order_id ) {
// Get Order Data
global $wpdb;
$order = wc_get_order( $order_id );
// Loop Order Items
foreach( $order->get_items() as $order_item ) {
// Get Line Item Data
$order_item_data = $order_item->get_data();
// Skip Line Items Missing Product, Variation
if(
empty( $order_item_data['product_id'] )
|| empty( $order_item_data['variation_id'] )
) {
continue;
}
// Skip Line Items Missing Downloadable Product Variation
$product_variation = wc_get_product(
$order_item_data['variation_id']
);
if( ! $product_variation->is_downloadable() ) {
continue;
}
// Skip Line Items Missing Consultation Package Attribute
$product_attributes = $product_variation->get_attributes();
if( empty( $product_attributes['consultation-package'] ) ) {
continue;
}
// Get Calendly User ID
$product = wc_get_product( $order_item_data['product_id'] );
$user_id = $product->get_meta( 'user_id' );
if( ! $user_id ) {
$message = 'Error: Unable to find Consultant User ID.';
$order->add_order_note( $message );
return;
}
// Get Calendly Token
$calendly_url = 'https://api.calendly.com';
$calendly_token = get_user_meta( $user_id, 'calendly_token', true );
if( ! $calendly_token ) {
$message = 'Error: Unable to find Consultant Calendly Token.';
$order->add_order_note( $message );
return;
}
// Get User's URI
$args = [
'headers' => [
'Authorization' => 'Bearer ' . $calendly_token,
'Content-Type' => 'application/json',
],
];
$response = wp_remote_get( $calendly_url . '/users/me', $args );
$response_body = wp_remote_retrieve_body( $response );
$response_body = json_decode( $response_body );
$user_uri = isset( $response_body->resource->uri )
? $response_body->resource->uri : '';
if( ! $user_uri ) {
wc_get_logger()->debug( wc_print_r( [ $args, $response_body ], true ) );
$message = 'Calendly error: Unable to find user - see debug log.';
$order->add_order_note( $message );
return;
}
// Get User's Event Types
$args = [
'body' => [ 'user' => $user_uri ],
'headers' => [
'Authorization' => 'Bearer ' . $calendly_token,
'Content-Type' => 'application/json',
],
];
$response = wp_remote_get( $calendly_url . '/event_types', $args );
$response_body = wp_remote_retrieve_body( $response );
$response_body = json_decode( $response_body );
$event_type_uri = '';
foreach( (array) $response_body->collection as $event_type ) {
if( $event_type->name === $product_attributes['consultation-package'] ) {
$event_type_uri = isset( $event_type->uri )
? $event_type->uri : '';
}
}
if( ! $event_type_uri ) {
wc_get_logger()->debug( wc_print_r( [ $args, $response_body ], true ) );
$message = 'Calendly error: Unable to match Event Type - see debug log.';
$order->add_order_note( $message );
return;
}
// Get One Time Link
$args = [
'body' => [
'max_event_count' => 1,
'owner' => $event_type_uri,
'owner_type' => 'EventType',
],
'headers' => [
'Authorization' => 'Bearer ' . $calendly_token,
'Content-Type' => 'application/x-www-form-urlencoded',
],
];
$response = wp_remote_post( $calendly_url . '/scheduling_links', $args );
$response_body = wp_remote_retrieve_body( $response );
$response_body = json_decode( $response_body );
$booking_url = isset( $response_body->resource->booking_url )
? $response_body->resource->booking_url : '';
if( ! $booking_url ) {
wc_get_logger()->debug( wc_print_r( [ $args, $response_body ], true ) );
$message = 'Calendly error: Unable to retrieve Booking URL.';
$order->add_order_note( $message );
return;
}
// Add Order Note
$message = sprintf(
'Assigned consultation package Booking URL %s',
$booking_url,
);
$order->add_order_note( $message );
// Add Line Item Meta
wc_update_order_item_meta(
$order_item->get_id(),
'Booking URL',
$booking_url
);
} // End Order Items Loop
} );
Calendly bookings logic on order completed
Share this:
Uses a product-to-user_id association, Calendly API token from WP user meta, and a product variation attribute for Calendly Event Type to generate unique booking URL at Thank You page, receipts, etc. specific to the selected variation.
Instructions for Calendly bookings logic on order completed
- Log into a staging or locally hosted clone of your site.
- Install and activate Code Snippets plugin.
- WP Admin > Snippets > Add New
- Copy and paste the code from the section above.
- Check to ensure formatting came over properly.
- Customize the code as desired.
- Add a meaningful title.
- Select whether to run on front-end or back-end (or both).
- Click “Save and Activate”.
- Test your site to ensure it works.
- Disable if any problems, or recover.
- Repeat for live environment.
Need help modifying Calendly bookings logic on order completed?
Contact me. I can help with fitting projects or refer to my partner.
License
All code snippets are licensed GPLv2 (or later) matching WordPress licensing.
Except when otherwise stated in writing the copyright holders and/or other parties provide the program as-is without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose.
Disclaimer of warranty