diff --git a/SoftLayer/CLI/server/detail.py b/SoftLayer/CLI/server/detail.py
index 61eeb43e..943b694b 100644
--- a/SoftLayer/CLI/server/detail.py
+++ b/SoftLayer/CLI/server/detail.py
@@ -35,7 +35,7 @@ def cli(env, identifier, passwords, price):
     result = utils.NestedDict(result)
 
     table.add_row(['id', result['id']])
-    table.add_row(['guid', result['globalIdentifier']] or formatting.blank())
+    table.add_row(['guid', result['globalIdentifier'] or formatting.blank()])
     table.add_row(['hostname', result['hostname']])
     table.add_row(['domain', result['domain']])
     table.add_row(['fqdn', result['fullyQualifiedDomainName']])
diff --git a/SoftLayer/managers/hardware.py b/SoftLayer/managers/hardware.py
index 1a1e350f..70aea1ec 100644
--- a/SoftLayer/managers/hardware.py
+++ b/SoftLayer/managers/hardware.py
@@ -47,51 +47,22 @@ def cancel_hardware(self, hardware_id, reason='unneeded', comment='',
         :param string comment: An optional comment to include with the
                                cancellation.
         """
-        # Check to see if this is actually a pre-configured server (BMC). They
-        # require a different cancellation call.
-        server = self.get_hardware(hardware_id,
-                                   mask='id,bareMetalInstanceFlag')
-
-        if server.get('bareMetalInstanceFlag'):
-            return self.cancel_metal(hardware_id, immediate)
 
+        # Get cancel reason
         reasons = self.get_cancellation_reasons()
-        cancel_reason = reasons['unneeded']
-
-        if reason in reasons:
-            cancel_reason = reasons[reason]
-
-        # Arguments per SLDN:
-        # attachmentId - Hardware ID
-        # Reason
-        # content - Comment about the cancellation
-        # cancelAssociatedItems
-        # attachmentType - Only option is HARDWARE
-        return self.client['Ticket'].createCancelServerTicket(hardware_id,
-                                                              cancel_reason,
-                                                              comment,
-                                                              True,
-                                                              'HARDWARE')
-
-    def cancel_metal(self, hardware_id, immediate=False):
-        """Cancels the specified bare metal instance.
-
-        :param int id: The ID of the bare metal instance to be cancelled.
-        :param bool immediate: If true, the bare metal instance will be
-                               cancelled immediately. Otherwise, it will be
-                               scheduled to cancel on the anniversary date.
-        """
+        cancel_reason = reasons.get(reason, reasons['unneeded'])
+
         hw_billing = self.get_hardware(hardware_id,
                                        mask='mask[id, billingItem.id]')
+        if 'billingItem' not in hw_billing:
+            raise SoftLayer.SoftLayerError(
+                "No billing item found for hardware")
 
         billing_id = hw_billing['billingItem']['id']
 
-        billing_item = self.client['Billing_Item']
-
-        if immediate:
-            return billing_item.cancelService(id=billing_id)
-        else:
-            return billing_item.cancelServiceOnAnniversaryDate(id=billing_id)
+        return self.client.call('Billing_Item', 'cancelItem',
+                                immediate, False, cancel_reason, comment,
+                                id=billing_id)
 
     def list_hardware(self, tags=None, cpus=None, memory=None, hostname=None,
                       domain=None, datacenter=None, nic_speed=None,

problem with hourly bare metal servers immediate cancelation in CLI and manager
slcli server cancel --immediate <server id> does not produce an error, but cancels server on its monthly anniversary. The cause of the problem is "old" logic in cancel_hardware method of harware.py. In SL API 4.0 harware.py place_order now only supports the fast server provisioning package (see version 4 notes: #469), but cancel_hardware is still looking for a 'bareMetalInstanceFlag'  and using Billing_Item cancelService. It should use Billing_Item cancelItem instead 
 
diff --git a/SoftLayer/tests/managers/hardware_tests.py b/SoftLayer/tests/managers/hardware_tests.py
index 283598c9..79aa5025 100644
--- a/SoftLayer/tests/managers/hardware_tests.py
+++ b/SoftLayer/tests/managers/hardware_tests.py
@@ -243,57 +243,53 @@ def test_place_order(self, create_dict):
         self.assert_called_with('SoftLayer_Product_Order', 'placeOrder',
                                 args=({'test': 1, 'verify': 1},))
 
-    def test_cancel_metal_immediately(self):
-
-        result = self.hardware.cancel_metal(6327, immediate=True)
-
-        self.assertEqual(result, True)
-        self.assert_called_with('SoftLayer_Billing_Item', 'cancelService',
-                                identifier=6327)
-
-    def test_cancel_metal_on_anniversary(self):
-
-        result = self.hardware.cancel_metal(6327, False)
-
-        self.assertEqual(result, True)
-        self.assert_called_with('SoftLayer_Billing_Item',
-                                'cancelServiceOnAnniversaryDate',
-                                identifier=6327)
-
     def test_cancel_hardware_without_reason(self):
         mock = self.set_mock('SoftLayer_Hardware_Server', 'getObject')
-        mock.return_value = {'id': 987, 'bareMetalInstanceFlag': False}
+        mock.return_value = {'id': 987, 'billingItem': {'id': 1234}}
 
         result = self.hardware.cancel_hardware(987)
 
-        self.assertEqual(result,
-                         fixtures.SoftLayer_Ticket.createCancelServerTicket)
+        self.assertEqual(result, True)
         reasons = self.hardware.get_cancellation_reasons()
-        args = (987, reasons['unneeded'], '', True, 'HARDWARE')
-        self.assert_called_with('SoftLayer_Ticket', 'createCancelServerTicket',
+        args = (False, False, reasons['unneeded'], '')
+        self.assert_called_with('SoftLayer_Billing_Item', 'cancelItem',
+                                identifier=1234,
                                 args=args)
 
     def test_cancel_hardware_with_reason_and_comment(self):
         mock = self.set_mock('SoftLayer_Hardware_Server', 'getObject')
-        mock.return_value = {'id': 987, 'bareMetalInstanceFlag': False}
+        mock.return_value = {'id': 987, 'billingItem': {'id': 1234}}
 
-        result = self.hardware.cancel_hardware(987, 'sales', 'Test Comment')
+        result = self.hardware.cancel_hardware(6327,
+                                               reason='sales',
+                                               comment='Test Comment')
 
-        self.assertEqual(result,
-                         fixtures.SoftLayer_Ticket.createCancelServerTicket)
+        self.assertEqual(result, True)
         reasons = self.hardware.get_cancellation_reasons()
-        args = (987, reasons['sales'], 'Test Comment', True, 'HARDWARE')
-        self.assert_called_with('SoftLayer_Ticket', 'createCancelServerTicket',
+        args = (False, False, reasons['sales'], 'Test Comment')
+        self.assert_called_with('SoftLayer_Billing_Item', 'cancelItem',
+                                identifier=1234,
                                 args=args)
 
-    def test_cancel_hardware_on_bmc(self):
+    def test_cancel_hardware(self):
 
         result = self.hardware.cancel_hardware(6327)
 
         self.assertEqual(result, True)
         self.assert_called_with('SoftLayer_Billing_Item',
-                                'cancelServiceOnAnniversaryDate',
-                                identifier=6327)
+                                'cancelItem',
+                                identifier=6327,
+                                args=(False, False, 'No longer needed', ''))
+
+    def test_cancel_hardware_no_billing_item(self):
+        mock = self.set_mock('SoftLayer_Hardware_Server', 'getObject')
+        mock.return_value = {'id': 987}
+
+        ex = self.assertRaises(SoftLayer.SoftLayerError,
+                               self.hardware.cancel_hardware,
+                               6327)
+        self.assertEqual("No billing item found for hardware",
+                         str(ex))
 
     def test_change_port_speed_public(self):
         self.hardware.change_port_speed(2, True, 100)

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gcc
3.6
tools/test-requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
attrs==22.2.0
Babel==2.11.0
certifi==2021.5.30
charset-normalizer==2.0.12
click==8.0.4
coverage==6.2
distlib==0.3.9
docutils==0.18.1
filelock==3.4.1
fixtures==4.0.1
idna==3.10
imagesize==1.4.1
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig==1.1.1
Jinja2==3.0.3
MarkupSafe==2.0.1
mock==5.2.0
nose==1.3.7
packaging==21.3
pbr==6.1.1
platformdirs==2.4.0
pluggy==1.0.0
prettytable==2.5.0
py==1.11.0
Pygments==2.14.0
pyparsing==3.1.4
pytest==7.0.1
pytz==2025.2
requests==2.27.1
six==1.17.0
snowballstemmer==2.2.0
-e git+https://github.com/softlayer/softlayer-python.git@200787d4c3bf37bc4e701caf6a52e24dd07d18a3#egg=SoftLayer
Sphinx==5.3.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
testtools==2.6.0
toml==0.10.2
tomli==1.2.3
tox==3.28.0
typing_extensions==4.1.1
urllib3==1.26.20
virtualenv==20.17.1
wcwidth==0.2.13
zipp==3.6.0

name: softlayer-python
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - attrs==22.2.0
      - babel==2.11.0
      - charset-normalizer==2.0.12
      - click==8.0.4
      - coverage==6.2
      - distlib==0.3.9
      - docutils==0.18.1
      - filelock==3.4.1
      - fixtures==4.0.1
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - jinja2==3.0.3
      - markupsafe==2.0.1
      - mock==5.2.0
      - nose==1.3.7
      - packaging==21.3
      - pbr==6.1.1
      - platformdirs==2.4.0
      - pluggy==1.0.0
      - prettytable==2.5.0
      - py==1.11.0
      - pygments==2.14.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytz==2025.2
      - requests==2.27.1
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sphinx==5.3.0
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - testtools==2.6.0
      - toml==0.10.2
      - tomli==1.2.3
      - tox==3.28.0
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - virtualenv==20.17.1
      - wcwidth==0.2.13
      - zipp==3.6.0
prefix: /opt/conda/envs/softlayer-python

SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_cancel_hardware SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_cancel_hardware_no_billing_item SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_cancel_hardware_with_reason_and_comment SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_cancel_hardware_without_reason
SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_change_port_speed_private SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_change_port_speed_public SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_edit SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_edit_blank SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_edit_meta SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_generate_create_dict SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_generate_create_dict_invalid_size SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_generate_create_dict_no_items SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_generate_create_dict_no_regions SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_get_create_options SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_get_create_options_package_missing SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_get_hardware SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_init_with_ordering_manager SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_list_hardware SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_list_hardware_with_filters SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_place_order SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_reload SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_rescue SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_resolve_ids_hostname SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_resolve_ids_ip SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_update_firmware SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_update_firmware_selective SoftLayer/tests/managers/hardware_tests.py::HardwareTests::test_verify_order SoftLayer/tests/managers/hardware_tests.py::HardwareHelperTests::test_get_bandwidth_price_id_no_items SoftLayer/tests/managers/hardware_tests.py::HardwareHelperTests::test_get_default_price_id_item_not_first SoftLayer/tests/managers/hardware_tests.py::HardwareHelperTests::test_get_default_price_id_no_items SoftLayer/tests/managers/hardware_tests.py::HardwareHelperTests::test_get_extra_price_id_no_items SoftLayer/tests/managers/hardware_tests.py::HardwareHelperTests::test_get_os_price_id_no_items SoftLayer/tests/managers/hardware_tests.py::HardwareHelperTests::test_get_port_speed_price_id_no_items
SoftLayer/CLI/server/detail.py SoftLayer/managers/hardware.py
SoftLayer/CLI/server/detail.py SoftLayer/managers/hardware.py