WooCommerce Webhook: invalid URL
Asked Answered
B

7

16

I am setting up WooCommerce to trigger a webhook upon order creation. I have set the webhook's URL as the url of a local web API we have setup for this purpose:

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

WooCommerce does trigger the webhook with the correct data payload, but the request is reported as failed in the webhook's logs:

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

which, translated from German, means "no valid URL was passed"

I then later changed the URL to a web-facing deployment of our API (https://xxx.azurewebsites.net/store/order/new), and the webhook was received without any problems by the API.

I am not sure if WC webhook's don't play nice with urls that have a custom port (in my case, port 3000), so I wanted to ask the question on whether this is true and if there is a way to make WC webhooks play nice with a localhost development environment.

Bast answered 7/8, 2015 at 10:22 Comment(0)
H
19

I solved it after inserting the following code at the end of the file: 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' );
Hally answered 28/5, 2021 at 12:27 Comment(2)
This should be the accepted answer since no modifications on wp core are needed and the filter "http_request_host_is_external" does not work for none default ports. Thank you FlavioMeldameldoh
This is the best answer for the reason given by @NikoHadouken above. I'd like to add that you shouldn't edit the functions.php that comes with your theme - rather use the plugin customiser tool from WooThemesRectocele
T
8

For WooCommerce version 3.3.5, Bjorn's solution doesn't seem to work.

In my case, I had to eddit the file wp-content/plugins/woocommerce/includes/class-wc-webhook.php:185, method deliver.

Comment the wp_safe_remote_request method, and instead, use the insecure http request method.

// 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 );
Trenttrento answered 29/4, 2018 at 2:39 Comment(0)
N
7

It is not the custom port, but localhost.

There is a check in wp-includes/http.php wp_http_validate_url() that rejects all kinds of local IPs unless specifically allowed with a filter on http_request_host_is_external that returns true...

Cheers, Björn

Nel answered 1/10, 2015 at 15:32 Comment(2)
awesome! you just made my day!Polyandrous
Really great, but there seems to be an issue with ports too. There's a check in that method: if ( 80 === $port || 443 === $port || 8080 === $port ), so it only supports common port numbers.Coxalgia
A
3

in the following function

/** * Validate a URL for safe use in the HTTP API. * * @since 3.5.2 * * @param string $url * @return false|string URL or false on failure. */

comment this line

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;
    }

and if you're using another port for example in laravel you have to add the port here

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;
}
Asuncionasunder answered 19/8, 2016 at 10:17 Comment(0)
S
0

If anyone is still looking for an answer to this, my solution was to make an A DNS record pointing to the server that receives the WebHook and then only allow internal traffic on the firewall.

Steps using DigitalOcean's VPC + Firewall and Cloudflare:

  1. Log in to CloudFlare, Create an A record pointing to the server's public IP
  2. On DigitalOcean's panel go to the firewall and only allow traffic from the origin server (or tag)
  3. Setup the webhook as usual on WooCommerce.

Felipe

Skillless answered 23/5, 2020 at 15:23 Comment(0)
B
0

What worked for me:

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

to

'reject_unsafe_urls'  => apply_filters( 'http_request_reject_unsafe_urls', true, $url ),
  1. In http.php, add your port in this line (I added port 3000 for this example)
if ( 80 === $port || 443 === $port || 8080 === $port || 3000 === $port ) {

Works in WooCommerce 4.2.2

Botryoidal answered 28/7, 2020 at 17:49 Comment(0)
S
0

Wordpress http request may be blocking certain ports and hosts. However, I can confirm that querying aganinst localhost:8080 would work.

On the other hand, you could also modify the http.php in order to extend the number of valid ports

Stealthy answered 19/2, 2021 at 11:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.