You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel集成FedEx API:跨地区运单创建请求配置问题求助

Laravel集成FedEx Shipment Create API 通用配置与问题排查

一、适配任意起运地-目的地的请求体通用配置逻辑

  • 身份验证与基础信息:确保webAuthenticationDetail和clientDetail的密钥、账号、计量器编号与当前环境(沙箱/生产)完全匹配,生产环境需确认账号已激活对应运输服务权限。
  • 发件人/收件人信息动态适配:
    • 区分国内/国际件:国际件必须填写收件人contact的personName、companyName,地址字段countryCode严格使用ISO 3166-1 alpha-2格式(如CN、US);国内件部分字段可简化,但postalCode必须准确无误。
    • 地址校验:所有地址需符合FedEx格式要求,比如美国邮编为5/9位数字,欧盟国家邮编需匹配当地规则;避免使用模糊地址(如无具体街道名称)。
    • 国际件额外字段:若收件人地址为住宅,需设置residential: true;欧盟地区收件人需添加taxIdentifiers(如EORI号)。
  • 货物与包装配置:
    • 重量与单位:根据起运地国家动态选择单位(如美国用LB,其他国家用KG),value必须大于0且与实际货物一致。
    • 包装类型:优先使用YOUR_PACKAGING自定义包装,兼容性更强;若使用FedEx官方包装,需选择对应packagingType(如FEDEX_BOX)。
    • 国际件强制清关信息:必须添加customsClearanceDetail,包含:
      • dutiesPayment:指定税费支付方(通常为发件人SENDER)。
      • commodities:每票货物的description(准确描述,避免模糊词汇)、harmonizedCode(HS编码,需与货物品类严格匹配)、countryOfManufacture、unitPrice等字段,缺一不可。
  • 服务类型动态匹配:从之前调用的“获取服务类型API”结果中,选择当前起运地-目的地组合支持的serviceType,禁止硬编码(如国内件用GROUND_HOME_DELIVERY,国际件用INTERNATIONAL_PRIORITY)。

二、“无法处理请求”错误的常见排查方向

  • 完整日志记录:在Laravel中记录完整的请求体和响应内容,便于定位问题:
    use Illuminate\Support\Facades\Log;
    
    // 发送请求前记录
    Log::info('FedEx Shipment Request', ['body' => $requestBody]);
    // 收到响应后记录
    Log::info('FedEx Shipment Response', ['body' => $response->json()]);
    
    从响应中提取具体错误代码和描述,而非仅依赖通用提示。
  • 环境与权限校验:
    • 沙箱环境部分国家/服务可能未开放,若生产环境报错,需确认账号已开通对应国际运输权限,无欠费或功能限制。
    • 检查API版本:version字段的major版本需与FedEx当前API版本一致(如v24),版本不匹配会直接导致请求失败。
  • 必填字段遗漏:
    • 国内件无需customsClearanceDetail,但国际件必须包含;部分国家收件人phoneNumber为必填项。
    • 避免空值:所有字段若未填写,需删除而非留空字符串(如stateOrProvinceCode在无州/省的国家可省略)。
  • 数据格式错误:
    • postalCode、countryCode格式不符合目的地国家要求。
    • 重量/尺寸单位与服务类型不兼容(如国际件用LB可能触发格式校验错误)。

三、Laravel中动态构建请求体的示例代码

/**
 * 动态构建FedEx Shipment Create请求体
 * @param array $origin 起运地信息(country_code, postal_code, contact_name等)
 * @param array $destination 目的地信息
 * @param array $packages 货物列表(weight, hs_code, description等)
 * @param string $serviceType 从服务列表API获取的合法服务类型
 * @return array
 */
