我正在尝试集成 FedEx API 以在我的 Node.js 应用程序中获取运费报价。我已按照文档进行操作,但始终收到 404 错误并显示以下消息:
“您请求的资源不再可用。”
FedEx API request failed with status: 404
- Response body: {"transactionId": "c2dda9ea-61fa-411a-9e39-e70239ee9370","errors":[{"code":"NOT.FOUND.ERROR","message":"The resource you requested is no longer available. Please modify your request and try again."}]}
我已根据 FedEx API 文档验证了端点 URL 和请求负载。这是我的 index.js 的相关部分:
const express = require('express');
const bodyParser = require('body-parser');
const fetch = require('node-fetch');
const path = require('path');
const app = express();
app.use(bodyParser.json());
const FEDEX_OAUTH_URL = 'https://apis.fedex.com/oauth/token';
const FEDEX_API_URL = 'https://apis.fedex.com/rate/v1/rates/quote';
const FEDEX_API_KEY = 'your_api_key';
const FEDEX_SECRET = 'your_api_secret';
const FEDEX_ACCOUNT_NUMBER = 'your_account_number';
async function getFedexToken() {
const response = await fetch(FEDEX_OAUTH_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: FEDEX_API_KEY,
client_secret: FEDEX_SECRET
})
});
const responseBody = await response.text();
if (!response.ok) {
throw new Error(`Failed to get FedEx OAuth token: ${response.statusText}. Response Body: ${responseBody}`);
}
const data = JSON.parse(responseBody);
return data.access_token;
}
app.post('/compare', async (req, res) => {
const { originPostcode, originCountry, destinationPostcode, destinationCountry, weight } = req.body;
const fedexRequest = {
accountNumber: {
value: FEDEX_ACCOUNT_NUMBER
},
requestedShipment: {
shipper: {
address: {
postalCode: originPostcode,
countryCode: originCountry.toUpperCase()
}
},
recipient: {
address: {
postalCode: destinationPostcode,
countryCode: destinationCountry.toUpperCase()
}
},
shipDateStamp: new Date().toISOString().split('T')[0], // Today's date in YYYY-MM-DD format
pickupType: 'DROPOFF_AT_FEDEX_LOCATION',
serviceType: 'INTERNATIONAL_PRIORITY',
rateRequestType: ['LIST', 'ACCOUNT'],
customsClearanceDetail: {
dutiesPayment: {
paymentType: 'SENDER',
payor: {
responsibleParty: null
}
},
commodities: [
{
description: 'Camera',
quantity: 1,
quantityUnits: 'PCS',
weight: {
units: 'KG',
value: weight
},
customsValue: {
amount: 100,
currency: 'USD'
}
}
]
},
requestedPackageLineItems: [
{
weight: {
units: 'KG',
value: weight
}
}
]
}
};
console.log('FedEx Request Payload:', JSON.stringify(fedexRequest, null, 2));
try {
const token = await getFedexToken();
const response = await fetch(FEDEX_API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-locale': 'en_US',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify(fedexRequest)
});
const responseBody = await response.text();
if (!response.ok) {
console.error('FedEx API request failed with status:', response.status);
console.error('Response body:', responseBody); // Log the detailed error response
throw new Error(`FedEx API request failed with status ${response.status}: ${responseBody}`);
}
const fedexData = JSON.parse(responseBody);
console.log('FedEx Response Data:', JSON.stringify(fedexData, null, 2));
if (!fedexData.output || !fedexData.output.rateReplyDetails) {
throw new Error(`Unexpected FedEx API response structure: ${JSON.stringify(fedexData)}`);
}
const results = fedexData.output.rateReplyDetails.map(detail => ({
courier: 'FedEx',
cost: detail.ratedShipmentDetails[0].totalNetChargeWithDutiesAndTaxes.amount,
service: detail.serviceType,
transitTime: detail.commitDetails[0].commitTimestamp
}));
res.json({ results });
} catch (error) {
console.error('Error fetching data from FedEx API:', error);
res.status(500).json({ error: error.message });
}
});
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
}).on('error', (err) => {
if (err.code === 'EADDRINUSE') {
console.error(`Port ${PORT} is already in use.`);
} else {
console.error(err);
}
});
我原本希望收到 FedEx 提供的货件详细信息的费率报价,但我不断收到 404 错误。我已经验证了端点和请求负载结构,但我不确定是什么导致资源“不再可用”。
问题:
您在
s
之后错过了终点末尾的 quote
。完整网址是 https://apis.fedex.com/rate/v1/rates/quotes
而不是 https://apis.fedex.com/rate/v1/rates/quote