CAPABILITY GATEWAY
让 ERP 原生页面调用第三方应用能力
用户无需离开订单报价等业务页面。ERP 后端把请求交给开放平台,平台验证安装、企业、环境、权限和能力提供方后,再向第三方应用签发一次性票据。
ERP 前端 → ERP API → DSFulfill 开放平台 → 第三方应用。浏览器不得直连第三方能力接口,也不得持有应用 Client Secret 或自行传入可信企业身份。
如果你负责第三方应用服务端,请继续阅读 开放应用能力接入指南 →
- ERP API 从登录会话取得当前
company_id与actor_id。 - 开放平台检查当前企业是否已安装应用、Installation 是否有效、Scope 与调用场景是否匹配。
- 平台向已登记的 Provider Endpoint 发送
invocation_id和 60 秒一次性ticket。 - 应用后端用当前环境 Client Credential 换票,获得可信上下文,再检查套餐、额度并执行能力。
- 结果沿原链路返回 ERP;异步能力先返回任务 ID,完成后回调平台。
接入准备
应用必须先完成正常安装授权,并在对应环境登记能力。Sandbox 与 Production 的 Client Credential、Endpoint 和能力状态互相独立;Production 能力随审核通过的 Release 发布。
{
"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 前端调用自己的后台接口,不直接调用开放平台。当前图片搜索入口为:
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。这些字段不得接受浏览器覆盖。
第三方能力提供方如何处理
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 兑换票据:
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 企业都不能创建新的免费额度主体。
完整图片搜索示例
- 用户在 ERP 订单报价页上传或选择图片。
- ERP 把图片保存为 Provider 可读取的短期 HTTPS URL,再发起能力调用。
- PicFind 换票后,用可信
company_id搜索该企业已同步的商品索引。 - PicFind 原子检查订阅与额度;同一
invocation_id重放时返回原结果,不重复扣费。 - ERP 展示候选商品,用户选择后继续报价流程。
{
"status": "completed",
"data": {
"items": [
{ "product_id": "19550", "title": "Example product", "image_url": "https://...", "score": 0.94 }
]
},
"usage": { "charged": 1, "remaining": 99 }
}检索条件必须始终包含换票得到的企业标识。不得按第三方登录账号、邮箱或前端传入的 Company ID 跨企业检索。
标准响应与错误处理
同步成功返回 completed;耗时任务返回 accepted + job_id,完成后使用 Installation Access Token 回调;业务条件不满足返回 denied。
{
"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。
- 分别验收未安装、权限不足、无订阅、额度不足、多提供方、超时与重复请求。