Java 圆通快递 API 工具类:创建订单、获取运单号、取消订单、查询订单、获取面单

该 Java 工具类封装了圆通快递 API 的常用功能,包括创建订单、获取运单号、取消订单、查询订单和获取面单等。代码经过完善和优化,易于使用,并提供详细的使用示例。

代码示例:

import java.io.*;
import java.net.*;
import java.util.*;

public class YTOUtil {

    private static final String API_URL = 'http://api.yto.net.cn/CommonOrderModeBPlusServlet.action';

    private static final String CUST_ID = 'YOUR_CUST_ID'; // 顾客编码
    private static final String PARTNER_ID = 'YOUR_PARTNER_ID'; // 合作伙伴标识
    private static final String CLIENT_SECRET = 'YOUR_CLIENT_SECRET'; // 客户密钥

    // 创建订单接口
    public static String createOrder(String orderNo, String senderName, String senderMobile, String senderProvince,
                                     String senderCity, String senderDistrict, String senderAddress, String receiverName,
                                     String receiverMobile, String receiverProvince, String receiverCity,
                                     String receiverDistrict, String receiverAddress, String goodsName, int quantity,
                                     double weight, double totalPrice) throws Exception {
        String reqXml = "<?xml version='1.0' encoding='UTF-8'?><RequestOrder>" +
                "<clientID>" + CUST_ID + "</clientID>" +
                "<logisticProviderID>YTO</logisticProviderID>" +
                "<customerId>" + CUST_ID + "</customerId>" +
                "<txLogisticID>" + orderNo + "</txLogisticID>" +
                "<tradeNo>" + orderNo + "</tradeNo>" +
                "<orderType>1</orderType>" +
                "<serviceType>0</serviceType>" +
                "<flag>0</flag>" +
                "<sender>" +
                "<name>" + senderName + "</name>" +
                "<mobile>" + senderMobile + "</mobile>" +
                "<province>" + senderProvince + "</province>" +
                "<city>" + senderCity + "</city>" +
                "<expArea>" + senderDistrict + "</expArea>" +
                "<address>" + senderAddress + "</address>" +
                "</sender>" +
                "<receiver>" +
                "<name>" + receiverName + "</name>" +
                "<mobile>" + receiverMobile + "</mobile>" +
                "<province>" + receiverProvince + "</province>" +
                "<city>" + receiverCity + "</city>" +
                "<expArea>" + receiverDistrict + "</expArea>" +
                "<address>" + receiverAddress + "</address>" +
                "</receiver>" +
                "<goodsValue>" + totalPrice + "</goodsValue>" +
                "<itemsValue>" + totalPrice + "</itemsValue>" +
                "<items>" +
                "<item>" +
                "<itemName>" + goodsName + "</itemName>" +
                "<number>" + quantity + "</number>" +
                "<itemValue>" + totalPrice + "</itemValue>" +
                "<itemValueCurrency>CNY</itemValueCurrency>" +
                "<specification>规格</specification>" +
                "<brand>品牌</brand>" +
                "</item>" +
                "</items>" +
                "<insuranceValue>" + totalPrice + "</insuranceValue>" +
                "<special>6</special>" +
                "<remark>订单备注</remark>" +
                "</RequestOrder>";

        String respXml = doPost(reqXml);
        return parseOrderNo(respXml);
    }

    // 获取运单号
    public static String getMailNo(String orderNo) throws Exception {
        String reqXml = "<?xml version='1.0' encoding='UTF-8'?><RequestOrder>" +
                "<clientID>" + CUST_ID + "</clientID>" +
                "<logisticProviderID>YTO</logisticProviderID>" +
                "<customerId>" + CUST_ID + "</customerId>" +
                "<txLogisticID>" + orderNo + "</txLogisticID>" +
                "<tradeNo>" + orderNo + "</tradeNo>" +
                "<orderType>1</orderType>" +
                "<serviceType>0</serviceType>" +
                "<flag>0</flag>" +
                "<mailNo></mailNo>" +
                "</RequestOrder>";

        String respXml = doPost(reqXml);
        return parseMailNo(respXml);
    }

    // 取消订单接口
    public static boolean cancelOrder(String orderNo) throws Exception {
        String reqXml = "<?xml version='1.0' encoding='UTF-8'?><RequestOrderCancel>" +
                "<clientID>" + CUST_ID + "</clientID>" +
                "<logisticProviderID>YTO</logisticProviderID>" +
                "<customerId>" + CUST_ID + "</customerId>" +
                "<txLogisticID>" + orderNo + "</txLogisticID>" +
                "<tradeNo>" + orderNo + "</tradeNo>" +
                "<mailNo></mailNo>" +
                "</RequestOrderCancel>";

        String respXml = doPost(reqXml);
        return parseCancelResult(respXml);
    }

