Como crear endpoints personalizados para WooCommerce en PHP en WordPress

Contents

Introducción

En este artículo encontrarás un tutorial completo y detallado para crear endpoints personalizados en WooCommerce usando PHP. Cubriremos dos enfoques principales: añadir endpoints en la sección Mi cuenta (endpoints de tipo página/URL) y crear endpoints REST (para integraciones, AJAX y APIs). Incluye ejemplos listos para usar, consideraciones de seguridad, buenas prácticas, pruebas y cómo desplegar correctamente en producción.

Requisitos previos

  • WordPress actualizado.
  • WooCommerce activo.
  • Acceso para crear un plugin o editar un plugin hijo / functions.php de tu theme (se recomienda crear un plugin propio para mantener el código separado).
  • Permisos de administrador para activar el plugin y refrescar permalinks si hace falta.

¿Qué tipo de endpoint necesitas?

Antes de comenzar, decide qué necesitas:

  • Endpoint en Mi cuenta: una URL accesible dentro de la cuenta de usuario (p. ej. /mi-cuenta/mi-endpoint/) que muestra contenido HTML y se integra con el menú de WooCommerce.
  • Endpoint REST: ruta en la API REST de WordPress (p. ej. /wp-json/mi-plugin/v1/…) para retornar JSON, usado por aplicaciones, AJAX o clientes externos.

Estructura recomendada: crear un plugin básico

Vamos a usar un plugin simple como contenedor. El siguiente ejemplo incluye la estructura mínima y el manejo de flush_rewrite_rules en la activación/desactivación.


Crear un endpoint en Mi cuenta (WooCommerce)

Pasos principales:

  1. Registrar un rewrite endpoint con add_rewrite_endpoint.
  2. Añadir la query var correspondiente para que WP la reconozca.
  3. Añadir el item en el menú de Mi cuenta.
  4. Definir la acción para mostrar el contenido (hook específico de WooCommerce).
  5. Refrescar permalinks (flush_rewrite_rules).

Código completo para Mi cuenta

Este bloque contiene la implementación completa y auto-contenida para agregar un endpoint en Mi Cuenta con contenido básico.

 label ) {
        if ( key === customer-logout ) {
            new_items[mi-endpoint] = __( Mi Endpoint, text-domain )
        }
        new_items[ key ] = label
    }
    return new_items
}

/
  Contenido del endpoint.
  Nota: la acción es woocommerce_account_{endpoint}_endpoint
 /
