Webhook de WooCommerce: URL no válida

4 minutos de lectura

Estoy configurando WooCommerce para activar un webhook al crear el pedido. Configuré la URL del webhook como la URL de una API web local que configuramos para este propósito:

http://localhost:3000/store/orders/new

WooCommerce activa el webhook con la carga de datos correcta, pero la solicitud se informa como fallida en los registros del webhook:

Status: HTTP http_request_failed Es wurde keine gültige URL übermittelt.: Array

que, traducido del alemán, significa “no se pasó ninguna URL válida”

Luego cambié la URL a una implementación orientada a la web de nuestra API (https://xxx.azurewebsites.net/store/order/new), y la API recibió el webhook sin problemas.

No estoy seguro de si los webhooks de WC no funcionan bien con las URL que tienen un puerto personalizado (en mi caso, el puerto 3000), así que quería preguntar si esto es cierto y si hay una manera de hacer webhooks de WC. Juega bien con un entorno de desarrollo localhost.

Para la versión 3.3.5 de WooCommerce, la solución de Bjorn no parece funcionar.

En mi caso, tuve que editar el archivo. wp-content/plugins/woocommerce/includes/class-wc-webhook.php:185método deliver.

Comenta el wp_safe_remote_request y, en su lugar, utilice el método de solicitud http inseguro.

// Webhook away!
$http_call = _wp_http_get_object();
$response = $http_call->request( $this->get_delivery_url(), $http_args );
//$response = wp_safe_remote_request( $this->get_delivery_url(), $http_args );

No es el puerto personalizado, sino localhost.

Hay una comprobación en wp-includes/http.php wp_http_validate_url() que rechaza todo tipo de direcciones IP locales a menos que se permita específicamente con un filtro en http_request_host_is_external que devuelve verdadero…

Saludos, Bjorn

  • ¡increíble! ¡Usted acaba de hacer mi día!

    – GETah

    6 de diciembre de 2015 a las 13:19

  • Realmente genial, pero parece que también hay un problema con los puertos. Hay un cheque en ese método: if ( 80 === $port || 443 === $port || 8080 === $port )por lo que solo admite números de puerto comunes.

    – Aron Lorincz

    06/07/2016 a las 20:05


Lo resolví después de insertar el siguiente código al final del archivo: wp-content/themes/MYTHEME/functions.php

function allow_unsafe_urls ( $args ) {
       $args['reject_unsafe_urls'] = false;
       return $args;
    } ;

add_filter( 'http_request_args', 'allow_unsafe_urls' );

  • Esta debería ser la respuesta aceptada, ya que no se necesitan modificaciones en el núcleo de wp y el filtro “http_request_host_is_external” no funciona para ninguno de los puertos predeterminados. gracias flavio

    – Niko Hadouken

    21 de noviembre de 2021 a las 18:47


  • Esta es la mejor respuesta por el motivo dado por @NikoHadouken arriba. Me gustaría añadir que no deberías editar el functions.php que viene con su tema, en su lugar use el herramienta de personalización de complementos de WooThemes

    –Tian van Heerden

    2 de febrero a las 10:07


en la siguiente funcion

/** * Validar una URL para un uso seguro en la API HTTP. * * @since 3.5.2 * * @param string $url * @return false|string URL o false en caso de falla. */

comenta esta linea

if ( isset( $parsed_home['host'] ) ) {
        //$same_host = ( strtolower( $parsed_home['host'] ) === strtolower( $parsed_url['host'] ) || 'localhost' === strtolower( $parsed_url['host'] ) );
        $same_host = false;
    } else {
        $same_host = false;
    }

y si está utilizando otro puerto, por ejemplo, en laravel, debe agregar el puerto aquí

if ( empty( $parsed_url['port'] ) )
        return $url;

    $port = $parsed_url['port'];
    if ( 80 === $port || 443 === $port || 8080 === $port || 8000 === $port )
        return $url;

    if ( $parsed_home && $same_host && isset( $parsed_home['port'] ) && $parsed_home['port'] === $port )
        return $url;

    return false;
}

Si alguien todavía está buscando una respuesta a esto, mi solución fue crear un registro A DNS que apunte al servidor que recibe el WebHook y luego solo permitir el tráfico interno en el firewall.

Pasos usando VPC + Firewall de DigitalOcean y Cloudflare:

  1. Inicie sesión en CloudFlare, cree un registro A que apunte a la IP pública del servidor
  2. En el panel de DigitalOcean, vaya al firewall y solo permita el tráfico desde el servidor de origen (o etiqueta)
  3. Configure el webhook como de costumbre en WooCommerce.

felipe

Lo que funcionó para mí:

  1. En class-http.php, cambia
'reject_unsafe_urls'  => apply_filters( 'http_request_reject_unsafe_urls', false, $url ),

a

'reject_unsafe_urls'  => apply_filters( 'http_request_reject_unsafe_urls', true, $url ),
  1. En http.php, agregue su puerto en esta línea (agregué el puerto 3000 para este ejemplo)
if ( 80 === $port || 443 === $port || 8080 === $port || 3000 === $port ) {

Funciona en WooCommerce 4.2.2

avatar de usuario
alberto s.

La solicitud http de WordPress puede estar bloqueando ciertos puertos y hosts. Sin embargo, puedo confirmar que consultar contra localhost:8080 trabajaría.

Por otro lado, también podrías modificar el http.php para ampliar el número de puertos válidos

¿Ha sido útil esta solución?