    // 查询订单接口
    public static String queryOrder(String orderNo) throws Exception {
        String reqXml = "<?xml version='1.0' encoding='UTF-8'?><QueryOrder>" +
                "<clientID>" + CUST_ID + "</clientID>" +
                "<logisticProviderID>YTO</logisticProviderID>" +
                "<customerId>" + CUST_ID + "</customerId>" +
                "<txLogisticID>" + orderNo + "</txLogisticID>" +
                "<tradeNo>" + orderNo + "</tradeNo>" +
                "</QueryOrder>";

        String respXml = doPost(reqXml);
        return parseQueryResult(respXml);
    }

    // 获取面单
    public static byte[] getExpressBill(String orderNo) throws Exception {
        String reqXml = "<?xml version='1.0' encoding='UTF-8'?><RequestOrderDistributeInfo>" +
                "<clientID>" + CUST_ID + "</clientID>" +
                "<logisticProviderID>YTO</logisticProviderID>" +
                "<customerId>" + CUST_ID + "</customerId>" +
                "<txLogisticID>" + orderNo + "</txLogisticID>" +
                "<tradeNo>" + orderNo + "</tradeNo>" +
                "</RequestOrderDistributeInfo>";

        String respXml = doPost(reqXml);
        return parseExpressBill(respXml);
    }

    // 发送POST请求
    private static String doPost(String reqXml) throws Exception {
        URL url = new URL(API_URL);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setRequestProperty("Content-type", "text/xml;charset=UTF-8");

        String timestamp = String.valueOf(System.currentTimeMillis());
        String sign = getSign(timestamp);

        conn.setRequestProperty("timestamp", timestamp);
        conn.setRequestProperty("sign", sign);

        OutputStream os = conn.getOutputStream();
        os.write(reqXml.getBytes());
        os.flush();
        os.close();

        if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
            throw new RuntimeException("请求失败:" + conn.getResponseMessage());
        }

        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();

        return sb.toString();
    }

    // 获取签名
    private static String getSign(String timestamp) throws Exception {
        String str = CUST_ID + PARTNER_ID + CLIENT_SECRET + timestamp;
        return md5(str);
    }

    // MD5加密
    private static String md5(String str) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] bytes = md.digest(str.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(b & 0xff);
            if (hex.length() == 1) {
                sb.append("0");
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    // 解析订单号
    private static String parseOrderNo(String respXml) throws Exception {
        Document doc = DocumentHelper.parseText(respXml);
        Element root = doc.getRootElement();
        Element result = root.element("Result");
        Element orderNo = result.element("mailNo");
        return orderNo.getTextTrim();
    }

    // 解析运单号
    private static String parseMailNo(String respXml) throws Exception {
        Document doc = DocumentHelper.parseText(respXml);
        Element root = doc.getRootElement();
        Element result = root.element("Result");
        Element mailNo = result.element("mailNo");
        return mailNo.getTextTrim();
    }

    // 解析取消结果
    private static boolean parseCancelResult(String respXml) throws Exception {
        Document doc = DocumentHelper.parseText(respXml);
        Element root = doc.getRootElement();
        Element result = root.element("Result");
        Element success = result.element("success");
        return Boolean.parseBoolean(success.getTextTrim());
    }

    // 解析查询结果
    private static String parseQueryResult(String respXml) throws Exception {
        Document doc = DocumentHelper.parseText(respXml);
        Element root = doc.getRootElement();
        Element result = root.element("Result");
        Element message = result.element("message");
        return message.getTextTrim();
    }

    // 解析面单
    private static byte[] parseExpressBill(String respXml) throws Exception {
        Document doc = DocumentHelper.parseText(respXml);
        Element root = doc.getRootElement();
        Element result = root.element("Result");
        Element image = result.element("image");
        return Base64.getDecoder().decode(image.getTextTrim());
    }

}

使用方法:

// 创建订单
String orderNo = YTOUtil.createOrder("YOUR_ORDER_NO", "张三", "13812345678", "广东省", "深圳市", "福田区", "福华路", "李四", "13987654321", "广东省", "深圳市", "罗湖区", "人民南路", "商品名称", 1, 1.5, 10.0);

// 获取运单号
String mailNo = YTOUtil.getMailNo(orderNo);

// 取消订单
boolean result = YTOUtil.cancelOrder(orderNo);

// 查询订单
String message = YTOUtil.queryOrder(orderNo);

// 获取面单
byte[] expressBill = YTOUtil.getExpressBill(orderNo);

注意:

  • 将代码中的 YOUR_CUST_IDYOUR_PARTNER_IDYOUR_CLIENT_SECRET 替换为您的实际圆通快递账号信息。
  • 该工具类使用 DocumentHelper 解析 XML,请确保项目中已添加相关依赖。
  • 代码中使用了 Base64 解码获取面单,请确保项目中已添加 java.util.Base64 依赖。
  • 该工具类仅供参考,实际使用时可能需要根据具体需求进行调整。
Java 圆通快递 API 工具类:创建订单、获取运单号、取消订单、查询订单、获取面单

原文地址: https://www.cveoy.top/t/topic/mKrP 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录