外卖系统接入配送API方案:如何实现订单与配送服务高效对接

简介: 本文详解外卖系统接入第三方配送API的完整方案,涵盖架构设计、接口规范、PHP代码实现、状态回调、幂等处理、异常重试及多平台适配等核心环节,助力自建平台高效解耦订单与履约,降低配送体系建设成本。(239字)

随着外卖业务不断发展,平台除了需要具备用户下单、商家接单、订单管理等基础能力,还需要解决一个核心问题:订单如何快速、高效地进入配送环节。

对于自建外卖平台、同城配送平台以及连锁餐饮系统来说,直接自建完整的配送体系往往需要投入较多的人力和技术成本。因此,越来越多外卖系统会通过接入第三方配送API,将订单系统与配送服务进行连接,实现订单自动创建配送任务、配送状态实时同步以及骑手信息回传。

本文将从系统架构、接口设计、核心流程以及代码实现几个方面,介绍外卖系统接入配送API的一套完整方案。
外卖系统.png

一、什么是外卖系统配送API

配送API可以理解为外卖系统与配送服务之间的数据桥梁。

用户完成下单后,外卖系统产生订单数据,然后通过API将订单信息提交给配送服务。配送服务根据配送地址、订单重量、配送距离等信息创建配送任务,并将配送状态返回给外卖系统。

基本流程可以简化为:

用户下单
   ↓
外卖系统生成订单
   ↓
商家确认接单
   ↓
调用配送API
   ↓
创建配送任务
   ↓
配送服务派单
   ↓
骑手接单
   ↓
骑手取货
   ↓
配送中
   ↓
配送完成
   ↓
配送状态回传外卖系统

这样可以将订单系统与配送系统进行解耦,让外卖平台专注于业务管理,而配送服务负责具体履约。

二、外卖系统接入配送API的整体架构

在实际开发过程中,可以将系统拆分成用户端、商家端、配送服务以及平台后台几个部分。

┌──────────────┐
│    用户端     │
│ H5 / 小程序 / APP │
└──────┬───────┘
       │ 下单
       ↓
┌──────────────┐
│   外卖业务系统  │
│ PHP + MySQL   │
└──────┬───────┘
       │
       │ 配送API
       ↓
┌──────────────┐
│   配送服务平台  │
└──────┬───────┘
       │
       │ 派单
       ↓
┌──────────────┐
│     骑手端     │
└──────┬───────┘
       │
       │ 状态回传
       ↓
┌──────────────┐
│   外卖系统后台  │
└──────────────┘

其中最重要的是中间的配送API服务层。

建议不要让订单业务代码直接大量依赖第三方接口,而是单独封装一个配送服务类。

例如:

interface DeliveryServiceInterface
{
   
    public function createOrder(array $order);

    public function cancelOrder(string $deliveryNo);

    public function queryOrder(string $deliveryNo);
}

后续如果需要更换配送服务,只需要替换具体实现即可,不需要大面积修改订单业务代码。

三、配送API需要对接哪些核心接口

一个完整的外卖配送接口体系通常包含以下几个核心功能。

1. 创建配送订单

商家确认订单后,外卖系统向配送服务提交配送任务。

通常需要传递:

{
   
    "order_no": "WM202609020001",
    "shop_name": "XX餐饮店",
    "shop_phone": "13800000000",
    "shop_address": "XX路100号",
    "user_name": "张先生",
    "user_phone": "13900000000",
    "user_address": "XX小区5号楼",
    "goods_amount": 38.5,
    "delivery_fee": 5,
    "remark": "请放在门口"
}

配送平台成功创建后,会返回一个配送单号。

{
   
    "code": 0,
    "message": "success",
    "delivery_no": "PS202609020001"
}

外卖系统需要保存这个配送单号,用于后续查询和状态同步。

2. 查询配送订单

当平台需要查看当前配送状态时,可以调用配送查询接口。

例如:

GET /api/delivery/order/detail

请求:

{
   
    "delivery_no": "PS202609020001"
}

返回:

{
   
    "delivery_no": "PS202609020001",
    "status": "delivering",
    "rider_name": "李师傅",
    "rider_phone": "13812345678"
}

然后将配送状态同步到外卖订单表。

四、PHP封装配送API调用

以PHP为例,可以对HTTP请求进行统一封装。

class DeliveryApi
{
   
