build_order_payload( $order, 'order_created' ); AIsoule_API::instance()->send_event( 'order_created', $payload ); } /** * Hook: Order status changed to processing. */ public function on_order_processing( $order_id, $order = null ) { $options = get_option( 'aisoule_whatsapp_settings', array() ); if ( empty( $options['notify_processing'] ) ) { return; } if ( ! $order && function_exists( 'wc_get_order' ) ) { $order = wc_get_order( $order_id ); } if ( ! $order ) { return; } $payload = $this->build_order_payload( $order, 'order_processing' ); AIsoule_API::instance()->send_event( 'order_processing', $payload ); } /** * Hook: Order status changed to completed. */ public function on_order_completed( $order_id, $order = null ) { $options = get_option( 'aisoule_whatsapp_settings', array() ); if ( empty( $options['notify_completed'] ) ) { return; } if ( ! $order && function_exists( 'wc_get_order' ) ) { $order = wc_get_order( $order_id ); } if ( ! $order ) { return; } $payload = $this->build_order_payload( $order, 'order_completed' ); AIsoule_API::instance()->send_event( 'order_completed', $payload ); } /** * Hook: Order status changed to cancelled. */ public function on_order_cancelled( $order_id, $order = null ) { $options = get_option( 'aisoule_whatsapp_settings', array() ); if ( empty( $options['notify_cancelled'] ) ) { return; } if ( ! $order && function_exists( 'wc_get_order' ) ) { $order = wc_get_order( $order_id ); } if ( ! $order ) { return; } $payload = $this->build_order_payload( $order, 'order_cancelled' ); AIsoule_API::instance()->send_event( 'order_cancelled', $payload ); } /** * Extract and serialize order data for AIsoule. */ private function build_order_payload( $order, $event_type ) { $items = array(); foreach ( $order->get_items() as $item_id => $item ) { $product = $item->get_product(); $items[] = array( 'id' => $item_id, 'name' => $item->get_name(), 'quantity' => $item->get_quantity(), 'subtotal' => $item->get_subtotal(), 'total' => $item->get_total(), 'sku' => $product ? $product->get_sku() : '', ); } $billing_phone = preg_replace( '/[^0-9+]/', '', $order->get_billing_phone() ); return array( 'event_type' => $event_type, 'order_id' => $order->get_id(), 'order_number' => $order->get_order_number(), 'status' => $order->get_status(), 'currency' => $order->get_currency(), 'total' => (float) $order->get_total(), 'shipping_total' => (float) $order->get_shipping_total(), 'discount_total' => (float) $order->get_discount_total(), 'payment_method' => $order->get_payment_method_title(), 'customer' => array( 'id' => $order->get_customer_id(), 'first_name' => $order->get_billing_first_name(), 'last_name' => $order->get_billing_last_name(), 'email' => $order->get_billing_email(), 'phone' => $billing_phone, 'city' => $order->get_billing_city(), 'country' => $order->get_billing_country(), ), 'items' => $items, 'checkout_url' => $order->get_checkout_order_received_url(), 'created_at' => $order->get_date_created() ? $order->get_date_created()->date( 'c' ) : gmdate( 'c' ), ); } /** * Enqueue checkout abandoned cart listener script. */ public function enqueue_checkout_scripts() { if ( ! function_exists( 'is_checkout' ) || ! is_checkout() ) { return; } $options = get_option( 'aisoule_whatsapp_settings', array() ); if ( empty( $options['abandoned_cart_enabled'] ) ) { return; } wp_enqueue_script( 'aisoule-checkout', AISOULE_PLUGIN_URL . 'assets/js/aisoule-checkout.js', array( 'jquery' ), AISOULE_VERSION, true ); wp_localize_script( 'aisoule-checkout', 'aisoule_vars', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'aisoule_checkout_nonce' ), ) ); } /** * AJAX endpoint to capture phone number on checkout blur. */ public function ajax_capture_cart() { check_ajax_referer( 'aisoule_checkout_nonce', 'nonce' ); $phone = isset( $_POST['phone'] ) ? sanitize_text_field( wp_unslash( $_POST['phone'] ) ) : ''; $email = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : ''; $name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : ''; if ( empty( $phone ) && empty( $email ) ) { wp_send_json_error( array( 'message' => 'No contact provided' ) ); } if ( function_exists( 'WC' ) && WC()->cart ) { $cart_items = array(); foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); $cart_items[] = array( 'product_id' => $cart_item['product_id'], 'name' => $_product ? $_product->get_name() : '', 'quantity' => $cart_item['quantity'], 'subtotal' => (float) $cart_item['line_subtotal'], ); } $payload = array( 'customer' => array( 'phone' => preg_replace( '/[^0-9+]/', '', $phone ), 'email' => $email, 'name' => $name, ), 'cart_total' => (float) WC()->cart->total, 'items' => $cart_items, 'recovery_url'=> wc_get_checkout_url(), ); AIsoule_API::instance()->send_event( 'abandoned_cart', $payload ); } wp_send_json_success( array( 'status' => 'captured' ) ); } }