is_connected() ) { agentshop()->log( 'Cannot register webhooks - not connected', 'warning' ); return array(); } $options = agentshop()->get_options(); $secret = $options['webhook_secret'] ?? ''; if ( empty( $secret ) ) { agentshop()->log( 'Cannot register webhooks - no secret', 'warning' ); return array(); } $delivery_url = agentshop()->get_api_endpoint() . '/api/woocommerce/webhooks'; $results = array(); foreach ( self::TOPICS as $topic ) { $results[ $topic ] = $this->register_webhook( $topic, $delivery_url, $secret ); } agentshop()->log( 'Webhooks registered', 'info', $results ); return $results; } /** * Register single webhook. * * @param string $topic Topic. * @param string $delivery_url Delivery URL. * @param string $secret Secret. * @return array */ private function register_webhook( $topic, $delivery_url, $secret ) { $existing = $this->find_webhook( $topic ); if ( $existing ) { $existing->set_delivery_url( $delivery_url ); $existing->set_secret( $secret ); $existing->set_status( 'active' ); $existing->save(); return array( 'action' => 'updated', 'webhook_id' => $existing->get_id(), ); } $webhook = new \WC_Webhook(); $webhook->set_name( self::PREFIX . ucfirst( str_replace( '.', ' ', $topic ) ) ); $webhook->set_topic( $topic ); $webhook->set_delivery_url( $delivery_url ); $webhook->set_secret( $secret ); $webhook->set_status( 'active' ); $webhook->set_api_version( 'wp_api_v2' ); $webhook->save(); return array( 'action' => 'created', 'webhook_id' => $webhook->get_id(), ); } /** * Find webhook by topic. * * @param string $topic Topic. * @return \WC_Webhook|null */ private function find_webhook( $topic ) { $data_store = \WC_Data_Store::load( 'webhook' ); $webhook_ids = $data_store->get_webhooks_ids(); foreach ( $webhook_ids as $webhook_id ) { $webhook = wc_get_webhook( $webhook_id ); if ( ! $webhook ) { continue; } if ( strpos( $webhook->get_name(), self::PREFIX ) === 0 && $webhook->get_topic() === $topic ) { return $webhook; } } return null; } /** * Unregister all webhooks. * * @return int */ public function unregister_all() { $data_store = \WC_Data_Store::load( 'webhook' ); $webhook_ids = $data_store->get_webhooks_ids(); $removed = 0; foreach ( $webhook_ids as $webhook_id ) { $webhook = wc_get_webhook( $webhook_id ); if ( ! $webhook ) { continue; } if ( strpos( $webhook->get_name(), self::PREFIX ) === 0 ) { $webhook->delete( true ); $removed++; } } agentshop()->log( "Webhooks unregistered: {$removed}", 'info' ); return $removed; } /** * Verify webhooks are active. * * @return array */ public function verify_webhooks() { $status = array( 'registered' => array(), 'missing' => array(), 'invalid' => array(), ); foreach ( self::TOPICS as $topic ) { $webhook = $this->find_webhook( $topic ); if ( ! $webhook ) { $status['missing'][] = $topic; } elseif ( 'active' !== $webhook->get_status() ) { $status['invalid'][] = $topic; } else { $status['registered'][] = $topic; } } if ( ! empty( $status['missing'] ) || ! empty( $status['invalid'] ) ) { agentshop()->log( 'Re-registering webhooks', 'info', $status ); $this->register_all(); } return $status; } /** * Get webhook status for admin display. * * @return array */ public function get_status() { $webhooks = array(); foreach ( self::TOPICS as $topic ) { $webhook = $this->find_webhook( $topic ); $webhooks[ $topic ] = array( 'topic' => $topic, 'registered' => (bool) $webhook, 'status' => $webhook ? $webhook->get_status() : 'not_registered', 'id' => $webhook ? $webhook->get_id() : null, ); } return $webhooks; } /** * Add custom webhook events. * * @param array $events Events. * @return array */ public function add_custom_events( $events ) { return $events; } }