    private string $baseUrl;
    private string $appKey;
    private string $appSecret;

    public function __construct()
    {
   
        $this->baseUrl = 'https://api.example.com';
        $this->appKey = 'your_app_key';
        $this->appSecret = 'your_app_secret';
    }

    private function request(string $method, string $uri, array $data = [])
    {
   
        $timestamp = time();

        $signString = $this->appKey
            . $timestamp
            . json_encode($data, JSON_UNESCAPED_UNICODE)
            . $this->appSecret;

        $sign = hash('sha256', $signString);

        $headers = [
            'Content-Type: application/json',
            'X-App-Key: ' . $this->appKey,
            'X-Timestamp: ' . $timestamp,
            'X-Sign: ' . $sign
        ];

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $this->baseUrl . $uri);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);

        if ($method === 'POST') {
   
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt(
                $ch,
                CURLOPT_POSTFIELDS,
                json_encode($data, JSON_UNESCAPED_UNICODE)
            );
        }

        $response = curl_exec($ch);

        if ($response === false) {
   
            throw new Exception(curl_error($ch));
        }

        curl_close($ch);

        return json_decode($response, true);
    }

    public function createOrder(array $order)
    {
   
        return $this->request(
            'POST',
            '/api/delivery/order/create',
            $order
        );
    }
}

实际项目中,baseUrlappKeyappSecret等信息应该放在环境变量或者系统配置中,不建议直接写死在业务代码里。

五、订单创建配送任务

当商家确认订单后,可以执行创建配送任务。

例如订单数据:

$order = [
    'order_no'      => 'WM202609020001',
    'shop_name'     => 'XX餐饮店',
    'shop_phone'    => '13800000000',
    'shop_address'  => 'XX路100号',
    'user_name'     => '张先生',
    'user_phone'    => '13900000000',
    'user_address'  => 'XX小区5号楼',
    'goods_amount'  => 38.5,
    'delivery_fee'  => 5,
    'remark'        => '请放在门口'
];

$deliveryApi = new DeliveryApi();

$result = $deliveryApi->createOrder($order);

if ($result['code'] === 0) {
   

    // 保存配送单号
    $deliveryNo = $result['delivery_no'];

    // 更新订单配送信息
    saveDeliveryNo(
        $order['order_no'],
        $deliveryNo
    );
}

数据库可以设计一个配送信息表:

CREATE TABLE `order_delivery` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `order_id` BIGINT UNSIGNED NOT NULL,
    `order_no` VARCHAR(64) NOT NULL,
    `delivery_no` VARCHAR(64) DEFAULT NULL,
    `rider_name` VARCHAR(50) DEFAULT NULL,
    `rider_phone` VARCHAR(30) DEFAULT NULL,
    `delivery_status` VARCHAR(30) DEFAULT 'pending',
    `created_at` DATETIME NOT NULL,
    `updated_at` DATETIME NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uk_order_no` (`order_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

这样可以把订单业务数据和配送业务数据进行分离。

六、配送状态回调是对接的核心

外卖系统接入配送API时,不能只依靠主动查询。

更合理的方式是:

配送平台
   ↓
状态发生变化
   ↓
调用外卖系统回调接口
   ↓
外卖系统验证请求
   ↓
更新订单配送状态
   ↓
更新用户端订单页面

例如配送状态:

pending      待配送
accepted     骑手已接单
picked_up    已取货
delivering   配送中
completed    配送完成
cancelled    配送取消

配送平台可以向:

POST /api/delivery/callback

发送:

{
   
    "delivery_no": "PS202609020001",
    "order_no": "WM202609020001",
    "status": "delivering",
    "rider_name": "李师傅",
    "rider_phone": "13812345678",
    "timestamp": 1788326400
}

七、PHP实现配送状态回调

后端接收到回调后,需要先验证签名,再处理订单。

public function callback()
{
   
    $body = file_get_contents('php://input');

    $data = json_decode($body, true);

    if (!$data) {
   
        return json([
            'code' => 400,
            'message' => 'invalid request'
        ]);
    }

    // 验证签名
    if (!$this->verifySign($data)) {
   
        return json([
            'code' => 401,
            'message' => 'invalid sign'
        ]);
    }

    $deliveryNo = $data['delivery_no'];
    $status     = $data['status'];

    $delivery = DeliveryOrder::where(
        'delivery_no',
        $deliveryNo
    )->first();

    if (!$delivery) {
   
        return json([
            'code' => 404,
            'message' => 'delivery order not found'
        ]);
    }

    $delivery->delivery_status = $status;
    $delivery->rider_name = $data['rider_name'] ?? '';
    $delivery->rider_phone = $data['rider_phone'] ?? '';
    $delivery->updated_at = date('Y-m-d H:i:s');

    $delivery->save();

    // 同步外卖订单状态
    $this->syncOrderStatus(
        $delivery->order_no,
        $status
    );

    return json([
        'code' => 0,
        'message' => 'success'
    ]);
}

这里需要特别注意幂等处理。

例如配送平台因为网络问题重复发送3次“配送完成”通知,外卖系统不能因此重复执行订单完成后的业务逻辑。

可以通过配送单号+状态+事件ID等方式实现幂等。

八、配送状态如何同步到用户端

配送状态更新后,可以进一步同步到用户端。

例如:

商家已接单
    ↓
等待骑手接单
    ↓
骑手已接单
    ↓
骑手正在取货
    ↓
骑手配送中
    ↓
订单已送达

如果系统使用WebSocket,可以在状态发生变化时实时推送:

$data = [
    'type' => 'delivery_status',
    'order_no' => 'WM202609020001',
    'status' => 'delivering',
    'rider_name' => '李师傅'
];

WebSocket::push(
    $userId,
    json_encode($data, JSON_UNESCAPED_UNICODE)
);

如果没有WebSocket,也可以采用短轮询方式,让用户端定时查询订单状态。

九、配送API需要考虑地图与距离计算

配送费用通常与配送距离存在直接关系。

因此外卖系统在设计配送模块时,可以将配送距离、配送区域、基础配送费以及额外费用进行拆分。

例如:

配送费 =
基础配送费
+ 距离费用
+ 时段附加费
+ 特殊区域费用

后端可以抽象成一个配送费计算方法:

function calculateDeliveryFee(
    float $baseFee,
    float $distance,
    float $distanceUnitPrice,
    float $timeFee = 0,
    float $areaFee = 0
): float {
   

    $distanceFee = 0;

    if ($distance > 3) {
   
        $extraDistance = $distance - 3;
        $distanceFee = $extraDistance * $distanceUnitPrice;
    }

    return round(
        $baseFee
        + $distanceFee
        + $timeFee
        + $areaFee,
        2
    );
}

例如:

$fee = calculateDeliveryFee(
    5,
    6.5,
    1.5,
    2,
    0
);

echo $fee;

如果基础配送费为5元,3公里以后每公里1.5元,当前距离6.5公里,并存在2元时段附加费,则可以根据业务规则计算最终配送费用。

实际项目中,费用规则应当放在后台配置,而不是固定写在代码里。

十、第三方配送API的异常处理

API对接最容易被忽略的就是异常情况。

例如:

接口超时
接口返回错误
配送区域不支持
配送服务暂停
骑手无法接单
订单创建失败
订单取消失败
回调重复
回调丢失
网络异常

因此建议增加重试机制。

例如:

function requestWithRetry(callable $request, int $maxRetry = 3)
{
   
    $retry = 0;

    while ($retry < $maxRetry) {
   

        try {
   

            $result = $request();

            if (
                isset($result['code'])
                && $result['code'] === 0
            ) {
   
                return $result;
            }

        } catch (Throwable $e) {
   

            // 写入日志
            error_log($e->getMessage());
        }

        $retry++;

        sleep(2);
    }

    throw new Exception(
        '配送API请求失败'
    );
}

不过需要注意,创建订单类接口不能简单地无限重试。

否则可能出现:

第一次请求成功
↓
外卖系统没有收到响应
↓
系统再次创建配送订单
↓
产生两个配送任务

因此创建配送任务时应该使用业务订单号作为幂等键。

十一、建议建立配送API适配层

如果未来可能接入多个配送服务,可以进一步设计统一配送接口。

例如:

interface DeliveryInterface
{
   
    public function create(array $order);

    public function cancel(string $deliveryNo);

    public function detail(string $deliveryNo);

    public function calculateFee(array $params);
}

不同配送服务分别实现:

class DeliveryProviderA implements DeliveryInterface
{
   
    public function create(array $order)
    {
   
        // 服务A接口
    }

