diff --git a/Cargo.lock b/Cargo.lock
index 96d388f7610f7bb05c0d5798ca38ffcc75a146a2..d98e9e2fc95a25280d9145a68e7318638febf5fa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -840,6 +840,7 @@ dependencies = [
  "pallet-xcm-benchmarks",
  "pallet-xcm-bridge-hub-router",
  "parachains-common",
+ "parachains-runtimes-test-utils",
  "parity-scale-codec",
  "polkadot-parachain-primitives",
  "polkadot-runtime-common",
@@ -973,6 +974,7 @@ dependencies = [
  "pallet-xcm-benchmarks",
  "pallet-xcm-bridge-hub-router",
  "parachains-common",
+ "parachains-runtimes-test-utils",
  "parity-scale-codec",
  "polkadot-parachain-primitives",
  "polkadot-runtime-common",
@@ -1013,6 +1015,7 @@ dependencies = [
  "frame-support",
  "frame-system",
  "hex-literal",
+ "pallet-asset-conversion",
  "pallet-assets",
  "pallet-balances",
  "pallet-collator-selection",
@@ -1030,6 +1033,7 @@ dependencies = [
  "staging-xcm-builder",
  "staging-xcm-executor",
  "substrate-wasm-builder",
+ "xcm-runtime-apis",
 ]
 
 [[package]]
@@ -2101,6 +2105,7 @@ dependencies = [
  "pallet-xcm-benchmarks",
  "pallet-xcm-bridge-hub",
  "parachains-common",
+ "parachains-runtimes-test-utils",
  "parity-scale-codec",
  "polkadot-parachain-primitives",
  "polkadot-runtime-common",
@@ -2294,6 +2299,7 @@ dependencies = [
  "pallet-xcm-benchmarks",
  "pallet-xcm-bridge-hub",
  "parachains-common",
+ "parachains-runtimes-test-utils",
  "parity-scale-codec",
  "polkadot-parachain-primitives",
  "polkadot-runtime-common",
@@ -2942,6 +2948,7 @@ dependencies = [
  "pallet-utility",
  "pallet-xcm",
  "parachains-common",
+ "parachains-runtimes-test-utils",
  "parity-scale-codec",
  "polkadot-parachain-primitives",
  "polkadot-runtime-common",
@@ -3312,6 +3319,7 @@ dependencies = [
  "pallet-xcm",
  "pallet-xcm-benchmarks",
  "parachains-common",
+ "parachains-runtimes-test-utils",
  "parity-scale-codec",
  "polkadot-parachain-primitives",
  "polkadot-runtime-common",
@@ -3408,6 +3416,7 @@ dependencies = [
  "pallet-xcm",
  "pallet-xcm-benchmarks",
  "parachains-common",
+ "parachains-runtimes-test-utils",
  "parity-scale-codec",
  "polkadot-parachain-primitives",
  "polkadot-runtime-common",
@@ -12244,6 +12253,7 @@ dependencies = [
  "pallet-session",
  "pallet-timestamp",
  "pallet-xcm",
+ "parachains-common",
  "parity-scale-codec",
  "polkadot-parachain-primitives",
  "sp-consensus-aura",
@@ -12255,6 +12265,7 @@ dependencies = [
  "staging-xcm",
  "staging-xcm-executor",
  "substrate-wasm-builder",
+ "xcm-runtime-apis",
 ]
 
 [[package]]
@@ -12608,6 +12619,7 @@ dependencies = [
  "pallet-xcm",
  "pallet-xcm-benchmarks",
  "parachains-common",
+ "parachains-runtimes-test-utils",
  "parity-scale-codec",
  "polkadot-parachain-primitives",
  "polkadot-runtime-common",
@@ -12708,6 +12720,7 @@ dependencies = [
  "pallet-xcm",
  "pallet-xcm-benchmarks",
  "parachains-common",
+ "parachains-runtimes-test-utils",
  "parity-scale-codec",
  "polkadot-parachain-primitives",
  "polkadot-runtime-common",
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml
index 0df799aa968dad635f91258195077a95c9807467..9a467de6ff88dfd9afb07efee0b09a2382ec9374 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml
@@ -89,7 +89,8 @@ bp-bridge-hub-westend.workspace = true
 snowbridge-router-primitives.workspace = true
 
 [dev-dependencies]
-asset-test-utils = { default-features = true, path = "../test-utils" }
+asset-test-utils = { workspace = true, default-features = true }
+parachains-runtimes-test-utils = { workspace = true, default-features = true }
 
 [build-dependencies]
 substrate-wasm-builder = { optional = true, workspace = true, default-features = true }
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
index c481b9bb7fd6e8b59a8b453703cb5c56097ab9e7..6f27eb6ed3ba90e94c188e5560fabee7d9a65a30 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
@@ -1334,37 +1334,31 @@ impl_runtime_apis! {
 			// We accept the native token to pay fees.
 			let mut acceptable_assets = vec![AssetId(native_token.clone())];
 			// We also accept all assets in a pool with the native token.
-			let assets_in_pool_with_native = assets_common::get_assets_in_pool_with::<
-				Runtime,
-				xcm::v4::Location
-			>(&native_token).map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?.into_iter();
-			acceptable_assets.extend(assets_in_pool_with_native);
+			acceptable_assets.extend(
+				assets_common::PoolAdapter::<Runtime>::get_assets_in_pool_with(native_token)
+				.map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?
+			);
 			PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
 		}
 
 		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
 			let native_asset = xcm_config::TokenLocation::get();
 			let fee_in_native = WeightToFee::weight_to_fee(&weight);
-			match asset.try_as::<AssetId>() {
+			let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
+			match latest_asset_id {
 				Ok(asset_id) if asset_id.0 == native_asset => {
 					// for native token
 					Ok(fee_in_native)
 				},
 				Ok(asset_id) => {
-					let assets_in_pool_with_this_asset: Vec<_> = assets_common::get_assets_in_pool_with::<
-						Runtime,
-						xcm::v4::Location
-					>(&asset_id.0).map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?;
-					if assets_in_pool_with_this_asset
-						.into_iter()
-						.map(|asset_id| asset_id.0)
-						.any(|location| location == native_asset) {
-						pallet_asset_conversion::Pallet::<Runtime>::quote_price_tokens_for_exact_tokens(
-							asset_id.clone().0,
+					// Try to get current price of `asset_id` in `native_asset`.
+					if let Ok(Some(swapped_in_native)) = assets_common::PoolAdapter::<Runtime>::quote_price_tokens_for_exact_tokens(
+							asset_id.0.clone(),
 							native_asset,
 							fee_in_native,
 							true, // We include the fee.
-						).ok_or(XcmPaymentApiError::AssetNotFound)
+						) {
+						Ok(swapped_in_native)
 					} else {
 						log::trace!(target: "xcm::xcm_runtime_apis", "query_weight_to_asset_fee - unhandled asset_id: {asset_id:?}!");
 						Err(XcmPaymentApiError::AssetNotFound)
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs
index 7e0226f144e68f478745dea1ddbae5b99b10d3ba..a74a9b6256de2bbe89cb68070a2eb10c927d9e2d 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs
@@ -24,10 +24,10 @@ use asset_hub_rococo_runtime::{
 		ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, ForeignCreatorsSovereignAccountOf,
 		LocationToAccountId, StakingPot, TokenLocation, TrustBackedAssetsPalletLocation, XcmConfig,
 	},
-	AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection,
-	ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase,
-	MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
-	SessionKeys, ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue,
+	AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, Block,
+	CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance,
+	MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall,
+	RuntimeEvent, RuntimeOrigin, SessionKeys, ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue,
 };
 use asset_test_utils::{
 	test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys,
@@ -1407,3 +1407,19 @@ fn change_xcm_bridge_hub_ethereum_base_fee_by_governance_works() {
 		},
 	)
 }
+
+#[test]
+fn xcm_payment_api_works() {
+	parachains_runtimes_test_utils::test_cases::xcm_payment_api_with_native_token_works::<
+		Runtime,
+		RuntimeCall,
+		RuntimeOrigin,
+		Block,
+	>();
+	asset_test_utils::test_cases::xcm_payment_api_with_pools_works::<
+		Runtime,
+		RuntimeCall,
+		RuntimeOrigin,
+		Block,
+	>();
+}
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml
index 72a37aeaa86db90d89c7bb99bb6f4dfbccd96db7..cc181533b517a24f4ff231c56dd389beb85ab9db 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml
@@ -90,7 +90,8 @@ bp-bridge-hub-westend.workspace = true
 snowbridge-router-primitives.workspace = true
 
 [dev-dependencies]
-asset-test-utils = { default-features = true, path = "../test-utils" }
+asset-test-utils = { workspace = true, default-features = true }
+parachains-runtimes-test-utils = { workspace = true, default-features = true }
 
 [build-dependencies]
 substrate-wasm-builder = { optional = true, workspace = true, default-features = true }
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
index bc11f8b1e7c831f649742b4363c2c98cb5cd1f4e..54f09a9d9ba756c9acf8495a64f4af362bd2e989 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
@@ -1367,38 +1367,31 @@ impl_runtime_apis! {
 			// We accept the native token to pay fees.
 			let mut acceptable_assets = vec![AssetId(native_token.clone())];
 			// We also accept all assets in a pool with the native token.
-			let assets_in_pool_with_native = assets_common::get_assets_in_pool_with::<
-				Runtime,
-				xcm::v4::Location
-			>(&native_token).map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?.into_iter();
-			acceptable_assets.extend(assets_in_pool_with_native);
+			acceptable_assets.extend(
+				assets_common::PoolAdapter::<Runtime>::get_assets_in_pool_with(native_token)
+				.map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?
+			);
 			PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
 		}
 
 		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
 			let native_asset = xcm_config::WestendLocation::get();
 			let fee_in_native = WeightToFee::weight_to_fee(&weight);
-			match asset.try_as::<AssetId>() {
+			let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
+			match latest_asset_id {
 				Ok(asset_id) if asset_id.0 == native_asset => {
 					// for native asset
 					Ok(fee_in_native)
 				},
 				Ok(asset_id) => {
-					// We recognize assets in a pool with the native one.
-					let assets_in_pool_with_this_asset: Vec<_> = assets_common::get_assets_in_pool_with::<
-						Runtime,
-						xcm::v4::Location
-					>(&asset_id.0).map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?;
-					if assets_in_pool_with_this_asset
-						.into_iter()
-						.map(|asset_id| asset_id.0)
-						.any(|location| location == native_asset) {
-						pallet_asset_conversion::Pallet::<Runtime>::quote_price_tokens_for_exact_tokens(
-							asset_id.clone().0,
+					// Try to get current price of `asset_id` in `native_asset`.
+					if let Ok(Some(swapped_in_native)) = assets_common::PoolAdapter::<Runtime>::quote_price_tokens_for_exact_tokens(
+							asset_id.0.clone(),
 							native_asset,
 							fee_in_native,
 							true, // We include the fee.
-						).ok_or(XcmPaymentApiError::AssetNotFound)
+						) {
+						Ok(swapped_in_native)
 					} else {
 						log::trace!(target: "xcm::xcm_runtime_apis", "query_weight_to_asset_fee - unhandled asset_id: {asset_id:?}!");
 						Err(XcmPaymentApiError::AssetNotFound)
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs
index 0fcdfd08af7dd9f76ca18fd7bf9972daafff9e8f..f598abccd28652acb771f2765369f7345e30da02 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs
@@ -25,7 +25,7 @@ use asset_hub_westend_runtime::{
 		LocationToAccountId, StakingPot, TrustBackedAssetsPalletLocation, WestendLocation,
 		XcmConfig,
 	},
-	AllPalletsWithoutSystem, Assets, Balances, ExistentialDeposit, ForeignAssets,
+	AllPalletsWithoutSystem, Assets, Balances, Block, ExistentialDeposit, ForeignAssets,
 	ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem,
 	PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys,
 	ToRococoXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue,
@@ -1379,3 +1379,19 @@ fn reserve_transfer_native_asset_to_non_teleport_para_works() {
 		WeightLimit::Unlimited,
 	);
 }
+
+#[test]
+fn xcm_payment_api_works() {
+	parachains_runtimes_test_utils::test_cases::xcm_payment_api_with_native_token_works::<
+		Runtime,
+		RuntimeCall,
+		RuntimeOrigin,
+		Block,
+	>();
+	asset_test_utils::test_cases::xcm_payment_api_with_pools_works::<
+		Runtime,
+		RuntimeCall,
+		RuntimeOrigin,
+		Block,
+	>();
+}
diff --git a/cumulus/parachains/runtimes/assets/common/src/lib.rs b/cumulus/parachains/runtimes/assets/common/src/lib.rs
index 26046e5974b5b6c16cc19e8726cf9aa5c89d978b..9de4c0ef6db8879d411d3f809c10ca012a14a714 100644
--- a/cumulus/parachains/runtimes/assets/common/src/lib.rs
+++ b/cumulus/parachains/runtimes/assets/common/src/lib.rs
@@ -28,7 +28,7 @@ extern crate alloc;
 use crate::matching::{LocalLocationPattern, ParentLocation};
 use alloc::vec::Vec;
 use codec::{Decode, EncodeLike};
-use core::cmp::PartialEq;
+use core::{cmp::PartialEq, marker::PhantomData};
 use frame_support::traits::{Equals, EverythingBut};
 use parachains_common::{AssetIdForTrustBackedAssets, CollectionId, ItemId};
 use sp_runtime::traits::TryConvertInto;
@@ -137,24 +137,62 @@ pub type PoolAssetsConvertedConcreteId<PoolAssetsPalletLocation, Balance> =
 		TryConvertInto,
 	>;
 
-/// Returns an iterator of all assets in a pool with `asset`.
-///
-/// Should only be used in runtime APIs since it iterates over the whole
-/// `pallet_asset_conversion::Pools` map.
-///
-/// It takes in any version of an XCM Location but always returns the latest one.
-/// This is to allow some margin of migrating the pools when updating the XCM version.
-///
-/// An error of type `()` is returned if the version conversion fails for XCM locations.
-/// This error should be mapped by the caller to a more descriptive one.
-pub fn get_assets_in_pool_with<
-	Runtime: pallet_asset_conversion::Config<PoolId = (L, L)>,
-	L: TryInto<Location> + Clone + Decode + EncodeLike + PartialEq,
->(
-	asset: &L,
-) -> Result<Vec<AssetId>, ()> {
-	pallet_asset_conversion::Pools::<Runtime>::iter_keys()
-		.filter_map(|(asset_1, asset_2)| {
+/// Adapter implementation for accessing pools (`pallet_asset_conversion`) that uses `AssetKind` as
+/// a `xcm::v*` which could be different from the `xcm::latest`.
+pub struct PoolAdapter<Runtime>(PhantomData<Runtime>);
+impl<
+		Runtime: pallet_asset_conversion::Config<PoolId = (L, L), AssetKind = L>,
+		L: TryFrom<Location> + TryInto<Location> + Clone + Decode + EncodeLike + PartialEq,
+	> PoolAdapter<Runtime>
+{
+	/// Returns a vector of all assets in a pool with `asset`.
+	///
+	/// Should only be used in runtime APIs since it iterates over the whole
+	/// `pallet_asset_conversion::Pools` map.
+	///
+	/// It takes in any version of an XCM Location but always returns the latest one.
+	/// This is to allow some margin of migrating the pools when updating the XCM version.
+	///
+	/// An error of type `()` is returned if the version conversion fails for XCM locations.
+	/// This error should be mapped by the caller to a more descriptive one.
+	pub fn get_assets_in_pool_with(asset: Location) -> Result<Vec<AssetId>, ()> {
+		// convert latest to the `L` version.
+		let asset: L = asset.try_into().map_err(|_| ())?;
+		Self::iter_assets_in_pool_with(&asset)
+			.map(|location| {
+				// convert `L` to the latest `AssetId`
+				location.try_into().map_err(|_| ()).map(AssetId)
+			})
+			.collect::<Result<Vec<_>, _>>()
+	}
+
+	/// Provides a current prices. Wrapper over
+	/// `pallet_asset_conversion::Pallet::<T>::quote_price_tokens_for_exact_tokens`.
+	///
+	/// An error of type `()` is returned if the version conversion fails for XCM locations.
+	/// This error should be mapped by the caller to a more descriptive one.
+	pub fn quote_price_tokens_for_exact_tokens(
+		asset_1: Location,
+		asset_2: Location,
+		amount: Runtime::Balance,
+		include_fees: bool,
+	) -> Result<Option<Runtime::Balance>, ()> {
+		// Convert latest to the `L` version.
+		let asset_1: L = asset_1.try_into().map_err(|_| ())?;
+		let asset_2: L = asset_2.try_into().map_err(|_| ())?;
+
+		// Quote swap price.
+		Ok(pallet_asset_conversion::Pallet::<Runtime>::quote_price_tokens_for_exact_tokens(
+			asset_1,
+			asset_2,
+			amount,
+			include_fees,
+		))
+	}
+
+	/// Helper function for filtering pool.
+	pub fn iter_assets_in_pool_with(asset: &L) -> impl Iterator<Item = L> + '_ {
+		pallet_asset_conversion::Pools::<Runtime>::iter_keys().filter_map(|(asset_1, asset_2)| {
 			if asset_1 == *asset {
 				Some(asset_2)
 			} else if asset_2 == *asset {
@@ -163,8 +201,7 @@ pub fn get_assets_in_pool_with<
 				None
 			}
 		})
-		.map(|location| location.try_into().map_err(|_| ()).map(AssetId))
-		.collect::<Result<Vec<_>, _>>()
+	}
 }
 
 #[cfg(test)]
diff --git a/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml b/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml
index e0be82cf5251bb9d73337143734b914dd8af0d5a..100b15d415aac7515a1fe448c33a6ed3b2298cd7 100644
--- a/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml
+++ b/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml
@@ -11,26 +11,36 @@ workspace = true
 
 [dependencies]
 codec = { features = ["derive", "max-encoded-len"], workspace = true }
-frame-support.workspace = true
-frame-system.workspace = true
-pallet-assets.workspace = true
-pallet-balances.workspace = true
-pallet-timestamp.workspace = true
-pallet-session.workspace = true
-sp-io.workspace = true
-sp-runtime.workspace = true
-cumulus-pallet-parachain-system.workspace = true
-cumulus-pallet-xcmp-queue.workspace = true
-pallet-collator-selection.workspace = true
-parachains-common.workspace = true
-cumulus-primitives-core.workspace = true
-parachain-info.workspace = true
-parachains-runtimes-test-utils.workspace = true
-xcm.workspace = true
-xcm-builder.workspace = true
-xcm-executor.workspace = true
-pallet-xcm.workspace = true
-pallet-xcm-bridge-hub-router.workspace = true
+
+# Substrate
+frame-support = { workspace = true }
+frame-system = { workspace = true }
+pallet-assets = { workspace = true }
+pallet-asset-conversion = { workspace = true }
+pallet-balances = { workspace = true }
+pallet-timestamp = { workspace = true }
+pallet-session = { workspace = true }
+sp-io = { workspace = true }
+sp-runtime = { workspace = true }
+
+# Cumulus
+cumulus-pallet-parachain-system = { workspace = true }
+cumulus-pallet-xcmp-queue = { workspace = true }
+pallet-collator-selection = { workspace = true }
+parachains-common = { workspace = true }
+cumulus-primitives-core = { workspace = true }
+parachain-info = { workspace = true }
+parachains-runtimes-test-utils = { workspace = true }
+
+# Polkadot
+xcm = { workspace = true }
+xcm-builder = { workspace = true }
+xcm-executor = { workspace = true }
+pallet-xcm = { workspace = true }
+xcm-runtime-apis = { workspace = true }
+
+# Bridges
+pallet-xcm-bridge-hub-router = { workspace = true }
 
 [dev-dependencies]
 hex-literal = { workspace = true, default-features = true }
@@ -48,6 +58,7 @@ std = [
 	"cumulus-primitives-core/std",
 	"frame-support/std",
 	"frame-system/std",
+	"pallet-asset-conversion/std",
 	"pallet-assets/std",
 	"pallet-balances/std",
 	"pallet-collator-selection/std",
@@ -62,5 +73,6 @@ std = [
 	"sp-runtime/std",
 	"xcm-builder/std",
 	"xcm-executor/std",
+	"xcm-runtime-apis/std",
 	"xcm/std",
 ]
diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs
index 67b585ecfe86ff71f59888524353c12af1bc44c8..faec8bd2f03d1473a3d67996e972b5f2e36c70bf 100644
--- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs
+++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs
@@ -34,11 +34,14 @@ use parachains_runtimes_test_utils::{
 	CollatorSessionKeys, ExtBuilder, SlotDurations, ValidatorIdOf, XcmReceivedFrom,
 };
 use sp_runtime::{
-	traits::{MaybeEquivalence, StaticLookup, Zero},
+	traits::{Block as BlockT, MaybeEquivalence, StaticLookup, Zero},
 	DispatchError, Saturating,
 };
 use xcm::{latest::prelude::*, VersionedAssets};
 use xcm_executor::{traits::ConvertLocation, XcmExecutor};
+use xcm_runtime_apis::fees::{
+	runtime_decl_for_xcm_payment_api::XcmPaymentApiV1, Error as XcmPaymentApiError,
+};
 
 type RuntimeHelper<Runtime, AllPalletsWithoutSystem = ()> =
 	parachains_runtimes_test_utils::RuntimeHelper<Runtime, AllPalletsWithoutSystem>;
@@ -1593,3 +1596,108 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works<
 			);
 		})
 }
+
+pub fn xcm_payment_api_with_pools_works<Runtime, RuntimeCall, RuntimeOrigin, Block>()
+where
+	Runtime: XcmPaymentApiV1<Block>
+		+ frame_system::Config<RuntimeOrigin = RuntimeOrigin, AccountId = AccountId>
+		+ pallet_balances::Config<Balance = u128>
+		+ pallet_session::Config
+		+ pallet_xcm::Config
+		+ parachain_info::Config
+		+ pallet_collator_selection::Config
+		+ cumulus_pallet_parachain_system::Config
+		+ cumulus_pallet_xcmp_queue::Config
+		+ pallet_timestamp::Config
+		+ pallet_assets::Config<
+			pallet_assets::Instance1,
+			AssetId = u32,
+			Balance = <Runtime as pallet_balances::Config>::Balance,
+		> + pallet_asset_conversion::Config<
+			AssetKind = xcm::v4::Location,
+			Balance = <Runtime as pallet_balances::Config>::Balance,
+		>,
+	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
+	RuntimeOrigin: OriginTrait<AccountId = <Runtime as frame_system::Config>::AccountId>,
+	<<Runtime as frame_system::Config>::Lookup as StaticLookup>::Source:
+		From<<Runtime as frame_system::Config>::AccountId>,
+	Block: BlockT,
+{
+	use xcm::prelude::*;
+
+	ExtBuilder::<Runtime>::default().build().execute_with(|| {
+		let test_account = AccountId::from([0u8; 32]);
+		let transfer_amount = 100u128;
+		let xcm_to_weigh = Xcm::<RuntimeCall>::builder_unsafe()
+			.withdraw_asset((Here, transfer_amount))
+			.buy_execution((Here, transfer_amount), Unlimited)
+			.deposit_asset(AllCounted(1), [1u8; 32])
+			.build();
+		let versioned_xcm_to_weigh = VersionedXcm::from(xcm_to_weigh.clone().into());
+
+		let xcm_weight = Runtime::query_xcm_weight(versioned_xcm_to_weigh);
+		assert!(xcm_weight.is_ok());
+		let native_token: Location = Parent.into();
+		let native_token_versioned = VersionedAssetId::from(AssetId(native_token.clone()));
+		let execution_fees =
+			Runtime::query_weight_to_asset_fee(xcm_weight.unwrap(), native_token_versioned);
+		assert!(execution_fees.is_ok());
+
+		// We need some balance to create an asset.
+		assert_ok!(
+			pallet_balances::Pallet::<Runtime>::mint_into(&test_account, 3_000_000_000_000,)
+		);
+
+		// Now we try to use an asset that's not in a pool.
+		let asset_id = 1984u32; // USDT.
+		let asset_not_in_pool: Location =
+			(PalletInstance(50), GeneralIndex(asset_id.into())).into();
+		assert_ok!(pallet_assets::Pallet::<Runtime, pallet_assets::Instance1>::create(
+			RuntimeOrigin::signed(test_account.clone()),
+			asset_id.into(),
+			test_account.clone().into(),
+			1000
+		));
+		let execution_fees = Runtime::query_weight_to_asset_fee(
+			xcm_weight.unwrap(),
+			VersionedAssetId::from(AssetId(asset_not_in_pool.clone())),
+		);
+		assert_eq!(execution_fees, Err(XcmPaymentApiError::AssetNotFound));
+
+		// We add it to a pool with native.
+		assert_ok!(pallet_asset_conversion::Pallet::<Runtime>::create_pool(
+			RuntimeOrigin::signed(test_account.clone()),
+			native_token.clone().try_into().unwrap(),
+			asset_not_in_pool.clone().try_into().unwrap()
+		));
+		let execution_fees = Runtime::query_weight_to_asset_fee(
+			xcm_weight.unwrap(),
+			VersionedAssetId::from(AssetId(asset_not_in_pool.clone())),
+		);
+		// Still not enough because it doesn't have any liquidity.
+		assert_eq!(execution_fees, Err(XcmPaymentApiError::AssetNotFound));
+
+		// We mint some of the asset...
+		assert_ok!(pallet_assets::Pallet::<Runtime, pallet_assets::Instance1>::mint(
+			RuntimeOrigin::signed(test_account.clone()),
+			asset_id.into(),
+			test_account.clone().into(),
+			3_000_000_000_000,
+		));
+		// ...so we can add liquidity to the pool.
+		assert_ok!(pallet_asset_conversion::Pallet::<Runtime>::add_liquidity(
+			RuntimeOrigin::signed(test_account.clone()),
+			native_token.try_into().unwrap(),
+			asset_not_in_pool.clone().try_into().unwrap(),
+			1_000_000_000_000,
+			2_000_000_000_000,
+			0,
+			0,
+			test_account
+		));
+		let execution_fees =
+			Runtime::query_weight_to_asset_fee(xcm_weight.unwrap(), VersionedAssetId::from(AssetId(asset_not_in_pool)));
+		// Now it works!
+		assert_ok!(execution_fees);
+	});
+}
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml
index fddbf99c65dbf5ce45dabe1d3b7ebf74fba02989..2ad53d8df36a6c81032345cf8b9d3e3a9989d95b 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml
@@ -111,11 +111,12 @@ snowbridge-runtime-common.workspace = true
 bridge-hub-common.workspace = true
 
 [dev-dependencies]
-bridge-hub-test-utils = { default-features = true, path = "../test-utils" }
-bridge-runtime-common = { features = ["integrity-test"], default-features = true, path = "../../../../../bridges/bin/runtime-common" }
-pallet-bridge-relayers = { features = ["integrity-test"], path = "../../../../../bridges/modules/relayers", default-features = false }
-sp-keyring = { default-features = true, path = "../../../../../substrate/primitives/keyring" }
-snowbridge-runtime-test-common = { default-features = true, path = "../../../../../bridges/snowbridge/runtime/test-common" }
+sp-keyring = { workspace = true }
+bridge-hub-test-utils = { workspace = true, default-features = true }
+bridge-runtime-common = { features = ["integrity-test"], workspace = true, default-features = true }
+pallet-bridge-relayers = { features = ["integrity-test"], workspace = true }
+snowbridge-runtime-test-common = { workspace = true, default-features = true }
+parachains-runtimes-test-utils = { workspace = true, default-features = true }
 
 [features]
 default = ["std"]
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
index d39641a18b50aa44a930ae25692c8380b77b2e6a..ff8e656bef6cc7aa5e3c60530e5a646b8e5bfa1c 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
@@ -836,7 +836,8 @@ impl_runtime_apis! {
 		}
 
 		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
-			match asset.try_as::<AssetId>() {
+			let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
+			match latest_asset_id {
 				Ok(asset_id) if asset_id.0 == xcm_config::TokenLocation::get() => {
 					// for native token
 					Ok(WeightToFee::weight_to_fee(&weight))
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs
index ce2c0981ba85e8f46a5bcd58757f21028019c0d8..8fe2efb4fb7b5b2fa40c68faf2addfaec70d7356 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs
@@ -18,13 +18,12 @@
 
 use bp_polkadot_core::Signature;
 use bridge_hub_rococo_runtime::{
-	bridge_common_config, bridge_to_bulletin_config,
 	bridge_to_ethereum_config::EthereumGatewayAddress,
-	bridge_to_westend_config,
+	bridge_common_config, bridge_to_bulletin_config, bridge_to_westend_config,
 	xcm_config::{LocationToAccountId, RelayNetwork, TokenLocation, XcmConfig},
-	AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, ExistentialDeposit,
-	ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys,
-	SignedExtra, TransactionPayment, UncheckedExtrinsic,
+	AllPalletsWithoutSystem, Block, BridgeRejectObsoleteHeadersAndMessages, Executive,
+	ExistentialDeposit, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent,
+	RuntimeOrigin, SessionKeys, SignedExtra, TransactionPayment, UncheckedExtrinsic,
 };
 use bridge_hub_test_utils::SlotDurations;
 use codec::{Decode, Encode};
@@ -721,3 +720,13 @@ mod bridge_hub_bulletin_tests {
 		)
 	}
 }
+
+#[test]
+fn xcm_payment_api_works() {
+	parachains_runtimes_test_utils::test_cases::xcm_payment_api_with_native_token_works::<
+		Runtime,
+		RuntimeCall,
+		RuntimeOrigin,
+		Block,
+	>();
+}
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml
index b1799608e32404cdf43a4f092ba9bfa3e5bec4a8..78217f67d4bd229a276cdd1a50ab9d32a88e1092 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml
@@ -105,11 +105,12 @@ snowbridge-router-primitives.workspace = true
 snowbridge-runtime-common.workspace = true
 
 [dev-dependencies]
-bridge-hub-test-utils = { default-features = true, path = "../test-utils" }
-bridge-runtime-common = { features = ["integrity-test"], default-features = true, path = "../../../../../bridges/bin/runtime-common" }
-pallet-bridge-relayers = { features = ["integrity-test"], path = "../../../../../bridges/modules/relayers", default-features = false }
-sp-keyring = { default-features = true, path = "../../../../../substrate/primitives/keyring" }
-snowbridge-runtime-test-common = { default-features = true, path = "../../../../../bridges/snowbridge/runtime/test-common" }
+sp-keyring = { workspace = true, default-features = true }
+bridge-hub-test-utils = { workspace = true, default-features = true }
+bridge-runtime-common = { features = ["integrity-test"], workspace = true, default-features = true }
+pallet-bridge-relayers = { features = ["integrity-test"], workspace = true }
+snowbridge-runtime-test-common = { workspace = true, default-features = true }
+parachains-runtimes-test-utils = { workspace = true, default-features = true }
 
 [features]
 default = ["std"]
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs
index 18b5408364d218ec077052633d957ec63908d3b4..cd053ead827c1a477591bc0d19ce92fe29266085 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs
@@ -768,7 +768,8 @@ impl_runtime_apis! {
 		}
 
 		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
-			match asset.try_as::<AssetId>() {
+			let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
+			match latest_asset_id {
 				Ok(asset_id) if asset_id.0 == xcm_config::WestendLocation::get() => {
 					// for native token
 					Ok(WeightToFee::weight_to_fee(&weight))
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs
index 3f2952db01534e3f184d707994f8f1061163c593..29449b936833d93d6a772ed614897b43e11c1ef2 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs
@@ -27,9 +27,9 @@ use bridge_hub_westend_runtime::{
 	bridge_common_config, bridge_to_rococo_config,
 	bridge_to_rococo_config::RococoGlobalConsensusNetwork,
 	xcm_config::{LocationToAccountId, RelayNetwork, WestendLocation, XcmConfig},
-	AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, ExistentialDeposit,
-	ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys,
-	SignedExtra, TransactionPayment, UncheckedExtrinsic,
+	AllPalletsWithoutSystem, Block, BridgeRejectObsoleteHeadersAndMessages, Executive,
+	ExistentialDeposit, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent,
+	RuntimeOrigin, SessionKeys, SignedExtra, TransactionPayment, UncheckedExtrinsic,
 };
 use bridge_to_rococo_config::{
 	BridgeGrandpaRococoInstance, BridgeHubRococoLocation, BridgeParachainRococoInstance,
@@ -413,3 +413,13 @@ pub fn can_calculate_fee_for_standalone_message_confirmation_transaction() {
 		),
 	)
 }
+
+#[test]
+fn xcm_payment_api_works() {
+	parachains_runtimes_test_utils::test_cases::xcm_payment_api_with_native_token_works::<
+		Runtime,
+		RuntimeCall,
+		RuntimeOrigin,
+		Block,
+	>();
+}
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml
index b4cf59716743c7937a953c70974cd277c6dacec2..7731fec764733609c85376fa0cb899516d97f5d5 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml
@@ -85,7 +85,8 @@ testnet-parachains-constants = { features = ["westend"], workspace = true }
 substrate-wasm-builder = { optional = true, workspace = true, default-features = true }
 
 [dev-dependencies]
-sp-io = { features = ["std"], default-features = true, path = "../../../../../substrate/primitives/io" }
+sp-io = { features = ["std"], workspace = true, default-features = true }
+parachains-runtimes-test-utils = { workspace = true, default-features = true }
 
 [features]
 default = ["std"]
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs
index a7b111bb43dcb1361d414735e0e6c75dbb48ee0b..18b6dcf2e77dd13b0d9d84155d0709ad30838688 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs
@@ -952,7 +952,8 @@ impl_runtime_apis! {
 		}
 
 		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
-			match asset.try_as::<AssetId>() {
+			let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
+			match latest_asset_id {
 				Ok(asset_id) if asset_id.0 == xcm_config::WndLocation::get() => {
 					// for native token
 					Ok(WeightToFee::weight_to_fee(&weight))
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/tests/tests.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/tests/tests.rs
new file mode 100644
index 0000000000000000000000000000000000000000..fb0149303e51a307bea03a3c95c88eca49b35c00
--- /dev/null
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/tests/tests.rs
@@ -0,0 +1,29 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+#![cfg(test)]
+
+use collectives_westend_runtime::{Block, Runtime, RuntimeCall, RuntimeOrigin};
+
+#[test]
+fn xcm_payment_api_works() {
+	parachains_runtimes_test_utils::test_cases::xcm_payment_api_with_native_token_works::<
+		Runtime,
+		RuntimeCall,
+		RuntimeOrigin,
+		Block,
+	>();
+}
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml
index e21ebf1e0770d96cfe4e1f977d2ff5a97c029f28..917a2292da6d20e5de573706fb6e880b6d3de73c 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml
@@ -74,6 +74,9 @@ parachain-info.workspace = true
 parachains-common.workspace = true
 testnet-parachains-constants = { features = ["rococo"], workspace = true }
 
+[dev-dependencies]
+parachains-runtimes-test-utils = { workspace = true }
+
 [features]
 default = ["std"]
 std = [
@@ -114,6 +117,7 @@ std = [
 	"pallet-xcm/std",
 	"parachain-info/std",
 	"parachains-common/std",
+	"parachains-runtimes-test-utils/std",
 	"polkadot-parachain-primitives/std",
 	"polkadot-runtime-common/std",
 	"rococo-runtime-constants/std",
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
index 1e082a44620578a30ebec49f2e28987ed5b2685b..5686ebcfddff036da71deaa0097b2b067bcf5c11 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
@@ -808,7 +808,8 @@ impl_runtime_apis! {
 		}
 
 		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
-			match asset.try_as::<AssetId>() {
+			let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
+			match latest_asset_id {
 				Ok(asset_id) if asset_id.0 == xcm_config::RocRelayLocation::get() => {
 					// for native token
 					Ok(WeightToFee::weight_to_fee(&weight))
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/tests/tests.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/tests/tests.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a1208e0e2171ad4211f9462e26c44ca1f0df74ca
--- /dev/null
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/tests/tests.rs
@@ -0,0 +1,29 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+#![cfg(test)]
+
+use coretime_rococo_runtime::{Block, Runtime, RuntimeCall, RuntimeOrigin};
+
+#[test]
+fn xcm_payment_api_works() {
+	parachains_runtimes_test_utils::test_cases::xcm_payment_api_with_native_token_works::<
+		Runtime,
+		RuntimeCall,
+		RuntimeOrigin,
+		Block,
+	>();
+}
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml
index d06e9d5761d756e3862d0e1a49cafea887cdb703..f765eb1b8e707b1d66969e3169e5a7e1042e8af3 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml
@@ -73,6 +73,9 @@ parachain-info.workspace = true
 parachains-common.workspace = true
 testnet-parachains-constants = { features = ["westend"], workspace = true }
 
+[dev-dependencies]
+parachains-runtimes-test-utils = { workspace = true, default-features = true }
+
 [features]
 default = ["std"]
 std = [
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs
index f3ed4f107cfa592a108306cde5e6a65ee706cbc6..7c13ac1e012881b38c155e6855deacd1f67102ac 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs
@@ -799,7 +799,8 @@ impl_runtime_apis! {
 		}
 
 		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
-			match asset.try_as::<AssetId>() {
+			let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
+			match latest_asset_id {
 				Ok(asset_id) if asset_id.0 == xcm_config::TokenRelayLocation::get() => {
 					// for native token
 					Ok(WeightToFee::weight_to_fee(&weight))
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/tests/tests.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/tests/tests.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7aeb2ba9393ad34a0e301d1d36a347cd4d43077a
--- /dev/null
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/tests/tests.rs
@@ -0,0 +1,29 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+#![cfg(test)]
+
+use coretime_westend_runtime::{Block, Runtime, RuntimeCall, RuntimeOrigin};
+
+#[test]
+fn xcm_payment_api_works() {
+	parachains_runtimes_test_utils::test_cases::xcm_payment_api_with_native_token_works::<
+		Runtime,
+		RuntimeCall,
+		RuntimeOrigin,
+		Block,
+	>();
+}
diff --git a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml
index 9718a877da99603b1654ffa4a73b333ff09ea609..876bc0e4c0b292afb1f5de7deef92a655ecbd3a1 100644
--- a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml
+++ b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml
@@ -70,6 +70,9 @@ parachain-info.workspace = true
 parachains-common.workspace = true
 testnet-parachains-constants = { features = ["rococo"], workspace = true }
 
+[dev-dependencies]
+parachains-runtimes-test-utils = { workspace = true, default-features = true }
+
 [features]
 default = ["std"]
 std = [
diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs
index 1dc33e9ad8ac658336c17bcc0f903951418beded..232c1cd0ebe39de9166d0c3fbd825f95f7eb9972 100644
--- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs
@@ -751,7 +751,8 @@ impl_runtime_apis! {
 		}
 
 		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
-			match asset.try_as::<AssetId>() {
+			let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
+			match latest_asset_id {
 				Ok(asset_id) if asset_id.0 == xcm_config::RelayLocation::get() => {
 					// for native token
 					Ok(WeightToFee::weight_to_fee(&weight))
diff --git a/cumulus/parachains/runtimes/people/people-rococo/tests/tests.rs b/cumulus/parachains/runtimes/people/people-rococo/tests/tests.rs
new file mode 100644
index 0000000000000000000000000000000000000000..da50f70a83f3bf62cd19a815edab53c321fe11af
--- /dev/null
+++ b/cumulus/parachains/runtimes/people/people-rococo/tests/tests.rs
@@ -0,0 +1,29 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+#![cfg(test)]
+
+use people_rococo_runtime::{Block, Runtime, RuntimeCall, RuntimeOrigin};
+
+#[test]
+fn xcm_payment_api_works() {
+	parachains_runtimes_test_utils::test_cases::xcm_payment_api_with_native_token_works::<
+		Runtime,
+		RuntimeCall,
+		RuntimeOrigin,
+		Block,
+	>();
+}
diff --git a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml
index d06689d2498d00bbad282f0f3b19707c9b23bceb..70d29b24c63057826678a228eb1c0523357db49b 100644
--- a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml
+++ b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml
@@ -70,6 +70,9 @@ parachain-info.workspace = true
 parachains-common.workspace = true
 testnet-parachains-constants = { features = ["westend"], workspace = true }
 
+[dev-dependencies]
+parachains-runtimes-test-utils = { workspace = true, default-features = true }
+
 [features]
 default = ["std"]
 std = [
diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs
index 2519399890d3b6ff8c5f414dd77785e842486824..9e3c5972369c8473ce5d4128e4d891487e603929 100644
--- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs
@@ -751,7 +751,8 @@ impl_runtime_apis! {
 		}
 
 		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
-			match asset.try_as::<AssetId>() {
+			let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
+			match latest_asset_id {
 				Ok(asset_id) if asset_id.0 == xcm_config::RelayLocation::get() => {
 					// for native token
 					Ok(WeightToFee::weight_to_fee(&weight))
diff --git a/cumulus/parachains/runtimes/people/people-westend/tests/tests.rs b/cumulus/parachains/runtimes/people/people-westend/tests/tests.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4dd6ede05c7ca42e9ed188aa927aff547f6690ef
--- /dev/null
+++ b/cumulus/parachains/runtimes/people/people-westend/tests/tests.rs
@@ -0,0 +1,29 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+#![cfg(test)]
+
+use people_westend_runtime::{Block, Runtime, RuntimeCall, RuntimeOrigin};
+
+#[test]
+fn xcm_payment_api_works() {
+	parachains_runtimes_test_utils::test_cases::xcm_payment_api_with_native_token_works::<
+		Runtime,
+		RuntimeCall,
+		RuntimeOrigin,
+		Block,
+	>();
+}
diff --git a/cumulus/parachains/runtimes/test-utils/Cargo.toml b/cumulus/parachains/runtimes/test-utils/Cargo.toml
index 26e514b8a697ef526c23f39f569936304d6c3d73..605c748a306501c91a71cd614d20688460e34fe6 100644
--- a/cumulus/parachains/runtimes/test-utils/Cargo.toml
+++ b/cumulus/parachains/runtimes/test-utils/Cargo.toml
@@ -11,28 +11,35 @@ workspace = true
 
 [dependencies]
 codec = { features = ["derive", "max-encoded-len"], workspace = true }
-frame-support.workspace = true
-frame-system.workspace = true
-pallet-balances.workspace = true
-pallet-session.workspace = true
-pallet-timestamp.workspace = true
-sp-consensus-aura.workspace = true
-sp-io.workspace = true
-sp-runtime.workspace = true
-sp-tracing.workspace = true
-sp-tracing.default-features = true
-sp-core.workspace = true
-cumulus-pallet-parachain-system.workspace = true
-cumulus-pallet-xcmp-queue.workspace = true
-pallet-collator-selection.workspace = true
-parachain-info.workspace = true
-cumulus-primitives-core.workspace = true
-cumulus-primitives-parachain-inherent.workspace = true
-cumulus-test-relay-sproof-builder.workspace = true
-xcm.workspace = true
-xcm-executor.workspace = true
-pallet-xcm.workspace = true
-polkadot-parachain-primitives.workspace = true
+
+# Substrate
+frame-support = { workspace = true }
+frame-system = { workspace = true }
+pallet-balances = { workspace = true }
+pallet-session = { workspace = true }
+pallet-timestamp = { workspace = true }
+sp-consensus-aura = { workspace = true }
+sp-io = { workspace = true }
+sp-runtime = { workspace = true }
+sp-tracing = { workspace = true, default-features = true }
+sp-core = { workspace = true }
+
+# Cumulus
+cumulus-pallet-parachain-system = { workspace = true }
+cumulus-pallet-xcmp-queue = { workspace = true }
+pallet-collator-selection = { workspace = true }
+parachain-info = { workspace = true }
+parachains-common = { workspace = true }
+cumulus-primitives-core = { workspace = true }
+cumulus-primitives-parachain-inherent = { workspace = true }
+cumulus-test-relay-sproof-builder = { workspace = true }
+
+# Polkadot
+xcm = { workspace = true }
+xcm-executor = { workspace = true }
+pallet-xcm = { workspace = true }
+xcm-runtime-apis = { workspace = true }
+polkadot-parachain-primitives = { workspace = true }
 
 [dev-dependencies]
 hex-literal = { workspace = true, default-features = true }
@@ -58,11 +65,13 @@ std = [
 	"pallet-timestamp/std",
 	"pallet-xcm/std",
 	"parachain-info/std",
+	"parachains-common/std",
 	"polkadot-parachain-primitives/std",
 	"sp-consensus-aura/std",
 	"sp-core/std",
 	"sp-io/std",
 	"sp-runtime/std",
 	"xcm-executor/std",
+	"xcm-runtime-apis/std",
 	"xcm/std",
 ]
diff --git a/cumulus/parachains/runtimes/test-utils/src/test_cases.rs b/cumulus/parachains/runtimes/test-utils/src/test_cases.rs
index 1c58df189b673af60bc3e4a9ae7391294287e2aa..0f863291ee0bbbc5e1edbf3d0caeb3040bc1edd3 100644
--- a/cumulus/parachains/runtimes/test-utils/src/test_cases.rs
+++ b/cumulus/parachains/runtimes/test-utils/src/test_cases.rs
@@ -18,7 +18,15 @@
 
 use crate::{AccountIdOf, CollatorSessionKeys, ExtBuilder, ValidatorIdOf};
 use codec::Encode;
-use frame_support::{assert_ok, traits::Get};
+use frame_support::{
+	assert_ok,
+	traits::{Get, OriginTrait},
+};
+use parachains_common::AccountId;
+use sp_runtime::traits::{Block as BlockT, StaticLookup};
+use xcm_runtime_apis::fees::{
+	runtime_decl_for_xcm_payment_api::XcmPaymentApiV1, Error as XcmPaymentApiError,
+};
 
 type RuntimeHelper<Runtime, AllPalletsWithoutSystem = ()> =
 	crate::RuntimeHelper<Runtime, AllPalletsWithoutSystem>;
@@ -145,3 +153,60 @@ pub fn set_storage_keys_by_governance_works<Runtime>(
 		assert_storage();
 	});
 }
+
+pub fn xcm_payment_api_with_native_token_works<Runtime, RuntimeCall, RuntimeOrigin, Block>()
+where
+	Runtime: XcmPaymentApiV1<Block>
+		+ frame_system::Config<RuntimeOrigin = RuntimeOrigin, AccountId = AccountId>
+		+ pallet_balances::Config<Balance = u128>
+		+ pallet_session::Config
+		+ pallet_xcm::Config
+		+ parachain_info::Config
+		+ pallet_collator_selection::Config
+		+ cumulus_pallet_parachain_system::Config
+		+ cumulus_pallet_xcmp_queue::Config
+		+ pallet_timestamp::Config,
+	ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
+	RuntimeOrigin: OriginTrait<AccountId = <Runtime as frame_system::Config>::AccountId>,
+	<<Runtime as frame_system::Config>::Lookup as StaticLookup>::Source:
+		From<<Runtime as frame_system::Config>::AccountId>,
+	Block: BlockT,
+{
+	use xcm::prelude::*;
+	ExtBuilder::<Runtime>::default().build().execute_with(|| {
+		let transfer_amount = 100u128;
+		let xcm_to_weigh = Xcm::<RuntimeCall>::builder_unsafe()
+			.withdraw_asset((Here, transfer_amount))
+			.buy_execution((Here, transfer_amount), Unlimited)
+			.deposit_asset(AllCounted(1), [1u8; 32])
+			.build();
+		let versioned_xcm_to_weigh = VersionedXcm::from(xcm_to_weigh.clone().into());
+
+		// We first try calling it with a lower XCM version.
+		let lower_version_xcm_to_weigh =
+			versioned_xcm_to_weigh.clone().into_version(XCM_VERSION - 1).unwrap();
+		let xcm_weight = Runtime::query_xcm_weight(lower_version_xcm_to_weigh);
+		assert!(xcm_weight.is_ok());
+		let native_token: Location = Parent.into();
+		let native_token_versioned = VersionedAssetId::from(AssetId(native_token));
+		let lower_version_native_token =
+			native_token_versioned.clone().into_version(XCM_VERSION - 1).unwrap();
+		let execution_fees =
+			Runtime::query_weight_to_asset_fee(xcm_weight.unwrap(), lower_version_native_token);
+		assert!(execution_fees.is_ok());
+
+		// Now we call it with the latest version.
+		let xcm_weight = Runtime::query_xcm_weight(versioned_xcm_to_weigh);
+		assert!(xcm_weight.is_ok());
+		let execution_fees =
+			Runtime::query_weight_to_asset_fee(xcm_weight.unwrap(), native_token_versioned);
+		assert!(execution_fees.is_ok());
+
+		// If we call it with anything other than the native token it will error.
+		let non_existent_token: Location = Here.into();
+		let non_existent_token_versioned = VersionedAssetId::from(AssetId(non_existent_token));
+		let execution_fees =
+			Runtime::query_weight_to_asset_fee(xcm_weight.unwrap(), non_existent_token_versioned);
+		assert_eq!(execution_fees, Err(XcmPaymentApiError::AssetNotFound));
+	});
+}
diff --git a/polkadot/xcm/xcm-runtime-apis/tests/fee_estimation.rs b/polkadot/xcm/xcm-runtime-apis/tests/fee_estimation.rs
index e5dac7c7a04edaed341274d79690b09e7c987b42..bfc370857e1978a7dc961b85919220f08e441ab0 100644
--- a/polkadot/xcm/xcm-runtime-apis/tests/fee_estimation.rs
+++ b/polkadot/xcm/xcm-runtime-apis/tests/fee_estimation.rs
@@ -353,3 +353,26 @@ fn dry_run_xcm() {
 		);
 	});
 }
+
+#[test]
+fn calling_payment_api_with_a_lower_version_works() {
+	let transfer_amount = 100u128;
+	let xcm_to_weigh = Xcm::<RuntimeCall>::builder_unsafe()
+		.withdraw_asset((Here, transfer_amount))
+		.buy_execution((Here, transfer_amount), Unlimited)
+		.deposit_asset(AllCounted(1), [1u8; 32])
+		.build();
+	let versioned_xcm_to_weigh = VersionedXcm::from(xcm_to_weigh.clone().into());
+	let lower_version_xcm_to_weigh = versioned_xcm_to_weigh.into_version(XCM_VERSION - 1).unwrap();
+	let client = TestClient;
+	let runtime_api = client.runtime_api();
+	let xcm_weight =
+		runtime_api.query_xcm_weight(H256::zero(), lower_version_xcm_to_weigh).unwrap();
+	assert!(xcm_weight.is_ok());
+	let native_token = VersionedAssetId::from(AssetId(Here.into()));
+	let lower_version_native_token = native_token.into_version(XCM_VERSION - 1).unwrap();
+	let execution_fees = runtime_api
+		.query_weight_to_asset_fee(H256::zero(), xcm_weight.unwrap(), lower_version_native_token)
+		.unwrap();
+	assert!(execution_fees.is_ok());
+}
diff --git a/polkadot/xcm/xcm-runtime-apis/tests/mock.rs b/polkadot/xcm/xcm-runtime-apis/tests/mock.rs
index b2a416468e7cd97794594f9485b4e429292ec255..ff7f48ef55b7b2f39dbc6ad7d90b6c999987415c 100644
--- a/polkadot/xcm/xcm-runtime-apis/tests/mock.rs
+++ b/polkadot/xcm/xcm-runtime-apis/tests/mock.rs
@@ -435,7 +435,8 @@ sp_api::mock_impl_runtime_apis! {
 		}
 
 		fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
-			match asset.try_as::<AssetId>() {
+			let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
+			match latest_asset_id {
 				Ok(asset_id) if asset_id.0 == HereLocation::get() => {
 					Ok(WeightToFee::weight_to_fee(&weight))
 				},
diff --git a/prdoc/pr_6664.prdoc b/prdoc/pr_6664.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..592ba4c6b29d0863405f3d5547ab2ce1040e3dd6
--- /dev/null
+++ b/prdoc/pr_6664.prdoc
@@ -0,0 +1,22 @@
+# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
+# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
+
+title: Fix version conversion in XcmPaymentApi::query_weight_to_asset_fee.
+
+doc:
+  - audience: Runtime Dev
+    description: |
+      The `query_weight_to_asset_fee` function of the `XcmPaymentApi` was trying
+      to convert versions in the wrong way.
+      This resulted in all calls made with lower versions failing.
+      The version conversion is now done correctly and these same calls will now succeed.
+
+crates:
+  - name: asset-hub-westend-runtime
+    bump: patch
+  - name: asset-hub-rococo-runtime
+    bump: patch
+  - name: xcm-runtime-apis
+    bump: patch
+  - name: assets-common
+    bump: patch