function wcce_account_endpoint_content() {
    // Puedes obtener información del usuario actual
    user_id = get_current_user_id()
    if ( ! user_id ) {
        echo 

. esc_html__( Debes estar logueado para ver esta página., text-domain ) .

return } // Ejemplo: obtener 5 últimos pedidos del usuario args = array( customer_id => user_id, limit => 5, orderby => date, order => DESC, ) orders = wc_get_orders( args ) echo

. esc_html__( Tus últimos pedidos, text-domain ) .

if ( empty( orders ) ) { echo

. esc_html__( No se encontraron pedidos., text-domain ) .

return } echo
    foreach ( orders as order ) { order_id = order->get_id() date = wc_format_datetime( order->get_date_created() ) total = order->get_formatted_order_total() printf(
  • %s — %s — %s
  • , esc_html( sprintf( __( Pedido #%d, text-domain ), order_id ) ), esc_html( date ), wp_kses_post( total ) ) } echo
} ?>

Después de activar el plugin, ve a Ajustes > Enlaces permanentes y guarda para refrescar las reglas de reescritura (si no usas la activación que ya llama flush_rewrite_rules).

Crear endpoints REST personalizados

Los endpoints REST son ideales para integrar con frontends JavaScript, aplicaciones móviles o servicios externos. Se registran con register_rest_route dentro de rest_api_init. Asegúrate de implementar permission_callback para seguridad.

Ejemplo: Endpoint REST para obtener pedidos del usuario actual

Ruta: /wp-json/mi-plugin/v1/my-orders

 GET,
                callback            => wcce_rest_get_my_orders,
                permission_callback => wcce_rest_permission_logged_in,
            ),
        )
    )

    // Ejemplo POST seguro: añadir una nota al pedido (solo si eres propietario del pedido)
    register_rest_route(
        mi-plugin/v1,
        /orders/(?Pd )/add-note,
        array(
            methods             => POST,
            callback            => wcce_rest_add_order_note,
            permission_callback => wcce_rest_permission_can_modify_order,
            args                => array(
                note => array(
                    required => true,
                    sanitize_callback => sanitize_text_field,
                ),
            ),
        )
    )
}

function wcce_rest_permission_logged_in() {
    return is_user_logged_in()
}

function wcce_rest_get_my_orders( WP_REST_Request request ) {
    user_id = get_current_user_id()
    args = array(
        customer_id => user_id,
        limit       => 20,
        orderby     => date,
        order       => DESC,
    )

    orders = wc_get_orders( args )
    data = array()

    foreach ( orders as order ) {
        data[] = array(
            id       => order->get_id(),
            status   => order->get_status(),
            total    => order->get_total(),
            currency => order->get_currency(),
            date     => order->get_date_created()->date_i18n( get_option( date_format ) .  H:i ),
        )
    }

    return rest_ensure_response( data )
}

function wcce_rest_permission_can_modify_order( WP_REST_Request request ) {
    order_id = (int) request->get_param( id )
    order = wc_get_order( order_id )
    if ( ! order ) {
        return new WP_Error( no_order, Pedido no encontrado, array( status => 404 ) )
    }

    user_id = get_current_user_id()
    // Permitir si es admin o si el pedido pertenece al usuario actual
    if ( current_user_can( manage_woocommerce ) ) {
        return true
    }

    if ( (int) order->get_user_id() === user_id ) {
        return true
    }

    return new WP_Error( rest_forbidden, No tienes permiso para modificar este pedido, array( status => 403 ) )
}

function wcce_rest_add_order_note( WP_REST_Request request ) {
    order_id = (int) request->get_param( id )
    note = request->get_param( note )

    order = wc_get_order( order_id )
    if ( ! order ) {
        return new WP_Error( no_order, Pedido no encontrado, array( status => 404 ) )
    }

    // Añadir nota privada al pedido
    order->add_order_note( sanitize_text_field( note ), false )

    return rest_ensure_response( array( success => true, order_id => order_id ) )
}
?>

Control de acceso y seguridad

  • permission_callback: Siempre valida quién puede acceder a tu endpoint REST. No confíes solo en is_user_logged_in para acciones sensibles.
  • Validación y saneamiento: Usa sanitize_text_field, absint, esc_sql, wp_kses, o funciones específicas según el tipo de dato y contexto.
  • Comprobar propiedad de recursos: Al modificar pedidos, verifica que el current_user sea el propietario o tenga capacidad administrativa (p. ej. edit_shop_orders o manage_woocommerce).
  • Nonces y CSRF: Para peticiones desde el frontend en el mismo sitio (AJAX), utiliza wp_create_nonce y wp_verify_nonce cuando proceda.
  • Respuestas REST: Devuelve objetos WP_REST_Response o errores con WP_Error y códigos HTTP adecuados.

Buenas prácticas y rendimiento

  • Limita la cantidad de elementos por petición (paginación) para evitar consultas pesadas.
  • Implementa caché cuando sea posible (transients, cache HTTP, control de cabeceras).
  • Usa capacidades correctas para endpoints que modifican datos.
  • Versiona tu API (p. ej. mi-plugin/v1) para permitir cambios no rompientes en el futuro.
  • Evita exponer información sensible en respuestas JSON.

Ejemplo avanzado: Endpoint que devuelve productos relacionados con stock bajo

Route: /wp-json/mi-plugin/v1/low-stock-products

 GET,
            callback            => wcce_get_low_stock_products,
            permission_callback => function() { return current_user_can( manage_woocommerce ) }, // solo admin / manager
            args                => array(
                limit => array(
                    required => false,
                    default  => 20,
                    sanitize_callback => absint
                ),
            ),
        )
    )
})

function wcce_get_low_stock_products( WP_REST_Request request ) {
    limit = request->get_param( limit )
    limit = limit ? limit : 20

    args = array(
        status => publish,
        limit  => limit,
        stock_status => instock,
        orderby => date,
    )

    // Usamos wc_get_products con meta_query para stock bajo
    products = wc_get_products( array(
        limit => limit,
        status => publish,
        meta_query => array(
            array(
                key => _stock,
                value => 5,        // ejemplo: stock <= 5
                compare => <=,
                type => NUMERIC
            ),
        ),
    ) )

    data = array()
    foreach ( products as product ) {
        data[] = array(
            id    => product->get_id(),
            name  => product->get_name(),
            stock => product->get_stock_quantity(),
        )
    }

    return rest_ensure_response( data )
}
?>

Pruebas y depuración

  • Usa Postman o curl para probar tus endpoints REST. Ejemplo curl:
    curl -X GET https://tusitio.com/wp-json/mi-plugin/v1/my-orders -b cookie.txt
        
  • Para endpoints privados, incluye cookies de sesión o usa autenticación básica / JWT si procede.
  • Activa WP_DEBUG y revisa el log de errores para detectar problemas.
  • Para endpoints Mi cuenta, revisa que las reglas de reescritura funcionen (Ajustes > Enlaces permanentes > Guardar cambios).

Tabla comparativa rápida

Tipo Uso típico Formato Autenticación
Endpoint Mi Cuenta Contenido HTML para usuario en su panel HTML Sesión del usuario (WP login)
Endpoint REST Integraciones, AJAX, móviles JSON Nonces, cookies, tokens, permission_callback

Despliegue y mantenimiento

  • Versiona tu plugin y mantén cambios documentados.
  • Antes de lanzar a producción, prueba con datos reales o en un entorno staging.
  • Monitorea uso y errores (logs, Sentry, etc.) y aplica límites de uso si recibes tráfico masivo.

Conclusión

Crear endpoints personalizados para WooCommerce es una forma poderosa de extender la funcionalidad y personalizar la experiencia del usuario o exponer capacidades a aplicaciones externas. Con los ejemplos mostrados tienes plantillas claras para implementar endpoints en Mi cuenta y rutas REST seguras y escalables. Mantén siempre la validación, las comprobaciones de permisos y la limitación de recursos para garantizar la seguridad y rendimiento del sitio.



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *