第2章:快速开始

本文档提供 WMS API 的快速入门指南,帮助开发者快速完成系统对接。


2.1 前置准备

2.1.1 获取凭证

在开始对接前,您需要:

1. 联系技术支持团队,获取以下信息:

  • API Key(用于认证)
  • API Secret(用于认证)
  • 测试环境地址
  • 生产环境地址(上线前提供)

2. 确认环境信息

  • 测试环境(Sandbox):用于开发调试
  • 生产环境(Production):用于正式业务

2.2 完整对接流程

步骤1:获取 Token

首先,您需要获取访问令牌(Token)。

接口地址POST /ucauth/authc/account/createToken

请求头

X-Api-Key: your-api-key
X-Api-Secret: your-api-secret
Content-Type: application/json

请求示例(Java)

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class TokenService {
    
    private static final String TOKEN_URL = "https://api.sandbox.onixportltl.com/ucauth/authc/account/createToken";
    private RestTemplate restTemplate = new RestTemplate();
    
    public String getToken(String apiKey, String apiSecret) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("X-Api-Key", apiKey);
        headers.set("X-Api-Secret", apiSecret);
        headers.set("Content-Type", "application/json");
        
        HttpEntity<String> entity = new HttpEntity<>(headers);
        
        ResponseEntity<TokenResponse> response = restTemplate.exchange(
            TOKEN_URL, 
            HttpMethod.POST, 
            entity, 
            TokenResponse.class
        );
        
        TokenResponse tokenResponse = response.getBody();
        if (tokenResponse != null && tokenResponse.getSuccess()) {
            return tokenResponse.getResult().getAccessToken();
        }
        
        throw new RuntimeException("获取Token失败: " + 
            (tokenResponse != null ? tokenResponse.getErrorMsg() : "未知错误"));
    }
    
    // Token响应类
    public static class TokenResponse {
        private Boolean success;
        private Integer errorCode;
        private String errorMsg;
        private TokenResult result;
        
        // Getters and Setters
        public Boolean getSuccess() { return success; }
        public void setSuccess(Boolean success) { this.success = success; }
        public Integer getErrorCode() { return errorCode; }
        public void setErrorCode(Integer errorCode) { this.errorCode = errorCode; }
        public String getErrorMsg() { return errorMsg; }
        public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; }
        public TokenResult getResult() { return result; }
        public void setResult(TokenResult result) { this.result = result; }
    }
    
    public static class TokenResult {
        private String accessToken;
        private Long expiresIn;
        
        // Getters and Setters
        public String getAccessToken() { return accessToken; }
        public void setAccessToken(String accessToken) { this.accessToken = accessToken; }
        public Long getExpiresIn() { return expiresIn; }
        public void setExpiresIn(Long expiresIn) { this.expiresIn = expiresIn; }
    }
}

响应示例

{
  "success": true,
  "errorCode": null,
  "errorMsg": null,
  "result": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "expiresIn": 86400
  }
}

步骤2:调用业务接口

获取 Token 后,即可调用业务接口。以下以创建商品为例:

接口地址POST /onixport/api/wms/product/create

请求头

Authorization: Bearer {accessToken}
Content-Type: application/json

请求示例(Java)

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class ProductService {
    
    private static final String BASE_URL = "https://api.sandbox.onixportltl.com";
    private RestTemplate restTemplate = new RestTemplate();
    
    public void createProduct(String token, ProductRequest request) {
        String url = BASE_URL + "/onixport/api/wms/product/create";
        
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + token);
        headers.set("Content-Type", "application/json");
        
        HttpEntity<ProductRequest> entity = new HttpEntity<>(request, headers);
        
        ResponseEntity<Map> response = restTemplate.exchange(
            url, 
            HttpMethod.POST, 
            entity, 
            Map.class
        );
        
        Map<String, Object> result = response.getBody();
        if (result != null && Boolean.TRUE.equals(result.get("success"))) {
            System.out.println("商品创建成功");
        } else {
            System.err.println("商品创建失败: " + 
                (result != null ? (String) result.get("errorMsg") : "未知错误"));
        }
    }
    
    // 商品请求类
    public static class ProductRequest {
        private String sku;
        private String commodityName;
        private BigDecimal weight;
        private Integer dimensionsLength;
        private Integer dimensionsWidth;
        private Integer dimensionsHeight;
        
        // Getters and Setters
        // ...
    }
}

请求体示例

{
  "sku": "SKU123456",
  "commodityName": "iPhone 15 Case",
  "weight": 0.5,
  "dimensionsLength": 6,
  "dimensionsWidth": 3,
  "dimensionsHeight": 1,
  "declaredValue": 29.99,
  "enableExpiryControl": 0,
  "enableLocationControl": 0,
  "enableSerialControl": 0
}

2.3 错误处理

2.3.1 错误响应结构

所有接口的错误响应都遵循统一格式:

{
  "success": false,
  "errorCode": 1000,
  "errorMsg": "无效的参数",
  "result": null
}

2.3.2 错误处理示例

