Spring Boot集成Shiprocket API创建订单遇403错误,求排查及示例
Spring Boot集成Shiprocket API创建订单及403错误排查
一、403 Forbidden错误的可能原因
- 账号权限不足:Shiprocket账号可能未开通订单创建权限,或属于测试账号被限制操作,需登录Shiprocket后台确认账号权限配置。
- Token过期/无效:即使token非空,也可能已过有效期(Shiprocket的Auth Token通常有时间限制),建议在调用前验证token有效性,或捕获
401 Unauthorized异常时重新获取token。 - 请求头格式问题:确认
Authorization头严格遵循Bearer {token}格式,注意Bearer与token之间的空格,避免额外空格或特殊字符。 - IP白名单限制:Shiprocket后台可能设置了IP白名单,你的服务器IP不在允许列表内导致请求被拒绝,需在Shiprocket后台添加服务器IP到白名单。
- API端点或版本错误:确认调用的订单创建端点
/v1/external/orders/create/adhoc是否与你的账号适用的API版本匹配,部分账号可能需要使用其他端点。
二、Shiprocket订单创建请求体示例
以下是符合Shiprocket API要求的订单创建请求体(JSON格式):
{ "order_id": "ORD-20240520-001", "order_date": "2024-05-20T12:30:00Z", "pickup_location": "default", "billing_customer_name": "张三", "billing_address": "上海市浦东新区张江高科技园区", "billing_city": "上海市", "billing_pincode": "201203", "billing_state": "上海", "billing_country": "India", "billing_email": "zhangsan@example.com", "billing_phone": "13900139000", "shipping_is_billing": true, "order_items": [ { "name": "无线蓝牙耳机", "sku": "BT-001", "units": 1, "selling_price": 299.00, "discount": 0, "tax": 26.91, "hsn": "85183000" } ], "payment_method": "prepaid", "sub_total": 299.00, "total_discount": 0, "length": 15, "breadth": 10, "height": 8, "weight": 0.3 }
注意:
billing_country需设置为India(Shiprocket当前仅支持印度境内订单),hsn需填写正确的商品海关编码。
三、优化后的WebClient配置与调用示例
1. WebClient配置类
复用WebClient实例,统一配置基础URL和默认请求头:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.reactive.function.client.WebClient; @Configuration public class ShiprocketConfig { @Bean public WebClient shiprocketWebClient() { return WebClient.builder() .baseUrl("https://apiv2.shiprocket.in/v1/external") .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .build(); } }
2. 认证与订单创建服务类
添加错误处理,捕获403/401等异常,提升代码健壮性:
import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClientResponseException; import java.util.Map; @Service public class ShiprocketService { private final WebClient shiprocketWebClient; public ShiprocketService(WebClient shiprocketWebClient) { this.shiprocketWebClient = shiprocketWebClient; } // 获取认证Token public String getAuthToken(String email, String password) { try { return shiprocketWebClient.post() .uri("/auth/login") .bodyValue(Map.of("email", email, "password", password)) .retrieve() .bodyToMono(ShiprocketAuthResponse.class) .block() .getToken(); } catch (WebClientResponseException ex) { throw new RuntimeException("认证失败: " + ex.getResponseBodyAsString(), ex); } } // 创建临时订单 public String createAdhocOrder(String token, Object orderPayload) { try { return shiprocketWebClient.post() .uri("/orders/create/adhoc") .header("Authorization", "Bearer " + token) .bodyValue(orderPayload) .retrieve() .bodyToMono(String.class) .block(); } catch (WebClientResponseException.Forbidden ex) { // 打印详细响应体,排查具体拒绝原因 System.err.println("403错误详情: " + ex.getResponseBodyAsString()); throw new RuntimeException("订单创建权限被拒绝", ex); } catch (WebClientResponseException.Unauthorized ex) { // Token过期,可在此处重新获取Token并重试 throw new RuntimeException("Token已过期,请重新认证", ex); } catch (WebClientResponseException ex) { throw new RuntimeException("Shiprocket API调用失败: " + ex.getResponseBodyAsString(), ex); } } // 认证响应DTO public static class ShiprocketAuthResponse { private String token; public String getToken() { return token; } public void setToken(String token) { this.token = token; } } }
内容的提问来源于stack exchange,提问作者Surya R
相关产品推荐
相关产品推荐

