DDSFulfill开发文档
文档  /  ERP 内嵌能力

CAPABILITY GATEWAY

让 ERP 原生页面调用第三方应用能力

用户无需离开订单报价等业务页面。ERP 后端把请求交给开放平台,平台验证安装、企业、环境、权限和能力提供方后,再向第三方应用签发一次性票据。

固定信任链

ERP 前端 → ERP API → DSFulfill 开放平台 → 第三方应用。浏览器不得直连第三方能力接口,也不得持有应用 Client Secret 或自行传入可信企业身份。

如果你负责第三方应用服务端,请继续阅读 开放应用能力接入指南 →

  1. ERP API 从登录会话取得当前 company_id 与 actor_id。
  2. 开放平台检查当前企业是否已安装应用、Installation 是否有效、Scope 与调用场景是否匹配。
  3. 平台向已登记的 Provider Endpoint 发送 invocation_id 和 60 秒一次性 ticket。
  4. 应用后端用当前环境 Client Credential 换票,获得可信上下文,再检查套餐、额度并执行能力。
  5. 结果沿原链路返回 ERP;异步能力先返回任务 ID,完成后回调平台。

接入准备

应用必须先完成正常安装授权,并在对应环境登记能力。Sandbox 与 Production 的 Client Credential、Endpoint 和能力状态互相独立;Production 能力随审核通过的 Release 发布。

PUT /v1/capabilities/image-search.searchJSON
{
  "version": "1.0",
  "title": "以图搜索本地商品",
  "description": "在订单报价中以图片查找当前企业商品库",
  "mode": "sync",
  "endpoint_url": "https://app.example.com/api/capabilities/image-search",
  "timeout_seconds": 10,
  "required_scopes": ["products:read"],
  "surfaces": ["order.quote.product-picker"],
  "input_schema": { "type": "object", "required": ["image_url"] },
  "output_schema": { "type": "object", "required": ["items"] }
}

登记请求使用 HTTP Basic Auth:用户名为当前环境 Client ID,密码为当前环境 Client Secret。Sandbox Endpoint 可使用本地开发地址;Production 必须使用公网 HTTPS。

ERP 发起调用

ERP 前端调用自己的后台接口,不直接调用开放平台。当前图片搜索入口为:

POST /api/admin/developer-platform/capability-invocationsJSON
Headers:
  Idempotency-Key: quote-9842-image-search-1

{
  "application_id": "open:app_xxx",
  "input": {
    "image_url": "https://cdn.example.com/query.jpg",
    "limit": 12
  }
}

application_id 可省略以使用当前企业已授权的唯一提供方;有多个同类应用时应由用户选择。Idempotency-Key 必须稳定且唯一,网络重试必须复用同一个值。

ERP API 再通过内部凭证调用 POST /api/internal/erp/capability-invocations,并补充可信的 company_id、actor_id、capability: image-search.search 与 surface: order.quote.product-picker。这些字段不得接受浏览器覆盖。

第三方能力提供方如何处理

平台调用 Provider EndpointJSON
Headers:
  X-DSFulfill-Environment: sandbox
  X-DSFulfill-Capability: image-search.search
  X-DSFulfill-Invocation-Id: inv_xxx

{
  "invocation_id": "inv_xxx",
  "ticket": "ds_cap_xxx"
}

不要直接信任 Header,也不要从浏览器 Cookie 推断用户。服务端立即使用同环境 Client Credential 兑换票据:

POST /v1/capability-invocations/tickets/exchangeJSON
Authorization: Basic base64(CLIENT_ID:CLIENT_SECRET)

{ "ticket": "ds_cap_xxx" }

// 可信响应
{
  "data": {
    "invocation_id": "inv_xxx",
    "application_id": "app_xxx",
    "installation_id": "ins_xxx",
    "company_id": "company_xxx",
    "actor_id": "admin_xxx",
    "environment": "sandbox",
    "capability": "image-search.search",
    "surface": "order.quote.product-picker",
    "input": { "image_url": "https://cdn.example.com/query.jpg", "limit": 12 },
    "expires_at": "2026-09-06T12:00:00.000Z"
  }
}

应用以 company_id + installation_id 定位租户,以 invocation_id 做执行与计费幂等。退出应用账号或切换 ERP 企业都不能创建新的免费额度主体。

标准响应与错误处理

同步成功返回 completed;耗时任务返回 accepted + job_id,完成后使用 Installation Access Token 回调;业务条件不满足返回 denied。

额度不足JSON
{
  "status": "denied",
  "reason": "INSUFFICIENT_CREDITS",
  "action": {
    "type": "open_app",
    "label": "前往充值",
    "launch_path": "/billing"
  }
}

开放平台会把常见失败标准化:APP_NOT_INSTALLED 引导安装,CAPABILITY_NOT_AUTHORIZED 引导重新授权,SUBSCRIPTION_REQUIRED 引导订阅,INSUFFICIENT_CREDITS 引导充值,SETUP_REQUIRED 引导初始化,PROVIDER_REQUIRED 让用户选择提供方,RATE_LIMITED 稍后重试,CAPABILITY_UNAVAILABLE 表示提供方暂不可用。

launch_path 必须是应用站内相对路径;开放平台会绑定实际 application_id,第三方不能指定任意外部跳转。

安全与验收清单

  • Client Secret、平台内部 Token 只保存在服务端;日志必须脱敏票据和凭证。
  • 一次性票据应立即兑换,过期或应用、环境不匹配必须拒绝。
  • 企业身份只认换票结果;每次查询、套餐和额度检查都绑定 Installation。
  • 以 invocation_id 原子幂等执行和扣费;失败重试不得重复消耗额度。
  • Provider Endpoint 需在超时内返回;图片等大文件使用短期 URL,不嵌入请求 JSON。
  • 分别验收未安装、权限不足、无订阅、额度不足、多提供方、超时与重复请求。