public void handleError(Map<String, Object> response) {
    if (response == null || Boolean.TRUE.equals(response.get("success"))) {
        return;
    }
    
    Integer errorCode = (Integer) response.get("errorCode");
    String errorMsg = (String) response.get("errorMsg");
    
    // 只有 500 错误可以重试
    if (errorCode != null && errorCode == 500) {
        // 实现重试逻辑(指数退避)
        retryRequest();
        return;
    }
    
    // 其他错误码不可重试
    switch (errorCode) {
        case 401:
            // Token 过期,重新获取 Token
            refreshToken();
            break;
        case 1000:
            // 参数错误,检查并修正参数
            validateParameters();
            break;
        default:
            // 记录错误日志
            log.error("请求失败 [{}]: {}", errorCode, errorMsg);
            break;
    }
}

2.4 完整示例:创建出库订单

以下是一个完整的创建出库订单示例:

import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;

public class OutboundOrderService {
    
    private static final String BASE_URL = "https://api.sandbox.onixportltl.com";
    private RestTemplate restTemplate = new RestTemplate();
    private TokenService tokenService;
    
    public void createOutboundOrder(String apiKey, String apiSecret) {
        // 1. 获取 Token
        String token = tokenService.getToken(apiKey, apiSecret);
        
        // 2. 构建请求
        OutboundCreateRequest request = new OutboundCreateRequest();
        List<OutboundInfo> outboundInfoList = new ArrayList<>();
        
        OutboundInfo outboundInfo = new OutboundInfo();
        outboundInfo.setWarehouseCode("W1");
        outboundInfo.setReferenceNo("ORDER-2025-001");
        outboundInfo.setOrderType(1); // Fulfil
        outboundInfo.setCarrierCode(2); // UPS
        
        // 设置收件人信息
        outboundInfo.setConsigneeCompany("ABC Company");
        outboundInfo.setConsigneeName("John Doe");
        outboundInfo.setConsigneePhone("1234567890");
        outboundInfo.setConsigneeAddress1("123 Main St");
        outboundInfo.setConsigneeZipcode("90001");
        outboundInfo.setConsigneeCity("Los Angeles");
        outboundInfo.setConsigneeState("CA");
        outboundInfo.setConsigneeCountry("US");
        
        // 设置商品明细
        List<OutboundItem> itemList = new ArrayList<>();
        OutboundItem item = new OutboundItem();
        item.setSku("SKU123456");
        item.setInventoryType(1); // New
        item.setOutboundQty(10);
        itemList.add(item);
        outboundInfo.setItemList(itemList);
        
        outboundInfoList.add(outboundInfo);
        request.setOutboundInfoList(outboundInfoList);
        
        // 3. 发送请求
        String url = BASE_URL + "/onixport/api/wms/outbound/create";
        
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + token);
        headers.set("Content-Type", "application/json");
        
        HttpEntity<OutboundCreateRequest> entity = new HttpEntity<>(request, headers);
        
        ResponseEntity<Map> response = restTemplate.exchange(
            url, 
            HttpMethod.POST, 
            entity, 
            Map.class
        );
        
        // 4. 处理响应
        Map<String, Object> result = response.getBody();
        if (result != null && Boolean.TRUE.equals(result.get("success"))) {
            // 处理成功结果
            Map<String, Object> createResponse = 
                (Map<String, Object>) result.get("result");
            
            // 处理成功的订单
            List<Map<String, Object>> successList = (List<Map<String, Object>>) createResponse.get("successResultList");
            if (successList != null) {
                for (Map<String, Object> successItem : successList) {
                    System.out.println("订单创建成功: " + 
                        successItem.get("orderNo") + ", " + 
                        successItem.get("referenceNo"));
                }
            }
            
            // 处理失败的订单
            List<Map<String, Object>> failedList = (List<Map<String, Object>>) createResponse.get("failedResultList");
            if (failedList != null) {
                for (Map<String, Object> failedItem : failedList) {
                    System.err.println("订单创建失败: " + 
                        failedItem.get("referenceNo") + ", " + 
                        failedItem.get("errorMsg"));
                }
            }
        } else {
            // 处理错误
            handleError(result);
        }
    }
}

2.5 最佳实践

2.5.1 Token 管理

1. 缓存 Token:Token 有效期为 24 小时,建议缓存到 Redis 或本地缓存

2. 提前刷新:在 Token 过期前 1 分钟重新获取

3. 错误处理:遇到 401 错误时,重新获取 Token 后重试请求

2.5.2 批量操作

1. 分批处理:单次请求不超过 100 条,提高成功率

2. 错误处理:检查 successResultListfailedResultList,对失败的条目进行修正后重新提交

3. 幂等性:确保 referenceNo 唯一,避免重复创建

2.5.3 错误重试

1. 仅重试 500 错误:只有服务器错误(500)可以重试

2. 指数退避:实现指数退避重试策略(1秒、2秒、4秒)

3. 限制重试次数:最多重试 3 次

2.5.4 性能优化

1. 连接池:使用 HTTP 连接池,提高性能

2. 异步处理:对于批量操作,考虑异步处理

3. 限流控制:实现客户端限流,避免触发服务端限流


2.6 下一步

完成快速开始后,建议:

1. 阅读详细文档

2. 查看业务接口文档

3. 遇到问题


2.7 技术支持

如有问题,请联系技术支持团队。