4

So I am setting up a webhook with the Xero API and it expects a blank response with no cookies and gzip etc. I cannot seem to work out how to send a completely blank response.

Here's an example of my response from ngrok:

HTTP/1.1 401 Unauthorized
Server: nginx/1.13.3
Date: Wed, 12 Dec 2018 02:11:07 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive

0

Here's the code that executes the HTTP response:

http_response_code(401);
exit;

I've also tried this:

return response(null, 401);

But in the webhook setup panel it shows me this error:

Intent To Receive required
Last attempt at 2018-12-12 02:15:57 UTC
Failed to respond in timely manner

Despite the response time being <0.5s. I've sent a bunch of screen recordings to Xero but their support seem to think it will work.

Callum
  • 1,136
  • 3
  • 17
  • 43

1 Answers1

2

As the error says It seems in your code you are unable to respond in time (5s). refer this Failed to respond in timely manner issue . I also faced this issue while develop Xero integration using laravel. was able to fix this issue using queues, if hash matches I dispatch the Xero event to the job otherwise return 400.because the event is processing in the queue it will return the response in a timely manner.

use App\Jobs\XeroWebhook;
public function getUpdatedInvoiceInXero(Request $request)
{
    $paylod = file_get_contents('php://input');
    $events = json_decode($request->getContent())->events;
    $XeroWebhookKey= "your_webhook_key";
    $Hash = base64_encode(hash_hmac('sha256', $paylod, $XeroWebhookKey, true));

    if ($Hash === $_SERVER['HTTP_X_XERO_SIGNATURE']) {
        XeroWebhook::dispatch($events);
    } else {
        return response(null, 401);
    }
}

As you can see here I only check hash matching, I have included other functionalities in a job called "XeroWebhook". Laravel queues

namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class XeroWebhook implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    protected $events;
    public function __construct($events, $tenantId)
    {
        $this->events = $events;
    }

    public function handle()
    {
      // rest of the code
    }
}
gaga
  • 63
  • 1
  • 14