    public function cancel(string $deliveryNo)
    {
   
        // 服务A取消接口
    }

    public function detail(string $deliveryNo)
    {
   
        // 服务A查询接口
    }

    public function calculateFee(array $params)
    {
   
        // 服务A计费接口
    }
}

另外一个配送服务:

class DeliveryProviderB implements DeliveryInterface
{
   
    public function create(array $order)
    {
   
        // 服务B接口
    }

    public function cancel(string $deliveryNo)
    {
   
        // 服务B取消接口
    }

    public function detail(string $deliveryNo)
    {
   
        // 服务B查询接口
    }

    public function calculateFee(array $params)
    {
   
        // 服务B计费接口
    }
}

业务层只调用:

$deliveryService->create($order);

而不需要关心具体使用哪一家配送服务。

这种架构对于后续扩展配送渠道非常有帮助。

十二、外卖系统接入配送API的关键点

从实际开发角度来看,配送API对接并不是简单地调用几个HTTP接口,而是需要考虑整个订单生命周期。

核心需要解决以下几个问题:

1. 订单数据统一

外卖系统中的订单字段与配送平台字段可能不同,需要建立数据映射关系。

2. 配送订单幂等

避免因为网络重试造成重复配送。

3. 状态统一

不同配送平台可能采用不同的状态名称,需要转换成外卖系统自己的标准状态。

4. 回调安全

所有回调接口都应该进行签名验证,防止非法请求修改订单状态。

5. 异常重试

网络超时、接口异常等情况需要支持自动重试和人工补偿。

6. 日志记录

建议记录:

订单号
配送单号
请求参数
响应数据
请求时间
响应时间
接口耗时
错误信息
重试次数

方便出现问题时快速定位。

十三、一个完整的配送业务流程

最终,一个较为完整的外卖配送业务流程可以设计为:

用户提交订单
      ↓
订单支付成功
      ↓
商家接单
      ↓
计算配送费用
      ↓
创建配送任务
      ↓
配送平台接收订单
      ↓
骑手接单
      ↓
骑手到店取货
      ↓
开始配送
      ↓
配送状态实时同步
      ↓
用户收到商品
      ↓
配送完成
      ↓
外卖订单完成

与此同时,平台后台可以通过数据看板统计:

配送订单量
配送完成率
平均配送时长
平均配送距离
配送取消率
骑手接单率
异常订单数量

通过这些数据,可以进一步优化配送区域、配送规则以及骑手调度策略。
外卖系统.png

十四、总结

外卖系统接入配送API,本质上是通过标准化接口打通订单系统与配送服务,让订单从“商家接单”能够自动进入“配送履约”环节。

在开发过程中,除了完成创建配送订单、查询配送状态、取消配送以及状态回调等基础接口,还需要重点考虑接口安全、订单幂等、异常重试、数据同步以及多配送渠道适配等问题。

对于需要搭建外卖平台的企业来说,更合理的方式不是简单增加一个配送接口,而是将配送能力设计成独立的服务模块。这样既能够降低系统之间的耦合,也方便后续扩展不同配送渠道。

最终形成:

用户下单
   ↓
商家接单
   ↓
订单中心
   ↓
配送服务
   ↓
骑手履约
   ↓
状态回传
   ↓
用户收货

通过外卖系统与配送API的深度结合,可以进一步实现订单、商家、配送、骑手和用户之间的数据互通,为外卖平台建立更加完整的订单履约体系。

