USPS Shipping Options API v3调用遇400错误:请求体无效或格式错误
看起来你已经搞定了OAuth认证的基础部分,但400错误基本都是请求体的格式或字段不符合USPS API的严格要求,我帮你梳理几个最容易踩坑的点,结合这个API的常见规范来排查:
重量与尺寸的格式是重灾区
USPS Shipping Options API v3对包裹的重量、尺寸字段要求非常严格,你当前直接传数值的方式大概率不符合要求——这些字段需要是包含数值和单位的嵌套对象,而不是单独的数字。比如重量需要明确是盎司(OZ)还是磅(LB),尺寸要指定英寸(IN):"weight": {"value": 10, "unit": "OZ"}, "length": {"value": 6, "unit": "IN"}, "height": {"value": 4, "unit": "IN"}, "width": {"value": 3, "unit": "IN"}你之前直接传数值,API根本无法识别单位,这肯定会触发格式错误。
mailClass的位置可能不对
你把mailClass放在了packageDescription里面,但根据API v3的规范,mailClass应该是和originZIPCode同层级的顶级字段,而不是嵌套在包裹描述里。这个位置错误也是常见的400触发点。pricingOptions的结构可能不需要数组
你的代码里把pricingOptions做成了数组,但很多时候USPS API要求这是一个单个的对象,而不是数组结构。比如应该是{"pricingOptions": {"priceType": "RETAIL"}}而不是数组包裹的形式。确保ZIP码是字符串类型
如果你传入的origin_zip或destination_zip是数字类型(比如90210),那对于带前导零的ZIP码(比如01234)会自动丢失前导零,导致API识别为无效ZIP码。所以一定要转成字符串再传入。
结合这些修改,调整后的payload应该是这样的:
payload = { "pricingOptions": {"priceType": "RETAIL"}, "originZIPCode": str(origin_zip), "destinationZIPCode": str(destination_zip), "mailClass": mail_class, "packageDescription": { "weight": {"value": weight, "unit": "OZ"}, "length": {"value": length, "unit": "IN"}, "height": {"value": height, "unit": "IN"}, "width": {"value": width, "unit": "IN"} } }
另外,你可以在打印payload的时候用json.dumps(payload, indent=2),这样能更清晰地看到请求体的结构,方便和官方文档的示例做对比。如果还是有问题,可以去USPS的开发者后台看具体的错误详情(有些时候返回的错误信息会更详细)。
备注:内容来源于stack exchange,提问作者Vishal Addnectar