function buildFedExShipmentRequest($origin, $destination, $packages, $serviceType)
{
    $isInternational = $origin['country_code'] !== $destination['country_code'];
    $weightUnit = $origin['country_code'] === 'US' ? 'LB' : 'KG';
    $dimUnit = $origin['country_code'] === 'US' ? 'IN' : 'CM';

    $baseRequest = [
        'webAuthenticationDetail' => [
            'userCredential' => [
                'key' => env('FEDEX_KEY'),
                'password' => env('FEDEX_PASSWORD')
            ]
        ],
        'clientDetail' => [
            'accountNumber' => env('FEDEX_ACCOUNT_NUMBER'),
            'meterNumber' => env('FEDEX_METER_NUMBER')
        ],
        'transactionDetail' => [
            'customerTransactionId' => 'SHIP-' . uniqid()
        ],
        'version' => [
            'serviceId' => 'ship',
            'major' => 24,
            'intermediate' => 0,
            'minor' => 0
        ],
        'requestedShipment' => [
            'shipTimestamp' => now()->toIso8601String(),
            'serviceType' => $serviceType,
            'packagingType' => 'YOUR_PACKAGING',
            'shipper' => $this->buildContactAddress($origin),
            'recipient' => $this->buildContactAddress($destination),
            'shippingChargesPayment' => [
                'paymentType' => 'SENDER',
                'payor' => [
                    'accountNumber' => env('FEDEX_ACCOUNT_NUMBER'),
                    'countryCode' => $origin['country_code']
                ]
            ],
            'packageCount' => count($packages),
            'requestedPackageLineItems' => $this->buildPackageItems($packages, $weightUnit, $dimUnit)
        ]
    ];

    // 添加国际件清关信息
    if ($isInternational) {
        $baseRequest['requestedShipment']['customsClearanceDetail'] = [
            'dutiesPayment' => [
                'paymentType' => 'SENDER',
                'payor' => [
                    'accountNumber' => env('FEDEX_ACCOUNT_NUMBER'),
                    'countryCode' => $origin['country_code']
                ]
            ],
            'commodities' => $this->buildCommodities($packages, $weightUnit, $origin)
        ];
    }

    return $baseRequest;
}

// 辅助函数:构建联系人地址
private function buildContactAddress($addressData)
{
    $address = [
        'contact' => [
            'personName' => $addressData['contact_name'],
            'companyName' => $addressData['company_name'],
            'phoneNumber' => $addressData['phone']
        ],
        'address' => [
            'streetLines' => array_filter([$addressData['address1'], $addressData['address2']]),
            'city' => $addressData['city'],
            'postalCode' => $addressData['postal_code'],
            'countryCode' => $addressData['country_code'],
            'residential' => $addressData['is_residential'] ?? false
        ]
    ];

    // 仅当有州/省信息时添加
    if (!empty($addressData['state'])) {
        $address['address']['stateOrProvinceCode'] = $addressData['state'];
    }

    return $address;
}

// 辅助函数:构建货物包装信息
private function buildPackageItems($packages, $weightUnit, $dimUnit)
{
    return array_map(function ($pkg) use ($weightUnit, $dimUnit) {
        return [
            'weight' => [
                'units' => $weightUnit,
                'value' => $pkg['weight']
            ],
            'dimensions' => [
                'units' => $dimUnit,
                'length' => $pkg['length'],
                'width' => $pkg['width'],
                'height' => $pkg['height']
            ]
        ];
    }, $packages);
}

// 辅助函数:构建国际件商品清关信息
private function buildCommodities($packages, $weightUnit, $origin)
{
    return array_map(function ($pkg) use ($weightUnit, $origin) {
        return [
            'description' => $pkg['description'],
            'quantity' => 1,
            'quantityUnits' => 'PCS',
            'weight' => [
                'units' => $weightUnit,
                'value' => $pkg['weight']
            ],
            'unitPrice' => [
                'currency' => $origin['currency'] ?? 'USD',
                'amount' => $pkg['unit_price']
            ],
            'harmonizedCode' => $pkg['hs_code'],
            'countryOfManufacture' => $origin['country_code']
        ];
    }, $packages);
}

四、额外排查建议

  • 使用FedEx开发者门户的API测试工具,直接提交请求体,排除Laravel代码的影响,确认问题是否来自参数本身。
  • 若问题持续,提取日志中的错误代码,联系FedEx技术支持时提供完整请求/响应内容,避免仅描述通用错误提示。

内容的提问来源于stack exchange,提问作者Mirza Moiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 20:00:53