相关文章
|
19天前
|
人工智能 缓存 前端开发
DeepSeek Harness 首发实测 + 入门教程,夯爆了!梁神我错了
DeepSeek Harness + DeepSeek V4 Pro 项目实战保姆级教程!手把手带你从零安装开源 AI 编程工具,开发架构图、知识讲解网站、3D 网页游戏、全栈 AI 应用 4 个项目,覆盖运行模式选择、插件安装与开发,看看能不能对标 Claude。
13091 82
DeepSeek Harness 首发实测 + 入门教程,夯爆了!梁神我错了
|
7天前
|
人工智能 自然语言处理 安全
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
本文聚焦阿里云2026年推出的三款自研AI办公产品,清晰拆解千问办公、Qoder Teams、Qoder CN的差异化定位与能力边界:千问办公主打职场全场景提效,支持自然语言指令一键完成PPT生成、数据分析等高频办公任务;Qoder Teams面向程序员团队,深度整合AI代码生成、团队协同与企业知识库能力;Qoder CN则专为金融、政务等强合规场景打造,实现数据不出境与VPC私有化部署。文章同步给出分场景选型指南与最新活动定价,帮助不同类型的企业按需组合产品,实现业务岗、研发岗与强合规场景的AI能力全覆盖。
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
|
2天前
|
缓存 人工智能 API
阿里云Qwen3.8‑Flash完整能力解析:模型特性、API调用实操与计费规则深度拆解
在AI应用快速落地的当下,开发者与企业选型大模型API,不再只单纯关注评测榜单分数,推理速度、上下文长度、多模态能力、工具调用稳定性以及实际调用成本,共同决定项目能否平稳上线。Qwen3.8‑Flash作为新一代多模态混合专家模型,主打高性能推理与低成本开销,面向编程开发、智能Agent工作流、超长文档解析、图文混合理解等高频场景,提供托管API服务,权重同时开放可供本地部署,兼容主流接口协议,能够无缝接入各类开发工具链。很多开发者在接入过程中,容易混淆普通按量Token计费、缓存计费、各类订阅计划之间的差异,造成实际账单超出预估。本文从模型底层架构、核心功能能力、适用场景、API调用实操、完
675 0
|
12天前
|
Web App开发 人工智能 API
16 个超火的 DeepSeek Harness 插件,大肥鱼已经落后 N 个版本了。。。
DeepSeek Harness 精选插件推荐合集,从图片识别、浏览器操控、多 Agent 协作到手机远程控制,一口气带你看完 DSH 社区热门的十几个插件,覆盖技能扩展、UI 界面增强、整活玩法三大类,让你的鲸鱼变得更强。
1725 4
|
13天前
|
人工智能 Java BI
【AI】DeepSeek Harness 安装、运行、管理插件
本文介绍了如何运行DeepSeek开源的Agent框架DeepSeek Harness(dsh)。主要内容包括:使用nvm安装适配的Node版本;通过代理加速克隆GitHub源码;使用pnpm安装依赖并启动项目;配置DeepSeek API Token;安装扩展功能的插件。该框架自带Web界面,支持模型适配、文件编辑等插件化功能
1901 1
|
人工智能 JavaScript 开发工具
DeepSeek Harness 本地安装与使用指南
DeepSeek Harness(DSH)是DeepSeek AI开源的Agent运行框架,支持本地文件操作、命令执行与工具调用。基于Cordis插件架构,具备高扩展性与强可控性,适合开发者搭建可控Agent环境或开展模型基准测试。当前为开发者预览版,需Node.js环境,推荐先用`npx @deepseek-ai/dsh web`快速体验。
5137 0
|
15天前
|
人工智能 JavaScript 测试技术
保姆级教程:DeepSeek Harness从安装到跑通测试,30分钟上手
DeepSeek Harness是DeepSeek开源的AI Agent运行时,主打“一行命令安装、5分钟跑通”。它让模型真正动手干活——读代码、跑测试、分析失败、生成修复方案。本文手把手教你30分钟从零上手,覆盖安装、配置、实测及避坑指南,助你快速掌握下一代AI编程范式。
|
7天前
|
人工智能 Linux iOS开发
Ollama使用教程:Ollama官网下载、Ollama本地部署大模型(2026最新)
Ollama 是一款免费开源的本地大模型运行工具,支持在 Windows/macOS/Linux 上离线运行 Qwen、DeepSeek、Llama 等主流开源模型,数据不出本机、隐私安全。提供 OpenAI 兼容 API,命令行一键拉取/运行/管理模型,无需联网,无调用限制,是开发者与 AI 爱好者部署本地 AI 助手的理想选择。(239 字)
|
14天前
|
人工智能 JavaScript 测试技术
从 0 到 1,DeepSeek Harness 保姆级安装与使用教程!
DeepSeek Harness是DeepSeek推出的开源Agent运行框架,秉持“一切皆插件”理念,支持模型、工具、技能、工作流等全模块自由替换与扩展。其核心Cordis内核实现动态插件管理,赋能Agent自进化。已成GitHub史上增速最快开源项目(15w+ Star),标志着国内大模型从拼价格转向重架构与生态的新拐点。
1339 6
从 0 到 1,DeepSeek Harness 保姆级安装与使用教程!