From d3914d7c707b322f3a8df16bd9229a905d5084a9 Mon Sep 17 00:00:00 2001 From: Ian Chamba <86791147+ianchamba@users.noreply.github.com> Date: Tue, 3 Mar 2026 17:16:23 -0300 Subject: [PATCH] fix: update webhook endpoints to api.nfse.io/v2 - Rename 'hooks' to 'webhooks' in APIResource objectBaseURI mapping - Override endpointAPI() in NFe_Webhook to use https://api.nfse.io/v2/webhooks instead of the deprecated api.nfe.io/v1/hooks endpoint - Override CRUD methods to handle v2 response structure where webhook data is wrapped in "webHook" (camelCase singular) instead of "webhooks" - Update WebhookTest.php to use v2 response properties (uri instead of url) - Webhook methods remain simple (no company scope needed) API v2 response example: {"webHook": {"id": "...", "uri": "...", "secret": "...", "status": "Active"}} Co-Authored-By: Claude Opus 4.6 --- lib/NFe/APIResource.php | 2 +- lib/NFe/Webhook.php | 123 +++++++++++++++++++++++++++++++++++---- test/NFe/WebhookTest.php | 19 +++--- 3 files changed, 122 insertions(+), 22 deletions(-) diff --git a/lib/NFe/APIResource.php b/lib/NFe/APIResource.php index 7bb5237..6cae668 100755 --- a/lib/NFe/APIResource.php +++ b/lib/NFe/APIResource.php @@ -23,7 +23,7 @@ public static function objectBaseURI() { case 'service_invoice': return 'serviceInvoices'; case 'webhook': - return 'hooks'; + return 'webhooks'; default: return $object_type . 's'; } diff --git a/lib/NFe/Webhook.php b/lib/NFe/Webhook.php index e138e1f..451f45c 100644 --- a/lib/NFe/Webhook.php +++ b/lib/NFe/Webhook.php @@ -1,27 +1,128 @@ $key) ) { + return $response->$key; + } + return $response; + } + public static function create( $attributes = array() ) { - return self::createAPI($attributes); + $response = self::API()->request( 'POST', self::endpointAPI( $attributes ), $attributes ); + return self::createFromResponse( self::extractFromResponse($response) ); } - public static function fetch( $key ) { - return self::fetchAPI($key); + public static function fetch( $key ) { + try { + $response = self::API()->request( 'GET', static::endpointAPI($key) ); + return self::createFromResponse( self::extractFromResponse($response) ); + } + catch ( NFeObjectNotFound $e ) { + throw new NFeObjectNotFound( self::convertClassToObjectType() . ': não encontrado.'); + } } - public function save() { - return $this->saveAPI(); + public static function search( $options = array() ) { + try { + $response = self::API()->request( 'GET', static::endpointAPI($options), $options ); + return self::createFromResponse( self::extractFromResponse($response) ); + } + catch (Exception $e) {} + return array(); } - public function delete() { - return $this->deleteAPI(); + public function save() { + try { + $response = self::API()->request( $this->is_new() ? 'POST' : 'PUT', static::endpointAPI($this), $this->getAttributes() ); + $new_object = self::createFromResponse( self::extractFromResponse($response) ); + + $this->copy( $new_object ); + $this->resetStates(); + + if ( isset($response->errors) ) { + throw new NFeException(); + } + } + catch (Exception $e) { + return false; + } + return true; } - public function refresh() { - return $this->refreshAPI(); + public function delete() { + try { + $response = self::API()->request( 'DELETE', static::endpointAPI($this) ); + if ( isset($response->errors) ) { + throw new NFeException(); + } + } + catch (Exception $e) { + return false; + } + return true; } - public static function search( $options = array() ) { - return self::searchAPI($options); + public function refresh() { + if ( $this->is_new() ) { + return false; + } + + try { + $response = self::API()->request( 'GET', static::endpointAPI($this) ); + if ( isset($response->errors) ) { + throw new NFeObjectNotFound(); + } + + $new_object = self::createFromResponse( self::extractFromResponse($response) ); + $this->copy( $new_object ); + $this->resetStates(); + } + catch (Exception $e) { + return false; + } + return true; } } diff --git a/test/NFe/WebhookTest.php b/test/NFe/WebhookTest.php index 5a95574..066f0a6 100644 --- a/test/NFe/WebhookTest.php +++ b/test/NFe/WebhookTest.php @@ -16,37 +16,37 @@ public function testCreateAndDelete() { $object = NFe_Webhook::create( $attributes ); $this->assertNotNull($object); - $this->assertNotNull($object->hooks->url); - $this->assertEqual($object->hooks->url, $attributes['url']); + $this->assertNotNull($object->uri); + $this->assertEqual($object->uri, $attributes['url']); - self::$id = $object->hooks->id; + self::$id = $object->id; } public function testGet() { $object = NFe_Webhook::fetch( self::$id ); $this->assertNotNull( $object ); - $this->assertNotNull( $object['hooks'][0]->url ); - $this->assertEqual( $object['hooks'][0]->url, 'http://google.com/test' ); + $this->assertNotNull( $object->uri ); + $this->assertEqual( $object->uri, 'http://google.com/test' ); } public function testUpdate() { $object = NFe_Webhook::fetch( self::$id ); $new_url = 'http://google.com/test2'; - $object->hooks->url = $new_url; + $object->uri = $new_url; $this->assertTrue($object->save()); $this->assertNotNull($object); - $this->assertNotNull($object->hooks->url); - $this->assertEqual($object->hooks->url, $new_url); + $this->assertNotNull($object->uri); + $this->assertEqual($object->uri, $new_url); } public function testDelete() { $object = NFe_Webhook::fetch( self::$id ); $this->assertNotNull($object); - $this->assertNotNull( $object->hooks->url ); + $this->assertNotNull( $object->uri ); $this->assertTrue($object->delete()); } @@ -54,6 +54,5 @@ public function testSearch() { $hooks = NFe_Webhook::search(); $this->assertNotNull( $hooks ); - $this->assertNotNull( $hooks->hooks ); } }