is_available(); } public function is_active(): bool { return $this->is_available() && $this->is_enabled(); } public function boot(): void { Agentmatica_WooCommerce_Cart::init(); Agentmatica_WooCommerce_Orders::init(); } /** * @return array> */ public function get_abilities(): array { $abilities = array( self::CART_ADD => array( 'name' => self::CART_ADD, 'label' => __( 'Add item to chat cart', 'agentmatica-mcp-connector' ), 'description' => __( 'Create or update a guest cart for an Agentmatica chat session.', 'agentmatica-mcp-connector' ), 'input_schema' => array( 'type' => 'object', 'properties' => array( 'session_key' => array( 'type' => 'string', 'description' => 'Stable chat conversation id from Agentmatica.', ), 'product_id' => array( 'type' => 'integer', 'description' => 'WooCommerce product id.', 'minimum' => 1, ), 'quantity' => array( 'type' => 'integer', 'description' => 'Quantity to add.', 'default' => 1, 'minimum' => 1, ), 'variation_id' => array( 'type' => 'integer', 'description' => 'Optional WooCommerce variation id for sized variable products.', 'minimum' => 1, ), ), 'required' => array( 'session_key', 'product_id' ), ), 'callback' => array( Agentmatica_WooCommerce_Cart::class, 'add_item' ), 'readonly' => false, 'idempotent' => false, ), self::CHECKOUT_URL => array( 'name' => self::CHECKOUT_URL, 'label' => __( 'Get chat checkout URL', 'agentmatica-mcp-connector' ), 'description' => __( 'Return a checkout link for the current chat cart session.', 'agentmatica-mcp-connector' ), 'input_schema' => array( 'type' => 'object', 'properties' => array( 'session_key' => array( 'type' => 'string', 'description' => 'Stable chat conversation id from Agentmatica.', ), ), 'required' => array( 'session_key' ), ), 'callback' => array( Agentmatica_WooCommerce_Cart::class, 'checkout_url' ), 'readonly' => true, 'idempotent' => true, ), self::CUSTOMER_VERIFY => array( 'name' => self::CUSTOMER_VERIFY, 'label' => __( 'Verify customer for order lookup', 'agentmatica-mcp-connector' ), 'description' => __( 'Verify order number + billing email and bind this chat session.', 'agentmatica-mcp-connector' ), 'input_schema' => array( 'type' => 'object', 'properties' => array( 'session_key' => array( 'type' => 'string', 'description' => 'Stable chat conversation id from Agentmatica.', ), 'order_number' => array( 'type' => 'string', 'description' => 'WooCommerce order number.', ), 'email' => array( 'type' => 'string', 'description' => 'Billing email for the order.', ), ), 'required' => array( 'session_key', 'order_number', 'email' ), ), 'callback' => array( Agentmatica_WooCommerce_Orders::class, 'customer_verify' ), 'readonly' => true, 'idempotent' => false, ), self::ORDERS_LIST => array( 'name' => self::ORDERS_LIST, 'label' => __( 'List verified customer orders', 'agentmatica-mcp-connector' ), 'description' => __( 'Return recent orders for a verified chat session.', 'agentmatica-mcp-connector' ), 'input_schema' => array( 'type' => 'object', 'properties' => array( 'session_key' => array( 'type' => 'string', 'description' => 'Stable chat conversation id from Agentmatica.', ), ), 'required' => array( 'session_key' ), ), 'callback' => array( Agentmatica_WooCommerce_Orders::class, 'orders_list' ), 'readonly' => true, 'idempotent' => true, ), self::ORDER_GET => array( 'name' => self::ORDER_GET, 'label' => __( 'Get verified customer order', 'agentmatica-mcp-connector' ), 'description' => __( 'Return order details for a verified chat session.', 'agentmatica-mcp-connector' ), 'input_schema' => array( 'type' => 'object', 'properties' => array( 'session_key' => array( 'type' => 'string', 'description' => 'Stable chat conversation id from Agentmatica.', ), 'order_number' => array( 'type' => 'string', 'description' => 'WooCommerce order number.', ), ), 'required' => array( 'session_key', 'order_number' ), ), 'callback' => array( Agentmatica_WooCommerce_Orders::class, 'order_get' ), 'readonly' => true, 'idempotent' => true, ), self::CUSTOMER_TOKEN_VERIFY => array( 'name' => self::CUSTOMER_TOKEN_VERIFY, 'label' => __( 'Verify logged-in customer token', 'agentmatica-mcp-connector' ), 'description' => __( 'Validate a short-lived customer token from the storefront.', 'agentmatica-mcp-connector' ), 'input_schema' => array( 'type' => 'object', 'properties' => array( 'session_key' => array( 'type' => 'string', 'description' => 'Stable chat conversation id from Agentmatica.', ), 'customer_token' => array( 'type' => 'string', 'description' => 'Signed customer token from the storefront.', ), ), 'required' => array( 'session_key', 'customer_token' ), ), 'callback' => array( __CLASS__, 'verify_customer_token' ), 'readonly' => true, 'idempotent' => true, ), ); if ( Agentmatica_Ability_Delegation::should_register_fallback_catalog() ) { $abilities = array( self::PRODUCTS_LIST => array( 'name' => self::PRODUCTS_LIST, 'label' => __( 'List storefront products', 'agentmatica-mcp-connector' ), 'description' => __( 'Read-only catalog listing for visitor chat.', 'agentmatica-mcp-connector' ), 'input_schema' => array( 'type' => 'object', 'properties' => array( 'per_page' => array( 'type' => 'integer', 'description' => 'Number of products to return (1-50).', 'default' => 20, 'minimum' => 1, 'maximum' => 50, ), 'page' => array( 'type' => 'integer', 'description' => 'Page number.', 'default' => 1, 'minimum' => 1, ), 'status' => array( 'type' => 'string', 'description' => 'Product status filter.', 'default' => 'publish', 'enum' => array( 'publish' ), ), 'search' => array( 'type' => 'string', 'description' => 'Optional product search term.', ), ), ), 'callback' => array( Agentmatica_WooCommerce_Catalog::class, 'list_products' ), 'readonly' => true, 'idempotent' => true, ), ) + $abilities; } return $abilities; } /** * @param array|null $input * @return array */ public static function verify_customer_token( $input = null ): array { $input = is_array( $input ) ? $input : array(); $session_key = Agentmatica_WooCommerce_Cart::sanitize_session_key( (string) ( $input['session_key'] ?? '' ) ); $token = trim( (string) ( $input['customer_token'] ?? '' ) ); if ( $session_key === '' || $token === '' ) { return array( 'success' => false, 'message' => __( 'session_key and customer_token are required.', 'agentmatica-mcp-connector' ), ); } $claims = Agentmatica_Customer_Token::verify_token( $token ); if ( $claims === null ) { return array( 'success' => false, 'message' => __( 'Invalid or expired customer token.', 'agentmatica-mcp-connector' ), ); } $claim_session = Agentmatica_WooCommerce_Cart::sanitize_session_key( (string) ( $claims['session_key'] ?? '' ) ); if ( $claim_session === '' || $claim_session !== $session_key ) { return array( 'success' => false, 'message' => __( 'Customer token does not match this chat session.', 'agentmatica-mcp-connector' ), ); } return Agentmatica_WooCommerce_Orders::bind_logged_in_customer( array( 'session_key' => $session_key, 'wp_user_id' => (int) ( $claims['wp_user_id'] ?? 0 ), ) ); } }