orderBuilder = $orderBuilder; $this->activityLog = $activityLog; } public function registerRoutes(): void { register_rest_route( self::NAMESPACE, '/orders', [ 'methods' => 'POST', 'callback' => [ $this, 'create' ], 'permission_callback' => [ $this, 'authorize' ], ] ); register_rest_route( self::NAMESPACE, '/orders', [ 'methods' => 'GET', 'callback' => [ $this, 'lookup' ], 'permission_callback' => [ $this, 'authorize' ], 'args' => [ 'pos_order_id' => [ 'required' => true ], ], ] ); } public function authorize(): bool { return current_user_can( 'manage_woocommerce' ); } /** * GET /orders?pos_order_id=X — lets akantio_pos check whether an order * for this POS sale already exists before attempting to push one, so a * broken local sync record doesn't keep creating duplicates in * WooCommerce (POST /orders is idempotent by itself too, see * OrderBuilder::build(), but this lets the caller skip the push * entirely and just reconcile its own state). */ public function lookup( WP_REST_Request $request ) { $posOrderId = (string) $request->get_param( 'pos_order_id' ); if ( '' === $posOrderId ) { return new WP_Error( 'akantio_woo_missing_pos_order_id', 'pos_order_id is required.', [ 'status' => 400 ] ); } $order = $this->orderBuilder->findExistingByPosOrderId( $posOrderId ); if ( null === $order ) { return new WP_Error( 'akantio_woo_order_not_found', 'No order found for this pos_order_id.', [ 'status' => 404 ] ); } return new WP_REST_Response( [ 'id' => $order->get_id(), 'order_number' => $order->get_order_number(), 'status' => $order->get_status(), ], 200 ); } public function create( WP_REST_Request $request ) { $data = $request->get_json_params(); if ( ! is_array( $data ) ) { return new WP_Error( 'akantio_woo_invalid_body', 'Request body must be a JSON object.', [ 'status' => 400 ] ); } try { $payload = OrderPayload::fromArray( $data ); } catch ( InvalidArgumentException $e ) { return new WP_Error( 'akantio_woo_invalid_payload', $e->getMessage(), [ 'status' => 400 ] ); } try { $order = $this->orderBuilder->build( $payload ); } catch ( ProductNotFoundException $e ) { return new WP_Error( 'akantio_woo_product_not_found', $e->getMessage(), [ 'status' => 422 ] ); } catch ( RuntimeException $e ) { return new WP_Error( 'akantio_woo_order_creation_failed', $e->getMessage(), [ 'status' => 500 ] ); } $this->activityLog->record( 'order_created', [ 'pos_order_id' => $payload->posOrderId(), 'woo_order_id' => $order->get_id(), ] ); return new WP_REST_Response( [ 'id' => $order->get_id(), 'order_number' => $order->get_order_number(), 'status' => $order->get_status(), ], 201 ); } }